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
);
75 /********************************************************************
76 * Canonicalize servername.
77 ********************************************************************/
79 static const char *canon_servername(const char *servername
)
81 const char *pservername
= servername
;
82 while (*pservername
== '\\') {
88 /* translate between internal status numbers and NT status numbers */
89 static int nt_printj_status(int v
)
95 return JOB_STATUS_PAUSED
;
97 return JOB_STATUS_SPOOLING
;
99 return JOB_STATUS_PRINTING
;
101 return JOB_STATUS_ERROR
;
103 return JOB_STATUS_DELETING
;
105 return JOB_STATUS_OFFLINE
;
107 return JOB_STATUS_PAPEROUT
;
109 return JOB_STATUS_PRINTED
;
111 return JOB_STATUS_DELETED
;
113 return JOB_STATUS_BLOCKED
;
114 case LPQ_USER_INTERVENTION
:
115 return JOB_STATUS_USER_INTERVENTION
;
120 static int nt_printq_status(int v
)
124 return PRINTER_STATUS_PAUSED
;
133 /****************************************************************************
134 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
135 ****************************************************************************/
137 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION
**pp
)
142 SAFE_FREE((*pp
)->ctr
.type
);
146 /***************************************************************************
147 Disconnect from the client
148 ****************************************************************************/
150 static void srv_spoolss_replycloseprinter(int snum
, POLICY_HND
*handle
)
155 * Tell the specific printing tdb we no longer want messages for this printer
156 * by deregistering our PID.
159 if (!print_notify_deregister_pid(snum
))
160 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum
) ));
162 /* weird if the test succeds !!! */
163 if (smb_connections
==0) {
164 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
168 result
= rpccli_spoolss_reply_close_printer(notify_cli_pipe
,
172 if (!W_ERROR_IS_OK(result
))
173 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
174 dos_errstr(result
)));
176 /* if it's the last connection, deconnect the IPC$ share */
177 if (smb_connections
==1) {
179 cli_shutdown( notify_cli_pipe
->cli
);
180 notify_cli_pipe
= NULL
; /* The above call shuts downn the pipe also. */
182 messaging_deregister(smbd_messaging_context(),
183 MSG_PRINTER_NOTIFY2
, NULL
);
185 /* Tell the connections db we're no longer interested in
186 * printer notify messages. */
188 register_message_flags( False
, FLAG_MSG_PRINT_NOTIFY
);
194 /****************************************************************************
195 Functions to free a printer entry datastruct.
196 ****************************************************************************/
198 static void free_printer_entry(void *ptr
)
200 Printer_entry
*Printer
= (Printer_entry
*)ptr
;
202 if (Printer
->notify
.client_connected
==True
) {
205 if ( Printer
->printer_type
== SPLHND_SERVER
) {
207 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
208 } else if (Printer
->printer_type
== SPLHND_PRINTER
) {
209 snum
= print_queue_snum(Printer
->sharename
);
211 srv_spoolss_replycloseprinter(snum
,
212 &Printer
->notify
.client_hnd
);
216 Printer
->notify
.flags
=0;
217 Printer
->notify
.options
=0;
218 Printer
->notify
.localmachine
[0]='\0';
219 Printer
->notify
.printerlocal
=0;
220 free_spool_notify_option(&Printer
->notify
.option
);
221 Printer
->notify
.option
=NULL
;
222 Printer
->notify
.client_connected
=False
;
224 free_nt_devicemode( &Printer
->nt_devmode
);
225 free_a_printer( &Printer
->printer_info
, 2 );
227 talloc_destroy( Printer
->ctx
);
229 /* Remove from the internal list. */
230 DLIST_REMOVE(printers_list
, Printer
);
235 /****************************************************************************
236 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
237 ****************************************************************************/
239 static SPOOL_NOTIFY_OPTION
*dup_spool_notify_option(SPOOL_NOTIFY_OPTION
*sp
)
241 SPOOL_NOTIFY_OPTION
*new_sp
= NULL
;
246 new_sp
= SMB_MALLOC_P(SPOOL_NOTIFY_OPTION
);
253 new_sp
->ctr
.type
= (SPOOL_NOTIFY_OPTION_TYPE
*)memdup(sp
->ctr
.type
, sizeof(SPOOL_NOTIFY_OPTION_TYPE
) * sp
->ctr
.count
);
255 if (!new_sp
->ctr
.type
) {
264 /****************************************************************************
265 find printer index by handle
266 ****************************************************************************/
268 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
, POLICY_HND
*hnd
)
270 Printer_entry
*find_printer
= NULL
;
272 if(!find_policy_by_hnd(p
,hnd
,(void **)(void *)&find_printer
)) {
273 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
280 /****************************************************************************
281 Close printer index by handle.
282 ****************************************************************************/
284 static bool close_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
286 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
289 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
293 close_policy_hnd(p
, hnd
);
298 /****************************************************************************
299 Delete a printer given a handle.
300 ****************************************************************************/
302 WERROR
delete_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *sharename
)
304 char *cmd
= lp_deleteprinter_cmd();
305 char *command
= NULL
;
307 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
308 bool is_print_op
= False
;
310 /* can't fail if we don't try */
315 command
= talloc_asprintf(ctx
,
322 is_print_op
= user_has_privileges( token
, &se_printop
);
324 DEBUG(10,("Running [%s]\n", command
));
326 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
331 if ( (ret
= smbrun(command
, NULL
)) == 0 ) {
332 /* Tell everyone we updated smb.conf. */
333 message_send_all(smbd_messaging_context(),
334 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
340 /********** END SePrintOperatorPrivlege BLOCK **********/
342 DEBUGADD(10,("returned [%d]\n", ret
));
344 TALLOC_FREE(command
);
347 return WERR_BADFID
; /* What to return here? */
349 /* go ahead and re-read the services immediately */
350 reload_services( False
);
352 if ( lp_servicenumber( sharename
) < 0 )
353 return WERR_ACCESS_DENIED
;
358 /****************************************************************************
359 Delete a printer given a handle.
360 ****************************************************************************/
362 static WERROR
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
364 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
367 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
372 * It turns out that Windows allows delete printer on a handle
373 * opened by an admin user, then used on a pipe handle created
374 * by an anonymous user..... but they're working on security.... riiight !
378 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
379 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
380 return WERR_ACCESS_DENIED
;
383 /* this does not need a become root since the access check has been
384 done on the handle already */
386 if (del_a_printer( Printer
->sharename
) != 0) {
387 DEBUG(3,("Error deleting printer %s\n", Printer
->sharename
));
391 return delete_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, Printer
->sharename
);
394 /****************************************************************************
395 Return the snum of a printer corresponding to an handle.
396 ****************************************************************************/
398 static bool get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
,
399 struct share_params
**params
)
401 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
404 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
408 switch (Printer
->printer_type
) {
410 DEBUG(4,("short name:%s\n", Printer
->sharename
));
411 *number
= print_queue_snum(Printer
->sharename
);
412 return (*number
!= -1);
420 /****************************************************************************
421 Set printer handle type.
422 Check if it's \\server or \\server\printer
423 ****************************************************************************/
425 static bool set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
427 DEBUG(3,("Setting printer type=%s\n", handlename
));
429 if ( strlen(handlename
) < 3 ) {
430 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
434 /* it's a print server */
435 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
436 DEBUGADD(4,("Printer is a print server\n"));
437 Printer
->printer_type
= SPLHND_SERVER
;
439 /* it's a printer (set_printer_hnd_name() will handle port monitors */
441 DEBUGADD(4,("Printer is a printer\n"));
442 Printer
->printer_type
= SPLHND_PRINTER
;
448 /****************************************************************************
449 Set printer handle name.. Accept names like \\server, \\server\printer,
450 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
451 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
452 XcvDataPort() interface.
453 ****************************************************************************/
455 static bool set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
458 int n_services
=lp_numservices();
459 char *aprinter
, *printername
;
460 const char *servername
;
463 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
466 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename
, (unsigned long)strlen(handlename
)));
468 aprinter
= handlename
;
469 if ( *handlename
== '\\' ) {
470 servername
= canon_servername(handlename
);
471 if ( (aprinter
= strchr_m( servername
, '\\' )) != NULL
) {
479 /* save the servername to fill in replies on this handle */
481 if ( !is_myname_or_ipaddr( servername
) )
484 fstrcpy( Printer
->servername
, servername
);
486 if ( Printer
->printer_type
== SPLHND_SERVER
)
489 if ( Printer
->printer_type
!= SPLHND_PRINTER
)
492 DEBUGADD(5, ("searching for [%s]\n", aprinter
));
494 /* check for the Port Monitor Interface */
496 if ( strequal( aprinter
, SPL_XCV_MONITOR_TCPMON
) ) {
497 Printer
->printer_type
= SPLHND_PORTMON_TCP
;
498 fstrcpy(sname
, SPL_XCV_MONITOR_TCPMON
);
501 else if ( strequal( aprinter
, SPL_XCV_MONITOR_LOCALMON
) ) {
502 Printer
->printer_type
= SPLHND_PORTMON_LOCAL
;
503 fstrcpy(sname
, SPL_XCV_MONITOR_LOCALMON
);
507 /* Search all sharenames first as this is easier than pulling
508 the printer_info_2 off of disk. Don't use find_service() since
509 that calls out to map_username() */
511 /* do another loop to look for printernames */
513 for (snum
=0; !found
&& snum
<n_services
; snum
++) {
515 /* no point going on if this is not a printer */
517 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
)) )
520 fstrcpy(sname
, lp_servicename(snum
));
521 if ( strequal( aprinter
, sname
) ) {
526 /* no point looking up the printer object if
527 we aren't allowing printername != sharename */
529 if ( lp_force_printername(snum
) )
532 fstrcpy(sname
, lp_servicename(snum
));
536 /* This call doesn't fill in the location or comment from
537 * a CUPS server for efficiency with large numbers of printers.
541 result
= get_a_printer_search( NULL
, &printer
, 2, sname
);
542 if ( !W_ERROR_IS_OK(result
) ) {
543 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
544 sname
, dos_errstr(result
)));
548 /* printername is always returned as \\server\printername */
549 if ( !(printername
= strchr_m(&printer
->info_2
->printername
[2], '\\')) ) {
550 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
551 printer
->info_2
->printername
));
552 free_a_printer( &printer
, 2);
558 if ( strequal(printername
, aprinter
) ) {
559 free_a_printer( &printer
, 2);
564 DEBUGADD(10, ("printername: %s\n", printername
));
566 free_a_printer( &printer
, 2);
569 free_a_printer( &printer
, 2);
572 DEBUGADD(4,("Printer not found\n"));
576 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
578 fstrcpy(Printer
->sharename
, sname
);
583 /****************************************************************************
584 Find first available printer slot. creates a printer handle for you.
585 ****************************************************************************/
587 static bool open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
, uint32 access_granted
)
589 Printer_entry
*new_printer
;
591 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
593 if((new_printer
=SMB_MALLOC_P(Printer_entry
)) == NULL
)
596 ZERO_STRUCTP(new_printer
);
598 if (!create_policy_hnd(p
, hnd
, free_printer_entry
, new_printer
)) {
599 SAFE_FREE(new_printer
);
603 /* Add to the internal list. */
604 DLIST_ADD(printers_list
, new_printer
);
606 new_printer
->notify
.option
=NULL
;
608 if ( !(new_printer
->ctx
= talloc_init("Printer Entry [%p]", hnd
)) ) {
609 DEBUG(0,("open_printer_hnd: talloc_init() failed!\n"));
610 close_printer_handle(p
, hnd
);
614 if (!set_printer_hnd_printertype(new_printer
, name
)) {
615 close_printer_handle(p
, hnd
);
619 if (!set_printer_hnd_name(new_printer
, name
)) {
620 close_printer_handle(p
, hnd
);
624 new_printer
->access_granted
= access_granted
;
626 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
631 /***************************************************************************
632 check to see if the client motify handle is monitoring the notification
633 given by (notify_type, notify_field).
634 **************************************************************************/
636 static bool is_monitoring_event_flags(uint32 flags
, uint16 notify_type
,
642 static bool is_monitoring_event(Printer_entry
*p
, uint16 notify_type
,
645 SPOOL_NOTIFY_OPTION
*option
= p
->notify
.option
;
649 * Flags should always be zero when the change notify
650 * is registered by the client's spooler. A user Win32 app
651 * might use the flags though instead of the NOTIFY_OPTION_INFO
660 return is_monitoring_event_flags(
661 p
->notify
.flags
, notify_type
, notify_field
);
663 for (i
= 0; i
< option
->count
; i
++) {
665 /* Check match for notify_type */
667 if (option
->ctr
.type
[i
].type
!= notify_type
)
670 /* Check match for field */
672 for (j
= 0; j
< option
->ctr
.type
[i
].count
; j
++) {
673 if (option
->ctr
.type
[i
].fields
[j
] == notify_field
) {
679 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
680 p
->servername
, p
->sharename
, notify_type
, notify_field
));
685 /* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
687 static void notify_one_value(struct spoolss_notify_msg
*msg
,
688 SPOOL_NOTIFY_INFO_DATA
*data
,
691 data
->notify_data
.value
[0] = msg
->notify
.value
[0];
692 data
->notify_data
.value
[1] = 0;
695 static void notify_string(struct spoolss_notify_msg
*msg
,
696 SPOOL_NOTIFY_INFO_DATA
*data
,
701 /* The length of the message includes the trailing \0 */
703 init_unistr2(&unistr
, msg
->notify
.data
, UNI_STR_TERMINATE
);
705 data
->notify_data
.data
.length
= msg
->len
* 2;
706 data
->notify_data
.data
.string
= TALLOC_ARRAY(mem_ctx
, uint16
, msg
->len
);
708 if (!data
->notify_data
.data
.string
) {
709 data
->notify_data
.data
.length
= 0;
713 memcpy(data
->notify_data
.data
.string
, unistr
.buffer
, msg
->len
* 2);
716 static void notify_system_time(struct spoolss_notify_msg
*msg
,
717 SPOOL_NOTIFY_INFO_DATA
*data
,
723 if (msg
->len
!= sizeof(time_t)) {
724 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
729 if (!prs_init(&ps
, RPC_MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
)) {
730 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
734 if (!make_systemtime(&systime
, gmtime((time_t *)msg
->notify
.data
))) {
735 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
740 if (!spoolss_io_system_time("", &ps
, 0, &systime
)) {
745 data
->notify_data
.data
.length
= prs_offset(&ps
);
746 if (prs_offset(&ps
)) {
747 data
->notify_data
.data
.string
= (uint16
*)
748 TALLOC(mem_ctx
, prs_offset(&ps
));
749 if (!data
->notify_data
.data
.string
) {
753 prs_copy_all_data_out((char *)data
->notify_data
.data
.string
, &ps
);
755 data
->notify_data
.data
.string
= NULL
;
761 struct notify2_message_table
{
763 void (*fn
)(struct spoolss_notify_msg
*msg
,
764 SPOOL_NOTIFY_INFO_DATA
*data
, TALLOC_CTX
*mem_ctx
);
767 static struct notify2_message_table printer_notify_table
[] = {
768 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string
},
769 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string
},
770 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string
},
771 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string
},
772 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string
},
773 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string
},
774 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string
},
775 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL
},
776 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string
},
777 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string
},
778 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL
},
779 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string
},
780 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
781 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value
},
782 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value
},
783 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL
},
784 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL
},
785 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL
},
786 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value
},
789 static struct notify2_message_table job_notify_table
[] = {
790 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL
},
791 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL
},
792 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL
},
793 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string
},
794 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL
},
795 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL
},
796 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL
},
797 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL
},
798 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL
},
799 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL
},
800 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value
},
801 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL
},
802 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
803 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string
},
804 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL
},
805 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL
},
806 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time
},
807 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL
},
808 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL
},
809 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL
},
810 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value
},
811 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL
},
812 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value
},
813 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL
},
817 /***********************************************************************
818 Allocate talloc context for container object
819 **********************************************************************/
821 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
826 ctr
->ctx
= talloc_init("notify_msg_ctr_init %p", ctr
);
831 /***********************************************************************
832 release all allocated memory and zero out structure
833 **********************************************************************/
835 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
841 talloc_destroy(ctr
->ctx
);
848 /***********************************************************************
849 **********************************************************************/
851 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
859 /***********************************************************************
860 **********************************************************************/
862 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
864 if ( !ctr
|| !ctr
->msg_groups
)
867 if ( idx
>= ctr
->num_groups
)
870 return &ctr
->msg_groups
[idx
];
874 /***********************************************************************
875 How many groups of change messages do we have ?
876 **********************************************************************/
878 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
883 return ctr
->num_groups
;
886 /***********************************************************************
887 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
888 **********************************************************************/
890 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
892 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
893 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
894 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
900 /* loop over all groups looking for a matching printer name */
902 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
903 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
907 /* add a new group? */
909 if ( i
== ctr
->num_groups
) {
912 if ( !(groups
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, ctr
->msg_groups
, SPOOLSS_NOTIFY_MSG_GROUP
, ctr
->num_groups
)) ) {
913 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
916 ctr
->msg_groups
= groups
;
918 /* clear the new entry and set the printer name */
920 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
921 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
924 /* add the change messages; 'i' is the correct index now regardless */
926 msg_grp
= &ctr
->msg_groups
[i
];
930 if ( !(msg_list
= TALLOC_REALLOC_ARRAY( ctr
->ctx
, msg_grp
->msgs
, SPOOLSS_NOTIFY_MSG
, msg_grp
->num_msgs
)) ) {
931 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
934 msg_grp
->msgs
= msg_list
;
936 new_slot
= msg_grp
->num_msgs
-1;
937 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
939 /* need to allocate own copy of data */
942 msg_grp
->msgs
[new_slot
].notify
.data
= (char *)
943 TALLOC_MEMDUP( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
945 return ctr
->num_groups
;
948 /***********************************************************************
949 Send a change notication message on all handles which have a call
951 **********************************************************************/
953 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
956 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
957 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
958 SPOOLSS_NOTIFY_MSG
*messages
;
959 int sending_msg_count
;
962 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
966 messages
= msg_group
->msgs
;
969 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
973 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
975 /* loop over all printers */
977 for (p
= printers_list
; p
; p
= p
->next
) {
978 SPOOL_NOTIFY_INFO_DATA
*data
;
983 /* Is there notification on this handle? */
985 if ( !p
->notify
.client_connected
)
988 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p
->servername
, p
->sharename
));
990 /* For this printer? Print servers always receive
993 if ( ( p
->printer_type
== SPLHND_PRINTER
) &&
994 ( !strequal(msg_group
->printername
, p
->sharename
) ) )
997 DEBUG(10,("Our printer\n"));
999 /* allocate the max entries possible */
1001 data
= TALLOC_ARRAY( mem_ctx
, SPOOL_NOTIFY_INFO_DATA
, msg_group
->num_msgs
);
1008 /* build the array of change notifications */
1010 sending_msg_count
= 0;
1012 for ( i
=0; i
<msg_group
->num_msgs
; i
++ ) {
1013 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
1015 /* Are we monitoring this event? */
1017 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
1020 sending_msg_count
++;
1023 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1024 msg
->type
, msg
->field
, p
->sharename
));
1027 * if the is a printer notification handle and not a job notification
1028 * type, then set the id to 0. Other wise just use what was specified
1031 * When registering change notification on a print server handle
1032 * we always need to send back the id (snum) matching the printer
1033 * for which the change took place. For change notify registered
1034 * on a printer handle, this does not matter and the id should be 0.
1039 if ( ( p
->printer_type
== SPLHND_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
1045 /* Convert unix jobid to smb jobid */
1047 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
) {
1048 id
= sysjob_to_jobid(msg
->id
);
1051 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
1056 construct_info_data( &data
[data_len
], msg
->type
, msg
->field
, id
);
1059 case PRINTER_NOTIFY_TYPE
:
1060 if ( printer_notify_table
[msg
->field
].fn
)
1061 printer_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
1064 case JOB_NOTIFY_TYPE
:
1065 if ( job_notify_table
[msg
->field
].fn
)
1066 job_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
1070 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
1077 if ( sending_msg_count
) {
1078 rpccli_spoolss_rrpcn( notify_cli_pipe
, mem_ctx
, &p
->notify
.client_hnd
,
1079 data_len
, data
, p
->notify
.change
, 0 );
1084 DEBUG(8,("send_notify2_changes: Exit...\n"));
1088 /***********************************************************************
1089 **********************************************************************/
1091 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, struct timeval
*tv
, void *buf
, size_t len
)
1094 uint32 tv_sec
, tv_usec
;
1097 /* Unpack message */
1099 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "f",
1102 offset
+= tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "ddddddd",
1104 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1107 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "dd",
1108 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1110 tdb_unpack((uint8
*)buf
+ offset
, len
- offset
, "B",
1111 &msg
->len
, &msg
->notify
.data
);
1113 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1114 msg
->printer
, (unsigned int)msg
->id
, msg
->type
, msg
->field
, msg
->flags
));
1116 tv
->tv_sec
= tv_sec
;
1117 tv
->tv_usec
= tv_usec
;
1120 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1121 msg
->notify
.value
[1]));
1123 dump_data(3, (uint8
*)msg
->notify
.data
, msg
->len
);
1128 /********************************************************************
1129 Receive a notify2 message list
1130 ********************************************************************/
1132 static void receive_notify2_message_list(struct messaging_context
*msg
,
1135 struct server_id server_id
,
1138 size_t msg_count
, i
;
1139 char *buf
= (char *)data
->data
;
1142 SPOOLSS_NOTIFY_MSG notify
;
1143 SPOOLSS_NOTIFY_MSG_CTR messages
;
1146 if (data
->length
< 4) {
1147 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1151 msg_count
= IVAL(buf
, 0);
1154 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count
));
1156 if (msg_count
== 0) {
1157 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1161 /* initialize the container */
1163 ZERO_STRUCT( messages
);
1164 notify_msg_ctr_init( &messages
);
1167 * build message groups for each printer identified
1168 * in a change_notify msg. Remember that a PCN message
1169 * includes the handle returned for the srv_spoolss_replyopenprinter()
1170 * call. Therefore messages are grouped according to printer handle.
1173 for ( i
=0; i
<msg_count
; i
++ ) {
1174 struct timeval msg_tv
;
1176 if (msg_ptr
+ 4 - buf
> data
->length
) {
1177 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1181 msg_len
= IVAL(msg_ptr
,0);
1184 if (msg_ptr
+ msg_len
- buf
> data
->length
) {
1185 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1189 /* unpack messages */
1191 ZERO_STRUCT( notify
);
1192 notify2_unpack_msg( ¬ify
, &msg_tv
, msg_ptr
, msg_len
);
1195 /* add to correct list in container */
1197 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1199 /* free memory that might have been allocated by notify2_unpack_msg() */
1201 if ( notify
.len
!= 0 )
1202 SAFE_FREE( notify
.notify
.data
);
1205 /* process each group of messages */
1207 num_groups
= notify_msg_ctr_numgroups( &messages
);
1208 for ( i
=0; i
<num_groups
; i
++ )
1209 send_notify2_changes( &messages
, i
);
1214 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32
)msg_count
));
1216 notify_msg_ctr_destroy( &messages
);
1221 /********************************************************************
1222 Send a message to ourself about new driver being installed
1223 so we can upgrade the information for each printer bound to this
1225 ********************************************************************/
1227 static bool srv_spoolss_drv_upgrade_printer(char* drivername
)
1229 int len
= strlen(drivername
);
1234 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1237 messaging_send_buf(smbd_messaging_context(), procid_self(),
1238 MSG_PRINTER_DRVUPGRADE
,
1239 (uint8
*)drivername
, len
+1);
1244 /**********************************************************************
1245 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1246 over all printers, upgrading ones as necessary
1247 **********************************************************************/
1249 void do_drv_upgrade_printer(struct messaging_context
*msg
,
1252 struct server_id server_id
,
1257 int n_services
= lp_numservices();
1260 len
= MIN(data
->length
,sizeof(drivername
)-1);
1261 strncpy(drivername
, (const char *)data
->data
, len
);
1263 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername
));
1265 /* Iterate the printer list */
1267 for (snum
=0; snum
<n_services
; snum
++)
1269 if (lp_snum_ok(snum
) && lp_print_ok(snum
) )
1272 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1274 result
= get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
));
1275 if (!W_ERROR_IS_OK(result
))
1278 if (printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
))
1280 DEBUG(6,("Updating printer [%s]\n", printer
->info_2
->printername
));
1282 /* all we care about currently is the change_id */
1284 result
= mod_a_printer(printer
, 2);
1285 if (!W_ERROR_IS_OK(result
)) {
1286 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1287 dos_errstr(result
)));
1291 free_a_printer(&printer
, 2);
1298 /********************************************************************
1299 Update the cache for all printq's with a registered client
1301 ********************************************************************/
1303 void update_monitored_printq_cache( void )
1305 Printer_entry
*printer
= printers_list
;
1308 /* loop through all printers and update the cache where
1309 client_connected == True */
1312 if ( (printer
->printer_type
== SPLHND_PRINTER
)
1313 && printer
->notify
.client_connected
)
1315 snum
= print_queue_snum(printer
->sharename
);
1316 print_queue_status( snum
, NULL
, NULL
);
1319 printer
= printer
->next
;
1324 /********************************************************************
1325 Send a message to ourself about new driver being installed
1326 so we can upgrade the information for each printer bound to this
1328 ********************************************************************/
1330 static bool srv_spoolss_reset_printerdata(char* drivername
)
1332 int len
= strlen(drivername
);
1337 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1340 messaging_send_buf(smbd_messaging_context(), procid_self(),
1341 MSG_PRINTERDATA_INIT_RESET
,
1342 (uint8
*)drivername
, len
+1);
1347 /**********************************************************************
1348 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1349 over all printers, resetting printer data as neessary
1350 **********************************************************************/
1352 void reset_all_printerdata(struct messaging_context
*msg
,
1355 struct server_id server_id
,
1360 int n_services
= lp_numservices();
1363 len
= MIN( data
->length
, sizeof(drivername
)-1 );
1364 strncpy( drivername
, (const char *)data
->data
, len
);
1366 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername
));
1368 /* Iterate the printer list */
1370 for ( snum
=0; snum
<n_services
; snum
++ )
1372 if ( lp_snum_ok(snum
) && lp_print_ok(snum
) )
1375 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1377 result
= get_a_printer( NULL
, &printer
, 2, lp_const_servicename(snum
) );
1378 if ( !W_ERROR_IS_OK(result
) )
1382 * if the printer is bound to the driver,
1383 * then reset to the new driver initdata
1386 if ( printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
) )
1388 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer
->info_2
->printername
));
1390 if ( !set_driver_init(printer
, 2) ) {
1391 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1392 printer
->info_2
->printername
, printer
->info_2
->drivername
));
1395 result
= mod_a_printer( printer
, 2 );
1396 if ( !W_ERROR_IS_OK(result
) ) {
1397 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1398 get_dos_error_msg(result
)));
1402 free_a_printer( &printer
, 2 );
1411 /********************************************************************
1412 Copy routines used by convert_to_openprinterex()
1413 *******************************************************************/
1415 static DEVICEMODE
* dup_devicemode(TALLOC_CTX
*ctx
, DEVICEMODE
*devmode
)
1423 DEBUG (8,("dup_devmode\n"));
1425 /* bulk copy first */
1427 d
= (DEVICEMODE
*)TALLOC_MEMDUP(ctx
, devmode
, sizeof(DEVICEMODE
));
1431 /* dup the pointer members separately */
1433 len
= unistrlen(devmode
->devicename
.buffer
);
1435 d
->devicename
.buffer
= TALLOC_ARRAY(ctx
, uint16
, len
);
1436 if (!d
->devicename
.buffer
) {
1439 if (unistrcpy(d
->devicename
.buffer
, devmode
->devicename
.buffer
) != len
)
1444 len
= unistrlen(devmode
->formname
.buffer
);
1446 d
->formname
.buffer
= TALLOC_ARRAY(ctx
, uint16
, len
);
1447 if (!d
->formname
.buffer
) {
1450 if (unistrcpy(d
->formname
.buffer
, devmode
->formname
.buffer
) != len
)
1454 if (devmode
->driverextra
) {
1455 d
->dev_private
= (uint8
*)TALLOC_MEMDUP(ctx
, devmode
->dev_private
,
1456 devmode
->driverextra
);
1457 if (!d
->dev_private
) {
1461 d
->dev_private
= NULL
;
1466 static void copy_devmode_ctr(TALLOC_CTX
*ctx
, DEVMODE_CTR
*new_ctr
, DEVMODE_CTR
*ctr
)
1468 if (!new_ctr
|| !ctr
)
1471 DEBUG(8,("copy_devmode_ctr\n"));
1473 new_ctr
->size
= ctr
->size
;
1474 new_ctr
->devmode_ptr
= ctr
->devmode_ptr
;
1476 if(ctr
->devmode_ptr
)
1477 new_ctr
->devmode
= dup_devicemode(ctx
, ctr
->devmode
);
1480 static void copy_printer_default(TALLOC_CTX
*ctx
, PRINTER_DEFAULT
*new_def
, PRINTER_DEFAULT
*def
)
1482 if (!new_def
|| !def
)
1485 DEBUG(8,("copy_printer_defaults\n"));
1487 new_def
->datatype_ptr
= def
->datatype_ptr
;
1489 if (def
->datatype_ptr
)
1490 copy_unistr2(&new_def
->datatype
, &def
->datatype
);
1492 copy_devmode_ctr(ctx
, &new_def
->devmode_cont
, &def
->devmode_cont
);
1494 new_def
->access_required
= def
->access_required
;
1497 /********************************************************************
1498 * Convert a SPOOL_Q_OPEN_PRINTER structure to a
1499 * SPOOL_Q_OPEN_PRINTER_EX structure
1500 ********************************************************************/
1502 static WERROR
convert_to_openprinterex(TALLOC_CTX
*ctx
, SPOOL_Q_OPEN_PRINTER_EX
*q_u_ex
, SPOOL_Q_OPEN_PRINTER
*q_u
)
1504 if (!q_u_ex
|| !q_u
)
1507 DEBUG(8,("convert_to_openprinterex\n"));
1509 if ( q_u
->printername
) {
1510 q_u_ex
->printername
= TALLOC_ZERO_P( ctx
, UNISTR2
);
1511 if (q_u_ex
->printername
== NULL
)
1513 copy_unistr2(q_u_ex
->printername
, q_u
->printername
);
1516 copy_printer_default(ctx
, &q_u_ex
->printer_default
, &q_u
->printer_default
);
1521 /********************************************************************
1522 * spoolss_open_printer
1524 * called from the spoolss dispatcher
1525 ********************************************************************/
1527 WERROR
_spoolss_open_printer(pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER
*q_u
, SPOOL_R_OPEN_PRINTER
*r_u
)
1529 SPOOL_Q_OPEN_PRINTER_EX q_u_ex
;
1530 SPOOL_R_OPEN_PRINTER_EX r_u_ex
;
1535 ZERO_STRUCT(q_u_ex
);
1536 ZERO_STRUCT(r_u_ex
);
1538 /* convert the OpenPrinter() call to OpenPrinterEx() */
1540 r_u_ex
.status
= convert_to_openprinterex(p
->mem_ctx
, &q_u_ex
, q_u
);
1541 if (!W_ERROR_IS_OK(r_u_ex
.status
))
1542 return r_u_ex
.status
;
1544 r_u_ex
.status
= _spoolss_open_printer_ex(p
, &q_u_ex
, &r_u_ex
);
1546 /* convert back to OpenPrinter() */
1548 memcpy(r_u
, &r_u_ex
, sizeof(*r_u
));
1550 if (W_ERROR_EQUAL(r_u
->status
, WERR_INVALID_PARAM
)) {
1551 /* OpenPrinterEx returns this for a bad
1552 * printer name. We must return WERR_INVALID_PRINTER_NAME
1555 r_u
->status
= WERR_INVALID_PRINTER_NAME
;
1560 /********************************************************************
1561 ********************************************************************/
1563 WERROR
_spoolss_open_printer_ex( pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER_EX
*q_u
, SPOOL_R_OPEN_PRINTER_EX
*r_u
)
1565 PRINTER_DEFAULT
*printer_default
= &q_u
->printer_default
;
1566 POLICY_HND
*handle
= &r_u
->handle
;
1570 Printer_entry
*Printer
=NULL
;
1572 if (!q_u
->printername
) {
1573 return WERR_INVALID_PARAM
;
1576 /* some sanity check because you can open a printer or a print server */
1577 /* aka: \\server\printer or \\server */
1579 unistr2_to_ascii(name
, q_u
->printername
, sizeof(name
));
1581 DEBUGADD(3,("checking name: %s\n",name
));
1583 if (!open_printer_hnd(p
, handle
, name
, 0)) {
1584 return WERR_INVALID_PARAM
;
1587 Printer
=find_printer_index_by_hnd(p
, handle
);
1589 DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer "
1590 "handle we created for printer %s\n", name
));
1591 close_printer_handle(p
,handle
);
1592 return WERR_INVALID_PARAM
;
1596 * First case: the user is opening the print server:
1598 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1599 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1601 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1602 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1603 * or if the user is listed in the smb.conf printer admin parameter.
1605 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1606 * client view printer folder, but does not show the MSAPW.
1608 * Note: this test needs code to check access rights here too. Jeremy
1609 * could you look at this?
1611 * Second case: the user is opening a printer:
1612 * NT doesn't let us connect to a printer if the connecting user
1613 * doesn't have print permission.
1615 * Third case: user is opening a Port Monitor
1616 * access checks same as opening a handle to the print server.
1619 switch (Printer
->printer_type
)
1622 case SPLHND_PORTMON_TCP
:
1623 case SPLHND_PORTMON_LOCAL
:
1624 /* Printserver handles use global struct... */
1628 /* Map standard access rights to object specific access rights */
1630 se_map_standard(&printer_default
->access_required
,
1631 &printserver_std_mapping
);
1633 /* Deny any object specific bits that don't apply to print
1634 servers (i.e printer and job specific bits) */
1636 printer_default
->access_required
&= SPECIFIC_RIGHTS_MASK
;
1638 if (printer_default
->access_required
&
1639 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1640 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1641 close_printer_handle(p
, handle
);
1642 return WERR_ACCESS_DENIED
;
1645 /* Allow admin access */
1647 if ( printer_default
->access_required
& SERVER_ACCESS_ADMINISTER
)
1649 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
1651 if (!lp_ms_add_printer_wizard()) {
1652 close_printer_handle(p
, handle
);
1653 return WERR_ACCESS_DENIED
;
1656 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1657 and not a printer admin, then fail */
1659 if ((p
->pipe_user
.ut
.uid
!= 0) &&
1660 !user_has_privileges(p
->pipe_user
.nt_user_token
,
1662 !token_contains_name_in_list(
1663 uidtoname(p
->pipe_user
.ut
.uid
), NULL
,
1664 p
->pipe_user
.nt_user_token
,
1665 lp_printer_admin(snum
))) {
1666 close_printer_handle(p
, handle
);
1667 return WERR_ACCESS_DENIED
;
1670 printer_default
->access_required
= SERVER_ACCESS_ADMINISTER
;
1674 printer_default
->access_required
= SERVER_ACCESS_ENUMERATE
;
1677 DEBUG(4,("Setting print server access = %s\n", (printer_default
->access_required
== SERVER_ACCESS_ADMINISTER
)
1678 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1680 /* We fall through to return WERR_OK */
1683 case SPLHND_PRINTER
:
1684 /* NT doesn't let us connect to a printer if the connecting user
1685 doesn't have print permission. */
1687 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
1688 close_printer_handle(p
, handle
);
1692 se_map_standard(&printer_default
->access_required
, &printer_std_mapping
);
1694 /* map an empty access mask to the minimum access mask */
1695 if (printer_default
->access_required
== 0x0)
1696 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1699 * If we are not serving the printer driver for this printer,
1700 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1701 * will keep NT clients happy --jerry
1704 if (lp_use_client_driver(snum
)
1705 && (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
))
1707 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1710 /* check smb.conf parameters and the the sec_desc */
1712 if ( !check_access(smbd_server_fd(), lp_hostsallow(snum
), lp_hostsdeny(snum
)) ) {
1713 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1714 return WERR_ACCESS_DENIED
;
1717 if (!user_ok_token(uidtoname(p
->pipe_user
.ut
.uid
),
1718 p
->pipe_user
.nt_user_token
, snum
) ||
1719 !print_access_check(&p
->pipe_user
, snum
,
1720 printer_default
->access_required
)) {
1721 DEBUG(3, ("access DENIED for printer open\n"));
1722 close_printer_handle(p
, handle
);
1723 return WERR_ACCESS_DENIED
;
1726 if ((printer_default
->access_required
& SPECIFIC_RIGHTS_MASK
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1727 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1728 close_printer_handle(p
, handle
);
1729 return WERR_ACCESS_DENIED
;
1732 if (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
)
1733 printer_default
->access_required
= PRINTER_ACCESS_ADMINISTER
;
1735 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1737 DEBUG(4,("Setting printer access = %s\n", (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1738 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1743 /* sanity check to prevent programmer error */
1747 Printer
->access_granted
= printer_default
->access_required
;
1750 * If the client sent a devmode in the OpenPrinter() call, then
1751 * save it here in case we get a job submission on this handle
1754 if ( (Printer
->printer_type
!= SPLHND_SERVER
)
1755 && q_u
->printer_default
.devmode_cont
.devmode_ptr
)
1757 convert_devicemode( Printer
->sharename
, q_u
->printer_default
.devmode_cont
.devmode
,
1758 &Printer
->nt_devmode
);
1761 #if 0 /* JERRY -- I'm doubtful this is really effective */
1762 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1763 optimization in Windows 2000 clients --jerry */
1765 if ( (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1766 && (RA_WIN2K
== get_remote_arch()) )
1768 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
1769 sys_usleep( 500000 );
1776 /****************************************************************************
1777 ****************************************************************************/
1779 static bool convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
1780 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
1786 /* allocate memory if needed. Messy because
1787 convert_printer_info is used to update an existing
1788 printer or build a new one */
1790 if ( !printer
->info_2
) {
1791 printer
->info_2
= TALLOC_ZERO_P( printer
, NT_PRINTER_INFO_LEVEL_2
);
1792 if ( !printer
->info_2
) {
1793 DEBUG(0,("convert_printer_info: talloc() failed!\n"));
1798 ret
= uni_2_asc_printer_info_2(uni
->info_2
, printer
->info_2
);
1799 printer
->info_2
->setuptime
= time(NULL
);
1807 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
1808 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
1814 printer
->info_3
=NULL
;
1815 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
1819 printer
->info_6
=NULL
;
1820 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
1830 bool convert_devicemode(const char *printername
, const DEVICEMODE
*devmode
,
1831 NT_DEVICEMODE
**pp_nt_devmode
)
1833 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1836 * Ensure nt_devmode is a valid pointer
1837 * as we will be overwriting it.
1840 if (nt_devmode
== NULL
) {
1841 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1842 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1846 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
1847 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
1849 nt_devmode
->specversion
=devmode
->specversion
;
1850 nt_devmode
->driverversion
=devmode
->driverversion
;
1851 nt_devmode
->size
=devmode
->size
;
1852 nt_devmode
->fields
=devmode
->fields
;
1853 nt_devmode
->orientation
=devmode
->orientation
;
1854 nt_devmode
->papersize
=devmode
->papersize
;
1855 nt_devmode
->paperlength
=devmode
->paperlength
;
1856 nt_devmode
->paperwidth
=devmode
->paperwidth
;
1857 nt_devmode
->scale
=devmode
->scale
;
1858 nt_devmode
->copies
=devmode
->copies
;
1859 nt_devmode
->defaultsource
=devmode
->defaultsource
;
1860 nt_devmode
->printquality
=devmode
->printquality
;
1861 nt_devmode
->color
=devmode
->color
;
1862 nt_devmode
->duplex
=devmode
->duplex
;
1863 nt_devmode
->yresolution
=devmode
->yresolution
;
1864 nt_devmode
->ttoption
=devmode
->ttoption
;
1865 nt_devmode
->collate
=devmode
->collate
;
1867 nt_devmode
->logpixels
=devmode
->logpixels
;
1868 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
1869 nt_devmode
->pelswidth
=devmode
->pelswidth
;
1870 nt_devmode
->pelsheight
=devmode
->pelsheight
;
1871 nt_devmode
->displayflags
=devmode
->displayflags
;
1872 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
1873 nt_devmode
->icmmethod
=devmode
->icmmethod
;
1874 nt_devmode
->icmintent
=devmode
->icmintent
;
1875 nt_devmode
->mediatype
=devmode
->mediatype
;
1876 nt_devmode
->dithertype
=devmode
->dithertype
;
1877 nt_devmode
->reserved1
=devmode
->reserved1
;
1878 nt_devmode
->reserved2
=devmode
->reserved2
;
1879 nt_devmode
->panningwidth
=devmode
->panningwidth
;
1880 nt_devmode
->panningheight
=devmode
->panningheight
;
1883 * Only change private and driverextra if the incoming devmode
1884 * has a new one. JRA.
1887 if ((devmode
->driverextra
!= 0) && (devmode
->dev_private
!= NULL
)) {
1888 SAFE_FREE(nt_devmode
->nt_dev_private
);
1889 nt_devmode
->driverextra
=devmode
->driverextra
;
1890 if((nt_devmode
->nt_dev_private
=SMB_MALLOC_ARRAY(uint8
, nt_devmode
->driverextra
)) == NULL
)
1892 memcpy(nt_devmode
->nt_dev_private
, devmode
->dev_private
, nt_devmode
->driverextra
);
1895 *pp_nt_devmode
= nt_devmode
;
1900 /********************************************************************
1901 * _spoolss_enddocprinter_internal.
1902 ********************************************************************/
1904 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1906 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1910 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
1914 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
1917 Printer
->document_started
=False
;
1918 print_job_end(snum
, Printer
->jobid
,NORMAL_CLOSE
);
1919 /* error codes unhandled so far ... */
1924 /********************************************************************
1925 * api_spoolss_closeprinter
1926 ********************************************************************/
1928 WERROR
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
1930 POLICY_HND
*handle
= &q_u
->handle
;
1932 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1934 if (Printer
&& Printer
->document_started
)
1935 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1937 if (!close_printer_handle(p
, handle
))
1940 /* clear the returned printer handle. Observed behavior
1941 from Win2k server. Don't think this really matters.
1942 Previous code just copied the value of the closed
1945 memset(&r_u
->handle
, '\0', sizeof(r_u
->handle
));
1950 /********************************************************************
1951 * api_spoolss_deleteprinter
1953 ********************************************************************/
1955 WERROR
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
1957 POLICY_HND
*handle
= &q_u
->handle
;
1958 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1961 if (Printer
&& Printer
->document_started
)
1962 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1964 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1966 result
= delete_printer_handle(p
, handle
);
1968 update_c_setprinter(False
);
1973 /*******************************************************************
1974 * static function to lookup the version id corresponding to an
1975 * long architecture string
1976 ******************************************************************/
1978 static int get_version_id (char * arch
)
1981 struct table_node archi_table
[]= {
1983 {"Windows 4.0", "WIN40", 0 },
1984 {"Windows NT x86", "W32X86", 2 },
1985 {"Windows NT R4000", "W32MIPS", 2 },
1986 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1987 {"Windows NT PowerPC", "W32PPC", 2 },
1988 {"Windows IA64", "IA64", 3 },
1989 {"Windows x64", "x64", 3 },
1993 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1995 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1996 return (archi_table
[i
].version
);
2002 /********************************************************************
2003 * _spoolss_deleteprinterdriver
2004 ********************************************************************/
2006 WERROR
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
, SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
2010 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2011 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2014 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2015 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2017 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2018 and not a printer admin, then fail */
2020 if ( (p
->pipe_user
.ut
.uid
!= 0)
2021 && !user_has_privileges(p
->pipe_user
.nt_user_token
, &se_printop
)
2022 && !token_contains_name_in_list( uidtoname(p
->pipe_user
.ut
.uid
),
2023 NULL
, p
->pipe_user
.nt_user_token
, lp_printer_admin(-1)) )
2025 return WERR_ACCESS_DENIED
;
2028 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
));
2029 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
));
2031 /* check that we have a valid driver name first */
2033 if ((version
=get_version_id(arch
)) == -1)
2034 return WERR_INVALID_ENVIRONMENT
;
2037 ZERO_STRUCT(info_win2k
);
2039 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
)))
2041 /* try for Win2k driver if "Windows NT x86" */
2043 if ( version
== 2 ) {
2045 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2046 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2050 /* otherwise it was a failure */
2052 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2058 if (printer_driver_in_use(info
.info_3
)) {
2059 status
= WERR_PRINTER_DRIVER_IN_USE
;
2065 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2067 /* if we get to here, we now have 2 driver info structures to remove */
2068 /* remove the Win2k driver first*/
2070 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &p
->pipe_user
, 3, False
);
2071 free_a_printer_driver( info_win2k
, 3 );
2073 /* this should not have failed---if it did, report to client */
2074 if ( !W_ERROR_IS_OK(status_win2k
) )
2076 status
= status_win2k
;
2082 status
= delete_printer_driver(info
.info_3
, &p
->pipe_user
, version
, False
);
2084 /* if at least one of the deletes succeeded return OK */
2086 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2090 free_a_printer_driver( info
, 3 );
2095 /********************************************************************
2096 * spoolss_deleteprinterdriverex
2097 ********************************************************************/
2099 WERROR
_spoolss_deleteprinterdriverex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVEREX
*q_u
, SPOOL_R_DELETEPRINTERDRIVEREX
*r_u
)
2103 NT_PRINTER_DRIVER_INFO_LEVEL info
;
2104 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
2106 uint32 flags
= q_u
->delete_flags
;
2109 WERROR status_win2k
= WERR_ACCESS_DENIED
;
2110 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
2112 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2113 and not a printer admin, then fail */
2115 if ( (p
->pipe_user
.ut
.uid
!= 0)
2116 && !user_has_privileges(p
->pipe_user
.nt_user_token
, &se_printop
)
2117 && !token_contains_name_in_list( uidtoname(p
->pipe_user
.ut
.uid
),
2118 NULL
, p
->pipe_user
.nt_user_token
, lp_printer_admin(-1)) )
2120 return WERR_ACCESS_DENIED
;
2123 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
));
2124 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
));
2126 /* check that we have a valid driver name first */
2127 if ((version
=get_version_id(arch
)) == -1) {
2128 /* this is what NT returns */
2129 return WERR_INVALID_ENVIRONMENT
;
2132 if ( flags
& DPD_DELETE_SPECIFIC_VERSION
)
2133 version
= q_u
->version
;
2136 ZERO_STRUCT(info_win2k
);
2138 status
= get_a_printer_driver(&info
, 3, driver
, arch
, version
);
2140 if ( !W_ERROR_IS_OK(status
) )
2143 * if the client asked for a specific version,
2144 * or this is something other than Windows NT x86,
2148 if ( (flags
&DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
2151 /* try for Win2k driver if "Windows NT x86" */
2154 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
2155 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
2160 if ( printer_driver_in_use(info
.info_3
) ) {
2161 status
= WERR_PRINTER_DRIVER_IN_USE
;
2166 * we have a couple of cases to consider.
2167 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2168 * then the delete should fail if **any** files overlap with
2170 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2171 * non-overlapping files
2172 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2173 * is set, the do not delete any files
2174 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2177 delete_files
= flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
2179 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2181 if ( delete_files
&& printer_driver_files_in_use(info
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2182 /* no idea of the correct error here */
2183 status
= WERR_ACCESS_DENIED
;
2188 /* also check for W32X86/3 if necessary; maybe we already have? */
2190 if ( (version
== 2) && ((flags
&DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2191 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2194 if ( delete_files
&& printer_driver_files_in_use(info_win2k
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2195 /* no idea of the correct error here */
2196 free_a_printer_driver( info_win2k
, 3 );
2197 status
= WERR_ACCESS_DENIED
;
2201 /* if we get to here, we now have 2 driver info structures to remove */
2202 /* remove the Win2k driver first*/
2204 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &p
->pipe_user
, 3, delete_files
);
2205 free_a_printer_driver( info_win2k
, 3 );
2207 /* this should not have failed---if it did, report to client */
2209 if ( !W_ERROR_IS_OK(status_win2k
) )
2214 status
= delete_printer_driver(info
.info_3
, &p
->pipe_user
, version
, delete_files
);
2216 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2219 free_a_printer_driver( info
, 3 );
2225 /****************************************************************************
2226 Internal routine for retreiving printerdata
2227 ***************************************************************************/
2229 static WERROR
get_printer_dataex( TALLOC_CTX
*ctx
, NT_PRINTER_INFO_LEVEL
*printer
,
2230 const char *key
, const char *value
, uint32
*type
, uint8
**data
,
2231 uint32
*needed
, uint32 in_size
)
2233 REGISTRY_VALUE
*val
;
2237 if ( !(val
= get_printer_data( printer
->info_2
, key
, value
)) )
2238 return WERR_BADFILE
;
2240 *type
= regval_type( val
);
2242 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size
));
2244 size
= regval_size( val
);
2246 /* copy the min(in_size, len) */
2249 data_len
= (size
> in_size
) ? in_size
: size
*sizeof(uint8
);
2251 /* special case for 0 length values */
2253 if ( (*data
= (uint8
*)TALLOC_MEMDUP(ctx
, regval_data_p(val
), data_len
)) == NULL
)
2257 if ( (*data
= (uint8
*)TALLOC_ZERO(ctx
, in_size
)) == NULL
)
2266 DEBUG(5,("get_printer_dataex: copy done\n"));
2271 /****************************************************************************
2272 Internal routine for removing printerdata
2273 ***************************************************************************/
2275 static WERROR
delete_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
)
2277 return delete_printer_data( printer
->info_2
, key
, value
);
2280 /****************************************************************************
2281 Internal routine for storing printerdata
2282 ***************************************************************************/
2284 WERROR
set_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, const char *key
, const char *value
,
2285 uint32 type
, uint8
*data
, int real_len
)
2287 /* the registry objects enforce uniqueness based on value name */
2289 return add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
2292 /********************************************************************
2293 GetPrinterData on a printer server Handle.
2294 ********************************************************************/
2296 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
2300 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2302 if (!StrCaseCmp(value
, "W3SvcInstalled")) {
2304 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2306 SIVAL(*data
, 0, 0x00);
2311 if (!StrCaseCmp(value
, "BeepEnabled")) {
2313 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2315 SIVAL(*data
, 0, 0x00);
2320 if (!StrCaseCmp(value
, "EventLog")) {
2322 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2324 /* formally was 0x1b */
2325 SIVAL(*data
, 0, 0x0);
2330 if (!StrCaseCmp(value
, "NetPopup")) {
2332 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2334 SIVAL(*data
, 0, 0x00);
2339 if (!StrCaseCmp(value
, "MajorVersion")) {
2341 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2344 /* Windows NT 4.0 seems to not allow uploading of drivers
2345 to a server that reports 0x3 as the MajorVersion.
2346 need to investigate more how Win2k gets around this .
2349 if ( RA_WINNT
== get_remote_arch() )
2358 if (!StrCaseCmp(value
, "MinorVersion")) {
2360 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2368 * uint32 size = 0x114
2370 * uint32 minor = [0|1]
2371 * uint32 build = [2195|2600]
2372 * extra unicode string = e.g. "Service Pack 3"
2374 if (!StrCaseCmp(value
, "OSVersion")) {
2378 if ( !(*data
= TALLOC_ZERO_ARRAY(ctx
, uint8
, (*needed
> in_size
) ? *needed
:in_size
)) )
2381 SIVAL(*data
, 0, *needed
); /* size */
2382 SIVAL(*data
, 4, 5); /* Windows 2000 == 5.0 */
2384 SIVAL(*data
, 12, 2195); /* build */
2386 /* leave extra string empty */
2392 if (!StrCaseCmp(value
, "DefaultSpoolDirectory")) {
2393 const char *string
="C:\\PRINTERS";
2395 *needed
= 2*(strlen(string
)+1);
2396 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2398 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2400 /* it's done by hand ready to go on the wire */
2401 for (i
=0; i
<strlen(string
); i
++) {
2402 (*data
)[2*i
]=string
[i
];
2403 (*data
)[2*i
+1]='\0';
2408 if (!StrCaseCmp(value
, "Architecture")) {
2409 const char *string
="Windows NT x86";
2411 *needed
= 2*(strlen(string
)+1);
2412 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2414 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2415 for (i
=0; i
<strlen(string
); i
++) {
2416 (*data
)[2*i
]=string
[i
];
2417 (*data
)[2*i
+1]='\0';
2422 if (!StrCaseCmp(value
, "DsPresent")) {
2424 if ( !(*data
= TALLOC_ARRAY(ctx
, uint8
, sizeof(uint32
) )) )
2427 /* only show the publish check box if we are a
2428 memeber of a AD domain */
2430 if ( lp_security() == SEC_ADS
)
2431 SIVAL(*data
, 0, 0x01);
2433 SIVAL(*data
, 0, 0x00);
2439 if (!StrCaseCmp(value
, "DNSMachineName")) {
2440 const char *hostname
= get_mydnsfullname();
2443 return WERR_BADFILE
;
2445 *needed
= 2*(strlen(hostname
)+1);
2446 if((*data
= (uint8
*)TALLOC(ctx
, (*needed
> in_size
) ? *needed
:in_size
)) == NULL
)
2448 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2449 for (i
=0; i
<strlen(hostname
); i
++) {
2450 (*data
)[2*i
]=hostname
[i
];
2451 (*data
)[2*i
+1]='\0';
2457 return WERR_BADFILE
;
2460 /********************************************************************
2461 * spoolss_getprinterdata
2462 ********************************************************************/
2464 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
2466 POLICY_HND
*handle
= &q_u
->handle
;
2467 UNISTR2
*valuename
= &q_u
->valuename
;
2468 uint32 in_size
= q_u
->size
;
2469 uint32
*type
= &r_u
->type
;
2470 uint32
*out_size
= &r_u
->size
;
2471 uint8
**data
= &r_u
->data
;
2472 uint32
*needed
= &r_u
->needed
;
2475 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
2476 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2480 * Reminder: when it's a string, the length is in BYTES
2481 * even if UNICODE is negociated.
2486 *out_size
= in_size
;
2488 /* in case of problem, return some default values */
2493 DEBUG(4,("_spoolss_getprinterdata\n"));
2496 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2497 status
= WERR_BADFID
;
2501 unistr2_to_ascii(value
, valuename
, sizeof(value
));
2503 if ( Printer
->printer_type
== SPLHND_SERVER
)
2504 status
= getprinterdata_printer_server( p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
2507 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) ) {
2508 status
= WERR_BADFID
;
2512 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
2513 if ( !W_ERROR_IS_OK(status
) )
2516 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2518 if ( strequal(value
, "ChangeId") ) {
2520 *needed
= sizeof(uint32
);
2521 if ( (*data
= (uint8
*)TALLOC(p
->mem_ctx
, sizeof(uint32
))) == NULL
) {
2522 status
= WERR_NOMEM
;
2525 SIVAL( *data
, 0, printer
->info_2
->changeid
);
2529 status
= get_printer_dataex( p
->mem_ctx
, printer
, SPOOL_PRINTERDATA_KEY
, value
, type
, data
, needed
, *out_size
);
2532 if (*needed
> *out_size
)
2533 status
= WERR_MORE_DATA
;
2536 if ( !W_ERROR_IS_OK(status
) )
2538 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status
),*out_size
));
2540 /* reply this param doesn't exist */
2543 if((*data
=(uint8
*)TALLOC_ZERO_ARRAY(p
->mem_ctx
, uint8
, *out_size
)) == NULL
) {
2545 free_a_printer( &printer
, 2 );
2553 /* cleanup & exit */
2556 free_a_printer( &printer
, 2 );
2561 /*********************************************************
2562 Connect to the client machine.
2563 **********************************************************/
2565 static bool spoolss_connect_to_client(struct rpc_pipe_client
**pp_pipe
,
2566 struct sockaddr_storage
*client_ss
, const char *remote_machine
)
2569 struct cli_state
*the_cli
;
2570 struct sockaddr_storage rm_addr
;
2572 if ( is_zero_addr(client_ss
) ) {
2573 if ( !resolve_name( remote_machine
, &rm_addr
, 0x20) ) {
2574 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine
));
2578 if (ismyaddr(&rm_addr
)) {
2579 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine
));
2583 char addr
[INET6_ADDRSTRLEN
];
2584 rm_addr
= *client_ss
;
2585 print_sockaddr(addr
, sizeof(addr
), &rm_addr
);
2586 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2590 /* setup the connection */
2592 ret
= cli_full_connection( &the_cli
, global_myname(), remote_machine
,
2593 &rm_addr
, 0, "IPC$", "IPC",
2597 0, lp_client_signing(), NULL
);
2599 if ( !NT_STATUS_IS_OK( ret
) ) {
2600 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2605 if ( the_cli
->protocol
!= PROTOCOL_NT1
) {
2606 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2607 cli_shutdown(the_cli
);
2612 * Ok - we have an anonymous connection to the IPC$ share.
2613 * Now start the NT Domain stuff :-).
2616 if ( !(*pp_pipe
= cli_rpc_pipe_open_noauth(the_cli
, PI_SPOOLSS
, &ret
)) ) {
2617 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2618 remote_machine
, nt_errstr(ret
)));
2619 cli_shutdown(the_cli
);
2623 /* make sure to save the cli_state pointer. Keep its own talloc_ctx */
2625 (*pp_pipe
)->cli
= the_cli
;
2630 /***************************************************************************
2631 Connect to the client.
2632 ****************************************************************************/
2634 static bool srv_spoolss_replyopenprinter(int snum
, const char *printer
,
2635 uint32 localprinter
, uint32 type
,
2636 POLICY_HND
*handle
, struct sockaddr_storage
*client_ss
)
2641 * If it's the first connection, contact the client
2642 * and connect to the IPC$ share anonymously
2644 if (smb_connections
==0) {
2645 fstring unix_printer
;
2647 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2649 if ( !spoolss_connect_to_client( ¬ify_cli_pipe
, client_ss
, unix_printer
))
2652 messaging_register(smbd_messaging_context(), NULL
,
2653 MSG_PRINTER_NOTIFY2
,
2654 receive_notify2_message_list
);
2655 /* Tell the connections db we're now interested in printer
2656 * notify messages. */
2657 register_message_flags( True
, FLAG_MSG_PRINT_NOTIFY
);
2661 * Tell the specific printing tdb we want messages for this printer
2662 * by registering our PID.
2665 if (!print_notify_register_pid(snum
))
2666 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer
));
2670 result
= rpccli_spoolss_reply_open_printer(notify_cli_pipe
,
2677 if (!W_ERROR_IS_OK(result
))
2678 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2679 dos_errstr(result
)));
2681 return (W_ERROR_IS_OK(result
));
2684 /********************************************************************
2686 * ReplyFindFirstPrinterChangeNotifyEx
2688 * before replying OK: status=0 a rpc call is made to the workstation
2689 * asking ReplyOpenPrinter
2691 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2692 * called from api_spoolss_rffpcnex
2693 ********************************************************************/
2695 WERROR
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
2697 POLICY_HND
*handle
= &q_u
->handle
;
2698 uint32 flags
= q_u
->flags
;
2699 uint32 options
= q_u
->options
;
2700 UNISTR2
*localmachine
= &q_u
->localmachine
;
2701 uint32 printerlocal
= q_u
->printerlocal
;
2703 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
2704 struct sockaddr_storage client_ss
;
2706 /* store the notify value in the printer struct */
2708 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2711 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2715 Printer
->notify
.flags
=flags
;
2716 Printer
->notify
.options
=options
;
2717 Printer
->notify
.printerlocal
=printerlocal
;
2719 if (Printer
->notify
.option
)
2720 free_spool_notify_option(&Printer
->notify
.option
);
2722 Printer
->notify
.option
=dup_spool_notify_option(option
);
2724 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
,
2725 sizeof(Printer
->notify
.localmachine
));
2727 /* Connect to the client machine and send a ReplyOpenPrinter */
2729 if ( Printer
->printer_type
== SPLHND_SERVER
)
2731 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
2732 !get_printer_snum(p
, handle
, &snum
, NULL
) )
2735 if (!interpret_string_addr(&client_ss
,
2736 p
->conn
->client_address
,
2738 return WERR_SERVER_UNAVAILABLE
;
2741 if(!srv_spoolss_replyopenprinter(snum
, Printer
->notify
.localmachine
,
2742 Printer
->notify
.printerlocal
, 1,
2743 &Printer
->notify
.client_hnd
, &client_ss
))
2744 return WERR_SERVER_UNAVAILABLE
;
2746 Printer
->notify
.client_connected
=True
;
2751 /*******************************************************************
2752 * fill a notify_info_data with the servername
2753 ********************************************************************/
2755 void spoolss_notify_server_name(int snum
,
2756 SPOOL_NOTIFY_INFO_DATA
*data
,
2757 print_queue_struct
*queue
,
2758 NT_PRINTER_INFO_LEVEL
*printer
,
2759 TALLOC_CTX
*mem_ctx
)
2761 smb_ucs2_t
*temp
= NULL
;
2764 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->servername
);
2765 if (len
== (uint32
)-1) {
2769 data
->notify_data
.data
.length
= len
;
2771 data
->notify_data
.data
.string
= (uint16
*)temp
;
2773 data
->notify_data
.data
.string
= NULL
;
2777 /*******************************************************************
2778 * fill a notify_info_data with the printername (not including the servername).
2779 ********************************************************************/
2781 void spoolss_notify_printer_name(int snum
,
2782 SPOOL_NOTIFY_INFO_DATA
*data
,
2783 print_queue_struct
*queue
,
2784 NT_PRINTER_INFO_LEVEL
*printer
,
2785 TALLOC_CTX
*mem_ctx
)
2787 smb_ucs2_t
*temp
= NULL
;
2790 /* the notify name should not contain the \\server\ part */
2791 char *p
= strrchr(printer
->info_2
->printername
, '\\');
2794 p
= printer
->info_2
->printername
;
2799 len
= rpcstr_push_talloc(mem_ctx
, &temp
, p
);
2800 if (len
== (uint32
)-1) {
2804 data
->notify_data
.data
.length
= len
;
2806 data
->notify_data
.data
.string
= (uint16
*)temp
;
2808 data
->notify_data
.data
.string
= NULL
;
2812 /*******************************************************************
2813 * fill a notify_info_data with the servicename
2814 ********************************************************************/
2816 void spoolss_notify_share_name(int snum
,
2817 SPOOL_NOTIFY_INFO_DATA
*data
,
2818 print_queue_struct
*queue
,
2819 NT_PRINTER_INFO_LEVEL
*printer
,
2820 TALLOC_CTX
*mem_ctx
)
2822 smb_ucs2_t
*temp
= NULL
;
2825 len
= rpcstr_push_talloc(mem_ctx
, &temp
, lp_servicename(snum
));
2826 if (len
== (uint32
)-1) {
2830 data
->notify_data
.data
.length
= len
;
2832 data
->notify_data
.data
.string
= (uint16
*)temp
;
2834 data
->notify_data
.data
.string
= NULL
;
2839 /*******************************************************************
2840 * fill a notify_info_data with the port name
2841 ********************************************************************/
2843 void spoolss_notify_port_name(int snum
,
2844 SPOOL_NOTIFY_INFO_DATA
*data
,
2845 print_queue_struct
*queue
,
2846 NT_PRINTER_INFO_LEVEL
*printer
,
2847 TALLOC_CTX
*mem_ctx
)
2849 smb_ucs2_t
*temp
= NULL
;
2852 /* even if it's strange, that's consistant in all the code */
2854 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->portname
);
2855 if (len
== (uint32
)-1) {
2859 data
->notify_data
.data
.length
= len
;
2861 data
->notify_data
.data
.string
= (uint16
*)temp
;
2863 data
->notify_data
.data
.string
= NULL
;
2867 /*******************************************************************
2868 * fill a notify_info_data with the printername
2869 * but it doesn't exist, have to see what to do
2870 ********************************************************************/
2872 void spoolss_notify_driver_name(int snum
,
2873 SPOOL_NOTIFY_INFO_DATA
*data
,
2874 print_queue_struct
*queue
,
2875 NT_PRINTER_INFO_LEVEL
*printer
,
2876 TALLOC_CTX
*mem_ctx
)
2878 smb_ucs2_t
*temp
= NULL
;
2881 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->drivername
);
2882 if (len
== (uint32
)-1) {
2886 data
->notify_data
.data
.length
= len
;
2888 data
->notify_data
.data
.string
= (uint16
*)temp
;
2890 data
->notify_data
.data
.string
= NULL
;
2894 /*******************************************************************
2895 * fill a notify_info_data with the comment
2896 ********************************************************************/
2898 void spoolss_notify_comment(int snum
,
2899 SPOOL_NOTIFY_INFO_DATA
*data
,
2900 print_queue_struct
*queue
,
2901 NT_PRINTER_INFO_LEVEL
*printer
,
2902 TALLOC_CTX
*mem_ctx
)
2904 smb_ucs2_t
*temp
= NULL
;
2907 if (*printer
->info_2
->comment
== '\0')
2908 len
= rpcstr_push_talloc(mem_ctx
, &temp
, lp_comment(snum
));
2910 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->comment
);
2912 if (len
== (uint32
)-1) {
2915 data
->notify_data
.data
.length
= len
;
2917 data
->notify_data
.data
.string
= (uint16
*)temp
;
2919 data
->notify_data
.data
.string
= NULL
;
2923 /*******************************************************************
2924 * fill a notify_info_data with the comment
2925 * location = "Room 1, floor 2, building 3"
2926 ********************************************************************/
2928 void spoolss_notify_location(int snum
,
2929 SPOOL_NOTIFY_INFO_DATA
*data
,
2930 print_queue_struct
*queue
,
2931 NT_PRINTER_INFO_LEVEL
*printer
,
2932 TALLOC_CTX
*mem_ctx
)
2934 smb_ucs2_t
*temp
= NULL
;
2937 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->location
);
2938 if (len
== (uint32
)-1) {
2942 data
->notify_data
.data
.length
= len
;
2944 data
->notify_data
.data
.string
= (uint16
*)temp
;
2946 data
->notify_data
.data
.string
= NULL
;
2950 /*******************************************************************
2951 * fill a notify_info_data with the device mode
2952 * jfm:xxxx don't to it for know but that's a real problem !!!
2953 ********************************************************************/
2955 static void spoolss_notify_devmode(int snum
,
2956 SPOOL_NOTIFY_INFO_DATA
*data
,
2957 print_queue_struct
*queue
,
2958 NT_PRINTER_INFO_LEVEL
*printer
,
2959 TALLOC_CTX
*mem_ctx
)
2961 /* for a dummy implementation we have to zero the fields */
2962 data
->notify_data
.data
.length
= 0;
2963 data
->notify_data
.data
.string
= NULL
;
2966 /*******************************************************************
2967 * fill a notify_info_data with the separator file name
2968 ********************************************************************/
2970 void spoolss_notify_sepfile(int snum
,
2971 SPOOL_NOTIFY_INFO_DATA
*data
,
2972 print_queue_struct
*queue
,
2973 NT_PRINTER_INFO_LEVEL
*printer
,
2974 TALLOC_CTX
*mem_ctx
)
2976 smb_ucs2_t
*temp
= NULL
;
2979 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->sepfile
);
2980 if (len
== (uint32
)-1) {
2984 data
->notify_data
.data
.length
= len
;
2986 data
->notify_data
.data
.string
= (uint16
*)temp
;
2988 data
->notify_data
.data
.string
= NULL
;
2992 /*******************************************************************
2993 * fill a notify_info_data with the print processor
2994 * jfm:xxxx return always winprint to indicate we don't do anything to it
2995 ********************************************************************/
2997 void spoolss_notify_print_processor(int snum
,
2998 SPOOL_NOTIFY_INFO_DATA
*data
,
2999 print_queue_struct
*queue
,
3000 NT_PRINTER_INFO_LEVEL
*printer
,
3001 TALLOC_CTX
*mem_ctx
)
3003 smb_ucs2_t
*temp
= NULL
;
3006 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->printprocessor
);
3007 if (len
== (uint32
)-1) {
3011 data
->notify_data
.data
.length
= len
;
3013 data
->notify_data
.data
.string
= (uint16
*)temp
;
3015 data
->notify_data
.data
.string
= NULL
;
3019 /*******************************************************************
3020 * fill a notify_info_data with the print processor options
3021 * jfm:xxxx send an empty string
3022 ********************************************************************/
3024 void spoolss_notify_parameters(int snum
,
3025 SPOOL_NOTIFY_INFO_DATA
*data
,
3026 print_queue_struct
*queue
,
3027 NT_PRINTER_INFO_LEVEL
*printer
,
3028 TALLOC_CTX
*mem_ctx
)
3030 smb_ucs2_t
*temp
= NULL
;
3033 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->parameters
);
3034 if (len
== (uint32
)-1) {
3038 data
->notify_data
.data
.length
= len
;
3040 data
->notify_data
.data
.string
= (uint16
*)temp
;
3042 data
->notify_data
.data
.string
= NULL
;
3046 /*******************************************************************
3047 * fill a notify_info_data with the data type
3048 * jfm:xxxx always send RAW as data type
3049 ********************************************************************/
3051 void spoolss_notify_datatype(int snum
,
3052 SPOOL_NOTIFY_INFO_DATA
*data
,
3053 print_queue_struct
*queue
,
3054 NT_PRINTER_INFO_LEVEL
*printer
,
3055 TALLOC_CTX
*mem_ctx
)
3057 smb_ucs2_t
*temp
= NULL
;
3060 len
= rpcstr_push_talloc(mem_ctx
, &temp
, printer
->info_2
->datatype
);
3061 if (len
== (uint32
)-1) {
3065 data
->notify_data
.data
.length
= len
;
3067 data
->notify_data
.data
.string
= (uint16
*)temp
;
3069 data
->notify_data
.data
.string
= NULL
;
3073 /*******************************************************************
3074 * fill a notify_info_data with the security descriptor
3075 * jfm:xxxx send an null pointer to say no security desc
3076 * have to implement security before !
3077 ********************************************************************/
3079 static void spoolss_notify_security_desc(int snum
,
3080 SPOOL_NOTIFY_INFO_DATA
*data
,
3081 print_queue_struct
*queue
,
3082 NT_PRINTER_INFO_LEVEL
*printer
,
3083 TALLOC_CTX
*mem_ctx
)
3085 data
->notify_data
.sd
.size
= printer
->info_2
->secdesc_buf
->sd_size
;
3086 data
->notify_data
.sd
.desc
= dup_sec_desc( mem_ctx
, printer
->info_2
->secdesc_buf
->sd
) ;
3089 /*******************************************************************
3090 * fill a notify_info_data with the attributes
3091 * jfm:xxxx a samba printer is always shared
3092 ********************************************************************/
3094 void spoolss_notify_attributes(int snum
,
3095 SPOOL_NOTIFY_INFO_DATA
*data
,
3096 print_queue_struct
*queue
,
3097 NT_PRINTER_INFO_LEVEL
*printer
,
3098 TALLOC_CTX
*mem_ctx
)
3100 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
3101 data
->notify_data
.value
[1] = 0;
3104 /*******************************************************************
3105 * fill a notify_info_data with the priority
3106 ********************************************************************/
3108 static void spoolss_notify_priority(int snum
,
3109 SPOOL_NOTIFY_INFO_DATA
*data
,
3110 print_queue_struct
*queue
,
3111 NT_PRINTER_INFO_LEVEL
*printer
,
3112 TALLOC_CTX
*mem_ctx
)
3114 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
3115 data
->notify_data
.value
[1] = 0;
3118 /*******************************************************************
3119 * fill a notify_info_data with the default priority
3120 ********************************************************************/
3122 static void spoolss_notify_default_priority(int snum
,
3123 SPOOL_NOTIFY_INFO_DATA
*data
,
3124 print_queue_struct
*queue
,
3125 NT_PRINTER_INFO_LEVEL
*printer
,
3126 TALLOC_CTX
*mem_ctx
)
3128 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
3129 data
->notify_data
.value
[1] = 0;
3132 /*******************************************************************
3133 * fill a notify_info_data with the start time
3134 ********************************************************************/
3136 static void spoolss_notify_start_time(int snum
,
3137 SPOOL_NOTIFY_INFO_DATA
*data
,
3138 print_queue_struct
*queue
,
3139 NT_PRINTER_INFO_LEVEL
*printer
,
3140 TALLOC_CTX
*mem_ctx
)
3142 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
3143 data
->notify_data
.value
[1] = 0;
3146 /*******************************************************************
3147 * fill a notify_info_data with the until time
3148 ********************************************************************/
3150 static void spoolss_notify_until_time(int snum
,
3151 SPOOL_NOTIFY_INFO_DATA
*data
,
3152 print_queue_struct
*queue
,
3153 NT_PRINTER_INFO_LEVEL
*printer
,
3154 TALLOC_CTX
*mem_ctx
)
3156 data
->notify_data
.value
[0] = printer
->info_2
->untiltime
;
3157 data
->notify_data
.value
[1] = 0;
3160 /*******************************************************************
3161 * fill a notify_info_data with the status
3162 ********************************************************************/
3164 static void spoolss_notify_status(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 print_status_struct status
;
3172 print_queue_length(snum
, &status
);
3173 data
->notify_data
.value
[0]=(uint32
) status
.status
;
3174 data
->notify_data
.value
[1] = 0;
3177 /*******************************************************************
3178 * fill a notify_info_data with the number of jobs queued
3179 ********************************************************************/
3181 void spoolss_notify_cjobs(int snum
,
3182 SPOOL_NOTIFY_INFO_DATA
*data
,
3183 print_queue_struct
*queue
,
3184 NT_PRINTER_INFO_LEVEL
*printer
,
3185 TALLOC_CTX
*mem_ctx
)
3187 data
->notify_data
.value
[0] = print_queue_length(snum
, NULL
);
3188 data
->notify_data
.value
[1] = 0;
3191 /*******************************************************************
3192 * fill a notify_info_data with the average ppm
3193 ********************************************************************/
3195 static void spoolss_notify_average_ppm(int snum
,
3196 SPOOL_NOTIFY_INFO_DATA
*data
,
3197 print_queue_struct
*queue
,
3198 NT_PRINTER_INFO_LEVEL
*printer
,
3199 TALLOC_CTX
*mem_ctx
)
3201 /* always respond 8 pages per minutes */
3202 /* a little hard ! */
3203 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
3204 data
->notify_data
.value
[1] = 0;
3207 /*******************************************************************
3208 * fill a notify_info_data with username
3209 ********************************************************************/
3211 static void spoolss_notify_username(int snum
,
3212 SPOOL_NOTIFY_INFO_DATA
*data
,
3213 print_queue_struct
*queue
,
3214 NT_PRINTER_INFO_LEVEL
*printer
,
3215 TALLOC_CTX
*mem_ctx
)
3217 smb_ucs2_t
*temp
= NULL
;
3220 len
= rpcstr_push_talloc(mem_ctx
, &temp
, queue
->fs_user
);
3221 if (len
== (uint32
)-1) {
3225 data
->notify_data
.data
.length
= len
;
3227 data
->notify_data
.data
.string
= (uint16
*)temp
;
3229 data
->notify_data
.data
.string
= NULL
;
3233 /*******************************************************************
3234 * fill a notify_info_data with job status
3235 ********************************************************************/
3237 static void spoolss_notify_job_status(int snum
,
3238 SPOOL_NOTIFY_INFO_DATA
*data
,
3239 print_queue_struct
*queue
,
3240 NT_PRINTER_INFO_LEVEL
*printer
,
3241 TALLOC_CTX
*mem_ctx
)
3243 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
3244 data
->notify_data
.value
[1] = 0;
3247 /*******************************************************************
3248 * fill a notify_info_data with job name
3249 ********************************************************************/
3251 static void spoolss_notify_job_name(int snum
,
3252 SPOOL_NOTIFY_INFO_DATA
*data
,
3253 print_queue_struct
*queue
,
3254 NT_PRINTER_INFO_LEVEL
*printer
,
3255 TALLOC_CTX
*mem_ctx
)
3257 smb_ucs2_t
*temp
= NULL
;
3260 len
= rpcstr_push_talloc(mem_ctx
, &temp
, queue
->fs_file
);
3261 if (len
== (uint32
)-1) {
3265 data
->notify_data
.data
.length
= len
;
3267 data
->notify_data
.data
.string
= (uint16
*)temp
;
3269 data
->notify_data
.data
.string
= NULL
;
3273 /*******************************************************************
3274 * fill a notify_info_data with job status
3275 ********************************************************************/
3277 static void spoolss_notify_job_status_string(int snum
,
3278 SPOOL_NOTIFY_INFO_DATA
*data
,
3279 print_queue_struct
*queue
,
3280 NT_PRINTER_INFO_LEVEL
*printer
,
3281 TALLOC_CTX
*mem_ctx
)
3284 * Now we're returning job status codes we just return a "" here. JRA.
3288 smb_ucs2_t
*temp
= NULL
;
3291 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3294 switch (queue
->status
) {
3299 p
= ""; /* NT provides the paused string */
3308 #endif /* NO LONGER NEEDED. */
3310 len
= rpcstr_push_talloc(mem_ctx
, &temp
, p
);
3311 if (len
== (uint32
)-1) {
3315 data
->notify_data
.data
.length
= len
;
3317 data
->notify_data
.data
.string
= (uint16
*)temp
;
3319 data
->notify_data
.data
.string
= NULL
;
3323 /*******************************************************************
3324 * fill a notify_info_data with job time
3325 ********************************************************************/
3327 static void spoolss_notify_job_time(int snum
,
3328 SPOOL_NOTIFY_INFO_DATA
*data
,
3329 print_queue_struct
*queue
,
3330 NT_PRINTER_INFO_LEVEL
*printer
,
3331 TALLOC_CTX
*mem_ctx
)
3333 data
->notify_data
.value
[0]=0x0;
3334 data
->notify_data
.value
[1]=0;
3337 /*******************************************************************
3338 * fill a notify_info_data with job size
3339 ********************************************************************/
3341 static void spoolss_notify_job_size(int snum
,
3342 SPOOL_NOTIFY_INFO_DATA
*data
,
3343 print_queue_struct
*queue
,
3344 NT_PRINTER_INFO_LEVEL
*printer
,
3345 TALLOC_CTX
*mem_ctx
)
3347 data
->notify_data
.value
[0]=queue
->size
;
3348 data
->notify_data
.value
[1]=0;
3351 /*******************************************************************
3352 * fill a notify_info_data with page info
3353 ********************************************************************/
3354 static void spoolss_notify_total_pages(int snum
,
3355 SPOOL_NOTIFY_INFO_DATA
*data
,
3356 print_queue_struct
*queue
,
3357 NT_PRINTER_INFO_LEVEL
*printer
,
3358 TALLOC_CTX
*mem_ctx
)
3360 data
->notify_data
.value
[0]=queue
->page_count
;
3361 data
->notify_data
.value
[1]=0;
3364 /*******************************************************************
3365 * fill a notify_info_data with pages printed info.
3366 ********************************************************************/
3367 static void spoolss_notify_pages_printed(int snum
,
3368 SPOOL_NOTIFY_INFO_DATA
*data
,
3369 print_queue_struct
*queue
,
3370 NT_PRINTER_INFO_LEVEL
*printer
,
3371 TALLOC_CTX
*mem_ctx
)
3373 data
->notify_data
.value
[0]=0; /* Add code when back-end tracks this */
3374 data
->notify_data
.value
[1]=0;
3377 /*******************************************************************
3378 Fill a notify_info_data with job position.
3379 ********************************************************************/
3381 static void spoolss_notify_job_position(int snum
,
3382 SPOOL_NOTIFY_INFO_DATA
*data
,
3383 print_queue_struct
*queue
,
3384 NT_PRINTER_INFO_LEVEL
*printer
,
3385 TALLOC_CTX
*mem_ctx
)
3387 data
->notify_data
.value
[0]=queue
->job
;
3388 data
->notify_data
.value
[1]=0;
3391 /*******************************************************************
3392 Fill a notify_info_data with submitted time.
3393 ********************************************************************/
3395 static void spoolss_notify_submitted_time(int snum
,
3396 SPOOL_NOTIFY_INFO_DATA
*data
,
3397 print_queue_struct
*queue
,
3398 NT_PRINTER_INFO_LEVEL
*printer
,
3399 TALLOC_CTX
*mem_ctx
)
3406 t
=gmtime(&queue
->time
);
3408 len
= sizeof(SYSTEMTIME
);
3410 data
->notify_data
.data
.length
= len
;
3411 data
->notify_data
.data
.string
= (uint16
*)TALLOC(mem_ctx
, len
);
3413 if (!data
->notify_data
.data
.string
) {
3414 data
->notify_data
.data
.length
= 0;
3418 make_systemtime(&st
, t
);
3421 * Systemtime must be linearized as a set of UINT16's.
3422 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3425 p
= (char *)data
->notify_data
.data
.string
;
3426 SSVAL(p
, 0, st
.year
);
3427 SSVAL(p
, 2, st
.month
);
3428 SSVAL(p
, 4, st
.dayofweek
);
3429 SSVAL(p
, 6, st
.day
);
3430 SSVAL(p
, 8, st
.hour
);
3431 SSVAL(p
, 10, st
.minute
);
3432 SSVAL(p
, 12, st
.second
);
3433 SSVAL(p
, 14, st
.milliseconds
);
3436 struct s_notify_info_data_table
3442 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
3443 print_queue_struct
*queue
,
3444 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
3447 /* A table describing the various print notification constants and
3448 whether the notification data is a pointer to a variable sized
3449 buffer, a one value uint32 or a two value uint32. */
3451 static const struct s_notify_info_data_table notify_info_data_table
[] =
3453 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3454 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3455 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING
, spoolss_notify_share_name
},
3456 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3457 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3458 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING
, spoolss_notify_comment
},
3459 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING
, spoolss_notify_location
},
3460 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3461 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING
, spoolss_notify_sepfile
},
3462 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3463 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3464 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3465 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC
, spoolss_notify_security_desc
},
3466 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE
, spoolss_notify_attributes
},
3467 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3468 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_default_priority
},
3469 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3470 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3471 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_status
},
3472 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER
, NULL
},
3473 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE
, spoolss_notify_cjobs
},
3474 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE
, spoolss_notify_average_ppm
},
3475 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER
, NULL
},
3476 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER
, NULL
},
3477 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER
, NULL
},
3478 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER
, NULL
},
3479 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3480 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3481 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3482 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3483 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3484 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3485 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3486 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3487 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3488 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3489 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_job_status
},
3490 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING
, spoolss_notify_job_status_string
},
3491 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER
, NULL
},
3492 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING
, spoolss_notify_job_name
},
3493 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3494 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE
, spoolss_notify_job_position
},
3495 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER
, spoolss_notify_submitted_time
},
3496 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3497 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3498 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_job_time
},
3499 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE
, spoolss_notify_total_pages
},
3500 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE
, spoolss_notify_pages_printed
},
3501 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE
, spoolss_notify_job_size
},
3502 { PRINT_TABLE_END
, 0x0, NULL
, 0x0, NULL
},
3505 /*******************************************************************
3506 Return the size of info_data structure.
3507 ********************************************************************/
3509 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
3513 for (i
= 0; i
< (sizeof(notify_info_data_table
)/sizeof(struct s_notify_info_data_table
)); i
++) {
3514 if ( (notify_info_data_table
[i
].type
== type
)
3515 && (notify_info_data_table
[i
].field
== field
) ) {
3516 switch(notify_info_data_table
[i
].size
) {
3517 case NOTIFY_ONE_VALUE
:
3518 case NOTIFY_TWO_VALUE
:
3523 /* The only pointer notify data I have seen on
3524 the wire is the submitted time and this has
3525 the notify size set to 4. -tpot */
3527 case NOTIFY_POINTER
:
3530 case NOTIFY_SECDESC
:
3536 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
3541 /*******************************************************************
3542 Return the type of notify_info_data.
3543 ********************************************************************/
3545 static uint32
type_of_notify_info_data(uint16 type
, uint16 field
)
3549 for (i
= 0; i
< (sizeof(notify_info_data_table
)/sizeof(struct s_notify_info_data_table
)); i
++) {
3550 if (notify_info_data_table
[i
].type
== type
&&
3551 notify_info_data_table
[i
].field
== field
)
3552 return notify_info_data_table
[i
].size
;
3558 /****************************************************************************
3559 ****************************************************************************/
3561 static bool search_notify(uint16 type
, uint16 field
, int *value
)
3565 for (i
= 0; notify_info_data_table
[i
].type
!= PRINT_TABLE_END
; i
++) {
3566 if (notify_info_data_table
[i
].type
== type
&&
3567 notify_info_data_table
[i
].field
== field
&&
3568 notify_info_data_table
[i
].fn
!= NULL
) {
3577 /****************************************************************************
3578 ****************************************************************************/
3580 void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
3582 info_data
->type
= type
;
3583 info_data
->field
= field
;
3584 info_data
->reserved
= 0;
3586 info_data
->size
= size_of_notify_info_data(type
, field
);
3587 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
3592 /*******************************************************************
3594 * fill a notify_info struct with info asked
3596 ********************************************************************/
3598 static bool construct_notify_printer_info(Printer_entry
*print_hnd
, SPOOL_NOTIFY_INFO
*info
, int
3599 snum
, SPOOL_NOTIFY_OPTION_TYPE
3600 *option_type
, uint32 id
,
3601 TALLOC_CTX
*mem_ctx
)
3607 SPOOL_NOTIFY_INFO_DATA
*current_data
;
3608 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3609 print_queue_struct
*queue
=NULL
;
3611 type
=option_type
->type
;
3613 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3614 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3615 option_type
->count
, lp_servicename(snum
)));
3617 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &printer
, 2, lp_const_servicename(snum
))))
3620 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3621 field
= option_type
->fields
[field_num
];
3623 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3625 if (!search_notify(type
, field
, &j
) )
3628 if((info
->data
=SMB_REALLOC_ARRAY(info
->data
, SPOOL_NOTIFY_INFO_DATA
, info
->count
+1)) == NULL
) {
3629 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3630 free_a_printer(&printer
, 2);
3634 current_data
= &info
->data
[info
->count
];
3636 construct_info_data(current_data
, type
, field
, id
);
3638 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3639 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
3641 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3647 free_a_printer(&printer
, 2);
3651 /*******************************************************************
3653 * fill a notify_info struct with info asked
3655 ********************************************************************/
3657 static bool construct_notify_jobs_info(print_queue_struct
*queue
,
3658 SPOOL_NOTIFY_INFO
*info
,
3659 NT_PRINTER_INFO_LEVEL
*printer
,
3660 int snum
, SPOOL_NOTIFY_OPTION_TYPE
3661 *option_type
, uint32 id
,
3662 TALLOC_CTX
*mem_ctx
)
3668 SPOOL_NOTIFY_INFO_DATA
*current_data
;
3670 DEBUG(4,("construct_notify_jobs_info\n"));
3672 type
= option_type
->type
;
3674 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3675 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3676 option_type
->count
));
3678 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3679 field
= option_type
->fields
[field_num
];
3681 if (!search_notify(type
, field
, &j
) )
3684 if((info
->data
=SMB_REALLOC_ARRAY(info
->data
, SPOOL_NOTIFY_INFO_DATA
, info
->count
+1)) == NULL
) {
3685 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3689 current_data
=&(info
->data
[info
->count
]);
3691 construct_info_data(current_data
, type
, field
, id
);
3692 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3701 * JFM: The enumeration is not that simple, it's even non obvious.
3703 * let's take an example: I want to monitor the PRINTER SERVER for
3704 * the printer's name and the number of jobs currently queued.
3705 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3706 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3708 * I have 3 printers on the back of my server.
3710 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3713 * 1 printer 1 name 1
3714 * 2 printer 1 cjob 1
3715 * 3 printer 2 name 2
3716 * 4 printer 2 cjob 2
3717 * 5 printer 3 name 3
3718 * 6 printer 3 name 3
3720 * that's the print server case, the printer case is even worse.
3723 /*******************************************************************
3725 * enumerate all printers on the printserver
3726 * fill a notify_info struct with info asked
3728 ********************************************************************/
3730 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
3731 SPOOL_NOTIFY_INFO
*info
,
3732 TALLOC_CTX
*mem_ctx
)
3735 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3736 int n_services
=lp_numservices();
3738 SPOOL_NOTIFY_OPTION
*option
;
3739 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3741 DEBUG(4,("printserver_notify_info\n"));
3746 option
=Printer
->notify
.option
;
3751 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3752 sending a ffpcn() request first */
3757 for (i
=0; i
<option
->count
; i
++) {
3758 option_type
=&(option
->ctr
.type
[i
]);
3760 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
3763 for (snum
=0; snum
<n_services
; snum
++)
3765 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
3766 construct_notify_printer_info ( Printer
, info
, snum
, option_type
, snum
, mem_ctx
);
3772 * Debugging information, don't delete.
3775 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3776 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3777 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3779 for (i
=0; i
<info
->count
; i
++) {
3780 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3781 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3782 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3789 /*******************************************************************
3791 * fill a notify_info struct with info asked
3793 ********************************************************************/
3795 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
3796 TALLOC_CTX
*mem_ctx
)
3799 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3802 SPOOL_NOTIFY_OPTION
*option
;
3803 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3805 print_queue_struct
*queue
=NULL
;
3806 print_status_struct status
;
3808 DEBUG(4,("printer_notify_info\n"));
3813 option
=Printer
->notify
.option
;
3819 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3820 sending a ffpcn() request first */
3825 get_printer_snum(p
, hnd
, &snum
, NULL
);
3827 for (i
=0; i
<option
->count
; i
++) {
3828 option_type
=&option
->ctr
.type
[i
];
3830 switch ( option_type
->type
) {
3831 case PRINTER_NOTIFY_TYPE
:
3832 if(construct_notify_printer_info(Printer
, info
, snum
,
3838 case JOB_NOTIFY_TYPE
: {
3839 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3841 count
= print_queue_status(snum
, &queue
, &status
);
3843 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))))
3846 for (j
=0; j
<count
; j
++) {
3847 construct_notify_jobs_info(&queue
[j
], info
,
3854 free_a_printer(&printer
, 2);
3864 * Debugging information, don't delete.
3867 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3868 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3869 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3871 for (i=0; i<info->count; i++) {
3872 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3873 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3874 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3880 /********************************************************************
3882 ********************************************************************/
3884 WERROR
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
3886 POLICY_HND
*handle
= &q_u
->handle
;
3887 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
3889 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
3890 WERROR result
= WERR_BADFID
;
3892 /* we always have a NOTIFY_INFO struct */
3896 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3897 OUR_HANDLE(handle
)));
3901 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3904 * We are now using the change value, and
3905 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3906 * I don't have a global notification system, I'm sending back all the
3907 * informations even when _NOTHING_ has changed.
3910 /* We need to keep track of the change value to send back in
3911 RRPCN replies otherwise our updates are ignored. */
3913 Printer
->notify
.fnpcn
= True
;
3915 if (Printer
->notify
.client_connected
) {
3916 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u
->change
));
3917 Printer
->notify
.change
= q_u
->change
;
3920 /* just ignore the SPOOL_NOTIFY_OPTION */
3922 switch (Printer
->printer_type
) {
3924 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
3927 case SPLHND_PRINTER
:
3928 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
3932 Printer
->notify
.fnpcn
= False
;
3938 /********************************************************************
3939 * construct_printer_info_0
3940 * fill a printer_info_0 struct
3941 ********************************************************************/
3943 static bool construct_printer_info_0(Printer_entry
*print_hnd
, PRINTER_INFO_0
*printer
, int snum
)
3945 char *chaine
= NULL
;
3947 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3948 counter_printer_0
*session_counter
;
3949 uint32 global_counter
;
3952 print_status_struct status
;
3953 TALLOC_CTX
*ctx
= talloc_tos();
3955 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
3958 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
3960 chaine
= talloc_asprintf(ctx
, "\\\\%s", get_server_name(print_hnd
));
3962 free_a_printer(&ntprinter
,2);
3966 count
= print_queue_length(snum
, &status
);
3968 /* check if we already have a counter for this printer */
3969 for(session_counter
= counter_list
; session_counter
; session_counter
= session_counter
->next
) {
3970 if (session_counter
->snum
== snum
)
3974 init_unistr(&printer
->servername
, chaine
);
3976 /* it's the first time, add it to the list */
3977 if (session_counter
==NULL
) {
3978 if((session_counter
=SMB_MALLOC_P(counter_printer_0
)) == NULL
) {
3979 free_a_printer(&ntprinter
, 2);
3982 ZERO_STRUCTP(session_counter
);
3983 session_counter
->snum
=snum
;
3984 session_counter
->counter
=0;
3985 DLIST_ADD(counter_list
, session_counter
);
3989 session_counter
->counter
++;
3992 * the global_counter should be stored in a TDB as it's common to all the clients
3993 * and should be zeroed on samba startup
3995 global_counter
=session_counter
->counter
;
3996 printer
->cjobs
= count
;
3997 printer
->total_jobs
= 0;
3998 printer
->total_bytes
= 0;
4000 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
4001 t
=gmtime(&setuptime
);
4003 printer
->year
= t
->tm_year
+1900;
4004 printer
->month
= t
->tm_mon
+1;
4005 printer
->dayofweek
= t
->tm_wday
;
4006 printer
->day
= t
->tm_mday
;
4007 printer
->hour
= t
->tm_hour
;
4008 printer
->minute
= t
->tm_min
;
4009 printer
->second
= t
->tm_sec
;
4010 printer
->milliseconds
= 0;
4012 printer
->global_counter
= global_counter
;
4013 printer
->total_pages
= 0;
4015 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
4016 printer
->major_version
= 0x0005; /* NT 5 */
4017 printer
->build_version
= 0x0893; /* build 2195 */
4019 printer
->unknown7
= 0x1;
4020 printer
->unknown8
= 0x0;
4021 printer
->unknown9
= 0x0;
4022 printer
->session_counter
= session_counter
->counter
;
4023 printer
->unknown11
= 0x0;
4024 printer
->printer_errors
= 0x0; /* number of print failure */
4025 printer
->unknown13
= 0x0;
4026 printer
->unknown14
= 0x1;
4027 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
4028 printer
->unknown16
= 0x0;
4029 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
4030 printer
->unknown18
= 0x0;
4031 printer
->status
= nt_printq_status(status
.status
);
4032 printer
->unknown20
= 0x0;
4033 printer
->c_setprinter
= get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4034 printer
->unknown22
= 0x0;
4035 printer
->unknown23
= 0x6; /* 6 ???*/
4036 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
4037 printer
->unknown25
= 0;
4038 printer
->unknown26
= 0;
4039 printer
->unknown27
= 0;
4040 printer
->unknown28
= 0;
4041 printer
->unknown29
= 0;
4043 free_a_printer(&ntprinter
,2);
4047 /********************************************************************
4048 * construct_printer_info_1
4049 * fill a printer_info_1 struct
4050 ********************************************************************/
4051 static bool construct_printer_info_1(Printer_entry
*print_hnd
, uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
4053 char *chaine
= NULL
;
4054 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4055 TALLOC_CTX
*ctx
= talloc_tos();
4057 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4060 printer
->flags
=flags
;
4062 if (*ntprinter
->info_2
->comment
== '\0') {
4063 init_unistr(&printer
->comment
, lp_comment(snum
));
4064 chaine
= talloc_asprintf(ctx
,
4065 "%s,%s,%s", ntprinter
->info_2
->printername
,
4066 ntprinter
->info_2
->drivername
, lp_comment(snum
));
4069 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4070 chaine
= talloc_asprintf(ctx
,
4071 "%s,%s,%s", ntprinter
->info_2
->printername
,
4072 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
4076 free_a_printer(&ntprinter
,2);
4080 init_unistr(&printer
->description
, chaine
);
4081 init_unistr(&printer
->name
, ntprinter
->info_2
->printername
);
4083 free_a_printer(&ntprinter
,2);
4088 /****************************************************************************
4089 Free a DEVMODE struct.
4090 ****************************************************************************/
4092 static void free_dev_mode(DEVICEMODE
*dev
)
4097 SAFE_FREE(dev
->dev_private
);
4102 /****************************************************************************
4103 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4104 should be valid upon entry
4105 ****************************************************************************/
4107 static bool convert_nt_devicemode( DEVICEMODE
*devmode
, NT_DEVICEMODE
*ntdevmode
)
4109 if ( !devmode
|| !ntdevmode
)
4112 init_unistr(&devmode
->devicename
, ntdevmode
->devicename
);
4114 init_unistr(&devmode
->formname
, ntdevmode
->formname
);
4116 devmode
->specversion
= ntdevmode
->specversion
;
4117 devmode
->driverversion
= ntdevmode
->driverversion
;
4118 devmode
->size
= ntdevmode
->size
;
4119 devmode
->driverextra
= ntdevmode
->driverextra
;
4120 devmode
->fields
= ntdevmode
->fields
;
4122 devmode
->orientation
= ntdevmode
->orientation
;
4123 devmode
->papersize
= ntdevmode
->papersize
;
4124 devmode
->paperlength
= ntdevmode
->paperlength
;
4125 devmode
->paperwidth
= ntdevmode
->paperwidth
;
4126 devmode
->scale
= ntdevmode
->scale
;
4127 devmode
->copies
= ntdevmode
->copies
;
4128 devmode
->defaultsource
= ntdevmode
->defaultsource
;
4129 devmode
->printquality
= ntdevmode
->printquality
;
4130 devmode
->color
= ntdevmode
->color
;
4131 devmode
->duplex
= ntdevmode
->duplex
;
4132 devmode
->yresolution
= ntdevmode
->yresolution
;
4133 devmode
->ttoption
= ntdevmode
->ttoption
;
4134 devmode
->collate
= ntdevmode
->collate
;
4135 devmode
->icmmethod
= ntdevmode
->icmmethod
;
4136 devmode
->icmintent
= ntdevmode
->icmintent
;
4137 devmode
->mediatype
= ntdevmode
->mediatype
;
4138 devmode
->dithertype
= ntdevmode
->dithertype
;
4140 if (ntdevmode
->nt_dev_private
!= NULL
) {
4141 if ((devmode
->dev_private
=(uint8
*)memdup(ntdevmode
->nt_dev_private
, ntdevmode
->driverextra
)) == NULL
)
4148 /****************************************************************************
4149 Create a DEVMODE struct. Returns malloced memory.
4150 ****************************************************************************/
4152 DEVICEMODE
*construct_dev_mode(const char *servicename
)
4154 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4155 DEVICEMODE
*devmode
= NULL
;
4157 DEBUG(7,("construct_dev_mode\n"));
4159 DEBUGADD(8,("getting printer characteristics\n"));
4161 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, servicename
)))
4164 if ( !printer
->info_2
->devmode
) {
4165 DEBUG(5, ("BONG! There was no device mode!\n"));
4169 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) == NULL
) {
4170 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4174 ZERO_STRUCTP(devmode
);
4176 DEBUGADD(8,("loading DEVICEMODE\n"));
4178 if ( !convert_nt_devicemode( devmode
, printer
->info_2
->devmode
) ) {
4179 free_dev_mode( devmode
);
4184 free_a_printer(&printer
,2);
4189 /********************************************************************
4190 * construct_printer_info_2
4191 * fill a printer_info_2 struct
4192 ********************************************************************/
4194 static bool construct_printer_info_2(Printer_entry
*print_hnd
, PRINTER_INFO_2
*printer
, int snum
)
4197 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4199 print_status_struct status
;
4201 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4204 count
= print_queue_length(snum
, &status
);
4206 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4207 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4208 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
4209 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
4210 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
4212 if (*ntprinter
->info_2
->comment
== '\0')
4213 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
4215 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
4217 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
4218 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
4219 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
4220 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
4221 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
4223 printer
->attributes
= ntprinter
->info_2
->attributes
;
4225 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
4226 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
4227 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
4228 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
4229 printer
->status
= nt_printq_status(status
.status
); /* status */
4230 printer
->cjobs
= count
; /* jobs */
4231 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
4233 if ( !(printer
->devmode
= construct_dev_mode(
4234 lp_const_servicename(snum
))) )
4235 DEBUG(8, ("Returning NULL Devicemode!\n"));
4237 printer
->secdesc
= NULL
;
4239 if ( ntprinter
->info_2
->secdesc_buf
4240 && ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0 )
4242 /* don't use talloc_steal() here unless you do a deep steal of all
4243 the SEC_DESC members */
4245 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4246 ntprinter
->info_2
->secdesc_buf
->sd
);
4249 free_a_printer(&ntprinter
, 2);
4254 /********************************************************************
4255 * construct_printer_info_3
4256 * fill a printer_info_3 struct
4257 ********************************************************************/
4259 static bool construct_printer_info_3(Printer_entry
*print_hnd
, PRINTER_INFO_3
**pp_printer
, int snum
)
4261 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4262 PRINTER_INFO_3
*printer
= NULL
;
4264 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4268 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_3
)) == NULL
) {
4269 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4270 free_a_printer(&ntprinter
, 2);
4274 ZERO_STRUCTP(printer
);
4276 /* These are the components of the SD we are returning. */
4278 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->sd_size
!= 0) {
4279 /* don't use talloc_steal() here unless you do a deep steal of all
4280 the SEC_DESC members */
4282 printer
->secdesc
= dup_sec_desc( talloc_tos(),
4283 ntprinter
->info_2
->secdesc_buf
->sd
);
4286 free_a_printer(&ntprinter
, 2);
4288 *pp_printer
= printer
;
4292 /********************************************************************
4293 * construct_printer_info_4
4294 * fill a printer_info_4 struct
4295 ********************************************************************/
4297 static bool construct_printer_info_4(Printer_entry
*print_hnd
, PRINTER_INFO_4
*printer
, int snum
)
4299 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4301 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4304 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4305 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4306 printer
->attributes
= ntprinter
->info_2
->attributes
;
4308 free_a_printer(&ntprinter
, 2);
4312 /********************************************************************
4313 * construct_printer_info_5
4314 * fill a printer_info_5 struct
4315 ********************************************************************/
4317 static bool construct_printer_info_5(Printer_entry
*print_hnd
, PRINTER_INFO_5
*printer
, int snum
)
4319 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4321 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2, lp_const_servicename(snum
))))
4324 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
);
4325 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
);
4326 printer
->attributes
= ntprinter
->info_2
->attributes
;
4328 /* these two are not used by NT+ according to MSDN */
4330 printer
->device_not_selected_timeout
= 0x0; /* have seen 0x3a98 */
4331 printer
->transmission_retry_timeout
= 0x0; /* have seen 0xafc8 */
4333 free_a_printer(&ntprinter
, 2);
4338 /********************************************************************
4339 * construct_printer_info_6
4340 * fill a printer_info_6 struct
4341 ********************************************************************/
4343 static bool construct_printer_info_6(Printer_entry
*print_hnd
,
4344 PRINTER_INFO_6
*printer
,
4347 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4349 print_status_struct status
;
4351 if (!W_ERROR_IS_OK(get_a_printer(print_hnd
, &ntprinter
, 2,
4352 lp_const_servicename(snum
))))
4355 count
= print_queue_length(snum
, &status
);
4357 printer
->status
= nt_printq_status(status
.status
);
4359 free_a_printer(&ntprinter
, 2);
4364 /********************************************************************
4365 * construct_printer_info_7
4366 * fill a printer_info_7 struct
4367 ********************************************************************/
4369 static bool construct_printer_info_7(Printer_entry
*print_hnd
, PRINTER_INFO_7
*printer
, int snum
)
4371 char *guid_str
= NULL
;
4374 if (is_printer_published(print_hnd
, snum
, &guid
)) {
4375 if (asprintf(&guid_str
, "{%s}",
4376 smb_uuid_string(talloc_tos(), guid
)) == -1) {
4379 strupper_m(guid_str
);
4380 init_unistr(&printer
->guid
, guid_str
);
4381 SAFE_FREE(guid_str
);
4382 printer
->action
= SPOOL_DS_PUBLISH
;
4384 init_unistr(&printer
->guid
, "");
4385 printer
->action
= SPOOL_DS_UNPUBLISH
;
4391 /********************************************************************
4392 Spoolss_enumprinters.
4393 ********************************************************************/
4395 static WERROR
enum_all_printers_info_1(uint32 flags
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4399 int n_services
=lp_numservices();
4400 PRINTER_INFO_1
*printers
=NULL
;
4401 PRINTER_INFO_1 current_prt
;
4402 WERROR result
= WERR_OK
;
4404 DEBUG(4,("enum_all_printers_info_1\n"));
4406 for (snum
=0; snum
<n_services
; snum
++) {
4407 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4408 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4410 if (construct_printer_info_1(NULL
, flags
, ¤t_prt
, snum
)) {
4411 if((printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_1
, *returned
+1)) == NULL
) {
4412 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4416 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
4418 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
4424 /* check the required size. */
4425 for (i
=0; i
<*returned
; i
++)
4426 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
4428 if (*needed
> offered
) {
4429 result
= WERR_INSUFFICIENT_BUFFER
;
4433 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4434 result
= WERR_NOMEM
;
4438 /* fill the buffer with the structures */
4439 for (i
=0; i
<*returned
; i
++)
4440 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
4445 SAFE_FREE(printers
);
4447 if ( !W_ERROR_IS_OK(result
) )
4453 /********************************************************************
4454 enum_all_printers_info_1_local.
4455 *********************************************************************/
4457 static WERROR
enum_all_printers_info_1_local(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4459 DEBUG(4,("enum_all_printers_info_1_local\n"));
4461 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4464 /********************************************************************
4465 enum_all_printers_info_1_name.
4466 *********************************************************************/
4468 static WERROR
enum_all_printers_info_1_name(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4472 DEBUG(4,("enum_all_printers_info_1_name\n"));
4474 if ((name
[0] == '\\') && (name
[1] == '\\'))
4477 if (is_myname_or_ipaddr(s
)) {
4478 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4481 return WERR_INVALID_NAME
;
4484 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4485 /********************************************************************
4486 enum_all_printers_info_1_remote.
4487 *********************************************************************/
4489 static WERROR
enum_all_printers_info_1_remote(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4491 PRINTER_INFO_1
*printer
;
4492 fstring printername
;
4495 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4496 WERROR result
= WERR_OK
;
4498 /* JFM: currently it's more a place holder than anything else.
4499 * In the spooler world there is a notion of server registration.
4500 * the print servers are registered on the PDC (in the same domain)
4502 * We should have a TDB here. The registration is done thru an
4503 * undocumented RPC call.
4506 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4511 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", name
);
4512 slprintf(desc
, sizeof(desc
)-1,"%s", name
);
4513 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
4515 init_unistr(&printer
->description
, desc
);
4516 init_unistr(&printer
->name
, printername
);
4517 init_unistr(&printer
->comment
, comment
);
4518 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
4520 /* check the required size. */
4521 *needed
+= spoolss_size_printer_info_1(printer
);
4523 if (*needed
> offered
) {
4524 result
= WERR_INSUFFICIENT_BUFFER
;
4528 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4529 result
= WERR_NOMEM
;
4533 /* fill the buffer with the structures */
4534 smb_io_printer_info_1("", buffer
, printer
, 0);
4540 if ( !W_ERROR_IS_OK(result
) )
4548 /********************************************************************
4549 enum_all_printers_info_1_network.
4550 *********************************************************************/
4552 static WERROR
enum_all_printers_info_1_network(fstring name
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4556 DEBUG(4,("enum_all_printers_info_1_network\n"));
4558 /* If we respond to a enum_printers level 1 on our name with flags
4559 set to PRINTER_ENUM_REMOTE with a list of printers then these
4560 printers incorrectly appear in the APW browse list.
4561 Specifically the printers for the server appear at the workgroup
4562 level where all the other servers in the domain are
4563 listed. Windows responds to this call with a
4564 WERR_CAN_NOT_COMPLETE so we should do the same. */
4566 if (name
[0] == '\\' && name
[1] == '\\')
4569 if (is_myname_or_ipaddr(s
))
4570 return WERR_CAN_NOT_COMPLETE
;
4572 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8
, buffer
, offered
, needed
, returned
);
4575 /********************************************************************
4576 * api_spoolss_enumprinters
4578 * called from api_spoolss_enumprinters (see this to understand)
4579 ********************************************************************/
4581 static WERROR
enum_all_printers_info_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4585 int n_services
=lp_numservices();
4586 PRINTER_INFO_2
*printers
=NULL
;
4587 PRINTER_INFO_2 current_prt
;
4588 WERROR result
= WERR_OK
;
4592 for (snum
=0; snum
<n_services
; snum
++) {
4593 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4594 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4596 if (construct_printer_info_2(NULL
, ¤t_prt
, snum
)) {
4597 if ( !(printers
=SMB_REALLOC_ARRAY(printers
, PRINTER_INFO_2
, *returned
+1)) ) {
4598 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4603 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
+ 1));
4605 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
4612 /* check the required size. */
4613 for (i
=0; i
<*returned
; i
++)
4614 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
4616 if (*needed
> offered
) {
4617 result
= WERR_INSUFFICIENT_BUFFER
;
4621 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4622 result
= WERR_NOMEM
;
4626 /* fill the buffer with the structures */
4627 for (i
=0; i
<*returned
; i
++)
4628 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
4633 for (i
=0; i
<*returned
; i
++)
4634 free_devmode(printers
[i
].devmode
);
4636 SAFE_FREE(printers
);
4638 if ( !W_ERROR_IS_OK(result
) )
4644 /********************************************************************
4645 * handle enumeration of printers at level 1
4646 ********************************************************************/
4648 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
4649 RPC_BUFFER
*buffer
, uint32 offered
,
4650 uint32
*needed
, uint32
*returned
)
4652 /* Not all the flags are equals */
4654 if (flags
& PRINTER_ENUM_LOCAL
)
4655 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
4657 if (flags
& PRINTER_ENUM_NAME
)
4658 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
4660 #if 0 /* JERRY - disabled for now */
4661 if (flags
& PRINTER_ENUM_REMOTE
)
4662 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
4665 if (flags
& PRINTER_ENUM_NETWORK
)
4666 return enum_all_printers_info_1_network(name
, buffer
, offered
, needed
, returned
);
4668 return WERR_OK
; /* NT4sp5 does that */
4671 /********************************************************************
4672 * handle enumeration of printers at level 2
4673 ********************************************************************/
4675 static WERROR
enumprinters_level2( uint32 flags
, const char *servername
,
4676 RPC_BUFFER
*buffer
, uint32 offered
,
4677 uint32
*needed
, uint32
*returned
)
4679 if (flags
& PRINTER_ENUM_LOCAL
) {
4680 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4683 if (flags
& PRINTER_ENUM_NAME
) {
4684 if (is_myname_or_ipaddr(canon_servername(servername
)))
4685 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4687 return WERR_INVALID_NAME
;
4690 if (flags
& PRINTER_ENUM_REMOTE
)
4691 return WERR_UNKNOWN_LEVEL
;
4696 /********************************************************************
4697 * handle enumeration of printers at level 5
4698 ********************************************************************/
4700 static WERROR
enumprinters_level5( uint32 flags
, const char *servername
,
4701 RPC_BUFFER
*buffer
, uint32 offered
,
4702 uint32
*needed
, uint32
*returned
)
4704 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4708 /********************************************************************
4709 * api_spoolss_enumprinters
4711 * called from api_spoolss_enumprinters (see this to understand)
4712 ********************************************************************/
4714 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
4716 uint32 flags
= q_u
->flags
;
4717 UNISTR2
*servername
= &q_u
->servername
;
4718 uint32 level
= q_u
->level
;
4719 RPC_BUFFER
*buffer
= NULL
;
4720 uint32 offered
= q_u
->offered
;
4721 uint32
*needed
= &r_u
->needed
;
4722 uint32
*returned
= &r_u
->returned
;
4726 /* that's an [in out] buffer */
4728 if (!q_u
->buffer
&& (offered
!=0)) {
4729 return WERR_INVALID_PARAM
;
4732 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
4733 buffer
= r_u
->buffer
;
4735 DEBUG(4,("_spoolss_enumprinters\n"));
4742 * flags==PRINTER_ENUM_NAME
4743 * if name=="" then enumerates all printers
4744 * if name!="" then enumerate the printer
4745 * flags==PRINTER_ENUM_REMOTE
4746 * name is NULL, enumerate printers
4747 * Level 2: name!="" enumerates printers, name can't be NULL
4748 * Level 3: doesn't exist
4749 * Level 4: does a local registry lookup
4750 * Level 5: same as Level 2
4753 unistr2_to_ascii(name
, servername
, sizeof(name
));
4758 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
4760 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
4762 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
4767 return WERR_UNKNOWN_LEVEL
;
4770 /****************************************************************************
4771 ****************************************************************************/
4773 static WERROR
getprinter_level_0(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4775 PRINTER_INFO_0
*printer
=NULL
;
4776 WERROR result
= WERR_OK
;
4778 if((printer
=SMB_MALLOC_P(PRINTER_INFO_0
)) == NULL
)
4781 construct_printer_info_0(print_hnd
, printer
, snum
);
4783 /* check the required size. */
4784 *needed
+= spoolss_size_printer_info_0(printer
);
4786 if (*needed
> offered
) {
4787 result
= WERR_INSUFFICIENT_BUFFER
;
4791 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4792 result
= WERR_NOMEM
;
4796 /* fill the buffer with the structures */
4797 smb_io_printer_info_0("", buffer
, printer
, 0);
4807 /****************************************************************************
4808 ****************************************************************************/
4810 static WERROR
getprinter_level_1(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4812 PRINTER_INFO_1
*printer
=NULL
;
4813 WERROR result
= WERR_OK
;
4815 if((printer
=SMB_MALLOC_P(PRINTER_INFO_1
)) == NULL
)
4818 construct_printer_info_1(print_hnd
, PRINTER_ENUM_ICON8
, printer
, snum
);
4820 /* check the required size. */
4821 *needed
+= spoolss_size_printer_info_1(printer
);
4823 if (*needed
> offered
) {
4824 result
= WERR_INSUFFICIENT_BUFFER
;
4828 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4829 result
= WERR_NOMEM
;
4833 /* fill the buffer with the structures */
4834 smb_io_printer_info_1("", buffer
, printer
, 0);
4843 /****************************************************************************
4844 ****************************************************************************/
4846 static WERROR
getprinter_level_2(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4848 PRINTER_INFO_2
*printer
=NULL
;
4849 WERROR result
= WERR_OK
;
4851 if((printer
=SMB_MALLOC_P(PRINTER_INFO_2
))==NULL
)
4854 construct_printer_info_2(print_hnd
, printer
, snum
);
4856 /* check the required size. */
4857 *needed
+= spoolss_size_printer_info_2(printer
);
4859 if (*needed
> offered
) {
4860 result
= WERR_INSUFFICIENT_BUFFER
;
4864 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4865 result
= WERR_NOMEM
;
4869 /* fill the buffer with the structures */
4870 if (!smb_io_printer_info_2("", buffer
, printer
, 0))
4871 result
= WERR_NOMEM
;
4875 free_printer_info_2(printer
);
4880 /****************************************************************************
4881 ****************************************************************************/
4883 static WERROR
getprinter_level_3(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4885 PRINTER_INFO_3
*printer
=NULL
;
4886 WERROR result
= WERR_OK
;
4888 if (!construct_printer_info_3(print_hnd
, &printer
, snum
))
4891 /* check the required size. */
4892 *needed
+= spoolss_size_printer_info_3(printer
);
4894 if (*needed
> offered
) {
4895 result
= WERR_INSUFFICIENT_BUFFER
;
4899 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4900 result
= WERR_NOMEM
;
4904 /* fill the buffer with the structures */
4905 smb_io_printer_info_3("", buffer
, printer
, 0);
4909 free_printer_info_3(printer
);
4914 /****************************************************************************
4915 ****************************************************************************/
4917 static WERROR
getprinter_level_4(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4919 PRINTER_INFO_4
*printer
=NULL
;
4920 WERROR result
= WERR_OK
;
4922 if((printer
=SMB_MALLOC_P(PRINTER_INFO_4
))==NULL
)
4925 if (!construct_printer_info_4(print_hnd
, printer
, snum
)) {
4930 /* check the required size. */
4931 *needed
+= spoolss_size_printer_info_4(printer
);
4933 if (*needed
> offered
) {
4934 result
= WERR_INSUFFICIENT_BUFFER
;
4938 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4939 result
= WERR_NOMEM
;
4943 /* fill the buffer with the structures */
4944 smb_io_printer_info_4("", buffer
, printer
, 0);
4948 free_printer_info_4(printer
);
4953 /****************************************************************************
4954 ****************************************************************************/
4956 static WERROR
getprinter_level_5(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4958 PRINTER_INFO_5
*printer
=NULL
;
4959 WERROR result
= WERR_OK
;
4961 if((printer
=SMB_MALLOC_P(PRINTER_INFO_5
))==NULL
)
4964 if (!construct_printer_info_5(print_hnd
, printer
, snum
)) {
4965 free_printer_info_5(printer
);
4969 /* check the required size. */
4970 *needed
+= spoolss_size_printer_info_5(printer
);
4972 if (*needed
> offered
) {
4973 result
= WERR_INSUFFICIENT_BUFFER
;
4977 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
4978 result
= WERR_NOMEM
;
4982 /* fill the buffer with the structures */
4983 smb_io_printer_info_5("", buffer
, printer
, 0);
4987 free_printer_info_5(printer
);
4992 static WERROR
getprinter_level_6(Printer_entry
*print_hnd
,
4994 RPC_BUFFER
*buffer
, uint32 offered
,
4997 PRINTER_INFO_6
*printer
;
4998 WERROR result
= WERR_OK
;
5000 if ((printer
= SMB_MALLOC_P(PRINTER_INFO_6
)) == NULL
) {
5004 if (!construct_printer_info_6(print_hnd
, printer
, snum
)) {
5005 free_printer_info_6(printer
);
5009 /* check the required size. */
5010 *needed
+= spoolss_size_printer_info_6(printer
);
5012 if (*needed
> offered
) {
5013 result
= WERR_INSUFFICIENT_BUFFER
;
5017 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5018 result
= WERR_NOMEM
;
5022 /* fill the buffer with the structures */
5023 smb_io_printer_info_6("", buffer
, printer
, 0);
5027 free_printer_info_6(printer
);
5032 static WERROR
getprinter_level_7(Printer_entry
*print_hnd
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5034 PRINTER_INFO_7
*printer
=NULL
;
5035 WERROR result
= WERR_OK
;
5037 if((printer
=SMB_MALLOC_P(PRINTER_INFO_7
))==NULL
)
5040 if (!construct_printer_info_7(print_hnd
, printer
, snum
)) {
5041 result
= WERR_NOMEM
;
5045 /* check the required size. */
5046 *needed
+= spoolss_size_printer_info_7(printer
);
5048 if (*needed
> offered
) {
5049 result
= WERR_INSUFFICIENT_BUFFER
;
5053 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5054 result
= WERR_NOMEM
;
5059 /* fill the buffer with the structures */
5060 smb_io_printer_info_7("", buffer
, printer
, 0);
5064 free_printer_info_7(printer
);
5069 /****************************************************************************
5070 ****************************************************************************/
5072 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
5074 POLICY_HND
*handle
= &q_u
->handle
;
5075 uint32 level
= q_u
->level
;
5076 RPC_BUFFER
*buffer
= NULL
;
5077 uint32 offered
= q_u
->offered
;
5078 uint32
*needed
= &r_u
->needed
;
5079 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
5083 /* that's an [in out] buffer */
5085 if (!q_u
->buffer
&& (offered
!=0)) {
5086 return WERR_INVALID_PARAM
;
5089 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5090 buffer
= r_u
->buffer
;
5094 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5099 return getprinter_level_0(Printer
, snum
, buffer
, offered
, needed
);
5101 return getprinter_level_1(Printer
, snum
, buffer
, offered
, needed
);
5103 return getprinter_level_2(Printer
, snum
, buffer
, offered
, needed
);
5105 return getprinter_level_3(Printer
, snum
, buffer
, offered
, needed
);
5107 return getprinter_level_4(Printer
, snum
, buffer
, offered
, needed
);
5109 return getprinter_level_5(Printer
, snum
, buffer
, offered
, needed
);
5111 return getprinter_level_6(Printer
, snum
, buffer
, offered
, needed
);
5113 return getprinter_level_7(Printer
, snum
, buffer
, offered
, needed
);
5115 return WERR_UNKNOWN_LEVEL
;
5118 /********************************************************************
5119 * fill a DRIVER_INFO_1 struct
5120 ********************************************************************/
5122 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
, fstring architecture
)
5124 init_unistr( &info
->name
, driver
.info_3
->name
);
5127 /********************************************************************
5128 * construct_printer_driver_info_1
5129 ********************************************************************/
5131 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5133 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5134 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5136 ZERO_STRUCT(driver
);
5138 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5139 return WERR_INVALID_PRINTER_NAME
;
5141 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5142 free_a_printer(&printer
, 2);
5143 return WERR_UNKNOWN_PRINTER_DRIVER
;
5146 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
5148 free_a_printer(&printer
,2);
5153 /********************************************************************
5154 * construct_printer_driver_info_2
5155 * fill a printer_info_2 struct
5156 ********************************************************************/
5158 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5160 TALLOC_CTX
*ctx
= talloc_tos();
5162 const char *cservername
= canon_servername(servername
);
5164 info
->version
=driver
.info_3
->cversion
;
5166 init_unistr( &info
->name
, driver
.info_3
->name
);
5167 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5169 if (strlen(driver
.info_3
->driverpath
)) {
5170 temp
= talloc_asprintf(ctx
,
5173 driver
.info_3
->driverpath
);
5174 init_unistr( &info
->driverpath
, temp
);
5176 init_unistr( &info
->driverpath
, "" );
5180 if (strlen(driver
.info_3
->datafile
)) {
5181 temp
= talloc_asprintf(ctx
,
5184 driver
.info_3
->datafile
);
5185 init_unistr( &info
->datafile
, temp
);
5187 init_unistr( &info
->datafile
, "" );
5190 if (strlen(driver
.info_3
->configfile
)) {
5191 temp
= talloc_asprintf(ctx
,
5194 driver
.info_3
->configfile
);
5195 init_unistr( &info
->configfile
, temp
);
5197 init_unistr( &info
->configfile
, "" );
5200 /********************************************************************
5201 * construct_printer_driver_info_2
5202 * fill a printer_info_2 struct
5203 ********************************************************************/
5205 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5207 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5208 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5210 ZERO_STRUCT(printer
);
5211 ZERO_STRUCT(driver
);
5213 if (!W_ERROR_IS_OK(get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
))))
5214 return WERR_INVALID_PRINTER_NAME
;
5216 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
))) {
5217 free_a_printer(&printer
, 2);
5218 return WERR_UNKNOWN_PRINTER_DRIVER
;
5221 fill_printer_driver_info_2(info
, driver
, servername
);
5223 free_a_printer(&printer
,2);
5228 /********************************************************************
5229 * copy a strings array and convert to UNICODE
5231 * convert an array of ascii string to a UNICODE string
5232 ********************************************************************/
5234 static uint32
init_unistr_array(uint16
**uni_array
, fstring
*char_array
, const char *servername
)
5240 TALLOC_CTX
*ctx
= talloc_tos();
5242 DEBUG(6,("init_unistr_array\n"));
5246 if ( !char_array
) {
5251 v
= ""; /* hack to handle null lists */
5254 /* hack to allow this to be used in places other than when generating
5255 the list of dependent files */
5259 line
= talloc_asprintf(ctx
,
5261 canon_servername(servername
),
5264 line
= talloc_strdup(ctx
, v
);
5268 SAFE_FREE(*uni_array
);
5271 DEBUGADD(6,("%d:%s:%lu\n", i
, line
, (unsigned long)strlen(line
)));
5273 /* add one extra unit16 for the second terminating NULL */
5275 if ( (*uni_array
=SMB_REALLOC_ARRAY(*uni_array
, uint16
, j
+1+strlen(line
)+2)) == NULL
) {
5276 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5283 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, STR_TERMINATE
) / sizeof(uint16
));
5288 /* special case for ""; we need to add both NULL's here */
5290 (*uni_array
)[j
++]=0x0000;
5291 (*uni_array
)[j
]=0x0000;
5294 DEBUGADD(6,("last one:done\n"));
5296 /* return size of array in uint16's */
5301 /********************************************************************
5302 * construct_printer_info_3
5303 * fill a printer_info_3 struct
5304 ********************************************************************/
5306 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5309 TALLOC_CTX
*ctx
= talloc_tos();
5310 const char *cservername
= canon_servername(servername
);
5314 info
->version
=driver
.info_3
->cversion
;
5316 init_unistr( &info
->name
, driver
.info_3
->name
);
5317 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5319 if (strlen(driver
.info_3
->driverpath
)) {
5320 temp
= talloc_asprintf(ctx
,
5323 driver
.info_3
->driverpath
);
5324 init_unistr( &info
->driverpath
, temp
);
5326 init_unistr( &info
->driverpath
, "" );
5329 if (strlen(driver
.info_3
->datafile
)) {
5330 temp
= talloc_asprintf(ctx
,
5333 driver
.info_3
->datafile
);
5334 init_unistr( &info
->datafile
, temp
);
5336 init_unistr( &info
->datafile
, "" );
5339 if (strlen(driver
.info_3
->configfile
)) {
5340 temp
= talloc_asprintf(ctx
,
5343 driver
.info_3
->configfile
);
5344 init_unistr( &info
->configfile
, temp
);
5346 init_unistr( &info
->configfile
, "" );
5349 if (strlen(driver
.info_3
->helpfile
)) {
5350 temp
= talloc_asprintf(ctx
,
5353 driver
.info_3
->helpfile
);
5354 init_unistr( &info
->helpfile
, temp
);
5356 init_unistr( &info
->helpfile
, "" );
5359 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5360 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5362 info
->dependentfiles
=NULL
;
5363 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, cservername
);
5366 /********************************************************************
5367 * construct_printer_info_3
5368 * fill a printer_info_3 struct
5369 ********************************************************************/
5371 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, const char *servername
, fstring architecture
, uint32 version
)
5373 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5374 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5376 ZERO_STRUCT(driver
);
5378 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5379 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5380 if (!W_ERROR_IS_OK(status
))
5381 return WERR_INVALID_PRINTER_NAME
;
5383 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5384 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5389 * I put this code in during testing. Helpful when commenting out the
5390 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5391 * as win2k always queries the driver using an infor level of 6.
5392 * I've left it in (but ifdef'd out) because I'll probably
5393 * use it in experimentation again in the future. --jerry 22/01/2002
5396 if (!W_ERROR_IS_OK(status
)) {
5398 * Is this a W2k client ?
5401 /* Yes - try again with a WinNT driver. */
5403 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5404 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
5408 if (!W_ERROR_IS_OK(status
)) {
5409 free_a_printer(&printer
,2);
5410 return WERR_UNKNOWN_PRINTER_DRIVER
;
5418 fill_printer_driver_info_3(info
, driver
, servername
);
5420 free_a_printer(&printer
,2);
5425 /********************************************************************
5426 * construct_printer_info_6
5427 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5428 ********************************************************************/
5430 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, const char *servername
)
5434 TALLOC_CTX
*ctx
= talloc_tos();
5435 const char *cservername
= canon_servername(servername
);
5438 memset(&nullstr
, '\0', sizeof(fstring
));
5440 info
->version
=driver
.info_3
->cversion
;
5442 init_unistr( &info
->name
, driver
.info_3
->name
);
5443 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
5445 if (strlen(driver
.info_3
->driverpath
)) {
5446 temp
= talloc_asprintf(ctx
,
5449 driver
.info_3
->driverpath
);
5450 init_unistr( &info
->driverpath
, temp
);
5452 init_unistr( &info
->driverpath
, "" );
5455 if (strlen(driver
.info_3
->datafile
)) {
5456 temp
= talloc_asprintf(ctx
,
5459 driver
.info_3
->datafile
);
5460 init_unistr( &info
->datafile
, temp
);
5462 init_unistr( &info
->datafile
, "" );
5465 if (strlen(driver
.info_3
->configfile
)) {
5466 temp
= talloc_asprintf(ctx
,
5469 driver
.info_3
->configfile
);
5470 init_unistr( &info
->configfile
, temp
);
5472 init_unistr( &info
->configfile
, "" );
5475 if (strlen(driver
.info_3
->helpfile
)) {
5476 temp
= talloc_asprintf(ctx
,
5479 driver
.info_3
->helpfile
);
5480 init_unistr( &info
->helpfile
, temp
);
5482 init_unistr( &info
->helpfile
, "" );
5485 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
5486 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
5488 info
->dependentfiles
= NULL
;
5489 init_unistr_array( &info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
5491 info
->previousdrivernames
=NULL
;
5492 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
5494 info
->driver_date
=0;
5497 info
->driver_version_low
=0;
5498 info
->driver_version_high
=0;
5500 init_unistr( &info
->mfgname
, "");
5501 init_unistr( &info
->oem_url
, "");
5502 init_unistr( &info
->hardware_id
, "");
5503 init_unistr( &info
->provider
, "");
5506 /********************************************************************
5507 * construct_printer_info_6
5508 * fill a printer_info_6 struct
5509 ********************************************************************/
5511 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
,
5512 const char *servername
, fstring architecture
, uint32 version
)
5514 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
5515 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
5518 ZERO_STRUCT(driver
);
5520 status
=get_a_printer(NULL
, &printer
, 2, lp_const_servicename(snum
) );
5522 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5524 if (!W_ERROR_IS_OK(status
))
5525 return WERR_INVALID_PRINTER_NAME
;
5527 status
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5529 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5531 if (!W_ERROR_IS_OK(status
))
5534 * Is this a W2k client ?
5538 free_a_printer(&printer
,2);
5539 return WERR_UNKNOWN_PRINTER_DRIVER
;
5542 /* Yes - try again with a WinNT driver. */
5544 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5545 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5546 if (!W_ERROR_IS_OK(status
)) {
5547 free_a_printer(&printer
,2);
5548 return WERR_UNKNOWN_PRINTER_DRIVER
;
5552 fill_printer_driver_info_6(info
, driver
, servername
);
5554 free_a_printer(&printer
,2);
5555 free_a_printer_driver(driver
, 3);
5560 /****************************************************************************
5561 ****************************************************************************/
5563 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
5565 SAFE_FREE(info
->dependentfiles
);
5568 /****************************************************************************
5569 ****************************************************************************/
5571 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
5573 SAFE_FREE(info
->dependentfiles
);
5576 /****************************************************************************
5577 ****************************************************************************/
5579 static WERROR
getprinterdriver2_level1(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5581 DRIVER_INFO_1
*info
=NULL
;
5584 if((info
=SMB_MALLOC_P(DRIVER_INFO_1
)) == NULL
)
5587 result
= construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
5588 if (!W_ERROR_IS_OK(result
))
5591 /* check the required size. */
5592 *needed
+= spoolss_size_printer_driver_info_1(info
);
5594 if (*needed
> offered
) {
5595 result
= WERR_INSUFFICIENT_BUFFER
;
5599 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5600 result
= WERR_NOMEM
;
5604 /* fill the buffer with the structures */
5605 smb_io_printer_driver_info_1("", buffer
, info
, 0);
5614 /****************************************************************************
5615 ****************************************************************************/
5617 static WERROR
getprinterdriver2_level2(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5619 DRIVER_INFO_2
*info
=NULL
;
5622 if((info
=SMB_MALLOC_P(DRIVER_INFO_2
)) == NULL
)
5625 result
= construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
5626 if (!W_ERROR_IS_OK(result
))
5629 /* check the required size. */
5630 *needed
+= spoolss_size_printer_driver_info_2(info
);
5632 if (*needed
> offered
) {
5633 result
= WERR_INSUFFICIENT_BUFFER
;
5637 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5638 result
= WERR_NOMEM
;
5642 /* fill the buffer with the structures */
5643 smb_io_printer_driver_info_2("", buffer
, info
, 0);
5652 /****************************************************************************
5653 ****************************************************************************/
5655 static WERROR
getprinterdriver2_level3(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5662 result
= construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
5663 if (!W_ERROR_IS_OK(result
))
5666 /* check the required size. */
5667 *needed
+= spoolss_size_printer_driver_info_3(&info
);
5669 if (*needed
> offered
) {
5670 result
= WERR_INSUFFICIENT_BUFFER
;
5674 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5675 result
= WERR_NOMEM
;
5679 /* fill the buffer with the structures */
5680 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
5683 free_printer_driver_info_3(&info
);
5688 /****************************************************************************
5689 ****************************************************************************/
5691 static WERROR
getprinterdriver2_level6(const char *servername
, fstring architecture
, uint32 version
, int snum
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5698 result
= construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
5699 if (!W_ERROR_IS_OK(result
))
5702 /* check the required size. */
5703 *needed
+= spoolss_size_printer_driver_info_6(&info
);
5705 if (*needed
> offered
) {
5706 result
= WERR_INSUFFICIENT_BUFFER
;
5710 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
5711 result
= WERR_NOMEM
;
5715 /* fill the buffer with the structures */
5716 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
5719 free_printer_driver_info_6(&info
);
5724 /****************************************************************************
5725 ****************************************************************************/
5727 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
5729 POLICY_HND
*handle
= &q_u
->handle
;
5730 UNISTR2
*uni_arch
= &q_u
->architecture
;
5731 uint32 level
= q_u
->level
;
5732 uint32 clientmajorversion
= q_u
->clientmajorversion
;
5733 RPC_BUFFER
*buffer
= NULL
;
5734 uint32 offered
= q_u
->offered
;
5735 uint32
*needed
= &r_u
->needed
;
5736 uint32
*servermajorversion
= &r_u
->servermajorversion
;
5737 uint32
*serverminorversion
= &r_u
->serverminorversion
;
5738 Printer_entry
*printer
;
5741 fstring architecture
;
5744 /* that's an [in out] buffer */
5746 if (!q_u
->buffer
&& (offered
!=0)) {
5747 return WERR_INVALID_PARAM
;
5750 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
5751 buffer
= r_u
->buffer
;
5753 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5755 if ( !(printer
= find_printer_index_by_hnd( p
, handle
)) ) {
5756 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5757 return WERR_INVALID_PRINTER_NAME
;
5761 *servermajorversion
= 0;
5762 *serverminorversion
= 0;
5764 fstrcpy(servername
, get_server_name( printer
));
5765 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
));
5767 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5772 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5774 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5776 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5778 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5781 /* apparently this call is the equivalent of
5782 EnumPrinterDataEx() for the DsDriver key */
5787 return WERR_UNKNOWN_LEVEL
;
5790 /****************************************************************************
5791 ****************************************************************************/
5793 WERROR
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
5795 POLICY_HND
*handle
= &q_u
->handle
;
5797 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5800 DEBUG(3,("Error in startpageprinter printer handle\n"));
5804 Printer
->page_started
=True
;
5808 /****************************************************************************
5809 ****************************************************************************/
5811 WERROR
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
5813 POLICY_HND
*handle
= &q_u
->handle
;
5816 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5819 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle
)));
5823 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5826 Printer
->page_started
=False
;
5827 print_job_endpage(snum
, Printer
->jobid
);
5832 /********************************************************************
5833 * api_spoolss_getprinter
5834 * called from the spoolss dispatcher
5836 ********************************************************************/
5838 WERROR
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
5840 POLICY_HND
*handle
= &q_u
->handle
;
5841 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
5842 uint32
*jobid
= &r_u
->jobid
;
5843 TALLOC_CTX
*ctx
= p
->mem_ctx
;
5844 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
5846 char *jobname
= NULL
;
5848 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5851 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5856 * a nice thing with NT is it doesn't listen to what you tell it.
5857 * when asked to send _only_ RAW datas, it tries to send datas
5860 * So I add checks like in NT Server ...
5863 if (info_1
->p_datatype
!= 0) {
5864 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
5865 if (strcmp(datatype
, "RAW") != 0) {
5867 return WERR_INVALID_DATATYPE
;
5871 /* get the share number of the printer */
5872 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
5876 jobname
= unistr2_to_ascii_talloc(ctx
, &info_1
->docname
);
5878 Printer
->jobid
= print_job_start(&p
->pipe_user
, snum
, jobname
, Printer
->nt_devmode
);
5880 /* An error occured in print_job_start() so return an appropriate
5883 if (Printer
->jobid
== -1) {
5884 return map_werror_from_unix(errno
);
5887 Printer
->document_started
=True
;
5888 (*jobid
) = Printer
->jobid
;
5893 /********************************************************************
5894 * api_spoolss_getprinter
5895 * called from the spoolss dispatcher
5897 ********************************************************************/
5899 WERROR
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
5901 POLICY_HND
*handle
= &q_u
->handle
;
5903 return _spoolss_enddocprinter_internal(p
, handle
);
5906 /****************************************************************************
5907 ****************************************************************************/
5909 WERROR
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
5911 POLICY_HND
*handle
= &q_u
->handle
;
5912 uint32 buffer_size
= q_u
->buffer_size
;
5913 uint8
*buffer
= q_u
->buffer
;
5914 uint32
*buffer_written
= &q_u
->buffer_size2
;
5916 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5919 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5920 r_u
->buffer_written
= q_u
->buffer_size2
;
5924 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5927 (*buffer_written
) = (uint32
)print_job_write(snum
, Printer
->jobid
, (const char *)buffer
,
5928 (SMB_OFF_T
)-1, (size_t)buffer_size
);
5929 if (*buffer_written
== (uint32
)-1) {
5930 r_u
->buffer_written
= 0;
5931 if (errno
== ENOSPC
)
5932 return WERR_NO_SPOOL_SPACE
;
5934 return WERR_ACCESS_DENIED
;
5937 r_u
->buffer_written
= q_u
->buffer_size2
;
5942 /********************************************************************
5943 * api_spoolss_getprinter
5944 * called from the spoolss dispatcher
5946 ********************************************************************/
5948 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
5952 WERROR errcode
= WERR_BADFUNC
;
5953 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5956 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5960 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
5964 case PRINTER_CONTROL_PAUSE
:
5965 if (print_queue_pause(&p
->pipe_user
, snum
, &errcode
)) {
5969 case PRINTER_CONTROL_RESUME
:
5970 case PRINTER_CONTROL_UNPAUSE
:
5971 if (print_queue_resume(&p
->pipe_user
, snum
, &errcode
)) {
5975 case PRINTER_CONTROL_PURGE
:
5976 if (print_queue_purge(&p
->pipe_user
, snum
, &errcode
)) {
5981 return WERR_UNKNOWN_LEVEL
;
5987 /********************************************************************
5988 * api_spoolss_abortprinter
5989 * From MSDN: "Deletes printer's spool file if printer is configured
5991 ********************************************************************/
5993 WERROR
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
5995 POLICY_HND
*handle
= &q_u
->handle
;
5996 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5998 WERROR errcode
= WERR_OK
;
6001 DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
6005 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6008 print_job_delete( &p
->pipe_user
, snum
, Printer
->jobid
, &errcode
);
6013 /********************************************************************
6014 * called by spoolss_api_setprinter
6015 * when updating a printer description
6016 ********************************************************************/
6018 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
6019 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6020 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
6022 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
6026 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6028 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
, NULL
)) {
6029 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6030 OUR_HANDLE(handle
)));
6032 result
= WERR_BADFID
;
6037 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6038 result
= WERR_INVALID_PARAM
;
6042 /* Check the user has permissions to change the security
6043 descriptor. By experimentation with two NT machines, the user
6044 requires Full Access to the printer to change security
6047 if ( Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6048 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6049 result
= WERR_ACCESS_DENIED
;
6053 /* NT seems to like setting the security descriptor even though
6054 nothing may have actually changed. */
6056 if ( !nt_printing_getsec(p
->mem_ctx
, Printer
->sharename
, &old_secdesc_ctr
)) {
6057 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6058 result
= WERR_BADFID
;
6062 if (DEBUGLEVEL
>= 10) {
6066 the_acl
= old_secdesc_ctr
->sd
->dacl
;
6067 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6068 PRINTERNAME(snum
), the_acl
->num_aces
));
6070 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6071 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6072 &the_acl
->aces
[i
].trustee
),
6073 the_acl
->aces
[i
].access_mask
));
6076 the_acl
= secdesc_ctr
->sd
->dacl
;
6079 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6080 PRINTERNAME(snum
), the_acl
->num_aces
));
6082 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
6083 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6084 &the_acl
->aces
[i
].trustee
),
6085 the_acl
->aces
[i
].access_mask
));
6088 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6092 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
6093 if (!new_secdesc_ctr
) {
6094 result
= WERR_NOMEM
;
6098 if (sec_desc_equal(new_secdesc_ctr
->sd
, old_secdesc_ctr
->sd
)) {
6103 result
= nt_printing_setsec(Printer
->sharename
, new_secdesc_ctr
);
6110 /********************************************************************
6111 Canonicalize printer info from a client
6113 ATTN: It does not matter what we set the servername to hear
6114 since we do the necessary work in get_a_printer() to set it to
6115 the correct value based on what the client sent in the
6116 _spoolss_open_printer_ex().
6117 ********************************************************************/
6119 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
6121 fstring printername
;
6124 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6125 "portname=%s drivername=%s comment=%s location=%s\n",
6126 info
->servername
, info
->printername
, info
->sharename
,
6127 info
->portname
, info
->drivername
, info
->comment
, info
->location
));
6129 /* we force some elements to "correct" values */
6130 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", global_myname());
6131 fstrcpy(info
->sharename
, lp_servicename(snum
));
6133 /* check to see if we allow printername != sharename */
6135 if ( lp_force_printername(snum
) ) {
6136 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6137 global_myname(), info
->sharename
);
6140 /* make sure printername is in \\server\printername format */
6142 fstrcpy( printername
, info
->printername
);
6144 if ( printername
[0] == '\\' && printername
[1] == '\\' ) {
6145 if ( (p
= strchr_m( &printername
[2], '\\' )) != NULL
)
6149 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
6150 global_myname(), p
);
6153 info
->attributes
|= PRINTER_ATTRIBUTE_SAMBA
;
6154 info
->attributes
&= ~PRINTER_ATTRIBUTE_NOT_SAMBA
;
6161 /****************************************************************************
6162 ****************************************************************************/
6164 WERROR
add_port_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, const char *portname
, const char *uri
)
6166 char *cmd
= lp_addport_cmd();
6167 char *command
= NULL
;
6169 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6170 bool is_print_op
= False
;
6173 return WERR_ACCESS_DENIED
;
6176 command
= talloc_asprintf(ctx
,
6177 "%s \"%s\" \"%s\"", cmd
, portname
, uri
);
6183 is_print_op
= user_has_privileges( token
, &se_printop
);
6185 DEBUG(10,("Running [%s]\n", command
));
6187 /********* BEGIN SePrintOperatorPrivilege **********/
6192 ret
= smbrun(command
, NULL
);
6197 /********* END SePrintOperatorPrivilege **********/
6199 DEBUGADD(10,("returned [%d]\n", ret
));
6201 TALLOC_FREE(command
);
6204 return WERR_ACCESS_DENIED
;
6210 /****************************************************************************
6211 ****************************************************************************/
6213 bool add_printer_hook(TALLOC_CTX
*ctx
, NT_USER_TOKEN
*token
, NT_PRINTER_INFO_LEVEL
*printer
)
6215 char *cmd
= lp_addprinter_cmd();
6217 char *command
= NULL
;
6221 SE_PRIV se_printop
= SE_PRINT_OPERATOR
;
6222 bool is_print_op
= False
;
6223 char *remote_machine
= talloc_strdup(ctx
, "%m");
6225 if (!remote_machine
) {
6228 remote_machine
= talloc_sub_basic(ctx
,
6229 current_user_info
.smb_name
,
6230 current_user_info
.domain
,
6232 if (!remote_machine
) {
6236 command
= talloc_asprintf(ctx
,
6237 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6238 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
6239 printer
->info_2
->portname
, printer
->info_2
->drivername
,
6240 printer
->info_2
->location
, printer
->info_2
->comment
, remote_machine
);
6246 is_print_op
= user_has_privileges( token
, &se_printop
);
6248 DEBUG(10,("Running [%s]\n", command
));
6250 /********* BEGIN SePrintOperatorPrivilege **********/
6255 if ( (ret
= smbrun(command
, &fd
)) == 0 ) {
6256 /* Tell everyone we updated smb.conf. */
6257 message_send_all(smbd_messaging_context(),
6258 MSG_SMB_CONF_UPDATED
, NULL
, 0, NULL
);
6264 /********* END SePrintOperatorPrivilege **********/
6266 DEBUGADD(10,("returned [%d]\n", ret
));
6268 TALLOC_FREE(command
);
6269 TALLOC_FREE(remote_machine
);
6277 /* reload our services immediately */
6278 reload_services( False
);
6281 /* Get lines and convert them back to dos-codepage */
6282 qlines
= fd_lines_load(fd
, &numlines
, 0);
6283 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6286 /* Set the portname to what the script says the portname should be. */
6287 /* but don't require anything to be return from the script exit a good error code */
6290 /* Set the portname to what the script says the portname should be. */
6291 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
6292 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
6295 file_lines_free(qlines
);
6300 /********************************************************************
6301 * Called by spoolss_api_setprinter
6302 * when updating a printer description.
6303 ********************************************************************/
6305 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
6306 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6307 DEVICEMODE
*devmode
)
6310 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
6311 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6316 DEBUG(8,("update_printer\n"));
6321 result
= WERR_BADFID
;
6325 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6326 result
= WERR_BADFID
;
6330 if (!W_ERROR_IS_OK(get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
))) ||
6331 (!W_ERROR_IS_OK(get_a_printer(Printer
, &old_printer
, 2, lp_const_servicename(snum
))))) {
6332 result
= WERR_BADFID
;
6336 DEBUGADD(8,("Converting info_2 struct\n"));
6339 * convert_printer_info converts the incoming
6340 * info from the client and overwrites the info
6341 * just read from the tdb in the pointer 'printer'.
6344 if (!convert_printer_info(info
, printer
, level
)) {
6345 result
= WERR_NOMEM
;
6350 /* we have a valid devmode
6351 convert it and link it*/
6353 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6354 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
6355 &printer
->info_2
->devmode
)) {
6356 result
= WERR_NOMEM
;
6361 /* Do sanity check on the requested changes for Samba */
6363 if (!check_printer_ok(printer
->info_2
, snum
)) {
6364 result
= WERR_INVALID_PARAM
;
6368 /* FIXME!!! If the driver has changed we really should verify that
6369 it is installed before doing much else --jerry */
6371 /* Check calling user has permission to update printer description */
6373 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
6374 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6375 result
= WERR_ACCESS_DENIED
;
6379 /* Call addprinter hook */
6380 /* Check changes to see if this is really needed */
6382 if ( *lp_addprinter_cmd()
6383 && (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
)
6384 || !strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)
6385 || !strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)
6386 || !strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) )
6388 /* add_printer_hook() will call reload_services() */
6390 if ( !add_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, printer
) ) {
6391 result
= WERR_ACCESS_DENIED
;
6397 * When a *new* driver is bound to a printer, the drivername is used to
6398 * lookup previously saved driver initialization info, which is then
6399 * bound to the printer, simulating what happens in the Windows arch.
6401 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
6403 if (!set_driver_init(printer
, 2))
6405 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6406 printer
->info_2
->drivername
));
6409 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6410 printer
->info_2
->drivername
));
6412 notify_printer_driver(snum
, printer
->info_2
->drivername
);
6416 * flag which changes actually occured. This is a small subset of
6417 * all the possible changes. We also have to update things in the
6421 if (!strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
)) {
6422 init_unistr2( &buffer
, printer
->info_2
->comment
, UNI_STR_TERMINATE
);
6423 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "description",
6424 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6426 notify_printer_comment(snum
, printer
->info_2
->comment
);
6429 if (!strequal(printer
->info_2
->sharename
, old_printer
->info_2
->sharename
)) {
6430 init_unistr2( &buffer
, printer
->info_2
->sharename
, UNI_STR_TERMINATE
);
6431 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shareName",
6432 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6434 notify_printer_sharename(snum
, printer
->info_2
->sharename
);
6437 if (!strequal(printer
->info_2
->printername
, old_printer
->info_2
->printername
)) {
6440 if ( (pname
= strchr_m( printer
->info_2
->printername
+2, '\\' )) != NULL
)
6443 pname
= printer
->info_2
->printername
;
6446 init_unistr2( &buffer
, pname
, UNI_STR_TERMINATE
);
6447 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "printerName",
6448 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6450 notify_printer_printername( snum
, pname
);
6453 if (!strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
)) {
6454 init_unistr2( &buffer
, printer
->info_2
->portname
, UNI_STR_TERMINATE
);
6455 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "portName",
6456 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6458 notify_printer_port(snum
, printer
->info_2
->portname
);
6461 if (!strequal(printer
->info_2
->location
, old_printer
->info_2
->location
)) {
6462 init_unistr2( &buffer
, printer
->info_2
->location
, UNI_STR_TERMINATE
);
6463 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "location",
6464 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6466 notify_printer_location(snum
, printer
->info_2
->location
);
6469 /* here we need to update some more DsSpooler keys */
6470 /* uNCName, serverName, shortServerName */
6472 init_unistr2( &buffer
, global_myname(), UNI_STR_TERMINATE
);
6473 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "serverName",
6474 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6475 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "shortServerName",
6476 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6478 slprintf( asc_buffer
, sizeof(asc_buffer
)-1, "\\\\%s\\%s",
6479 global_myname(), printer
->info_2
->sharename
);
6480 init_unistr2( &buffer
, asc_buffer
, UNI_STR_TERMINATE
);
6481 set_printer_dataex( printer
, SPOOL_DSSPOOLER_KEY
, "uNCName",
6482 REG_SZ
, (uint8
*)buffer
.buffer
, buffer
.uni_str_len
*2 );
6484 /* Update printer info */
6485 result
= mod_a_printer(printer
, 2);
6488 free_a_printer(&printer
, 2);
6489 free_a_printer(&old_printer
, 2);
6495 /****************************************************************************
6496 ****************************************************************************/
6497 static WERROR
publish_or_unpublish_printer(pipes_struct
*p
, POLICY_HND
*handle
,
6498 const SPOOL_PRINTER_INFO_LEVEL
*info
)
6501 SPOOL_PRINTER_INFO_LEVEL_7
*info7
= info
->info_7
;
6503 Printer_entry
*Printer
;
6505 if ( lp_security() != SEC_ADS
) {
6506 return WERR_UNKNOWN_LEVEL
;
6509 Printer
= find_printer_index_by_hnd(p
, handle
);
6511 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7
->action
));
6516 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6519 nt_printer_publish(Printer
, snum
, info7
->action
);
6523 return WERR_UNKNOWN_LEVEL
;
6526 /****************************************************************************
6527 ****************************************************************************/
6529 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
6531 POLICY_HND
*handle
= &q_u
->handle
;
6532 uint32 level
= q_u
->level
;
6533 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
6534 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
6535 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
6536 uint32 command
= q_u
->command
;
6539 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6542 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6546 /* check the level */
6549 return control_printer(handle
, command
, p
);
6551 result
= update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
6552 if (!W_ERROR_IS_OK(result
))
6555 result
= update_printer_sec(handle
, level
, info
, p
, secdesc_ctr
);
6558 return update_printer_sec(handle
, level
, info
, p
,
6561 return publish_or_unpublish_printer(p
, handle
, info
);
6563 return WERR_UNKNOWN_LEVEL
;
6567 /****************************************************************************
6568 ****************************************************************************/
6570 WERROR
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
6572 POLICY_HND
*handle
= &q_u
->handle
;
6573 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
6576 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
6580 if (Printer
->notify
.client_connected
==True
) {
6583 if ( Printer
->printer_type
== SPLHND_SERVER
)
6585 else if ( (Printer
->printer_type
== SPLHND_PRINTER
) &&
6586 !get_printer_snum(p
, handle
, &snum
, NULL
) )
6589 srv_spoolss_replycloseprinter(snum
, &Printer
->notify
.client_hnd
);
6592 Printer
->notify
.flags
=0;
6593 Printer
->notify
.options
=0;
6594 Printer
->notify
.localmachine
[0]='\0';
6595 Printer
->notify
.printerlocal
=0;
6596 if (Printer
->notify
.option
)
6597 free_spool_notify_option(&Printer
->notify
.option
);
6598 Printer
->notify
.client_connected
=False
;
6603 /****************************************************************************
6604 ****************************************************************************/
6606 WERROR
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
6608 /* that's an [in out] buffer */
6610 if (!q_u
->buffer
&& (q_u
->offered
!=0)) {
6611 return WERR_INVALID_PARAM
;
6614 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6617 return WERR_INVALID_PARAM
; /* this is what a NT server
6618 returns for AddJob. AddJob
6619 must fail on non-local
6623 /****************************************************************************
6624 ****************************************************************************/
6626 static void fill_job_info_1(JOB_INFO_1
*job_info
, const print_queue_struct
*queue
,
6627 int position
, int snum
,
6628 const NT_PRINTER_INFO_LEVEL
*ntprinter
)
6632 t
=gmtime(&queue
->time
);
6634 job_info
->jobid
=queue
->job
;
6635 init_unistr(&job_info
->printername
, lp_servicename(snum
));
6636 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6637 init_unistr(&job_info
->username
, queue
->fs_user
);
6638 init_unistr(&job_info
->document
, queue
->fs_file
);
6639 init_unistr(&job_info
->datatype
, "RAW");
6640 init_unistr(&job_info
->text_status
, "");
6641 job_info
->status
=nt_printj_status(queue
->status
);
6642 job_info
->priority
=queue
->priority
;
6643 job_info
->position
=position
;
6644 job_info
->totalpages
=queue
->page_count
;
6645 job_info
->pagesprinted
=0;
6647 make_systemtime(&job_info
->submitted
, t
);
6650 /****************************************************************************
6651 ****************************************************************************/
6653 static bool fill_job_info_2(JOB_INFO_2
*job_info
, const print_queue_struct
*queue
,
6654 int position
, int snum
,
6655 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6656 DEVICEMODE
*devmode
)
6660 t
=gmtime(&queue
->time
);
6662 job_info
->jobid
=queue
->job
;
6664 init_unistr(&job_info
->printername
, ntprinter
->info_2
->printername
);
6666 init_unistr(&job_info
->machinename
, ntprinter
->info_2
->servername
);
6667 init_unistr(&job_info
->username
, queue
->fs_user
);
6668 init_unistr(&job_info
->document
, queue
->fs_file
);
6669 init_unistr(&job_info
->notifyname
, queue
->fs_user
);
6670 init_unistr(&job_info
->datatype
, "RAW");
6671 init_unistr(&job_info
->printprocessor
, "winprint");
6672 init_unistr(&job_info
->parameters
, "");
6673 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
6674 init_unistr(&job_info
->text_status
, "");
6676 /* and here the security descriptor */
6678 job_info
->status
=nt_printj_status(queue
->status
);
6679 job_info
->priority
=queue
->priority
;
6680 job_info
->position
=position
;
6681 job_info
->starttime
=0;
6682 job_info
->untiltime
=0;
6683 job_info
->totalpages
=queue
->page_count
;
6684 job_info
->size
=queue
->size
;
6685 make_systemtime(&(job_info
->submitted
), t
);
6686 job_info
->timeelapsed
=0;
6687 job_info
->pagesprinted
=0;
6689 job_info
->devmode
= devmode
;
6694 /****************************************************************************
6695 Enumjobs at level 1.
6696 ****************************************************************************/
6698 static WERROR
enumjobs_level1(const print_queue_struct
*queue
, int snum
,
6699 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6700 RPC_BUFFER
*buffer
, uint32 offered
,
6701 uint32
*needed
, uint32
*returned
)
6705 WERROR result
= WERR_OK
;
6707 info
=SMB_MALLOC_ARRAY(JOB_INFO_1
,*returned
);
6713 for (i
=0; i
<*returned
; i
++)
6714 fill_job_info_1( &info
[i
], &queue
[i
], i
, snum
, ntprinter
);
6716 /* check the required size. */
6717 for (i
=0; i
<*returned
; i
++)
6718 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
6720 if (*needed
> offered
) {
6721 result
= WERR_INSUFFICIENT_BUFFER
;
6725 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6726 result
= WERR_NOMEM
;
6730 /* fill the buffer with the structures */
6731 for (i
=0; i
<*returned
; i
++)
6732 smb_io_job_info_1("", buffer
, &info
[i
], 0);
6738 if ( !W_ERROR_IS_OK(result
) )
6744 /****************************************************************************
6745 Enumjobs at level 2.
6746 ****************************************************************************/
6748 static WERROR
enumjobs_level2(const print_queue_struct
*queue
, int snum
,
6749 const NT_PRINTER_INFO_LEVEL
*ntprinter
,
6750 RPC_BUFFER
*buffer
, uint32 offered
,
6751 uint32
*needed
, uint32
*returned
)
6753 JOB_INFO_2
*info
= NULL
;
6755 WERROR result
= WERR_OK
;
6756 DEVICEMODE
*devmode
= NULL
;
6758 if ( !(info
= SMB_MALLOC_ARRAY(JOB_INFO_2
,*returned
)) ) {
6763 /* this should not be a failure condition if the devmode is NULL */
6765 devmode
= construct_dev_mode(lp_const_servicename(snum
));
6767 for (i
=0; i
<*returned
; i
++)
6768 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
, devmode
);
6770 /* check the required size. */
6771 for (i
=0; i
<*returned
; i
++)
6772 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
6774 if (*needed
> offered
) {
6775 result
= WERR_INSUFFICIENT_BUFFER
;
6779 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6780 result
= WERR_NOMEM
;
6784 /* fill the buffer with the structures */
6785 for (i
=0; i
<*returned
; i
++)
6786 smb_io_job_info_2("", buffer
, &info
[i
], 0);
6789 free_devmode(devmode
);
6792 if ( !W_ERROR_IS_OK(result
) )
6799 /****************************************************************************
6801 ****************************************************************************/
6803 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
6805 POLICY_HND
*handle
= &q_u
->handle
;
6806 uint32 level
= q_u
->level
;
6807 RPC_BUFFER
*buffer
= NULL
;
6808 uint32 offered
= q_u
->offered
;
6809 uint32
*needed
= &r_u
->needed
;
6810 uint32
*returned
= &r_u
->returned
;
6812 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
6814 print_status_struct prt_status
;
6815 print_queue_struct
*queue
=NULL
;
6817 /* that's an [in out] buffer */
6819 if (!q_u
->buffer
&& (offered
!=0)) {
6820 return WERR_INVALID_PARAM
;
6823 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
6824 buffer
= r_u
->buffer
;
6826 DEBUG(4,("_spoolss_enumjobs\n"));
6831 /* lookup the printer snum and tdb entry */
6833 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
6836 wret
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
6837 if ( !W_ERROR_IS_OK(wret
) )
6840 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
6841 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
6843 if (*returned
== 0) {
6845 free_a_printer(&ntprinter
, 2);
6851 wret
= enumjobs_level1(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6854 wret
= enumjobs_level2(queue
, snum
, ntprinter
, buffer
, offered
, needed
, returned
);
6858 wret
= WERR_UNKNOWN_LEVEL
;
6863 free_a_printer( &ntprinter
, 2 );
6867 /****************************************************************************
6868 ****************************************************************************/
6870 WERROR
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
6875 /****************************************************************************
6876 ****************************************************************************/
6878 WERROR
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
6880 POLICY_HND
*handle
= &q_u
->handle
;
6881 uint32 jobid
= q_u
->jobid
;
6882 uint32 command
= q_u
->command
;
6885 WERROR errcode
= WERR_BADFUNC
;
6887 if (!get_printer_snum(p
, handle
, &snum
, NULL
)) {
6891 if (!print_job_exists(lp_const_servicename(snum
), jobid
)) {
6892 return WERR_INVALID_PRINTER_NAME
;
6896 case JOB_CONTROL_CANCEL
:
6897 case JOB_CONTROL_DELETE
:
6898 if (print_job_delete(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6902 case JOB_CONTROL_PAUSE
:
6903 if (print_job_pause(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6907 case JOB_CONTROL_RESTART
:
6908 case JOB_CONTROL_RESUME
:
6909 if (print_job_resume(&p
->pipe_user
, snum
, jobid
, &errcode
)) {
6914 return WERR_UNKNOWN_LEVEL
;
6920 /****************************************************************************
6921 Enumerates all printer drivers at level 1.
6922 ****************************************************************************/
6924 static WERROR
enumprinterdrivers_level1(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6929 fstring
*list
= NULL
;
6930 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6931 DRIVER_INFO_1
*driver_info_1
=NULL
;
6932 WERROR result
= WERR_OK
;
6936 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6938 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6939 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6941 if(ndrivers
== -1) {
6942 SAFE_FREE(driver_info_1
);
6947 if((driver_info_1
=SMB_REALLOC_ARRAY(driver_info_1
, DRIVER_INFO_1
, *returned
+ndrivers
)) == NULL
) {
6948 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6954 for (i
=0; i
<ndrivers
; i
++) {
6956 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6957 ZERO_STRUCT(driver
);
6958 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6959 architecture
, version
);
6960 if (!W_ERROR_IS_OK(status
)) {
6962 SAFE_FREE(driver_info_1
);
6965 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
6966 free_a_printer_driver(driver
, 3);
6969 *returned
+=ndrivers
;
6973 /* check the required size. */
6974 for (i
=0; i
<*returned
; i
++) {
6975 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6976 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
6979 if (*needed
> offered
) {
6980 result
= WERR_INSUFFICIENT_BUFFER
;
6984 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
6985 result
= WERR_NOMEM
;
6989 /* fill the buffer with the driver structures */
6990 for (i
=0; i
<*returned
; i
++) {
6991 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
6992 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
6996 SAFE_FREE(driver_info_1
);
6998 if ( !W_ERROR_IS_OK(result
) )
7004 /****************************************************************************
7005 Enumerates all printer drivers at level 2.
7006 ****************************************************************************/
7008 static WERROR
enumprinterdrivers_level2(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7013 fstring
*list
= NULL
;
7014 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7015 DRIVER_INFO_2
*driver_info_2
=NULL
;
7016 WERROR result
= WERR_OK
;
7020 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7022 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7023 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7025 if(ndrivers
== -1) {
7026 SAFE_FREE(driver_info_2
);
7031 if((driver_info_2
=SMB_REALLOC_ARRAY(driver_info_2
, DRIVER_INFO_2
, *returned
+ndrivers
)) == NULL
) {
7032 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7038 for (i
=0; i
<ndrivers
; i
++) {
7041 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7042 ZERO_STRUCT(driver
);
7043 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7044 architecture
, version
);
7045 if (!W_ERROR_IS_OK(status
)) {
7047 SAFE_FREE(driver_info_2
);
7050 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
7051 free_a_printer_driver(driver
, 3);
7054 *returned
+=ndrivers
;
7058 /* check the required size. */
7059 for (i
=0; i
<*returned
; i
++) {
7060 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7061 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
7064 if (*needed
> offered
) {
7065 result
= WERR_INSUFFICIENT_BUFFER
;
7069 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7070 result
= WERR_NOMEM
;
7074 /* fill the buffer with the form structures */
7075 for (i
=0; i
<*returned
; i
++) {
7076 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7077 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
7081 SAFE_FREE(driver_info_2
);
7083 if ( !W_ERROR_IS_OK(result
) )
7089 /****************************************************************************
7090 Enumerates all printer drivers at level 3.
7091 ****************************************************************************/
7093 static WERROR
enumprinterdrivers_level3(const char *servername
, fstring architecture
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7098 fstring
*list
= NULL
;
7099 DRIVER_INFO_3
*driver_info_3
=NULL
;
7100 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7101 WERROR result
= WERR_OK
;
7105 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
7107 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
7108 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
7110 if(ndrivers
== -1) {
7111 SAFE_FREE(driver_info_3
);
7116 if((driver_info_3
=SMB_REALLOC_ARRAY(driver_info_3
, DRIVER_INFO_3
, *returned
+ndrivers
)) == NULL
) {
7117 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7123 for (i
=0; i
<ndrivers
; i
++) {
7126 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
7127 ZERO_STRUCT(driver
);
7128 status
= get_a_printer_driver(&driver
, 3, list
[i
],
7129 architecture
, version
);
7130 if (!W_ERROR_IS_OK(status
)) {
7132 SAFE_FREE(driver_info_3
);
7135 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
7136 free_a_printer_driver(driver
, 3);
7139 *returned
+=ndrivers
;
7143 /* check the required size. */
7144 for (i
=0; i
<*returned
; i
++) {
7145 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
7146 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
7149 if (*needed
> offered
) {
7150 result
= WERR_INSUFFICIENT_BUFFER
;
7154 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7155 result
= WERR_NOMEM
;
7159 /* fill the buffer with the driver structures */
7160 for (i
=0; i
<*returned
; i
++) {
7161 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
7162 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
7166 for (i
=0; i
<*returned
; i
++) {
7167 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
7170 SAFE_FREE(driver_info_3
);
7172 if ( !W_ERROR_IS_OK(result
) )
7178 /****************************************************************************
7179 Enumerates all printer drivers.
7180 ****************************************************************************/
7182 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
7184 uint32 level
= q_u
->level
;
7185 RPC_BUFFER
*buffer
= NULL
;
7186 uint32 offered
= q_u
->offered
;
7187 uint32
*needed
= &r_u
->needed
;
7188 uint32
*returned
= &r_u
->returned
;
7189 const char *cservername
;
7191 fstring architecture
;
7193 /* that's an [in out] buffer */
7195 if (!q_u
->buffer
&& (offered
!=0)) {
7196 return WERR_INVALID_PARAM
;
7199 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7200 buffer
= r_u
->buffer
;
7202 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7207 unistr2_to_ascii(architecture
, &q_u
->environment
, sizeof(architecture
));
7208 unistr2_to_ascii(servername
, &q_u
->name
, sizeof(servername
));
7210 cservername
= canon_servername(servername
);
7212 if (!is_myname_or_ipaddr(cservername
))
7213 return WERR_UNKNOWN_PRINTER_DRIVER
;
7217 return enumprinterdrivers_level1(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7219 return enumprinterdrivers_level2(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7221 return enumprinterdrivers_level3(cservername
, architecture
, buffer
, offered
, needed
, returned
);
7223 return WERR_UNKNOWN_LEVEL
;
7227 /****************************************************************************
7228 ****************************************************************************/
7230 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
7232 form
->flag
=list
->flag
;
7233 init_unistr(&form
->name
, list
->name
);
7234 form
->width
=list
->width
;
7235 form
->length
=list
->length
;
7236 form
->left
=list
->left
;
7237 form
->top
=list
->top
;
7238 form
->right
=list
->right
;
7239 form
->bottom
=list
->bottom
;
7242 /****************************************************************************
7243 ****************************************************************************/
7245 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
7247 uint32 level
= q_u
->level
;
7248 RPC_BUFFER
*buffer
= NULL
;
7249 uint32 offered
= q_u
->offered
;
7250 uint32
*needed
= &r_u
->needed
;
7251 uint32
*numofforms
= &r_u
->numofforms
;
7252 uint32 numbuiltinforms
;
7254 nt_forms_struct
*list
=NULL
;
7255 nt_forms_struct
*builtinlist
=NULL
;
7260 /* that's an [in out] buffer */
7262 if (!q_u
->buffer
&& (offered
!=0) ) {
7263 return WERR_INVALID_PARAM
;
7266 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7267 buffer
= r_u
->buffer
;
7269 DEBUG(4,("_spoolss_enumforms\n"));
7270 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7271 DEBUGADD(5,("Info level [%d]\n", level
));
7273 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
7274 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
7275 *numofforms
= get_ntforms(&list
);
7276 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
7277 *numofforms
+= numbuiltinforms
;
7279 if (*numofforms
== 0) {
7280 SAFE_FREE(builtinlist
);
7282 return WERR_NO_MORE_ITEMS
;
7287 if ((forms_1
=SMB_MALLOC_ARRAY(FORM_1
, *numofforms
)) == NULL
) {
7288 SAFE_FREE(builtinlist
);
7294 /* construct the list of form structures */
7295 for (i
=0; i
<numbuiltinforms
; i
++) {
7296 DEBUGADD(6,("Filling form number [%d]\n",i
));
7297 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
7300 SAFE_FREE(builtinlist
);
7302 for (; i
<*numofforms
; i
++) {
7303 DEBUGADD(6,("Filling form number [%d]\n",i
));
7304 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
7309 /* check the required size. */
7310 for (i
=0; i
<numbuiltinforms
; i
++) {
7311 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7312 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7314 for (; i
<*numofforms
; i
++) {
7315 DEBUGADD(6,("adding form [%d]'s size\n",i
));
7316 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
7319 *needed
=buffer_size
;
7321 if (*needed
> offered
) {
7324 return WERR_INSUFFICIENT_BUFFER
;
7327 if (!rpcbuf_alloc_size(buffer
, buffer_size
)){
7333 /* fill the buffer with the form structures */
7334 for (i
=0; i
<numbuiltinforms
; i
++) {
7335 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7336 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7338 for (; i
<*numofforms
; i
++) {
7339 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
7340 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
7349 SAFE_FREE(builtinlist
);
7350 return WERR_UNKNOWN_LEVEL
;
7354 /****************************************************************************
7355 ****************************************************************************/
7357 WERROR
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
7359 uint32 level
= q_u
->level
;
7360 UNISTR2
*uni_formname
= &q_u
->formname
;
7361 RPC_BUFFER
*buffer
= NULL
;
7362 uint32 offered
= q_u
->offered
;
7363 uint32
*needed
= &r_u
->needed
;
7365 nt_forms_struct
*list
=NULL
;
7366 nt_forms_struct builtin_form
;
7371 int numofforms
=0, i
=0;
7373 /* that's an [in out] buffer */
7375 if (!q_u
->buffer
&& (offered
!=0)) {
7376 return WERR_INVALID_PARAM
;
7379 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7380 buffer
= r_u
->buffer
;
7382 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
));
7384 DEBUG(4,("_spoolss_getform\n"));
7385 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
7386 DEBUGADD(5,("Info level [%d]\n", level
));
7388 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
7389 if (!foundBuiltin
) {
7390 numofforms
= get_ntforms(&list
);
7391 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
7393 if (numofforms
== 0)
7400 fill_form_1(&form_1
, &builtin_form
);
7403 /* Check if the requested name is in the list of form structures */
7404 for (i
=0; i
<numofforms
; i
++) {
7406 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
7408 if (strequal(form_name
, list
[i
].name
)) {
7409 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
7410 fill_form_1(&form_1
, &list
[i
]);
7416 if (i
== numofforms
) {
7420 /* check the required size. */
7422 *needed
=spoolss_size_form_1(&form_1
);
7424 if (*needed
> offered
)
7425 return WERR_INSUFFICIENT_BUFFER
;
7427 if (!rpcbuf_alloc_size(buffer
, buffer_size
))
7430 /* fill the buffer with the form structures */
7431 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
7432 smb_io_form_1("", buffer
, &form_1
, 0);
7438 return WERR_UNKNOWN_LEVEL
;
7442 /****************************************************************************
7443 ****************************************************************************/
7445 static void fill_port_1(PORT_INFO_1
*port
, const char *name
)
7447 init_unistr(&port
->port_name
, name
);
7450 /****************************************************************************
7451 TODO: This probably needs distinguish between TCP/IP and Local ports
7453 ****************************************************************************/
7455 static void fill_port_2(PORT_INFO_2
*port
, const char *name
)
7457 init_unistr(&port
->port_name
, name
);
7458 init_unistr(&port
->monitor_name
, "Local Monitor");
7459 init_unistr(&port
->description
, SPL_LOCAL_PORT
);
7460 port
->port_type
=PORT_TYPE_WRITE
;
7465 /****************************************************************************
7466 wrapper around the enumer ports command
7467 ****************************************************************************/
7469 WERROR
enumports_hook(TALLOC_CTX
*ctx
, int *count
, char ***lines
)
7471 char *cmd
= lp_enumports_cmd();
7472 char **qlines
= NULL
;
7473 char *command
= NULL
;
7481 /* if no hook then just fill in the default port */
7484 if (!(qlines
= SMB_MALLOC_ARRAY( char*, 2 ))) {
7487 if (!(qlines
[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME
))) {
7495 /* we have a valid enumport command */
7497 command
= talloc_asprintf(ctx
, "%s \"%d\"", cmd
, 1);
7502 DEBUG(10,("Running [%s]\n", command
));
7503 ret
= smbrun(command
, &fd
);
7504 DEBUG(10,("Returned [%d]\n", ret
));
7505 TALLOC_FREE(command
);
7510 return WERR_ACCESS_DENIED
;
7514 qlines
= fd_lines_load(fd
, &numlines
, 0);
7515 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
7525 /****************************************************************************
7527 ****************************************************************************/
7529 static WERROR
enumports_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7531 PORT_INFO_1
*ports
=NULL
;
7533 WERROR result
= WERR_OK
;
7534 char **qlines
= NULL
;
7537 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7538 if (!W_ERROR_IS_OK(result
)) {
7539 file_lines_free(qlines
);
7544 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_1
, numlines
)) == NULL
) {
7545 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7546 dos_errstr(WERR_NOMEM
)));
7547 file_lines_free(qlines
);
7551 for (i
=0; i
<numlines
; i
++) {
7552 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7553 fill_port_1(&ports
[i
], qlines
[i
]);
7556 file_lines_free(qlines
);
7558 *returned
= numlines
;
7560 /* check the required size. */
7561 for (i
=0; i
<*returned
; i
++) {
7562 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7563 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
7566 if (*needed
> offered
) {
7567 result
= WERR_INSUFFICIENT_BUFFER
;
7571 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7572 result
= WERR_NOMEM
;
7576 /* fill the buffer with the ports structures */
7577 for (i
=0; i
<*returned
; i
++) {
7578 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7579 smb_io_port_1("", buffer
, &ports
[i
], 0);
7585 if ( !W_ERROR_IS_OK(result
) )
7591 /****************************************************************************
7593 ****************************************************************************/
7595 static WERROR
enumports_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7597 PORT_INFO_2
*ports
=NULL
;
7599 WERROR result
= WERR_OK
;
7600 char **qlines
= NULL
;
7603 result
= enumports_hook(talloc_tos(), &numlines
, &qlines
);
7604 if ( !W_ERROR_IS_OK(result
)) {
7605 file_lines_free(qlines
);
7610 if((ports
=SMB_MALLOC_ARRAY( PORT_INFO_2
, numlines
)) == NULL
) {
7611 file_lines_free(qlines
);
7615 for (i
=0; i
<numlines
; i
++) {
7616 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
7617 fill_port_2(&(ports
[i
]), qlines
[i
]);
7621 file_lines_free(qlines
);
7623 *returned
= numlines
;
7625 /* check the required size. */
7626 for (i
=0; i
<*returned
; i
++) {
7627 DEBUGADD(6,("adding port [%d]'s size\n", i
));
7628 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
7631 if (*needed
> offered
) {
7632 result
= WERR_INSUFFICIENT_BUFFER
;
7636 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
7637 result
= WERR_NOMEM
;
7641 /* fill the buffer with the ports structures */
7642 for (i
=0; i
<*returned
; i
++) {
7643 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
7644 smb_io_port_2("", buffer
, &ports
[i
], 0);
7650 if ( !W_ERROR_IS_OK(result
) )
7656 /****************************************************************************
7658 ****************************************************************************/
7660 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
7662 uint32 level
= q_u
->level
;
7663 RPC_BUFFER
*buffer
= NULL
;
7664 uint32 offered
= q_u
->offered
;
7665 uint32
*needed
= &r_u
->needed
;
7666 uint32
*returned
= &r_u
->returned
;
7668 /* that's an [in out] buffer */
7670 if (!q_u
->buffer
&& (offered
!=0)) {
7671 return WERR_INVALID_PARAM
;
7674 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
7675 buffer
= r_u
->buffer
;
7677 DEBUG(4,("_spoolss_enumports\n"));
7684 return enumports_level_1(buffer
, offered
, needed
, returned
);
7686 return enumports_level_2(buffer
, offered
, needed
, returned
);
7688 return WERR_UNKNOWN_LEVEL
;
7692 /****************************************************************************
7693 ****************************************************************************/
7695 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
7696 const SPOOL_PRINTER_INFO_LEVEL
*info
,
7697 DEVICEMODE
*devmode
, SEC_DESC_BUF
*sec_desc_buf
,
7698 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
7701 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7704 WERROR err
= WERR_OK
;
7706 if ( !(printer
= TALLOC_ZERO_P(NULL
, NT_PRINTER_INFO_LEVEL
)) ) {
7707 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7711 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7712 if (!convert_printer_info(info
, printer
, 2)) {
7713 free_a_printer(&printer
, 2);
7717 /* check to see if the printer already exists */
7719 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
7720 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7721 printer
->info_2
->sharename
));
7722 free_a_printer(&printer
, 2);
7723 return WERR_PRINTER_ALREADY_EXISTS
;
7726 /* FIXME!!! smbd should check to see if the driver is installed before
7727 trying to add a printer like this --jerry */
7729 if (*lp_addprinter_cmd() ) {
7730 if ( !add_printer_hook(p
->mem_ctx
, p
->pipe_user
.nt_user_token
, printer
) ) {
7731 free_a_printer(&printer
,2);
7732 return WERR_ACCESS_DENIED
;
7735 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7736 "smb.conf parameter \"addprinter command\" is defined. This"
7737 "parameter must exist for this call to succeed\n",
7738 printer
->info_2
->sharename
));
7741 /* use our primary netbios name since get_a_printer() will convert
7742 it to what the client expects on a case by case basis */
7744 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", global_myname(),
7745 printer
->info_2
->sharename
);
7748 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
7749 free_a_printer(&printer
,2);
7750 return WERR_ACCESS_DENIED
;
7753 /* you must be a printer admin to add a new printer */
7754 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
7755 free_a_printer(&printer
,2);
7756 return WERR_ACCESS_DENIED
;
7760 * Do sanity check on the requested changes for Samba.
7763 if (!check_printer_ok(printer
->info_2
, snum
)) {
7764 free_a_printer(&printer
,2);
7765 return WERR_INVALID_PARAM
;
7769 * When a printer is created, the drivername bound to the printer is used
7770 * to lookup previously saved driver initialization info, which is then
7771 * bound to the new printer, simulating what happens in the Windows arch.
7776 set_driver_init(printer
, 2);
7780 /* A valid devmode was included, convert and link it
7782 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7784 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
7785 &printer
->info_2
->devmode
))
7789 /* write the ASCII on disk */
7790 err
= mod_a_printer(printer
, 2);
7791 if (!W_ERROR_IS_OK(err
)) {
7792 free_a_printer(&printer
,2);
7796 if (!open_printer_hnd(p
, handle
, name
, PRINTER_ACCESS_ADMINISTER
)) {
7797 /* Handle open failed - remove addition. */
7798 del_a_printer(printer
->info_2
->sharename
);
7799 free_a_printer(&printer
,2);
7800 return WERR_ACCESS_DENIED
;
7803 update_c_setprinter(False
);
7804 free_a_printer(&printer
,2);
7809 /****************************************************************************
7810 ****************************************************************************/
7812 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
7814 UNISTR2
*uni_srv_name
= q_u
->server_name
;
7815 uint32 level
= q_u
->level
;
7816 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
7817 DEVICEMODE
*devmode
= q_u
->devmode_ctr
.devmode
;
7818 SEC_DESC_BUF
*sdb
= q_u
->secdesc_ctr
;
7819 uint32 user_switch
= q_u
->user_switch
;
7820 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
7821 POLICY_HND
*handle
= &r_u
->handle
;
7825 /* we don't handle yet */
7826 /* but I know what to do ... */
7827 return WERR_UNKNOWN_LEVEL
;
7829 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
7831 user_switch
, user
, handle
);
7833 return WERR_UNKNOWN_LEVEL
;
7837 /****************************************************************************
7838 ****************************************************************************/
7840 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
7842 uint32 level
= q_u
->level
;
7843 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
7844 WERROR err
= WERR_OK
;
7845 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7846 fstring driver_name
;
7849 ZERO_STRUCT(driver
);
7851 if (!convert_printer_driver_info(info
, &driver
, level
)) {
7856 DEBUG(5,("Cleaning driver's information\n"));
7857 err
= clean_up_driver_struct(driver
, level
, &p
->pipe_user
);
7858 if (!W_ERROR_IS_OK(err
))
7861 DEBUG(5,("Moving driver to final destination\n"));
7862 if( !W_ERROR_IS_OK(err
= move_driver_to_download_area(driver
, level
, &p
->pipe_user
, &err
)) ) {
7866 if (add_a_printer_driver(driver
, level
)!=0) {
7867 err
= WERR_ACCESS_DENIED
;
7873 fstrcpy(driver_name
,
7874 driver
.info_3
->name
? driver
.info_3
->name
: "");
7877 fstrcpy(driver_name
,
7878 driver
.info_6
->name
? driver
.info_6
->name
: "");
7883 * I think this is where he DrvUpgradePrinter() hook would be
7884 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7885 * server. Right now, we just need to send ourselves a message
7886 * to update each printer bound to this driver. --jerry
7889 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7890 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7895 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7896 * decide if the driver init data should be deleted. The rules are:
7897 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7898 * 2) delete init data only if there is no 2k/Xp driver
7899 * 3) always delete init data
7900 * The generalized rule is always use init data from the highest order driver.
7901 * It is necessary to follow the driver install by an initialization step to
7902 * finish off this process.
7905 version
= driver
.info_3
->cversion
;
7906 else if (level
== 6)
7907 version
= driver
.info_6
->version
;
7912 * 9x printer driver - never delete init data
7915 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7920 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7921 * there is no 2k/Xp driver init data for this driver name.
7925 NT_PRINTER_DRIVER_INFO_LEVEL driver1
;
7927 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1
, 3, driver_name
, "Windows NT x86", 3))) {
7929 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7931 if (!del_driver_init(driver_name
))
7932 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name
));
7935 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7937 free_a_printer_driver(driver1
,3);
7938 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
7945 * 2k or Xp printer driver - always delete init data
7948 if (!del_driver_init(driver_name
))
7949 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name
));
7953 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level
));
7959 free_a_printer_driver(driver
, level
);
7963 /********************************************************************
7964 * spoolss_addprinterdriverex
7965 ********************************************************************/
7967 WERROR
_spoolss_addprinterdriverex(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVEREX
*q_u
, SPOOL_R_ADDPRINTERDRIVEREX
*r_u
)
7969 SPOOL_Q_ADDPRINTERDRIVER q_u_local
;
7970 SPOOL_R_ADDPRINTERDRIVER r_u_local
;
7973 * we only support the semantics of AddPrinterDriver()
7974 * i.e. only copy files that are newer than existing ones
7977 if ( q_u
->copy_flags
!= APD_COPY_NEW_FILES
)
7978 return WERR_ACCESS_DENIED
;
7980 ZERO_STRUCT(q_u_local
);
7981 ZERO_STRUCT(r_u_local
);
7983 /* just pass the information off to _spoolss_addprinterdriver() */
7984 q_u_local
.server_name_ptr
= q_u
->server_name_ptr
;
7985 copy_unistr2(&q_u_local
.server_name
, &q_u
->server_name
);
7986 q_u_local
.level
= q_u
->level
;
7987 memcpy( &q_u_local
.info
, &q_u
->info
, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL
) );
7989 return _spoolss_addprinterdriver( p
, &q_u_local
, &r_u_local
);
7992 /****************************************************************************
7993 ****************************************************************************/
7995 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
7997 init_unistr(&info
->name
, name
);
8000 /****************************************************************************
8001 ****************************************************************************/
8003 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
8006 char *long_archi
= NULL
;
8007 char *servername
= NULL
;
8008 const char *pservername
= NULL
;
8009 const char *short_archi
;
8010 DRIVER_DIRECTORY_1
*info
=NULL
;
8011 WERROR result
= WERR_OK
;
8012 TALLOC_CTX
*ctx
= talloc_tos();
8014 servername
= unistr2_to_ascii_talloc(ctx
, name
);
8018 long_archi
= unistr2_to_ascii_talloc(ctx
, uni_environment
);
8023 pservername
= canon_servername(servername
);
8025 if ( !is_myname_or_ipaddr(pservername
))
8026 return WERR_INVALID_PARAM
;
8028 if (!(short_archi
= get_short_archi(long_archi
)))
8029 return WERR_INVALID_ENVIRONMENT
;
8031 if((info
=SMB_MALLOC_P(DRIVER_DIRECTORY_1
)) == NULL
)
8034 path
= talloc_asprintf(ctx
,
8035 "\\\\%s\\print$\\%s", pservername
, short_archi
);
8037 result
= WERR_NOMEM
;
8041 DEBUG(4,("printer driver directory: [%s]\n", path
));
8043 fill_driverdir_1(info
, path
);
8045 *needed
+= spoolss_size_driverdir_info_1(info
);
8047 if (*needed
> offered
) {
8048 result
= WERR_INSUFFICIENT_BUFFER
;
8052 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8053 result
= WERR_NOMEM
;
8057 smb_io_driverdir_1("", buffer
, info
, 0);
8065 /****************************************************************************
8066 ****************************************************************************/
8068 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
8070 UNISTR2
*name
= &q_u
->name
;
8071 UNISTR2
*uni_environment
= &q_u
->environment
;
8072 uint32 level
= q_u
->level
;
8073 RPC_BUFFER
*buffer
= NULL
;
8074 uint32 offered
= q_u
->offered
;
8075 uint32
*needed
= &r_u
->needed
;
8077 /* that's an [in out] buffer */
8079 if (!q_u
->buffer
&& (offered
!=0)) {
8080 return WERR_INVALID_PARAM
;
8083 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8084 buffer
= r_u
->buffer
;
8086 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8092 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
8094 return WERR_UNKNOWN_LEVEL
;
8098 /****************************************************************************
8099 ****************************************************************************/
8101 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
8103 POLICY_HND
*handle
= &q_u
->handle
;
8104 uint32 idx
= q_u
->index
;
8105 uint32 in_value_len
= q_u
->valuesize
;
8106 uint32 in_data_len
= q_u
->datasize
;
8107 uint32
*out_max_value_len
= &r_u
->valuesize
;
8108 uint16
**out_value
= &r_u
->value
;
8109 uint32
*out_value_len
= &r_u
->realvaluesize
;
8110 uint32
*out_type
= &r_u
->type
;
8111 uint32
*out_max_data_len
= &r_u
->datasize
;
8112 uint8
**data_out
= &r_u
->data
;
8113 uint32
*out_data_len
= &r_u
->realdatasize
;
8115 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8117 uint32 biggest_valuesize
;
8118 uint32 biggest_datasize
;
8120 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8123 REGISTRY_VALUE
*val
= NULL
;
8124 NT_PRINTER_DATA
*p_data
;
8125 int i
, key_index
, num_values
;
8130 *out_max_data_len
= 0;
8134 DEBUG(5,("spoolss_enumprinterdata\n"));
8137 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8141 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8144 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8145 if (!W_ERROR_IS_OK(result
))
8148 p_data
= printer
->info_2
->data
;
8149 key_index
= lookup_printerkey( p_data
, SPOOL_PRINTERDATA_KEY
);
8154 * The NT machine wants to know the biggest size of value and data
8156 * cf: MSDN EnumPrinterData remark section
8159 if ( !in_value_len
&& !in_data_len
&& (key_index
!= -1) )
8161 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8163 biggest_valuesize
= 0;
8164 biggest_datasize
= 0;
8166 num_values
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
8168 for ( i
=0; i
<num_values
; i
++ )
8170 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
8172 name_length
= strlen(val
->valuename
);
8173 if ( strlen(val
->valuename
) > biggest_valuesize
)
8174 biggest_valuesize
= name_length
;
8176 if ( val
->size
> biggest_datasize
)
8177 biggest_datasize
= val
->size
;
8179 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
8183 /* the value is an UNICODE string but real_value_size is the length
8184 in bytes including the trailing 0 */
8186 *out_value_len
= 2 * (1+biggest_valuesize
);
8187 *out_data_len
= biggest_datasize
;
8189 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
8195 * the value len is wrong in NT sp3
8196 * that's the number of bytes not the number of unicode chars
8199 if ( key_index
!= -1 )
8200 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, idx
);
8205 /* out_value should default to "" or else NT4 has
8206 problems unmarshalling the response */
8208 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8211 if((*out_value
=(uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8213 result
= WERR_NOMEM
;
8216 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, "", in_value_len
, 0);
8222 /* the data is counted in bytes */
8224 *out_max_data_len
= in_data_len
;
8225 *out_data_len
= in_data_len
;
8227 /* only allocate when given a non-zero data_len */
8229 if ( in_data_len
&& ((*data_out
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) )
8231 result
= WERR_NOMEM
;
8235 result
= WERR_NO_MORE_ITEMS
;
8241 * - counted in bytes in the request
8242 * - counted in UNICODE chars in the max reply
8243 * - counted in bytes in the real size
8245 * take a pause *before* coding not *during* coding
8249 *out_max_value_len
=(in_value_len
/sizeof(uint16
));
8251 if ( (*out_value
= (uint16
*)TALLOC_ZERO(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
8253 result
= WERR_NOMEM
;
8257 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, regval_name(val
), (size_t)in_value_len
, 0);
8265 *out_type
= regval_type( val
);
8267 /* data - counted in bytes */
8269 *out_max_data_len
= in_data_len
;
8270 if ( in_data_len
&& (*data_out
= (uint8
*)TALLOC_ZERO(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
)
8272 result
= WERR_NOMEM
;
8275 data_len
= regval_size(val
);
8276 if ( *data_out
&& data_len
)
8277 memcpy( *data_out
, regval_data_p(val
), data_len
);
8278 *out_data_len
= data_len
;
8282 free_a_printer(&printer
, 2);
8286 /****************************************************************************
8287 ****************************************************************************/
8289 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
8291 POLICY_HND
*handle
= &q_u
->handle
;
8292 UNISTR2
*value
= &q_u
->value
;
8293 uint32 type
= q_u
->type
;
8294 uint8
*data
= q_u
->data
;
8295 uint32 real_len
= q_u
->real_len
;
8297 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8299 WERROR status
= WERR_OK
;
8300 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8303 DEBUG(5,("spoolss_setprinterdata\n"));
8306 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8310 if ( Printer
->printer_type
== SPLHND_SERVER
) {
8311 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8312 return WERR_INVALID_PARAM
;
8315 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8319 * Access check : NT returns "access denied" if you make a
8320 * SetPrinterData call without the necessary privildge.
8321 * we were originally returning OK if nothing changed
8322 * which made Win2k issue **a lot** of SetPrinterData
8323 * when connecting to a printer --jerry
8326 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
8328 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8329 status
= WERR_ACCESS_DENIED
;
8333 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8334 if (!W_ERROR_IS_OK(status
))
8337 unistr2_to_ascii(valuename
, value
, sizeof(valuename
));
8340 * When client side code sets a magic printer data key, detect it and save
8341 * the current printer data and the magic key's data (its the DEVMODE) for
8342 * future printer/driver initializations.
8344 if ( (type
== REG_BINARY
) && strequal( valuename
, PHANTOM_DEVMODE_KEY
))
8346 /* Set devmode and printer initialization info */
8347 status
= save_driver_init( printer
, 2, data
, real_len
);
8349 srv_spoolss_reset_printerdata( printer
->info_2
->drivername
);
8353 status
= set_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
,
8354 type
, data
, real_len
);
8355 if ( W_ERROR_IS_OK(status
) )
8356 status
= mod_a_printer(printer
, 2);
8360 free_a_printer(&printer
, 2);
8365 /****************************************************************************
8366 ****************************************************************************/
8368 WERROR
_spoolss_resetprinter(pipes_struct
*p
, SPOOL_Q_RESETPRINTER
*q_u
, SPOOL_R_RESETPRINTER
*r_u
)
8370 POLICY_HND
*handle
= &q_u
->handle
;
8371 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8374 DEBUG(5,("_spoolss_resetprinter\n"));
8377 * All we do is to check to see if the handle and queue is valid.
8378 * This call really doesn't mean anything to us because we only
8379 * support RAW printing. --jerry
8383 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8387 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8391 /* blindly return success */
8396 /****************************************************************************
8397 ****************************************************************************/
8399 WERROR
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
8401 POLICY_HND
*handle
= &q_u
->handle
;
8402 UNISTR2
*value
= &q_u
->valuename
;
8404 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8406 WERROR status
= WERR_OK
;
8407 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8408 char *valuename
= NULL
;
8409 TALLOC_CTX
*ctx
= p
->mem_ctx
;
8411 DEBUG(5,("spoolss_deleteprinterdata\n"));
8414 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8418 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
8421 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8422 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties change denied by handle\n"));
8423 return WERR_ACCESS_DENIED
;
8426 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8427 if (!W_ERROR_IS_OK(status
))
8430 valuename
= unistr2_to_ascii_talloc(ctx
, value
);
8432 free_a_printer(&printer
, 2);
8436 status
= delete_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
);
8438 if ( W_ERROR_IS_OK(status
) )
8439 mod_a_printer( printer
, 2 );
8441 free_a_printer(&printer
, 2);
8442 TALLOC_FREE(valuename
);
8447 /****************************************************************************
8448 ****************************************************************************/
8450 WERROR
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
8452 POLICY_HND
*handle
= &q_u
->handle
;
8453 FORM
*form
= &q_u
->form
;
8454 nt_forms_struct tmpForm
;
8456 WERROR status
= WERR_OK
;
8457 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8460 nt_forms_struct
*list
=NULL
;
8461 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8463 DEBUG(5,("spoolss_addform\n"));
8466 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8471 /* forms can be added on printer of on the print server handle */
8473 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8475 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8478 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8479 if (!W_ERROR_IS_OK(status
))
8483 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8484 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8485 status
= WERR_ACCESS_DENIED
;
8489 /* can't add if builtin */
8491 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
8492 status
= WERR_ALREADY_EXISTS
;
8496 count
= get_ntforms(&list
);
8498 if(!add_a_form(&list
, form
, &count
)) {
8499 status
= WERR_NOMEM
;
8503 write_ntforms(&list
, count
);
8506 * ChangeID must always be set if this is a printer
8509 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8510 status
= mod_a_printer(printer
, 2);
8514 free_a_printer(&printer
, 2);
8520 /****************************************************************************
8521 ****************************************************************************/
8523 WERROR
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
8525 POLICY_HND
*handle
= &q_u
->handle
;
8526 UNISTR2
*form_name
= &q_u
->name
;
8527 nt_forms_struct tmpForm
;
8529 nt_forms_struct
*list
=NULL
;
8530 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8532 WERROR status
= WERR_OK
;
8533 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8535 DEBUG(5,("spoolss_deleteform\n"));
8538 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8542 /* forms can be deleted on printer of on the print server handle */
8544 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8546 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8549 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8550 if (!W_ERROR_IS_OK(status
))
8554 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8555 DEBUG(2,("_spoolss_deleteform: denied by handle permissions.\n"));
8556 status
= WERR_ACCESS_DENIED
;
8560 /* can't delete if builtin */
8562 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
8563 status
= WERR_INVALID_PARAM
;
8567 count
= get_ntforms(&list
);
8569 if ( !delete_a_form(&list
, form_name
, &count
, &status
))
8573 * ChangeID must always be set if this is a printer
8576 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8577 status
= mod_a_printer(printer
, 2);
8581 free_a_printer(&printer
, 2);
8587 /****************************************************************************
8588 ****************************************************************************/
8590 WERROR
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
8592 POLICY_HND
*handle
= &q_u
->handle
;
8593 FORM
*form
= &q_u
->form
;
8594 nt_forms_struct tmpForm
;
8596 WERROR status
= WERR_OK
;
8597 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8600 nt_forms_struct
*list
=NULL
;
8601 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8603 DEBUG(5,("spoolss_setform\n"));
8606 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8610 /* forms can be modified on printer of on the print server handle */
8612 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8614 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
8617 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
8618 if (!W_ERROR_IS_OK(status
))
8622 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
8623 DEBUG(2,("_spoolss_setform: denied by handle permissions\n"));
8624 status
= WERR_ACCESS_DENIED
;
8628 /* can't set if builtin */
8629 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
8630 status
= WERR_INVALID_PARAM
;
8634 count
= get_ntforms(&list
);
8635 update_a_form(&list
, form
, count
);
8636 write_ntforms(&list
, count
);
8639 * ChangeID must always be set if this is a printer
8642 if ( Printer
->printer_type
== SPLHND_PRINTER
)
8643 status
= mod_a_printer(printer
, 2);
8648 free_a_printer(&printer
, 2);
8654 /****************************************************************************
8655 enumprintprocessors level 1.
8656 ****************************************************************************/
8658 static WERROR
enumprintprocessors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8660 PRINTPROCESSOR_1
*info_1
=NULL
;
8661 WERROR result
= WERR_OK
;
8663 if((info_1
= SMB_MALLOC_P(PRINTPROCESSOR_1
)) == NULL
)
8668 init_unistr(&info_1
->name
, "winprint");
8670 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
8672 if (*needed
> offered
) {
8673 result
= WERR_INSUFFICIENT_BUFFER
;
8677 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8678 result
= WERR_NOMEM
;
8682 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
8687 if ( !W_ERROR_IS_OK(result
) )
8693 /****************************************************************************
8694 ****************************************************************************/
8696 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
8698 uint32 level
= q_u
->level
;
8699 RPC_BUFFER
*buffer
= NULL
;
8700 uint32 offered
= q_u
->offered
;
8701 uint32
*needed
= &r_u
->needed
;
8702 uint32
*returned
= &r_u
->returned
;
8704 /* that's an [in out] buffer */
8706 if (!q_u
->buffer
&& (offered
!=0)) {
8707 return WERR_INVALID_PARAM
;
8710 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8711 buffer
= r_u
->buffer
;
8713 DEBUG(5,("spoolss_enumprintprocessors\n"));
8716 * Enumerate the print processors ...
8718 * Just reply with "winprint", to keep NT happy
8719 * and I can use my nice printer checker.
8727 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
8729 return WERR_UNKNOWN_LEVEL
;
8733 /****************************************************************************
8734 enumprintprocdatatypes level 1.
8735 ****************************************************************************/
8737 static WERROR
enumprintprocdatatypes_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8739 PRINTPROCDATATYPE_1
*info_1
=NULL
;
8740 WERROR result
= WERR_OK
;
8742 if((info_1
= SMB_MALLOC_P(PRINTPROCDATATYPE_1
)) == NULL
)
8747 init_unistr(&info_1
->name
, "RAW");
8749 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
8751 if (*needed
> offered
) {
8752 result
= WERR_INSUFFICIENT_BUFFER
;
8756 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8757 result
= WERR_NOMEM
;
8761 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
8766 if ( !W_ERROR_IS_OK(result
) )
8772 /****************************************************************************
8773 ****************************************************************************/
8775 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
8777 uint32 level
= q_u
->level
;
8778 RPC_BUFFER
*buffer
= NULL
;
8779 uint32 offered
= q_u
->offered
;
8780 uint32
*needed
= &r_u
->needed
;
8781 uint32
*returned
= &r_u
->returned
;
8783 /* that's an [in out] buffer */
8785 if (!q_u
->buffer
&& (offered
!=0)) {
8786 return WERR_INVALID_PARAM
;
8789 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8790 buffer
= r_u
->buffer
;
8792 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8799 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
8801 return WERR_UNKNOWN_LEVEL
;
8805 /****************************************************************************
8806 enumprintmonitors level 1.
8807 ****************************************************************************/
8809 static WERROR
enumprintmonitors_level_1(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8811 PRINTMONITOR_1
*info_1
;
8812 WERROR result
= WERR_OK
;
8815 if((info_1
= SMB_MALLOC_ARRAY(PRINTMONITOR_1
, 2)) == NULL
)
8820 init_unistr(&(info_1
[0].name
), SPL_LOCAL_PORT
);
8821 init_unistr(&(info_1
[1].name
), SPL_TCPIP_PORT
);
8823 for ( i
=0; i
<*returned
; i
++ ) {
8824 *needed
+= spoolss_size_printmonitor_info_1(&info_1
[i
]);
8827 if (*needed
> offered
) {
8828 result
= WERR_INSUFFICIENT_BUFFER
;
8832 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8833 result
= WERR_NOMEM
;
8837 for ( i
=0; i
<*returned
; i
++ ) {
8838 smb_io_printmonitor_info_1("", buffer
, &info_1
[i
], 0);
8844 if ( !W_ERROR_IS_OK(result
) )
8850 /****************************************************************************
8851 enumprintmonitors level 2.
8852 ****************************************************************************/
8854 static WERROR
enumprintmonitors_level_2(RPC_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
8856 PRINTMONITOR_2
*info_2
;
8857 WERROR result
= WERR_OK
;
8860 if((info_2
= SMB_MALLOC_ARRAY(PRINTMONITOR_2
, 2)) == NULL
)
8865 init_unistr( &(info_2
[0].name
), SPL_LOCAL_PORT
);
8866 init_unistr( &(info_2
[0].environment
), "Windows NT X86" );
8867 init_unistr( &(info_2
[0].dll_name
), "localmon.dll" );
8869 init_unistr( &(info_2
[1].name
), SPL_TCPIP_PORT
);
8870 init_unistr( &(info_2
[1].environment
), "Windows NT X86" );
8871 init_unistr( &(info_2
[1].dll_name
), "tcpmon.dll" );
8873 for ( i
=0; i
<*returned
; i
++ ) {
8874 *needed
+= spoolss_size_printmonitor_info_2(&info_2
[i
]);
8877 if (*needed
> offered
) {
8878 result
= WERR_INSUFFICIENT_BUFFER
;
8882 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8883 result
= WERR_NOMEM
;
8887 for ( i
=0; i
<*returned
; i
++ ) {
8888 smb_io_printmonitor_info_2("", buffer
, &info_2
[i
], 0);
8894 if ( !W_ERROR_IS_OK(result
) )
8900 /****************************************************************************
8901 ****************************************************************************/
8903 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
8905 uint32 level
= q_u
->level
;
8906 RPC_BUFFER
*buffer
= NULL
;
8907 uint32 offered
= q_u
->offered
;
8908 uint32
*needed
= &r_u
->needed
;
8909 uint32
*returned
= &r_u
->returned
;
8911 /* that's an [in out] buffer */
8913 if (!q_u
->buffer
&& (offered
!=0)) {
8914 return WERR_INVALID_PARAM
;
8917 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
8918 buffer
= r_u
->buffer
;
8920 DEBUG(5,("spoolss_enumprintmonitors\n"));
8923 * Enumerate the print monitors ...
8925 * Just reply with "Local Port", to keep NT happy
8926 * and I can use my nice printer checker.
8934 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
8936 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
8938 return WERR_UNKNOWN_LEVEL
;
8942 /****************************************************************************
8943 ****************************************************************************/
8945 static WERROR
getjob_level_1(print_queue_struct
**queue
, int count
, int snum
,
8946 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8947 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
8952 JOB_INFO_1
*info_1
=NULL
;
8953 WERROR result
= WERR_OK
;
8955 info_1
=SMB_MALLOC_P(JOB_INFO_1
);
8957 if (info_1
== NULL
) {
8961 for (i
=0; i
<count
&& found
==False
; i
++) {
8962 if ((*queue
)[i
].job
==(int)jobid
)
8968 /* NT treats not found as bad param... yet another bad choice */
8969 return WERR_INVALID_PARAM
;
8972 fill_job_info_1( info_1
, &((*queue
)[i
-1]), i
, snum
, ntprinter
);
8974 *needed
+= spoolss_size_job_info_1(info_1
);
8976 if (*needed
> offered
) {
8977 result
= WERR_INSUFFICIENT_BUFFER
;
8981 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
8982 result
= WERR_NOMEM
;
8986 smb_io_job_info_1("", buffer
, info_1
, 0);
8994 /****************************************************************************
8995 ****************************************************************************/
8997 static WERROR
getjob_level_2(print_queue_struct
**queue
, int count
, int snum
,
8998 NT_PRINTER_INFO_LEVEL
*ntprinter
,
8999 uint32 jobid
, RPC_BUFFER
*buffer
, uint32 offered
,
9006 DEVICEMODE
*devmode
= NULL
;
9007 NT_DEVICEMODE
*nt_devmode
= NULL
;
9009 if ( !(info_2
=SMB_MALLOC_P(JOB_INFO_2
)) )
9012 ZERO_STRUCTP(info_2
);
9014 for ( i
=0; i
<count
&& found
==False
; i
++ )
9016 if ((*queue
)[i
].job
== (int)jobid
)
9021 /* NT treats not found as bad param... yet another bad
9023 result
= WERR_INVALID_PARAM
;
9028 * if the print job does not have a DEVMODE associated with it,
9029 * just use the one for the printer. A NULL devicemode is not
9030 * a failure condition
9033 if ( !(nt_devmode
=print_job_devmode( lp_const_servicename(snum
), jobid
)) )
9034 devmode
= construct_dev_mode(lp_const_servicename(snum
));
9036 if ((devmode
= SMB_MALLOC_P(DEVICEMODE
)) != NULL
) {
9037 ZERO_STRUCTP( devmode
);
9038 convert_nt_devicemode( devmode
, nt_devmode
);
9042 fill_job_info_2(info_2
, &((*queue
)[i
-1]), i
, snum
, ntprinter
, devmode
);
9044 *needed
+= spoolss_size_job_info_2(info_2
);
9046 if (*needed
> offered
) {
9047 result
= WERR_INSUFFICIENT_BUFFER
;
9051 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9052 result
= WERR_NOMEM
;
9056 smb_io_job_info_2("", buffer
, info_2
, 0);
9061 /* Cleanup allocated memory */
9063 free_job_info_2(info_2
); /* Also frees devmode */
9069 /****************************************************************************
9070 ****************************************************************************/
9072 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
9074 POLICY_HND
*handle
= &q_u
->handle
;
9075 uint32 jobid
= q_u
->jobid
;
9076 uint32 level
= q_u
->level
;
9077 RPC_BUFFER
*buffer
= NULL
;
9078 uint32 offered
= q_u
->offered
;
9079 uint32
*needed
= &r_u
->needed
;
9080 WERROR wstatus
= WERR_OK
;
9081 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
9084 print_queue_struct
*queue
= NULL
;
9085 print_status_struct prt_status
;
9087 /* that's an [in out] buffer */
9089 if (!q_u
->buffer
&& (offered
!=0)) {
9090 return WERR_INVALID_PARAM
;
9093 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9094 buffer
= r_u
->buffer
;
9096 DEBUG(5,("spoolss_getjob\n"));
9100 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9103 wstatus
= get_a_printer(NULL
, &ntprinter
, 2, lp_servicename(snum
));
9104 if ( !W_ERROR_IS_OK(wstatus
) )
9107 count
= print_queue_status(snum
, &queue
, &prt_status
);
9109 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9110 count
, prt_status
.status
, prt_status
.message
));
9114 wstatus
= getjob_level_1(&queue
, count
, snum
, ntprinter
, jobid
,
9115 buffer
, offered
, needed
);
9118 wstatus
= getjob_level_2(&queue
, count
, snum
, ntprinter
, jobid
,
9119 buffer
, offered
, needed
);
9122 wstatus
= WERR_UNKNOWN_LEVEL
;
9127 free_a_printer( &ntprinter
, 2 );
9132 /********************************************************************
9133 spoolss_getprinterdataex
9135 From MSDN documentation of GetPrinterDataEx: pass request
9136 to GetPrinterData if key is "PrinterDriverData".
9137 ********************************************************************/
9139 WERROR
_spoolss_getprinterdataex(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATAEX
*q_u
, SPOOL_R_GETPRINTERDATAEX
*r_u
)
9141 POLICY_HND
*handle
= &q_u
->handle
;
9142 uint32 in_size
= q_u
->size
;
9143 uint32
*type
= &r_u
->type
;
9144 uint32
*out_size
= &r_u
->size
;
9145 uint8
**data
= &r_u
->data
;
9146 uint32
*needed
= &r_u
->needed
;
9147 fstring keyname
, valuename
;
9149 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9151 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9153 WERROR status
= WERR_OK
;
9155 DEBUG(4,("_spoolss_getprinterdataex\n"));
9157 unistr2_to_ascii(keyname
, &q_u
->keyname
, sizeof(keyname
));
9158 unistr2_to_ascii(valuename
, &q_u
->valuename
, sizeof(valuename
));
9160 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
9161 keyname
, valuename
));
9163 /* in case of problem, return some default values */
9167 *out_size
= in_size
;
9170 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9171 status
= WERR_BADFID
;
9175 /* Is the handle to a printer or to the server? */
9177 if (Printer
->printer_type
== SPLHND_SERVER
) {
9178 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
9179 status
= WERR_INVALID_PARAM
;
9183 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9186 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9187 if ( !W_ERROR_IS_OK(status
) )
9190 /* check to see if the keyname is valid */
9191 if ( !strlen(keyname
) ) {
9192 status
= WERR_INVALID_PARAM
;
9196 if ( lookup_printerkey( printer
->info_2
->data
, keyname
) == -1 ) {
9197 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname
));
9198 free_a_printer( &printer
, 2 );
9199 status
= WERR_BADFILE
;
9203 /* When given a new keyname, we should just create it */
9205 status
= get_printer_dataex( p
->mem_ctx
, printer
, keyname
, valuename
, type
, data
, needed
, in_size
);
9207 if (*needed
> *out_size
)
9208 status
= WERR_MORE_DATA
;
9211 if ( !W_ERROR_IS_OK(status
) )
9213 DEBUG(5, ("error: allocating %d\n", *out_size
));
9215 /* reply this param doesn't exist */
9219 if( (*data
=(uint8
*)TALLOC_ZERO(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
) {
9220 status
= WERR_NOMEM
;
9229 free_a_printer( &printer
, 2 );
9234 /********************************************************************
9235 * spoolss_setprinterdataex
9236 ********************************************************************/
9238 WERROR
_spoolss_setprinterdataex(pipes_struct
*p
, SPOOL_Q_SETPRINTERDATAEX
*q_u
, SPOOL_R_SETPRINTERDATAEX
*r_u
)
9240 POLICY_HND
*handle
= &q_u
->handle
;
9241 uint32 type
= q_u
->type
;
9242 uint8
*data
= q_u
->data
;
9243 uint32 real_len
= q_u
->real_len
;
9245 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9247 WERROR status
= WERR_OK
;
9248 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9253 DEBUG(4,("_spoolss_setprinterdataex\n"));
9255 /* From MSDN documentation of SetPrinterDataEx: pass request to
9256 SetPrinterData if key is "PrinterDriverData" */
9259 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9263 if ( Printer
->printer_type
== SPLHND_SERVER
) {
9264 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
9265 return WERR_INVALID_PARAM
;
9268 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9272 * Access check : NT returns "access denied" if you make a
9273 * SetPrinterData call without the necessary privildge.
9274 * we were originally returning OK if nothing changed
9275 * which made Win2k issue **a lot** of SetPrinterData
9276 * when connecting to a printer --jerry
9279 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
9281 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
9282 return WERR_ACCESS_DENIED
;
9285 status
= get_a_printer(Printer
, &printer
, 2, lp_servicename(snum
));
9286 if (!W_ERROR_IS_OK(status
))
9289 unistr2_to_ascii( valuename
, &q_u
->value
, sizeof(valuename
));
9290 unistr2_to_ascii( keyname
, &q_u
->key
, sizeof(keyname
));
9292 /* check for OID in valuename */
9294 if ( (oid_string
= strchr( valuename
, ',' )) != NULL
)
9300 /* save the registry data */
9302 status
= set_printer_dataex( printer
, keyname
, valuename
, type
, data
, real_len
);
9304 if ( W_ERROR_IS_OK(status
) )
9306 /* save the OID if one was specified */
9308 fstrcat( keyname
, "\\" );
9309 fstrcat( keyname
, SPOOL_OID_KEY
);
9312 * I'm not checking the status here on purpose. Don't know
9313 * if this is right, but I'm returning the status from the
9314 * previous set_printer_dataex() call. I have no idea if
9315 * this is right. --jerry
9318 set_printer_dataex( printer
, keyname
, valuename
,
9319 REG_SZ
, (uint8
*)oid_string
,
9320 strlen(oid_string
)+1 );
9323 status
= mod_a_printer(printer
, 2);
9326 free_a_printer(&printer
, 2);
9332 /********************************************************************
9333 * spoolss_deleteprinterdataex
9334 ********************************************************************/
9336 WERROR
_spoolss_deleteprinterdataex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATAEX
*q_u
, SPOOL_R_DELETEPRINTERDATAEX
*r_u
)
9338 POLICY_HND
*handle
= &q_u
->handle
;
9339 UNISTR2
*value
= &q_u
->valuename
;
9340 UNISTR2
*key
= &q_u
->keyname
;
9342 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9344 WERROR status
= WERR_OK
;
9345 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
9346 char *valuename
= NULL
;
9347 char *keyname
= NULL
;
9348 TALLOC_CTX
*ctx
= p
->mem_ctx
;
9350 DEBUG(5,("spoolss_deleteprinterdataex\n"));
9353 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9357 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9360 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9361 DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n"));
9362 return WERR_ACCESS_DENIED
;
9365 valuename
= unistr2_to_ascii_talloc(ctx
, value
);
9366 keyname
= unistr2_to_ascii_talloc(ctx
, key
);
9367 if (!valuename
|| !keyname
) {
9371 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9372 if (!W_ERROR_IS_OK(status
))
9375 status
= delete_printer_dataex( printer
, keyname
, valuename
);
9377 if ( W_ERROR_IS_OK(status
) )
9378 mod_a_printer( printer
, 2 );
9380 free_a_printer(&printer
, 2);
9385 /********************************************************************
9386 * spoolss_enumprinterkey
9387 ********************************************************************/
9390 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
9393 fstring
*keynames
= NULL
;
9394 uint16
*enumkeys
= NULL
;
9397 POLICY_HND
*handle
= &q_u
->handle
;
9398 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9399 NT_PRINTER_DATA
*data
;
9400 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9402 WERROR status
= WERR_BADFILE
;
9405 DEBUG(4,("_spoolss_enumprinterkey\n"));
9408 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9412 if ( !get_printer_snum(p
,handle
, &snum
, NULL
) )
9415 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9416 if (!W_ERROR_IS_OK(status
))
9419 /* get the list of subkey names */
9421 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9422 data
= printer
->info_2
->data
;
9424 num_keys
= get_printer_subkeys( data
, key
, &keynames
);
9426 if ( num_keys
== -1 ) {
9427 status
= WERR_BADFILE
;
9431 printerkey_len
= init_unistr_array( &enumkeys
, keynames
, NULL
);
9433 r_u
->needed
= printerkey_len
*2;
9435 if ( q_u
->size
< r_u
->needed
) {
9436 status
= WERR_MORE_DATA
;
9440 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, printerkey_len
, enumkeys
)) {
9441 status
= WERR_NOMEM
;
9447 if ( q_u
->size
< r_u
->needed
)
9448 status
= WERR_MORE_DATA
;
9451 free_a_printer( &printer
, 2 );
9452 SAFE_FREE( keynames
);
9457 /********************************************************************
9458 * spoolss_deleteprinterkey
9459 ********************************************************************/
9461 WERROR
_spoolss_deleteprinterkey(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERKEY
*q_u
, SPOOL_R_DELETEPRINTERKEY
*r_u
)
9463 POLICY_HND
*handle
= &q_u
->handle
;
9464 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9466 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9470 DEBUG(5,("spoolss_deleteprinterkey\n"));
9473 DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
9477 /* if keyname == NULL, return error */
9479 if ( !q_u
->keyname
.buffer
)
9480 return WERR_INVALID_PARAM
;
9482 if (!get_printer_snum(p
, handle
, &snum
, NULL
))
9485 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
9486 DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n"));
9487 return WERR_ACCESS_DENIED
;
9490 status
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9491 if (!W_ERROR_IS_OK(status
))
9494 /* delete the key and all subneys */
9496 unistr2_to_ascii(key
, &q_u
->keyname
, sizeof(key
));
9498 status
= delete_all_printer_data( printer
->info_2
, key
);
9500 if ( W_ERROR_IS_OK(status
) )
9501 status
= mod_a_printer(printer
, 2);
9503 free_a_printer( &printer
, 2 );
9509 /********************************************************************
9510 * spoolss_enumprinterdataex
9511 ********************************************************************/
9513 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
9515 POLICY_HND
*handle
= &q_u
->handle
;
9516 uint32 in_size
= q_u
->size
;
9519 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
9520 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
9521 NT_PRINTER_DATA
*p_data
;
9523 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
9528 REGISTRY_VALUE
*val
;
9533 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9536 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle
)));
9541 * first check for a keyname of NULL or "". Win2k seems to send
9542 * this a lot and we should send back WERR_INVALID_PARAM
9543 * no need to spend time looking up the printer in this case.
9547 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9548 if ( !strlen(key
) ) {
9549 result
= WERR_INVALID_PARAM
;
9553 /* get the printer off of disk */
9555 if (!get_printer_snum(p
,handle
, &snum
, NULL
))
9558 ZERO_STRUCT(printer
);
9559 result
= get_a_printer(Printer
, &printer
, 2, lp_const_servicename(snum
));
9560 if (!W_ERROR_IS_OK(result
))
9563 /* now look for a match on the key name */
9565 p_data
= printer
->info_2
->data
;
9567 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
));
9568 if ( (key_index
= lookup_printerkey( p_data
, key
)) == -1 )
9570 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
9571 result
= WERR_INVALID_PARAM
;
9578 /* allocate the memory for the array of pointers -- if necessary */
9580 num_entries
= regval_ctr_numvals( p_data
->keys
[key_index
].values
);
9583 if ( (enum_values
=TALLOC_ARRAY(p
->mem_ctx
, PRINTER_ENUM_VALUES
, num_entries
)) == NULL
)
9585 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9586 (unsigned long)num_entries
*sizeof(PRINTER_ENUM_VALUES
)));
9587 result
= WERR_NOMEM
;
9591 memset( enum_values
, 0x0, num_entries
*sizeof(PRINTER_ENUM_VALUES
) );
9595 * loop through all params and build the array to pass
9596 * back to the client
9599 for ( i
=0; i
<num_entries
; i
++ )
9601 /* lookup the registry value */
9603 val
= regval_ctr_specific_value( p_data
->keys
[key_index
].values
, i
);
9604 DEBUG(10,("retrieved value number [%d] [%s]\n", i
, regval_name(val
) ));
9608 value_name
= regval_name( val
);
9609 init_unistr( &enum_values
[i
].valuename
, value_name
);
9610 enum_values
[i
].value_len
= (strlen(value_name
)+1) * 2;
9611 enum_values
[i
].type
= regval_type( val
);
9613 data_len
= regval_size( val
);
9615 if ( !(enum_values
[i
].data
= (uint8
*)TALLOC_MEMDUP(p
->mem_ctx
, regval_data_p(val
), data_len
)) )
9617 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9619 result
= WERR_NOMEM
;
9623 enum_values
[i
].data_len
= data_len
;
9625 /* keep track of the size of the array in bytes */
9627 needed
+= spoolss_size_printer_enum_values(&enum_values
[i
]);
9630 /* housekeeping information in the reply */
9632 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9633 * the hand marshalled container size is a multiple
9634 * of 4 bytes for RPC alignment.
9638 needed
+= 4-(needed
% 4);
9641 r_u
->needed
= needed
;
9642 r_u
->returned
= num_entries
;
9644 if (needed
> in_size
) {
9645 result
= WERR_MORE_DATA
;
9649 /* copy data into the reply */
9651 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9652 response buffer size is != the offered buffer size
9654 r_u->ctr.size = r_u->needed;
9656 r_u
->ctr
.size
= in_size
;
9658 r_u
->ctr
.size_of_array
= r_u
->returned
;
9659 r_u
->ctr
.values
= enum_values
;
9663 free_a_printer(&printer
, 2);
9668 /****************************************************************************
9669 ****************************************************************************/
9671 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1
*info
, const char *name
)
9673 init_unistr(&info
->name
, name
);
9676 static WERROR
getprintprocessordirectory_level_1(UNISTR2
*name
,
9677 UNISTR2
*environment
,
9682 char *long_archi
= NULL
;
9683 PRINTPROCESSOR_DIRECTORY_1
*info
=NULL
;
9684 WERROR result
= WERR_OK
;
9685 TALLOC_CTX
*ctx
= talloc_tos();
9687 long_archi
= unistr2_to_ascii_talloc(ctx
, environment
);
9692 if (!get_short_archi(long_archi
))
9693 return WERR_INVALID_ENVIRONMENT
;
9695 if((info
=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1
)) == NULL
)
9698 fill_printprocessordirectory_1(info
, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9700 *needed
+= spoolss_size_printprocessordirectory_info_1(info
);
9702 if (*needed
> offered
) {
9703 result
= WERR_INSUFFICIENT_BUFFER
;
9707 if (!rpcbuf_alloc_size(buffer
, *needed
)) {
9708 result
= WERR_INSUFFICIENT_BUFFER
;
9712 smb_io_printprocessordirectory_1("", buffer
, info
, 0);
9720 WERROR
_spoolss_getprintprocessordirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTPROCESSORDIRECTORY
*q_u
, SPOOL_R_GETPRINTPROCESSORDIRECTORY
*r_u
)
9722 uint32 level
= q_u
->level
;
9723 RPC_BUFFER
*buffer
= NULL
;
9724 uint32 offered
= q_u
->offered
;
9725 uint32
*needed
= &r_u
->needed
;
9728 /* that's an [in out] buffer */
9730 if (!q_u
->buffer
&& (offered
!=0)) {
9731 return WERR_INVALID_PARAM
;
9734 rpcbuf_move(q_u
->buffer
, &r_u
->buffer
);
9735 buffer
= r_u
->buffer
;
9737 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9743 result
= getprintprocessordirectory_level_1
9744 (&q_u
->name
, &q_u
->environment
, buffer
, offered
, needed
);
9747 result
= WERR_UNKNOWN_LEVEL
;
9753 /*******************************************************************
9754 Streams the monitor UI DLL name in UNICODE
9755 *******************************************************************/
9757 static WERROR
xcvtcp_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9758 RPC_BUFFER
*out
, uint32
*needed
)
9760 const char *dllname
= "tcpmonui.dll";
9762 *needed
= (strlen(dllname
)+1) * 2;
9764 if ( rpcbuf_get_size(out
) < *needed
) {
9765 return WERR_INSUFFICIENT_BUFFER
;
9768 if ( !make_monitorui_buf( out
, dllname
) ) {
9775 /*******************************************************************
9776 Create a new TCP/IP port
9777 *******************************************************************/
9779 static WERROR
xcvtcp_addport( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9780 RPC_BUFFER
*out
, uint32
*needed
)
9782 NT_PORT_DATA_1 port1
;
9783 TALLOC_CTX
*ctx
= talloc_tos();
9784 char *device_uri
= NULL
;
9786 ZERO_STRUCT( port1
);
9788 /* convert to our internal port data structure */
9790 if ( !convert_port_data_1( &port1
, in
) ) {
9794 /* create the device URI and call the add_port_hook() */
9796 switch ( port1
.protocol
) {
9797 case PORT_PROTOCOL_DIRECT
:
9798 device_uri
= talloc_asprintf(ctx
,
9799 "socket://%s:%d/", port1
.hostaddr
, port1
.port
);
9802 case PORT_PROTOCOL_LPR
:
9803 device_uri
= talloc_asprintf(ctx
,
9804 "lpr://%s/%s", port1
.hostaddr
, port1
.queue
);
9808 return WERR_UNKNOWN_PORT
;
9815 return add_port_hook(ctx
, token
, port1
.name
, device_uri
);
9818 /*******************************************************************
9819 *******************************************************************/
9821 struct xcv_api_table xcvtcp_cmds
[] = {
9822 { "MonitorUI", xcvtcp_monitorui
},
9823 { "AddPort", xcvtcp_addport
},
9827 static WERROR
process_xcvtcp_command( NT_USER_TOKEN
*token
, const char *command
,
9828 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9833 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command
));
9835 for ( i
=0; xcvtcp_cmds
[i
].name
; i
++ ) {
9836 if ( strcmp( command
, xcvtcp_cmds
[i
].name
) == 0 )
9837 return xcvtcp_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9840 return WERR_BADFUNC
;
9843 /*******************************************************************
9844 *******************************************************************/
9845 #if 0 /* don't support management using the "Local Port" monitor */
9847 static WERROR
xcvlocal_monitorui( NT_USER_TOKEN
*token
, RPC_BUFFER
*in
,
9848 RPC_BUFFER
*out
, uint32
*needed
)
9850 const char *dllname
= "localui.dll";
9852 *needed
= (strlen(dllname
)+1) * 2;
9854 if ( rpcbuf_get_size(out
) < *needed
) {
9855 return WERR_INSUFFICIENT_BUFFER
;
9858 if ( !make_monitorui_buf( out
, dllname
)) {
9865 /*******************************************************************
9866 *******************************************************************/
9868 struct xcv_api_table xcvlocal_cmds
[] = {
9869 { "MonitorUI", xcvlocal_monitorui
},
9873 struct xcv_api_table xcvlocal_cmds
[] = {
9880 /*******************************************************************
9881 *******************************************************************/
9883 static WERROR
process_xcvlocal_command( NT_USER_TOKEN
*token
, const char *command
,
9884 RPC_BUFFER
*inbuf
, RPC_BUFFER
*outbuf
,
9889 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command
));
9891 for ( i
=0; xcvlocal_cmds
[i
].name
; i
++ ) {
9892 if ( strcmp( command
, xcvlocal_cmds
[i
].name
) == 0 )
9893 return xcvlocal_cmds
[i
].fn( token
, inbuf
, outbuf
, needed
);
9895 return WERR_BADFUNC
;
9898 /*******************************************************************
9899 *******************************************************************/
9901 WERROR
_spoolss_xcvdataport(pipes_struct
*p
, SPOOL_Q_XCVDATAPORT
*q_u
, SPOOL_R_XCVDATAPORT
*r_u
)
9903 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
9907 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u
->handle
)));
9911 /* Has to be a handle to the TCP/IP port monitor */
9913 if ( !(Printer
->printer_type
& (SPLHND_PORTMON_LOCAL
|SPLHND_PORTMON_TCP
)) ) {
9914 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
9918 /* requires administrative access to the server */
9920 if ( !(Printer
->access_granted
& SERVER_ACCESS_ADMINISTER
) ) {
9921 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
9922 return WERR_ACCESS_DENIED
;
9925 /* Get the command name. There's numerous commands supported by the
9926 TCPMON interface. */
9928 rpcstr_pull(command
, q_u
->dataname
.buffer
, sizeof(command
),
9929 q_u
->dataname
.uni_str_len
*2, 0);
9931 /* Allocate the outgoing buffer */
9933 rpcbuf_init( &r_u
->outdata
, q_u
->offered
, p
->mem_ctx
);
9935 switch ( Printer
->printer_type
) {
9936 case SPLHND_PORTMON_TCP
:
9937 return process_xcvtcp_command( p
->pipe_user
.nt_user_token
, command
,
9938 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9939 case SPLHND_PORTMON_LOCAL
:
9940 return process_xcvlocal_command( p
->pipe_user
.nt_user_token
, command
,
9941 &q_u
->indata
, &r_u
->outdata
, &r_u
->needed
);
9944 return WERR_INVALID_PRINT_MONITOR
;