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-2002,
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 2 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, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
27 up, all the errors returned are DOS errors, not NT status codes. */
32 #define DBGC_CLASS DBGC_RPC_SRV
33 /* #define EMULATE_WIN2K_HACK 1 */
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_"
41 #define PRINTER_HANDLE_IS_PRINTER 0
42 #define PRINTER_HANDLE_IS_PRINTSERVER 1
44 /* Table to map the driver version */
46 char * drv_ver_to_os
[] = {
47 "WIN9X", /* driver version/cversion 0 */
49 "WINNT", /* driver version/cversion 2 */
50 "WIN2K", /* driver version/cversion 3 */
60 /* structure to store the printer handles */
61 /* and a reference to what it's pointing to */
62 /* and the notify info asked about */
63 /* that's the central struct */
64 typedef struct _Printer
{
65 struct _Printer
*prev
, *next
;
66 BOOL document_started
;
68 uint32 jobid
; /* jobid in printing backend */
72 fstring printerservername
;
75 uint32 access_granted
;
81 SPOOL_NOTIFY_OPTION
*option
;
82 POLICY_HND client_hnd
;
83 uint32 client_connected
;
91 /* devmode sent in the OpenPrinter() call */
92 NT_DEVICEMODE
*nt_devmode
;
96 static Printer_entry
*printers_list
;
98 typedef struct _counter_printer_0
{
106 static ubi_dlList counter_list
;
108 static struct cli_state notify_cli
; /* print notify back-channel */
109 static uint32 smb_connections
=0;
112 /* in printing/nt_printing.c */
114 extern STANDARD_MAPPING printer_std_mapping
, printserver_std_mapping
;
116 #define OUR_HANDLE(hnd) (((hnd)==NULL)?"NULL":(IVAL((hnd)->data5,4)==(uint32)sys_getpid()?"OURS":"OTHER")), \
117 ((unsigned int)IVAL((hnd)->data5,4)),((unsigned int)sys_getpid())
119 /* translate between internal status numbers and NT status numbers */
120 static int nt_printj_status(int v
)
126 return JOB_STATUS_PAUSED
;
128 return JOB_STATUS_SPOOLING
;
130 return JOB_STATUS_PRINTING
;
132 return JOB_STATUS_ERROR
;
134 return JOB_STATUS_DELETING
;
136 return JOB_STATUS_OFFLINE
;
138 return JOB_STATUS_PAPEROUT
;
140 return JOB_STATUS_PRINTED
;
142 return JOB_STATUS_DELETED
;
144 return JOB_STATUS_BLOCKED
;
145 case LPQ_USER_INTERVENTION
:
146 return JOB_STATUS_USER_INTERVENTION
;
151 static int nt_printq_status(int v
)
155 return PRINTER_STATUS_PAUSED
;
164 /****************************************************************************
165 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
166 ****************************************************************************/
168 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION
**pp
)
173 SAFE_FREE((*pp
)->ctr
.type
);
177 /***************************************************************************
178 Disconnect from the client
179 ****************************************************************************/
181 static void srv_spoolss_replycloseprinter(POLICY_HND
*handle
)
185 /* weird if the test succeds !!! */
186 if (smb_connections
==0) {
187 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
191 result
= cli_spoolss_reply_close_printer(¬ify_cli
, notify_cli
.mem_ctx
, handle
);
193 if (!W_ERROR_IS_OK(result
))
194 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
195 dos_errstr(result
)));
197 /* if it's the last connection, deconnect the IPC$ share */
198 if (smb_connections
==1) {
199 cli_nt_session_close(¬ify_cli
);
200 cli_ulogoff(¬ify_cli
);
201 cli_shutdown(¬ify_cli
);
202 message_deregister(MSG_PRINTER_NOTIFY2
);
204 /* Tell the connections db we're no longer interested in
205 * printer notify messages. */
207 register_message_flags( False
, FLAG_MSG_PRINTING
);
213 /****************************************************************************
214 Functions to free a printer entry datastruct.
215 ****************************************************************************/
217 static void free_printer_entry(void *ptr
)
219 Printer_entry
*Printer
= (Printer_entry
*)ptr
;
221 if (Printer
->notify
.client_connected
==True
)
222 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
224 Printer
->notify
.flags
=0;
225 Printer
->notify
.options
=0;
226 Printer
->notify
.localmachine
[0]='\0';
227 Printer
->notify
.printerlocal
=0;
228 free_spool_notify_option(&Printer
->notify
.option
);
229 Printer
->notify
.option
=NULL
;
230 Printer
->notify
.client_connected
=False
;
232 free_nt_devicemode( &Printer
->nt_devmode
);
234 /* Remove from the internal list. */
235 DLIST_REMOVE(printers_list
, Printer
);
240 /****************************************************************************
241 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
242 ****************************************************************************/
244 SPOOL_NOTIFY_OPTION
*dup_spool_notify_option(SPOOL_NOTIFY_OPTION
*sp
)
246 SPOOL_NOTIFY_OPTION
*new_sp
= NULL
;
251 new_sp
= (SPOOL_NOTIFY_OPTION
*)malloc(sizeof(SPOOL_NOTIFY_OPTION
));
258 new_sp
->ctr
.type
= (SPOOL_NOTIFY_OPTION_TYPE
*)memdup(sp
->ctr
.type
, sizeof(SPOOL_NOTIFY_OPTION_TYPE
) * sp
->ctr
.count
);
260 if (!new_sp
->ctr
.type
) {
269 /****************************************************************************
270 find printer index by handle
271 ****************************************************************************/
273 static Printer_entry
*find_printer_index_by_hnd(pipes_struct
*p
, POLICY_HND
*hnd
)
275 Printer_entry
*find_printer
= NULL
;
277 if(!find_policy_by_hnd(p
,hnd
,(void **)&find_printer
)) {
278 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
285 /****************************************************************************
286 Close printer index by handle.
287 ****************************************************************************/
289 static BOOL
close_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
291 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
294 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
298 close_policy_hnd(p
, hnd
);
303 /****************************************************************************
304 Delete a printer given a handle.
305 ****************************************************************************/
307 static WERROR
delete_printer_handle(pipes_struct
*p
, POLICY_HND
*hnd
)
309 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
312 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
316 if (del_a_printer(Printer
->dev
.handlename
) != 0) {
317 DEBUG(3,("Error deleting printer %s\n", Printer
->dev
.handlename
));
321 /* Check calling user has permission to delete printer. Note that
322 since we set the snum parameter to -1 only administrators can
323 delete the printer. This stops people with the Full Control
324 permission from deleting the printer. */
326 if (!print_access_check(NULL
, -1, PRINTER_ACCESS_ADMINISTER
)) {
327 DEBUG(3, ("printer delete denied by security descriptor\n"));
328 return WERR_ACCESS_DENIED
;
331 if (*lp_deleteprinter_cmd()) {
333 char *cmd
= lp_deleteprinter_cmd();
338 /* Printer->dev.handlename equals portname equals sharename */
339 slprintf(command
, sizeof(command
)-1, "%s \"%s\"", cmd
,
340 Printer
->dev
.handlename
);
342 DEBUG(10,("Running [%s]\n", command
));
343 ret
= smbrun(command
, NULL
);
345 return WERR_BADFID
; /* What to return here? */
347 DEBUGADD(10,("returned [%d]\n", ret
));
349 /* Send SIGHUP to process group... is there a better way? */
352 if ( ( i
= lp_servicenumber( Printer
->dev
.handlename
) ) >= 0 ) {
356 return WERR_ACCESS_DENIED
;
362 /****************************************************************************
363 Return the snum of a printer corresponding to an handle.
364 ****************************************************************************/
366 static BOOL
get_printer_snum(pipes_struct
*p
, POLICY_HND
*hnd
, int *number
)
368 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, hnd
);
371 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd
)));
375 switch (Printer
->printer_type
) {
376 case PRINTER_HANDLE_IS_PRINTER
:
377 DEBUG(4,("short name:%s\n", Printer
->dev
.handlename
));
378 *number
= print_queue_snum(Printer
->dev
.handlename
);
379 return (*number
!= -1);
380 case PRINTER_HANDLE_IS_PRINTSERVER
:
387 /****************************************************************************
388 Set printer handle type.
389 Check if it's \\server or \\server\printer
390 ****************************************************************************/
392 static BOOL
set_printer_hnd_printertype(Printer_entry
*Printer
, char *handlename
)
394 DEBUG(3,("Setting printer type=%s\n", handlename
));
396 if ( strlen(handlename
) < 3 ) {
397 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename
));
401 /* it's a print server */
402 if (*handlename
=='\\' && *(handlename
+1)=='\\' && !strchr_m(handlename
+2, '\\')) {
403 DEBUGADD(4,("Printer is a print server\n"));
404 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTSERVER
;
408 DEBUGADD(4,("Printer is a printer\n"));
409 Printer
->printer_type
= PRINTER_HANDLE_IS_PRINTER
;
415 /****************************************************************************
416 Set printer handle name.
417 ****************************************************************************/
419 static BOOL
set_printer_hnd_name(Printer_entry
*Printer
, char *handlename
)
422 int n_services
=lp_numservices();
427 DEBUG(4,("Setting printer name=%s (len=%d)\n", handlename
, strlen(handlename
)));
429 if (Printer
->printer_type
==PRINTER_HANDLE_IS_PRINTSERVER
) {
430 ZERO_STRUCT(Printer
->dev
.printerservername
);
431 strncpy(Printer
->dev
.printerservername
, handlename
, strlen(handlename
));
435 if (Printer
->printer_type
!=PRINTER_HANDLE_IS_PRINTER
)
438 if (*handlename
=='\\') {
439 aprinter
=strchr_m(handlename
+2, '\\');
446 DEBUGADD(5,("searching for [%s] (len=%d)\n", aprinter
, strlen(aprinter
)));
449 * The original code allowed smbd to store a printer name that
450 * was different from the share name. This is not possible
451 * anymore, so I've simplified this loop greatly. Here
452 * we are just verifying that the printer name is a valid
453 * printer service defined in smb.conf
454 * --jerry [Fri Feb 15 11:17:46 CST 2002]
457 for (snum
=0; snum
<n_services
; snum
++) {
459 if ( !(lp_snum_ok(snum
) && lp_print_ok(snum
) ) )
462 fstrcpy(sname
, lp_servicename(snum
));
464 DEBUGADD(5,("share:%s\n",sname
));
466 if (! StrCaseCmp(sname
, aprinter
)) {
475 DEBUGADD(4,("Printer not found\n"));
479 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter
, sname
));
481 ZERO_STRUCT(Printer
->dev
.handlename
);
482 fstrcpy(Printer
->dev
.handlename
, sname
);
487 /****************************************************************************
488 Find first available printer slot. creates a printer handle for you.
489 ****************************************************************************/
491 static BOOL
open_printer_hnd(pipes_struct
*p
, POLICY_HND
*hnd
, char *name
, uint32 access_granted
)
493 Printer_entry
*new_printer
;
495 DEBUG(10,("open_printer_hnd: name [%s]\n", name
));
497 if((new_printer
=(Printer_entry
*)malloc(sizeof(Printer_entry
))) == NULL
)
500 ZERO_STRUCTP(new_printer
);
502 new_printer
->notify
.option
=NULL
;
504 /* Add to the internal list. */
505 DLIST_ADD(printers_list
, new_printer
);
507 if (!create_policy_hnd(p
, hnd
, free_printer_entry
, new_printer
)) {
508 SAFE_FREE(new_printer
);
512 if (!set_printer_hnd_printertype(new_printer
, name
)) {
513 close_printer_handle(p
, hnd
);
517 if (!set_printer_hnd_name(new_printer
, name
)) {
518 close_printer_handle(p
, hnd
);
522 new_printer
->access_granted
= access_granted
;
524 DEBUG(5, ("%d printer handles active\n", (int)p
->pipe_handles
->count
));
529 /****************************************************************************
530 Allocate more memory for a BUFFER.
531 ****************************************************************************/
533 static BOOL
alloc_buffer_size(NEW_BUFFER
*buffer
, uint32 buffer_size
)
541 /* damn, I'm doing the reverse operation of prs_grow() :) */
542 if (buffer_size
< prs_data_size(ps
))
545 extra_space
= buffer_size
- prs_data_size(ps
);
548 * save the offset and move to the end of the buffer
549 * prs_grow() checks the extra_space against the offset
551 old_offset
=prs_offset(ps
);
552 prs_set_offset(ps
, prs_data_size(ps
));
554 if (!prs_grow(ps
, extra_space
))
557 prs_set_offset(ps
, old_offset
);
559 buffer
->string_at_end
=prs_data_size(ps
);
564 /***************************************************************************
565 check to see if the client motify handle is monitoring the notification
566 given by (notify_type, notify_field).
567 **************************************************************************/
569 static BOOL
is_monitoring_event_flags(uint32 flags
, uint16 notify_type
,
575 static BOOL
is_monitoring_event(Printer_entry
*p
, uint16 notify_type
,
578 SPOOL_NOTIFY_OPTION
*option
= p
->notify
.option
;
582 * Flags should always be zero when the change notify
583 * is registered by the cliebnt's spooler. A user Win32 app
584 * might use the flags though instead of the NOTIFY_OPTION_INFO
589 return is_monitoring_event_flags(
590 p
->notify
.flags
, notify_type
, notify_field
);
592 for (i
= 0; i
< option
->count
; i
++) {
594 /* Check match for notify_type */
596 if (option
->ctr
.type
[i
].type
!= notify_type
)
599 /* Check match for field */
601 for (j
= 0; j
< option
->ctr
.type
[i
].count
; j
++) {
602 if (option
->ctr
.type
[i
].fields
[j
] == notify_field
) {
608 DEBUG(10, ("%s is not monitoring 0x%02x/0x%02x\n",
609 (p
->printer_type
== PRINTER_HANDLE_IS_PRINTER
) ?
610 p
->dev
.handlename
: p
->dev
.printerservername
,
611 notify_type
, notify_field
));
616 /* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
618 static void notify_one_value(struct spoolss_notify_msg
*msg
,
619 SPOOL_NOTIFY_INFO_DATA
*data
,
622 data
->notify_data
.value
[0] = msg
->notify
.value
[0];
623 data
->notify_data
.value
[1] = 0;
626 static void notify_string(struct spoolss_notify_msg
*msg
,
627 SPOOL_NOTIFY_INFO_DATA
*data
,
632 /* The length of the message includes the trailing \0 */
634 init_unistr2(&unistr
, msg
->notify
.data
, msg
->len
);
636 data
->notify_data
.data
.length
= msg
->len
* 2;
637 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, msg
->len
* 2);
639 if (!data
->notify_data
.data
.string
) {
640 data
->notify_data
.data
.length
= 0;
644 memcpy(data
->notify_data
.data
.string
, unistr
.buffer
, msg
->len
* 2);
647 static void notify_system_time(struct spoolss_notify_msg
*msg
,
648 SPOOL_NOTIFY_INFO_DATA
*data
,
654 if (msg
->len
!= sizeof(time_t)) {
655 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
660 if (!prs_init(&ps
, MAX_PDU_FRAG_LEN
, mem_ctx
, MARSHALL
)) {
661 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
665 if (!make_systemtime(&systime
, localtime((time_t *)msg
->notify
.data
))) {
666 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
670 if (!spoolss_io_system_time("", &ps
, 0, &systime
))
673 data
->notify_data
.data
.length
= prs_offset(&ps
);
674 data
->notify_data
.data
.string
=
675 talloc(mem_ctx
, prs_offset(&ps
));
677 memcpy(data
->notify_data
.data
.string
, prs_data_p(&ps
), prs_offset(&ps
));
682 struct notify2_message_table
{
684 void (*fn
)(struct spoolss_notify_msg
*msg
,
685 SPOOL_NOTIFY_INFO_DATA
*data
, TALLOC_CTX
*mem_ctx
);
688 static struct notify2_message_table printer_notify_table
[] = {
689 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string
},
690 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string
},
691 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string
},
692 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string
},
693 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string
},
694 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string
},
695 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string
},
696 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL
},
697 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string
},
698 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string
},
699 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL
},
700 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string
},
701 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
702 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value
},
703 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value
},
704 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL
},
705 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL
},
706 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL
},
707 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value
},
710 static struct notify2_message_table job_notify_table
[] = {
711 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL
},
712 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL
},
713 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL
},
714 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string
},
715 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL
},
716 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL
},
717 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL
},
718 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL
},
719 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL
},
720 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL
},
721 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value
},
722 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL
},
723 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL
},
724 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string
},
725 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL
},
726 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL
},
727 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time
},
728 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL
},
729 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL
},
730 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL
},
731 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value
},
732 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL
},
733 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value
},
734 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL
},
738 /***********************************************************************
739 Allocate talloc context for container object
740 **********************************************************************/
742 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
747 ctr
->ctx
= talloc_init();
752 /***********************************************************************
753 release all allocated memory and zero out structure
754 **********************************************************************/
756 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
762 talloc_destroy(ctr
->ctx
);
769 /***********************************************************************
770 **********************************************************************/
772 static TALLOC_CTX
* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
780 /***********************************************************************
781 **********************************************************************/
783 static SPOOLSS_NOTIFY_MSG_GROUP
* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
785 if ( !ctr
|| !ctr
->msg_groups
)
788 if ( idx
>= ctr
->num_groups
)
791 return &ctr
->msg_groups
[idx
];
795 /***********************************************************************
796 How many groups of change messages do we have ?
797 **********************************************************************/
799 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR
*ctr
)
804 return ctr
->num_groups
;
807 /***********************************************************************
808 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
809 **********************************************************************/
811 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, SPOOLSS_NOTIFY_MSG
*msg
)
813 SPOOLSS_NOTIFY_MSG_GROUP
*groups
= NULL
;
814 SPOOLSS_NOTIFY_MSG_GROUP
*msg_grp
= NULL
;
815 SPOOLSS_NOTIFY_MSG
*msg_list
= NULL
;
821 /* loop over all groups looking for a matching printer name */
823 for ( i
=0; i
<ctr
->num_groups
; i
++ ) {
824 if ( strcmp(ctr
->msg_groups
[i
].printername
, msg
->printer
) == 0 )
828 /* add a new group? */
830 if ( i
== ctr
->num_groups
)
834 if ( !(groups
= talloc_realloc( ctr
->ctx
, ctr
->msg_groups
, sizeof(SPOOLSS_NOTIFY_MSG_GROUP
)*ctr
->num_groups
)) ) {
835 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
838 ctr
->msg_groups
= groups
;
840 /* clear the new entry and set the printer name */
842 ZERO_STRUCT( ctr
->msg_groups
[ctr
->num_groups
-1] );
843 fstrcpy( ctr
->msg_groups
[ctr
->num_groups
-1].printername
, msg
->printer
);
846 /* add the change messages; 'i' is the correct index now regardless */
848 msg_grp
= &ctr
->msg_groups
[i
];
852 if ( !(msg_list
= talloc_realloc( ctr
->ctx
, msg_grp
->msgs
, sizeof(SPOOLSS_NOTIFY_MSG
)*msg_grp
->num_msgs
)) ) {
853 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp
->num_msgs
));
856 msg_grp
->msgs
= msg_list
;
858 new_slot
= msg_grp
->num_msgs
-1;
859 memcpy( &msg_grp
->msgs
[new_slot
], msg
, sizeof(SPOOLSS_NOTIFY_MSG
) );
861 /* need to allocate own copy of data */
864 msg_grp
->msgs
[new_slot
].notify
.data
= talloc_memdup( ctr
->ctx
, msg
->notify
.data
, msg
->len
);
866 return ctr
->num_groups
;
869 /***********************************************************************
870 Send a change notication message on all handles which have a call
872 **********************************************************************/
874 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR
*ctr
, uint32 idx
)
877 TALLOC_CTX
*mem_ctx
= notify_ctr_getctx( ctr
);
878 SPOOLSS_NOTIFY_MSG_GROUP
*msg_group
= notify_ctr_getgroup( ctr
, idx
);
879 SPOOLSS_NOTIFY_MSG
*messages
;
883 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
887 messages
= msg_group
->msgs
;
890 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
894 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group
->printername
));
896 /* loop over all printers */
898 for (p
= printers_list
; p
; p
= p
->next
)
900 SPOOL_NOTIFY_INFO_DATA
*data
;
905 /* Is there notification on this handle? */
907 if ( !p
->notify
.client_connected
)
910 DEBUG(10,("Client connected! [%s]\n", p
->dev
.handlename
));
912 /* For this printer? Print servers always receive
915 if ( ( p
->printer_type
== PRINTER_HANDLE_IS_PRINTER
) &&
916 ( !strequal(msg_group
->printername
, p
->dev
.handlename
) ) )
919 DEBUG(10,("Our printer\n"));
921 /* allocate the max entries possible */
923 data
= talloc( mem_ctx
, msg_group
->num_msgs
*sizeof(SPOOL_NOTIFY_INFO_DATA
) );
926 /* build the array of change notifications */
928 for ( i
=0; i
<msg_group
->num_msgs
; i
++ )
930 SPOOLSS_NOTIFY_MSG
*msg
= &messages
[i
];
932 /* Are we monitoring this event? */
934 if (!is_monitoring_event(p
, msg
->type
, msg
->field
))
938 DEBUG(10,("process_notify2_message: Sending message type [%x] field [%x] for printer [%s]\n",
939 msg
->type
, msg
->field
, p
->dev
.handlename
));
942 * if the is a printer notification handle and not a job notification
943 * type, then set the id to 0. Other wise just use what was specified
946 * When registering change notification on a print server handle
947 * we always need to send back the id (snum) matching the printer
948 * for which the change took place. For change notify registered
949 * on a printer handle, this does not matter and the id should be 0.
954 if ( ( p
->printer_type
== PRINTER_HANDLE_IS_PRINTER
) && ( msg
->type
== PRINTER_NOTIFY_TYPE
) )
960 /* Convert unix jobid to smb jobid */
962 if (msg
->flags
& SPOOLSS_NOTIFY_MSG_UNIX_JOBID
)
964 id
= sysjob_to_jobid(msg
->id
);
967 DEBUG(3, ("no such unix jobid %d\n", msg
->id
));
972 construct_info_data( &data
[data_len
], msg
->type
, msg
->field
, id
);
975 case PRINTER_NOTIFY_TYPE
:
976 if ( !printer_notify_table
[msg
->field
].fn
)
978 printer_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
982 case JOB_NOTIFY_TYPE
:
983 if ( !job_notify_table
[msg
->field
].fn
)
985 job_notify_table
[msg
->field
].fn(msg
, &data
[data_len
], mem_ctx
);
990 DEBUG(5, ("Unknown notification type %d\n", msg
->type
));
997 cli_spoolss_rrpcn( ¬ify_cli
, mem_ctx
, &p
->notify
.client_hnd
,
998 data_len
, data
, p
->notify
.change
, 0 );
1002 DEBUG(8,("send_notify2_changes: Exit...\n"));
1006 /***********************************************************************
1007 **********************************************************************/
1009 static BOOL
notify2_unpack_msg( SPOOLSS_NOTIFY_MSG
*msg
, void *buf
, size_t len
)
1014 /* Unpack message */
1016 offset
+= tdb_unpack((char *)buf
+ offset
, len
- offset
, "f",
1019 offset
+= tdb_unpack((char *)buf
+ offset
, len
- offset
, "ddddd",
1020 &msg
->type
, &msg
->field
, &msg
->id
, &msg
->len
, &msg
->flags
);
1023 tdb_unpack((char *)buf
+ offset
, len
- offset
, "dd",
1024 &msg
->notify
.value
[0], &msg
->notify
.value
[1]);
1026 tdb_unpack((char *)buf
+ offset
, len
- offset
, "B",
1027 &msg
->len
, &msg
->notify
.data
);
1029 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message, type %d, field 0x%02x, flags 0x%04x\n",
1030 msg
->type
, msg
->field
, msg
->flags
));
1033 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg
->notify
.value
[0],
1034 msg
->notify
.value
[1]));
1036 dump_data(3, msg
->notify
.data
, msg
->len
);
1041 /********************************************************************
1042 Receive a notify2 message list
1043 ********************************************************************/
1045 static void receive_notify2_message_list(int msg_type
, pid_t src
, void *msg
, size_t len
)
1047 size_t msg_count
, i
;
1048 char *buf
= (char *)msg
;
1051 SPOOLSS_NOTIFY_MSG notify
;
1052 SPOOLSS_NOTIFY_MSG_CTR messages
;
1056 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1060 msg_count
= IVAL(buf
, 0);
1063 DEBUG(5, ("receive_notify2_message_list: got %d messages in list\n", msg_count
));
1065 if (msg_count
== 0) {
1066 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1070 /* initialize the container */
1072 ZERO_STRUCT( messages
);
1073 notify_msg_ctr_init( &messages
);
1076 * build message groups for each printer identified
1077 * in a change_notify msg. Remember that a PCN message
1078 * includes the handle returned for the srv_spoolss_replyopenprinter()
1079 * call. Therefore messages are grouped according to printer handle.
1082 for ( i
=0; i
<msg_count
; i
++ )
1084 if (msg_ptr
+ 4 - buf
> len
) {
1085 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1089 msg_len
= IVAL(msg_ptr
,0);
1092 if (msg_ptr
+ msg_len
- buf
> len
) {
1093 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1097 /* unpack messages */
1099 ZERO_STRUCT( notify
);
1100 notify2_unpack_msg( ¬ify
, msg_ptr
, msg_len
);
1103 /* add to correct list in container */
1105 notify_msg_ctr_addmsg( &messages
, ¬ify
);
1107 /* free memory that might have been allocated by notify2_unpack_msg() */
1109 if ( notify
.len
!= 0 )
1110 SAFE_FREE( notify
.notify
.data
);
1113 /* process each group of messages */
1115 num_groups
= notify_msg_ctr_numgroups( &messages
);
1116 for ( i
=0; i
<num_groups
; i
++ )
1117 send_notify2_changes( &messages
, i
);
1122 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32
)msg_count
));
1124 notify_msg_ctr_destroy( &messages
);
1129 /********************************************************************
1130 Send a message to ourself about new driver being installed
1131 so we can upgrade the information for each printer bound to this
1133 ********************************************************************/
1135 static BOOL
srv_spoolss_drv_upgrade_printer(char* drivername
)
1137 int len
= strlen(drivername
);
1142 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1145 message_send_pid(sys_getpid(), MSG_PRINTER_DRVUPGRADE
, drivername
, len
+1, False
);
1150 /**********************************************************************
1151 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1152 over all printers, upgrading ones as neessary
1153 **********************************************************************/
1155 void do_drv_upgrade_printer(int msg_type
, pid_t src
, void *buf
, size_t len
)
1159 int n_services
= lp_numservices();
1161 len
= MIN(len
,sizeof(drivername
)-1);
1162 strncpy(drivername
, buf
, len
);
1164 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername
));
1166 /* Iterate the printer list */
1168 for (snum
=0; snum
<n_services
; snum
++)
1170 if (lp_snum_ok(snum
) && lp_print_ok(snum
) )
1173 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1175 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
1176 if (!W_ERROR_IS_OK(result
))
1179 if (printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
))
1181 DEBUG(6,("Updating printer [%s]\n", printer
->info_2
->printername
));
1183 /* all we care about currently is the change_id */
1185 result
= mod_a_printer(*printer
, 2);
1186 if (!W_ERROR_IS_OK(result
)) {
1187 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1188 dos_errstr(result
)));
1192 free_a_printer(&printer
, 2);
1199 /********************************************************************
1200 Send a message to ourself about new driver being installed
1201 so we can upgrade the information for each printer bound to this
1203 ********************************************************************/
1205 static BOOL
srv_spoolss_reset_printerdata(char* drivername
)
1207 int len
= strlen(drivername
);
1212 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1215 message_send_pid(sys_getpid(), MSG_PRINTERDATA_INIT_RESET
, drivername
, len
+1, False
);
1220 /**********************************************************************
1221 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1222 over all printers, resetting printer data as neessary
1223 **********************************************************************/
1225 void reset_all_printerdata(int msg_type
, pid_t src
, void *buf
, size_t len
)
1229 int n_services
= lp_numservices();
1231 len
= MIN( len
, sizeof(drivername
)-1 );
1232 strncpy( drivername
, buf
, len
);
1234 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername
));
1236 /* Iterate the printer list */
1238 for ( snum
=0; snum
<n_services
; snum
++ )
1240 if ( lp_snum_ok(snum
) && lp_print_ok(snum
) )
1243 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
1245 result
= get_a_printer( &printer
, 2, lp_servicename(snum
) );
1246 if ( !W_ERROR_IS_OK(result
) )
1250 * if the printer is bound to the driver,
1251 * then reset to the new driver initdata
1254 if ( printer
&& printer
->info_2
&& !strcmp(drivername
, printer
->info_2
->drivername
) )
1256 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer
->info_2
->printername
));
1258 if ( !set_driver_init(printer
, 2) ) {
1259 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1260 printer
->info_2
->printername
, printer
->info_2
->drivername
));
1264 free_a_printer( &printer
, 2 );
1273 /********************************************************************
1274 Copy routines used by convert_to_openprinterex()
1275 *******************************************************************/
1277 static DEVICEMODE
* dup_devicemode(TALLOC_CTX
*ctx
, DEVICEMODE
*devmode
)
1285 DEBUG (8,("dup_devmode\n"));
1287 /* bulk copy first */
1289 d
= talloc_memdup(ctx
, devmode
, sizeof(DEVICEMODE
));
1293 /* dup the pointer members separately */
1295 len
= unistrlen(devmode
->devicename
.buffer
);
1297 d
->devicename
.buffer
= talloc(ctx
, len
*2);
1298 if (unistrcpy(d
->devicename
.buffer
, devmode
->devicename
.buffer
) != len
)
1303 len
= unistrlen(devmode
->formname
.buffer
);
1305 d
->devicename
.buffer
= talloc(ctx
, len
*2);
1306 if (unistrcpy(d
->formname
.buffer
, devmode
->formname
.buffer
) != len
)
1310 d
->private = talloc_memdup(ctx
, devmode
->private, devmode
->driverextra
);
1315 static void copy_devmode_ctr(TALLOC_CTX
*ctx
, DEVMODE_CTR
*new_ctr
, DEVMODE_CTR
*ctr
)
1317 if (!new_ctr
|| !ctr
)
1320 DEBUG(8,("copy_devmode_ctr\n"));
1322 new_ctr
->size
= ctr
->size
;
1323 new_ctr
->devmode_ptr
= ctr
->devmode_ptr
;
1325 if(ctr
->devmode_ptr
)
1326 new_ctr
->devmode
= dup_devicemode(ctx
, ctr
->devmode
);
1329 static void copy_printer_default(TALLOC_CTX
*ctx
, PRINTER_DEFAULT
*new_def
, PRINTER_DEFAULT
*def
)
1331 if (!new_def
|| !def
)
1334 DEBUG(8,("copy_printer_defaults\n"));
1336 new_def
->datatype_ptr
= def
->datatype_ptr
;
1338 if (def
->datatype_ptr
)
1339 copy_unistr2(&new_def
->datatype
, &def
->datatype
);
1341 copy_devmode_ctr(ctx
, &new_def
->devmode_cont
, &def
->devmode_cont
);
1343 new_def
->access_required
= def
->access_required
;
1346 /********************************************************************
1347 * Convert a SPOOL_Q_OPEN_PRINTER structure to a
1348 * SPOOL_Q_OPEN_PRINTER_EX structure
1349 ********************************************************************/
1351 static void convert_to_openprinterex(TALLOC_CTX
*ctx
, SPOOL_Q_OPEN_PRINTER_EX
*q_u_ex
, SPOOL_Q_OPEN_PRINTER
*q_u
)
1353 if (!q_u_ex
|| !q_u
)
1356 DEBUG(8,("convert_to_openprinterex\n"));
1358 q_u_ex
->printername_ptr
= q_u
->printername_ptr
;
1360 if (q_u
->printername_ptr
)
1361 copy_unistr2(&q_u_ex
->printername
, &q_u
->printername
);
1363 copy_printer_default(ctx
, &q_u_ex
->printer_default
, &q_u
->printer_default
);
1366 /********************************************************************
1367 * spoolss_open_printer
1369 * called from the spoolss dispatcher
1370 ********************************************************************/
1372 WERROR
_spoolss_open_printer(pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER
*q_u
, SPOOL_R_OPEN_PRINTER
*r_u
)
1374 SPOOL_Q_OPEN_PRINTER_EX q_u_ex
;
1375 SPOOL_R_OPEN_PRINTER_EX r_u_ex
;
1380 ZERO_STRUCT(q_u_ex
);
1381 ZERO_STRUCT(r_u_ex
);
1383 /* convert the OpenPrinter() call to OpenPrinterEx() */
1385 convert_to_openprinterex(p
->mem_ctx
, &q_u_ex
, q_u
);
1387 r_u_ex
.status
= _spoolss_open_printer_ex(p
, &q_u_ex
, &r_u_ex
);
1389 /* convert back to OpenPrinter() */
1391 memcpy(r_u
, &r_u_ex
, sizeof(*r_u
));
1396 /********************************************************************
1397 * spoolss_open_printer
1399 * If the openprinterex rpc call contains a devmode,
1400 * it's a per-user one. This per-user devmode is derivated
1401 * from the global devmode. Openprinterex() contains a per-user
1402 * devmode for when you do EMF printing and spooling.
1403 * In the EMF case, the NT workstation is only doing half the job
1404 * of rendering the page. The other half is done by running the printer
1405 * driver on the server.
1406 * The EMF file doesn't contain the page description (paper size, orientation, ...).
1407 * The EMF file only contains what is to be printed on the page.
1408 * So in order for the server to know how to print, the NT client sends
1409 * a devicemode attached to the openprinterex call.
1410 * But this devicemode is short lived, it's only valid for the current print job.
1412 * If Samba would have supported EMF spooling, this devicemode would
1413 * have been attached to the handle, to sent it to the driver to correctly
1414 * rasterize the EMF file.
1416 * As Samba only supports RAW spooling, we only receive a ready-to-print file,
1417 * we just act as a pass-thru between windows and the printer.
1419 * In order to know that Samba supports only RAW spooling, NT has to call
1420 * getprinter() at level 2 (attribute field) or NT has to call startdoc()
1421 * and until NT sends a RAW job, we refuse it.
1423 * But to call getprinter() or startdoc(), you first need a valid handle,
1424 * and to get an handle you have to call openprintex(). Hence why you have
1425 * a devicemode in the openprinterex() call.
1428 * Differences between NT4 and NT 2000.
1431 * On NT4, you only have a global devicemode. This global devicemode can be changed
1432 * by the administrator (or by a user with enough privs). Everytime a user
1433 * wants to print, the devicemode is resetted to the default. In Word, everytime
1434 * you print, the printer's characteristics are always reset to the global devicemode.
1438 * In W2K, there is the notion of per-user devicemode. The first time you use
1439 * a printer, a per-user devicemode is build from the global devicemode.
1440 * If you change your per-user devicemode, it is saved in the registry, under the
1441 * H_KEY_CURRENT_KEY sub_tree. So that everytime you print, you have your default
1442 * printer preferences available.
1444 * To change the per-user devicemode: it's the "Printing Preferences ..." button
1445 * on the General Tab of the printer properties windows.
1447 * To change the global devicemode: it's the "Printing Defaults..." button
1448 * on the Advanced Tab of the printer properties window.
1451 ********************************************************************/
1453 WERROR
_spoolss_open_printer_ex( pipes_struct
*p
, SPOOL_Q_OPEN_PRINTER_EX
*q_u
, SPOOL_R_OPEN_PRINTER_EX
*r_u
)
1455 UNISTR2
*printername
= NULL
;
1456 PRINTER_DEFAULT
*printer_default
= &q_u
->printer_default
;
1457 POLICY_HND
*handle
= &r_u
->handle
;
1461 struct current_user user
;
1462 Printer_entry
*Printer
=NULL
;
1464 if (q_u
->printername_ptr
!= 0)
1465 printername
= &q_u
->printername
;
1467 if (printername
== NULL
)
1468 return WERR_INVALID_PRINTER_NAME
;
1470 /* some sanity check because you can open a printer or a print server */
1471 /* aka: \\server\printer or \\server */
1472 unistr2_to_ascii(name
, printername
, sizeof(name
)-1);
1474 DEBUGADD(3,("checking name: %s\n",name
));
1476 if (!open_printer_hnd(p
, handle
, name
, 0))
1477 return WERR_INVALID_PRINTER_NAME
;
1479 Printer
=find_printer_index_by_hnd(p
, handle
);
1481 DEBUG(0,(" _spoolss_open_printer_ex: logic error. \
1482 Can't find printer handle we created for printer %s\n", name
));
1483 close_printer_handle(p
,handle
);
1484 return WERR_INVALID_PRINTER_NAME
;
1487 get_current_user(&user
, p
);
1490 * First case: the user is opening the print server:
1492 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1493 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1495 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1496 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1497 * or if the user is listed in the smb.conf printer admin parameter.
1499 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1500 * client view printer folder, but does not show the MSAPW.
1502 * Note: this test needs code to check access rights here too. Jeremy
1503 * could you look at this?
1505 * Second case: the user is opening a printer:
1506 * NT doesn't let us connect to a printer if the connecting user
1507 * doesn't have print permission.
1510 if (Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
)
1512 /* Printserver handles use global struct... */
1516 /* Map standard access rights to object specific access rights */
1518 se_map_standard(&printer_default
->access_required
,
1519 &printserver_std_mapping
);
1521 /* Deny any object specific bits that don't apply to print
1522 servers (i.e printer and job specific bits) */
1524 printer_default
->access_required
&= SPECIFIC_RIGHTS_MASK
;
1526 if (printer_default
->access_required
&
1527 ~(SERVER_ACCESS_ADMINISTER
| SERVER_ACCESS_ENUMERATE
)) {
1528 DEBUG(3, ("access DENIED for non-printserver bits"));
1529 close_printer_handle(p
, handle
);
1530 return WERR_ACCESS_DENIED
;
1533 /* Allow admin access */
1535 if ( printer_default
->access_required
& SERVER_ACCESS_ADMINISTER
)
1537 if (!lp_ms_add_printer_wizard()) {
1538 close_printer_handle(p
, handle
);
1539 return WERR_ACCESS_DENIED
;
1542 /* if the user is not root and not a printer admin, then fail */
1545 && !user_in_list(uidtoname(user
.uid
), lp_printer_admin(snum
)) )
1547 close_printer_handle(p
, handle
);
1548 return WERR_ACCESS_DENIED
;
1551 printer_default
->access_required
= SERVER_ACCESS_ADMINISTER
;
1555 printer_default
->access_required
= SERVER_ACCESS_ENUMERATE
;
1558 DEBUG(4,("Setting print server access = %s\n", (printer_default
->access_required
== SERVER_ACCESS_ADMINISTER
)
1559 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1561 /* We fall through to return WERR_OK */
1566 /* NT doesn't let us connect to a printer if the connecting user
1567 doesn't have print permission. */
1569 if (!get_printer_snum(p
, handle
, &snum
))
1572 se_map_standard(&printer_default
->access_required
, &printer_std_mapping
);
1574 /* map an empty access mask to the minimum access mask */
1575 if (printer_default
->access_required
== 0x0)
1576 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1579 * If we are not serving the printer driver for this printer,
1580 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1581 * will keep NT clients happy --jerry
1584 if (lp_use_client_driver(snum
)
1585 && (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
))
1587 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1590 /* check smb.conf parameters and the the sec_desc */
1592 if (!user_ok(uidtoname(user
.uid
), snum
) || !print_access_check(&user
, snum
, printer_default
->access_required
)) {
1593 DEBUG(3, ("access DENIED for printer open\n"));
1594 close_printer_handle(p
, handle
);
1595 return WERR_ACCESS_DENIED
;
1598 if ((printer_default
->access_required
& SPECIFIC_RIGHTS_MASK
)& ~(PRINTER_ACCESS_ADMINISTER
|PRINTER_ACCESS_USE
)) {
1599 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1600 close_printer_handle(p
, handle
);
1601 return WERR_ACCESS_DENIED
;
1604 if (printer_default
->access_required
& PRINTER_ACCESS_ADMINISTER
)
1605 printer_default
->access_required
= PRINTER_ACCESS_ADMINISTER
;
1607 printer_default
->access_required
= PRINTER_ACCESS_USE
;
1609 DEBUG(4,("Setting printer access = %s\n", (printer_default
->access_required
== PRINTER_ACCESS_ADMINISTER
)
1610 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1614 Printer
->access_granted
= printer_default
->access_required
;
1617 * If the client sent a devmode in the OpenPrinter() call, then
1618 * save it here in case we get a job submission on this handle
1621 if ( (Printer
->printer_type
!= PRINTER_HANDLE_IS_PRINTSERVER
)
1622 && q_u
->printer_default
.devmode_cont
.devmode_ptr
)
1624 convert_devicemode( Printer
->dev
.handlename
, q_u
->printer_default
.devmode_cont
.devmode
,
1625 &Printer
->nt_devmode
);
1631 /****************************************************************************
1632 ****************************************************************************/
1634 static BOOL
convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL
*uni
,
1635 NT_PRINTER_INFO_LEVEL
*printer
, uint32 level
)
1641 ret
= uni_2_asc_printer_info_2(uni
->info_2
, &printer
->info_2
);
1650 static BOOL
convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL
*uni
,
1651 NT_PRINTER_DRIVER_INFO_LEVEL
*printer
, uint32 level
)
1657 printer
->info_3
=NULL
;
1658 if (!uni_2_asc_printer_driver_3(uni
->info_3
, &printer
->info_3
))
1662 printer
->info_6
=NULL
;
1663 if (!uni_2_asc_printer_driver_6(uni
->info_6
, &printer
->info_6
))
1673 BOOL
convert_devicemode(char *printername
, const DEVICEMODE
*devmode
,
1674 NT_DEVICEMODE
**pp_nt_devmode
)
1676 NT_DEVICEMODE
*nt_devmode
= *pp_nt_devmode
;
1679 * Ensure nt_devmode is a valid pointer
1680 * as we will be overwriting it.
1683 if (nt_devmode
== NULL
) {
1684 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1685 if ((nt_devmode
= construct_nt_devicemode(printername
)) == NULL
)
1689 rpcstr_pull(nt_devmode
->devicename
,devmode
->devicename
.buffer
, 31, -1, 0);
1690 rpcstr_pull(nt_devmode
->formname
,devmode
->formname
.buffer
, 31, -1, 0);
1692 nt_devmode
->specversion
=devmode
->specversion
;
1693 nt_devmode
->driverversion
=devmode
->driverversion
;
1694 nt_devmode
->size
=devmode
->size
;
1695 nt_devmode
->fields
=devmode
->fields
;
1696 nt_devmode
->orientation
=devmode
->orientation
;
1697 nt_devmode
->papersize
=devmode
->papersize
;
1698 nt_devmode
->paperlength
=devmode
->paperlength
;
1699 nt_devmode
->paperwidth
=devmode
->paperwidth
;
1700 nt_devmode
->scale
=devmode
->scale
;
1701 nt_devmode
->copies
=devmode
->copies
;
1702 nt_devmode
->defaultsource
=devmode
->defaultsource
;
1703 nt_devmode
->printquality
=devmode
->printquality
;
1704 nt_devmode
->color
=devmode
->color
;
1705 nt_devmode
->duplex
=devmode
->duplex
;
1706 nt_devmode
->yresolution
=devmode
->yresolution
;
1707 nt_devmode
->ttoption
=devmode
->ttoption
;
1708 nt_devmode
->collate
=devmode
->collate
;
1710 nt_devmode
->logpixels
=devmode
->logpixels
;
1711 nt_devmode
->bitsperpel
=devmode
->bitsperpel
;
1712 nt_devmode
->pelswidth
=devmode
->pelswidth
;
1713 nt_devmode
->pelsheight
=devmode
->pelsheight
;
1714 nt_devmode
->displayflags
=devmode
->displayflags
;
1715 nt_devmode
->displayfrequency
=devmode
->displayfrequency
;
1716 nt_devmode
->icmmethod
=devmode
->icmmethod
;
1717 nt_devmode
->icmintent
=devmode
->icmintent
;
1718 nt_devmode
->mediatype
=devmode
->mediatype
;
1719 nt_devmode
->dithertype
=devmode
->dithertype
;
1720 nt_devmode
->reserved1
=devmode
->reserved1
;
1721 nt_devmode
->reserved2
=devmode
->reserved2
;
1722 nt_devmode
->panningwidth
=devmode
->panningwidth
;
1723 nt_devmode
->panningheight
=devmode
->panningheight
;
1726 * Only change private and driverextra if the incoming devmode
1727 * has a new one. JRA.
1730 if ((devmode
->driverextra
!= 0) && (devmode
->private != NULL
)) {
1731 SAFE_FREE(nt_devmode
->private);
1732 nt_devmode
->driverextra
=devmode
->driverextra
;
1733 if((nt_devmode
->private=(uint8
*)malloc(nt_devmode
->driverextra
* sizeof(uint8
))) == NULL
)
1735 memcpy(nt_devmode
->private, devmode
->private, nt_devmode
->driverextra
);
1738 *pp_nt_devmode
= nt_devmode
;
1743 /********************************************************************
1744 * _spoolss_enddocprinter_internal.
1745 ********************************************************************/
1747 static WERROR
_spoolss_enddocprinter_internal(pipes_struct
*p
, POLICY_HND
*handle
)
1749 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1753 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
1757 if (!get_printer_snum(p
, handle
, &snum
))
1760 Printer
->document_started
=False
;
1761 print_job_end(snum
, Printer
->jobid
,True
);
1762 /* error codes unhandled so far ... */
1767 /********************************************************************
1768 * api_spoolss_closeprinter
1769 ********************************************************************/
1771 WERROR
_spoolss_closeprinter(pipes_struct
*p
, SPOOL_Q_CLOSEPRINTER
*q_u
, SPOOL_R_CLOSEPRINTER
*r_u
)
1773 POLICY_HND
*handle
= &q_u
->handle
;
1775 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1777 if (Printer
&& Printer
->document_started
)
1778 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1780 if (!close_printer_handle(p
, handle
))
1783 /* clear the returned printer handle. Observed behavior
1784 from Win2k server. Don't think this really matters.
1785 Previous code just copied the value of the closed
1788 memset(&r_u
->handle
, '\0', sizeof(r_u
->handle
));
1793 /********************************************************************
1794 * api_spoolss_deleteprinter
1796 ********************************************************************/
1798 WERROR
_spoolss_deleteprinter(pipes_struct
*p
, SPOOL_Q_DELETEPRINTER
*q_u
, SPOOL_R_DELETEPRINTER
*r_u
)
1800 POLICY_HND
*handle
= &q_u
->handle
;
1801 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
1804 if (Printer
&& Printer
->document_started
)
1805 _spoolss_enddocprinter_internal(p
, handle
); /* print job was not closed */
1807 memcpy(&r_u
->handle
, &q_u
->handle
, sizeof(r_u
->handle
));
1809 result
= delete_printer_handle(p
, handle
);
1811 update_c_setprinter(False
);
1816 /*******************************************************************
1817 * static function to lookup the version id corresponding to an
1818 * long architecture string
1819 ******************************************************************/
1821 static int get_version_id (char * arch
)
1824 struct table_node archi_table
[]= {
1826 {"Windows 4.0", "WIN40", 0 },
1827 {"Windows NT x86", "W32X86", 2 },
1828 {"Windows NT R4000", "W32MIPS", 2 },
1829 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1830 {"Windows NT PowerPC", "W32PPC", 2 },
1834 for (i
=0; archi_table
[i
].long_archi
!= NULL
; i
++)
1836 if (strcmp(arch
, archi_table
[i
].long_archi
) == 0)
1837 return (archi_table
[i
].version
);
1843 /********************************************************************
1844 * _spoolss_deleteprinterdriver
1845 ********************************************************************/
1847 WERROR
_spoolss_deleteprinterdriver(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVER
*q_u
, SPOOL_R_DELETEPRINTERDRIVER
*r_u
)
1851 NT_PRINTER_DRIVER_INFO_LEVEL info
;
1852 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
1854 struct current_user user
;
1856 WERROR status_win2k
= WERR_ACCESS_DENIED
;
1858 get_current_user(&user
, p
);
1860 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
)-1 );
1861 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
)-1 );
1863 /* check that we have a valid driver name first */
1865 if ((version
=get_version_id(arch
)) == -1)
1866 return WERR_INVALID_ENVIRONMENT
;
1869 ZERO_STRUCT(info_win2k
);
1871 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
)))
1873 /* try for Win2k driver if "Windows NT x86" */
1875 if ( version
== 2 ) {
1877 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
1878 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
1884 if (printer_driver_in_use(info
.info_3
)) {
1885 status
= WERR_PRINTER_DRIVER_IN_USE
;
1891 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
1893 /* if we get to here, we now have 2 driver info structures to remove */
1894 /* remove the Win2k driver first*/
1896 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &user
, 3, False
);
1897 free_a_printer_driver( info_win2k
, 3 );
1899 /* this should not have failed---if it did, report to client */
1900 if ( !W_ERROR_IS_OK(status_win2k
) )
1905 status
= delete_printer_driver(info
.info_3
, &user
, version
, False
);
1907 /* if at least one of the deletes succeeded return OK */
1909 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
1913 free_a_printer_driver( info
, 3 );
1918 /********************************************************************
1919 * spoolss_deleteprinterdriverex
1920 ********************************************************************/
1922 WERROR
_spoolss_deleteprinterdriverex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDRIVEREX
*q_u
, SPOOL_R_DELETEPRINTERDRIVEREX
*r_u
)
1926 NT_PRINTER_DRIVER_INFO_LEVEL info
;
1927 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k
;
1929 uint32 flags
= q_u
->delete_flags
;
1931 struct current_user user
;
1933 WERROR status_win2k
= WERR_ACCESS_DENIED
;
1935 get_current_user(&user
, p
);
1937 unistr2_to_ascii(driver
, &q_u
->driver
, sizeof(driver
)-1 );
1938 unistr2_to_ascii(arch
, &q_u
->arch
, sizeof(arch
)-1 );
1940 /* check that we have a valid driver name first */
1941 if ((version
=get_version_id(arch
)) == -1) {
1942 /* this is what NT returns */
1943 return WERR_INVALID_ENVIRONMENT
;
1946 if ( flags
& DPD_DELETE_SPECIFIC_VERSION
)
1947 version
= q_u
->version
;
1950 ZERO_STRUCT(info_win2k
);
1952 status
= get_a_printer_driver(&info
, 3, driver
, arch
, version
);
1954 if ( !W_ERROR_IS_OK(status
) )
1957 * if the client asked for a specific version,
1958 * or this is something other than Windows NT x86,
1962 if ( (flags
&DPD_DELETE_SPECIFIC_VERSION
) || (version
!=2) )
1965 /* try for Win2k driver if "Windows NT x86" */
1968 if (!W_ERROR_IS_OK(get_a_printer_driver(&info
, 3, driver
, arch
, version
))) {
1969 status
= WERR_UNKNOWN_PRINTER_DRIVER
;
1974 if ( printer_driver_in_use(info
.info_3
) ) {
1975 status
= WERR_PRINTER_DRIVER_IN_USE
;
1980 * we have a couple of cases to consider.
1981 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1982 * then the delete should fail if **any** files overlap with
1984 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1985 * non-overlapping files
1986 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1987 * is set, the do not delete any files
1988 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1991 delete_files
= flags
& (DPD_DELETE_ALL_FILES
|DPD_DELETE_UNUSED_FILES
);
1993 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1995 if ( delete_files
&& printer_driver_files_in_use(info
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
1996 /* no idea of the correct error here */
1997 status
= WERR_ACCESS_DENIED
;
2002 /* also check for W32X86/3 if necessary; maybe we already have? */
2004 if ( (version
== 2) && ((flags
&DPD_DELETE_SPECIFIC_VERSION
) != DPD_DELETE_SPECIFIC_VERSION
) ) {
2005 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k
, 3, driver
, arch
, 3)))
2008 if ( delete_files
&& printer_driver_files_in_use(info_win2k
.info_3
) & (flags
&DPD_DELETE_ALL_FILES
) ) {
2009 /* no idea of the correct error here */
2010 free_a_printer_driver( info_win2k
, 3 );
2011 status
= WERR_ACCESS_DENIED
;
2015 /* if we get to here, we now have 2 driver info structures to remove */
2016 /* remove the Win2k driver first*/
2018 status_win2k
= delete_printer_driver(info_win2k
.info_3
, &user
, 3, delete_files
);
2019 free_a_printer_driver( info_win2k
, 3 );
2021 /* this should not have failed---if it did, report to client */
2023 if ( !W_ERROR_IS_OK(status_win2k
) )
2028 status
= delete_printer_driver(info
.info_3
, &user
, version
, delete_files
);
2030 if ( W_ERROR_IS_OK(status
) || W_ERROR_IS_OK(status_win2k
) )
2033 free_a_printer_driver( info
, 3 );
2039 /****************************************************************************
2040 Internal routine for retreiving printerdata
2041 ***************************************************************************/
2043 static WERROR
get_printer_dataex( TALLOC_CTX
*ctx
, NT_PRINTER_INFO_LEVEL
*printer
,
2044 char *key
, char *value
, uint32
*type
, uint8
**data
,
2045 uint32
*needed
, uint32 in_size
)
2047 REGISTRY_VALUE
*val
;
2050 if ( !(val
= get_printer_data( printer
->info_2
, key
, value
)) )
2051 return WERR_BADFILE
;
2053 *type
= regval_type( val
);
2055 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size
));
2057 size
= regval_size( val
);
2059 /* copy the min(in_size, len) */
2062 data_len
= (size
> in_size
) ? in_size
: size
*sizeof(uint8
);
2063 if ( (*data
= (uint8
*)talloc_memdup(ctx
, regval_data_p(val
), data_len
)) == NULL
)
2071 DEBUG(5,("get_printer_dataex: copy done\n"));
2076 /****************************************************************************
2077 Internal routine for removing printerdata
2078 ***************************************************************************/
2080 static WERROR
delete_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, char *key
, char *value
)
2082 delete_printer_data( printer
->info_2
, key
, value
);
2084 return mod_a_printer(*printer
, 2);
2087 /****************************************************************************
2088 Internal routine for storing printerdata
2089 ***************************************************************************/
2091 static WERROR
set_printer_dataex( NT_PRINTER_INFO_LEVEL
*printer
, char *key
, char *value
,
2092 uint32 type
, uint8
*data
, int real_len
)
2094 delete_printer_data( printer
->info_2
, key
, value
);
2096 add_printer_data( printer
->info_2
, key
, value
, type
, data
, real_len
);
2098 return mod_a_printer(*printer
, 2);
2101 /********************************************************************
2102 GetPrinterData on a printer server Handle.
2103 ********************************************************************/
2105 static WERROR
getprinterdata_printer_server(TALLOC_CTX
*ctx
, fstring value
, uint32
*type
, uint8
**data
, uint32
*needed
, uint32 in_size
)
2109 DEBUG(8,("getprinterdata_printer_server:%s\n", value
));
2111 if (!strcmp(value
, "W3SvcInstalled")) {
2113 if((*data
= (uint8
*)talloc_zero(ctx
, 4*sizeof(uint8
) )) == NULL
)
2119 if (!strcmp(value
, "BeepEnabled")) {
2121 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
2123 SIVAL(*data
, 0, 0x00);
2128 if (!strcmp(value
, "EventLog")) {
2130 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
2132 /* formally was 0x1b */
2133 SIVAL(*data
, 0, 0x0);
2138 if (!strcmp(value
, "NetPopup")) {
2140 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
2142 SIVAL(*data
, 0, 0x00);
2147 if (!strcmp(value
, "MajorVersion")) {
2149 if((*data
= (uint8
*)talloc(ctx
, 4*sizeof(uint8
) )) == NULL
)
2151 #ifndef EMULATE_WIN2K_HACK /* JERRY */
2160 if (!strcmp(value
, "DefaultSpoolDirectory")) {
2163 fstrcpy(string
, string_truncate(lp_serverstring(), MAX_SERVER_STRING_LENGTH
));
2165 *needed
= 2*(strlen(string
)+1);
2166 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
2168 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2170 /* it's done by hand ready to go on the wire */
2171 for (i
=0; i
<strlen(string
); i
++) {
2172 (*data
)[2*i
]=string
[i
];
2173 (*data
)[2*i
+1]='\0';
2178 if (!strcmp(value
, "Architecture")) {
2179 pstring string
="Windows NT x86";
2181 *needed
= 2*(strlen(string
)+1);
2182 if((*data
= (uint8
*)talloc(ctx
, ((*needed
> in_size
) ? *needed
:in_size
) *sizeof(uint8
))) == NULL
)
2184 memset(*data
, 0, (*needed
> in_size
) ? *needed
:in_size
);
2185 for (i
=0; i
<strlen(string
); i
++) {
2186 (*data
)[2*i
]=string
[i
];
2187 (*data
)[2*i
+1]='\0';
2192 return WERR_INVALID_PARAM
;
2195 /********************************************************************
2196 * spoolss_getprinterdata
2197 ********************************************************************/
2199 WERROR
_spoolss_getprinterdata(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATA
*q_u
, SPOOL_R_GETPRINTERDATA
*r_u
)
2201 POLICY_HND
*handle
= &q_u
->handle
;
2202 UNISTR2
*valuename
= &q_u
->valuename
;
2203 uint32 in_size
= q_u
->size
;
2204 uint32
*type
= &r_u
->type
;
2205 uint32
*out_size
= &r_u
->size
;
2206 uint8
**data
= &r_u
->data
;
2207 uint32
*needed
= &r_u
->needed
;
2210 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
2211 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
2215 * Reminder: when it's a string, the length is in BYTES
2216 * even if UNICODE is negociated.
2221 *out_size
= in_size
;
2223 /* in case of problem, return some default values */
2228 DEBUG(4,("_spoolss_getprinterdata\n"));
2231 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2232 status
= WERR_BADFID
;
2236 unistr2_to_ascii(value
, valuename
, sizeof(value
)-1);
2238 if ( Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
)
2239 status
= getprinterdata_printer_server( p
->mem_ctx
, value
, type
, data
, needed
, *out_size
);
2242 if ( !get_printer_snum(p
,handle
, &snum
) ) {
2243 status
= WERR_BADFID
;
2247 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
2248 if ( !W_ERROR_IS_OK(status
) )
2251 status
= get_printer_dataex( p
->mem_ctx
, printer
, SPOOL_PRINTERDATA_KEY
, value
, type
, data
, needed
, *out_size
);
2254 if (*needed
> *out_size
)
2255 status
= WERR_MORE_DATA
;
2258 if ( !W_ERROR_IS_OK(status
) )
2260 DEBUG(5, ("error: allocating %d\n", *out_size
));
2262 /* reply this param doesn't exist */
2265 if((*data
=(uint8
*)talloc_zero(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
) {
2267 free_a_printer( &printer
, 2 );
2276 /* cleanup & exit */
2279 free_a_printer( &printer
, 2 );
2284 /*********************************************************
2285 Connect to the client machine.
2286 **********************************************************/
2288 static BOOL
spoolss_connect_to_client(struct cli_state
*the_cli
, char *remote_machine
)
2290 extern pstring global_myname
;
2292 ZERO_STRUCTP(the_cli
);
2293 if(cli_initialise(the_cli
) == NULL
) {
2294 DEBUG(0,("connect_to_client: unable to initialize client connection.\n"));
2298 if(!resolve_name( remote_machine
, &the_cli
->dest_ip
, 0x20)) {
2299 DEBUG(0,("connect_to_client: Can't resolve address for %s\n", remote_machine
));
2300 cli_shutdown(the_cli
);
2304 if (ismyip(the_cli
->dest_ip
)) {
2305 DEBUG(0,("connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine
));
2306 cli_shutdown(the_cli
);
2310 if (!cli_connect(the_cli
, remote_machine
, &the_cli
->dest_ip
)) {
2311 DEBUG(0,("connect_to_client: unable to connect to SMB server on machine %s. Error was : %s.\n", remote_machine
, cli_errstr(the_cli
) ));
2312 cli_shutdown(the_cli
);
2316 if (!attempt_netbios_session_request(the_cli
, global_myname
, remote_machine
, &the_cli
->dest_ip
)) {
2317 DEBUG(0,("connect_to_client: machine %s rejected the NetBIOS session request.\n",
2319 cli_shutdown(the_cli
);
2323 the_cli
->protocol
= PROTOCOL_NT1
;
2325 if (!cli_negprot(the_cli
)) {
2326 DEBUG(0,("connect_to_client: machine %s rejected the negotiate protocol. Error was : %s.\n", remote_machine
, cli_errstr(the_cli
) ));
2327 cli_shutdown(the_cli
);
2331 if (the_cli
->protocol
!= PROTOCOL_NT1
) {
2332 DEBUG(0,("connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine
));
2333 cli_shutdown(the_cli
);
2338 * Do an anonymous session setup.
2341 if (!cli_session_setup(the_cli
, "", "", 0, "", 0, "")) {
2342 DEBUG(0,("connect_to_client: machine %s rejected the session setup. Error was : %s.\n", remote_machine
, cli_errstr(the_cli
) ));
2343 cli_shutdown(the_cli
);
2347 if (!(the_cli
->sec_mode
& 1)) {
2348 DEBUG(0,("connect_to_client: machine %s isn't in user level security mode\n", remote_machine
));
2349 cli_shutdown(the_cli
);
2353 if (!cli_send_tconX(the_cli
, "IPC$", "IPC", "", 1)) {
2354 DEBUG(0,("connect_to_client: machine %s rejected the tconX on the IPC$ share. Error was : %s.\n", remote_machine
, cli_errstr(the_cli
) ));
2355 cli_shutdown(the_cli
);
2360 * Ok - we have an anonymous connection to the IPC$ share.
2361 * Now start the NT Domain stuff :-).
2364 if(cli_nt_session_open(the_cli
, PIPE_SPOOLSS
) == False
) {
2365 DEBUG(0,("connect_to_client: unable to open the domain client session to machine %s. Error was : %s.\n", remote_machine
, cli_errstr(the_cli
)));
2366 cli_nt_session_close(the_cli
);
2367 cli_ulogoff(the_cli
);
2368 cli_shutdown(the_cli
);
2375 /***************************************************************************
2376 Connect to the client.
2377 ****************************************************************************/
2379 static BOOL
srv_spoolss_replyopenprinter(char *printer
, uint32 localprinter
, uint32 type
, POLICY_HND
*handle
)
2384 * If it's the first connection, contact the client
2385 * and connect to the IPC$ share anonumously
2387 if (smb_connections
==0) {
2388 fstring unix_printer
;
2390 fstrcpy(unix_printer
, printer
+2); /* the +2 is to strip the leading 2 backslashs */
2392 if(!spoolss_connect_to_client(¬ify_cli
, unix_printer
))
2395 message_register(MSG_PRINTER_NOTIFY2
, receive_notify2_message_list
);
2396 /* Tell the connections db we're now interested in printer
2397 * notify messages. */
2398 register_message_flags( True
, FLAG_MSG_PRINTING
);
2403 result
= cli_spoolss_reply_open_printer(¬ify_cli
, notify_cli
.mem_ctx
, printer
, localprinter
,
2406 if (!W_ERROR_IS_OK(result
))
2407 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2408 dos_errstr(result
)));
2410 return (W_ERROR_IS_OK(result
));
2413 /********************************************************************
2415 * ReplyFindFirstPrinterChangeNotifyEx
2417 * before replying OK: status=0 a rpc call is made to the workstation
2418 * asking ReplyOpenPrinter
2420 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2421 * called from api_spoolss_rffpcnex
2422 ********************************************************************/
2424 WERROR
_spoolss_rffpcnex(pipes_struct
*p
, SPOOL_Q_RFFPCNEX
*q_u
, SPOOL_R_RFFPCNEX
*r_u
)
2426 POLICY_HND
*handle
= &q_u
->handle
;
2427 uint32 flags
= q_u
->flags
;
2428 uint32 options
= q_u
->options
;
2429 UNISTR2
*localmachine
= &q_u
->localmachine
;
2430 uint32 printerlocal
= q_u
->printerlocal
;
2431 SPOOL_NOTIFY_OPTION
*option
= q_u
->option
;
2433 /* store the notify value in the printer struct */
2435 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
2438 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
2442 Printer
->notify
.flags
=flags
;
2443 Printer
->notify
.options
=options
;
2444 Printer
->notify
.printerlocal
=printerlocal
;
2446 if (Printer
->notify
.option
)
2447 free_spool_notify_option(&Printer
->notify
.option
);
2449 Printer
->notify
.option
=dup_spool_notify_option(option
);
2451 unistr2_to_ascii(Printer
->notify
.localmachine
, localmachine
,
2452 sizeof(Printer
->notify
.localmachine
)-1);
2454 /* Connect to the client machine and send a ReplyOpenPrinter */
2456 if(!srv_spoolss_replyopenprinter(Printer
->notify
.localmachine
,
2457 Printer
->notify
.printerlocal
, 1,
2458 &Printer
->notify
.client_hnd
))
2459 return WERR_SERVER_UNAVAILABLE
;
2461 Printer
->notify
.client_connected
=True
;
2466 /*******************************************************************
2467 * fill a notify_info_data with the servername
2468 ********************************************************************/
2470 void spoolss_notify_server_name(int snum
,
2471 SPOOL_NOTIFY_INFO_DATA
*data
,
2472 print_queue_struct
*queue
,
2473 NT_PRINTER_INFO_LEVEL
*printer
,
2474 TALLOC_CTX
*mem_ctx
)
2476 pstring temp_name
, temp
;
2479 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", get_called_name());
2481 len
= rpcstr_push(temp
, temp_name
, sizeof(temp
)-2, STR_TERMINATE
);
2483 data
->notify_data
.data
.length
= len
;
2484 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2486 if (!data
->notify_data
.data
.string
) {
2487 data
->notify_data
.data
.length
= 0;
2491 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2494 /*******************************************************************
2495 * fill a notify_info_data with the printername (not including the servername).
2496 ********************************************************************/
2498 void spoolss_notify_printer_name(int snum
,
2499 SPOOL_NOTIFY_INFO_DATA
*data
,
2500 print_queue_struct
*queue
,
2501 NT_PRINTER_INFO_LEVEL
*printer
,
2502 TALLOC_CTX
*mem_ctx
)
2507 /* the notify name should not contain the \\server\ part */
2508 char *p
= strrchr(printer
->info_2
->printername
, '\\');
2511 p
= printer
->info_2
->printername
;
2516 len
= rpcstr_push(temp
, p
, sizeof(temp
)-2, STR_TERMINATE
);
2518 data
->notify_data
.data
.length
= len
;
2519 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2521 if (!data
->notify_data
.data
.string
) {
2522 data
->notify_data
.data
.length
= 0;
2526 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2529 /*******************************************************************
2530 * fill a notify_info_data with the servicename
2531 ********************************************************************/
2533 void spoolss_notify_share_name(int snum
,
2534 SPOOL_NOTIFY_INFO_DATA
*data
,
2535 print_queue_struct
*queue
,
2536 NT_PRINTER_INFO_LEVEL
*printer
,
2537 TALLOC_CTX
*mem_ctx
)
2542 len
= rpcstr_push(temp
, lp_servicename(snum
), sizeof(temp
)-2, STR_TERMINATE
);
2544 data
->notify_data
.data
.length
= len
;
2545 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2547 if (!data
->notify_data
.data
.string
) {
2548 data
->notify_data
.data
.length
= 0;
2552 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2555 /*******************************************************************
2556 * fill a notify_info_data with the port name
2557 ********************************************************************/
2559 void spoolss_notify_port_name(int snum
,
2560 SPOOL_NOTIFY_INFO_DATA
*data
,
2561 print_queue_struct
*queue
,
2562 NT_PRINTER_INFO_LEVEL
*printer
,
2563 TALLOC_CTX
*mem_ctx
)
2568 /* even if it's strange, that's consistant in all the code */
2570 len
= rpcstr_push(temp
, printer
->info_2
->portname
, sizeof(temp
)-2, STR_TERMINATE
);
2572 data
->notify_data
.data
.length
= len
;
2573 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2575 if (!data
->notify_data
.data
.string
) {
2576 data
->notify_data
.data
.length
= 0;
2580 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2583 /*******************************************************************
2584 * fill a notify_info_data with the printername
2585 * but it doesn't exist, have to see what to do
2586 ********************************************************************/
2588 void spoolss_notify_driver_name(int snum
,
2589 SPOOL_NOTIFY_INFO_DATA
*data
,
2590 print_queue_struct
*queue
,
2591 NT_PRINTER_INFO_LEVEL
*printer
,
2592 TALLOC_CTX
*mem_ctx
)
2597 len
= rpcstr_push(temp
, printer
->info_2
->drivername
, sizeof(temp
)-2, STR_TERMINATE
);
2599 data
->notify_data
.data
.length
= len
;
2600 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2602 if (!data
->notify_data
.data
.string
) {
2603 data
->notify_data
.data
.length
= 0;
2607 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2610 /*******************************************************************
2611 * fill a notify_info_data with the comment
2612 ********************************************************************/
2614 void spoolss_notify_comment(int snum
,
2615 SPOOL_NOTIFY_INFO_DATA
*data
,
2616 print_queue_struct
*queue
,
2617 NT_PRINTER_INFO_LEVEL
*printer
,
2618 TALLOC_CTX
*mem_ctx
)
2623 if (*printer
->info_2
->comment
== '\0')
2624 len
= rpcstr_push(temp
, lp_comment(snum
), sizeof(temp
)-2, STR_TERMINATE
);
2626 len
= rpcstr_push(temp
, printer
->info_2
->comment
, sizeof(temp
)-2, STR_TERMINATE
);
2628 data
->notify_data
.data
.length
= len
;
2629 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2631 if (!data
->notify_data
.data
.string
) {
2632 data
->notify_data
.data
.length
= 0;
2636 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2639 /*******************************************************************
2640 * fill a notify_info_data with the comment
2641 * location = "Room 1, floor 2, building 3"
2642 ********************************************************************/
2644 void spoolss_notify_location(int snum
,
2645 SPOOL_NOTIFY_INFO_DATA
*data
,
2646 print_queue_struct
*queue
,
2647 NT_PRINTER_INFO_LEVEL
*printer
,
2648 TALLOC_CTX
*mem_ctx
)
2653 len
= rpcstr_push(temp
, printer
->info_2
->location
,sizeof(temp
)-2, STR_TERMINATE
);
2655 data
->notify_data
.data
.length
= len
;
2656 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2658 if (!data
->notify_data
.data
.string
) {
2659 data
->notify_data
.data
.length
= 0;
2663 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2666 /*******************************************************************
2667 * fill a notify_info_data with the device mode
2668 * jfm:xxxx don't to it for know but that's a real problem !!!
2669 ********************************************************************/
2671 static void spoolss_notify_devmode(int snum
,
2672 SPOOL_NOTIFY_INFO_DATA
*data
,
2673 print_queue_struct
*queue
,
2674 NT_PRINTER_INFO_LEVEL
*printer
,
2675 TALLOC_CTX
*mem_ctx
)
2679 /*******************************************************************
2680 * fill a notify_info_data with the separator file name
2681 ********************************************************************/
2683 void spoolss_notify_sepfile(int snum
,
2684 SPOOL_NOTIFY_INFO_DATA
*data
,
2685 print_queue_struct
*queue
,
2686 NT_PRINTER_INFO_LEVEL
*printer
,
2687 TALLOC_CTX
*mem_ctx
)
2692 len
= rpcstr_push(temp
, printer
->info_2
->sepfile
, sizeof(temp
)-2, STR_TERMINATE
);
2694 data
->notify_data
.data
.length
= len
;
2695 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2697 if (!data
->notify_data
.data
.string
) {
2698 data
->notify_data
.data
.length
= 0;
2702 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2705 /*******************************************************************
2706 * fill a notify_info_data with the print processor
2707 * jfm:xxxx return always winprint to indicate we don't do anything to it
2708 ********************************************************************/
2710 void spoolss_notify_print_processor(int snum
,
2711 SPOOL_NOTIFY_INFO_DATA
*data
,
2712 print_queue_struct
*queue
,
2713 NT_PRINTER_INFO_LEVEL
*printer
,
2714 TALLOC_CTX
*mem_ctx
)
2719 len
= rpcstr_push(temp
, printer
->info_2
->printprocessor
, sizeof(temp
)-2, STR_TERMINATE
);
2721 data
->notify_data
.data
.length
= len
;
2722 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2724 if (!data
->notify_data
.data
.string
) {
2725 data
->notify_data
.data
.length
= 0;
2729 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2732 /*******************************************************************
2733 * fill a notify_info_data with the print processor options
2734 * jfm:xxxx send an empty string
2735 ********************************************************************/
2737 void spoolss_notify_parameters(int snum
,
2738 SPOOL_NOTIFY_INFO_DATA
*data
,
2739 print_queue_struct
*queue
,
2740 NT_PRINTER_INFO_LEVEL
*printer
,
2741 TALLOC_CTX
*mem_ctx
)
2746 len
= rpcstr_push(temp
, printer
->info_2
->parameters
, sizeof(temp
)-2, STR_TERMINATE
);
2748 data
->notify_data
.data
.length
= len
;
2749 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2751 if (!data
->notify_data
.data
.string
) {
2752 data
->notify_data
.data
.length
= 0;
2756 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2759 /*******************************************************************
2760 * fill a notify_info_data with the data type
2761 * jfm:xxxx always send RAW as data type
2762 ********************************************************************/
2764 void spoolss_notify_datatype(int snum
,
2765 SPOOL_NOTIFY_INFO_DATA
*data
,
2766 print_queue_struct
*queue
,
2767 NT_PRINTER_INFO_LEVEL
*printer
,
2768 TALLOC_CTX
*mem_ctx
)
2773 len
= rpcstr_push(temp
, printer
->info_2
->datatype
, sizeof(pstring
)-2, STR_TERMINATE
);
2775 data
->notify_data
.data
.length
= len
;
2776 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2778 if (!data
->notify_data
.data
.string
) {
2779 data
->notify_data
.data
.length
= 0;
2783 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2786 /*******************************************************************
2787 * fill a notify_info_data with the security descriptor
2788 * jfm:xxxx send an null pointer to say no security desc
2789 * have to implement security before !
2790 ********************************************************************/
2792 static void spoolss_notify_security_desc(int snum
,
2793 SPOOL_NOTIFY_INFO_DATA
*data
,
2794 print_queue_struct
*queue
,
2795 NT_PRINTER_INFO_LEVEL
*printer
,
2796 TALLOC_CTX
*mem_ctx
)
2798 data
->notify_data
.sd
.size
= printer
->info_2
->secdesc_buf
->len
;
2799 data
->notify_data
.sd
.desc
= dup_sec_desc( mem_ctx
, printer
->info_2
->secdesc_buf
->sec
) ;
2802 /*******************************************************************
2803 * fill a notify_info_data with the attributes
2804 * jfm:xxxx a samba printer is always shared
2805 ********************************************************************/
2807 void spoolss_notify_attributes(int snum
,
2808 SPOOL_NOTIFY_INFO_DATA
*data
,
2809 print_queue_struct
*queue
,
2810 NT_PRINTER_INFO_LEVEL
*printer
,
2811 TALLOC_CTX
*mem_ctx
)
2813 data
->notify_data
.value
[0] = printer
->info_2
->attributes
;
2814 data
->notify_data
.value
[1] = 0;
2817 /*******************************************************************
2818 * fill a notify_info_data with the priority
2819 ********************************************************************/
2821 static void spoolss_notify_priority(int snum
,
2822 SPOOL_NOTIFY_INFO_DATA
*data
,
2823 print_queue_struct
*queue
,
2824 NT_PRINTER_INFO_LEVEL
*printer
,
2825 TALLOC_CTX
*mem_ctx
)
2827 data
->notify_data
.value
[0] = printer
->info_2
->priority
;
2828 data
->notify_data
.value
[1] = 0;
2831 /*******************************************************************
2832 * fill a notify_info_data with the default priority
2833 ********************************************************************/
2835 static void spoolss_notify_default_priority(int snum
,
2836 SPOOL_NOTIFY_INFO_DATA
*data
,
2837 print_queue_struct
*queue
,
2838 NT_PRINTER_INFO_LEVEL
*printer
,
2839 TALLOC_CTX
*mem_ctx
)
2841 data
->notify_data
.value
[0] = printer
->info_2
->default_priority
;
2842 data
->notify_data
.value
[1] = 0;
2845 /*******************************************************************
2846 * fill a notify_info_data with the start time
2847 ********************************************************************/
2849 static void spoolss_notify_start_time(int snum
,
2850 SPOOL_NOTIFY_INFO_DATA
*data
,
2851 print_queue_struct
*queue
,
2852 NT_PRINTER_INFO_LEVEL
*printer
,
2853 TALLOC_CTX
*mem_ctx
)
2855 data
->notify_data
.value
[0] = printer
->info_2
->starttime
;
2856 data
->notify_data
.value
[1] = 0;
2859 /*******************************************************************
2860 * fill a notify_info_data with the until time
2861 ********************************************************************/
2863 static void spoolss_notify_until_time(int snum
,
2864 SPOOL_NOTIFY_INFO_DATA
*data
,
2865 print_queue_struct
*queue
,
2866 NT_PRINTER_INFO_LEVEL
*printer
,
2867 TALLOC_CTX
*mem_ctx
)
2869 data
->notify_data
.value
[0] = printer
->info_2
->untiltime
;
2870 data
->notify_data
.value
[1] = 0;
2873 /*******************************************************************
2874 * fill a notify_info_data with the status
2875 ********************************************************************/
2877 static void spoolss_notify_status(int snum
,
2878 SPOOL_NOTIFY_INFO_DATA
*data
,
2879 print_queue_struct
*queue
,
2880 NT_PRINTER_INFO_LEVEL
*printer
,
2881 TALLOC_CTX
*mem_ctx
)
2883 print_status_struct status
;
2885 print_queue_length(snum
, &status
);
2886 data
->notify_data
.value
[0]=(uint32
) status
.status
;
2887 data
->notify_data
.value
[1] = 0;
2890 /*******************************************************************
2891 * fill a notify_info_data with the number of jobs queued
2892 ********************************************************************/
2894 void spoolss_notify_cjobs(int snum
,
2895 SPOOL_NOTIFY_INFO_DATA
*data
,
2896 print_queue_struct
*queue
,
2897 NT_PRINTER_INFO_LEVEL
*printer
,
2898 TALLOC_CTX
*mem_ctx
)
2900 data
->notify_data
.value
[0] = print_queue_length(snum
, NULL
);
2901 data
->notify_data
.value
[1] = 0;
2904 /*******************************************************************
2905 * fill a notify_info_data with the average ppm
2906 ********************************************************************/
2908 static void spoolss_notify_average_ppm(int snum
,
2909 SPOOL_NOTIFY_INFO_DATA
*data
,
2910 print_queue_struct
*queue
,
2911 NT_PRINTER_INFO_LEVEL
*printer
,
2912 TALLOC_CTX
*mem_ctx
)
2914 /* always respond 8 pages per minutes */
2915 /* a little hard ! */
2916 data
->notify_data
.value
[0] = printer
->info_2
->averageppm
;
2917 data
->notify_data
.value
[1] = 0;
2920 /*******************************************************************
2921 * fill a notify_info_data with username
2922 ********************************************************************/
2924 static void spoolss_notify_username(int snum
,
2925 SPOOL_NOTIFY_INFO_DATA
*data
,
2926 print_queue_struct
*queue
,
2927 NT_PRINTER_INFO_LEVEL
*printer
,
2928 TALLOC_CTX
*mem_ctx
)
2933 len
= rpcstr_push(temp
, queue
->fs_user
, sizeof(temp
)-2, STR_TERMINATE
);
2935 data
->notify_data
.data
.length
= len
;
2936 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2938 if (!data
->notify_data
.data
.string
) {
2939 data
->notify_data
.data
.length
= 0;
2943 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2946 /*******************************************************************
2947 * fill a notify_info_data with job status
2948 ********************************************************************/
2950 static void spoolss_notify_job_status(int snum
,
2951 SPOOL_NOTIFY_INFO_DATA
*data
,
2952 print_queue_struct
*queue
,
2953 NT_PRINTER_INFO_LEVEL
*printer
,
2954 TALLOC_CTX
*mem_ctx
)
2956 data
->notify_data
.value
[0]=nt_printj_status(queue
->status
);
2957 data
->notify_data
.value
[1] = 0;
2960 /*******************************************************************
2961 * fill a notify_info_data with job name
2962 ********************************************************************/
2964 static void spoolss_notify_job_name(int snum
,
2965 SPOOL_NOTIFY_INFO_DATA
*data
,
2966 print_queue_struct
*queue
,
2967 NT_PRINTER_INFO_LEVEL
*printer
,
2968 TALLOC_CTX
*mem_ctx
)
2973 len
= rpcstr_push(temp
, queue
->fs_file
, sizeof(temp
)-2, STR_TERMINATE
);
2975 data
->notify_data
.data
.length
= len
;
2976 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
2978 if (!data
->notify_data
.data
.string
) {
2979 data
->notify_data
.data
.length
= 0;
2983 memcpy(data
->notify_data
.data
.string
, temp
, len
);
2986 /*******************************************************************
2987 * fill a notify_info_data with job status
2988 ********************************************************************/
2990 static void spoolss_notify_job_status_string(int snum
,
2991 SPOOL_NOTIFY_INFO_DATA
*data
,
2992 print_queue_struct
*queue
,
2993 NT_PRINTER_INFO_LEVEL
*printer
,
2994 TALLOC_CTX
*mem_ctx
)
2997 * Now we're returning job status codes we just return a "" here. JRA.
3004 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3007 switch (queue
->status
) {
3012 p
= ""; /* NT provides the paused string */
3021 #endif /* NO LONGER NEEDED. */
3023 len
= rpcstr_push(temp
, p
, sizeof(temp
) - 2, STR_TERMINATE
);
3025 data
->notify_data
.data
.length
= len
;
3026 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
3028 if (!data
->notify_data
.data
.string
) {
3029 data
->notify_data
.data
.length
= 0;
3033 memcpy(data
->notify_data
.data
.string
, temp
, len
);
3036 /*******************************************************************
3037 * fill a notify_info_data with job time
3038 ********************************************************************/
3040 static void spoolss_notify_job_time(int snum
,
3041 SPOOL_NOTIFY_INFO_DATA
*data
,
3042 print_queue_struct
*queue
,
3043 NT_PRINTER_INFO_LEVEL
*printer
,
3044 TALLOC_CTX
*mem_ctx
)
3046 data
->notify_data
.value
[0]=0x0;
3047 data
->notify_data
.value
[1]=0;
3050 /*******************************************************************
3051 * fill a notify_info_data with job size
3052 ********************************************************************/
3054 static void spoolss_notify_job_size(int snum
,
3055 SPOOL_NOTIFY_INFO_DATA
*data
,
3056 print_queue_struct
*queue
,
3057 NT_PRINTER_INFO_LEVEL
*printer
,
3058 TALLOC_CTX
*mem_ctx
)
3060 data
->notify_data
.value
[0]=queue
->size
;
3061 data
->notify_data
.value
[1]=0;
3064 /*******************************************************************
3065 * fill a notify_info_data with page info
3066 ********************************************************************/
3067 static void spoolss_notify_total_pages(int snum
,
3068 SPOOL_NOTIFY_INFO_DATA
*data
,
3069 print_queue_struct
*queue
,
3070 NT_PRINTER_INFO_LEVEL
*printer
,
3071 TALLOC_CTX
*mem_ctx
)
3073 data
->notify_data
.value
[0]=queue
->page_count
;
3074 data
->notify_data
.value
[1]=0;
3077 /*******************************************************************
3078 * fill a notify_info_data with pages printed info.
3079 ********************************************************************/
3080 static void spoolss_notify_pages_printed(int snum
,
3081 SPOOL_NOTIFY_INFO_DATA
*data
,
3082 print_queue_struct
*queue
,
3083 NT_PRINTER_INFO_LEVEL
*printer
,
3084 TALLOC_CTX
*mem_ctx
)
3086 data
->notify_data
.value
[0]=0; /* Add code when back-end tracks this */
3087 data
->notify_data
.value
[1]=0;
3090 /*******************************************************************
3091 Fill a notify_info_data with job position.
3092 ********************************************************************/
3094 static void spoolss_notify_job_position(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]=queue
->job
;
3101 data
->notify_data
.value
[1]=0;
3104 /*******************************************************************
3105 Fill a notify_info_data with submitted time.
3106 ********************************************************************/
3108 static void spoolss_notify_submitted_time(int snum
,
3109 SPOOL_NOTIFY_INFO_DATA
*data
,
3110 print_queue_struct
*queue
,
3111 NT_PRINTER_INFO_LEVEL
*printer
,
3112 TALLOC_CTX
*mem_ctx
)
3119 t
=gmtime(&queue
->time
);
3121 len
= sizeof(SYSTEMTIME
);
3123 data
->notify_data
.data
.length
= len
;
3124 data
->notify_data
.data
.string
= (uint16
*)talloc(mem_ctx
, len
);
3126 if (!data
->notify_data
.data
.string
) {
3127 data
->notify_data
.data
.length
= 0;
3131 make_systemtime(&st
, t
);
3134 * Systemtime must be linearized as a set of UINT16's.
3135 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3138 p
= (char *)data
->notify_data
.data
.string
;
3139 SSVAL(p
, 0, st
.year
);
3140 SSVAL(p
, 2, st
.month
);
3141 SSVAL(p
, 4, st
.dayofweek
);
3142 SSVAL(p
, 6, st
.day
);
3143 SSVAL(p
, 8, st
.hour
);
3144 SSVAL(p
, 10, st
.minute
);
3145 SSVAL(p
, 12, st
.second
);
3146 SSVAL(p
, 14, st
.milliseconds
);
3149 struct s_notify_info_data_table
3155 void (*fn
) (int snum
, SPOOL_NOTIFY_INFO_DATA
*data
,
3156 print_queue_struct
*queue
,
3157 NT_PRINTER_INFO_LEVEL
*printer
, TALLOC_CTX
*mem_ctx
);
3160 /* A table describing the various print notification constants and
3161 whether the notification data is a pointer to a variable sized
3162 buffer, a one value uint32 or a two value uint32. */
3164 struct s_notify_info_data_table notify_info_data_table
[] =
3166 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SERVER_NAME
, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3167 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINTER_NAME
, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3168 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SHARE_NAME
, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING
, spoolss_notify_share_name
},
3169 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PORT_NAME
, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3170 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DRIVER_NAME
, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3171 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_COMMENT
, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING
, spoolss_notify_comment
},
3172 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_LOCATION
, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING
, spoolss_notify_location
},
3173 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEVMODE
, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3174 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SEPFILE
, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING
, spoolss_notify_sepfile
},
3175 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRINT_PROCESSOR
, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3176 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PARAMETERS
, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3177 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DATATYPE
, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3178 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_SECURITY_DESCRIPTOR
, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC
, spoolss_notify_security_desc
},
3179 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_ATTRIBUTES
, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE
, spoolss_notify_attributes
},
3180 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PRIORITY
, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3181 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_DEFAULT_PRIORITY
, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_default_priority
},
3182 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_START_TIME
, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3183 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_UNTIL_TIME
, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3184 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS
, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_status
},
3185 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_STATUS_STRING
, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER
, NULL
},
3186 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_CJOBS
, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE
, spoolss_notify_cjobs
},
3187 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_AVERAGE_PPM
, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE
, spoolss_notify_average_ppm
},
3188 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_PAGES
, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER
, NULL
},
3189 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_PAGES_PRINTED
, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER
, NULL
},
3190 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_TOTAL_BYTES
, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER
, NULL
},
3191 { PRINTER_NOTIFY_TYPE
, PRINTER_NOTIFY_BYTES_PRINTED
, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER
, NULL
},
3192 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINTER_NAME
, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING
, spoolss_notify_printer_name
},
3193 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_MACHINE_NAME
, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING
, spoolss_notify_server_name
},
3194 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PORT_NAME
, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING
, spoolss_notify_port_name
},
3195 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_USER_NAME
, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3196 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_NOTIFY_NAME
, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING
, spoolss_notify_username
},
3197 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DATATYPE
, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING
, spoolss_notify_datatype
},
3198 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRINT_PROCESSOR
, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING
, spoolss_notify_print_processor
},
3199 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PARAMETERS
, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING
, spoolss_notify_parameters
},
3200 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DRIVER_NAME
, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING
, spoolss_notify_driver_name
},
3201 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DEVMODE
, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER
, spoolss_notify_devmode
},
3202 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS
, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE
, spoolss_notify_job_status
},
3203 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_STATUS_STRING
, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING
, spoolss_notify_job_status_string
},
3204 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SECURITY_DESCRIPTOR
, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER
, NULL
},
3205 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_DOCUMENT
, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING
, spoolss_notify_job_name
},
3206 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PRIORITY
, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE
, spoolss_notify_priority
},
3207 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_POSITION
, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE
, spoolss_notify_job_position
},
3208 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_SUBMITTED
, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER
, spoolss_notify_submitted_time
},
3209 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_START_TIME
, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_start_time
},
3210 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_UNTIL_TIME
, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_until_time
},
3211 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TIME
, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE
, spoolss_notify_job_time
},
3212 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_PAGES
, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE
, spoolss_notify_total_pages
},
3213 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_PAGES_PRINTED
, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE
, spoolss_notify_pages_printed
},
3214 { JOB_NOTIFY_TYPE
, JOB_NOTIFY_TOTAL_BYTES
, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE
, spoolss_notify_job_size
},
3217 /*******************************************************************
3218 Return the size of info_data structure.
3219 ********************************************************************/
3221 static uint32
size_of_notify_info_data(uint16 type
, uint16 field
)
3225 for (i
= 0; i
< sizeof(notify_info_data_table
); i
++)
3227 if ( (notify_info_data_table
[i
].type
== type
)
3228 && (notify_info_data_table
[i
].field
== field
) )
3230 switch(notify_info_data_table
[i
].size
)
3232 case NOTIFY_ONE_VALUE
:
3233 case NOTIFY_TWO_VALUE
:
3238 /* The only pointer notify data I have seen on
3239 the wire is the submitted time and this has
3240 the notify size set to 4. -tpot */
3242 case NOTIFY_POINTER
:
3245 case NOTIFY_SECDESC
:
3251 DEBUG(5, ("invalid notify data type %d/%d\n", type
, field
));
3256 /*******************************************************************
3257 Return the type of notify_info_data.
3258 ********************************************************************/
3260 static int type_of_notify_info_data(uint16 type
, uint16 field
)
3264 for (i
= 0; i
< sizeof(notify_info_data_table
); i
++) {
3265 if (notify_info_data_table
[i
].type
== type
&&
3266 notify_info_data_table
[i
].field
== field
)
3267 return notify_info_data_table
[i
].size
;
3273 /****************************************************************************
3274 ****************************************************************************/
3276 static int search_notify(uint16 type
, uint16 field
, int *value
)
3280 for (i
= 0; i
< sizeof(notify_info_data_table
); i
++) {
3281 if (notify_info_data_table
[i
].type
== type
&&
3282 notify_info_data_table
[i
].field
== field
&&
3283 notify_info_data_table
[i
].fn
!= NULL
) {
3292 /****************************************************************************
3293 ****************************************************************************/
3295 void construct_info_data(SPOOL_NOTIFY_INFO_DATA
*info_data
, uint16 type
, uint16 field
, int id
)
3297 info_data
->type
= type
;
3298 info_data
->field
= field
;
3299 info_data
->reserved
= 0;
3301 info_data
->size
= size_of_notify_info_data(type
, field
);
3302 info_data
->enc_type
= type_of_notify_info_data(type
, field
);
3309 /*******************************************************************
3311 * fill a notify_info struct with info asked
3313 ********************************************************************/
3315 static BOOL
construct_notify_printer_info(SPOOL_NOTIFY_INFO
*info
, int
3316 snum
, SPOOL_NOTIFY_OPTION_TYPE
3317 *option_type
, uint32 id
,
3318 TALLOC_CTX
*mem_ctx
)
3324 SPOOL_NOTIFY_INFO_DATA
*current_data
, *tid
;
3325 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3326 print_queue_struct
*queue
=NULL
;
3328 type
=option_type
->type
;
3330 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3331 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3332 option_type
->count
, lp_servicename(snum
)));
3334 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
3337 for(field_num
=0; field_num
<option_type
->count
; field_num
++)
3339 field
= option_type
->fields
[field_num
];
3341 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num
, type
, field
));
3343 if (!search_notify(type
, field
, &j
) )
3346 if((tid
=(SPOOL_NOTIFY_INFO_DATA
*)Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
)
3348 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3354 current_data
= &info
->data
[info
->count
];
3356 construct_info_data(current_data
, type
, field
, id
);
3358 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3359 notify_info_data_table
[j
].name
, snum
, printer
->info_2
->printername
));
3361 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3367 free_a_printer(&printer
, 2);
3371 /*******************************************************************
3373 * fill a notify_info struct with info asked
3375 ********************************************************************/
3377 static BOOL
construct_notify_jobs_info(print_queue_struct
*queue
,
3378 SPOOL_NOTIFY_INFO
*info
,
3379 NT_PRINTER_INFO_LEVEL
*printer
,
3380 int snum
, SPOOL_NOTIFY_OPTION_TYPE
3381 *option_type
, uint32 id
,
3382 TALLOC_CTX
*mem_ctx
)
3388 SPOOL_NOTIFY_INFO_DATA
*current_data
, *tid
;
3390 DEBUG(4,("construct_notify_jobs_info\n"));
3392 type
= option_type
->type
;
3394 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3395 (option_type
->type
==PRINTER_NOTIFY_TYPE
?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3396 option_type
->count
));
3398 for(field_num
=0; field_num
<option_type
->count
; field_num
++) {
3399 field
= option_type
->fields
[field_num
];
3401 if (!search_notify(type
, field
, &j
) )
3404 if((tid
=Realloc(info
->data
, (info
->count
+1)*sizeof(SPOOL_NOTIFY_INFO_DATA
))) == NULL
) {
3405 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3408 else info
->data
= tid
;
3410 current_data
=&(info
->data
[info
->count
]);
3412 construct_info_data(current_data
, type
, field
, id
);
3413 notify_info_data_table
[j
].fn(snum
, current_data
, queue
,
3422 * JFM: The enumeration is not that simple, it's even non obvious.
3424 * let's take an example: I want to monitor the PRINTER SERVER for
3425 * the printer's name and the number of jobs currently queued.
3426 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3427 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3429 * I have 3 printers on the back of my server.
3431 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3434 * 1 printer 1 name 1
3435 * 2 printer 1 cjob 1
3436 * 3 printer 2 name 2
3437 * 4 printer 2 cjob 2
3438 * 5 printer 3 name 3
3439 * 6 printer 3 name 3
3441 * that's the print server case, the printer case is even worse.
3444 /*******************************************************************
3446 * enumerate all printers on the printserver
3447 * fill a notify_info struct with info asked
3449 ********************************************************************/
3451 static WERROR
printserver_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
,
3452 SPOOL_NOTIFY_INFO
*info
,
3453 TALLOC_CTX
*mem_ctx
)
3456 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3457 int n_services
=lp_numservices();
3460 SPOOL_NOTIFY_OPTION
*option
;
3461 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3463 DEBUG(4,("printserver_notify_info\n"));
3468 option
=Printer
->notify
.option
;
3474 for (i
=0; i
<option
->count
; i
++) {
3475 option_type
=&(option
->ctr
.type
[i
]);
3477 if (option_type
->type
!=PRINTER_NOTIFY_TYPE
)
3480 for (snum
=0; snum
<n_services
; snum
++)
3482 if ( lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) )
3483 construct_notify_printer_info ( info
, snum
, option_type
, snum
, mem_ctx
);
3489 * Debugging information, don't delete.
3492 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3493 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info
->version
, info
->flags
, info
->count
));
3494 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3496 for (i
=0; i
<info
->count
; i
++) {
3497 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3498 i
, info
->data
[i
].type
, info
->data
[i
].field
, info
->data
[i
].reserved
,
3499 info
->data
[i
].id
, info
->data
[i
].size
, info
->data
[i
].enc_type
));
3506 /*******************************************************************
3508 * fill a notify_info struct with info asked
3510 ********************************************************************/
3512 static WERROR
printer_notify_info(pipes_struct
*p
, POLICY_HND
*hnd
, SPOOL_NOTIFY_INFO
*info
,
3513 TALLOC_CTX
*mem_ctx
)
3516 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, hnd
);
3519 SPOOL_NOTIFY_OPTION
*option
;
3520 SPOOL_NOTIFY_OPTION_TYPE
*option_type
;
3522 print_queue_struct
*queue
=NULL
;
3523 print_status_struct status
;
3525 DEBUG(4,("printer_notify_info\n"));
3530 option
=Printer
->notify
.option
;
3536 get_printer_snum(p
, hnd
, &snum
);
3538 for (i
=0; i
<option
->count
; i
++) {
3539 option_type
=&option
->ctr
.type
[i
];
3541 switch ( option_type
->type
) {
3542 case PRINTER_NOTIFY_TYPE
:
3543 if(construct_notify_printer_info(info
, snum
,
3549 case JOB_NOTIFY_TYPE
: {
3550 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3552 count
= print_queue_status(snum
, &queue
, &status
);
3554 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2,
3555 lp_servicename(snum
))))
3558 for (j
=0; j
<count
; j
++) {
3559 construct_notify_jobs_info(&queue
[j
], info
,
3566 free_a_printer(&printer
, 2);
3576 * Debugging information, don't delete.
3579 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3580 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3581 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3583 for (i=0; i<info->count; i++) {
3584 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3585 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3586 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3592 /********************************************************************
3594 ********************************************************************/
3596 WERROR
_spoolss_rfnpcnex( pipes_struct
*p
, SPOOL_Q_RFNPCNEX
*q_u
, SPOOL_R_RFNPCNEX
*r_u
)
3598 POLICY_HND
*handle
= &q_u
->handle
;
3599 SPOOL_NOTIFY_INFO
*info
= &r_u
->info
;
3601 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
3602 WERROR result
= WERR_BADFID
;
3604 /* we always have a NOTIFY_INFO struct */
3608 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3609 OUR_HANDLE(handle
)));
3613 DEBUG(4,("Printer type %x\n",Printer
->printer_type
));
3616 * We are now using the change value, and
3617 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3618 * I don't have a global notification system, I'm sending back all the
3619 * informations even when _NOTHING_ has changed.
3622 /* We need to keep track of the change value to send back in
3623 RRPCN replies otherwise our updates are ignored. */
3625 if (Printer
->notify
.client_connected
) {
3626 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u
->change
));
3627 Printer
->notify
.change
= q_u
->change
;
3630 /* just ignore the SPOOL_NOTIFY_OPTION */
3632 switch (Printer
->printer_type
) {
3633 case PRINTER_HANDLE_IS_PRINTSERVER
:
3634 result
= printserver_notify_info(p
, handle
, info
, p
->mem_ctx
);
3637 case PRINTER_HANDLE_IS_PRINTER
:
3638 result
= printer_notify_info(p
, handle
, info
, p
->mem_ctx
);
3646 /********************************************************************
3647 * construct_printer_info_0
3648 * fill a printer_info_0 struct
3649 ********************************************************************/
3651 static BOOL
construct_printer_info_0(PRINTER_INFO_0
*printer
, int snum
)
3655 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3656 counter_printer_0
*session_counter
;
3657 uint32 global_counter
;
3660 print_status_struct status
;
3662 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
3665 count
= print_queue_length(snum
, &status
);
3667 /* check if we already have a counter for this printer */
3668 session_counter
= (counter_printer_0
*)ubi_dlFirst(&counter_list
);
3670 for(; session_counter
; session_counter
= (counter_printer_0
*)ubi_dlNext(session_counter
)) {
3671 if (session_counter
->snum
== snum
)
3675 /* it's the first time, add it to the list */
3676 if (session_counter
==NULL
) {
3677 if((session_counter
=(counter_printer_0
*)malloc(sizeof(counter_printer_0
))) == NULL
) {
3678 free_a_printer(&ntprinter
, 2);
3681 ZERO_STRUCTP(session_counter
);
3682 session_counter
->snum
=snum
;
3683 session_counter
->counter
=0;
3684 ubi_dlAddHead( &counter_list
, (ubi_dlNode
*)session_counter
);
3688 session_counter
->counter
++;
3691 * the global_counter should be stored in a TDB as it's common to all the clients
3692 * and should be zeroed on samba startup
3694 global_counter
=session_counter
->counter
;
3696 pstrcpy(chaine
,ntprinter
->info_2
->printername
);
3698 init_unistr(&printer
->printername
, chaine
);
3700 slprintf(chaine
,sizeof(chaine
)-1,"\\\\%s", get_called_name());
3701 init_unistr(&printer
->servername
, chaine
);
3703 printer
->cjobs
= count
;
3704 printer
->total_jobs
= 0;
3705 printer
->total_bytes
= 0;
3707 setuptime
= (time_t)ntprinter
->info_2
->setuptime
;
3708 t
=gmtime(&setuptime
);
3710 printer
->year
= t
->tm_year
+1900;
3711 printer
->month
= t
->tm_mon
+1;
3712 printer
->dayofweek
= t
->tm_wday
;
3713 printer
->day
= t
->tm_mday
;
3714 printer
->hour
= t
->tm_hour
;
3715 printer
->minute
= t
->tm_min
;
3716 printer
->second
= t
->tm_sec
;
3717 printer
->milliseconds
= 0;
3719 printer
->global_counter
= global_counter
;
3720 printer
->total_pages
= 0;
3721 #ifndef EMULATE_WIN2K_HACK /* JERRY */
3722 printer
->major_version
= 0x0004; /* NT 4 */
3723 printer
->build_version
= 0x0565; /* build 1381 */
3725 printer
->major_version
= 0x0005; /* NT 5 */
3726 printer
->build_version
= 0x0893; /* build 2195 */
3728 printer
->unknown7
= 0x1;
3729 printer
->unknown8
= 0x0;
3730 printer
->unknown9
= 0x0;
3731 printer
->session_counter
= session_counter
->counter
;
3732 printer
->unknown11
= 0x0;
3733 printer
->printer_errors
= 0x0; /* number of print failure */
3734 printer
->unknown13
= 0x0;
3735 printer
->unknown14
= 0x1;
3736 printer
->unknown15
= 0x024a; /* 586 Pentium ? */
3737 printer
->unknown16
= 0x0;
3738 printer
->change_id
= ntprinter
->info_2
->changeid
; /* ChangeID in milliseconds*/
3739 printer
->unknown18
= 0x0;
3740 printer
->status
= nt_printq_status(status
.status
);
3741 printer
->unknown20
= 0x0;
3742 printer
->c_setprinter
= get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3743 printer
->unknown22
= 0x0;
3744 printer
->unknown23
= 0x6; /* 6 ???*/
3745 printer
->unknown24
= 0; /* unknown 24 to 26 are always 0 */
3746 printer
->unknown25
= 0;
3747 printer
->unknown26
= 0;
3748 printer
->unknown27
= 0;
3749 printer
->unknown28
= 0;
3750 printer
->unknown29
= 0;
3752 free_a_printer(&ntprinter
,2);
3756 /********************************************************************
3757 * construct_printer_info_1
3758 * fill a printer_info_1 struct
3759 ********************************************************************/
3760 static BOOL
construct_printer_info_1(uint32 flags
, PRINTER_INFO_1
*printer
, int snum
)
3764 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3766 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
3769 printer
->flags
=flags
;
3771 if (*ntprinter
->info_2
->comment
== '\0') {
3772 init_unistr(&printer
->comment
, lp_comment(snum
));
3773 slprintf(chaine
,sizeof(chaine
)-1,"%s,%s,%s", ntprinter
->info_2
->printername
,
3774 ntprinter
->info_2
->drivername
, lp_comment(snum
));
3777 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
3778 slprintf(chaine
,sizeof(chaine
)-1,"%s,%s,%s", ntprinter
->info_2
->printername
,
3779 ntprinter
->info_2
->drivername
, ntprinter
->info_2
->comment
);
3782 slprintf(chaine2
,sizeof(chaine
)-1,"%s", ntprinter
->info_2
->printername
);
3784 init_unistr(&printer
->description
, chaine
);
3785 init_unistr(&printer
->name
, chaine2
);
3787 free_a_printer(&ntprinter
,2);
3792 /****************************************************************************
3793 Free a DEVMODE struct.
3794 ****************************************************************************/
3796 static void free_dev_mode(DEVICEMODE
*dev
)
3801 SAFE_FREE(dev
->private);
3806 /****************************************************************************
3807 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
3808 should be valid upon entry
3809 ****************************************************************************/
3811 static BOOL
convert_nt_devicemode( DEVICEMODE
*devmode
, NT_DEVICEMODE
*ntdevmode
)
3813 if ( !devmode
|| !ntdevmode
)
3816 init_unistr(&devmode
->devicename
, ntdevmode
->devicename
);
3818 init_unistr(&devmode
->formname
, ntdevmode
->formname
);
3820 devmode
->specversion
= ntdevmode
->specversion
;
3821 devmode
->driverversion
= ntdevmode
->driverversion
;
3822 devmode
->size
= ntdevmode
->size
;
3823 devmode
->driverextra
= ntdevmode
->driverextra
;
3824 devmode
->fields
= ntdevmode
->fields
;
3826 devmode
->orientation
= ntdevmode
->orientation
;
3827 devmode
->papersize
= ntdevmode
->papersize
;
3828 devmode
->paperlength
= ntdevmode
->paperlength
;
3829 devmode
->paperwidth
= ntdevmode
->paperwidth
;
3830 devmode
->scale
= ntdevmode
->scale
;
3831 devmode
->copies
= ntdevmode
->copies
;
3832 devmode
->defaultsource
= ntdevmode
->defaultsource
;
3833 devmode
->printquality
= ntdevmode
->printquality
;
3834 devmode
->color
= ntdevmode
->color
;
3835 devmode
->duplex
= ntdevmode
->duplex
;
3836 devmode
->yresolution
= ntdevmode
->yresolution
;
3837 devmode
->ttoption
= ntdevmode
->ttoption
;
3838 devmode
->collate
= ntdevmode
->collate
;
3839 devmode
->icmmethod
= ntdevmode
->icmmethod
;
3840 devmode
->icmintent
= ntdevmode
->icmintent
;
3841 devmode
->mediatype
= ntdevmode
->mediatype
;
3842 devmode
->dithertype
= ntdevmode
->dithertype
;
3844 if (ntdevmode
->private != NULL
) {
3845 if ((devmode
->private=(uint8
*)memdup(ntdevmode
->private, ntdevmode
->driverextra
)) == NULL
)
3852 /****************************************************************************
3853 Create a DEVMODE struct. Returns malloced memory.
3854 ****************************************************************************/
3856 DEVICEMODE
*construct_dev_mode(int snum
)
3858 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
3859 DEVICEMODE
*devmode
= NULL
;
3861 DEBUG(7,("construct_dev_mode\n"));
3863 DEBUGADD(8,("getting printer characteristics\n"));
3865 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
3868 if ( !printer
->info_2
->devmode
) {
3869 DEBUG(5, ("BONG! There was no device mode!\n"));
3873 if ((devmode
= (DEVICEMODE
*)malloc(sizeof(DEVICEMODE
))) == NULL
) {
3874 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
3878 ZERO_STRUCTP(devmode
);
3880 DEBUGADD(8,("loading DEVICEMODE\n"));
3882 if ( !convert_nt_devicemode( devmode
, printer
->info_2
->devmode
) ) {
3883 free_dev_mode( devmode
);
3888 free_a_printer(&printer
,2);
3893 /********************************************************************
3894 * construct_printer_info_2
3895 * fill a printer_info_2 struct
3896 ********************************************************************/
3898 static BOOL
construct_printer_info_2(PRINTER_INFO_2
*printer
, int snum
)
3901 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3903 print_status_struct status
;
3905 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
3908 count
= print_queue_length(snum
, &status
);
3910 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
3911 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
3912 init_unistr(&printer
->sharename
, lp_servicename(snum
)); /* sharename */
3913 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* port */
3914 init_unistr(&printer
->drivername
, ntprinter
->info_2
->drivername
); /* drivername */
3916 if (*ntprinter
->info_2
->comment
== '\0')
3917 init_unistr(&printer
->comment
, lp_comment(snum
)); /* comment */
3919 init_unistr(&printer
->comment
, ntprinter
->info_2
->comment
); /* saved comment. */
3921 init_unistr(&printer
->location
, ntprinter
->info_2
->location
); /* location */
3922 init_unistr(&printer
->sepfile
, ntprinter
->info_2
->sepfile
); /* separator file */
3923 init_unistr(&printer
->printprocessor
, ntprinter
->info_2
->printprocessor
);/* print processor */
3924 init_unistr(&printer
->datatype
, ntprinter
->info_2
->datatype
); /* datatype */
3925 init_unistr(&printer
->parameters
, ntprinter
->info_2
->parameters
); /* parameters (of print processor) */
3927 printer
->attributes
= ntprinter
->info_2
->attributes
;
3929 printer
->priority
= ntprinter
->info_2
->priority
; /* priority */
3930 printer
->defaultpriority
= ntprinter
->info_2
->default_priority
; /* default priority */
3931 printer
->starttime
= ntprinter
->info_2
->starttime
; /* starttime */
3932 printer
->untiltime
= ntprinter
->info_2
->untiltime
; /* untiltime */
3933 printer
->status
= nt_printq_status(status
.status
); /* status */
3934 printer
->cjobs
= count
; /* jobs */
3935 printer
->averageppm
= ntprinter
->info_2
->averageppm
; /* average pages per minute */
3937 if((printer
->devmode
= construct_dev_mode(snum
)) == NULL
) {
3938 DEBUG(8, ("Returning NULL Devicemode!\n"));
3941 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
3942 /* steal the printer info sec_desc structure. [badly done]. */
3943 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
3944 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen memory. */
3945 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen memory. */
3946 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen memory. */
3949 printer
->secdesc
= NULL
;
3952 free_a_printer(&ntprinter
, 2);
3956 /********************************************************************
3957 * construct_printer_info_3
3958 * fill a printer_info_3 struct
3959 ********************************************************************/
3961 static BOOL
construct_printer_info_3(PRINTER_INFO_3
**pp_printer
, int snum
)
3963 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
3964 PRINTER_INFO_3
*printer
= NULL
;
3966 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
3970 if ((printer
= (PRINTER_INFO_3
*)malloc(sizeof(PRINTER_INFO_3
))) == NULL
) {
3971 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
3975 ZERO_STRUCTP(printer
);
3977 printer
->flags
= 4; /* These are the components of the SD we are returning. */
3978 if (ntprinter
->info_2
->secdesc_buf
&& ntprinter
->info_2
->secdesc_buf
->len
!= 0) {
3979 /* steal the printer info sec_desc structure. [badly done]. */
3980 printer
->secdesc
= ntprinter
->info_2
->secdesc_buf
->sec
;
3984 * Set the flags for the components we are returning.
3987 if (printer
->secdesc
->owner_sid
)
3988 printer
->flags
|= OWNER_SECURITY_INFORMATION
;
3990 if (printer
->secdesc
->grp_sid
)
3991 printer
->flags
|= GROUP_SECURITY_INFORMATION
;
3993 if (printer
->secdesc
->dacl
)
3994 printer
->flags
|= DACL_SECURITY_INFORMATION
;
3996 if (printer
->secdesc
->sacl
)
3997 printer
->flags
|= SACL_SECURITY_INFORMATION
;
4000 ntprinter
->info_2
->secdesc_buf
->sec
= NULL
; /* Stolen the malloced memory. */
4001 ntprinter
->info_2
->secdesc_buf
->len
= 0; /* Stolen the malloced memory. */
4002 ntprinter
->info_2
->secdesc_buf
->max_len
= 0; /* Stolen the malloced memory. */
4005 free_a_printer(&ntprinter
, 2);
4007 *pp_printer
= printer
;
4011 /********************************************************************
4012 * construct_printer_info_4
4013 * fill a printer_info_4 struct
4014 ********************************************************************/
4016 static BOOL
construct_printer_info_4(PRINTER_INFO_4
*printer
, int snum
)
4018 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4020 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
4023 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4024 init_unistr(&printer
->servername
, ntprinter
->info_2
->servername
); /* servername*/
4025 printer
->attributes
= ntprinter
->info_2
->attributes
;
4027 free_a_printer(&ntprinter
, 2);
4031 /********************************************************************
4032 * construct_printer_info_5
4033 * fill a printer_info_5 struct
4034 ********************************************************************/
4036 static BOOL
construct_printer_info_5(PRINTER_INFO_5
*printer
, int snum
)
4038 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
4040 if (!W_ERROR_IS_OK(get_a_printer(&ntprinter
, 2, lp_servicename(snum
))))
4043 init_unistr(&printer
->printername
, ntprinter
->info_2
->printername
); /* printername*/
4044 init_unistr(&printer
->portname
, ntprinter
->info_2
->portname
); /* portname */
4045 printer
->attributes
= ntprinter
->info_2
->attributes
;
4046 printer
->device_not_selected_timeout
= 0x3a98;
4047 printer
->transmission_retry_timeout
= 0xafc8;
4049 free_a_printer(&ntprinter
, 2);
4053 /********************************************************************
4054 Spoolss_enumprinters.
4055 ********************************************************************/
4057 static WERROR
enum_all_printers_info_1(uint32 flags
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4061 int n_services
=lp_numservices();
4062 PRINTER_INFO_1
*tp
, *printers
=NULL
;
4063 PRINTER_INFO_1 current_prt
;
4065 DEBUG(4,("enum_all_printers_info_1\n"));
4067 for (snum
=0; snum
<n_services
; snum
++) {
4068 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4069 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4071 if (construct_printer_info_1(flags
, ¤t_prt
, snum
)) {
4072 if((tp
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_1
))) == NULL
) {
4073 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4074 SAFE_FREE(printers
);
4079 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned
));
4081 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_1
));
4087 /* check the required size. */
4088 for (i
=0; i
<*returned
; i
++)
4089 (*needed
) += spoolss_size_printer_info_1(&printers
[i
]);
4091 if (!alloc_buffer_size(buffer
, *needed
))
4092 return WERR_INSUFFICIENT_BUFFER
;
4094 /* fill the buffer with the structures */
4095 for (i
=0; i
<*returned
; i
++)
4096 smb_io_printer_info_1("", buffer
, &printers
[i
], 0);
4099 SAFE_FREE(printers
);
4101 if (*needed
> offered
) {
4103 return WERR_INSUFFICIENT_BUFFER
;
4109 /********************************************************************
4110 enum_all_printers_info_1_local.
4111 *********************************************************************/
4113 static WERROR
enum_all_printers_info_1_local(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4115 DEBUG(4,("enum_all_printers_info_1_local\n"));
4117 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4120 /********************************************************************
4121 enum_all_printers_info_1_name.
4122 *********************************************************************/
4124 static WERROR
enum_all_printers_info_1_name(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4128 DEBUG(4,("enum_all_printers_info_1_name\n"));
4130 if ((name
[0] == '\\') && (name
[1] == '\\'))
4133 if (is_myname_or_ipaddr(s
)) {
4134 return enum_all_printers_info_1(PRINTER_ENUM_ICON8
, buffer
, offered
, needed
, returned
);
4137 return WERR_INVALID_NAME
;
4140 /********************************************************************
4141 enum_all_printers_info_1_remote.
4142 *********************************************************************/
4144 static WERROR
enum_all_printers_info_1_remote(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4146 PRINTER_INFO_1
*printer
;
4147 fstring printername
;
4150 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4152 /* JFM: currently it's more a place holder than anything else.
4153 * In the spooler world there is a notion of server registration.
4154 * the print servers are registring (sp ?) on the PDC (in the same domain)
4156 * We should have a TDB here. The registration is done thru an undocumented RPC call.
4159 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
4164 slprintf(printername
, sizeof(printername
)-1,"Windows NT Remote Printers!!\\\\%s", get_called_name());
4165 slprintf(desc
, sizeof(desc
)-1,"%s", get_called_name());
4166 slprintf(comment
, sizeof(comment
)-1, "Logged on Domain");
4168 init_unistr(&printer
->description
, desc
);
4169 init_unistr(&printer
->name
, printername
);
4170 init_unistr(&printer
->comment
, comment
);
4171 printer
->flags
=PRINTER_ENUM_ICON3
|PRINTER_ENUM_CONTAINER
;
4173 /* check the required size. */
4174 *needed
+= spoolss_size_printer_info_1(printer
);
4176 if (!alloc_buffer_size(buffer
, *needed
)) {
4178 return WERR_INSUFFICIENT_BUFFER
;
4181 /* fill the buffer with the structures */
4182 smb_io_printer_info_1("", buffer
, printer
, 0);
4187 if (*needed
> offered
) {
4189 return WERR_INSUFFICIENT_BUFFER
;
4195 /********************************************************************
4196 enum_all_printers_info_1_network.
4197 *********************************************************************/
4199 static WERROR
enum_all_printers_info_1_network(fstring name
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4203 DEBUG(4,("enum_all_printers_info_1_network\n"));
4205 /* If we respond to a enum_printers level 1 on our name with flags
4206 set to PRINTER_ENUM_REMOTE with a list of printers then these
4207 printers incorrectly appear in the APW browse list.
4208 Specifically the printers for the server appear at the workgroup
4209 level where all the other servers in the domain are
4210 listed. Windows responds to this call with a
4211 WERR_CAN_NOT_COMPLETE so we should do the same. */
4213 if (name
[0] == '\\' && name
[1] == '\\')
4216 if (is_myname_or_ipaddr(s
))
4217 return WERR_CAN_NOT_COMPLETE
;
4219 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8
, buffer
, offered
, needed
, returned
);
4222 /********************************************************************
4223 * api_spoolss_enumprinters
4225 * called from api_spoolss_enumprinters (see this to understand)
4226 ********************************************************************/
4228 static WERROR
enum_all_printers_info_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
4232 int n_services
=lp_numservices();
4233 PRINTER_INFO_2
*tp
, *printers
=NULL
;
4234 PRINTER_INFO_2 current_prt
;
4236 for (snum
=0; snum
<n_services
; snum
++) {
4237 if (lp_browseable(snum
) && lp_snum_ok(snum
) && lp_print_ok(snum
) ) {
4238 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum
), snum
));
4240 if (construct_printer_info_2(¤t_prt
, snum
)) {
4241 if((tp
=Realloc(printers
, (*returned
+1)*sizeof(PRINTER_INFO_2
))) == NULL
) {
4242 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4243 SAFE_FREE(printers
);
4248 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned
));
4249 memcpy(&printers
[*returned
], ¤t_prt
, sizeof(PRINTER_INFO_2
));
4255 /* check the required size. */
4256 for (i
=0; i
<*returned
; i
++)
4257 (*needed
) += spoolss_size_printer_info_2(&printers
[i
]);
4259 if (!alloc_buffer_size(buffer
, *needed
)) {
4260 for (i
=0; i
<*returned
; i
++) {
4261 free_devmode(printers
[i
].devmode
);
4263 SAFE_FREE(printers
);
4264 return WERR_INSUFFICIENT_BUFFER
;
4267 /* fill the buffer with the structures */
4268 for (i
=0; i
<*returned
; i
++)
4269 smb_io_printer_info_2("", buffer
, &(printers
[i
]), 0);
4272 for (i
=0; i
<*returned
; i
++) {
4273 free_devmode(printers
[i
].devmode
);
4275 SAFE_FREE(printers
);
4277 if (*needed
> offered
) {
4279 return WERR_INSUFFICIENT_BUFFER
;
4285 /********************************************************************
4286 * handle enumeration of printers at level 1
4287 ********************************************************************/
4289 static WERROR
enumprinters_level1( uint32 flags
, fstring name
,
4290 NEW_BUFFER
*buffer
, uint32 offered
,
4291 uint32
*needed
, uint32
*returned
)
4293 /* Not all the flags are equals */
4295 if (flags
& PRINTER_ENUM_LOCAL
)
4296 return enum_all_printers_info_1_local(buffer
, offered
, needed
, returned
);
4298 if (flags
& PRINTER_ENUM_NAME
)
4299 return enum_all_printers_info_1_name(name
, buffer
, offered
, needed
, returned
);
4301 if (flags
& PRINTER_ENUM_REMOTE
)
4302 return enum_all_printers_info_1_remote(name
, buffer
, offered
, needed
, returned
);
4304 if (flags
& PRINTER_ENUM_NETWORK
)
4305 return enum_all_printers_info_1_network(name
, buffer
, offered
, needed
, returned
);
4307 return WERR_OK
; /* NT4sp5 does that */
4310 /********************************************************************
4311 * handle enumeration of printers at level 2
4312 ********************************************************************/
4314 static WERROR
enumprinters_level2( uint32 flags
, fstring servername
,
4315 NEW_BUFFER
*buffer
, uint32 offered
,
4316 uint32
*needed
, uint32
*returned
)
4318 char *s
= servername
;
4320 if (flags
& PRINTER_ENUM_LOCAL
) {
4321 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4324 if (flags
& PRINTER_ENUM_NAME
) {
4325 if ((servername
[0] == '\\') && (servername
[1] == '\\'))
4327 if (is_myname_or_ipaddr(s
))
4328 return enum_all_printers_info_2(buffer
, offered
, needed
, returned
);
4330 return WERR_INVALID_NAME
;
4333 if (flags
& PRINTER_ENUM_REMOTE
)
4334 return WERR_UNKNOWN_LEVEL
;
4339 /********************************************************************
4340 * handle enumeration of printers at level 5
4341 ********************************************************************/
4343 static WERROR
enumprinters_level5( uint32 flags
, fstring servername
,
4344 NEW_BUFFER
*buffer
, uint32 offered
,
4345 uint32
*needed
, uint32
*returned
)
4347 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4351 /********************************************************************
4352 * api_spoolss_enumprinters
4354 * called from api_spoolss_enumprinters (see this to understand)
4355 ********************************************************************/
4357 WERROR
_spoolss_enumprinters( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERS
*q_u
, SPOOL_R_ENUMPRINTERS
*r_u
)
4359 uint32 flags
= q_u
->flags
;
4360 UNISTR2
*servername
= &q_u
->servername
;
4361 uint32 level
= q_u
->level
;
4362 NEW_BUFFER
*buffer
= NULL
;
4363 uint32 offered
= q_u
->offered
;
4364 uint32
*needed
= &r_u
->needed
;
4365 uint32
*returned
= &r_u
->returned
;
4369 /* that's an [in out] buffer */
4370 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4371 buffer
= r_u
->buffer
;
4373 DEBUG(4,("_spoolss_enumprinters\n"));
4380 * flags==PRINTER_ENUM_NAME
4381 * if name=="" then enumerates all printers
4382 * if name!="" then enumerate the printer
4383 * flags==PRINTER_ENUM_REMOTE
4384 * name is NULL, enumerate printers
4385 * Level 2: name!="" enumerates printers, name can't be NULL
4386 * Level 3: doesn't exist
4387 * Level 4: does a local registry lookup
4388 * Level 5: same as Level 2
4391 unistr2_to_ascii(name
, servername
, sizeof(name
)-1);
4396 return enumprinters_level1(flags
, name
, buffer
, offered
, needed
, returned
);
4398 return enumprinters_level2(flags
, name
, buffer
, offered
, needed
, returned
);
4400 return enumprinters_level5(flags
, name
, buffer
, offered
, needed
, returned
);
4405 return WERR_UNKNOWN_LEVEL
;
4408 /****************************************************************************
4409 ****************************************************************************/
4411 static WERROR
getprinter_level_0(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4413 PRINTER_INFO_0
*printer
=NULL
;
4415 if((printer
=(PRINTER_INFO_0
*)malloc(sizeof(PRINTER_INFO_0
))) == NULL
)
4418 construct_printer_info_0(printer
, snum
);
4420 /* check the required size. */
4421 *needed
+= spoolss_size_printer_info_0(printer
);
4423 if (!alloc_buffer_size(buffer
, *needed
)) {
4425 return WERR_INSUFFICIENT_BUFFER
;
4428 /* fill the buffer with the structures */
4429 smb_io_printer_info_0("", buffer
, printer
, 0);
4434 if (*needed
> offered
) {
4435 return WERR_INSUFFICIENT_BUFFER
;
4441 /****************************************************************************
4442 ****************************************************************************/
4444 static WERROR
getprinter_level_1(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4446 PRINTER_INFO_1
*printer
=NULL
;
4448 if((printer
=(PRINTER_INFO_1
*)malloc(sizeof(PRINTER_INFO_1
))) == NULL
)
4451 construct_printer_info_1(PRINTER_ENUM_ICON8
, printer
, snum
);
4453 /* check the required size. */
4454 *needed
+= spoolss_size_printer_info_1(printer
);
4456 if (!alloc_buffer_size(buffer
, *needed
)) {
4458 return WERR_INSUFFICIENT_BUFFER
;
4461 /* fill the buffer with the structures */
4462 smb_io_printer_info_1("", buffer
, printer
, 0);
4467 if (*needed
> offered
) {
4468 return WERR_INSUFFICIENT_BUFFER
;
4474 /****************************************************************************
4475 ****************************************************************************/
4477 static WERROR
getprinter_level_2(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4479 PRINTER_INFO_2
*printer
=NULL
;
4481 if((printer
=(PRINTER_INFO_2
*)malloc(sizeof(PRINTER_INFO_2
)))==NULL
)
4484 construct_printer_info_2(printer
, snum
);
4486 /* check the required size. */
4487 *needed
+= spoolss_size_printer_info_2(printer
);
4489 if (!alloc_buffer_size(buffer
, *needed
)) {
4490 free_printer_info_2(printer
);
4491 return WERR_INSUFFICIENT_BUFFER
;
4494 /* fill the buffer with the structures */
4495 if (!smb_io_printer_info_2("", buffer
, printer
, 0)) {
4496 free_printer_info_2(printer
);
4501 free_printer_info_2(printer
);
4503 if (*needed
> offered
) {
4504 return WERR_INSUFFICIENT_BUFFER
;
4510 /****************************************************************************
4511 ****************************************************************************/
4513 static WERROR
getprinter_level_3(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4515 PRINTER_INFO_3
*printer
=NULL
;
4517 if (!construct_printer_info_3(&printer
, snum
))
4520 /* check the required size. */
4521 *needed
+= spoolss_size_printer_info_3(printer
);
4523 if (!alloc_buffer_size(buffer
, *needed
)) {
4524 free_printer_info_3(printer
);
4525 return WERR_INSUFFICIENT_BUFFER
;
4528 /* fill the buffer with the structures */
4529 smb_io_printer_info_3("", buffer
, printer
, 0);
4532 free_printer_info_3(printer
);
4534 if (*needed
> offered
) {
4535 return WERR_INSUFFICIENT_BUFFER
;
4541 /****************************************************************************
4542 ****************************************************************************/
4544 static WERROR
getprinter_level_4(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4546 PRINTER_INFO_4
*printer
=NULL
;
4548 if((printer
=(PRINTER_INFO_4
*)malloc(sizeof(PRINTER_INFO_4
)))==NULL
)
4551 if (!construct_printer_info_4(printer
, snum
))
4554 /* check the required size. */
4555 *needed
+= spoolss_size_printer_info_4(printer
);
4557 if (!alloc_buffer_size(buffer
, *needed
)) {
4558 free_printer_info_4(printer
);
4559 return WERR_INSUFFICIENT_BUFFER
;
4562 /* fill the buffer with the structures */
4563 smb_io_printer_info_4("", buffer
, printer
, 0);
4566 free_printer_info_4(printer
);
4568 if (*needed
> offered
) {
4569 return WERR_INSUFFICIENT_BUFFER
;
4575 /****************************************************************************
4576 ****************************************************************************/
4578 static WERROR
getprinter_level_5(int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
4580 PRINTER_INFO_5
*printer
=NULL
;
4582 if((printer
=(PRINTER_INFO_5
*)malloc(sizeof(PRINTER_INFO_5
)))==NULL
)
4585 if (!construct_printer_info_5(printer
, snum
))
4588 /* check the required size. */
4589 *needed
+= spoolss_size_printer_info_5(printer
);
4591 if (!alloc_buffer_size(buffer
, *needed
)) {
4592 free_printer_info_5(printer
);
4593 return WERR_INSUFFICIENT_BUFFER
;
4596 /* fill the buffer with the structures */
4597 smb_io_printer_info_5("", buffer
, printer
, 0);
4600 free_printer_info_5(printer
);
4602 if (*needed
> offered
) {
4603 return WERR_INSUFFICIENT_BUFFER
;
4609 /****************************************************************************
4610 ****************************************************************************/
4612 WERROR
_spoolss_getprinter(pipes_struct
*p
, SPOOL_Q_GETPRINTER
*q_u
, SPOOL_R_GETPRINTER
*r_u
)
4614 POLICY_HND
*handle
= &q_u
->handle
;
4615 uint32 level
= q_u
->level
;
4616 NEW_BUFFER
*buffer
= NULL
;
4617 uint32 offered
= q_u
->offered
;
4618 uint32
*needed
= &r_u
->needed
;
4622 /* that's an [in out] buffer */
4623 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
4624 buffer
= r_u
->buffer
;
4628 if (!get_printer_snum(p
, handle
, &snum
))
4633 return getprinter_level_0(snum
, buffer
, offered
, needed
);
4635 return getprinter_level_1(snum
, buffer
, offered
, needed
);
4637 return getprinter_level_2(snum
, buffer
, offered
, needed
);
4639 return getprinter_level_3(snum
, buffer
, offered
, needed
);
4641 return getprinter_level_4(snum
, buffer
, offered
, needed
);
4643 return getprinter_level_5(snum
, buffer
, offered
, needed
);
4645 return WERR_UNKNOWN_LEVEL
;
4648 /********************************************************************
4649 * fill a DRIVER_INFO_1 struct
4650 ********************************************************************/
4652 static void fill_printer_driver_info_1(DRIVER_INFO_1
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
, fstring architecture
)
4654 init_unistr( &info
->name
, driver
.info_3
->name
);
4657 /********************************************************************
4658 * construct_printer_driver_info_1
4659 ********************************************************************/
4661 static WERROR
construct_printer_driver_info_1(DRIVER_INFO_1
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
4663 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4664 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
4666 ZERO_STRUCT(driver
);
4668 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
4669 return WERR_INVALID_PRINTER_NAME
;
4671 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
)))
4672 return WERR_UNKNOWN_PRINTER_DRIVER
;
4674 fill_printer_driver_info_1(info
, driver
, servername
, architecture
);
4676 free_a_printer(&printer
,2);
4681 /********************************************************************
4682 * construct_printer_driver_info_2
4683 * fill a printer_info_2 struct
4684 ********************************************************************/
4686 static void fill_printer_driver_info_2(DRIVER_INFO_2
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
4690 info
->version
=driver
.info_3
->cversion
;
4692 init_unistr( &info
->name
, driver
.info_3
->name
);
4693 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
4696 if (strlen(driver
.info_3
->driverpath
)) {
4697 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
4698 init_unistr( &info
->driverpath
, temp
);
4700 init_unistr( &info
->driverpath
, "" );
4702 if (strlen(driver
.info_3
->datafile
)) {
4703 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
4704 init_unistr( &info
->datafile
, temp
);
4706 init_unistr( &info
->datafile
, "" );
4708 if (strlen(driver
.info_3
->configfile
)) {
4709 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
4710 init_unistr( &info
->configfile
, temp
);
4712 init_unistr( &info
->configfile
, "" );
4715 /********************************************************************
4716 * construct_printer_driver_info_2
4717 * fill a printer_info_2 struct
4718 ********************************************************************/
4720 static WERROR
construct_printer_driver_info_2(DRIVER_INFO_2
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
4722 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4723 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
4725 ZERO_STRUCT(printer
);
4726 ZERO_STRUCT(driver
);
4728 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))))
4729 return WERR_INVALID_PRINTER_NAME
;
4731 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
)))
4732 return WERR_UNKNOWN_PRINTER_DRIVER
;
4734 fill_printer_driver_info_2(info
, driver
, servername
);
4736 free_a_printer(&printer
,2);
4741 /********************************************************************
4742 * copy a strings array and convert to UNICODE
4744 * convert an array of ascii string to a UNICODE string
4745 ********************************************************************/
4747 static uint32
init_unistr_array(uint16
**uni_array
, fstring
*char_array
, char *servername
)
4755 DEBUG(6,("init_unistr_array\n"));
4766 v
= ""; /* hack to handle null lists */
4769 /* hack to allow this to be used in places other than when generating
4770 the list of dependent files */
4773 slprintf( line
, sizeof(line
)-1, "\\\\%s%s", servername
, v
);
4777 DEBUGADD(6,("%d:%s:%d\n", i
, line
, strlen(line
)));
4779 if ( (tuary
=Realloc(*uni_array
, (j
+strlen(line
)+2)*sizeof(uint16
))) == NULL
) {
4780 DEBUG(2,("init_unistr_array: Realloc error\n" ));
4788 j
+= (rpcstr_push((*uni_array
+j
), line
, sizeof(uint16
)*strlen(line
)+2, STR_TERMINATE
) / sizeof(uint16
));
4793 (*uni_array
)[j
]=0x0000;
4796 DEBUGADD(6,("last one:done\n"));
4798 /* return size of array in uint16's */
4803 /********************************************************************
4804 * construct_printer_info_3
4805 * fill a printer_info_3 struct
4806 ********************************************************************/
4808 static void fill_printer_driver_info_3(DRIVER_INFO_3
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
4814 info
->version
=driver
.info_3
->cversion
;
4816 init_unistr( &info
->name
, driver
.info_3
->name
);
4817 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
4819 if (strlen(driver
.info_3
->driverpath
)) {
4820 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
4821 init_unistr( &info
->driverpath
, temp
);
4823 init_unistr( &info
->driverpath
, "" );
4825 if (strlen(driver
.info_3
->datafile
)) {
4826 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
4827 init_unistr( &info
->datafile
, temp
);
4829 init_unistr( &info
->datafile
, "" );
4831 if (strlen(driver
.info_3
->configfile
)) {
4832 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
4833 init_unistr( &info
->configfile
, temp
);
4835 init_unistr( &info
->configfile
, "" );
4837 if (strlen(driver
.info_3
->helpfile
)) {
4838 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
4839 init_unistr( &info
->helpfile
, temp
);
4841 init_unistr( &info
->helpfile
, "" );
4843 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
4844 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
4846 info
->dependentfiles
=NULL
;
4847 init_unistr_array(&info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
4850 /********************************************************************
4851 * construct_printer_info_3
4852 * fill a printer_info_3 struct
4853 ********************************************************************/
4855 static WERROR
construct_printer_driver_info_3(DRIVER_INFO_3
*info
, int snum
, fstring servername
, fstring architecture
, uint32 version
)
4857 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4858 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
4860 ZERO_STRUCT(driver
);
4862 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
4863 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
4864 if (!W_ERROR_IS_OK(status
))
4865 return WERR_INVALID_PRINTER_NAME
;
4867 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
4868 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
4873 * I put this code in during testing. Helpful when commenting out the
4874 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
4875 * as win2k always queries the driver using an infor level of 6.
4876 * I've left it in (but ifdef'd out) because I'll probably
4877 * use it in experimentation again in the future. --jerry 22/01/2002
4880 if (!W_ERROR_IS_OK(status
)) {
4882 * Is this a W2k client ?
4885 /* Yes - try again with a WinNT driver. */
4887 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
4888 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status
)));
4892 if (!W_ERROR_IS_OK(status
)) {
4893 free_a_printer(&printer
,2);
4894 return WERR_UNKNOWN_PRINTER_DRIVER
;
4902 fill_printer_driver_info_3(info
, driver
, servername
);
4904 free_a_printer(&printer
,2);
4909 /********************************************************************
4910 * construct_printer_info_6
4911 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
4912 ********************************************************************/
4914 static void fill_printer_driver_info_6(DRIVER_INFO_6
*info
, NT_PRINTER_DRIVER_INFO_LEVEL driver
, fstring servername
)
4920 memset(&nullstr
, '\0', sizeof(fstring
));
4922 info
->version
=driver
.info_3
->cversion
;
4924 init_unistr( &info
->name
, driver
.info_3
->name
);
4925 init_unistr( &info
->architecture
, driver
.info_3
->environment
);
4927 if (strlen(driver
.info_3
->driverpath
)) {
4928 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->driverpath
);
4929 init_unistr( &info
->driverpath
, temp
);
4931 init_unistr( &info
->driverpath
, "" );
4933 if (strlen(driver
.info_3
->datafile
)) {
4934 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->datafile
);
4935 init_unistr( &info
->datafile
, temp
);
4937 init_unistr( &info
->datafile
, "" );
4939 if (strlen(driver
.info_3
->configfile
)) {
4940 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->configfile
);
4941 init_unistr( &info
->configfile
, temp
);
4943 init_unistr( &info
->configfile
, "" );
4945 if (strlen(driver
.info_3
->helpfile
)) {
4946 slprintf(temp
, sizeof(temp
)-1, "\\\\%s%s", servername
, driver
.info_3
->helpfile
);
4947 init_unistr( &info
->helpfile
, temp
);
4949 init_unistr( &info
->helpfile
, "" );
4951 init_unistr( &info
->monitorname
, driver
.info_3
->monitorname
);
4952 init_unistr( &info
->defaultdatatype
, driver
.info_3
->defaultdatatype
);
4954 info
->dependentfiles
= NULL
;
4955 init_unistr_array( &info
->dependentfiles
, driver
.info_3
->dependentfiles
, servername
);
4957 info
->previousdrivernames
=NULL
;
4958 init_unistr_array(&info
->previousdrivernames
, &nullstr
, servername
);
4960 info
->driver_date
.low
=0;
4961 info
->driver_date
.high
=0;
4964 info
->driver_version_low
=0;
4965 info
->driver_version_high
=0;
4967 init_unistr( &info
->mfgname
, "");
4968 init_unistr( &info
->oem_url
, "");
4969 init_unistr( &info
->hardware_id
, "");
4970 init_unistr( &info
->provider
, "");
4973 /********************************************************************
4974 * construct_printer_info_6
4975 * fill a printer_info_6 struct
4976 ********************************************************************/
4978 static WERROR
construct_printer_driver_info_6(DRIVER_INFO_6
*info
, int snum
,
4979 fstring servername
, fstring architecture
, uint32 version
)
4981 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
4982 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
4985 ZERO_STRUCT(driver
);
4987 status
=get_a_printer(&printer
, 2, lp_servicename(snum
) );
4989 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
4991 if (!W_ERROR_IS_OK(status
))
4992 return WERR_INVALID_PRINTER_NAME
;
4994 status
= get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
4996 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
4998 if (!W_ERROR_IS_OK(status
))
5001 * Is this a W2k client ?
5005 free_a_printer(&printer
,2);
5006 return WERR_UNKNOWN_PRINTER_DRIVER
;
5009 /* Yes - try again with a WinNT driver. */
5011 status
=get_a_printer_driver(&driver
, 3, printer
->info_2
->drivername
, architecture
, version
);
5012 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status
)));
5013 if (!W_ERROR_IS_OK(status
)) {
5014 free_a_printer(&printer
,2);
5015 return WERR_UNKNOWN_PRINTER_DRIVER
;
5019 fill_printer_driver_info_6(info
, driver
, servername
);
5021 free_a_printer(&printer
,2);
5026 /****************************************************************************
5027 ****************************************************************************/
5029 static void free_printer_driver_info_3(DRIVER_INFO_3
*info
)
5031 SAFE_FREE(info
->dependentfiles
);
5034 /****************************************************************************
5035 ****************************************************************************/
5037 static void free_printer_driver_info_6(DRIVER_INFO_6
*info
)
5039 SAFE_FREE(info
->dependentfiles
);
5043 /****************************************************************************
5044 ****************************************************************************/
5046 static WERROR
getprinterdriver2_level1(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5048 DRIVER_INFO_1
*info
=NULL
;
5051 if((info
=(DRIVER_INFO_1
*)malloc(sizeof(DRIVER_INFO_1
))) == NULL
)
5054 status
=construct_printer_driver_info_1(info
, snum
, servername
, architecture
, version
);
5055 if (!W_ERROR_IS_OK(status
)) {
5060 /* check the required size. */
5061 *needed
+= spoolss_size_printer_driver_info_1(info
);
5063 if (!alloc_buffer_size(buffer
, *needed
)) {
5065 return WERR_INSUFFICIENT_BUFFER
;
5068 /* fill the buffer with the structures */
5069 smb_io_printer_driver_info_1("", buffer
, info
, 0);
5074 if (*needed
> offered
)
5075 return WERR_INSUFFICIENT_BUFFER
;
5080 /****************************************************************************
5081 ****************************************************************************/
5083 static WERROR
getprinterdriver2_level2(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5085 DRIVER_INFO_2
*info
=NULL
;
5088 if((info
=(DRIVER_INFO_2
*)malloc(sizeof(DRIVER_INFO_2
))) == NULL
)
5091 status
=construct_printer_driver_info_2(info
, snum
, servername
, architecture
, version
);
5092 if (!W_ERROR_IS_OK(status
)) {
5097 /* check the required size. */
5098 *needed
+= spoolss_size_printer_driver_info_2(info
);
5100 if (!alloc_buffer_size(buffer
, *needed
)) {
5102 return WERR_INSUFFICIENT_BUFFER
;
5105 /* fill the buffer with the structures */
5106 smb_io_printer_driver_info_2("", buffer
, info
, 0);
5111 if (*needed
> offered
)
5112 return WERR_INSUFFICIENT_BUFFER
;
5117 /****************************************************************************
5118 ****************************************************************************/
5120 static WERROR
getprinterdriver2_level3(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5127 status
=construct_printer_driver_info_3(&info
, snum
, servername
, architecture
, version
);
5128 if (!W_ERROR_IS_OK(status
)) {
5132 /* check the required size. */
5133 *needed
+= spoolss_size_printer_driver_info_3(&info
);
5135 if (!alloc_buffer_size(buffer
, *needed
)) {
5136 free_printer_driver_info_3(&info
);
5137 return WERR_INSUFFICIENT_BUFFER
;
5140 /* fill the buffer with the structures */
5141 smb_io_printer_driver_info_3("", buffer
, &info
, 0);
5143 free_printer_driver_info_3(&info
);
5145 if (*needed
> offered
)
5146 return WERR_INSUFFICIENT_BUFFER
;
5151 /****************************************************************************
5152 ****************************************************************************/
5154 static WERROR
getprinterdriver2_level6(fstring servername
, fstring architecture
, uint32 version
, int snum
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
5161 status
=construct_printer_driver_info_6(&info
, snum
, servername
, architecture
, version
);
5162 if (!W_ERROR_IS_OK(status
)) {
5166 /* check the required size. */
5167 *needed
+= spoolss_size_printer_driver_info_6(&info
);
5169 if (!alloc_buffer_size(buffer
, *needed
)) {
5170 free_printer_driver_info_6(&info
);
5171 return WERR_INSUFFICIENT_BUFFER
;
5174 /* fill the buffer with the structures */
5175 smb_io_printer_driver_info_6("", buffer
, &info
, 0);
5177 free_printer_driver_info_6(&info
);
5179 if (*needed
> offered
)
5180 return WERR_INSUFFICIENT_BUFFER
;
5185 /****************************************************************************
5186 ****************************************************************************/
5188 WERROR
_spoolss_getprinterdriver2(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVER2
*q_u
, SPOOL_R_GETPRINTERDRIVER2
*r_u
)
5190 POLICY_HND
*handle
= &q_u
->handle
;
5191 UNISTR2
*uni_arch
= &q_u
->architecture
;
5192 uint32 level
= q_u
->level
;
5193 uint32 clientmajorversion
= q_u
->clientmajorversion
;
5194 NEW_BUFFER
*buffer
= NULL
;
5195 uint32 offered
= q_u
->offered
;
5196 uint32
*needed
= &r_u
->needed
;
5197 uint32
*servermajorversion
= &r_u
->servermajorversion
;
5198 uint32
*serverminorversion
= &r_u
->serverminorversion
;
5201 fstring architecture
;
5204 /* that's an [in out] buffer */
5205 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5206 buffer
= r_u
->buffer
;
5208 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5211 *servermajorversion
= 0;
5212 *serverminorversion
= 0;
5214 pstrcpy(servername
, get_called_name());
5215 unistr2_to_ascii(architecture
, uni_arch
, sizeof(architecture
)-1);
5217 if (!get_printer_snum(p
, handle
, &snum
))
5222 return getprinterdriver2_level1(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5224 return getprinterdriver2_level2(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5226 return getprinterdriver2_level3(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5228 return getprinterdriver2_level6(servername
, architecture
, clientmajorversion
, snum
, buffer
, offered
, needed
);
5231 return WERR_UNKNOWN_LEVEL
;
5234 /****************************************************************************
5235 ****************************************************************************/
5237 WERROR
_spoolss_startpageprinter(pipes_struct
*p
, SPOOL_Q_STARTPAGEPRINTER
*q_u
, SPOOL_R_STARTPAGEPRINTER
*r_u
)
5239 POLICY_HND
*handle
= &q_u
->handle
;
5241 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5244 DEBUG(3,("Error in startpageprinter printer handle\n"));
5248 Printer
->page_started
=True
;
5252 /****************************************************************************
5253 ****************************************************************************/
5255 WERROR
_spoolss_endpageprinter(pipes_struct
*p
, SPOOL_Q_ENDPAGEPRINTER
*q_u
, SPOOL_R_ENDPAGEPRINTER
*r_u
)
5257 POLICY_HND
*handle
= &q_u
->handle
;
5260 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5263 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle
)));
5267 if (!get_printer_snum(p
, handle
, &snum
))
5270 Printer
->page_started
=False
;
5271 print_job_endpage(snum
, Printer
->jobid
);
5276 /********************************************************************
5277 * api_spoolss_getprinter
5278 * called from the spoolss dispatcher
5280 ********************************************************************/
5282 WERROR
_spoolss_startdocprinter(pipes_struct
*p
, SPOOL_Q_STARTDOCPRINTER
*q_u
, SPOOL_R_STARTDOCPRINTER
*r_u
)
5284 POLICY_HND
*handle
= &q_u
->handle
;
5285 DOC_INFO
*docinfo
= &q_u
->doc_info_container
.docinfo
;
5286 uint32
*jobid
= &r_u
->jobid
;
5288 DOC_INFO_1
*info_1
= &docinfo
->doc_info_1
;
5292 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5293 struct current_user user
;
5296 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5300 get_current_user(&user
, p
);
5303 * a nice thing with NT is it doesn't listen to what you tell it.
5304 * when asked to send _only_ RAW datas, it tries to send datas
5307 * So I add checks like in NT Server ...
5310 if (info_1
->p_datatype
!= 0) {
5311 unistr2_to_ascii(datatype
, &info_1
->datatype
, sizeof(datatype
));
5312 if (strcmp(datatype
, "RAW") != 0) {
5314 return WERR_INVALID_DATATYPE
;
5318 /* get the share number of the printer */
5319 if (!get_printer_snum(p
, handle
, &snum
)) {
5323 unistr2_to_ascii(jobname
, &info_1
->docname
, sizeof(jobname
));
5325 Printer
->jobid
= print_job_start(&user
, snum
, jobname
, Printer
->nt_devmode
);
5327 /* An error occured in print_job_start() so return an appropriate
5330 if (Printer
->jobid
== -1) {
5331 return map_werror_from_unix(errno
);
5334 Printer
->document_started
=True
;
5335 (*jobid
) = Printer
->jobid
;
5340 /********************************************************************
5341 * api_spoolss_getprinter
5342 * called from the spoolss dispatcher
5344 ********************************************************************/
5346 WERROR
_spoolss_enddocprinter(pipes_struct
*p
, SPOOL_Q_ENDDOCPRINTER
*q_u
, SPOOL_R_ENDDOCPRINTER
*r_u
)
5348 POLICY_HND
*handle
= &q_u
->handle
;
5350 return _spoolss_enddocprinter_internal(p
, handle
);
5353 /****************************************************************************
5354 ****************************************************************************/
5356 WERROR
_spoolss_writeprinter(pipes_struct
*p
, SPOOL_Q_WRITEPRINTER
*q_u
, SPOOL_R_WRITEPRINTER
*r_u
)
5358 POLICY_HND
*handle
= &q_u
->handle
;
5359 uint32 buffer_size
= q_u
->buffer_size
;
5360 uint8
*buffer
= q_u
->buffer
;
5361 uint32
*buffer_written
= &q_u
->buffer_size2
;
5363 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5366 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5367 r_u
->buffer_written
= q_u
->buffer_size2
;
5371 if (!get_printer_snum(p
, handle
, &snum
))
5374 (*buffer_written
) = print_job_write(snum
, Printer
->jobid
, (char *)buffer
, buffer_size
);
5375 if (*buffer_written
== -1) {
5376 r_u
->buffer_written
= 0;
5377 if (errno
== ENOSPC
)
5378 return WERR_NO_SPOOL_SPACE
;
5380 return WERR_ACCESS_DENIED
;
5383 r_u
->buffer_written
= q_u
->buffer_size2
;
5388 /********************************************************************
5389 * api_spoolss_getprinter
5390 * called from the spoolss dispatcher
5392 ********************************************************************/
5394 static WERROR
control_printer(POLICY_HND
*handle
, uint32 command
,
5397 struct current_user user
;
5399 WERROR errcode
= WERR_BADFUNC
;
5400 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5402 get_current_user(&user
, p
);
5405 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5409 if (!get_printer_snum(p
, handle
, &snum
))
5413 case PRINTER_CONTROL_PAUSE
:
5414 if (print_queue_pause(&user
, snum
, &errcode
)) {
5418 case PRINTER_CONTROL_RESUME
:
5419 case PRINTER_CONTROL_UNPAUSE
:
5420 if (print_queue_resume(&user
, snum
, &errcode
)) {
5424 #if 0 /* JERRY - Never called */
5425 case PRINTER_CONTROL_PURGE
:
5426 if (print_queue_purge(&user
, snum
, &errcode
)) {
5432 return WERR_UNKNOWN_LEVEL
;
5438 /********************************************************************
5439 * api_spoolss_abortprinter
5440 * From MSDN: "Deletes printer's spool file if printer is configured
5442 ********************************************************************/
5444 WERROR
_spoolss_abortprinter(pipes_struct
*p
, SPOOL_Q_ABORTPRINTER
*q_u
, SPOOL_R_ABORTPRINTER
*r_u
)
5446 POLICY_HND
*handle
= &q_u
->handle
;
5447 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5449 struct current_user user
;
5450 WERROR errcode
= WERR_OK
;
5453 DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle
)));
5457 if (!get_printer_snum(p
, handle
, &snum
))
5460 get_current_user( &user
, p
);
5462 print_job_delete( &user
, snum
, Printer
->jobid
, &errcode
);
5467 /********************************************************************
5468 * called by spoolss_api_setprinter
5469 * when updating a printer description
5470 ********************************************************************/
5472 static WERROR
update_printer_sec(POLICY_HND
*handle
, uint32 level
,
5473 const SPOOL_PRINTER_INFO_LEVEL
*info
,
5474 pipes_struct
*p
, SEC_DESC_BUF
*secdesc_ctr
)
5476 SEC_DESC_BUF
*new_secdesc_ctr
= NULL
, *old_secdesc_ctr
= NULL
;
5477 struct current_user user
;
5481 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5483 if (!Printer
|| !get_printer_snum(p
, handle
, &snum
)) {
5484 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5485 OUR_HANDLE(handle
)));
5487 result
= WERR_BADFID
;
5491 /* NT seems to like setting the security descriptor even though
5492 nothing may have actually changed. This causes annoying
5493 dialog boxes when the user doesn't have permission to change
5494 the security descriptor. */
5496 nt_printing_getsec(p
->mem_ctx
, Printer
->dev
.handlename
, &old_secdesc_ctr
);
5498 if (DEBUGLEVEL
>= 10) {
5502 the_acl
= old_secdesc_ctr
->sec
->dacl
;
5503 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5504 PRINTERNAME(snum
), the_acl
->num_aces
));
5506 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
5509 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
5511 DEBUG(10, ("%s 0x%08x\n", sid_str
,
5512 the_acl
->ace
[i
].info
.mask
));
5515 the_acl
= secdesc_ctr
->sec
->dacl
;
5518 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5519 PRINTERNAME(snum
), the_acl
->num_aces
));
5521 for (i
= 0; i
< the_acl
->num_aces
; i
++) {
5524 sid_to_string(sid_str
, &the_acl
->ace
[i
].trustee
);
5526 DEBUG(10, ("%s 0x%08x\n", sid_str
,
5527 the_acl
->ace
[i
].info
.mask
));
5530 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5534 new_secdesc_ctr
= sec_desc_merge(p
->mem_ctx
, secdesc_ctr
, old_secdesc_ctr
);
5536 if (sec_desc_equal(new_secdesc_ctr
->sec
, old_secdesc_ctr
->sec
)) {
5541 /* Work out which user is performing the operation */
5543 get_current_user(&user
, p
);
5545 /* Check the user has permissions to change the security
5546 descriptor. By experimentation with two NT machines, the user
5547 requires Full Access to the printer to change security
5550 if (!print_access_check(&user
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
5551 result
= WERR_ACCESS_DENIED
;
5555 result
= nt_printing_setsec(Printer
->dev
.handlename
, new_secdesc_ctr
);
5562 /********************************************************************
5563 Do Samba sanity checks on a printer info struct.
5564 this has changed purpose: it now "canonicalises" printer
5565 info from a client rather than just checking it is correct
5566 ********************************************************************/
5568 static BOOL
check_printer_ok(NT_PRINTER_INFO_LEVEL_2
*info
, int snum
)
5570 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s portname=%s drivername=%s comment=%s location=%s\n",
5571 info
->servername
, info
->printername
, info
->sharename
, info
->portname
, info
->drivername
, info
->comment
, info
->location
));
5573 /* we force some elements to "correct" values */
5574 slprintf(info
->servername
, sizeof(info
->servername
)-1, "\\\\%s", get_called_name());
5575 fstrcpy(info
->sharename
, lp_servicename(snum
));
5576 slprintf(info
->printername
, sizeof(info
->printername
)-1, "\\\\%s\\%s",
5577 get_called_name(), info
->sharename
);
5578 info
->attributes
= PRINTER_ATTRIBUTE_SHARED
| PRINTER_ATTRIBUTE_NETWORK
;
5583 /****************************************************************************
5584 ****************************************************************************/
5586 static BOOL
add_printer_hook(NT_PRINTER_INFO_LEVEL
*printer
)
5588 extern userdom_struct current_user_info
;
5589 char *cmd
= lp_addprinter_cmd();
5592 pstring driverlocation
;
5596 fstring remote_machine
= "%m";
5598 /* build driver path... only 9X architecture is needed for legacy reasons */
5599 slprintf(driverlocation
, sizeof(driverlocation
)-1, "\\\\%s\\print$\\WIN40\\0",
5601 /* change \ to \\ for the shell */
5602 all_string_sub(driverlocation
,"\\","\\\\",sizeof(pstring
));
5603 standard_sub_basic(current_user_info
.smb_name
, remote_machine
,sizeof(remote_machine
));
5605 slprintf(command
, sizeof(command
)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5606 cmd
, printer
->info_2
->printername
, printer
->info_2
->sharename
,
5607 printer
->info_2
->portname
, printer
->info_2
->drivername
,
5608 printer
->info_2
->location
, driverlocation
, remote_machine
);
5610 DEBUG(10,("Running [%s]\n", command
));
5611 ret
= smbrun(command
, &fd
);
5612 DEBUGADD(10,("returned [%d]\n", ret
));
5621 /* Get lines and convert them back to dos-codepage */
5622 qlines
= fd_lines_load(fd
, &numlines
);
5623 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
5627 /* Set the portname to what the script says the portname should be. */
5628 strncpy(printer
->info_2
->portname
, qlines
[0], sizeof(printer
->info_2
->portname
));
5629 DEBUGADD(6,("Line[0] = [%s]\n", qlines
[0]));
5631 /* Send SIGHUP to process group... is there a better way? */
5636 file_lines_free(qlines
);
5640 /********************************************************************
5641 * Called by spoolss_api_setprinter
5642 * when updating a printer description.
5643 ********************************************************************/
5645 static WERROR
update_printer(pipes_struct
*p
, POLICY_HND
*handle
, uint32 level
,
5646 const SPOOL_PRINTER_INFO_LEVEL
*info
,
5647 DEVICEMODE
*devmode
)
5650 NT_PRINTER_INFO_LEVEL
*printer
= NULL
, *old_printer
= NULL
;
5651 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5654 DEBUG(8,("update_printer\n"));
5659 DEBUG(0,("update_printer: Send a mail to samba@samba.org\n"));
5660 DEBUGADD(0,("with the following message: update_printer: level!=2\n"));
5661 result
= WERR_UNKNOWN_LEVEL
;
5666 result
= WERR_BADFID
;
5670 if (!get_printer_snum(p
, handle
, &snum
)) {
5671 result
= WERR_BADFID
;
5675 if (!W_ERROR_IS_OK(get_a_printer(&printer
, 2, lp_servicename(snum
))) ||
5676 (!W_ERROR_IS_OK(get_a_printer(&old_printer
, 2, lp_servicename(snum
))))) {
5677 result
= WERR_BADFID
;
5681 DEBUGADD(8,("Converting info_2 struct\n"));
5684 * convert_printer_info converts the incoming
5685 * info from the client and overwrites the info
5686 * just read from the tdb in the pointer 'printer'.
5689 if (!convert_printer_info(info
, printer
, level
)) {
5690 result
= WERR_NOMEM
;
5695 /* we have a valid devmode
5696 convert it and link it*/
5698 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5699 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
5700 &printer
->info_2
->devmode
)) {
5701 result
= WERR_NOMEM
;
5706 /* Do sanity check on the requested changes for Samba */
5708 if (!check_printer_ok(printer
->info_2
, snum
)) {
5709 result
= WERR_INVALID_PARAM
;
5713 /* Check calling user has permission to update printer description */
5715 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
5716 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5717 result
= WERR_ACCESS_DENIED
;
5721 /* Call addprinter hook */
5723 if (*lp_addprinter_cmd()) {
5724 if ( !add_printer_hook(printer
) ) {
5725 result
= WERR_ACCESS_DENIED
;
5731 * When a *new* driver is bound to a printer, the drivername is used to
5732 * lookup previously saved driver initialization info, which is then
5733 * bound to the printer, simulating what happens in the Windows arch.
5735 if (!strequal(printer
->info_2
->drivername
, old_printer
->info_2
->drivername
))
5737 if (!set_driver_init(printer
, 2))
5739 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
5740 printer
->info_2
->drivername
));
5743 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5744 printer
->info_2
->drivername
));
5746 notify_printer_driver(snum
, printer
->info_2
->drivername
);
5749 /* Update printer info */
5750 result
= mod_a_printer(*printer
, 2);
5752 /* flag which changes actually occured. This is a small subset of
5753 all the possible changes */
5755 if (!strequal(printer
->info_2
->comment
, old_printer
->info_2
->comment
))
5756 notify_printer_comment(snum
, printer
->info_2
->comment
);
5758 if (!strequal(printer
->info_2
->sharename
, old_printer
->info_2
->sharename
))
5759 notify_printer_sharename(snum
, printer
->info_2
->sharename
);
5761 if (!strequal(printer
->info_2
->portname
, old_printer
->info_2
->portname
))
5762 notify_printer_port(snum
, printer
->info_2
->portname
);
5764 if (!strequal(printer
->info_2
->location
, old_printer
->info_2
->location
))
5765 notify_printer_location(snum
, printer
->info_2
->location
);
5768 free_a_printer(&printer
, 2);
5769 free_a_printer(&old_printer
, 2);
5775 /****************************************************************************
5776 ****************************************************************************/
5778 WERROR
_spoolss_setprinter(pipes_struct
*p
, SPOOL_Q_SETPRINTER
*q_u
, SPOOL_R_SETPRINTER
*r_u
)
5780 POLICY_HND
*handle
= &q_u
->handle
;
5781 uint32 level
= q_u
->level
;
5782 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
5783 DEVMODE_CTR devmode_ctr
= q_u
->devmode_ctr
;
5784 SEC_DESC_BUF
*secdesc_ctr
= q_u
->secdesc_ctr
;
5785 uint32 command
= q_u
->command
;
5787 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5790 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5794 /* check the level */
5797 return control_printer(handle
, command
, p
);
5799 return update_printer(p
, handle
, level
, info
, devmode_ctr
.devmode
);
5801 return update_printer_sec(handle
, level
, info
, p
,
5804 return WERR_UNKNOWN_LEVEL
;
5808 /****************************************************************************
5809 ****************************************************************************/
5811 WERROR
_spoolss_fcpn(pipes_struct
*p
, SPOOL_Q_FCPN
*q_u
, SPOOL_R_FCPN
*r_u
)
5813 POLICY_HND
*handle
= &q_u
->handle
;
5815 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
5818 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle
)));
5822 if (Printer
->notify
.client_connected
==True
)
5823 srv_spoolss_replycloseprinter(&Printer
->notify
.client_hnd
);
5825 Printer
->notify
.flags
=0;
5826 Printer
->notify
.options
=0;
5827 Printer
->notify
.localmachine
[0]='\0';
5828 Printer
->notify
.printerlocal
=0;
5829 if (Printer
->notify
.option
)
5830 free_spool_notify_option(&Printer
->notify
.option
);
5831 Printer
->notify
.client_connected
=False
;
5836 /****************************************************************************
5837 ****************************************************************************/
5839 WERROR
_spoolss_addjob(pipes_struct
*p
, SPOOL_Q_ADDJOB
*q_u
, SPOOL_R_ADDJOB
*r_u
)
5841 /* that's an [in out] buffer (despite appearences to the contrary) */
5842 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
5845 return WERR_INVALID_PARAM
; /* this is what a NT server
5846 returns for AddJob. AddJob
5847 must fail on non-local
5851 /****************************************************************************
5852 ****************************************************************************/
5854 static void fill_job_info_1(JOB_INFO_1
*job_info
, print_queue_struct
*queue
,
5855 int position
, int snum
)
5861 t
=gmtime(&queue
->time
);
5862 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", get_called_name());
5864 job_info
->jobid
=queue
->job
;
5865 init_unistr(&job_info
->printername
, lp_servicename(snum
));
5866 init_unistr(&job_info
->machinename
, temp_name
);
5867 init_unistr(&job_info
->username
, queue
->fs_user
);
5868 init_unistr(&job_info
->document
, queue
->fs_file
);
5869 init_unistr(&job_info
->datatype
, "RAW");
5870 init_unistr(&job_info
->text_status
, "");
5871 job_info
->status
=nt_printj_status(queue
->status
);
5872 job_info
->priority
=queue
->priority
;
5873 job_info
->position
=position
;
5874 job_info
->totalpages
=queue
->page_count
;
5875 job_info
->pagesprinted
=0;
5877 make_systemtime(&job_info
->submitted
, t
);
5880 /****************************************************************************
5881 ****************************************************************************/
5883 static BOOL
fill_job_info_2(JOB_INFO_2
*job_info
, print_queue_struct
*queue
,
5884 int position
, int snum
,
5885 NT_PRINTER_INFO_LEVEL
*ntprinter
,
5886 DEVICEMODE
*devmode
)
5892 t
=gmtime(&queue
->time
);
5893 slprintf(temp_name
, sizeof(temp_name
)-1, "\\\\%s", get_called_name());
5895 job_info
->jobid
=queue
->job
;
5897 slprintf(chaine
, sizeof(chaine
)-1, "\\\\%s\\%s", get_called_name(), ntprinter
->info_2
->printername
);
5899 init_unistr(&job_info
->printername
, chaine
);
5901 init_unistr(&job_info
->machinename
, temp_name
);
5902 init_unistr(&job_info
->username
, queue
->fs_user
);
5903 init_unistr(&job_info
->document
, queue
->fs_file
);
5904 init_unistr(&job_info
->notifyname
, queue
->fs_user
);
5905 init_unistr(&job_info
->datatype
, "RAW");
5906 init_unistr(&job_info
->printprocessor
, "winprint");
5907 init_unistr(&job_info
->parameters
, "");
5908 init_unistr(&job_info
->drivername
, ntprinter
->info_2
->drivername
);
5909 init_unistr(&job_info
->text_status
, "");
5911 /* and here the security descriptor */
5913 job_info
->status
=nt_printj_status(queue
->status
);
5914 job_info
->priority
=queue
->priority
;
5915 job_info
->position
=position
;
5916 job_info
->starttime
=0;
5917 job_info
->untiltime
=0;
5918 job_info
->totalpages
=queue
->page_count
;
5919 job_info
->size
=queue
->size
;
5920 make_systemtime(&(job_info
->submitted
), t
);
5921 job_info
->timeelapsed
=0;
5922 job_info
->pagesprinted
=0;
5924 job_info
->devmode
= devmode
;
5929 /****************************************************************************
5930 Enumjobs at level 1.
5931 ****************************************************************************/
5933 static WERROR
enumjobs_level1(print_queue_struct
*queue
, int snum
,
5934 NEW_BUFFER
*buffer
, uint32 offered
,
5935 uint32
*needed
, uint32
*returned
)
5940 info
=(JOB_INFO_1
*)malloc(*returned
*sizeof(JOB_INFO_1
));
5947 for (i
=0; i
<*returned
; i
++)
5948 fill_job_info_1(&info
[i
], &queue
[i
], i
, snum
);
5952 /* check the required size. */
5953 for (i
=0; i
<*returned
; i
++)
5954 (*needed
) += spoolss_size_job_info_1(&info
[i
]);
5956 if (!alloc_buffer_size(buffer
, *needed
)) {
5958 return WERR_INSUFFICIENT_BUFFER
;
5961 /* fill the buffer with the structures */
5962 for (i
=0; i
<*returned
; i
++)
5963 smb_io_job_info_1("", buffer
, &info
[i
], 0);
5968 if (*needed
> offered
) {
5970 return WERR_INSUFFICIENT_BUFFER
;
5976 /****************************************************************************
5977 Enumjobs at level 2.
5978 ****************************************************************************/
5980 static WERROR
enumjobs_level2(print_queue_struct
*queue
, int snum
,
5981 NEW_BUFFER
*buffer
, uint32 offered
,
5982 uint32
*needed
, uint32
*returned
)
5984 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
5985 JOB_INFO_2
*info
= NULL
;
5988 DEVICEMODE
*devmode
= NULL
;
5990 info
=(JOB_INFO_2
*)malloc(*returned
*sizeof(JOB_INFO_2
));
5993 result
= WERR_NOMEM
;
5997 result
= get_a_printer(&ntprinter
, 2, lp_servicename(snum
));
5998 if (!W_ERROR_IS_OK(result
)) {
6003 if (!(devmode
= construct_dev_mode(snum
))) {
6005 result
= WERR_NOMEM
;
6009 for (i
=0; i
<*returned
; i
++)
6010 fill_job_info_2(&(info
[i
]), &queue
[i
], i
, snum
, ntprinter
,
6013 free_a_printer(&ntprinter
, 2);
6016 /* check the required size. */
6017 for (i
=0; i
<*returned
; i
++)
6018 (*needed
) += spoolss_size_job_info_2(&info
[i
]);
6020 if (*needed
> offered
) {
6022 result
= WERR_INSUFFICIENT_BUFFER
;
6026 if (!alloc_buffer_size(buffer
, *needed
)) {
6028 result
= WERR_INSUFFICIENT_BUFFER
;
6032 /* fill the buffer with the structures */
6033 for (i
=0; i
<*returned
; i
++)
6034 smb_io_job_info_2("", buffer
, &info
[i
], 0);
6039 free_a_printer(&ntprinter
, 2);
6040 free_devmode(devmode
);
6048 /****************************************************************************
6050 ****************************************************************************/
6052 WERROR
_spoolss_enumjobs( pipes_struct
*p
, SPOOL_Q_ENUMJOBS
*q_u
, SPOOL_R_ENUMJOBS
*r_u
)
6054 POLICY_HND
*handle
= &q_u
->handle
;
6055 uint32 level
= q_u
->level
;
6056 NEW_BUFFER
*buffer
= NULL
;
6057 uint32 offered
= q_u
->offered
;
6058 uint32
*needed
= &r_u
->needed
;
6059 uint32
*returned
= &r_u
->returned
;
6062 print_status_struct prt_status
;
6063 print_queue_struct
*queue
=NULL
;
6065 /* that's an [in out] buffer */
6066 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6067 buffer
= r_u
->buffer
;
6069 DEBUG(4,("_spoolss_enumjobs\n"));
6074 if (!get_printer_snum(p
, handle
, &snum
))
6077 *returned
= print_queue_status(snum
, &queue
, &prt_status
);
6078 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned
, prt_status
.status
, prt_status
.message
));
6080 if (*returned
== 0) {
6087 return enumjobs_level1(queue
, snum
, buffer
, offered
, needed
, returned
);
6089 return enumjobs_level2(queue
, snum
, buffer
, offered
, needed
, returned
);
6093 return WERR_UNKNOWN_LEVEL
;
6097 /****************************************************************************
6098 ****************************************************************************/
6100 WERROR
_spoolss_schedulejob( pipes_struct
*p
, SPOOL_Q_SCHEDULEJOB
*q_u
, SPOOL_R_SCHEDULEJOB
*r_u
)
6105 /****************************************************************************
6106 ****************************************************************************/
6108 WERROR
_spoolss_setjob(pipes_struct
*p
, SPOOL_Q_SETJOB
*q_u
, SPOOL_R_SETJOB
*r_u
)
6110 POLICY_HND
*handle
= &q_u
->handle
;
6111 uint32 jobid
= q_u
->jobid
;
6112 uint32 command
= q_u
->command
;
6114 struct current_user user
;
6116 WERROR errcode
= WERR_BADFUNC
;
6118 if (!get_printer_snum(p
, handle
, &snum
)) {
6122 if (!print_job_exists(snum
, jobid
)) {
6123 return WERR_INVALID_PRINTER_NAME
;
6126 get_current_user(&user
, p
);
6129 case JOB_CONTROL_CANCEL
:
6130 case JOB_CONTROL_DELETE
:
6131 if (print_job_delete(&user
, snum
, jobid
, &errcode
)) {
6135 case JOB_CONTROL_PAUSE
:
6136 if (print_job_pause(&user
, snum
, jobid
, &errcode
)) {
6140 case JOB_CONTROL_RESTART
:
6141 case JOB_CONTROL_RESUME
:
6142 if (print_job_resume(&user
, snum
, jobid
, &errcode
)) {
6147 return WERR_UNKNOWN_LEVEL
;
6153 /****************************************************************************
6154 Enumerates all printer drivers at level 1.
6155 ****************************************************************************/
6157 static WERROR
enumprinterdrivers_level1(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6162 fstring
*list
= NULL
;
6164 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6165 DRIVER_INFO_1
*tdi1
, *driver_info_1
=NULL
;
6169 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6171 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6172 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6178 if((tdi1
=(DRIVER_INFO_1
*)Realloc(driver_info_1
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_1
))) == NULL
) {
6179 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6180 SAFE_FREE(driver_info_1
);
6184 else driver_info_1
= tdi1
;
6187 for (i
=0; i
<ndrivers
; i
++) {
6189 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6190 ZERO_STRUCT(driver
);
6191 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6192 architecture
, version
);
6193 if (!W_ERROR_IS_OK(status
)) {
6197 fill_printer_driver_info_1(&driver_info_1
[*returned
+i
], driver
, servername
, architecture
);
6198 free_a_printer_driver(driver
, 3);
6201 *returned
+=ndrivers
;
6205 /* check the required size. */
6206 for (i
=0; i
<*returned
; i
++) {
6207 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6208 *needed
+= spoolss_size_printer_driver_info_1(&driver_info_1
[i
]);
6211 if (!alloc_buffer_size(buffer
, *needed
)) {
6212 SAFE_FREE(driver_info_1
);
6213 return WERR_INSUFFICIENT_BUFFER
;
6216 /* fill the buffer with the driver structures */
6217 for (i
=0; i
<*returned
; i
++) {
6218 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
6219 smb_io_printer_driver_info_1("", buffer
, &driver_info_1
[i
], 0);
6222 SAFE_FREE(driver_info_1
);
6224 if (*needed
> offered
) {
6226 return WERR_INSUFFICIENT_BUFFER
;
6232 /****************************************************************************
6233 Enumerates all printer drivers at level 2.
6234 ****************************************************************************/
6236 static WERROR
enumprinterdrivers_level2(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6241 fstring
*list
= NULL
;
6243 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6244 DRIVER_INFO_2
*tdi2
, *driver_info_2
=NULL
;
6248 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6250 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6251 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6257 if((tdi2
=(DRIVER_INFO_2
*)Realloc(driver_info_2
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_2
))) == NULL
) {
6258 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
6259 SAFE_FREE(driver_info_2
);
6263 else driver_info_2
= tdi2
;
6266 for (i
=0; i
<ndrivers
; i
++) {
6269 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6270 ZERO_STRUCT(driver
);
6271 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6272 architecture
, version
);
6273 if (!W_ERROR_IS_OK(status
)) {
6277 fill_printer_driver_info_2(&driver_info_2
[*returned
+i
], driver
, servername
);
6278 free_a_printer_driver(driver
, 3);
6281 *returned
+=ndrivers
;
6285 /* check the required size. */
6286 for (i
=0; i
<*returned
; i
++) {
6287 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6288 *needed
+= spoolss_size_printer_driver_info_2(&(driver_info_2
[i
]));
6291 if (!alloc_buffer_size(buffer
, *needed
)) {
6292 SAFE_FREE(driver_info_2
);
6293 return WERR_INSUFFICIENT_BUFFER
;
6296 /* fill the buffer with the form structures */
6297 for (i
=0; i
<*returned
; i
++) {
6298 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
6299 smb_io_printer_driver_info_2("", buffer
, &(driver_info_2
[i
]), 0);
6302 SAFE_FREE(driver_info_2
);
6304 if (*needed
> offered
) {
6306 return WERR_INSUFFICIENT_BUFFER
;
6312 /****************************************************************************
6313 Enumerates all printer drivers at level 3.
6314 ****************************************************************************/
6316 static WERROR
enumprinterdrivers_level3(fstring servername
, fstring architecture
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6321 fstring
*list
= NULL
;
6323 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
6324 DRIVER_INFO_3
*tdi3
, *driver_info_3
=NULL
;
6328 for (version
=0; version
<DRIVER_MAX_VERSION
; version
++) {
6330 ndrivers
=get_ntdrivers(&list
, architecture
, version
);
6331 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers
, architecture
, version
));
6337 if((tdi3
=(DRIVER_INFO_3
*)Realloc(driver_info_3
, (*returned
+ndrivers
) * sizeof(DRIVER_INFO_3
))) == NULL
) {
6338 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
6339 SAFE_FREE(driver_info_3
);
6343 else driver_info_3
= tdi3
;
6346 for (i
=0; i
<ndrivers
; i
++) {
6349 DEBUGADD(5,("\tdriver: [%s]\n", list
[i
]));
6350 ZERO_STRUCT(driver
);
6351 status
= get_a_printer_driver(&driver
, 3, list
[i
],
6352 architecture
, version
);
6353 if (!W_ERROR_IS_OK(status
)) {
6357 fill_printer_driver_info_3(&driver_info_3
[*returned
+i
], driver
, servername
);
6358 free_a_printer_driver(driver
, 3);
6361 *returned
+=ndrivers
;
6365 /* check the required size. */
6366 for (i
=0; i
<*returned
; i
++) {
6367 DEBUGADD(6,("adding driver [%d]'s size\n",i
));
6368 *needed
+= spoolss_size_printer_driver_info_3(&driver_info_3
[i
]);
6371 if (!alloc_buffer_size(buffer
, *needed
)) {
6372 SAFE_FREE(driver_info_3
);
6373 return WERR_INSUFFICIENT_BUFFER
;
6376 /* fill the buffer with the driver structures */
6377 for (i
=0; i
<*returned
; i
++) {
6378 DEBUGADD(6,("adding driver [%d] to buffer\n",i
));
6379 smb_io_printer_driver_info_3("", buffer
, &driver_info_3
[i
], 0);
6382 for (i
=0; i
<*returned
; i
++)
6383 SAFE_FREE(driver_info_3
[i
].dependentfiles
);
6385 SAFE_FREE(driver_info_3
);
6387 if (*needed
> offered
) {
6389 return WERR_INSUFFICIENT_BUFFER
;
6395 /****************************************************************************
6396 Enumerates all printer drivers.
6397 ****************************************************************************/
6399 WERROR
_spoolss_enumprinterdrivers( pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDRIVERS
*q_u
, SPOOL_R_ENUMPRINTERDRIVERS
*r_u
)
6401 UNISTR2
*environment
= &q_u
->environment
;
6402 uint32 level
= q_u
->level
;
6403 NEW_BUFFER
*buffer
= NULL
;
6404 uint32 offered
= q_u
->offered
;
6405 uint32
*needed
= &r_u
->needed
;
6406 uint32
*returned
= &r_u
->returned
;
6408 fstring
*list
= NULL
;
6410 fstring architecture
;
6412 /* that's an [in out] buffer */
6413 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6414 buffer
= r_u
->buffer
;
6416 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
6417 fstrcpy(servername
, get_called_name());
6421 unistr2_to_ascii(architecture
, environment
, sizeof(architecture
)-1);
6425 return enumprinterdrivers_level1(servername
, architecture
, buffer
, offered
, needed
, returned
);
6427 return enumprinterdrivers_level2(servername
, architecture
, buffer
, offered
, needed
, returned
);
6429 return enumprinterdrivers_level3(servername
, architecture
, buffer
, offered
, needed
, returned
);
6433 return WERR_UNKNOWN_LEVEL
;
6437 /****************************************************************************
6438 ****************************************************************************/
6440 static void fill_form_1(FORM_1
*form
, nt_forms_struct
*list
)
6442 form
->flag
=list
->flag
;
6443 init_unistr(&form
->name
, list
->name
);
6444 form
->width
=list
->width
;
6445 form
->length
=list
->length
;
6446 form
->left
=list
->left
;
6447 form
->top
=list
->top
;
6448 form
->right
=list
->right
;
6449 form
->bottom
=list
->bottom
;
6452 /****************************************************************************
6453 ****************************************************************************/
6455 WERROR
_spoolss_enumforms(pipes_struct
*p
, SPOOL_Q_ENUMFORMS
*q_u
, SPOOL_R_ENUMFORMS
*r_u
)
6457 uint32 level
= q_u
->level
;
6458 NEW_BUFFER
*buffer
= NULL
;
6459 uint32 offered
= q_u
->offered
;
6460 uint32
*needed
= &r_u
->needed
;
6461 uint32
*numofforms
= &r_u
->numofforms
;
6462 uint32 numbuiltinforms
;
6464 nt_forms_struct
*list
=NULL
;
6465 nt_forms_struct
*builtinlist
=NULL
;
6470 /* that's an [in out] buffer */
6471 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6472 buffer
= r_u
->buffer
;
6474 DEBUG(4,("_spoolss_enumforms\n"));
6475 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
6476 DEBUGADD(5,("Info level [%d]\n", level
));
6478 numbuiltinforms
= get_builtin_ntforms(&builtinlist
);
6479 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms
));
6480 *numofforms
= get_ntforms(&list
);
6481 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms
));
6482 *numofforms
+= numbuiltinforms
;
6484 if (*numofforms
== 0) return WERR_NO_MORE_ITEMS
;
6488 if ((forms_1
=(FORM_1
*)malloc(*numofforms
* sizeof(FORM_1
))) == NULL
) {
6493 /* construct the list of form structures */
6494 for (i
=0; i
<numbuiltinforms
; i
++) {
6495 DEBUGADD(6,("Filling form number [%d]\n",i
));
6496 fill_form_1(&forms_1
[i
], &builtinlist
[i
]);
6499 SAFE_FREE(builtinlist
);
6501 for (; i
<*numofforms
; i
++) {
6502 DEBUGADD(6,("Filling form number [%d]\n",i
));
6503 fill_form_1(&forms_1
[i
], &list
[i
-numbuiltinforms
]);
6508 /* check the required size. */
6509 for (i
=0; i
<numbuiltinforms
; i
++) {
6510 DEBUGADD(6,("adding form [%d]'s size\n",i
));
6511 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
6513 for (; i
<*numofforms
; i
++) {
6514 DEBUGADD(6,("adding form [%d]'s size\n",i
));
6515 buffer_size
+= spoolss_size_form_1(&forms_1
[i
]);
6518 *needed
=buffer_size
;
6520 if (!alloc_buffer_size(buffer
, buffer_size
)){
6522 return WERR_INSUFFICIENT_BUFFER
;
6525 /* fill the buffer with the form structures */
6526 for (i
=0; i
<numbuiltinforms
; i
++) {
6527 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
6528 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
6530 for (; i
<*numofforms
; i
++) {
6531 DEBUGADD(6,("adding form [%d] to buffer\n",i
));
6532 smb_io_form_1("", buffer
, &forms_1
[i
], 0);
6537 if (*needed
> offered
) {
6539 return WERR_INSUFFICIENT_BUFFER
;
6546 SAFE_FREE(builtinlist
);
6547 return WERR_UNKNOWN_LEVEL
;
6552 /****************************************************************************
6553 ****************************************************************************/
6555 WERROR
_spoolss_getform(pipes_struct
*p
, SPOOL_Q_GETFORM
*q_u
, SPOOL_R_GETFORM
*r_u
)
6557 uint32 level
= q_u
->level
;
6558 UNISTR2
*uni_formname
= &q_u
->formname
;
6559 NEW_BUFFER
*buffer
= NULL
;
6560 uint32 offered
= q_u
->offered
;
6561 uint32
*needed
= &r_u
->needed
;
6563 nt_forms_struct
*list
=NULL
;
6564 nt_forms_struct builtin_form
;
6569 int numofforms
=0, i
=0;
6571 /* that's an [in out] buffer */
6572 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6573 buffer
= r_u
->buffer
;
6575 unistr2_to_ascii(form_name
, uni_formname
, sizeof(form_name
)-1);
6577 DEBUG(4,("_spoolss_getform\n"));
6578 DEBUGADD(5,("Offered buffer size [%d]\n", offered
));
6579 DEBUGADD(5,("Info level [%d]\n", level
));
6581 foundBuiltin
= get_a_builtin_ntform(uni_formname
,&builtin_form
);
6582 if (!foundBuiltin
) {
6583 numofforms
= get_ntforms(&list
);
6584 DEBUGADD(5,("Number of forms [%d]\n", numofforms
));
6586 if (numofforms
== 0)
6593 fill_form_1(&form_1
, &builtin_form
);
6596 /* Check if the requested name is in the list of form structures */
6597 for (i
=0; i
<numofforms
; i
++) {
6599 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list
[i
].name
, form_name
));
6601 if (strequal(form_name
, list
[i
].name
)) {
6602 DEBUGADD(6,("Found form %s number [%d]\n", form_name
, i
));
6603 fill_form_1(&form_1
, &list
[i
]);
6609 if (i
== numofforms
) {
6613 /* check the required size. */
6615 *needed
=spoolss_size_form_1(&form_1
);
6617 if (!alloc_buffer_size(buffer
, buffer_size
)){
6618 return WERR_INSUFFICIENT_BUFFER
;
6621 if (*needed
> offered
) {
6622 return WERR_INSUFFICIENT_BUFFER
;
6625 /* fill the buffer with the form structures */
6626 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name
, i
));
6627 smb_io_form_1("", buffer
, &form_1
, 0);
6633 return WERR_UNKNOWN_LEVEL
;
6637 /****************************************************************************
6638 ****************************************************************************/
6640 static void fill_port_1(PORT_INFO_1
*port
, char *name
)
6642 init_unistr(&port
->port_name
, name
);
6645 /****************************************************************************
6646 ****************************************************************************/
6648 static void fill_port_2(PORT_INFO_2
*port
, char *name
)
6650 init_unistr(&port
->port_name
, name
);
6651 init_unistr(&port
->monitor_name
, "Local Monitor");
6652 init_unistr(&port
->description
, "Local Port");
6653 #define PORT_TYPE_WRITE 1
6654 port
->port_type
=PORT_TYPE_WRITE
;
6658 /****************************************************************************
6660 ****************************************************************************/
6662 static WERROR
enumports_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6664 PORT_INFO_1
*ports
=NULL
;
6667 if (*lp_enumports_cmd()) {
6668 char *cmd
= lp_enumports_cmd();
6675 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 1);
6677 DEBUG(10,("Running [%s]\n", command
));
6678 ret
= smbrun(command
, &fd
);
6679 DEBUG(10,("Returned [%d]\n", ret
));
6683 /* Is this the best error to return here? */
6684 return WERR_ACCESS_DENIED
;
6688 qlines
= fd_lines_load(fd
, &numlines
);
6689 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6693 if((ports
=(PORT_INFO_1
*)malloc( numlines
* sizeof(PORT_INFO_1
) )) == NULL
) {
6694 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
6695 dos_errstr(WERR_NOMEM
)));
6696 file_lines_free(qlines
);
6700 for (i
=0; i
<numlines
; i
++) {
6701 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
6702 fill_port_1(&ports
[i
], qlines
[i
]);
6705 file_lines_free(qlines
);
6708 *returned
= numlines
;
6711 *returned
= 1; /* Sole Samba port returned. */
6713 if((ports
=(PORT_INFO_1
*)malloc( sizeof(PORT_INFO_1
) )) == NULL
)
6716 DEBUG(10,("enumports_level_1: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
6718 fill_port_1(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
6721 /* check the required size. */
6722 for (i
=0; i
<*returned
; i
++) {
6723 DEBUGADD(6,("adding port [%d]'s size\n", i
));
6724 *needed
+= spoolss_size_port_info_1(&ports
[i
]);
6727 if (!alloc_buffer_size(buffer
, *needed
)) {
6729 return WERR_INSUFFICIENT_BUFFER
;
6732 /* fill the buffer with the ports structures */
6733 for (i
=0; i
<*returned
; i
++) {
6734 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
6735 smb_io_port_1("", buffer
, &ports
[i
], 0);
6740 if (*needed
> offered
) {
6742 return WERR_INSUFFICIENT_BUFFER
;
6748 /****************************************************************************
6750 ****************************************************************************/
6752 static WERROR
enumports_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
6754 PORT_INFO_2
*ports
=NULL
;
6757 if (*lp_enumports_cmd()) {
6758 char *cmd
= lp_enumports_cmd();
6767 if (*lp_pathname(lp_servicenumber(PRINTERS_NAME
)))
6768 path
= lp_pathname(lp_servicenumber(PRINTERS_NAME
));
6770 path
= lp_lockdir();
6772 slprintf(tmp_file
, sizeof(tmp_file
)-1, "%s/smbcmd.%u.", path
, (unsigned int)sys_getpid());
6773 slprintf(command
, sizeof(command
)-1, "%s \"%d\"", cmd
, 2);
6776 DEBUG(10,("Running [%s > %s]\n", command
,tmp_file
));
6777 ret
= smbrun(command
, &fd
);
6778 DEBUGADD(10,("returned [%d]\n", ret
));
6782 /* Is this the best error to return here? */
6783 return WERR_ACCESS_DENIED
;
6787 qlines
= fd_lines_load(fd
, &numlines
);
6788 DEBUGADD(10,("Lines returned = [%d]\n", numlines
));
6792 if((ports
=(PORT_INFO_2
*)malloc( numlines
* sizeof(PORT_INFO_2
) )) == NULL
) {
6793 file_lines_free(qlines
);
6797 for (i
=0; i
<numlines
; i
++) {
6798 DEBUG(6,("Filling port number [%d] with port [%s]\n", i
, qlines
[i
]));
6799 fill_port_2(&(ports
[i
]), qlines
[i
]);
6802 file_lines_free(qlines
);
6805 *returned
= numlines
;
6811 if((ports
=(PORT_INFO_2
*)malloc( sizeof(PORT_INFO_2
) )) == NULL
)
6814 DEBUG(10,("enumports_level_2: port name %s\n", SAMBA_PRINTER_PORT_NAME
));
6816 fill_port_2(&ports
[0], SAMBA_PRINTER_PORT_NAME
);
6819 /* check the required size. */
6820 for (i
=0; i
<*returned
; i
++) {
6821 DEBUGADD(6,("adding port [%d]'s size\n", i
));
6822 *needed
+= spoolss_size_port_info_2(&ports
[i
]);
6825 if (!alloc_buffer_size(buffer
, *needed
)) {
6827 return WERR_INSUFFICIENT_BUFFER
;
6830 /* fill the buffer with the ports structures */
6831 for (i
=0; i
<*returned
; i
++) {
6832 DEBUGADD(6,("adding port [%d] to buffer\n", i
));
6833 smb_io_port_2("", buffer
, &ports
[i
], 0);
6838 if (*needed
> offered
) {
6840 return WERR_INSUFFICIENT_BUFFER
;
6846 /****************************************************************************
6848 ****************************************************************************/
6850 WERROR
_spoolss_enumports( pipes_struct
*p
, SPOOL_Q_ENUMPORTS
*q_u
, SPOOL_R_ENUMPORTS
*r_u
)
6852 uint32 level
= q_u
->level
;
6853 NEW_BUFFER
*buffer
= NULL
;
6854 uint32 offered
= q_u
->offered
;
6855 uint32
*needed
= &r_u
->needed
;
6856 uint32
*returned
= &r_u
->returned
;
6858 /* that's an [in out] buffer */
6859 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
6860 buffer
= r_u
->buffer
;
6862 DEBUG(4,("_spoolss_enumports\n"));
6869 return enumports_level_1(buffer
, offered
, needed
, returned
);
6871 return enumports_level_2(buffer
, offered
, needed
, returned
);
6873 return WERR_UNKNOWN_LEVEL
;
6877 /****************************************************************************
6878 ****************************************************************************/
6880 static WERROR
spoolss_addprinterex_level_2( pipes_struct
*p
, const UNISTR2
*uni_srv_name
,
6881 const SPOOL_PRINTER_INFO_LEVEL
*info
,
6882 DEVICEMODE
*devmode
, SEC_DESC_BUF
*sec_desc_buf
,
6883 uint32 user_switch
, const SPOOL_USER_CTR
*user
,
6886 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
6889 WERROR err
= WERR_OK
;
6891 if ((printer
= (NT_PRINTER_INFO_LEVEL
*)malloc(sizeof(NT_PRINTER_INFO_LEVEL
))) == NULL
) {
6892 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
6896 ZERO_STRUCTP(printer
);
6898 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
6899 if (!convert_printer_info(info
, printer
, 2)) {
6900 free_a_printer(&printer
, 2);
6904 /* check to see if the printer already exists */
6906 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) != -1) {
6907 DEBUG(5, ("_spoolss_addprinterex: Attempted to add a printer named [%s] when one already existed!\n",
6908 printer
->info_2
->sharename
));
6909 free_a_printer(&printer
, 2);
6910 return WERR_PRINTER_ALREADY_EXISTS
;
6913 if (*lp_addprinter_cmd() )
6914 if ( !add_printer_hook(printer
) ) {
6915 free_a_printer(&printer
,2);
6916 return WERR_ACCESS_DENIED
;
6919 slprintf(name
, sizeof(name
)-1, "\\\\%s\\%s", get_called_name(),
6920 printer
->info_2
->sharename
);
6922 if ((snum
= print_queue_snum(printer
->info_2
->sharename
)) == -1) {
6923 free_a_printer(&printer
,2);
6924 return WERR_ACCESS_DENIED
;
6927 /* you must be a printer admin to add a new printer */
6928 if (!print_access_check(NULL
, snum
, PRINTER_ACCESS_ADMINISTER
)) {
6929 free_a_printer(&printer
,2);
6930 return WERR_ACCESS_DENIED
;
6934 * Do sanity check on the requested changes for Samba.
6937 if (!check_printer_ok(printer
->info_2
, snum
)) {
6938 free_a_printer(&printer
,2);
6939 return WERR_INVALID_PARAM
;
6943 * When a printer is created, the drivername bound to the printer is used
6944 * to lookup previously saved driver initialization info, which is then
6945 * bound to the new printer, simulating what happens in the Windows arch.
6950 set_driver_init(printer
, 2);
6954 /* A valid devmode was included, convert and link it
6956 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
6958 if (!convert_devicemode(printer
->info_2
->printername
, devmode
,
6959 &printer
->info_2
->devmode
))
6963 /* write the ASCII on disk */
6964 err
= mod_a_printer(*printer
, 2);
6965 if (!W_ERROR_IS_OK(err
)) {
6966 free_a_printer(&printer
,2);
6970 if (!open_printer_hnd(p
, handle
, name
, PRINTER_ACCESS_ADMINISTER
)) {
6971 /* Handle open failed - remove addition. */
6972 del_a_printer(printer
->info_2
->sharename
);
6973 free_a_printer(&printer
,2);
6974 return WERR_ACCESS_DENIED
;
6977 update_c_setprinter(False
);
6978 free_a_printer(&printer
,2);
6983 /****************************************************************************
6984 ****************************************************************************/
6986 WERROR
_spoolss_addprinterex( pipes_struct
*p
, SPOOL_Q_ADDPRINTEREX
*q_u
, SPOOL_R_ADDPRINTEREX
*r_u
)
6988 UNISTR2
*uni_srv_name
= &q_u
->server_name
;
6989 uint32 level
= q_u
->level
;
6990 SPOOL_PRINTER_INFO_LEVEL
*info
= &q_u
->info
;
6991 DEVICEMODE
*devmode
= q_u
->devmode_ctr
.devmode
;
6992 SEC_DESC_BUF
*sdb
= q_u
->secdesc_ctr
;
6993 uint32 user_switch
= q_u
->user_switch
;
6994 SPOOL_USER_CTR
*user
= &q_u
->user_ctr
;
6995 POLICY_HND
*handle
= &r_u
->handle
;
6999 /* we don't handle yet */
7000 /* but I know what to do ... */
7001 return WERR_UNKNOWN_LEVEL
;
7003 return spoolss_addprinterex_level_2(p
, uni_srv_name
, info
,
7005 user_switch
, user
, handle
);
7007 return WERR_UNKNOWN_LEVEL
;
7011 /****************************************************************************
7012 ****************************************************************************/
7014 WERROR
_spoolss_addprinterdriver(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVER
*q_u
, SPOOL_R_ADDPRINTERDRIVER
*r_u
)
7016 uint32 level
= q_u
->level
;
7017 SPOOL_PRINTER_DRIVER_INFO_LEVEL
*info
= &q_u
->info
;
7018 WERROR err
= WERR_OK
;
7019 NT_PRINTER_DRIVER_INFO_LEVEL driver
;
7020 struct current_user user
;
7021 fstring driver_name
;
7024 ZERO_STRUCT(driver
);
7026 get_current_user(&user
, p
);
7028 if (!convert_printer_driver_info(info
, &driver
, level
)) {
7033 DEBUG(5,("Cleaning driver's information\n"));
7034 err
= clean_up_driver_struct(driver
, level
, &user
);
7035 if (!W_ERROR_IS_OK(err
))
7038 DEBUG(5,("Moving driver to final destination\n"));
7039 if(!move_driver_to_download_area(driver
, level
, &user
, &err
)) {
7040 if (W_ERROR_IS_OK(err
))
7041 err
= WERR_ACCESS_DENIED
;
7045 if (add_a_printer_driver(driver
, level
)!=0) {
7046 err
= WERR_ACCESS_DENIED
;
7050 /* BEGIN_ADMIN_LOG */
7053 sys_adminlog(LOG_INFO
,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
7054 driver
.info_3
->name
,drv_ver_to_os
[driver
.info_3
->cversion
],uidtoname(user
.uid
));
7055 fstrcpy(driver_name
, driver
.info_3
->name
);
7058 sys_adminlog(LOG_INFO
,"Added printer driver. Print driver name: %s. Print driver OS: %s. Administrator name: %s.",
7059 driver
.info_6
->name
,drv_ver_to_os
[driver
.info_6
->version
],uidtoname(user
.uid
));
7060 fstrcpy(driver_name
, driver
.info_6
->name
);
7066 * I think this is where he DrvUpgradePrinter() hook would be
7067 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7068 * server. Right now, we just need to send ourselves a message
7069 * to update each printer bound to this driver. --jerry
7072 if (!srv_spoolss_drv_upgrade_printer(driver_name
)) {
7073 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7078 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7079 * decide if the driver init data should be deleted. The rules are:
7080 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7081 * 2) delete init data only if there is no 2k/Xp driver
7082 * 3) always delete init data
7083 * The generalized rule is always use init data from the highest order driver.
7084 * It is necessary to follow the driver install by an initialization step to
7085 * finish off this process.
7088 version
= driver
.info_3
->cversion
;
7089 else if (level
== 6)
7090 version
= driver
.info_6
->version
;
7095 * 9x printer driver - never delete init data
7098 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7103 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7104 * there is no 2k/Xp driver init data for this driver name.
7108 NT_PRINTER_DRIVER_INFO_LEVEL driver1
;
7110 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1
, 3, driver_name
, "Windows NT x86", 3))) {
7112 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7114 if (!del_driver_init(driver_name
))
7115 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name
));
7118 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7120 free_a_printer_driver(driver1
,3);
7121 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
7128 * 2k or Xp printer driver - always delete init data
7131 if (!del_driver_init(driver_name
))
7132 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name
));
7136 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level
));
7142 free_a_printer_driver(driver
, level
);
7146 /********************************************************************
7147 * spoolss_addprinterdriverex
7148 ********************************************************************/
7150 WERROR
_spoolss_addprinterdriverex(pipes_struct
*p
, SPOOL_Q_ADDPRINTERDRIVEREX
*q_u
, SPOOL_R_ADDPRINTERDRIVEREX
*r_u
)
7152 SPOOL_Q_ADDPRINTERDRIVER q_u_local
;
7153 SPOOL_R_ADDPRINTERDRIVER r_u_local
;
7156 * we only support the semantics of AddPrinterDriver()
7157 * i.e. only copy files that are newer than existing ones
7160 if ( q_u
->copy_flags
!= APD_COPY_NEW_FILES
)
7161 return WERR_ACCESS_DENIED
;
7163 ZERO_STRUCT(q_u_local
);
7164 ZERO_STRUCT(r_u_local
);
7166 /* just pass the information off to _spoolss_addprinterdriver() */
7167 q_u_local
.server_name_ptr
= q_u
->server_name_ptr
;
7168 copy_unistr2(&q_u_local
.server_name
, &q_u
->server_name
);
7169 q_u_local
.level
= q_u
->level
;
7170 memcpy( &q_u_local
.info
, &q_u
->info
, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL
) );
7172 return _spoolss_addprinterdriver( p
, &q_u_local
, &r_u_local
);
7175 /****************************************************************************
7176 ****************************************************************************/
7178 static void fill_driverdir_1(DRIVER_DIRECTORY_1
*info
, char *name
)
7180 init_unistr(&info
->name
, name
);
7183 /****************************************************************************
7184 ****************************************************************************/
7186 static WERROR
getprinterdriverdir_level_1(UNISTR2
*name
, UNISTR2
*uni_environment
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
7190 pstring short_archi
;
7191 DRIVER_DIRECTORY_1
*info
=NULL
;
7193 unistr2_to_ascii(long_archi
, uni_environment
, sizeof(long_archi
)-1);
7195 if (get_short_archi(short_archi
, long_archi
)==False
)
7196 return WERR_INVALID_ENVIRONMENT
;
7198 if((info
=(DRIVER_DIRECTORY_1
*)malloc(sizeof(DRIVER_DIRECTORY_1
))) == NULL
)
7201 slprintf(path
, sizeof(path
)-1, "\\\\%s\\print$\\%s", get_called_name(), short_archi
);
7203 DEBUG(4,("printer driver directory: [%s]\n", path
));
7205 fill_driverdir_1(info
, path
);
7207 *needed
+= spoolss_size_driverdir_info_1(info
);
7209 if (!alloc_buffer_size(buffer
, *needed
)) {
7211 return WERR_INSUFFICIENT_BUFFER
;
7214 smb_io_driverdir_1("", buffer
, info
, 0);
7218 if (*needed
> offered
)
7219 return WERR_INSUFFICIENT_BUFFER
;
7224 /****************************************************************************
7225 ****************************************************************************/
7227 WERROR
_spoolss_getprinterdriverdirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTERDRIVERDIR
*q_u
, SPOOL_R_GETPRINTERDRIVERDIR
*r_u
)
7229 UNISTR2
*name
= &q_u
->name
;
7230 UNISTR2
*uni_environment
= &q_u
->environment
;
7231 uint32 level
= q_u
->level
;
7232 NEW_BUFFER
*buffer
= NULL
;
7233 uint32 offered
= q_u
->offered
;
7234 uint32
*needed
= &r_u
->needed
;
7236 /* that's an [in out] buffer */
7237 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
7238 buffer
= r_u
->buffer
;
7240 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
7246 return getprinterdriverdir_level_1(name
, uni_environment
, buffer
, offered
, needed
);
7248 return WERR_UNKNOWN_LEVEL
;
7252 /****************************************************************************
7253 ****************************************************************************/
7255 WERROR
_spoolss_enumprinterdata(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATA
*q_u
, SPOOL_R_ENUMPRINTERDATA
*r_u
)
7257 POLICY_HND
*handle
= &q_u
->handle
;
7258 uint32 idx
= q_u
->index
;
7259 uint32 in_value_len
= q_u
->valuesize
;
7260 uint32 in_data_len
= q_u
->datasize
;
7261 uint32
*out_max_value_len
= &r_u
->valuesize
;
7262 uint16
**out_value
= &r_u
->value
;
7263 uint32
*out_value_len
= &r_u
->realvaluesize
;
7264 uint32
*out_type
= &r_u
->type
;
7265 uint32
*out_max_data_len
= &r_u
->datasize
;
7266 uint8
**data_out
= &r_u
->data
;
7267 uint32
*out_data_len
= &r_u
->realdatasize
;
7269 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7272 uint32 biggest_valuesize
;
7273 uint32 biggest_datasize
;
7275 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
7278 REGISTRY_VALUE
*val
;
7279 NT_PRINTER_DATA
*p_data
;
7280 int i
, key_index
, num_values
;
7283 ZERO_STRUCT( printer
);
7287 *out_max_data_len
= 0;
7291 DEBUG(5,("spoolss_enumprinterdata\n"));
7294 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
7298 if (!get_printer_snum(p
,handle
, &snum
))
7301 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
7302 if (!W_ERROR_IS_OK(result
))
7305 p_data
= &printer
->info_2
->data
;
7306 key_index
= lookup_printerkey( p_data
, SPOOL_PRINTERDATA_KEY
);
7311 * The NT machine wants to know the biggest size of value and data
7313 * cf: MSDN EnumPrinterData remark section
7316 if ( !in_value_len
&& !in_data_len
)
7318 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7321 biggest_valuesize
= 0;
7322 biggest_datasize
= 0;
7324 num_values
= regval_ctr_numvals( &p_data
->keys
[key_index
].values
);
7326 for ( i
=0; i
<num_values
; i
++ )
7328 val
= regval_ctr_specific_value( &p_data
->keys
[key_index
].values
, i
);
7330 name_length
= strlen(val
->valuename
);
7331 if ( strlen(val
->valuename
) > biggest_valuesize
)
7332 biggest_valuesize
= name_length
;
7334 if ( val
->size
> biggest_datasize
)
7335 biggest_datasize
= val
->size
;
7337 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize
,
7341 /* the value is an UNICODE string but real_value_size is the length
7342 in bytes including the trailing 0 */
7344 *out_value_len
= 2 * (1+biggest_valuesize
);
7345 *out_data_len
= biggest_datasize
;
7347 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len
, *out_data_len
));
7353 * the value len is wrong in NT sp3
7354 * that's the number of bytes not the number of unicode chars
7357 val
= regval_ctr_specific_value( &p_data
->keys
[key_index
].values
, idx
);
7362 /* out_value should default to "" or else NT4 has
7363 problems unmarshalling the response */
7365 *out_max_value_len
= (in_value_len
/sizeof(uint16
));
7367 if ( (*out_value
=(uint16
*)talloc_zero(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
7369 result
= WERR_NOMEM
;
7373 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, "", in_value_len
, 0);
7375 /* the data is counted in bytes */
7377 *out_max_data_len
= in_data_len
;
7378 *out_data_len
= in_data_len
;
7380 /* only allocate when given a non-zero data_len */
7382 if ( in_data_len
&& ((*data_out
=(uint8
*)talloc_zero(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
) )
7384 result
= WERR_NOMEM
;
7388 result
= WERR_NO_MORE_ITEMS
;
7394 * - counted in bytes in the request
7395 * - counted in UNICODE chars in the max reply
7396 * - counted in bytes in the real size
7398 * take a pause *before* coding not *during* coding
7402 *out_max_value_len
= ( in_value_len
/ sizeof(uint16
) );
7403 if ( (*out_value
= (uint16
*)talloc_zero(p
->mem_ctx
, in_value_len
*sizeof(uint8
))) == NULL
)
7405 result
= WERR_NOMEM
;
7409 *out_value_len
= (uint32
)rpcstr_push((char *)*out_value
, regval_name(val
), in_value_len
, 0);
7413 *out_type
= regval_type( val
);
7415 /* data - counted in bytes */
7417 *out_max_data_len
= in_data_len
;
7418 if ( (*data_out
= (uint8
*)talloc_zero(p
->mem_ctx
, in_data_len
*sizeof(uint8
))) == NULL
)
7420 result
= WERR_NOMEM
;
7423 data_len
= (size_t)regval_size(val
);
7424 memcpy( *data_out
, regval_data_p(val
), data_len
);
7425 *out_data_len
= data_len
;
7429 free_a_printer(&printer
, 2);
7433 /****************************************************************************
7434 ****************************************************************************/
7436 WERROR
_spoolss_setprinterdata( pipes_struct
*p
, SPOOL_Q_SETPRINTERDATA
*q_u
, SPOOL_R_SETPRINTERDATA
*r_u
)
7438 POLICY_HND
*handle
= &q_u
->handle
;
7439 UNISTR2
*value
= &q_u
->value
;
7440 uint32 type
= q_u
->type
;
7441 uint8
*data
= q_u
->data
;
7442 uint32 real_len
= q_u
->real_len
;
7444 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7446 WERROR status
= WERR_OK
;
7447 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
7450 DEBUG(5,("spoolss_setprinterdata\n"));
7453 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
7457 if (!get_printer_snum(p
,handle
, &snum
))
7461 * Access check : NT returns "access denied" if you make a
7462 * SetPrinterData call without the necessary privildge.
7463 * we were originally returning OK if nothing changed
7464 * which made Win2k issue **a lot** of SetPrinterData
7465 * when connecting to a printer --jerry
7468 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
7470 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
7471 status
= WERR_ACCESS_DENIED
;
7475 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
7476 if (!W_ERROR_IS_OK(status
))
7479 unistr2_to_ascii( valuename
, value
, sizeof(valuename
)-1 );
7482 * When client side code sets a magic printer data key, detect it and save
7483 * the current printer data and the magic key's data (its the DEVMODE) for
7484 * future printer/driver initializations.
7486 if ( (type
== REG_BINARY
) && strequal( valuename
, PHANTOM_DEVMODE_KEY
))
7488 /* Set devmode and printer initialization info */
7489 status
= save_driver_init( printer
, 2, data
, real_len
);
7491 srv_spoolss_reset_printerdata( printer
->info_2
->drivername
);
7495 status
= set_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
,
7496 type
, data
, real_len
);
7497 if ( W_ERROR_IS_OK(status
) )
7498 status
= mod_a_printer(*printer
, 2);
7502 free_a_printer(&printer
, 2);
7507 /****************************************************************************
7508 ****************************************************************************/
7510 WERROR
_spoolss_resetprinter(pipes_struct
*p
, SPOOL_Q_RESETPRINTER
*q_u
, SPOOL_R_RESETPRINTER
*r_u
)
7512 POLICY_HND
*handle
= &q_u
->handle
;
7513 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
7516 DEBUG(5,("_spoolss_resetprinter\n"));
7519 * All we do is to check to see if the handle and queue is valid.
7520 * This call really doesn't mean anything to us because we only
7521 * support RAW printing. --jerry
7525 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
7529 if (!get_printer_snum(p
,handle
, &snum
))
7533 /* blindly return success */
7538 /****************************************************************************
7539 ****************************************************************************/
7541 WERROR
_spoolss_deleteprinterdata(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATA
*q_u
, SPOOL_R_DELETEPRINTERDATA
*r_u
)
7543 POLICY_HND
*handle
= &q_u
->handle
;
7544 UNISTR2
*value
= &q_u
->valuename
;
7546 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7548 WERROR status
= WERR_OK
;
7549 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
7552 DEBUG(5,("spoolss_deleteprinterdata\n"));
7555 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
7559 if (!get_printer_snum(p
, handle
, &snum
))
7562 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
7563 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties change denied by handle\n"));
7564 return WERR_ACCESS_DENIED
;
7567 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
7568 if (!W_ERROR_IS_OK(status
))
7571 unistr2_to_ascii( valuename
, value
, sizeof(valuename
)-1 );
7573 status
= delete_printer_dataex( printer
, SPOOL_PRINTERDATA_KEY
, valuename
);
7575 free_a_printer(&printer
, 2);
7580 /****************************************************************************
7581 ****************************************************************************/
7583 WERROR
_spoolss_addform( pipes_struct
*p
, SPOOL_Q_ADDFORM
*q_u
, SPOOL_R_ADDFORM
*r_u
)
7585 POLICY_HND
*handle
= &q_u
->handle
;
7586 FORM
*form
= &q_u
->form
;
7587 nt_forms_struct tmpForm
;
7589 WERROR status
= WERR_OK
;
7590 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7593 nt_forms_struct
*list
=NULL
;
7594 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
7596 DEBUG(5,("spoolss_addform\n"));
7599 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
7604 /* forms can be added on printer of on the print server handle */
7606 if ( Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTER
)
7608 if (!get_printer_snum(p
,handle
, &snum
))
7611 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
7612 if (!W_ERROR_IS_OK(status
))
7616 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
7617 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
7618 status
= WERR_ACCESS_DENIED
;
7622 /* can't add if builtin */
7624 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
7625 status
= WERR_ALREADY_EXISTS
;
7629 count
= get_ntforms(&list
);
7631 if(!add_a_form(&list
, form
, &count
)) {
7632 status
= WERR_NOMEM
;
7636 write_ntforms(&list
, count
);
7639 * ChangeID must always be set if this is a printer
7642 if ( Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTER
)
7643 status
= mod_a_printer(*printer
, 2);
7647 free_a_printer(&printer
, 2);
7653 /****************************************************************************
7654 ****************************************************************************/
7656 WERROR
_spoolss_deleteform( pipes_struct
*p
, SPOOL_Q_DELETEFORM
*q_u
, SPOOL_R_DELETEFORM
*r_u
)
7658 POLICY_HND
*handle
= &q_u
->handle
;
7659 UNISTR2
*form_name
= &q_u
->name
;
7660 nt_forms_struct tmpForm
;
7662 nt_forms_struct
*list
=NULL
;
7663 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
7665 WERROR status
= WERR_OK
;
7666 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7668 DEBUG(5,("spoolss_deleteform\n"));
7671 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
7675 /* forms can be deleted on printer of on the print server handle */
7677 if ( Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTER
)
7679 if (!get_printer_snum(p
,handle
, &snum
))
7682 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
7683 if (!W_ERROR_IS_OK(status
))
7687 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
7688 DEBUG(2,("_spoolss_deleteform: denied by handle permissions.\n"));
7689 status
= WERR_ACCESS_DENIED
;
7693 /* can't delete if builtin */
7695 if (get_a_builtin_ntform(form_name
,&tmpForm
)) {
7696 status
= WERR_INVALID_PARAM
;
7700 count
= get_ntforms(&list
);
7702 if ( !delete_a_form(&list
, form_name
, &count
, &status
))
7706 * ChangeID must always be set if this is a printer
7709 if ( Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTER
)
7710 status
= mod_a_printer(*printer
, 2);
7714 free_a_printer(&printer
, 2);
7720 /****************************************************************************
7721 ****************************************************************************/
7723 WERROR
_spoolss_setform(pipes_struct
*p
, SPOOL_Q_SETFORM
*q_u
, SPOOL_R_SETFORM
*r_u
)
7725 POLICY_HND
*handle
= &q_u
->handle
;
7726 FORM
*form
= &q_u
->form
;
7727 nt_forms_struct tmpForm
;
7729 WERROR status
= WERR_OK
;
7730 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
7733 nt_forms_struct
*list
=NULL
;
7734 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
7736 DEBUG(5,("spoolss_setform\n"));
7739 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
7743 /* forms can be modified on printer of on the print server handle */
7745 if ( Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTER
)
7747 if (!get_printer_snum(p
,handle
, &snum
))
7750 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
7751 if (!W_ERROR_IS_OK(status
))
7755 if ( !(Printer
->access_granted
& (PRINTER_ACCESS_ADMINISTER
|SERVER_ACCESS_ADMINISTER
)) ) {
7756 DEBUG(2,("_spoolss_setform: denied by handle permissions\n"));
7757 status
= WERR_ACCESS_DENIED
;
7761 /* can't set if builtin */
7762 if (get_a_builtin_ntform(&form
->name
,&tmpForm
)) {
7763 status
= WERR_INVALID_PARAM
;
7767 count
= get_ntforms(&list
);
7768 update_a_form(&list
, form
, count
);
7769 write_ntforms(&list
, count
);
7772 * ChangeID must always be set if this is a printer
7775 if ( Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTER
)
7776 status
= mod_a_printer(*printer
, 2);
7781 free_a_printer(&printer
, 2);
7787 /****************************************************************************
7788 enumprintprocessors level 1.
7789 ****************************************************************************/
7791 static WERROR
enumprintprocessors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7793 PRINTPROCESSOR_1
*info_1
=NULL
;
7795 if((info_1
= (PRINTPROCESSOR_1
*)malloc(sizeof(PRINTPROCESSOR_1
))) == NULL
)
7800 init_unistr(&info_1
->name
, "winprint");
7802 *needed
+= spoolss_size_printprocessor_info_1(info_1
);
7804 if (!alloc_buffer_size(buffer
, *needed
))
7805 return WERR_INSUFFICIENT_BUFFER
;
7807 smb_io_printprocessor_info_1("", buffer
, info_1
, 0);
7811 if (*needed
> offered
) {
7813 return WERR_INSUFFICIENT_BUFFER
;
7819 /****************************************************************************
7820 ****************************************************************************/
7822 WERROR
_spoolss_enumprintprocessors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCESSORS
*q_u
, SPOOL_R_ENUMPRINTPROCESSORS
*r_u
)
7824 uint32 level
= q_u
->level
;
7825 NEW_BUFFER
*buffer
= NULL
;
7826 uint32 offered
= q_u
->offered
;
7827 uint32
*needed
= &r_u
->needed
;
7828 uint32
*returned
= &r_u
->returned
;
7830 /* that's an [in out] buffer */
7831 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
7832 buffer
= r_u
->buffer
;
7834 DEBUG(5,("spoolss_enumprintprocessors\n"));
7837 * Enumerate the print processors ...
7839 * Just reply with "winprint", to keep NT happy
7840 * and I can use my nice printer checker.
7848 return enumprintprocessors_level_1(buffer
, offered
, needed
, returned
);
7850 return WERR_UNKNOWN_LEVEL
;
7854 /****************************************************************************
7855 enumprintprocdatatypes level 1.
7856 ****************************************************************************/
7858 static WERROR
enumprintprocdatatypes_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7860 PRINTPROCDATATYPE_1
*info_1
=NULL
;
7862 if((info_1
= (PRINTPROCDATATYPE_1
*)malloc(sizeof(PRINTPROCDATATYPE_1
))) == NULL
)
7867 init_unistr(&info_1
->name
, "RAW");
7869 *needed
+= spoolss_size_printprocdatatype_info_1(info_1
);
7871 if (!alloc_buffer_size(buffer
, *needed
))
7872 return WERR_INSUFFICIENT_BUFFER
;
7874 smb_io_printprocdatatype_info_1("", buffer
, info_1
, 0);
7878 if (*needed
> offered
) {
7880 return WERR_INSUFFICIENT_BUFFER
;
7886 /****************************************************************************
7887 ****************************************************************************/
7889 WERROR
_spoolss_enumprintprocdatatypes(pipes_struct
*p
, SPOOL_Q_ENUMPRINTPROCDATATYPES
*q_u
, SPOOL_R_ENUMPRINTPROCDATATYPES
*r_u
)
7891 uint32 level
= q_u
->level
;
7892 NEW_BUFFER
*buffer
= NULL
;
7893 uint32 offered
= q_u
->offered
;
7894 uint32
*needed
= &r_u
->needed
;
7895 uint32
*returned
= &r_u
->returned
;
7897 /* that's an [in out] buffer */
7898 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
7899 buffer
= r_u
->buffer
;
7901 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
7908 return enumprintprocdatatypes_level_1(buffer
, offered
, needed
, returned
);
7910 return WERR_UNKNOWN_LEVEL
;
7914 /****************************************************************************
7915 enumprintmonitors level 1.
7916 ****************************************************************************/
7918 static WERROR
enumprintmonitors_level_1(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7920 PRINTMONITOR_1
*info_1
=NULL
;
7922 if((info_1
= (PRINTMONITOR_1
*)malloc(sizeof(PRINTMONITOR_1
))) == NULL
)
7927 init_unistr(&info_1
->name
, "Local Port");
7929 *needed
+= spoolss_size_printmonitor_info_1(info_1
);
7931 if (!alloc_buffer_size(buffer
, *needed
))
7932 return WERR_INSUFFICIENT_BUFFER
;
7934 smb_io_printmonitor_info_1("", buffer
, info_1
, 0);
7938 if (*needed
> offered
) {
7940 return WERR_INSUFFICIENT_BUFFER
;
7946 /****************************************************************************
7947 enumprintmonitors level 2.
7948 ****************************************************************************/
7950 static WERROR
enumprintmonitors_level_2(NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
, uint32
*returned
)
7952 PRINTMONITOR_2
*info_2
=NULL
;
7954 if((info_2
= (PRINTMONITOR_2
*)malloc(sizeof(PRINTMONITOR_2
))) == NULL
)
7959 init_unistr(&info_2
->name
, "Local Port");
7960 init_unistr(&info_2
->environment
, "Windows NT X86");
7961 init_unistr(&info_2
->dll_name
, "localmon.dll");
7963 *needed
+= spoolss_size_printmonitor_info_2(info_2
);
7965 if (!alloc_buffer_size(buffer
, *needed
))
7966 return WERR_INSUFFICIENT_BUFFER
;
7968 smb_io_printmonitor_info_2("", buffer
, info_2
, 0);
7972 if (*needed
> offered
) {
7974 return WERR_INSUFFICIENT_BUFFER
;
7980 /****************************************************************************
7981 ****************************************************************************/
7983 WERROR
_spoolss_enumprintmonitors(pipes_struct
*p
, SPOOL_Q_ENUMPRINTMONITORS
*q_u
, SPOOL_R_ENUMPRINTMONITORS
*r_u
)
7985 uint32 level
= q_u
->level
;
7986 NEW_BUFFER
*buffer
= NULL
;
7987 uint32 offered
= q_u
->offered
;
7988 uint32
*needed
= &r_u
->needed
;
7989 uint32
*returned
= &r_u
->returned
;
7991 /* that's an [in out] buffer */
7992 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
7993 buffer
= r_u
->buffer
;
7995 DEBUG(5,("spoolss_enumprintmonitors\n"));
7998 * Enumerate the print monitors ...
8000 * Just reply with "Local Port", to keep NT happy
8001 * and I can use my nice printer checker.
8009 return enumprintmonitors_level_1(buffer
, offered
, needed
, returned
);
8011 return enumprintmonitors_level_2(buffer
, offered
, needed
, returned
);
8013 return WERR_UNKNOWN_LEVEL
;
8017 /****************************************************************************
8018 ****************************************************************************/
8020 static WERROR
getjob_level_1(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
8024 JOB_INFO_1
*info_1
=NULL
;
8026 info_1
=(JOB_INFO_1
*)malloc(sizeof(JOB_INFO_1
));
8028 if (info_1
== NULL
) {
8033 for (i
=0; i
<count
&& found
==False
; i
++) {
8034 if (queue
[i
].job
==(int)jobid
)
8041 /* NT treats not found as bad param... yet another bad choice */
8042 return WERR_INVALID_PARAM
;
8045 fill_job_info_1(info_1
, &(queue
[i
-1]), i
, snum
);
8047 *needed
+= spoolss_size_job_info_1(info_1
);
8049 if (!alloc_buffer_size(buffer
, *needed
)) {
8051 return WERR_INSUFFICIENT_BUFFER
;
8054 smb_io_job_info_1("", buffer
, info_1
, 0);
8058 if (*needed
> offered
)
8059 return WERR_INSUFFICIENT_BUFFER
;
8064 /****************************************************************************
8065 ****************************************************************************/
8067 static WERROR
getjob_level_2(print_queue_struct
*queue
, int count
, int snum
, uint32 jobid
, NEW_BUFFER
*buffer
, uint32 offered
, uint32
*needed
)
8072 NT_PRINTER_INFO_LEVEL
*ntprinter
= NULL
;
8074 DEVICEMODE
*devmode
= NULL
;
8075 NT_DEVICEMODE
*nt_devmode
= NULL
;
8077 info_2
=(JOB_INFO_2
*)malloc(sizeof(JOB_INFO_2
));
8079 ZERO_STRUCTP(info_2
);
8081 if (info_2
== NULL
) {
8086 for ( i
=0; i
<count
&& found
==False
; i
++ )
8088 if (queue
[i
].job
== (int)jobid
)
8094 /* NT treats not found as bad param... yet another bad
8096 ret
= WERR_INVALID_PARAM
;
8100 ret
= get_a_printer(&ntprinter
, 2, lp_servicename(snum
));
8101 if (!W_ERROR_IS_OK(ret
))
8105 * if the print job does not have a DEVMODE associated with it,
8106 * just use the one for the printer
8109 if ( !(nt_devmode
=print_job_devmode( snum
, jobid
)) )
8110 devmode
= construct_dev_mode(snum
);
8112 if ((devmode
= (DEVICEMODE
*)malloc(sizeof(DEVICEMODE
))) != NULL
) {
8113 ZERO_STRUCTP( devmode
);
8114 convert_nt_devicemode( devmode
, nt_devmode
);
8123 fill_job_info_2(info_2
, &(queue
[i
-1]), i
, snum
, ntprinter
, devmode
);
8125 *needed
+= spoolss_size_job_info_2(info_2
);
8127 if (!alloc_buffer_size(buffer
, *needed
)) {
8128 ret
= WERR_INSUFFICIENT_BUFFER
;
8132 smb_io_job_info_2("", buffer
, info_2
, 0);
8134 if (*needed
> offered
) {
8135 ret
= WERR_INSUFFICIENT_BUFFER
;
8142 /* Cleanup allocated memory */
8144 free_job_info_2(info_2
); /* Also frees devmode */
8146 free_a_printer(&ntprinter
, 2);
8151 /****************************************************************************
8152 ****************************************************************************/
8154 WERROR
_spoolss_getjob( pipes_struct
*p
, SPOOL_Q_GETJOB
*q_u
, SPOOL_R_GETJOB
*r_u
)
8156 POLICY_HND
*handle
= &q_u
->handle
;
8157 uint32 jobid
= q_u
->jobid
;
8158 uint32 level
= q_u
->level
;
8159 NEW_BUFFER
*buffer
= NULL
;
8160 uint32 offered
= q_u
->offered
;
8161 uint32
*needed
= &r_u
->needed
;
8162 WERROR wstatus
= WERR_OK
;
8166 print_queue_struct
*queue
= NULL
;
8167 print_status_struct prt_status
;
8169 /* that's an [in out] buffer */
8170 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
8171 buffer
= r_u
->buffer
;
8173 DEBUG(5,("spoolss_getjob\n"));
8177 if (!get_printer_snum(p
, handle
, &snum
))
8180 count
= print_queue_status(snum
, &queue
, &prt_status
);
8182 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8183 count
, prt_status
.status
, prt_status
.message
));
8187 wstatus
= getjob_level_1(queue
, count
, snum
, jobid
,
8188 buffer
, offered
, needed
);
8191 wstatus
= getjob_level_2(queue
, count
, snum
, jobid
,
8192 buffer
, offered
, needed
);
8195 wstatus
= WERR_UNKNOWN_LEVEL
;
8203 /********************************************************************
8204 spoolss_getprinterdataex
8206 From MSDN documentation of GetPrinterDataEx: pass request
8207 to GetPrinterData if key is "PrinterDriverData".
8208 ********************************************************************/
8210 WERROR
_spoolss_getprinterdataex(pipes_struct
*p
, SPOOL_Q_GETPRINTERDATAEX
*q_u
, SPOOL_R_GETPRINTERDATAEX
*r_u
)
8212 POLICY_HND
*handle
= &q_u
->handle
;
8213 uint32 in_size
= q_u
->size
;
8214 uint32
*type
= &r_u
->type
;
8215 uint32
*out_size
= &r_u
->size
;
8216 uint8
**data
= &r_u
->data
;
8217 uint32
*needed
= &r_u
->needed
;
8218 fstring keyname
, valuename
;
8220 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8222 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8224 WERROR status
= WERR_OK
;
8226 DEBUG(4,("_spoolss_getprinterdataex\n"));
8228 unistr2_to_ascii(keyname
, &q_u
->keyname
, sizeof(keyname
) - 1);
8229 unistr2_to_ascii(valuename
, &q_u
->valuename
, sizeof(valuename
) - 1);
8231 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
8232 keyname
, valuename
));
8234 /* in case of problem, return some default values */
8238 *out_size
= in_size
;
8241 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8242 status
= WERR_BADFID
;
8246 /* Is the handle to a printer or to the server? */
8248 if (Printer
->printer_type
== PRINTER_HANDLE_IS_PRINTSERVER
) {
8249 DEBUG(10,("_spoolss_getprinterdatex: Not implemented for server handles yet\n"));
8250 status
= WERR_INVALID_PARAM
;
8254 if ( !get_printer_snum(p
,handle
, &snum
) )
8257 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
8258 if ( !W_ERROR_IS_OK(status
) )
8261 /* check to see if the keyname is valid */
8262 if ( !strlen(keyname
) ) {
8263 status
= WERR_INVALID_PARAM
;
8267 if ( lookup_printerkey( &printer
->info_2
->data
, keyname
) == -1 ) {
8268 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname
));
8269 free_a_printer( &printer
, 2 );
8270 status
= WERR_BADFILE
;
8274 /* When given a new keyname, we should just create it */
8276 status
= get_printer_dataex( p
->mem_ctx
, printer
, keyname
, valuename
, type
, data
, needed
, in_size
);
8278 if (*needed
> *out_size
)
8279 status
= WERR_MORE_DATA
;
8282 if ( !W_ERROR_IS_OK(status
) )
8284 DEBUG(5, ("error: allocating %d\n", *out_size
));
8286 /* reply this param doesn't exist */
8290 if( (*data
=(uint8
*)talloc_zero(p
->mem_ctx
, *out_size
*sizeof(uint8
))) == NULL
) {
8291 status
= WERR_NOMEM
;
8301 free_a_printer( &printer
, 2 );
8306 /********************************************************************
8307 * spoolss_setprinterdataex
8308 ********************************************************************/
8310 WERROR
_spoolss_setprinterdataex(pipes_struct
*p
, SPOOL_Q_SETPRINTERDATAEX
*q_u
, SPOOL_R_SETPRINTERDATAEX
*r_u
)
8312 POLICY_HND
*handle
= &q_u
->handle
;
8313 uint32 type
= q_u
->type
;
8314 uint8
*data
= q_u
->data
;
8315 uint32 real_len
= q_u
->real_len
;
8317 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8319 WERROR status
= WERR_OK
;
8320 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8325 DEBUG(4,("_spoolss_setprinterdataex\n"));
8327 /* From MSDN documentation of SetPrinterDataEx: pass request to
8328 SetPrinterData if key is "PrinterDriverData" */
8331 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8335 if ( !get_printer_snum(p
,handle
, &snum
) )
8339 * Access check : NT returns "access denied" if you make a
8340 * SetPrinterData call without the necessary privildge.
8341 * we were originally returning OK if nothing changed
8342 * which made Win2k issue **a lot** of SetPrinterData
8343 * when connecting to a printer --jerry
8346 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
)
8348 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
8349 return WERR_ACCESS_DENIED
;
8352 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
8353 if (!W_ERROR_IS_OK(status
))
8356 unistr2_to_ascii( valuename
, &q_u
->value
, sizeof(valuename
) - 1);
8357 unistr2_to_ascii( keyname
, &q_u
->key
, sizeof(keyname
) - 1);
8359 /* check for OID in valuename */
8361 if ( (oid_string
= strchr( valuename
, ',' )) != NULL
)
8367 /* save the registry data */
8369 status
= set_printer_dataex( printer
, keyname
, valuename
, type
, data
, real_len
);
8371 /* save the OID if one was specified and the previous set call succeeded */
8373 if ( W_ERROR_IS_OK(status
) && oid_string
)
8376 fstrcat( keyname
, "\\" );
8377 fstrcat( keyname
, SPOOL_OID_KEY
);
8380 * I'm not checking the status here on purpose. Don't know
8381 * if this is right, but I'm returning the status from the
8382 * previous set_printer_dataex() call. I have no idea if
8383 * this is right. --jerry
8386 set_printer_dataex( printer
, keyname
, valuename
,
8387 REG_SZ
, (void*)oid_string
, strlen(oid_string
)+1 );
8390 free_a_printer(&printer
, 2);
8396 /********************************************************************
8397 * spoolss_deleteprinterdataex
8398 ********************************************************************/
8400 WERROR
_spoolss_deleteprinterdataex(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERDATAEX
*q_u
, SPOOL_R_DELETEPRINTERDATAEX
*r_u
)
8402 POLICY_HND
*handle
= &q_u
->handle
;
8403 UNISTR2
*value
= &q_u
->valuename
;
8404 UNISTR2
*key
= &q_u
->keyname
;
8406 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8408 WERROR status
= WERR_OK
;
8409 Printer_entry
*Printer
=find_printer_index_by_hnd(p
, handle
);
8410 pstring valuename
, keyname
;
8412 DEBUG(5,("spoolss_deleteprinterdataex\n"));
8415 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8419 if (!get_printer_snum(p
, handle
, &snum
))
8422 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8423 DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n"));
8424 return WERR_ACCESS_DENIED
;
8427 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
8428 if (!W_ERROR_IS_OK(status
))
8431 unistr2_to_ascii( valuename
, value
, sizeof(valuename
)-1 );
8432 unistr2_to_ascii( keyname
, key
, sizeof(keyname
)-1 );
8434 status
= delete_printer_dataex( printer
, keyname
, valuename
);
8436 free_a_printer(&printer
, 2);
8441 /********************************************************************
8442 * spoolss_enumprinterkey
8443 ********************************************************************/
8446 WERROR
_spoolss_enumprinterkey(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERKEY
*q_u
, SPOOL_R_ENUMPRINTERKEY
*r_u
)
8449 fstring
*keynames
= NULL
;
8450 uint16
*enumkeys
= NULL
;
8453 POLICY_HND
*handle
= &q_u
->handle
;
8454 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8455 NT_PRINTER_DATA
*data
;
8456 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8458 WERROR status
= WERR_BADFILE
;
8461 DEBUG(4,("_spoolss_enumprinterkey\n"));
8464 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8468 if ( !get_printer_snum(p
,handle
, &snum
) )
8471 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
8472 if (!W_ERROR_IS_OK(status
))
8475 /* get the list of subkey names */
8477 unistr2_to_ascii( key
, &q_u
->key
, sizeof(key
)-1 );
8478 data
= &printer
->info_2
->data
;
8480 num_keys
= get_printer_subkeys( data
, key
, &keynames
);
8482 if ( num_keys
== -1 ) {
8483 status
= WERR_BADFILE
;
8487 printerkey_len
= init_unistr_array( &enumkeys
, keynames
, NULL
);
8489 r_u
->needed
= printerkey_len
*2;
8491 if ( q_u
->size
< r_u
->needed
) {
8492 status
= WERR_MORE_DATA
;
8496 if (!make_spoolss_buffer5(p
->mem_ctx
, &r_u
->keys
, printerkey_len
, enumkeys
)) {
8497 status
= WERR_NOMEM
;
8503 if ( q_u
->size
< r_u
->needed
)
8504 status
= WERR_MORE_DATA
;
8507 free_a_printer( &printer
, 2 );
8508 SAFE_FREE( keynames
);
8513 /********************************************************************
8514 * spoolss_deleteprinterkey
8515 ********************************************************************/
8517 WERROR
_spoolss_deleteprinterkey(pipes_struct
*p
, SPOOL_Q_DELETEPRINTERKEY
*q_u
, SPOOL_R_DELETEPRINTERKEY
*r_u
)
8519 POLICY_HND
*handle
= &q_u
->handle
;
8520 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, &q_u
->handle
);
8522 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8526 DEBUG(5,("spoolss_deleteprinterkey\n"));
8529 DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle
)));
8533 /* if keyname == NULL, return error */
8535 if ( !q_u
->keyname
.buffer
)
8536 return WERR_INVALID_PARAM
;
8538 if (!get_printer_snum(p
, handle
, &snum
))
8541 if (Printer
->access_granted
!= PRINTER_ACCESS_ADMINISTER
) {
8542 DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n"));
8543 return WERR_ACCESS_DENIED
;
8546 status
= get_a_printer(&printer
, 2, lp_servicename(snum
));
8547 if (!W_ERROR_IS_OK(status
))
8550 /* delete the key and all subneys */
8552 unistr2_to_ascii(key
, &q_u
->keyname
, sizeof(key
) - 1);
8554 status
= delete_all_printer_data( printer
->info_2
, key
);
8556 if ( W_ERROR_IS_OK(status
) )
8557 status
= mod_a_printer(*printer
, 2);
8559 free_a_printer( &printer
, 2 );
8565 /********************************************************************
8566 * spoolss_enumprinterdataex
8567 ********************************************************************/
8569 WERROR
_spoolss_enumprinterdataex(pipes_struct
*p
, SPOOL_Q_ENUMPRINTERDATAEX
*q_u
, SPOOL_R_ENUMPRINTERDATAEX
*r_u
)
8571 POLICY_HND
*handle
= &q_u
->handle
;
8572 uint32 in_size
= q_u
->size
;
8575 NT_PRINTER_INFO_LEVEL
*printer
= NULL
;
8576 PRINTER_ENUM_VALUES
*enum_values
= NULL
;
8577 NT_PRINTER_DATA
*p_data
;
8579 Printer_entry
*Printer
= find_printer_index_by_hnd(p
, handle
);
8584 REGISTRY_VALUE
*val
;
8589 DEBUG(4,("_spoolss_enumprinterdataex\n"));
8592 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle
)));
8596 /* first get the printer off of disk */
8598 if (!get_printer_snum(p
,handle
, &snum
))
8601 ZERO_STRUCT(printer
);
8602 result
= get_a_printer(&printer
, 2, lp_servicename(snum
));
8603 if (!W_ERROR_IS_OK(result
))
8606 /* now look for a match on the key name */
8608 p_data
= &printer
->info_2
->data
;
8610 unistr2_to_ascii(key
, &q_u
->key
, sizeof(key
) - 1);
8611 if ( (key_index
= lookup_printerkey( p_data
, key
)) == -1 )
8613 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key
));
8614 result
= WERR_INVALID_PARAM
;
8621 /* allocate the memory for the array of pointers -- if necessary */
8623 num_entries
= regval_ctr_numvals( &p_data
->keys
[key_index
].values
);
8626 if ( (enum_values
=talloc(p
->mem_ctx
, num_entries
*sizeof(PRINTER_ENUM_VALUES
))) == NULL
)
8628 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%d] bytes!\n",
8629 num_entries
*sizeof(PRINTER_ENUM_VALUES
)));
8630 result
= WERR_NOMEM
;
8634 memset( enum_values
, 0x0, num_entries
*sizeof(PRINTER_ENUM_VALUES
) );
8638 * loop through all params and build the array to pass
8639 * back to the client
8642 for ( i
=0; i
<num_entries
; i
++ )
8644 /* lookup the registry value */
8646 val
= regval_ctr_specific_value( &p_data
->keys
[key_index
].values
, i
);
8647 DEBUG(10,("retrieved value number [%d] [%s]\n", i
, regval_name(val
) ));
8651 value_name
= regval_name( val
);
8652 init_unistr( &enum_values
[i
].valuename
, value_name
);
8653 enum_values
[i
].value_len
= (strlen(value_name
)+1) * 2;
8654 enum_values
[i
].type
= regval_type( val
);
8656 data_len
= regval_size( val
);
8658 if ( !(enum_values
[i
].data
= talloc_memdup(p
->mem_ctx
, regval_data_p(val
), data_len
)) )
8660 DEBUG(0,("talloc_memdup failed to allocate memory [data_len=%d] for data!\n",
8662 result
= WERR_NOMEM
;
8666 enum_values
[i
].data_len
= data_len
;
8668 /* keep track of the size of the array in bytes */
8670 needed
+= spoolss_size_printer_enum_values(&enum_values
[i
]);
8673 /* housekeeping information in the reply */
8675 r_u
->needed
= needed
;
8676 r_u
->returned
= num_entries
;
8678 if (needed
> in_size
) {
8679 result
= WERR_MORE_DATA
;
8683 /* copy data into the reply */
8685 r_u
->ctr
.size
= r_u
->needed
;
8686 r_u
->ctr
.size_of_array
= r_u
->returned
;
8687 r_u
->ctr
.values
= enum_values
;
8692 free_a_printer(&printer
, 2);
8697 /****************************************************************************
8698 ****************************************************************************/
8700 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1
*info
, char *name
)
8702 init_unistr(&info
->name
, name
);
8705 static WERROR
getprintprocessordirectory_level_1(UNISTR2
*name
,
8706 UNISTR2
*environment
,
8713 pstring short_archi
;
8714 PRINTPROCESSOR_DIRECTORY_1
*info
=NULL
;
8716 unistr2_to_ascii(long_archi
, environment
, sizeof(long_archi
)-1);
8718 if (get_short_archi(short_archi
, long_archi
)==False
)
8719 return WERR_INVALID_ENVIRONMENT
;
8721 if((info
=(PRINTPROCESSOR_DIRECTORY_1
*)malloc(sizeof(PRINTPROCESSOR_DIRECTORY_1
))) == NULL
)
8724 pstrcpy(path
, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
8726 fill_printprocessordirectory_1(info
, path
);
8728 *needed
+= spoolss_size_printprocessordirectory_info_1(info
);
8730 if (!alloc_buffer_size(buffer
, *needed
)) {
8732 return WERR_INSUFFICIENT_BUFFER
;
8735 smb_io_printprocessordirectory_1("", buffer
, info
, 0);
8739 if (*needed
> offered
)
8740 return WERR_INSUFFICIENT_BUFFER
;
8745 WERROR
_spoolss_getprintprocessordirectory(pipes_struct
*p
, SPOOL_Q_GETPRINTPROCESSORDIRECTORY
*q_u
, SPOOL_R_GETPRINTPROCESSORDIRECTORY
*r_u
)
8747 uint32 level
= q_u
->level
;
8748 NEW_BUFFER
*buffer
= NULL
;
8749 uint32 offered
= q_u
->offered
;
8750 uint32
*needed
= &r_u
->needed
;
8753 /* that's an [in out] buffer */
8754 spoolss_move_buffer(q_u
->buffer
, &r_u
->buffer
);
8755 buffer
= r_u
->buffer
;
8757 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
8763 result
= getprintprocessordirectory_level_1
8764 (&q_u
->name
, &q_u
->environment
, buffer
, offered
, needed
);
8766 result
= WERR_UNKNOWN_LEVEL
;
8774 WERROR
_spoolss_replyopenprinter(pipes_struct
*p
, SPOOL_Q_REPLYOPENPRINTER
*q_u
,
8775 SPOOL_R_REPLYOPENPRINTER
*r_u
)
8777 DEBUG(5,("_spoolss_replyopenprinter\n"));
8779 DEBUG(10, ("replyopenprinter for localprinter %d\n", q_u
->printer
));
8784 WERROR
_spoolss_replycloseprinter(pipes_struct
*p
, SPOOL_Q_REPLYCLOSEPRINTER
*q_u
,
8785 SPOOL_R_REPLYCLOSEPRINTER
*r_u
)
8787 DEBUG(5,("_spoolss_replycloseprinter\n"));