2
* Unix SMB/CIFS implementation.
3
* RPC Pipe client / server routines
4
* Copyright (C) Andrew Tridgell 1992-2000,
5
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6
* Copyright (C) Jean François Micouleau 1998-2000,
7
* Copyright (C) Jeremy Allison 2001-2002,
8
* Copyright (C) Gerald Carter 2000-2004,
9
* Copyright (C) Tim Potter 2001-2002.
10
* Copyright (C) Guenther Deschner 2009.
12
* This program is free software; you can redistribute it and/or modify
13
* it under the terms of the GNU General Public License as published by
14
* the Free Software Foundation; either version 3 of the License, or
15
* (at your option) any later version.
17
* This program is distributed in the hope that it will be useful,
18
* but WITHOUT ANY WARRANTY; without even the implied warranty of
19
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20
* GNU General Public License for more details.
22
* You should have received a copy of the GNU General Public License
23
* along with this program; if not, see <http://www.gnu.org/licenses/>.
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. */
30
#include "../librpc/gen_ndr/srv_spoolss.h"
31
#include "../librpc/gen_ndr/cli_spoolss.h"
33
/* macros stolen from s4 spoolss server */
34
#define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \
35
((info)?ndr_size_##fn(info, level, ic, 0):0)
37
#define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \
38
((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0)
40
#define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,ic,info,count) \
41
((info)?ndr_size_##fn##_info(mem_ctx, ic, count, info):0)
43
#define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
46
extern userdom_struct current_user_info;
49
#define DBGC_CLASS DBGC_RPC_SRV
51
#ifndef MAX_OPEN_PRINTER_EXS
52
#define MAX_OPEN_PRINTER_EXS 50
55
#define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
56
#define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
58
static Printer_entry *printers_list;
60
typedef struct _counter_printer_0 {
61
struct _counter_printer_0 *next;
62
struct _counter_printer_0 *prev;
68
static counter_printer_0 *counter_list;
70
static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
71
static uint32_t smb_connections = 0;
74
/* in printing/nt_printing.c */
76
extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
78
/* API table for Xcv Monitor functions */
80
struct xcv_api_table {
82
WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
85
/********************************************************************
86
* Canonicalize servername.
87
********************************************************************/
89
static const char *canon_servername(const char *servername)
91
const char *pservername = servername;
92
while (*pservername == '\\') {
98
/* translate between internal status numbers and NT status numbers */
99
static int nt_printj_status(int v)
105
return JOB_STATUS_PAUSED;
107
return JOB_STATUS_SPOOLING;
109
return JOB_STATUS_PRINTING;
111
return JOB_STATUS_ERROR;
113
return JOB_STATUS_DELETING;
115
return JOB_STATUS_OFFLINE;
117
return JOB_STATUS_PAPEROUT;
119
return JOB_STATUS_PRINTED;
121
return JOB_STATUS_DELETED;
123
return JOB_STATUS_BLOCKED_DEVQ;
124
case LPQ_USER_INTERVENTION:
125
return JOB_STATUS_USER_INTERVENTION;
130
static int nt_printq_status(int v)
134
return PRINTER_STATUS_PAUSED;
143
static void prune_printername_cache(void);
145
/***************************************************************************
146
Disconnect from the client
147
****************************************************************************/
149
static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
155
* Tell the specific printing tdb we no longer want messages for this printer
156
* by deregistering our PID.
159
if (!print_notify_deregister_pid(snum))
160
DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
162
/* weird if the test succeds !!! */
163
if (smb_connections==0) {
164
DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
168
status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
171
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
172
DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
173
win_errstr(result)));
175
/* if it's the last connection, deconnect the IPC$ share */
176
if (smb_connections==1) {
178
cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
179
notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
181
messaging_deregister(smbd_messaging_context(),
182
MSG_PRINTER_NOTIFY2, NULL);
184
/* Tell the connections db we're no longer interested in
185
* printer notify messages. */
187
register_message_flags(false, FLAG_MSG_PRINT_NOTIFY);
193
/****************************************************************************
194
Functions to free a printer entry datastruct.
195
****************************************************************************/
197
static int printer_entry_destructor(Printer_entry *Printer)
199
if (Printer->notify.client_connected == true) {
202
if ( Printer->printer_type == SPLHND_SERVER) {
204
srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
205
} else if (Printer->printer_type == SPLHND_PRINTER) {
206
snum = print_queue_snum(Printer->sharename);
208
srv_spoolss_replycloseprinter(snum,
209
&Printer->notify.client_hnd);
213
Printer->notify.flags=0;
214
Printer->notify.options=0;
215
Printer->notify.localmachine[0]='\0';
216
Printer->notify.printerlocal=0;
217
TALLOC_FREE(Printer->notify.option);
218
Printer->notify.client_connected = false;
220
free_nt_devicemode( &Printer->nt_devmode );
221
free_a_printer( &Printer->printer_info, 2 );
223
/* Remove from the internal list. */
224
DLIST_REMOVE(printers_list, Printer);
228
/****************************************************************************
229
find printer index by handle
230
****************************************************************************/
232
static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
233
struct policy_handle *hnd)
235
Printer_entry *find_printer = NULL;
237
if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
238
DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
245
/****************************************************************************
246
Close printer index by handle.
247
****************************************************************************/
249
static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
251
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
254
DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
259
close_policy_hnd(p, hnd);
264
/****************************************************************************
265
Delete a printer given a handle.
266
****************************************************************************/
268
static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
270
char *cmd = lp_deleteprinter_cmd();
271
char *command = NULL;
273
SE_PRIV se_printop = SE_PRINT_OPERATOR;
274
bool is_print_op = false;
276
/* can't fail if we don't try */
281
command = talloc_asprintf(ctx,
288
is_print_op = user_has_privileges( token, &se_printop );
290
DEBUG(10,("Running [%s]\n", command));
292
/********** BEGIN SePrintOperatorPrivlege BLOCK **********/
297
if ( (ret = smbrun(command, NULL)) == 0 ) {
298
/* Tell everyone we updated smb.conf. */
299
message_send_all(smbd_messaging_context(),
300
MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
306
/********** END SePrintOperatorPrivlege BLOCK **********/
308
DEBUGADD(10,("returned [%d]\n", ret));
310
TALLOC_FREE(command);
313
return WERR_BADFID; /* What to return here? */
315
/* go ahead and re-read the services immediately */
317
reload_services(false);
320
if ( lp_servicenumber( sharename ) < 0 )
321
return WERR_ACCESS_DENIED;
326
/****************************************************************************
327
Delete a printer given a handle.
328
****************************************************************************/
330
static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
332
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
336
DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
342
* It turns out that Windows allows delete printer on a handle
343
* opened by an admin user, then used on a pipe handle created
344
* by an anonymous user..... but they're working on security.... riiight !
348
if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
349
DEBUG(3, ("delete_printer_handle: denied by handle\n"));
350
return WERR_ACCESS_DENIED;
353
/* this does not need a become root since the access check has been
354
done on the handle already */
356
if (del_a_printer( Printer->sharename ) != 0) {
357
DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
361
result = delete_printer_hook(p->mem_ctx, p->server_info->ptok,
363
if (!W_ERROR_IS_OK(result)) {
366
prune_printername_cache();
370
/****************************************************************************
371
Return the snum of a printer corresponding to an handle.
372
****************************************************************************/
374
static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
375
int *number, struct share_params **params)
377
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
380
DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
385
switch (Printer->printer_type) {
387
DEBUG(4,("short name:%s\n", Printer->sharename));
388
*number = print_queue_snum(Printer->sharename);
389
return (*number != -1);
397
/****************************************************************************
398
Set printer handle type.
399
Check if it's \\server or \\server\printer
400
****************************************************************************/
402
static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
404
DEBUG(3,("Setting printer type=%s\n", handlename));
406
if ( strlen(handlename) < 3 ) {
407
DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
411
/* it's a print server */
412
if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
413
DEBUGADD(4,("Printer is a print server\n"));
414
Printer->printer_type = SPLHND_SERVER;
416
/* it's a printer (set_printer_hnd_name() will handle port monitors */
418
DEBUGADD(4,("Printer is a printer\n"));
419
Printer->printer_type = SPLHND_PRINTER;
425
static void prune_printername_cache_fn(const char *key, const char *value,
426
time_t timeout, void *private_data)
431
static void prune_printername_cache(void)
433
gencache_iterate(prune_printername_cache_fn, NULL, "PRINTERNAME/*");
436
/****************************************************************************
437
Set printer handle name.. Accept names like \\server, \\server\printer,
438
\\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
439
the MSDN docs regarding OpenPrinter() for details on the XcvData() and
440
XcvDataPort() interface.
441
****************************************************************************/
443
static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename)
446
int n_services=lp_numservices();
447
char *aprinter, *printername;
448
const char *servername;
451
NT_PRINTER_INFO_LEVEL *printer = NULL;
455
* Hopefully nobody names his printers like this. Maybe \ or ,
456
* are illegal in printer names even?
458
const char printer_not_found[] = "Printer \\, !@#$%^&*( not found";
462
DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
463
(unsigned long)strlen(handlename)));
465
aprinter = CONST_DISCARD(char *, handlename);
466
if ( *handlename == '\\' ) {
467
servername = canon_servername(handlename);
468
if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
473
servername = global_myname();
476
/* save the servername to fill in replies on this handle */
478
if ( !is_myname_or_ipaddr( servername ) )
481
fstrcpy( Printer->servername, servername );
483
if ( Printer->printer_type == SPLHND_SERVER )
486
if ( Printer->printer_type != SPLHND_PRINTER )
489
DEBUGADD(5, ("searching for [%s]\n", aprinter ));
491
/* check for the Port Monitor Interface */
493
if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
494
Printer->printer_type = SPLHND_PORTMON_TCP;
495
fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
498
else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
499
Printer->printer_type = SPLHND_PORTMON_LOCAL;
500
fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
505
* With hundreds of printers, the "for" loop iterating all
506
* shares can be quite expensive, as it is done on every
507
* OpenPrinter. The loop maps "aprinter" to "sname", the
508
* result of which we cache in gencache.
511
cache_key = talloc_asprintf(talloc_tos(), "PRINTERNAME/%s",
513
if ((cache_key != NULL) && gencache_get(cache_key, &tmp, NULL)) {
515
found = (strcmp(tmp, printer_not_found) != 0);
517
DEBUG(4, ("Printer %s not found\n", aprinter));
525
/* Search all sharenames first as this is easier than pulling
526
the printer_info_2 off of disk. Don't use find_service() since
527
that calls out to map_username() */
529
/* do another loop to look for printernames */
531
for (snum=0; !found && snum<n_services; snum++) {
533
/* no point going on if this is not a printer */
535
if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
538
fstrcpy(sname, lp_servicename(snum));
539
if ( strequal( aprinter, sname ) ) {
544
/* no point looking up the printer object if
545
we aren't allowing printername != sharename */
547
if ( lp_force_printername(snum) )
550
fstrcpy(sname, lp_servicename(snum));
554
/* This call doesn't fill in the location or comment from
555
* a CUPS server for efficiency with large numbers of printers.
559
result = get_a_printer_search( NULL, &printer, 2, sname );
560
if ( !W_ERROR_IS_OK(result) ) {
561
DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
562
sname, win_errstr(result)));
566
/* printername is always returned as \\server\printername */
567
if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
568
DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
569
printer->info_2->printername));
570
free_a_printer( &printer, 2);
576
if ( strequal(printername, aprinter) ) {
577
free_a_printer( &printer, 2);
582
DEBUGADD(10, ("printername: %s\n", printername));
584
free_a_printer( &printer, 2);
587
free_a_printer( &printer, 2);
590
if (cache_key != NULL) {
591
gencache_set(cache_key, printer_not_found,
593
TALLOC_FREE(cache_key);
595
DEBUGADD(4,("Printer not found\n"));
599
if (cache_key != NULL) {
600
gencache_set(cache_key, sname, time(NULL)+300);
601
TALLOC_FREE(cache_key);
604
DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
606
fstrcpy(Printer->sharename, sname);
611
/****************************************************************************
612
Find first available printer slot. creates a printer handle for you.
613
****************************************************************************/
615
static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
616
const char *name, uint32_t access_granted)
618
Printer_entry *new_printer;
620
DEBUG(10,("open_printer_hnd: name [%s]\n", name));
622
new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
623
if (new_printer == NULL) {
626
talloc_set_destructor(new_printer, printer_entry_destructor);
628
if (!create_policy_hnd(p, hnd, new_printer)) {
629
TALLOC_FREE(new_printer);
633
/* Add to the internal list. */
634
DLIST_ADD(printers_list, new_printer);
636
new_printer->notify.option=NULL;
638
if (!set_printer_hnd_printertype(new_printer, name)) {
639
close_printer_handle(p, hnd);
643
if (!set_printer_hnd_name(new_printer, name)) {
644
close_printer_handle(p, hnd);
648
new_printer->access_granted = access_granted;
650
DEBUG(5, ("%d printer handles active\n",
651
(int)num_pipe_handles(p->pipe_handles)));
656
/***************************************************************************
657
check to see if the client motify handle is monitoring the notification
658
given by (notify_type, notify_field).
659
**************************************************************************/
661
static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
662
uint16_t notify_field)
667
static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
668
uint16_t notify_field)
670
struct spoolss_NotifyOption *option = p->notify.option;
674
* Flags should always be zero when the change notify
675
* is registered by the client's spooler. A user Win32 app
676
* might use the flags though instead of the NOTIFY_OPTION_INFO
685
return is_monitoring_event_flags(
686
p->notify.flags, notify_type, notify_field);
688
for (i = 0; i < option->count; i++) {
690
/* Check match for notify_type */
692
if (option->types[i].type != notify_type)
695
/* Check match for field */
697
for (j = 0; j < option->types[i].count; j++) {
698
if (option->types[i].fields[j].field == notify_field) {
704
DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
705
p->servername, p->sharename, notify_type, notify_field));
710
#define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
711
_data->data.integer[0] = _integer; \
712
_data->data.integer[1] = 0;
715
#define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
716
_data->data.string.string = talloc_strdup(mem_ctx, _p); \
717
if (!_data->data.string.string) {\
718
_data->data.string.size = 0; \
720
_data->data.string.size = strlen_m_term(_p) * 2;
722
#define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
723
_data->data.devmode.devmode = _devmode;
725
#define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
726
_data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
727
if (!_data->data.sd.sd) { \
728
_data->data.sd.sd_size = 0; \
730
_data->data.sd.sd_size = _size;
732
static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
737
struct spoolss_Time st;
741
if (!init_systemtime(&st, t)) {
745
p = talloc_array(mem_ctx, char, len);
751
* Systemtime must be linearized as a set of UINT16's.
752
* Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
755
SSVAL(p, 0, st.year);
756
SSVAL(p, 2, st.month);
757
SSVAL(p, 4, st.day_of_week);
759
SSVAL(p, 8, st.hour);
760
SSVAL(p, 10, st.minute);
761
SSVAL(p, 12, st.second);
762
SSVAL(p, 14, st.millisecond);
768
/* Convert a notification message to a struct spoolss_Notify */
770
static void notify_one_value(struct spoolss_notify_msg *msg,
771
struct spoolss_Notify *data,
774
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
777
static void notify_string(struct spoolss_notify_msg *msg,
778
struct spoolss_Notify *data,
781
/* The length of the message includes the trailing \0 */
783
data->data.string.size = msg->len * 2;
784
data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
785
if (!data->data.string.string) {
786
data->data.string.size = 0;
791
static void notify_system_time(struct spoolss_notify_msg *msg,
792
struct spoolss_Notify *data,
795
data->data.string.string = NULL;
796
data->data.string.size = 0;
798
if (msg->len != sizeof(time_t)) {
799
DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
804
init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
805
&data->data.string.string,
806
&data->data.string.size);
809
struct notify2_message_table {
811
void (*fn)(struct spoolss_notify_msg *msg,
812
struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
815
static struct notify2_message_table printer_notify_table[] = {
816
/* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
817
/* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
818
/* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
819
/* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
820
/* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
821
/* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
822
/* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
823
/* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
824
/* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
825
/* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
826
/* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
827
/* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
828
/* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
829
/* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
830
/* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
831
/* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
832
/* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
833
/* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
834
/* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
837
static struct notify2_message_table job_notify_table[] = {
838
/* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
839
/* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
840
/* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
841
/* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
842
/* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
843
/* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
844
/* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
845
/* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
846
/* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
847
/* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
848
/* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
849
/* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
850
/* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
851
/* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
852
/* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
853
/* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
854
/* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
855
/* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
856
/* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
857
/* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
858
/* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
859
/* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
860
/* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
861
/* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
865
/***********************************************************************
866
Allocate talloc context for container object
867
**********************************************************************/
869
static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
874
ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
879
/***********************************************************************
880
release all allocated memory and zero out structure
881
**********************************************************************/
883
static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
889
talloc_destroy(ctr->ctx);
896
/***********************************************************************
897
**********************************************************************/
899
static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
907
/***********************************************************************
908
**********************************************************************/
910
static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
912
if ( !ctr || !ctr->msg_groups )
915
if ( idx >= ctr->num_groups )
918
return &ctr->msg_groups[idx];
922
/***********************************************************************
923
How many groups of change messages do we have ?
924
**********************************************************************/
926
static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
931
return ctr->num_groups;
934
/***********************************************************************
935
Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
936
**********************************************************************/
938
static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
940
SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
941
SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
942
SPOOLSS_NOTIFY_MSG *msg_list = NULL;
948
/* loop over all groups looking for a matching printer name */
950
for ( i=0; i<ctr->num_groups; i++ ) {
951
if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
955
/* add a new group? */
957
if ( i == ctr->num_groups ) {
960
if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
961
DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
964
ctr->msg_groups = groups;
966
/* clear the new entry and set the printer name */
968
ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
969
fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
972
/* add the change messages; 'i' is the correct index now regardless */
974
msg_grp = &ctr->msg_groups[i];
978
if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
979
DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
982
msg_grp->msgs = msg_list;
984
new_slot = msg_grp->num_msgs-1;
985
memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
987
/* need to allocate own copy of data */
990
msg_grp->msgs[new_slot].notify.data = (char *)
991
TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
993
return ctr->num_groups;
996
/***********************************************************************
997
Send a change notication message on all handles which have a call
999
**********************************************************************/
1001
static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
1004
TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
1005
SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
1006
SPOOLSS_NOTIFY_MSG *messages;
1007
int sending_msg_count;
1010
DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
1014
messages = msg_group->msgs;
1017
DEBUG(5,("send_notify2_changes() called with no messages!\n"));
1021
DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
1023
/* loop over all printers */
1025
for (p = printers_list; p; p = p->next) {
1026
struct spoolss_Notify *notifies;
1031
/* Is there notification on this handle? */
1033
if ( !p->notify.client_connected )
1036
DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1038
/* For this printer? Print servers always receive
1041
if ( ( p->printer_type == SPLHND_PRINTER ) &&
1042
( !strequal(msg_group->printername, p->sharename) ) )
1045
DEBUG(10,("Our printer\n"));
1047
/* allocate the max entries possible */
1049
notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1054
/* build the array of change notifications */
1056
sending_msg_count = 0;
1058
for ( i=0; i<msg_group->num_msgs; i++ ) {
1059
SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1061
/* Are we monitoring this event? */
1063
if (!is_monitoring_event(p, msg->type, msg->field))
1066
sending_msg_count++;
1069
DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1070
msg->type, msg->field, p->sharename));
1073
* if the is a printer notification handle and not a job notification
1074
* type, then set the id to 0. Other wise just use what was specified
1077
* When registering change notification on a print server handle
1078
* we always need to send back the id (snum) matching the printer
1079
* for which the change took place. For change notify registered
1080
* on a printer handle, this does not matter and the id should be 0.
1085
if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1091
/* Convert unix jobid to smb jobid */
1093
if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1094
id = sysjob_to_jobid(msg->id);
1097
DEBUG(3, ("no such unix jobid %d\n", msg->id));
1102
construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1105
case PRINTER_NOTIFY_TYPE:
1106
if ( printer_notify_table[msg->field].fn )
1107
printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1110
case JOB_NOTIFY_TYPE:
1111
if ( job_notify_table[msg->field].fn )
1112
job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1116
DEBUG(5, ("Unknown notification type %d\n", msg->type));
1123
if ( sending_msg_count ) {
1126
union spoolss_ReplyPrinterInfo info;
1127
struct spoolss_NotifyInfo info0;
1128
uint32_t reply_result;
1130
info0.version = 0x2;
1131
info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1132
info0.count = count;
1133
info0.notifies = notifies;
1135
info.info0 = &info0;
1137
status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1138
&p->notify.client_hnd,
1139
p->notify.change, /* color */
1142
0, /* reply_type, must be 0 */
1145
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1146
DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1147
notify_cli_pipe->srv_name_slash,
1150
switch (reply_result) {
1153
case PRINTER_NOTIFY_INFO_DISCARDED:
1154
case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1155
case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1164
DEBUG(8,("send_notify2_changes: Exit...\n"));
1168
/***********************************************************************
1169
**********************************************************************/
1171
static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1174
uint32_t tv_sec, tv_usec;
1177
/* Unpack message */
1179
offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1182
offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1184
&msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1187
tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1188
&msg->notify.value[0], &msg->notify.value[1]);
1190
tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1191
&msg->len, &msg->notify.data);
1193
DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1194
msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1196
tv->tv_sec = tv_sec;
1197
tv->tv_usec = tv_usec;
1200
DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1201
msg->notify.value[1]));
1203
dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1208
/********************************************************************
1209
Receive a notify2 message list
1210
********************************************************************/
1212
static void receive_notify2_message_list(struct messaging_context *msg,
1215
struct server_id server_id,
1218
size_t msg_count, i;
1219
char *buf = (char *)data->data;
1222
SPOOLSS_NOTIFY_MSG notify;
1223
SPOOLSS_NOTIFY_MSG_CTR messages;
1226
if (data->length < 4) {
1227
DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1231
msg_count = IVAL(buf, 0);
1234
DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1236
if (msg_count == 0) {
1237
DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1241
/* initialize the container */
1243
ZERO_STRUCT( messages );
1244
notify_msg_ctr_init( &messages );
1247
* build message groups for each printer identified
1248
* in a change_notify msg. Remember that a PCN message
1249
* includes the handle returned for the srv_spoolss_replyopenprinter()
1250
* call. Therefore messages are grouped according to printer handle.
1253
for ( i=0; i<msg_count; i++ ) {
1254
struct timeval msg_tv;
1256
if (msg_ptr + 4 - buf > data->length) {
1257
DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1261
msg_len = IVAL(msg_ptr,0);
1264
if (msg_ptr + msg_len - buf > data->length) {
1265
DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1269
/* unpack messages */
1271
ZERO_STRUCT( notify );
1272
notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1275
/* add to correct list in container */
1277
notify_msg_ctr_addmsg( &messages, ¬ify );
1279
/* free memory that might have been allocated by notify2_unpack_msg() */
1281
if ( notify.len != 0 )
1282
SAFE_FREE( notify.notify.data );
1285
/* process each group of messages */
1287
num_groups = notify_msg_ctr_numgroups( &messages );
1288
for ( i=0; i<num_groups; i++ )
1289
send_notify2_changes( &messages, i );
1294
DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1295
(uint32_t)msg_count ));
1297
notify_msg_ctr_destroy( &messages );
1302
/********************************************************************
1303
Send a message to ourself about new driver being installed
1304
so we can upgrade the information for each printer bound to this
1306
********************************************************************/
1308
static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1310
int len = strlen(drivername);
1315
DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1318
messaging_send_buf(smbd_messaging_context(), procid_self(),
1319
MSG_PRINTER_DRVUPGRADE,
1320
(uint8_t *)drivername, len+1);
1325
/**********************************************************************
1326
callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1327
over all printers, upgrading ones as necessary
1328
**********************************************************************/
1330
void do_drv_upgrade_printer(struct messaging_context *msg,
1333
struct server_id server_id,
1338
int n_services = lp_numservices();
1341
len = MIN(data->length,sizeof(drivername)-1);
1342
strncpy(drivername, (const char *)data->data, len);
1344
DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1346
/* Iterate the printer list */
1348
for (snum=0; snum<n_services; snum++)
1350
if (lp_snum_ok(snum) && lp_print_ok(snum) )
1353
NT_PRINTER_INFO_LEVEL *printer = NULL;
1355
result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1356
if (!W_ERROR_IS_OK(result))
1359
if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1361
DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1363
/* all we care about currently is the change_id */
1365
result = mod_a_printer(printer, 2);
1366
if (!W_ERROR_IS_OK(result)) {
1367
DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1368
win_errstr(result)));
1372
free_a_printer(&printer, 2);
1379
/********************************************************************
1380
Update the cache for all printq's with a registered client
1382
********************************************************************/
1384
void update_monitored_printq_cache( void )
1386
Printer_entry *printer = printers_list;
1389
/* loop through all printers and update the cache where
1390
client_connected == true */
1393
if ( (printer->printer_type == SPLHND_PRINTER)
1394
&& printer->notify.client_connected )
1396
snum = print_queue_snum(printer->sharename);
1397
print_queue_status( snum, NULL, NULL );
1400
printer = printer->next;
1405
/********************************************************************
1406
Send a message to ourself about new driver being installed
1407
so we can upgrade the information for each printer bound to this
1409
********************************************************************/
1411
static bool srv_spoolss_reset_printerdata(char* drivername)
1413
int len = strlen(drivername);
1418
DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1421
messaging_send_buf(smbd_messaging_context(), procid_self(),
1422
MSG_PRINTERDATA_INIT_RESET,
1423
(uint8_t *)drivername, len+1);
1428
/**********************************************************************
1429
callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1430
over all printers, resetting printer data as neessary
1431
**********************************************************************/
1433
void reset_all_printerdata(struct messaging_context *msg,
1436
struct server_id server_id,
1441
int n_services = lp_numservices();
1444
len = MIN( data->length, sizeof(drivername)-1 );
1445
strncpy( drivername, (const char *)data->data, len );
1447
DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1449
/* Iterate the printer list */
1451
for ( snum=0; snum<n_services; snum++ )
1453
if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1456
NT_PRINTER_INFO_LEVEL *printer = NULL;
1458
result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1459
if ( !W_ERROR_IS_OK(result) )
1463
* if the printer is bound to the driver,
1464
* then reset to the new driver initdata
1467
if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1469
DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1471
if ( !set_driver_init(printer, 2) ) {
1472
DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1473
printer->info_2->printername, printer->info_2->drivername));
1476
result = mod_a_printer( printer, 2 );
1477
if ( !W_ERROR_IS_OK(result) ) {
1478
DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1479
get_dos_error_msg(result)));
1483
free_a_printer( &printer, 2 );
1492
/****************************************************************
1493
_spoolss_OpenPrinter
1494
****************************************************************/
1496
WERROR _spoolss_OpenPrinter(pipes_struct *p,
1497
struct spoolss_OpenPrinter *r)
1499
struct spoolss_OpenPrinterEx e;
1502
ZERO_STRUCT(e.in.userlevel);
1504
e.in.printername = r->in.printername;
1505
e.in.datatype = r->in.datatype;
1506
e.in.devmode_ctr = r->in.devmode_ctr;
1507
e.in.access_mask = r->in.access_mask;
1510
e.out.handle = r->out.handle;
1512
werr = _spoolss_OpenPrinterEx(p, &e);
1514
if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1515
/* OpenPrinterEx returns this for a bad
1516
* printer name. We must return WERR_INVALID_PRINTER_NAME
1519
werr = WERR_INVALID_PRINTER_NAME;
1525
/********************************************************************
1526
********************************************************************/
1528
bool convert_devicemode(const char *printername,
1529
const struct spoolss_DeviceMode *devmode,
1530
NT_DEVICEMODE **pp_nt_devmode)
1532
NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1535
* Ensure nt_devmode is a valid pointer
1536
* as we will be overwriting it.
1539
if (nt_devmode == NULL) {
1540
DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1541
if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1545
fstrcpy(nt_devmode->devicename, devmode->devicename);
1546
fstrcpy(nt_devmode->formname, devmode->formname);
1548
nt_devmode->devicename[31] = '\0';
1549
nt_devmode->formname[31] = '\0';
1551
nt_devmode->specversion = devmode->specversion;
1552
nt_devmode->driverversion = devmode->driverversion;
1553
nt_devmode->size = devmode->size;
1554
nt_devmode->fields = devmode->fields;
1555
nt_devmode->orientation = devmode->orientation;
1556
nt_devmode->papersize = devmode->papersize;
1557
nt_devmode->paperlength = devmode->paperlength;
1558
nt_devmode->paperwidth = devmode->paperwidth;
1559
nt_devmode->scale = devmode->scale;
1560
nt_devmode->copies = devmode->copies;
1561
nt_devmode->defaultsource = devmode->defaultsource;
1562
nt_devmode->printquality = devmode->printquality;
1563
nt_devmode->color = devmode->color;
1564
nt_devmode->duplex = devmode->duplex;
1565
nt_devmode->yresolution = devmode->yresolution;
1566
nt_devmode->ttoption = devmode->ttoption;
1567
nt_devmode->collate = devmode->collate;
1569
nt_devmode->logpixels = devmode->logpixels;
1570
nt_devmode->bitsperpel = devmode->bitsperpel;
1571
nt_devmode->pelswidth = devmode->pelswidth;
1572
nt_devmode->pelsheight = devmode->pelsheight;
1573
nt_devmode->displayflags = devmode->displayflags;
1574
nt_devmode->displayfrequency = devmode->displayfrequency;
1575
nt_devmode->icmmethod = devmode->icmmethod;
1576
nt_devmode->icmintent = devmode->icmintent;
1577
nt_devmode->mediatype = devmode->mediatype;
1578
nt_devmode->dithertype = devmode->dithertype;
1579
nt_devmode->reserved1 = devmode->reserved1;
1580
nt_devmode->reserved2 = devmode->reserved2;
1581
nt_devmode->panningwidth = devmode->panningwidth;
1582
nt_devmode->panningheight = devmode->panningheight;
1585
* Only change private and driverextra if the incoming devmode
1586
* has a new one. JRA.
1589
if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1590
SAFE_FREE(nt_devmode->nt_dev_private);
1591
nt_devmode->driverextra = devmode->__driverextra_length;
1592
if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL)
1594
memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1597
*pp_nt_devmode = nt_devmode;
1602
/****************************************************************
1603
_spoolss_OpenPrinterEx
1604
****************************************************************/
1606
WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1607
struct spoolss_OpenPrinterEx *r)
1610
Printer_entry *Printer=NULL;
1612
if (!r->in.printername) {
1613
return WERR_INVALID_PARAM;
1616
/* some sanity check because you can open a printer or a print server */
1617
/* aka: \\server\printer or \\server */
1619
DEBUGADD(3,("checking name: %s\n", r->in.printername));
1621
if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1622
ZERO_STRUCTP(r->out.handle);
1623
return WERR_INVALID_PARAM;
1626
Printer = find_printer_index_by_hnd(p, r->out.handle);
1628
DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1629
"handle we created for printer %s\n", r->in.printername));
1630
close_printer_handle(p, r->out.handle);
1631
ZERO_STRUCTP(r->out.handle);
1632
return WERR_INVALID_PARAM;
1636
* First case: the user is opening the print server:
1638
* Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1639
* client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1641
* Then both Win2k and WinNT clients try an OpenPrinterEx with
1642
* SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1643
* or if the user is listed in the smb.conf printer admin parameter.
1645
* Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1646
* client view printer folder, but does not show the MSAPW.
1648
* Note: this test needs code to check access rights here too. Jeremy
1649
* could you look at this?
1651
* Second case: the user is opening a printer:
1652
* NT doesn't let us connect to a printer if the connecting user
1653
* doesn't have print permission.
1655
* Third case: user is opening a Port Monitor
1656
* access checks same as opening a handle to the print server.
1659
switch (Printer->printer_type )
1662
case SPLHND_PORTMON_TCP:
1663
case SPLHND_PORTMON_LOCAL:
1664
/* Printserver handles use global struct... */
1668
/* Map standard access rights to object specific access rights */
1670
se_map_standard(&r->in.access_mask,
1671
&printserver_std_mapping);
1673
/* Deny any object specific bits that don't apply to print
1674
servers (i.e printer and job specific bits) */
1676
r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1678
if (r->in.access_mask &
1679
~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1680
DEBUG(3, ("access DENIED for non-printserver bits\n"));
1681
close_printer_handle(p, r->out.handle);
1682
ZERO_STRUCTP(r->out.handle);
1683
return WERR_ACCESS_DENIED;
1686
/* Allow admin access */
1688
if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1690
SE_PRIV se_printop = SE_PRINT_OPERATOR;
1692
if (!lp_ms_add_printer_wizard()) {
1693
close_printer_handle(p, r->out.handle);
1694
ZERO_STRUCTP(r->out.handle);
1695
return WERR_ACCESS_DENIED;
1698
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1699
and not a printer admin, then fail */
1701
if ((p->server_info->utok.uid != sec_initial_uid()) &&
1702
!user_has_privileges(p->server_info->ptok,
1704
!token_contains_name_in_list(
1705
uidtoname(p->server_info->utok.uid),
1706
pdb_get_domain(p->server_info->sam_account),
1708
p->server_info->ptok,
1709
lp_printer_admin(snum))) {
1710
close_printer_handle(p, r->out.handle);
1711
ZERO_STRUCTP(r->out.handle);
1712
return WERR_ACCESS_DENIED;
1715
r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1719
r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1722
DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1723
? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1725
/* We fall through to return WERR_OK */
1728
case SPLHND_PRINTER:
1729
/* NT doesn't let us connect to a printer if the connecting user
1730
doesn't have print permission. */
1732
if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1733
close_printer_handle(p, r->out.handle);
1734
ZERO_STRUCTP(r->out.handle);
1738
if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1739
r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1742
se_map_standard(&r->in.access_mask, &printer_std_mapping);
1744
/* map an empty access mask to the minimum access mask */
1745
if (r->in.access_mask == 0x0)
1746
r->in.access_mask = PRINTER_ACCESS_USE;
1749
* If we are not serving the printer driver for this printer,
1750
* map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1751
* will keep NT clients happy --jerry
1754
if (lp_use_client_driver(snum)
1755
&& (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1757
r->in.access_mask = PRINTER_ACCESS_USE;
1760
/* check smb.conf parameters and the the sec_desc */
1762
if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1763
DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1764
ZERO_STRUCTP(r->out.handle);
1765
return WERR_ACCESS_DENIED;
1768
if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1769
p->server_info->ptok, snum) ||
1770
!print_access_check(p->server_info, snum,
1771
r->in.access_mask)) {
1772
DEBUG(3, ("access DENIED for printer open\n"));
1773
close_printer_handle(p, r->out.handle);
1774
ZERO_STRUCTP(r->out.handle);
1775
return WERR_ACCESS_DENIED;
1778
if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1779
DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1780
close_printer_handle(p, r->out.handle);
1781
ZERO_STRUCTP(r->out.handle);
1782
return WERR_ACCESS_DENIED;
1785
if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1786
r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1788
r->in.access_mask = PRINTER_ACCESS_USE;
1790
DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1791
? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1796
/* sanity check to prevent programmer error */
1797
ZERO_STRUCTP(r->out.handle);
1801
Printer->access_granted = r->in.access_mask;
1804
* If the client sent a devmode in the OpenPrinter() call, then
1805
* save it here in case we get a job submission on this handle
1808
if ((Printer->printer_type != SPLHND_SERVER) &&
1809
r->in.devmode_ctr.devmode) {
1810
convert_devicemode(Printer->sharename,
1811
r->in.devmode_ctr.devmode,
1812
&Printer->nt_devmode);
1815
#if 0 /* JERRY -- I'm doubtful this is really effective */
1816
/* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1817
optimization in Windows 2000 clients --jerry */
1819
if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1820
&& (RA_WIN2K == get_remote_arch()) )
1822
DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1823
sys_usleep( 500000 );
1830
/****************************************************************************
1831
****************************************************************************/
1833
static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1834
NT_PRINTER_INFO_LEVEL_2 *d)
1836
DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1842
d->attributes = r->attributes;
1843
d->priority = r->priority;
1844
d->default_priority = r->defaultpriority;
1845
d->starttime = r->starttime;
1846
d->untiltime = r->untiltime;
1847
d->status = r->status;
1848
d->cjobs = r->cjobs;
1850
fstrcpy(d->servername, r->servername);
1851
fstrcpy(d->printername, r->printername);
1852
fstrcpy(d->sharename, r->sharename);
1853
fstrcpy(d->portname, r->portname);
1854
fstrcpy(d->drivername, r->drivername);
1855
slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1856
fstrcpy(d->location, r->location);
1857
fstrcpy(d->sepfile, r->sepfile);
1858
fstrcpy(d->printprocessor, r->printprocessor);
1859
fstrcpy(d->datatype, r->datatype);
1860
fstrcpy(d->parameters, r->parameters);
1865
/****************************************************************************
1866
****************************************************************************/
1868
static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr *info_ctr,
1869
NT_PRINTER_INFO_LEVEL *printer)
1873
switch (info_ctr->level) {
1875
/* allocate memory if needed. Messy because
1876
convert_printer_info is used to update an existing
1877
printer or build a new one */
1879
if (!printer->info_2) {
1880
printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1881
if (!printer->info_2) {
1882
DEBUG(0,("convert_printer_info: "
1883
"talloc() failed!\n"));
1888
ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1890
printer->info_2->setuptime = time(NULL);
1897
/****************************************************************
1898
_spoolss_ClosePrinter
1899
****************************************************************/
1901
WERROR _spoolss_ClosePrinter(pipes_struct *p,
1902
struct spoolss_ClosePrinter *r)
1904
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1906
if (Printer && Printer->document_started) {
1907
struct spoolss_EndDocPrinter e;
1909
e.in.handle = r->in.handle;
1911
_spoolss_EndDocPrinter(p, &e);
1914
if (!close_printer_handle(p, r->in.handle))
1917
/* clear the returned printer handle. Observed behavior
1918
from Win2k server. Don't think this really matters.
1919
Previous code just copied the value of the closed
1922
ZERO_STRUCTP(r->out.handle);
1927
/****************************************************************
1928
_spoolss_DeletePrinter
1929
****************************************************************/
1931
WERROR _spoolss_DeletePrinter(pipes_struct *p,
1932
struct spoolss_DeletePrinter *r)
1934
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1937
if (Printer && Printer->document_started) {
1938
struct spoolss_EndDocPrinter e;
1940
e.in.handle = r->in.handle;
1942
_spoolss_EndDocPrinter(p, &e);
1945
result = delete_printer_handle(p, r->in.handle);
1947
update_c_setprinter(false);
1952
/*******************************************************************
1953
* static function to lookup the version id corresponding to an
1954
* long architecture string
1955
******************************************************************/
1957
static const struct print_architecture_table_node archi_table[]= {
1959
{"Windows 4.0", SPL_ARCH_WIN40, 0 },
1960
{"Windows NT x86", SPL_ARCH_W32X86, 2 },
1961
{"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1962
{"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1963
{"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1964
{"Windows IA64", SPL_ARCH_IA64, 3 },
1965
{"Windows x64", SPL_ARCH_X64, 3 },
1969
static int get_version_id(const char *arch)
1973
for (i=0; archi_table[i].long_archi != NULL; i++)
1975
if (strcmp(arch, archi_table[i].long_archi) == 0)
1976
return (archi_table[i].version);
1982
/****************************************************************
1983
_spoolss_DeletePrinterDriver
1984
****************************************************************/
1986
WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1987
struct spoolss_DeletePrinterDriver *r)
1990
struct spoolss_DriverInfo8 *info = NULL;
1991
struct spoolss_DriverInfo8 *info_win2k = NULL;
1994
WERROR status_win2k = WERR_ACCESS_DENIED;
1995
SE_PRIV se_printop = SE_PRINT_OPERATOR;
1997
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1998
and not a printer admin, then fail */
2000
if ( (p->server_info->utok.uid != sec_initial_uid())
2001
&& !user_has_privileges(p->server_info->ptok, &se_printop )
2002
&& !token_contains_name_in_list(
2003
uidtoname(p->server_info->utok.uid),
2004
pdb_get_domain(p->server_info->sam_account),
2006
p->server_info->ptok,
2007
lp_printer_admin(-1)) )
2009
return WERR_ACCESS_DENIED;
2012
/* check that we have a valid driver name first */
2014
if ((version = get_version_id(r->in.architecture)) == -1)
2015
return WERR_INVALID_ENVIRONMENT;
2017
if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2021
/* try for Win2k driver if "Windows NT x86" */
2023
if ( version == 2 ) {
2025
if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
2030
status = WERR_UNKNOWN_PRINTER_DRIVER;
2034
/* otherwise it was a failure */
2036
status = WERR_UNKNOWN_PRINTER_DRIVER;
2042
if (printer_driver_in_use(info)) {
2043
status = WERR_PRINTER_DRIVER_IN_USE;
2049
if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
2052
r->in.architecture, 3)))
2054
/* if we get to here, we now have 2 driver info structures to remove */
2055
/* remove the Win2k driver first*/
2057
status_win2k = delete_printer_driver(
2058
p, info_win2k, 3, false);
2059
free_a_printer_driver(info_win2k);
2061
/* this should not have failed---if it did, report to client */
2062
if ( !W_ERROR_IS_OK(status_win2k) )
2064
status = status_win2k;
2070
status = delete_printer_driver(p, info, version, false);
2072
/* if at least one of the deletes succeeded return OK */
2074
if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2078
free_a_printer_driver(info);
2083
/****************************************************************
2084
_spoolss_DeletePrinterDriverEx
2085
****************************************************************/
2087
WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2088
struct spoolss_DeletePrinterDriverEx *r)
2090
struct spoolss_DriverInfo8 *info = NULL;
2091
struct spoolss_DriverInfo8 *info_win2k = NULL;
2095
WERROR status_win2k = WERR_ACCESS_DENIED;
2096
SE_PRIV se_printop = SE_PRINT_OPERATOR;
2098
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2099
and not a printer admin, then fail */
2101
if ( (p->server_info->utok.uid != sec_initial_uid())
2102
&& !user_has_privileges(p->server_info->ptok, &se_printop )
2103
&& !token_contains_name_in_list(
2104
uidtoname(p->server_info->utok.uid),
2105
pdb_get_domain(p->server_info->sam_account),
2107
p->server_info->ptok, lp_printer_admin(-1)) )
2109
return WERR_ACCESS_DENIED;
2112
/* check that we have a valid driver name first */
2113
if ((version = get_version_id(r->in.architecture)) == -1) {
2114
/* this is what NT returns */
2115
return WERR_INVALID_ENVIRONMENT;
2118
if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2119
version = r->in.version;
2121
status = get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2122
r->in.architecture, version);
2124
if ( !W_ERROR_IS_OK(status) )
2127
* if the client asked for a specific version,
2128
* or this is something other than Windows NT x86,
2132
if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2135
/* try for Win2k driver if "Windows NT x86" */
2138
if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, r->in.driver,
2141
status = WERR_UNKNOWN_PRINTER_DRIVER;
2146
if (printer_driver_in_use(info)) {
2147
status = WERR_PRINTER_DRIVER_IN_USE;
2152
* we have a couple of cases to consider.
2153
* (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2154
* then the delete should fail if **any** files overlap with
2156
* (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2157
* non-overlapping files
2158
* (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2159
* is set, the do not delete any files
2160
* Refer to MSDN docs on DeletePrinterDriverEx() for details.
2163
delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2165
/* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2167
if (delete_files && printer_driver_files_in_use(info, info) & (r->in.delete_flags & DPD_DELETE_ALL_FILES)) {
2168
/* no idea of the correct error here */
2169
status = WERR_ACCESS_DENIED;
2174
/* also check for W32X86/3 if necessary; maybe we already have? */
2176
if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2177
if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info_win2k,
2179
r->in.architecture, 3)))
2182
if (delete_files && printer_driver_files_in_use(info, info_win2k) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
2183
/* no idea of the correct error here */
2184
free_a_printer_driver(info_win2k);
2185
status = WERR_ACCESS_DENIED;
2189
/* if we get to here, we now have 2 driver info structures to remove */
2190
/* remove the Win2k driver first*/
2192
status_win2k = delete_printer_driver(
2193
p, info_win2k, 3, delete_files);
2194
free_a_printer_driver(info_win2k);
2196
/* this should not have failed---if it did, report to client */
2198
if ( !W_ERROR_IS_OK(status_win2k) )
2203
status = delete_printer_driver(p, info, version, delete_files);
2205
if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2208
free_a_printer_driver(info);
2214
/****************************************************************************
2215
Internal routine for removing printerdata
2216
***************************************************************************/
2218
static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2220
return delete_printer_data( printer->info_2, key, value );
2223
/****************************************************************************
2224
Internal routine for storing printerdata
2225
***************************************************************************/
2227
WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
2228
const char *key, const char *value,
2229
uint32_t type, uint8_t *data, int real_len)
2231
/* the registry objects enforce uniqueness based on value name */
2233
return add_printer_data( printer->info_2, key, value, type, data, real_len );
2236
/********************************************************************
2237
GetPrinterData on a printer server Handle.
2238
********************************************************************/
2240
static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2242
enum winreg_Type *type,
2243
union spoolss_PrinterData *data)
2245
DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2247
if (!StrCaseCmp(value, "W3SvcInstalled")) {
2253
if (!StrCaseCmp(value, "BeepEnabled")) {
2259
if (!StrCaseCmp(value, "EventLog")) {
2261
/* formally was 0x1b */
2266
if (!StrCaseCmp(value, "NetPopup")) {
2272
if (!StrCaseCmp(value, "MajorVersion")) {
2275
/* Windows NT 4.0 seems to not allow uploading of drivers
2276
to a server that reports 0x3 as the MajorVersion.
2277
need to investigate more how Win2k gets around this .
2280
if (RA_WINNT == get_remote_arch()) {
2289
if (!StrCaseCmp(value, "MinorVersion")) {
2296
* uint32_t size = 0x114
2297
* uint32_t major = 5
2298
* uint32_t minor = [0|1]
2299
* uint32_t build = [2195|2600]
2300
* extra unicode string = e.g. "Service Pack 3"
2302
if (!StrCaseCmp(value, "OSVersion")) {
2304
enum ndr_err_code ndr_err;
2305
struct spoolss_OSVersion os;
2307
os.major = 5; /* Windows 2000 == 5.0 */
2309
os.build = 2195; /* build */
2310
os.extra_string = ""; /* leave extra string empty */
2312
ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os,
2313
(ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2314
if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2315
return WERR_GENERAL_FAILURE;
2319
data->binary = blob;
2325
if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2328
data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2329
W_ERROR_HAVE_NO_MEMORY(data->string);
2334
if (!StrCaseCmp(value, "Architecture")) {
2337
data->string = talloc_strdup(mem_ctx, "Windows NT x86");
2338
W_ERROR_HAVE_NO_MEMORY(data->string);
2343
if (!StrCaseCmp(value, "DsPresent")) {
2346
/* only show the publish check box if we are a
2347
member of a AD domain */
2349
if (lp_security() == SEC_ADS) {
2357
if (!StrCaseCmp(value, "DNSMachineName")) {
2358
const char *hostname = get_mydnsfullname();
2361
return WERR_BADFILE;
2365
data->string = talloc_strdup(mem_ctx, hostname);
2366
W_ERROR_HAVE_NO_MEMORY(data->string);
2373
return WERR_INVALID_PARAM;
2376
/****************************************************************
2377
_spoolss_GetPrinterData
2378
****************************************************************/
2380
WERROR _spoolss_GetPrinterData(pipes_struct *p,
2381
struct spoolss_GetPrinterData *r)
2383
struct spoolss_GetPrinterDataEx r2;
2385
r2.in.handle = r->in.handle;
2386
r2.in.key_name = "PrinterDriverData";
2387
r2.in.value_name = r->in.value_name;
2388
r2.in.offered = r->in.offered;
2389
r2.out.type = r->out.type;
2390
r2.out.data = r->out.data;
2391
r2.out.needed = r->out.needed;
2393
return _spoolss_GetPrinterDataEx(p, &r2);
2396
/*********************************************************
2397
Connect to the client machine.
2398
**********************************************************/
2400
static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2401
struct sockaddr_storage *client_ss, const char *remote_machine)
2404
struct cli_state *the_cli;
2405
struct sockaddr_storage rm_addr;
2407
if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2408
if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2409
DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2413
if (ismyaddr((struct sockaddr *)&rm_addr)) {
2414
DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2418
char addr[INET6_ADDRSTRLEN];
2419
rm_addr = *client_ss;
2420
print_sockaddr(addr, sizeof(addr), &rm_addr);
2421
DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2425
/* setup the connection */
2427
ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2428
&rm_addr, 0, "IPC$", "IPC",
2432
0, lp_client_signing(), NULL );
2434
if ( !NT_STATUS_IS_OK( ret ) ) {
2435
DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2440
if ( the_cli->protocol != PROTOCOL_NT1 ) {
2441
DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2442
cli_shutdown(the_cli);
2447
* Ok - we have an anonymous connection to the IPC$ share.
2448
* Now start the NT Domain stuff :-).
2451
ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2452
if (!NT_STATUS_IS_OK(ret)) {
2453
DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2454
remote_machine, nt_errstr(ret)));
2455
cli_shutdown(the_cli);
2462
/***************************************************************************
2463
Connect to the client.
2464
****************************************************************************/
2466
static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2467
uint32_t localprinter, uint32_t type,
2468
struct policy_handle *handle,
2469
struct sockaddr_storage *client_ss)
2475
* If it's the first connection, contact the client
2476
* and connect to the IPC$ share anonymously
2478
if (smb_connections==0) {
2479
fstring unix_printer;
2481
fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2483
if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2486
messaging_register(smbd_messaging_context(), NULL,
2487
MSG_PRINTER_NOTIFY2,
2488
receive_notify2_message_list);
2489
/* Tell the connections db we're now interested in printer
2490
* notify messages. */
2491
register_message_flags(true, FLAG_MSG_PRINT_NOTIFY);
2495
* Tell the specific printing tdb we want messages for this printer
2496
* by registering our PID.
2499
if (!print_notify_register_pid(snum))
2500
DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2504
status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2512
if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2513
DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2514
win_errstr(result)));
2516
return (W_ERROR_IS_OK(result));
2519
/****************************************************************
2520
****************************************************************/
2522
static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2523
const struct spoolss_NotifyOption *r)
2525
struct spoolss_NotifyOption *option;
2532
option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2539
if (!option->count) {
2543
option->types = talloc_zero_array(option,
2544
struct spoolss_NotifyOptionType, option->count);
2545
if (!option->types) {
2546
talloc_free(option);
2550
for (i=0; i < option->count; i++) {
2551
option->types[i] = r->types[i];
2553
if (option->types[i].count) {
2554
option->types[i].fields = talloc_zero_array(option,
2555
union spoolss_Field, option->types[i].count);
2556
if (!option->types[i].fields) {
2557
talloc_free(option);
2560
for (k=0; k<option->types[i].count; k++) {
2561
option->types[i].fields[k] =
2562
r->types[i].fields[k];
2570
/****************************************************************
2571
* _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2573
* before replying OK: status=0 a rpc call is made to the workstation
2574
* asking ReplyOpenPrinter
2576
* in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2577
* called from api_spoolss_rffpcnex
2578
****************************************************************/
2580
WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2581
struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2584
struct spoolss_NotifyOption *option = r->in.notify_options;
2585
struct sockaddr_storage client_ss;
2587
/* store the notify value in the printer struct */
2589
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2592
DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2593
"Invalid handle (%s:%u:%u).\n",
2594
OUR_HANDLE(r->in.handle)));
2598
Printer->notify.flags = r->in.flags;
2599
Printer->notify.options = r->in.options;
2600
Printer->notify.printerlocal = r->in.printer_local;
2602
TALLOC_FREE(Printer->notify.option);
2603
Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2605
fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2607
/* Connect to the client machine and send a ReplyOpenPrinter */
2609
if ( Printer->printer_type == SPLHND_SERVER)
2611
else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2612
!get_printer_snum(p, r->in.handle, &snum, NULL) )
2615
if (!interpret_string_addr(&client_ss, p->client_address,
2617
return WERR_SERVER_UNAVAILABLE;
2620
if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2621
Printer->notify.printerlocal, 1,
2622
&Printer->notify.client_hnd, &client_ss))
2623
return WERR_SERVER_UNAVAILABLE;
2625
Printer->notify.client_connected = true;
2630
/*******************************************************************
2631
* fill a notify_info_data with the servername
2632
********************************************************************/
2634
void spoolss_notify_server_name(int snum,
2635
struct spoolss_Notify *data,
2636
print_queue_struct *queue,
2637
NT_PRINTER_INFO_LEVEL *printer,
2638
TALLOC_CTX *mem_ctx)
2640
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2643
/*******************************************************************
2644
* fill a notify_info_data with the printername (not including the servername).
2645
********************************************************************/
2647
void spoolss_notify_printer_name(int snum,
2648
struct spoolss_Notify *data,
2649
print_queue_struct *queue,
2650
NT_PRINTER_INFO_LEVEL *printer,
2651
TALLOC_CTX *mem_ctx)
2653
/* the notify name should not contain the \\server\ part */
2654
char *p = strrchr(printer->info_2->printername, '\\');
2657
p = printer->info_2->printername;
2662
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2665
/*******************************************************************
2666
* fill a notify_info_data with the servicename
2667
********************************************************************/
2669
void spoolss_notify_share_name(int snum,
2670
struct spoolss_Notify *data,
2671
print_queue_struct *queue,
2672
NT_PRINTER_INFO_LEVEL *printer,
2673
TALLOC_CTX *mem_ctx)
2675
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2678
/*******************************************************************
2679
* fill a notify_info_data with the port name
2680
********************************************************************/
2682
void spoolss_notify_port_name(int snum,
2683
struct spoolss_Notify *data,
2684
print_queue_struct *queue,
2685
NT_PRINTER_INFO_LEVEL *printer,
2686
TALLOC_CTX *mem_ctx)
2688
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
2691
/*******************************************************************
2692
* fill a notify_info_data with the printername
2693
* but it doesn't exist, have to see what to do
2694
********************************************************************/
2696
void spoolss_notify_driver_name(int snum,
2697
struct spoolss_Notify *data,
2698
print_queue_struct *queue,
2699
NT_PRINTER_INFO_LEVEL *printer,
2700
TALLOC_CTX *mem_ctx)
2702
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
2705
/*******************************************************************
2706
* fill a notify_info_data with the comment
2707
********************************************************************/
2709
void spoolss_notify_comment(int snum,
2710
struct spoolss_Notify *data,
2711
print_queue_struct *queue,
2712
NT_PRINTER_INFO_LEVEL *printer,
2713
TALLOC_CTX *mem_ctx)
2717
if (*printer->info_2->comment == '\0') {
2718
p = lp_comment(snum);
2720
p = printer->info_2->comment;
2723
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
2726
/*******************************************************************
2727
* fill a notify_info_data with the comment
2728
* location = "Room 1, floor 2, building 3"
2729
********************************************************************/
2731
void spoolss_notify_location(int snum,
2732
struct spoolss_Notify *data,
2733
print_queue_struct *queue,
2734
NT_PRINTER_INFO_LEVEL *printer,
2735
TALLOC_CTX *mem_ctx)
2737
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
2740
/*******************************************************************
2741
* fill a notify_info_data with the device mode
2742
* jfm:xxxx don't to it for know but that's a real problem !!!
2743
********************************************************************/
2745
static void spoolss_notify_devmode(int snum,
2746
struct spoolss_Notify *data,
2747
print_queue_struct *queue,
2748
NT_PRINTER_INFO_LEVEL *printer,
2749
TALLOC_CTX *mem_ctx)
2751
/* for a dummy implementation we have to zero the fields */
2752
SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2755
/*******************************************************************
2756
* fill a notify_info_data with the separator file name
2757
********************************************************************/
2759
void spoolss_notify_sepfile(int snum,
2760
struct spoolss_Notify *data,
2761
print_queue_struct *queue,
2762
NT_PRINTER_INFO_LEVEL *printer,
2763
TALLOC_CTX *mem_ctx)
2765
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
2768
/*******************************************************************
2769
* fill a notify_info_data with the print processor
2770
* jfm:xxxx return always winprint to indicate we don't do anything to it
2771
********************************************************************/
2773
void spoolss_notify_print_processor(int snum,
2774
struct spoolss_Notify *data,
2775
print_queue_struct *queue,
2776
NT_PRINTER_INFO_LEVEL *printer,
2777
TALLOC_CTX *mem_ctx)
2779
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
2782
/*******************************************************************
2783
* fill a notify_info_data with the print processor options
2784
* jfm:xxxx send an empty string
2785
********************************************************************/
2787
void spoolss_notify_parameters(int snum,
2788
struct spoolss_Notify *data,
2789
print_queue_struct *queue,
2790
NT_PRINTER_INFO_LEVEL *printer,
2791
TALLOC_CTX *mem_ctx)
2793
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
2796
/*******************************************************************
2797
* fill a notify_info_data with the data type
2798
* jfm:xxxx always send RAW as data type
2799
********************************************************************/
2801
void spoolss_notify_datatype(int snum,
2802
struct spoolss_Notify *data,
2803
print_queue_struct *queue,
2804
NT_PRINTER_INFO_LEVEL *printer,
2805
TALLOC_CTX *mem_ctx)
2807
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
2810
/*******************************************************************
2811
* fill a notify_info_data with the security descriptor
2812
* jfm:xxxx send an null pointer to say no security desc
2813
* have to implement security before !
2814
********************************************************************/
2816
static void spoolss_notify_security_desc(int snum,
2817
struct spoolss_Notify *data,
2818
print_queue_struct *queue,
2819
NT_PRINTER_INFO_LEVEL *printer,
2820
TALLOC_CTX *mem_ctx)
2822
SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
2823
printer->info_2->secdesc_buf->sd_size,
2824
printer->info_2->secdesc_buf->sd);
2827
/*******************************************************************
2828
* fill a notify_info_data with the attributes
2829
* jfm:xxxx a samba printer is always shared
2830
********************************************************************/
2832
void spoolss_notify_attributes(int snum,
2833
struct spoolss_Notify *data,
2834
print_queue_struct *queue,
2835
NT_PRINTER_INFO_LEVEL *printer,
2836
TALLOC_CTX *mem_ctx)
2838
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
2841
/*******************************************************************
2842
* fill a notify_info_data with the priority
2843
********************************************************************/
2845
static void spoolss_notify_priority(int snum,
2846
struct spoolss_Notify *data,
2847
print_queue_struct *queue,
2848
NT_PRINTER_INFO_LEVEL *printer,
2849
TALLOC_CTX *mem_ctx)
2851
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
2854
/*******************************************************************
2855
* fill a notify_info_data with the default priority
2856
********************************************************************/
2858
static void spoolss_notify_default_priority(int snum,
2859
struct spoolss_Notify *data,
2860
print_queue_struct *queue,
2861
NT_PRINTER_INFO_LEVEL *printer,
2862
TALLOC_CTX *mem_ctx)
2864
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
2867
/*******************************************************************
2868
* fill a notify_info_data with the start time
2869
********************************************************************/
2871
static void spoolss_notify_start_time(int snum,
2872
struct spoolss_Notify *data,
2873
print_queue_struct *queue,
2874
NT_PRINTER_INFO_LEVEL *printer,
2875
TALLOC_CTX *mem_ctx)
2877
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
2880
/*******************************************************************
2881
* fill a notify_info_data with the until time
2882
********************************************************************/
2884
static void spoolss_notify_until_time(int snum,
2885
struct spoolss_Notify *data,
2886
print_queue_struct *queue,
2887
NT_PRINTER_INFO_LEVEL *printer,
2888
TALLOC_CTX *mem_ctx)
2890
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
2893
/*******************************************************************
2894
* fill a notify_info_data with the status
2895
********************************************************************/
2897
static void spoolss_notify_status(int snum,
2898
struct spoolss_Notify *data,
2899
print_queue_struct *queue,
2900
NT_PRINTER_INFO_LEVEL *printer,
2901
TALLOC_CTX *mem_ctx)
2903
print_status_struct status;
2905
print_queue_length(snum, &status);
2906
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2909
/*******************************************************************
2910
* fill a notify_info_data with the number of jobs queued
2911
********************************************************************/
2913
void spoolss_notify_cjobs(int snum,
2914
struct spoolss_Notify *data,
2915
print_queue_struct *queue,
2916
NT_PRINTER_INFO_LEVEL *printer,
2917
TALLOC_CTX *mem_ctx)
2919
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2922
/*******************************************************************
2923
* fill a notify_info_data with the average ppm
2924
********************************************************************/
2926
static void spoolss_notify_average_ppm(int snum,
2927
struct spoolss_Notify *data,
2928
print_queue_struct *queue,
2929
NT_PRINTER_INFO_LEVEL *printer,
2930
TALLOC_CTX *mem_ctx)
2932
/* always respond 8 pages per minutes */
2933
/* a little hard ! */
2934
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
2937
/*******************************************************************
2938
* fill a notify_info_data with username
2939
********************************************************************/
2941
static void spoolss_notify_username(int snum,
2942
struct spoolss_Notify *data,
2943
print_queue_struct *queue,
2944
NT_PRINTER_INFO_LEVEL *printer,
2945
TALLOC_CTX *mem_ctx)
2947
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2950
/*******************************************************************
2951
* fill a notify_info_data with job status
2952
********************************************************************/
2954
static void spoolss_notify_job_status(int snum,
2955
struct spoolss_Notify *data,
2956
print_queue_struct *queue,
2957
NT_PRINTER_INFO_LEVEL *printer,
2958
TALLOC_CTX *mem_ctx)
2960
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2963
/*******************************************************************
2964
* fill a notify_info_data with job name
2965
********************************************************************/
2967
static void spoolss_notify_job_name(int snum,
2968
struct spoolss_Notify *data,
2969
print_queue_struct *queue,
2970
NT_PRINTER_INFO_LEVEL *printer,
2971
TALLOC_CTX *mem_ctx)
2973
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2976
/*******************************************************************
2977
* fill a notify_info_data with job status
2978
********************************************************************/
2980
static void spoolss_notify_job_status_string(int snum,
2981
struct spoolss_Notify *data,
2982
print_queue_struct *queue,
2983
NT_PRINTER_INFO_LEVEL *printer,
2984
TALLOC_CTX *mem_ctx)
2987
* Now we're returning job status codes we just return a "" here. JRA.
2992
#if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2995
switch (queue->status) {
3000
p = ""; /* NT provides the paused string */
3009
#endif /* NO LONGER NEEDED. */
3011
SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3014
/*******************************************************************
3015
* fill a notify_info_data with job time
3016
********************************************************************/
3018
static void spoolss_notify_job_time(int snum,
3019
struct spoolss_Notify *data,
3020
print_queue_struct *queue,
3021
NT_PRINTER_INFO_LEVEL *printer,
3022
TALLOC_CTX *mem_ctx)
3024
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3027
/*******************************************************************
3028
* fill a notify_info_data with job size
3029
********************************************************************/
3031
static void spoolss_notify_job_size(int snum,
3032
struct spoolss_Notify *data,
3033
print_queue_struct *queue,
3034
NT_PRINTER_INFO_LEVEL *printer,
3035
TALLOC_CTX *mem_ctx)
3037
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3040
/*******************************************************************
3041
* fill a notify_info_data with page info
3042
********************************************************************/
3043
static void spoolss_notify_total_pages(int snum,
3044
struct spoolss_Notify *data,
3045
print_queue_struct *queue,
3046
NT_PRINTER_INFO_LEVEL *printer,
3047
TALLOC_CTX *mem_ctx)
3049
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3052
/*******************************************************************
3053
* fill a notify_info_data with pages printed info.
3054
********************************************************************/
3055
static void spoolss_notify_pages_printed(int snum,
3056
struct spoolss_Notify *data,
3057
print_queue_struct *queue,
3058
NT_PRINTER_INFO_LEVEL *printer,
3059
TALLOC_CTX *mem_ctx)
3061
/* Add code when back-end tracks this */
3062
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3065
/*******************************************************************
3066
Fill a notify_info_data with job position.
3067
********************************************************************/
3069
static void spoolss_notify_job_position(int snum,
3070
struct spoolss_Notify *data,
3071
print_queue_struct *queue,
3072
NT_PRINTER_INFO_LEVEL *printer,
3073
TALLOC_CTX *mem_ctx)
3075
SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3078
/*******************************************************************
3079
Fill a notify_info_data with submitted time.
3080
********************************************************************/
3082
static void spoolss_notify_submitted_time(int snum,
3083
struct spoolss_Notify *data,
3084
print_queue_struct *queue,
3085
NT_PRINTER_INFO_LEVEL *printer,
3086
TALLOC_CTX *mem_ctx)
3088
data->data.string.string = NULL;
3089
data->data.string.size = 0;
3091
init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3092
&data->data.string.string,
3093
&data->data.string.size);
3097
struct s_notify_info_data_table
3099
enum spoolss_NotifyType type;
3102
enum spoolss_NotifyTable variable_type;
3103
void (*fn) (int snum, struct spoolss_Notify *data,
3104
print_queue_struct *queue,
3105
NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3108
/* A table describing the various print notification constants and
3109
whether the notification data is a pointer to a variable sized
3110
buffer, a one value uint32_t or a two value uint32_t. */
3112
static const struct s_notify_info_data_table notify_info_data_table[] =
3114
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3115
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3116
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3117
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3118
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3119
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3120
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3121
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3122
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3123
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3124
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3125
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3126
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3127
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3128
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3129
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3130
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3131
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3132
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3133
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3134
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3135
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3136
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3137
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3138
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3139
{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3140
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3141
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3142
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3143
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3144
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3145
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3146
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3147
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3148
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3149
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3150
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3151
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3152
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3153
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3154
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3155
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3156
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3157
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3158
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3159
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3160
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3161
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3162
{ JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3165
/*******************************************************************
3166
Return the variable_type of info_data structure.
3167
********************************************************************/
3169
static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3174
for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3175
if ( (notify_info_data_table[i].type == type) &&
3176
(notify_info_data_table[i].field == field) ) {
3177
return notify_info_data_table[i].variable_type;
3181
DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3186
/****************************************************************************
3187
****************************************************************************/
3189
static bool search_notify(enum spoolss_NotifyType type,
3195
for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3196
if (notify_info_data_table[i].type == type &&
3197
notify_info_data_table[i].field == field &&
3198
notify_info_data_table[i].fn != NULL) {
3207
/****************************************************************************
3208
****************************************************************************/
3210
void construct_info_data(struct spoolss_Notify *info_data,
3211
enum spoolss_NotifyType type,
3215
info_data->type = type;
3216
info_data->field.field = field;
3217
info_data->variable_type = variable_type_of_notify_info_data(type, field);
3218
info_data->job_id = id;
3221
/*******************************************************************
3223
* fill a notify_info struct with info asked
3225
********************************************************************/
3227
static bool construct_notify_printer_info(Printer_entry *print_hnd,
3228
struct spoolss_NotifyInfo *info,
3230
const struct spoolss_NotifyOptionType *option_type,
3232
TALLOC_CTX *mem_ctx)
3235
enum spoolss_NotifyType type;
3238
struct spoolss_Notify *current_data;
3239
NT_PRINTER_INFO_LEVEL *printer = NULL;
3240
print_queue_struct *queue=NULL;
3242
type = option_type->type;
3244
DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3245
(type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3246
option_type->count, lp_servicename(snum)));
3248
if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3251
for(field_num=0; field_num < option_type->count; field_num++) {
3252
field = option_type->fields[field_num].field;
3254
DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3256
if (!search_notify(type, field, &j) )
3259
info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3260
struct spoolss_Notify,
3262
if (info->notifies == NULL) {
3263
DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3264
free_a_printer(&printer, 2);
3268
current_data = &info->notifies[info->count];
3270
construct_info_data(current_data, type, field, id);
3272
DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3273
notify_info_data_table[j].name, snum, printer->info_2->printername ));
3275
notify_info_data_table[j].fn(snum, current_data, queue,
3281
free_a_printer(&printer, 2);
3285
/*******************************************************************
3287
* fill a notify_info struct with info asked
3289
********************************************************************/
3291
static bool construct_notify_jobs_info(print_queue_struct *queue,
3292
struct spoolss_NotifyInfo *info,
3293
NT_PRINTER_INFO_LEVEL *printer,
3295
const struct spoolss_NotifyOptionType *option_type,
3297
TALLOC_CTX *mem_ctx)
3300
enum spoolss_NotifyType type;
3302
struct spoolss_Notify *current_data;
3304
DEBUG(4,("construct_notify_jobs_info\n"));
3306
type = option_type->type;
3308
DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3309
(type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3310
option_type->count));
3312
for(field_num=0; field_num<option_type->count; field_num++) {
3313
field = option_type->fields[field_num].field;
3315
if (!search_notify(type, field, &j) )
3318
info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3319
struct spoolss_Notify,
3321
if (info->notifies == NULL) {
3322
DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3326
current_data=&(info->notifies[info->count]);
3328
construct_info_data(current_data, type, field, id);
3329
notify_info_data_table[j].fn(snum, current_data, queue,
3338
* JFM: The enumeration is not that simple, it's even non obvious.
3340
* let's take an example: I want to monitor the PRINTER SERVER for
3341
* the printer's name and the number of jobs currently queued.
3342
* So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3343
* Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3345
* I have 3 printers on the back of my server.
3347
* Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3350
* 1 printer 1 name 1
3351
* 2 printer 1 cjob 1
3352
* 3 printer 2 name 2
3353
* 4 printer 2 cjob 2
3354
* 5 printer 3 name 3
3355
* 6 printer 3 name 3
3357
* that's the print server case, the printer case is even worse.
3360
/*******************************************************************
3362
* enumerate all printers on the printserver
3363
* fill a notify_info struct with info asked
3365
********************************************************************/
3367
static WERROR printserver_notify_info(pipes_struct *p,
3368
struct policy_handle *hnd,
3369
struct spoolss_NotifyInfo *info,
3370
TALLOC_CTX *mem_ctx)
3373
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3374
int n_services=lp_numservices();
3376
struct spoolss_NotifyOption *option;
3377
struct spoolss_NotifyOptionType option_type;
3379
DEBUG(4,("printserver_notify_info\n"));
3384
option = Printer->notify.option;
3387
info->notifies = NULL;
3390
/* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3391
sending a ffpcn() request first */
3396
for (i=0; i<option->count; i++) {
3397
option_type = option->types[i];
3399
if (option_type.type != PRINTER_NOTIFY_TYPE)
3402
for (snum=0; snum<n_services; snum++)
3404
if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3405
construct_notify_printer_info ( Printer, info, snum, &option_type, snum, mem_ctx );
3411
* Debugging information, don't delete.
3414
DEBUG(1,("dumping the NOTIFY_INFO\n"));
3415
DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3416
DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3418
for (i=0; i<info->count; i++) {
3419
DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3420
i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3421
info->data[i].id, info->data[i].size, info->data[i].enc_type));
3428
/*******************************************************************
3430
* fill a notify_info struct with info asked
3432
********************************************************************/
3434
static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd,
3435
struct spoolss_NotifyInfo *info,
3436
TALLOC_CTX *mem_ctx)
3439
Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3442
struct spoolss_NotifyOption *option;
3443
struct spoolss_NotifyOptionType option_type;
3445
print_queue_struct *queue=NULL;
3446
print_status_struct status;
3448
DEBUG(4,("printer_notify_info\n"));
3453
option = Printer->notify.option;
3457
info->notifies = NULL;
3460
/* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3461
sending a ffpcn() request first */
3466
get_printer_snum(p, hnd, &snum, NULL);
3468
for (i=0; i<option->count; i++) {
3469
option_type = option->types[i];
3471
switch (option_type.type) {
3472
case PRINTER_NOTIFY_TYPE:
3473
if(construct_notify_printer_info(Printer, info, snum,
3479
case JOB_NOTIFY_TYPE: {
3480
NT_PRINTER_INFO_LEVEL *printer = NULL;
3482
count = print_queue_status(snum, &queue, &status);
3484
if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3487
for (j=0; j<count; j++) {
3488
construct_notify_jobs_info(&queue[j], info,
3495
free_a_printer(&printer, 2);
3505
* Debugging information, don't delete.
3508
DEBUG(1,("dumping the NOTIFY_INFO\n"));
3509
DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3510
DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3512
for (i=0; i<info->count; i++) {
3513
DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3514
i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3515
info->data[i].id, info->data[i].size, info->data[i].enc_type));
3521
/****************************************************************
3522
_spoolss_RouterRefreshPrinterChangeNotify
3523
****************************************************************/
3525
WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3526
struct spoolss_RouterRefreshPrinterChangeNotify *r)
3528
struct spoolss_NotifyInfo *info;
3530
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3531
WERROR result = WERR_BADFID;
3533
/* we always have a spoolss_NotifyInfo struct */
3534
info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3536
result = WERR_NOMEM;
3540
*r->out.info = info;
3543
DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3544
"Invalid handle (%s:%u:%u).\n",
3545
OUR_HANDLE(r->in.handle)));
3549
DEBUG(4,("Printer type %x\n",Printer->printer_type));
3552
* We are now using the change value, and
3553
* I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3554
* I don't have a global notification system, I'm sending back all the
3555
* informations even when _NOTHING_ has changed.
3558
/* We need to keep track of the change value to send back in
3559
RRPCN replies otherwise our updates are ignored. */
3561
Printer->notify.fnpcn = true;
3563
if (Printer->notify.client_connected) {
3564
DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3565
"Saving change value in request [%x]\n",
3567
Printer->notify.change = r->in.change_low;
3570
/* just ignore the spoolss_NotifyOption */
3572
switch (Printer->printer_type) {
3574
result = printserver_notify_info(p, r->in.handle,
3578
case SPLHND_PRINTER:
3579
result = printer_notify_info(p, r->in.handle,
3584
Printer->notify.fnpcn = false;
3590
/********************************************************************
3591
* construct_printer_info_0
3592
* fill a printer_info_0 struct
3593
********************************************************************/
3595
static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3596
const NT_PRINTER_INFO_LEVEL *ntprinter,
3597
struct spoolss_PrinterInfo0 *r,
3601
counter_printer_0 *session_counter;
3603
print_status_struct status;
3605
r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3606
W_ERROR_HAVE_NO_MEMORY(r->printername);
3608
r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3609
W_ERROR_HAVE_NO_MEMORY(r->servername);
3611
count = print_queue_length(snum, &status);
3613
/* check if we already have a counter for this printer */
3614
for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3615
if (session_counter->snum == snum)
3619
/* it's the first time, add it to the list */
3620
if (session_counter == NULL) {
3621
session_counter = SMB_MALLOC_P(counter_printer_0);
3622
W_ERROR_HAVE_NO_MEMORY(session_counter);
3623
ZERO_STRUCTP(session_counter);
3624
session_counter->snum = snum;
3625
session_counter->counter = 0;
3626
DLIST_ADD(counter_list, session_counter);
3630
session_counter->counter++;
3636
setuptime = (time_t)ntprinter->info_2->setuptime;
3638
init_systemtime(&r->time, gmtime(&setuptime));
3641
* the global_counter should be stored in a TDB as it's common to all the clients
3642
* and should be zeroed on samba startup
3644
r->global_counter = session_counter->counter;
3646
/* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3647
r->version = 0x0005; /* NT 5 */
3648
r->free_build = 0x0893; /* build 2195 */
3650
r->max_spooling = 0;
3651
r->session_counter = session_counter->counter;
3652
r->num_error_out_of_paper = 0x0;
3653
r->num_error_not_ready = 0x0; /* number of print failure */
3655
r->number_of_processors = 0x1;
3656
r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3657
r->high_part_total_bytes = 0x0;
3658
r->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3659
r->last_error = WERR_OK;
3660
r->status = nt_printq_status(status.status);
3661
r->enumerate_network_printers = 0x0;
3662
r->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3663
r->processor_architecture = 0x0;
3664
r->processor_level = 0x6; /* 6 ???*/
3672
/****************************************************************************
3673
Convert an NT_DEVICEMODE to a spoolss_DeviceMode structure. Both pointers
3674
should be valid upon entry
3675
****************************************************************************/
3677
static WERROR convert_nt_devicemode(TALLOC_CTX *mem_ctx,
3678
struct spoolss_DeviceMode *r,
3679
const NT_DEVICEMODE *ntdevmode)
3681
if (!r || !ntdevmode) {
3682
return WERR_INVALID_PARAM;
3685
r->devicename = talloc_strdup(mem_ctx, ntdevmode->devicename);
3686
W_ERROR_HAVE_NO_MEMORY(r->devicename);
3688
r->specversion = ntdevmode->specversion;
3689
r->driverversion = ntdevmode->driverversion;
3690
r->size = ntdevmode->size;
3691
r->__driverextra_length = ntdevmode->driverextra;
3692
r->fields = ntdevmode->fields;
3694
r->orientation = ntdevmode->orientation;
3695
r->papersize = ntdevmode->papersize;
3696
r->paperlength = ntdevmode->paperlength;
3697
r->paperwidth = ntdevmode->paperwidth;
3698
r->scale = ntdevmode->scale;
3699
r->copies = ntdevmode->copies;
3700
r->defaultsource = ntdevmode->defaultsource;
3701
r->printquality = ntdevmode->printquality;
3702
r->color = ntdevmode->color;
3703
r->duplex = ntdevmode->duplex;
3704
r->yresolution = ntdevmode->yresolution;
3705
r->ttoption = ntdevmode->ttoption;
3706
r->collate = ntdevmode->collate;
3708
r->formname = talloc_strdup(mem_ctx, ntdevmode->formname);
3709
W_ERROR_HAVE_NO_MEMORY(r->formname);
3711
/* all 0 below are values that have not been set in the old parsing/copy
3712
* function, maybe they should... - gd */
3718
r->displayflags = 0;
3719
r->displayfrequency = 0;
3720
r->icmmethod = ntdevmode->icmmethod;
3721
r->icmintent = ntdevmode->icmintent;
3722
r->mediatype = ntdevmode->mediatype;
3723
r->dithertype = ntdevmode->dithertype;
3726
r->panningwidth = 0;
3727
r->panningheight = 0;
3729
if (ntdevmode->nt_dev_private != NULL) {
3730
r->driverextra_data = data_blob_talloc(mem_ctx,
3731
ntdevmode->nt_dev_private,
3732
ntdevmode->driverextra);
3733
W_ERROR_HAVE_NO_MEMORY(r->driverextra_data.data);
3740
/****************************************************************************
3741
Create a spoolss_DeviceMode struct. Returns talloced memory.
3742
****************************************************************************/
3744
struct spoolss_DeviceMode *construct_dev_mode(TALLOC_CTX *mem_ctx,
3745
const char *servicename)
3748
NT_PRINTER_INFO_LEVEL *printer = NULL;
3749
struct spoolss_DeviceMode *devmode = NULL;
3751
DEBUG(7,("construct_dev_mode\n"));
3753
DEBUGADD(8,("getting printer characteristics\n"));
3755
if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
3758
if (!printer->info_2->devmode) {
3759
DEBUG(5, ("BONG! There was no device mode!\n"));
3763
devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
3765
DEBUG(2,("construct_dev_mode: talloc fail.\n"));
3769
DEBUGADD(8,("loading DEVICEMODE\n"));
3771
result = convert_nt_devicemode(mem_ctx, devmode, printer->info_2->devmode);
3772
if (!W_ERROR_IS_OK(result)) {
3773
TALLOC_FREE(devmode);
3777
free_a_printer(&printer,2);
3782
/********************************************************************
3783
* construct_printer_info1
3784
* fill a spoolss_PrinterInfo1 struct
3785
********************************************************************/
3787
static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3788
const NT_PRINTER_INFO_LEVEL *ntprinter,
3790
struct spoolss_PrinterInfo1 *r,
3795
r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3796
ntprinter->info_2->printername,
3797
ntprinter->info_2->drivername,
3798
ntprinter->info_2->location);
3799
W_ERROR_HAVE_NO_MEMORY(r->description);
3801
if (*ntprinter->info_2->comment == '\0') {
3802
r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3804
r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment); /* saved comment */
3806
W_ERROR_HAVE_NO_MEMORY(r->comment);
3808
r->name = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3809
W_ERROR_HAVE_NO_MEMORY(r->name);
3814
/********************************************************************
3815
* construct_printer_info2
3816
* fill a spoolss_PrinterInfo2 struct
3817
********************************************************************/
3819
static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3820
const NT_PRINTER_INFO_LEVEL *ntprinter,
3821
struct spoolss_PrinterInfo2 *r,
3826
print_status_struct status;
3828
count = print_queue_length(snum, &status);
3830
r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3831
W_ERROR_HAVE_NO_MEMORY(r->servername);
3832
r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3833
W_ERROR_HAVE_NO_MEMORY(r->printername);
3834
r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3835
W_ERROR_HAVE_NO_MEMORY(r->sharename);
3836
r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3837
W_ERROR_HAVE_NO_MEMORY(r->portname);
3838
r->drivername = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
3839
W_ERROR_HAVE_NO_MEMORY(r->drivername);
3841
if (*ntprinter->info_2->comment == '\0') {
3842
r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3844
r->comment = talloc_strdup(mem_ctx, ntprinter->info_2->comment);
3846
W_ERROR_HAVE_NO_MEMORY(r->comment);
3848
r->location = talloc_strdup(mem_ctx, ntprinter->info_2->location);
3849
W_ERROR_HAVE_NO_MEMORY(r->location);
3850
r->sepfile = talloc_strdup(mem_ctx, ntprinter->info_2->sepfile);
3851
W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3852
r->printprocessor = talloc_strdup(mem_ctx, ntprinter->info_2->printprocessor);
3853
W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3854
r->datatype = talloc_strdup(mem_ctx, ntprinter->info_2->datatype);
3855
W_ERROR_HAVE_NO_MEMORY(r->datatype);
3856
r->parameters = talloc_strdup(mem_ctx, ntprinter->info_2->parameters);
3857
W_ERROR_HAVE_NO_MEMORY(r->parameters);
3859
r->attributes = ntprinter->info_2->attributes;
3861
r->priority = ntprinter->info_2->priority;
3862
r->defaultpriority = ntprinter->info_2->default_priority;
3863
r->starttime = ntprinter->info_2->starttime;
3864
r->untiltime = ntprinter->info_2->untiltime;
3865
r->status = nt_printq_status(status.status);
3867
r->averageppm = ntprinter->info_2->averageppm;
3869
r->devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
3871
DEBUG(8,("Returning NULL Devicemode!\n"));
3876
if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3877
/* don't use talloc_steal() here unless you do a deep steal of all
3878
the SEC_DESC members */
3880
r->secdesc = dup_sec_desc(mem_ctx, ntprinter->info_2->secdesc_buf->sd);
3886
/********************************************************************
3887
* construct_printer_info3
3888
* fill a spoolss_PrinterInfo3 struct
3889
********************************************************************/
3891
static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3892
const NT_PRINTER_INFO_LEVEL *ntprinter,
3893
struct spoolss_PrinterInfo3 *r,
3896
/* These are the components of the SD we are returning. */
3898
if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
3899
/* don't use talloc_steal() here unless you do a deep steal of all
3900
the SEC_DESC members */
3902
r->secdesc = dup_sec_desc(mem_ctx,
3903
ntprinter->info_2->secdesc_buf->sd);
3904
W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3910
/********************************************************************
3911
* construct_printer_info4
3912
* fill a spoolss_PrinterInfo4 struct
3913
********************************************************************/
3915
static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3916
const NT_PRINTER_INFO_LEVEL *ntprinter,
3917
struct spoolss_PrinterInfo4 *r,
3920
r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3921
W_ERROR_HAVE_NO_MEMORY(r->printername);
3922
r->servername = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
3923
W_ERROR_HAVE_NO_MEMORY(r->servername);
3925
r->attributes = ntprinter->info_2->attributes;
3930
/********************************************************************
3931
* construct_printer_info5
3932
* fill a spoolss_PrinterInfo5 struct
3933
********************************************************************/
3935
static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3936
const NT_PRINTER_INFO_LEVEL *ntprinter,
3937
struct spoolss_PrinterInfo5 *r,
3940
r->printername = talloc_strdup(mem_ctx, ntprinter->info_2->printername);
3941
W_ERROR_HAVE_NO_MEMORY(r->printername);
3942
r->portname = talloc_strdup(mem_ctx, ntprinter->info_2->portname);
3943
W_ERROR_HAVE_NO_MEMORY(r->portname);
3945
r->attributes = ntprinter->info_2->attributes;
3947
/* these two are not used by NT+ according to MSDN */
3949
r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3950
r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3955
/********************************************************************
3956
* construct_printer_info_6
3957
* fill a spoolss_PrinterInfo6 struct
3958
********************************************************************/
3960
static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3961
const NT_PRINTER_INFO_LEVEL *ntprinter,
3962
struct spoolss_PrinterInfo6 *r,
3966
print_status_struct status;
3968
count = print_queue_length(snum, &status);
3970
r->status = nt_printq_status(status.status);
3975
/********************************************************************
3976
* construct_printer_info7
3977
* fill a spoolss_PrinterInfo7 struct
3978
********************************************************************/
3980
static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3981
Printer_entry *print_hnd,
3982
struct spoolss_PrinterInfo7 *r,
3987
if (is_printer_published(print_hnd, snum, &guid)) {
3988
r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3989
r->action = DSPRINT_PUBLISH;
3991
r->guid = talloc_strdup(mem_ctx, "");
3992
r->action = DSPRINT_UNPUBLISH;
3994
W_ERROR_HAVE_NO_MEMORY(r->guid);
3999
/********************************************************************
4000
* construct_printer_info8
4001
* fill a spoolss_PrinterInfo8 struct
4002
********************************************************************/
4004
static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
4005
const NT_PRINTER_INFO_LEVEL *ntprinter,
4006
struct spoolss_DeviceModeInfo *r,
4009
struct spoolss_DeviceMode *devmode;
4012
if (!ntprinter->info_2->devmode) {
4017
devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
4018
W_ERROR_HAVE_NO_MEMORY(devmode);
4020
result = convert_nt_devicemode(mem_ctx, devmode, ntprinter->info_2->devmode);
4021
if (!W_ERROR_IS_OK(result)) {
4022
TALLOC_FREE(devmode);
4026
r->devmode = devmode;
4032
/********************************************************************
4033
********************************************************************/
4035
static bool snum_is_shared_printer(int snum)
4037
return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
4040
/********************************************************************
4041
Spoolss_enumprinters.
4042
********************************************************************/
4044
static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
4047
union spoolss_PrinterInfo **info_p,
4051
int n_services = lp_numservices();
4052
union spoolss_PrinterInfo *info = NULL;
4054
WERROR result = WERR_OK;
4059
for (snum = 0; snum < n_services; snum++) {
4061
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4063
if (!snum_is_shared_printer(snum)) {
4067
DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
4068
lp_servicename(snum), snum));
4070
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4071
union spoolss_PrinterInfo,
4074
result = WERR_NOMEM;
4078
result = get_a_printer(NULL, &ntprinter, 2,
4079
lp_const_servicename(snum));
4080
if (!W_ERROR_IS_OK(result)) {
4086
result = construct_printer_info0(info, ntprinter,
4087
&info[count].info0, snum);
4090
result = construct_printer_info1(info, ntprinter, flags,
4091
&info[count].info1, snum);
4094
result = construct_printer_info2(info, ntprinter,
4095
&info[count].info2, snum);
4098
result = construct_printer_info4(info, ntprinter,
4099
&info[count].info4, snum);
4102
result = construct_printer_info5(info, ntprinter,
4103
&info[count].info5, snum);
4107
result = WERR_UNKNOWN_LEVEL;
4108
free_a_printer(&ntprinter, 2);
4112
free_a_printer(&ntprinter, 2);
4113
if (!W_ERROR_IS_OK(result)) {
4124
if (!W_ERROR_IS_OK(result)) {
4134
/********************************************************************
4135
* handle enumeration of printers at level 0
4136
********************************************************************/
4138
static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
4140
const char *servername,
4141
union spoolss_PrinterInfo **info,
4144
DEBUG(4,("enum_all_printers_info_0\n"));
4146
return enum_all_printers_info_level(mem_ctx, 0, flags, info, count);
4150
/********************************************************************
4151
********************************************************************/
4153
static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
4155
union spoolss_PrinterInfo **info,
4158
DEBUG(4,("enum_all_printers_info_1\n"));
4160
return enum_all_printers_info_level(mem_ctx, 1, flags, info, count);
4163
/********************************************************************
4164
enum_all_printers_info_1_local.
4165
*********************************************************************/
4167
static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
4168
union spoolss_PrinterInfo **info,
4171
DEBUG(4,("enum_all_printers_info_1_local\n"));
4173
return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4176
/********************************************************************
4177
enum_all_printers_info_1_name.
4178
*********************************************************************/
4180
static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
4182
union spoolss_PrinterInfo **info,
4185
const char *s = name;
4187
DEBUG(4,("enum_all_printers_info_1_name\n"));
4189
if ((name[0] == '\\') && (name[1] == '\\')) {
4193
if (!is_myname_or_ipaddr(s)) {
4194
return WERR_INVALID_NAME;
4197
return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_ICON8, info, count);
4200
/********************************************************************
4201
enum_all_printers_info_1_network.
4202
*********************************************************************/
4204
static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
4206
union spoolss_PrinterInfo **info,
4209
const char *s = name;
4211
DEBUG(4,("enum_all_printers_info_1_network\n"));
4213
/* If we respond to a enum_printers level 1 on our name with flags
4214
set to PRINTER_ENUM_REMOTE with a list of printers then these
4215
printers incorrectly appear in the APW browse list.
4216
Specifically the printers for the server appear at the workgroup
4217
level where all the other servers in the domain are
4218
listed. Windows responds to this call with a
4219
WERR_CAN_NOT_COMPLETE so we should do the same. */
4221
if (name[0] == '\\' && name[1] == '\\') {
4225
if (is_myname_or_ipaddr(s)) {
4226
return WERR_CAN_NOT_COMPLETE;
4229
return enum_all_printers_info_1(mem_ctx, PRINTER_ENUM_NAME, info, count);
4232
/********************************************************************
4233
* api_spoolss_enumprinters
4235
* called from api_spoolss_enumprinters (see this to understand)
4236
********************************************************************/
4238
static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
4239
union spoolss_PrinterInfo **info,
4242
DEBUG(4,("enum_all_printers_info_2\n"));
4244
return enum_all_printers_info_level(mem_ctx, 2, 0, info, count);
4247
/********************************************************************
4248
* handle enumeration of printers at level 1
4249
********************************************************************/
4251
static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
4254
union spoolss_PrinterInfo **info,
4257
/* Not all the flags are equals */
4259
if (flags & PRINTER_ENUM_LOCAL) {
4260
return enum_all_printers_info_1_local(mem_ctx, info, count);
4263
if (flags & PRINTER_ENUM_NAME) {
4264
return enum_all_printers_info_1_name(mem_ctx, name, info, count);
4267
if (flags & PRINTER_ENUM_NETWORK) {
4268
return enum_all_printers_info_1_network(mem_ctx, name, info, count);
4271
return WERR_OK; /* NT4sp5 does that */
4274
/********************************************************************
4275
* handle enumeration of printers at level 2
4276
********************************************************************/
4278
static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4280
const char *servername,
4281
union spoolss_PrinterInfo **info,
4284
if (flags & PRINTER_ENUM_LOCAL) {
4285
return enum_all_printers_info_2(mem_ctx, info, count);
4288
if (flags & PRINTER_ENUM_NAME) {
4289
if (!is_myname_or_ipaddr(canon_servername(servername))) {
4290
return WERR_INVALID_NAME;
4293
return enum_all_printers_info_2(mem_ctx, info, count);
4296
if (flags & PRINTER_ENUM_REMOTE) {
4297
return WERR_UNKNOWN_LEVEL;
4303
/********************************************************************
4304
* handle enumeration of printers at level 4
4305
********************************************************************/
4307
static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4309
const char *servername,
4310
union spoolss_PrinterInfo **info,
4313
DEBUG(4,("enum_all_printers_info_4\n"));
4315
return enum_all_printers_info_level(mem_ctx, 4, flags, info, count);
4319
/********************************************************************
4320
* handle enumeration of printers at level 5
4321
********************************************************************/
4323
static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4325
const char *servername,
4326
union spoolss_PrinterInfo **info,
4329
DEBUG(4,("enum_all_printers_info_5\n"));
4331
return enum_all_printers_info_level(mem_ctx, 5, flags, info, count);
4334
/****************************************************************
4335
_spoolss_EnumPrinters
4336
****************************************************************/
4338
WERROR _spoolss_EnumPrinters(pipes_struct *p,
4339
struct spoolss_EnumPrinters *r)
4341
const char *name = NULL;
4344
/* that's an [in out] buffer */
4346
if (!r->in.buffer && (r->in.offered != 0)) {
4347
return WERR_INVALID_PARAM;
4350
DEBUG(4,("_spoolss_EnumPrinters\n"));
4354
*r->out.info = NULL;
4358
* flags==PRINTER_ENUM_NAME
4359
* if name=="" then enumerates all printers
4360
* if name!="" then enumerate the printer
4361
* flags==PRINTER_ENUM_REMOTE
4362
* name is NULL, enumerate printers
4363
* Level 2: name!="" enumerates printers, name can't be NULL
4364
* Level 3: doesn't exist
4365
* Level 4: does a local registry lookup
4366
* Level 5: same as Level 2
4370
name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4371
W_ERROR_HAVE_NO_MEMORY(name);
4374
switch (r->in.level) {
4376
result = enumprinters_level0(p->mem_ctx, r->in.flags, name,
4377
r->out.info, r->out.count);
4380
result = enumprinters_level1(p->mem_ctx, r->in.flags, name,
4381
r->out.info, r->out.count);
4384
result = enumprinters_level2(p->mem_ctx, r->in.flags, name,
4385
r->out.info, r->out.count);
4388
result = enumprinters_level4(p->mem_ctx, r->in.flags, name,
4389
r->out.info, r->out.count);
4392
result = enumprinters_level5(p->mem_ctx, r->in.flags, name,
4393
r->out.info, r->out.count);
4396
return WERR_UNKNOWN_LEVEL;
4399
if (!W_ERROR_IS_OK(result)) {
4403
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4404
spoolss_EnumPrinters, NULL,
4405
*r->out.info, r->in.level,
4407
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4408
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4410
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4413
/****************************************************************
4415
****************************************************************/
4417
WERROR _spoolss_GetPrinter(pipes_struct *p,
4418
struct spoolss_GetPrinter *r)
4420
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4421
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4422
WERROR result = WERR_OK;
4426
/* that's an [in out] buffer */
4428
if (!r->in.buffer && (r->in.offered != 0)) {
4429
return WERR_INVALID_PARAM;
4434
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4438
result = get_a_printer(Printer, &ntprinter, 2,
4439
lp_const_servicename(snum));
4440
if (!W_ERROR_IS_OK(result)) {
4444
switch (r->in.level) {
4446
result = construct_printer_info0(p->mem_ctx, ntprinter,
4447
&r->out.info->info0, snum);
4450
result = construct_printer_info1(p->mem_ctx, ntprinter,
4452
&r->out.info->info1, snum);
4455
result = construct_printer_info2(p->mem_ctx, ntprinter,
4456
&r->out.info->info2, snum);
4459
result = construct_printer_info3(p->mem_ctx, ntprinter,
4460
&r->out.info->info3, snum);
4463
result = construct_printer_info4(p->mem_ctx, ntprinter,
4464
&r->out.info->info4, snum);
4467
result = construct_printer_info5(p->mem_ctx, ntprinter,
4468
&r->out.info->info5, snum);
4471
result = construct_printer_info6(p->mem_ctx, ntprinter,
4472
&r->out.info->info6, snum);
4475
result = construct_printer_info7(p->mem_ctx, Printer,
4476
&r->out.info->info7, snum);
4479
result = construct_printer_info8(p->mem_ctx, ntprinter,
4480
&r->out.info->info8, snum);
4483
result = WERR_UNKNOWN_LEVEL;
4487
free_a_printer(&ntprinter, 2);
4489
if (!W_ERROR_IS_OK(result)) {
4490
TALLOC_FREE(r->out.info);
4494
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo, NULL,
4495
r->out.info, r->in.level);
4496
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4498
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4501
/********************************************************************
4502
********************************************************************/
4504
static const char **string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4505
const char **string_array,
4506
const char *cservername)
4508
int i, num_strings = 0;
4509
const char **array = NULL;
4511
if (!string_array) {
4515
for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4517
const char *str = talloc_asprintf(mem_ctx, "\\\\%s%s",
4518
cservername, string_array[i]);
4525
if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4532
ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4533
&array, &num_strings);
4539
#define FILL_DRIVER_STRING(mem_ctx, in, out) \
4541
if (in && strlen(in)) { \
4542
out = talloc_strdup(mem_ctx, in); \
4543
W_ERROR_HAVE_NO_MEMORY(out); \
4549
#define FILL_DRIVER_UNC_STRING(mem_ctx, server, in, out) \
4551
if (in && strlen(in)) { \
4552
out = talloc_asprintf(mem_ctx, "\\\\%s%s", server, in); \
4554
out = talloc_strdup(mem_ctx, ""); \
4556
W_ERROR_HAVE_NO_MEMORY(out); \
4559
/********************************************************************
4560
* fill a spoolss_DriverInfo1 struct
4561
********************************************************************/
4563
static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4564
struct spoolss_DriverInfo1 *r,
4565
const struct spoolss_DriverInfo8 *driver,
4566
const char *servername)
4568
r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4569
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4574
/********************************************************************
4575
* fill a spoolss_DriverInfo2 struct
4576
********************************************************************/
4578
static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4579
struct spoolss_DriverInfo2 *r,
4580
const struct spoolss_DriverInfo8 *driver,
4581
const char *servername)
4584
const char *cservername = canon_servername(servername);
4586
r->version = driver->version;
4588
r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4589
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4590
r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4591
W_ERROR_HAVE_NO_MEMORY(r->architecture);
4593
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4594
driver->driver_path,
4597
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4601
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4602
driver->config_file,
4608
/********************************************************************
4609
* fill a spoolss_DriverInfo3 struct
4610
********************************************************************/
4612
static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4613
struct spoolss_DriverInfo3 *r,
4614
const struct spoolss_DriverInfo8 *driver,
4615
const char *servername)
4617
const char *cservername = canon_servername(servername);
4619
r->version = driver->version;
4621
r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4622
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4623
r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4624
W_ERROR_HAVE_NO_MEMORY(r->architecture);
4626
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4627
driver->driver_path,
4630
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4634
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4635
driver->config_file,
4638
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4642
FILL_DRIVER_STRING(mem_ctx,
4643
driver->monitor_name,
4646
FILL_DRIVER_STRING(mem_ctx,
4647
driver->default_datatype,
4648
r->default_datatype);
4650
r->dependent_files = string_array_from_driver_info(mem_ctx,
4651
driver->dependent_files,
4656
/********************************************************************
4657
* fill a spoolss_DriverInfo4 struct
4658
********************************************************************/
4660
static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4661
struct spoolss_DriverInfo4 *r,
4662
const struct spoolss_DriverInfo8 *driver,
4663
const char *servername)
4665
const char *cservername = canon_servername(servername);
4667
r->version = driver->version;
4669
r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4670
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4671
r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4672
W_ERROR_HAVE_NO_MEMORY(r->architecture);
4674
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4675
driver->driver_path,
4678
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4682
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4683
driver->config_file,
4686
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4690
r->dependent_files = string_array_from_driver_info(mem_ctx,
4691
driver->dependent_files,
4694
FILL_DRIVER_STRING(mem_ctx,
4695
driver->monitor_name,
4698
FILL_DRIVER_STRING(mem_ctx,
4699
driver->default_datatype,
4700
r->default_datatype);
4702
r->previous_names = string_array_from_driver_info(mem_ctx,
4703
driver->previous_names,
4709
/********************************************************************
4710
* fill a spoolss_DriverInfo5 struct
4711
********************************************************************/
4713
static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4714
struct spoolss_DriverInfo5 *r,
4715
const struct spoolss_DriverInfo8 *driver,
4716
const char *servername)
4718
const char *cservername = canon_servername(servername);
4720
r->version = driver->version;
4722
r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4723
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4724
r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4725
W_ERROR_HAVE_NO_MEMORY(r->architecture);
4727
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4728
driver->driver_path,
4731
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4735
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4736
driver->config_file,
4739
r->driver_attributes = 0;
4740
r->config_version = 0;
4741
r->driver_version = 0;
4745
/********************************************************************
4746
* fill a spoolss_DriverInfo6 struct
4747
********************************************************************/
4749
static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4750
struct spoolss_DriverInfo6 *r,
4751
const struct spoolss_DriverInfo8 *driver,
4752
const char *servername)
4754
const char *cservername = canon_servername(servername);
4756
r->version = driver->version;
4758
r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4759
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4760
r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4761
W_ERROR_HAVE_NO_MEMORY(r->architecture);
4763
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4764
driver->driver_path,
4767
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4771
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4772
driver->config_file,
4775
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4779
FILL_DRIVER_STRING(mem_ctx,
4780
driver->monitor_name,
4783
FILL_DRIVER_STRING(mem_ctx,
4784
driver->default_datatype,
4785
r->default_datatype);
4787
r->dependent_files = string_array_from_driver_info(mem_ctx,
4788
driver->dependent_files,
4790
r->previous_names = string_array_from_driver_info(mem_ctx,
4791
driver->previous_names,
4794
r->driver_date = driver->driver_date;
4795
r->driver_version = driver->driver_version;
4797
FILL_DRIVER_STRING(mem_ctx,
4798
driver->manufacturer_name,
4799
r->manufacturer_name);
4800
FILL_DRIVER_STRING(mem_ctx,
4801
driver->manufacturer_url,
4802
r->manufacturer_url);
4803
FILL_DRIVER_STRING(mem_ctx,
4804
driver->hardware_id,
4806
FILL_DRIVER_STRING(mem_ctx,
4813
/********************************************************************
4814
* fill a spoolss_DriverInfo8 struct
4815
********************************************************************/
4817
static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4818
struct spoolss_DriverInfo8 *r,
4819
const struct spoolss_DriverInfo8 *driver,
4820
const char *servername)
4822
const char *cservername = canon_servername(servername);
4824
r->version = driver->version;
4826
r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4827
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4828
r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4829
W_ERROR_HAVE_NO_MEMORY(r->architecture);
4831
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4832
driver->driver_path,
4835
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4839
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4840
driver->config_file,
4843
FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4847
FILL_DRIVER_STRING(mem_ctx,
4848
driver->monitor_name,
4851
FILL_DRIVER_STRING(mem_ctx,
4852
driver->default_datatype,
4853
r->default_datatype);
4855
r->dependent_files = string_array_from_driver_info(mem_ctx,
4856
driver->dependent_files,
4858
r->previous_names = string_array_from_driver_info(mem_ctx,
4859
driver->previous_names,
4862
r->driver_date = driver->driver_date;
4863
r->driver_version = driver->driver_version;
4865
FILL_DRIVER_STRING(mem_ctx,
4866
driver->manufacturer_name,
4867
r->manufacturer_name);
4868
FILL_DRIVER_STRING(mem_ctx,
4869
driver->manufacturer_url,
4870
r->manufacturer_url);
4871
FILL_DRIVER_STRING(mem_ctx,
4872
driver->hardware_id,
4874
FILL_DRIVER_STRING(mem_ctx,
4878
FILL_DRIVER_STRING(mem_ctx,
4879
driver->print_processor,
4880
r->print_processor);
4881
FILL_DRIVER_STRING(mem_ctx,
4882
driver->vendor_setup,
4885
r->color_profiles = string_array_from_driver_info(mem_ctx,
4886
driver->color_profiles,
4889
FILL_DRIVER_STRING(mem_ctx,
4893
r->printer_driver_attributes = driver->printer_driver_attributes;
4895
r->core_driver_dependencies = string_array_from_driver_info(mem_ctx,
4896
driver->core_driver_dependencies,
4899
r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4900
r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4905
#if 0 /* disabled until marshalling issues are resolved - gd */
4906
/********************************************************************
4907
********************************************************************/
4909
static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4910
struct spoolss_DriverFileInfo *r,
4911
const char *cservername,
4912
const char *file_name,
4913
enum spoolss_DriverFileType file_type,
4914
uint32_t file_version)
4916
r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4917
cservername, file_name);
4918
W_ERROR_HAVE_NO_MEMORY(r->file_name);
4919
r->file_type = file_type;
4920
r->file_version = file_version;
4925
/********************************************************************
4926
********************************************************************/
4928
static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4929
const struct spoolss_DriverInfo8 *driver,
4930
const char *cservername,
4931
struct spoolss_DriverFileInfo **info_p,
4934
struct spoolss_DriverFileInfo *info = NULL;
4942
if (strlen(driver->driver_path)) {
4943
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4944
struct spoolss_DriverFileInfo,
4946
W_ERROR_HAVE_NO_MEMORY(info);
4947
result = fill_spoolss_DriverFileInfo(info,
4950
driver->driver_path,
4951
SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4953
W_ERROR_NOT_OK_RETURN(result);
4957
if (strlen(driver->config_file)) {
4958
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4959
struct spoolss_DriverFileInfo,
4961
W_ERROR_HAVE_NO_MEMORY(info);
4962
result = fill_spoolss_DriverFileInfo(info,
4965
driver->config_file,
4966
SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4968
W_ERROR_NOT_OK_RETURN(result);
4972
if (strlen(driver->data_file)) {
4973
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4974
struct spoolss_DriverFileInfo,
4976
W_ERROR_HAVE_NO_MEMORY(info);
4977
result = fill_spoolss_DriverFileInfo(info,
4981
SPOOLSS_DRIVER_FILE_TYPE_DATA,
4983
W_ERROR_NOT_OK_RETURN(result);
4987
if (strlen(driver->help_file)) {
4988
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4989
struct spoolss_DriverFileInfo,
4991
W_ERROR_HAVE_NO_MEMORY(info);
4992
result = fill_spoolss_DriverFileInfo(info,
4996
SPOOLSS_DRIVER_FILE_TYPE_HELP,
4998
W_ERROR_NOT_OK_RETURN(result);
5002
for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
5003
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
5004
struct spoolss_DriverFileInfo,
5006
W_ERROR_HAVE_NO_MEMORY(info);
5007
result = fill_spoolss_DriverFileInfo(info,
5010
driver->dependent_files[i],
5011
SPOOLSS_DRIVER_FILE_TYPE_OTHER,
5013
W_ERROR_NOT_OK_RETURN(result);
5023
/********************************************************************
5024
* fill a spoolss_DriverInfo101 struct
5025
********************************************************************/
5027
static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
5028
struct spoolss_DriverInfo101 *r,
5029
const struct spoolss_DriverInfo8 *driver,
5030
const char *servername)
5032
const char *cservername = canon_servername(servername);
5035
r->version = driver->version;
5037
r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
5038
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
5039
r->architecture = talloc_strdup(mem_ctx, driver->architecture);
5040
W_ERROR_HAVE_NO_MEMORY(r->architecture);
5042
result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
5046
if (!W_ERROR_IS_OK(result)) {
5050
FILL_DRIVER_STRING(mem_ctx,
5051
driver->monitor_name,
5054
FILL_DRIVER_STRING(mem_ctx,
5055
driver->default_datatype,
5056
r->default_datatype);
5058
r->previous_names = string_array_from_driver_info(mem_ctx,
5059
driver->previous_names,
5061
r->driver_date = driver->driver_date;
5062
r->driver_version = driver->driver_version;
5064
FILL_DRIVER_STRING(mem_ctx,
5065
driver->manufacturer_name,
5066
r->manufacturer_name);
5067
FILL_DRIVER_STRING(mem_ctx,
5068
driver->manufacturer_url,
5069
r->manufacturer_url);
5070
FILL_DRIVER_STRING(mem_ctx,
5071
driver->hardware_id,
5073
FILL_DRIVER_STRING(mem_ctx,
5080
/********************************************************************
5081
********************************************************************/
5083
static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
5085
union spoolss_DriverInfo *r,
5087
const char *servername,
5088
const char *architecture,
5091
NT_PRINTER_INFO_LEVEL *printer = NULL;
5092
struct spoolss_DriverInfo8 *driver;
5095
result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
5097
DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5098
win_errstr(result)));
5100
if (!W_ERROR_IS_OK(result)) {
5101
return WERR_INVALID_PRINTER_NAME;
5104
result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5105
architecture, version);
5107
DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
5108
win_errstr(result)));
5110
if (!W_ERROR_IS_OK(result)) {
5112
* Is this a W2k client ?
5116
free_a_printer(&printer, 2);
5117
return WERR_UNKNOWN_PRINTER_DRIVER;
5120
/* Yes - try again with a WinNT driver. */
5122
result = get_a_printer_driver(mem_ctx, &driver, printer->info_2->drivername,
5123
architecture, version);
5124
DEBUG(8,("construct_printer_driver_level: status: %s\n",
5125
win_errstr(result)));
5126
if (!W_ERROR_IS_OK(result)) {
5127
free_a_printer(&printer, 2);
5128
return WERR_UNKNOWN_PRINTER_DRIVER;
5134
result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
5137
result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5140
result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5143
result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5146
result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5149
result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5152
result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5154
#if 0 /* disabled until marshalling issues are resolved - gd */
5156
result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5160
result = WERR_UNKNOWN_LEVEL;
5164
free_a_printer(&printer, 2);
5165
free_a_printer_driver(driver);
5170
/****************************************************************
5171
_spoolss_GetPrinterDriver2
5172
****************************************************************/
5174
WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
5175
struct spoolss_GetPrinterDriver2 *r)
5177
Printer_entry *printer;
5180
const char *servername;
5183
/* that's an [in out] buffer */
5185
if (!r->in.buffer && (r->in.offered != 0)) {
5186
return WERR_INVALID_PARAM;
5189
DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5191
if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5192
DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5193
return WERR_INVALID_PRINTER_NAME;
5197
*r->out.server_major_version = 0;
5198
*r->out.server_minor_version = 0;
5200
servername = get_server_name(printer);
5202
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5206
result = construct_printer_driver_info_level(p->mem_ctx, r->in.level,
5210
r->in.client_major_version);
5211
if (!W_ERROR_IS_OK(result)) {
5212
TALLOC_FREE(r->out.info);
5216
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo, NULL,
5217
r->out.info, r->in.level);
5218
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5220
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5224
/****************************************************************
5225
_spoolss_StartPagePrinter
5226
****************************************************************/
5228
WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5229
struct spoolss_StartPagePrinter *r)
5231
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5234
DEBUG(3,("_spoolss_StartPagePrinter: "
5235
"Error in startpageprinter printer handle\n"));
5239
Printer->page_started = true;
5243
/****************************************************************
5244
_spoolss_EndPagePrinter
5245
****************************************************************/
5247
WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5248
struct spoolss_EndPagePrinter *r)
5252
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5255
DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5256
OUR_HANDLE(r->in.handle)));
5260
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5263
Printer->page_started = false;
5264
print_job_endpage(snum, Printer->jobid);
5269
/****************************************************************
5270
_spoolss_StartDocPrinter
5271
****************************************************************/
5273
WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5274
struct spoolss_StartDocPrinter *r)
5276
struct spoolss_DocumentInfo1 *info_1;
5278
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5281
DEBUG(2,("_spoolss_StartDocPrinter: "
5282
"Invalid handle (%s:%u:%u)\n",
5283
OUR_HANDLE(r->in.handle)));
5287
if (r->in.level != 1) {
5288
return WERR_UNKNOWN_LEVEL;
5291
info_1 = r->in.info.info1;
5294
* a nice thing with NT is it doesn't listen to what you tell it.
5295
* when asked to send _only_ RAW datas, it tries to send datas
5298
* So I add checks like in NT Server ...
5301
if (info_1->datatype) {
5302
if (strcmp(info_1->datatype, "RAW") != 0) {
5304
return WERR_INVALID_DATATYPE;
5308
/* get the share number of the printer */
5309
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5313
Printer->jobid = print_job_start(p->server_info, snum,
5314
info_1->document_name,
5315
Printer->nt_devmode);
5317
/* An error occured in print_job_start() so return an appropriate
5320
if (Printer->jobid == -1) {
5321
return map_werror_from_unix(errno);
5324
Printer->document_started = true;
5325
*r->out.job_id = Printer->jobid;
5330
/****************************************************************
5331
_spoolss_EndDocPrinter
5332
****************************************************************/
5334
WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5335
struct spoolss_EndDocPrinter *r)
5337
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5341
DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5342
OUR_HANDLE(r->in.handle)));
5346
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5350
Printer->document_started = false;
5351
print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5352
/* error codes unhandled so far ... */
5357
/****************************************************************
5358
_spoolss_WritePrinter
5359
****************************************************************/
5361
WERROR _spoolss_WritePrinter(pipes_struct *p,
5362
struct spoolss_WritePrinter *r)
5364
uint32_t buffer_written;
5366
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5369
DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5370
OUR_HANDLE(r->in.handle)));
5371
*r->out.num_written = r->in._data_size;
5375
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5378
buffer_written = (uint32_t)print_job_write(snum, Printer->jobid,
5379
(const char *)r->in.data.data,
5381
(size_t)r->in._data_size);
5382
if (buffer_written == (uint32_t)-1) {
5383
*r->out.num_written = 0;
5384
if (errno == ENOSPC)
5385
return WERR_NO_SPOOL_SPACE;
5387
return WERR_ACCESS_DENIED;
5390
*r->out.num_written = r->in._data_size;
5395
/********************************************************************
5396
* api_spoolss_getprinter
5397
* called from the spoolss dispatcher
5399
********************************************************************/
5401
static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5405
WERROR errcode = WERR_BADFUNC;
5406
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5409
DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5410
OUR_HANDLE(handle)));
5414
if (!get_printer_snum(p, handle, &snum, NULL))
5418
case SPOOLSS_PRINTER_CONTROL_PAUSE:
5419
errcode = print_queue_pause(p->server_info, snum);
5421
case SPOOLSS_PRINTER_CONTROL_RESUME:
5422
case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5423
errcode = print_queue_resume(p->server_info, snum);
5425
case SPOOLSS_PRINTER_CONTROL_PURGE:
5426
errcode = print_queue_purge(p->server_info, snum);
5429
return WERR_UNKNOWN_LEVEL;
5436
/****************************************************************
5437
_spoolss_AbortPrinter
5438
* From MSDN: "Deletes printer's spool file if printer is configured
5440
****************************************************************/
5442
WERROR _spoolss_AbortPrinter(pipes_struct *p,
5443
struct spoolss_AbortPrinter *r)
5445
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5447
WERROR errcode = WERR_OK;
5450
DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5451
OUR_HANDLE(r->in.handle)));
5455
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5458
print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5463
/********************************************************************
5464
* called by spoolss_api_setprinter
5465
* when updating a printer description
5466
********************************************************************/
5468
static WERROR update_printer_sec(struct policy_handle *handle,
5469
pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
5471
SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
5475
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5477
if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5478
DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5479
OUR_HANDLE(handle)));
5481
result = WERR_BADFID;
5486
DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5487
result = WERR_INVALID_PARAM;
5491
/* Check the user has permissions to change the security
5492
descriptor. By experimentation with two NT machines, the user
5493
requires Full Access to the printer to change security
5496
if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5497
DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5498
result = WERR_ACCESS_DENIED;
5502
/* NT seems to like setting the security descriptor even though
5503
nothing may have actually changed. */
5505
if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
5506
DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
5507
result = WERR_BADFID;
5511
if (DEBUGLEVEL >= 10) {
5515
the_acl = old_secdesc_ctr->sd->dacl;
5516
DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5517
PRINTERNAME(snum), the_acl->num_aces));
5519
for (i = 0; i < the_acl->num_aces; i++) {
5520
DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5521
&the_acl->aces[i].trustee),
5522
the_acl->aces[i].access_mask));
5525
the_acl = secdesc_ctr->sd->dacl;
5528
DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5529
PRINTERNAME(snum), the_acl->num_aces));
5531
for (i = 0; i < the_acl->num_aces; i++) {
5532
DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5533
&the_acl->aces[i].trustee),
5534
the_acl->aces[i].access_mask));
5537
DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5541
new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
5542
if (!new_secdesc_ctr) {
5543
result = WERR_NOMEM;
5547
if (security_descriptor_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
5552
result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
5559
/********************************************************************
5560
Canonicalize printer info from a client
5562
ATTN: It does not matter what we set the servername to hear
5563
since we do the necessary work in get_a_printer() to set it to
5564
the correct value based on what the client sent in the
5565
_spoolss_open_printer_ex().
5566
********************************************************************/
5568
static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
5570
fstring printername;
5573
DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5574
"portname=%s drivername=%s comment=%s location=%s\n",
5575
info->servername, info->printername, info->sharename,
5576
info->portname, info->drivername, info->comment, info->location));
5578
/* we force some elements to "correct" values */
5579
slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
5580
fstrcpy(info->sharename, lp_servicename(snum));
5582
/* check to see if we allow printername != sharename */
5584
if ( lp_force_printername(snum) ) {
5585
slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5586
global_myname(), info->sharename );
5589
/* make sure printername is in \\server\printername format */
5591
fstrcpy( printername, info->printername );
5593
if ( printername[0] == '\\' && printername[1] == '\\' ) {
5594
if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5598
slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
5599
global_myname(), p );
5602
info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5603
info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5610
/****************************************************************************
5611
****************************************************************************/
5613
static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5615
char *cmd = lp_addport_cmd();
5616
char *command = NULL;
5618
SE_PRIV se_printop = SE_PRINT_OPERATOR;
5619
bool is_print_op = false;
5622
return WERR_ACCESS_DENIED;
5625
command = talloc_asprintf(ctx,
5626
"%s \"%s\" \"%s\"", cmd, portname, uri );
5632
is_print_op = user_has_privileges( token, &se_printop );
5634
DEBUG(10,("Running [%s]\n", command));
5636
/********* BEGIN SePrintOperatorPrivilege **********/
5641
ret = smbrun(command, NULL);
5646
/********* END SePrintOperatorPrivilege **********/
5648
DEBUGADD(10,("returned [%d]\n", ret));
5650
TALLOC_FREE(command);
5653
return WERR_ACCESS_DENIED;
5659
/****************************************************************************
5660
****************************************************************************/
5662
bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
5664
char *cmd = lp_addprinter_cmd();
5666
char *command = NULL;
5670
SE_PRIV se_printop = SE_PRINT_OPERATOR;
5671
bool is_print_op = false;
5672
char *remote_machine = talloc_strdup(ctx, "%m");
5674
if (!remote_machine) {
5677
remote_machine = talloc_sub_basic(ctx,
5678
current_user_info.smb_name,
5679
current_user_info.domain,
5681
if (!remote_machine) {
5685
command = talloc_asprintf(ctx,
5686
"%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5687
cmd, printer->info_2->printername, printer->info_2->sharename,
5688
printer->info_2->portname, printer->info_2->drivername,
5689
printer->info_2->location, printer->info_2->comment, remote_machine);
5695
is_print_op = user_has_privileges( token, &se_printop );
5697
DEBUG(10,("Running [%s]\n", command));
5699
/********* BEGIN SePrintOperatorPrivilege **********/
5704
if ( (ret = smbrun(command, &fd)) == 0 ) {
5705
/* Tell everyone we updated smb.conf. */
5706
message_send_all(smbd_messaging_context(),
5707
MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5713
/********* END SePrintOperatorPrivilege **********/
5715
DEBUGADD(10,("returned [%d]\n", ret));
5717
TALLOC_FREE(command);
5718
TALLOC_FREE(remote_machine);
5726
/* reload our services immediately */
5728
reload_services(false);
5732
/* Get lines and convert them back to dos-codepage */
5733
qlines = fd_lines_load(fd, &numlines, 0, NULL);
5734
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5737
/* Set the portname to what the script says the portname should be. */
5738
/* but don't require anything to be return from the script exit a good error code */
5741
/* Set the portname to what the script says the portname should be. */
5742
strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
5743
DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5746
TALLOC_FREE(qlines);
5751
/********************************************************************
5752
* Called by spoolss_api_setprinter
5753
* when updating a printer description.
5754
********************************************************************/
5756
static WERROR update_printer(pipes_struct *p, struct policy_handle *handle,
5757
struct spoolss_SetPrinterInfoCtr *info_ctr,
5758
struct spoolss_DeviceMode *devmode)
5761
NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
5762
Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5767
DEBUG(8,("update_printer\n"));
5772
result = WERR_BADFID;
5776
if (!get_printer_snum(p, handle, &snum, NULL)) {
5777
result = WERR_BADFID;
5781
if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
5782
(!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
5783
result = WERR_BADFID;
5787
DEBUGADD(8,("Converting info_2 struct\n"));
5790
* convert_printer_info converts the incoming
5791
* info from the client and overwrites the info
5792
* just read from the tdb in the pointer 'printer'.
5795
if (!convert_printer_info(info_ctr, printer)) {
5796
result = WERR_NOMEM;
5801
/* we have a valid devmode
5802
convert it and link it*/
5804
DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
5805
if (!convert_devicemode(printer->info_2->printername, devmode,
5806
&printer->info_2->devmode)) {
5807
result = WERR_NOMEM;
5812
/* Do sanity check on the requested changes for Samba */
5814
if (!check_printer_ok(printer->info_2, snum)) {
5815
result = WERR_INVALID_PARAM;
5819
/* FIXME!!! If the driver has changed we really should verify that
5820
it is installed before doing much else --jerry */
5822
/* Check calling user has permission to update printer description */
5824
if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5825
DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5826
result = WERR_ACCESS_DENIED;
5830
/* Call addprinter hook */
5831
/* Check changes to see if this is really needed */
5833
if ( *lp_addprinter_cmd()
5834
&& (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
5835
|| !strequal(printer->info_2->comment, old_printer->info_2->comment)
5836
|| !strequal(printer->info_2->portname, old_printer->info_2->portname)
5837
|| !strequal(printer->info_2->location, old_printer->info_2->location)) )
5839
/* add_printer_hook() will call reload_services() */
5841
if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
5843
result = WERR_ACCESS_DENIED;
5849
* When a *new* driver is bound to a printer, the drivername is used to
5850
* lookup previously saved driver initialization info, which is then
5851
* bound to the printer, simulating what happens in the Windows arch.
5853
if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
5855
if (!set_driver_init(printer, 2))
5857
DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
5858
printer->info_2->drivername));
5861
DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5862
printer->info_2->drivername));
5864
notify_printer_driver(snum, printer->info_2->drivername);
5868
* flag which changes actually occured. This is a small subset of
5869
* all the possible changes. We also have to update things in the
5873
if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
5874
push_reg_sz(talloc_tos(), &buffer, printer->info_2->comment);
5875
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
5876
REG_SZ, buffer.data, buffer.length);
5878
notify_printer_comment(snum, printer->info_2->comment);
5881
if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
5882
push_reg_sz(talloc_tos(), &buffer, printer->info_2->sharename);
5883
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
5884
REG_SZ, buffer.data, buffer.length);
5886
notify_printer_sharename(snum, printer->info_2->sharename);
5889
if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
5892
if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
5895
pname = printer->info_2->printername;
5898
push_reg_sz(talloc_tos(), &buffer, pname);
5899
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
5900
REG_SZ, buffer.data, buffer.length);
5902
notify_printer_printername( snum, pname );
5905
if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
5906
push_reg_sz(talloc_tos(), &buffer, printer->info_2->portname);
5907
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
5908
REG_SZ, buffer.data, buffer.length);
5910
notify_printer_port(snum, printer->info_2->portname);
5913
if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
5914
push_reg_sz(talloc_tos(), &buffer, printer->info_2->location);
5915
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
5916
REG_SZ, buffer.data, buffer.length);
5918
notify_printer_location(snum, printer->info_2->location);
5921
/* here we need to update some more DsSpooler keys */
5922
/* uNCName, serverName, shortServerName */
5924
push_reg_sz(talloc_tos(), &buffer, global_myname());
5925
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
5926
REG_SZ, buffer.data, buffer.length);
5927
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
5928
REG_SZ, buffer.data, buffer.length);
5930
slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
5931
global_myname(), printer->info_2->sharename );
5932
push_reg_sz(talloc_tos(), &buffer, asc_buffer);
5933
set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
5934
REG_SZ, buffer.data, buffer.length);
5936
/* Update printer info */
5937
result = mod_a_printer(printer, 2);
5940
free_a_printer(&printer, 2);
5941
free_a_printer(&old_printer, 2);
5947
/****************************************************************************
5948
****************************************************************************/
5949
static WERROR publish_or_unpublish_printer(pipes_struct *p,
5950
struct policy_handle *handle,
5951
struct spoolss_SetPrinterInfo7 *info7)
5955
Printer_entry *Printer;
5957
if ( lp_security() != SEC_ADS ) {
5958
return WERR_UNKNOWN_LEVEL;
5961
Printer = find_printer_index_by_hnd(p, handle);
5963
DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
5968
if (!get_printer_snum(p, handle, &snum, NULL))
5971
nt_printer_publish(Printer, snum, info7->action);
5975
return WERR_UNKNOWN_LEVEL;
5979
/****************************************************************
5981
****************************************************************/
5983
WERROR _spoolss_SetPrinter(pipes_struct *p,
5984
struct spoolss_SetPrinter *r)
5988
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5991
DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
5992
OUR_HANDLE(r->in.handle)));
5996
/* check the level */
5997
switch (r->in.info_ctr->level) {
5999
return control_printer(r->in.handle, r->in.command, p);
6001
result = update_printer(p, r->in.handle,
6003
r->in.devmode_ctr->devmode);
6004
if (!W_ERROR_IS_OK(result))
6006
if (r->in.secdesc_ctr->sd)
6007
result = update_printer_sec(r->in.handle, p,
6011
return update_printer_sec(r->in.handle, p,
6014
return publish_or_unpublish_printer(p, r->in.handle,
6015
r->in.info_ctr->info.info7);
6017
return WERR_UNKNOWN_LEVEL;
6021
/****************************************************************
6022
_spoolss_FindClosePrinterNotify
6023
****************************************************************/
6025
WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6026
struct spoolss_FindClosePrinterNotify *r)
6028
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6031
DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6032
"Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6036
if (Printer->notify.client_connected == true) {
6039
if ( Printer->printer_type == SPLHND_SERVER)
6041
else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6042
!get_printer_snum(p, r->in.handle, &snum, NULL) )
6045
srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6048
Printer->notify.flags=0;
6049
Printer->notify.options=0;
6050
Printer->notify.localmachine[0]='\0';
6051
Printer->notify.printerlocal=0;
6052
TALLOC_FREE(Printer->notify.option);
6053
Printer->notify.client_connected = false;
6058
/****************************************************************
6060
****************************************************************/
6062
WERROR _spoolss_AddJob(pipes_struct *p,
6063
struct spoolss_AddJob *r)
6065
if (!r->in.buffer && (r->in.offered != 0)) {
6066
return WERR_INVALID_PARAM;
6069
/* this is what a NT server returns for AddJob. AddJob must fail on
6070
* non-local printers */
6072
if (r->in.level != 1) {
6073
return WERR_UNKNOWN_LEVEL;
6076
return WERR_INVALID_PARAM;
6079
/****************************************************************************
6081
****************************************************************************/
6083
static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6084
struct spoolss_JobInfo1 *r,
6085
const print_queue_struct *queue,
6086
int position, int snum,
6087
const NT_PRINTER_INFO_LEVEL *ntprinter)
6091
t = gmtime(&queue->time);
6093
r->job_id = queue->job;
6095
r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6096
W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6097
r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6098
W_ERROR_HAVE_NO_MEMORY(r->server_name);
6099
r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6100
W_ERROR_HAVE_NO_MEMORY(r->user_name);
6101
r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6102
W_ERROR_HAVE_NO_MEMORY(r->document_name);
6103
r->data_type = talloc_strdup(mem_ctx, "RAW");
6104
W_ERROR_HAVE_NO_MEMORY(r->data_type);
6105
r->text_status = talloc_strdup(mem_ctx, "");
6106
W_ERROR_HAVE_NO_MEMORY(r->text_status);
6108
r->status = nt_printj_status(queue->status);
6109
r->priority = queue->priority;
6110
r->position = position;
6111
r->total_pages = queue->page_count;
6112
r->pages_printed = 0; /* ??? */
6114
init_systemtime(&r->submitted, t);
6119
/****************************************************************************
6121
****************************************************************************/
6123
static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6124
struct spoolss_JobInfo2 *r,
6125
const print_queue_struct *queue,
6126
int position, int snum,
6127
const NT_PRINTER_INFO_LEVEL *ntprinter,
6128
struct spoolss_DeviceMode *devmode)
6132
t = gmtime(&queue->time);
6134
r->job_id = queue->job;
6136
r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6137
W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6138
r->server_name = talloc_strdup(mem_ctx, ntprinter->info_2->servername);
6139
W_ERROR_HAVE_NO_MEMORY(r->server_name);
6140
r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6141
W_ERROR_HAVE_NO_MEMORY(r->user_name);
6142
r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6143
W_ERROR_HAVE_NO_MEMORY(r->document_name);
6144
r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6145
W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6146
r->data_type = talloc_strdup(mem_ctx, "RAW");
6147
W_ERROR_HAVE_NO_MEMORY(r->data_type);
6148
r->print_processor = talloc_strdup(mem_ctx, "winprint");
6149
W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6150
r->parameters = talloc_strdup(mem_ctx, "");
6151
W_ERROR_HAVE_NO_MEMORY(r->parameters);
6152
r->driver_name = talloc_strdup(mem_ctx, ntprinter->info_2->drivername);
6153
W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6155
r->devmode = devmode;
6157
r->text_status = talloc_strdup(mem_ctx, "");
6158
W_ERROR_HAVE_NO_MEMORY(r->text_status);
6162
r->status = nt_printj_status(queue->status);
6163
r->priority = queue->priority;
6164
r->position = position;
6167
r->total_pages = queue->page_count;
6168
r->size = queue->size;
6169
init_systemtime(&r->submitted, t);
6171
r->pages_printed = 0; /* ??? */
6176
/****************************************************************************
6178
****************************************************************************/
6180
static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6181
struct spoolss_JobInfo3 *r,
6182
const print_queue_struct *queue,
6183
const print_queue_struct *next_queue,
6184
int position, int snum,
6185
const NT_PRINTER_INFO_LEVEL *ntprinter)
6187
r->job_id = queue->job;
6190
r->next_job_id = next_queue->job;
6197
/****************************************************************************
6198
Enumjobs at level 1.
6199
****************************************************************************/
6201
static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6202
const print_queue_struct *queue,
6203
uint32_t num_queues, int snum,
6204
const NT_PRINTER_INFO_LEVEL *ntprinter,
6205
union spoolss_JobInfo **info_p,
6208
union spoolss_JobInfo *info;
6210
WERROR result = WERR_OK;
6212
info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6213
W_ERROR_HAVE_NO_MEMORY(info);
6215
*count = num_queues;
6217
for (i=0; i<*count; i++) {
6218
result = fill_job_info1(info,
6224
if (!W_ERROR_IS_OK(result)) {
6230
if (!W_ERROR_IS_OK(result)) {
6241
/****************************************************************************
6242
Enumjobs at level 2.
6243
****************************************************************************/
6245
static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6246
const print_queue_struct *queue,
6247
uint32_t num_queues, int snum,
6248
const NT_PRINTER_INFO_LEVEL *ntprinter,
6249
union spoolss_JobInfo **info_p,
6252
union spoolss_JobInfo *info;
6254
WERROR result = WERR_OK;
6256
info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6257
W_ERROR_HAVE_NO_MEMORY(info);
6259
*count = num_queues;
6261
for (i=0; i<*count; i++) {
6263
struct spoolss_DeviceMode *devmode;
6265
devmode = construct_dev_mode(info, lp_const_servicename(snum));
6267
result = WERR_NOMEM;
6271
result = fill_job_info2(info,
6278
if (!W_ERROR_IS_OK(result)) {
6284
if (!W_ERROR_IS_OK(result)) {
6295
/****************************************************************************
6296
Enumjobs at level 3.
6297
****************************************************************************/
6299
static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6300
const print_queue_struct *queue,
6301
uint32_t num_queues, int snum,
6302
const NT_PRINTER_INFO_LEVEL *ntprinter,
6303
union spoolss_JobInfo **info_p,
6306
union spoolss_JobInfo *info;
6308
WERROR result = WERR_OK;
6310
info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6311
W_ERROR_HAVE_NO_MEMORY(info);
6313
*count = num_queues;
6315
for (i=0; i<*count; i++) {
6316
const print_queue_struct *next_queue = NULL;
6319
next_queue = &queue[i+1];
6322
result = fill_job_info3(info,
6329
if (!W_ERROR_IS_OK(result)) {
6335
if (!W_ERROR_IS_OK(result)) {
6346
/****************************************************************
6348
****************************************************************/
6350
WERROR _spoolss_EnumJobs(pipes_struct *p,
6351
struct spoolss_EnumJobs *r)
6354
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6356
print_status_struct prt_status;
6357
print_queue_struct *queue = NULL;
6360
/* that's an [in out] buffer */
6362
if (!r->in.buffer && (r->in.offered != 0)) {
6363
return WERR_INVALID_PARAM;
6366
DEBUG(4,("_spoolss_EnumJobs\n"));
6370
*r->out.info = NULL;
6372
/* lookup the printer snum and tdb entry */
6374
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6378
result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6379
if (!W_ERROR_IS_OK(result)) {
6383
count = print_queue_status(snum, &queue, &prt_status);
6384
DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6385
count, prt_status.status, prt_status.message));
6389
free_a_printer(&ntprinter, 2);
6393
switch (r->in.level) {
6395
result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6396
ntprinter, r->out.info, r->out.count);
6399
result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6400
ntprinter, r->out.info, r->out.count);
6403
result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6404
ntprinter, r->out.info, r->out.count);
6407
result = WERR_UNKNOWN_LEVEL;
6412
free_a_printer(&ntprinter, 2);
6414
if (!W_ERROR_IS_OK(result)) {
6418
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6419
spoolss_EnumJobs, NULL,
6420
*r->out.info, r->in.level,
6422
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6423
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6425
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6428
/****************************************************************
6429
_spoolss_ScheduleJob
6430
****************************************************************/
6432
WERROR _spoolss_ScheduleJob(pipes_struct *p,
6433
struct spoolss_ScheduleJob *r)
6438
/****************************************************************
6440
****************************************************************/
6442
WERROR _spoolss_SetJob(pipes_struct *p,
6443
struct spoolss_SetJob *r)
6446
WERROR errcode = WERR_BADFUNC;
6448
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6452
if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6453
return WERR_INVALID_PRINTER_NAME;
6456
switch (r->in.command) {
6457
case SPOOLSS_JOB_CONTROL_CANCEL:
6458
case SPOOLSS_JOB_CONTROL_DELETE:
6459
if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) {
6463
case SPOOLSS_JOB_CONTROL_PAUSE:
6464
if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6468
case SPOOLSS_JOB_CONTROL_RESTART:
6469
case SPOOLSS_JOB_CONTROL_RESUME:
6470
if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6475
return WERR_UNKNOWN_LEVEL;
6481
/****************************************************************************
6482
Enumerates all printer drivers by level and architecture.
6483
****************************************************************************/
6485
static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6486
const char *servername,
6487
const char *architecture,
6489
union spoolss_DriverInfo **info_p,
6495
fstring *list = NULL;
6496
struct spoolss_DriverInfo8 *driver;
6497
union spoolss_DriverInfo *info = NULL;
6499
WERROR result = WERR_OK;
6504
for (version=0; version<DRIVER_MAX_VERSION; version++) {
6506
ndrivers = get_ntdrivers(&list, architecture, version);
6507
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
6508
ndrivers, architecture, version));
6510
if (ndrivers == -1) {
6511
result = WERR_NOMEM;
6515
if (ndrivers != 0) {
6516
info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6517
union spoolss_DriverInfo,
6520
DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6521
"failed to enlarge driver info buffer!\n"));
6522
result = WERR_NOMEM;
6527
for (i=0; i<ndrivers; i++) {
6528
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6529
ZERO_STRUCT(driver);
6530
result = get_a_printer_driver(mem_ctx, &driver, list[i],
6531
architecture, version);
6532
if (!W_ERROR_IS_OK(result)) {
6538
result = fill_printer_driver_info1(info, &info[count+i].info1,
6539
driver, servername);
6542
result = fill_printer_driver_info2(info, &info[count+i].info2,
6543
driver, servername);
6546
result = fill_printer_driver_info3(info, &info[count+i].info3,
6547
driver, servername);
6550
result = fill_printer_driver_info4(info, &info[count+i].info4,
6551
driver, servername);
6554
result = fill_printer_driver_info5(info, &info[count+i].info5,
6555
driver, servername);
6558
result = fill_printer_driver_info6(info, &info[count+i].info6,
6559
driver, servername);
6562
result = fill_printer_driver_info8(info, &info[count+i].info8,
6563
driver, servername);
6566
result = WERR_UNKNOWN_LEVEL;
6570
free_a_printer_driver(driver);
6572
if (!W_ERROR_IS_OK(result)) {
6584
if (!W_ERROR_IS_OK(result)) {
6595
/****************************************************************************
6596
Enumerates all printer drivers by level.
6597
****************************************************************************/
6599
static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6600
const char *servername,
6601
const char *architecture,
6603
union spoolss_DriverInfo **info_p,
6607
WERROR result = WERR_OK;
6609
if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6611
for (a=0; archi_table[a].long_archi != NULL; a++) {
6613
union spoolss_DriverInfo *info = NULL;
6616
result = enumprinterdrivers_level_by_architecture(mem_ctx,
6618
archi_table[a].long_archi,
6622
if (!W_ERROR_IS_OK(result)) {
6626
for (i=0; i < count; i++) {
6627
ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6628
info[i], info_p, count_p);
6635
return enumprinterdrivers_level_by_architecture(mem_ctx,
6643
/****************************************************************
6644
_spoolss_EnumPrinterDrivers
6645
****************************************************************/
6647
WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
6648
struct spoolss_EnumPrinterDrivers *r)
6650
const char *cservername;
6653
/* that's an [in out] buffer */
6655
if (!r->in.buffer && (r->in.offered != 0)) {
6656
return WERR_INVALID_PARAM;
6659
DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6663
*r->out.info = NULL;
6665
cservername = canon_servername(r->in.server);
6667
if (!is_myname_or_ipaddr(cservername)) {
6668
return WERR_UNKNOWN_PRINTER_DRIVER;
6671
result = enumprinterdrivers_level(p->mem_ctx, cservername,
6676
if (!W_ERROR_IS_OK(result)) {
6680
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6681
spoolss_EnumPrinterDrivers, NULL,
6682
*r->out.info, r->in.level,
6684
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6685
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6687
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6690
/****************************************************************************
6691
****************************************************************************/
6693
static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
6694
struct spoolss_FormInfo1 *r,
6695
const nt_forms_struct *form)
6697
r->form_name = talloc_strdup(mem_ctx, form->name);
6698
W_ERROR_HAVE_NO_MEMORY(r->form_name);
6700
r->flags = form->flag;
6701
r->size.width = form->width;
6702
r->size.height = form->length;
6703
r->area.left = form->left;
6704
r->area.top = form->top;
6705
r->area.right = form->right;
6706
r->area.bottom = form->bottom;
6711
/****************************************************************
6712
spoolss_enumforms_level1
6713
****************************************************************/
6715
static WERROR spoolss_enumforms_level1(TALLOC_CTX *mem_ctx,
6716
const nt_forms_struct *builtin_forms,
6717
uint32_t num_builtin_forms,
6718
const nt_forms_struct *user_forms,
6719
uint32_t num_user_forms,
6720
union spoolss_FormInfo **info_p,
6723
union spoolss_FormInfo *info;
6724
WERROR result = WERR_OK;
6727
*count = num_builtin_forms + num_user_forms;
6729
info = TALLOC_ARRAY(mem_ctx, union spoolss_FormInfo, *count);
6730
W_ERROR_HAVE_NO_MEMORY(info);
6732
/* construct the list of form structures */
6733
for (i=0; i<num_builtin_forms; i++) {
6734
DEBUGADD(6,("Filling builtin form number [%d]\n",i));
6735
result = fill_form_info_1(info, &info[i].info1,
6737
if (!W_ERROR_IS_OK(result)) {
6742
for (i=0; i<num_user_forms; i++) {
6743
DEBUGADD(6,("Filling user form number [%d]\n",i));
6744
result = fill_form_info_1(info, &info[i+num_builtin_forms].info1,
6746
if (!W_ERROR_IS_OK(result)) {
6752
if (!W_ERROR_IS_OK(result)) {
6763
/****************************************************************
6765
****************************************************************/
6767
WERROR _spoolss_EnumForms(pipes_struct *p,
6768
struct spoolss_EnumForms *r)
6771
nt_forms_struct *user_forms = NULL;
6772
nt_forms_struct *builtin_forms = NULL;
6773
uint32_t num_user_forms;
6774
uint32_t num_builtin_forms;
6778
*r->out.info = NULL;
6780
/* that's an [in out] buffer */
6782
if (!r->in.buffer && (r->in.offered != 0) ) {
6783
return WERR_INVALID_PARAM;
6786
DEBUG(4,("_spoolss_EnumForms\n"));
6787
DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6788
DEBUGADD(5,("Info level [%d]\n", r->in.level));
6790
num_builtin_forms = get_builtin_ntforms(&builtin_forms);
6791
DEBUGADD(5,("Number of builtin forms [%d]\n", num_builtin_forms));
6792
num_user_forms = get_ntforms(&user_forms);
6793
DEBUGADD(5,("Number of user forms [%d]\n", num_user_forms));
6795
if (num_user_forms + num_builtin_forms == 0) {
6796
SAFE_FREE(builtin_forms);
6797
SAFE_FREE(user_forms);
6798
return WERR_NO_MORE_ITEMS;
6801
switch (r->in.level) {
6803
result = spoolss_enumforms_level1(p->mem_ctx,
6812
result = WERR_UNKNOWN_LEVEL;
6816
SAFE_FREE(user_forms);
6817
SAFE_FREE(builtin_forms);
6819
if (!W_ERROR_IS_OK(result)) {
6823
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6824
spoolss_EnumForms, NULL,
6825
*r->out.info, r->in.level,
6827
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6828
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6830
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6833
/****************************************************************
6834
****************************************************************/
6836
static WERROR find_form_byname(const char *name,
6837
nt_forms_struct *form)
6839
nt_forms_struct *list = NULL;
6840
int num_forms = 0, i = 0;
6842
if (get_a_builtin_ntform_by_string(name, form)) {
6846
num_forms = get_ntforms(&list);
6847
DEBUGADD(5,("Number of forms [%d]\n", num_forms));
6849
if (num_forms == 0) {
6853
/* Check if the requested name is in the list of form structures */
6854
for (i = 0; i < num_forms; i++) {
6856
DEBUG(4,("checking form %s (want %s)\n", list[i].name, name));
6858
if (strequal(name, list[i].name)) {
6859
DEBUGADD(6,("Found form %s number [%d]\n", name, i));
6871
/****************************************************************
6873
****************************************************************/
6875
WERROR _spoolss_GetForm(pipes_struct *p,
6876
struct spoolss_GetForm *r)
6879
nt_forms_struct form;
6881
/* that's an [in out] buffer */
6883
if (!r->in.buffer && (r->in.offered != 0)) {
6884
return WERR_INVALID_PARAM;
6887
DEBUG(4,("_spoolss_GetForm\n"));
6888
DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6889
DEBUGADD(5,("Info level [%d]\n", r->in.level));
6891
result = find_form_byname(r->in.form_name, &form);
6892
if (!W_ERROR_IS_OK(result)) {
6893
TALLOC_FREE(r->out.info);
6897
switch (r->in.level) {
6899
result = fill_form_info_1(p->mem_ctx,
6900
&r->out.info->info1,
6905
result = WERR_UNKNOWN_LEVEL;
6909
if (!W_ERROR_IS_OK(result)) {
6910
TALLOC_FREE(r->out.info);
6914
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo, NULL,
6915
r->out.info, r->in.level);
6916
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6918
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6921
/****************************************************************************
6922
****************************************************************************/
6924
static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6925
struct spoolss_PortInfo1 *r,
6928
r->port_name = talloc_strdup(mem_ctx, name);
6929
W_ERROR_HAVE_NO_MEMORY(r->port_name);
6934
/****************************************************************************
6935
TODO: This probably needs distinguish between TCP/IP and Local ports
6937
****************************************************************************/
6939
static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6940
struct spoolss_PortInfo2 *r,
6943
r->port_name = talloc_strdup(mem_ctx, name);
6944
W_ERROR_HAVE_NO_MEMORY(r->port_name);
6946
r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6947
W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6949
r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6950
W_ERROR_HAVE_NO_MEMORY(r->description);
6952
r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6959
/****************************************************************************
6960
wrapper around the enumer ports command
6961
****************************************************************************/
6963
static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6965
char *cmd = lp_enumports_cmd();
6966
char **qlines = NULL;
6967
char *command = NULL;
6975
/* if no hook then just fill in the default port */
6978
if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
6981
if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
6982
TALLOC_FREE(qlines);
6989
/* we have a valid enumport command */
6991
command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
6996
DEBUG(10,("Running [%s]\n", command));
6997
ret = smbrun(command, &fd);
6998
DEBUG(10,("Returned [%d]\n", ret));
6999
TALLOC_FREE(command);
7004
return WERR_ACCESS_DENIED;
7008
qlines = fd_lines_load(fd, &numlines, 0, NULL);
7009
DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7019
/****************************************************************************
7021
****************************************************************************/
7023
static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7024
union spoolss_PortInfo **info_p,
7027
union spoolss_PortInfo *info = NULL;
7029
WERROR result = WERR_OK;
7030
char **qlines = NULL;
7033
result = enumports_hook(talloc_tos(), &numlines, &qlines );
7034
if (!W_ERROR_IS_OK(result)) {
7039
info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7041
DEBUG(10,("Returning WERR_NOMEM\n"));
7042
result = WERR_NOMEM;
7046
for (i=0; i<numlines; i++) {
7047
DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7048
result = fill_port_1(info, &info[i].info1, qlines[i]);
7049
if (!W_ERROR_IS_OK(result)) {
7054
TALLOC_FREE(qlines);
7057
if (!W_ERROR_IS_OK(result)) {
7059
TALLOC_FREE(qlines);
7071
/****************************************************************************
7073
****************************************************************************/
7075
static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7076
union spoolss_PortInfo **info_p,
7079
union spoolss_PortInfo *info = NULL;
7081
WERROR result = WERR_OK;
7082
char **qlines = NULL;
7085
result = enumports_hook(talloc_tos(), &numlines, &qlines );
7086
if (!W_ERROR_IS_OK(result)) {
7091
info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7093
DEBUG(10,("Returning WERR_NOMEM\n"));
7094
result = WERR_NOMEM;
7098
for (i=0; i<numlines; i++) {
7099
DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7100
result = fill_port_2(info, &info[i].info2, qlines[i]);
7101
if (!W_ERROR_IS_OK(result)) {
7106
TALLOC_FREE(qlines);
7109
if (!W_ERROR_IS_OK(result)) {
7111
TALLOC_FREE(qlines);
7123
/****************************************************************
7125
****************************************************************/
7127
WERROR _spoolss_EnumPorts(pipes_struct *p,
7128
struct spoolss_EnumPorts *r)
7132
/* that's an [in out] buffer */
7134
if (!r->in.buffer && (r->in.offered != 0)) {
7135
return WERR_INVALID_PARAM;
7138
DEBUG(4,("_spoolss_EnumPorts\n"));
7142
*r->out.info = NULL;
7144
switch (r->in.level) {
7146
result = enumports_level_1(p->mem_ctx, r->out.info,
7150
result = enumports_level_2(p->mem_ctx, r->out.info,
7154
return WERR_UNKNOWN_LEVEL;
7157
if (!W_ERROR_IS_OK(result)) {
7161
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7162
spoolss_EnumPorts, NULL,
7163
*r->out.info, r->in.level,
7165
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7166
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7168
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7171
/****************************************************************************
7172
****************************************************************************/
7174
static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7176
struct spoolss_SetPrinterInfoCtr *info_ctr,
7177
struct spoolss_DeviceMode *devmode,
7178
struct security_descriptor *sec_desc,
7179
struct spoolss_UserLevelCtr *user_ctr,
7180
struct policy_handle *handle)
7182
NT_PRINTER_INFO_LEVEL *printer = NULL;
7185
WERROR err = WERR_OK;
7187
if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7188
DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7192
/* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7193
if (!convert_printer_info(info_ctr, printer)) {
7194
free_a_printer(&printer, 2);
7198
/* check to see if the printer already exists */
7200
if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7201
DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7202
printer->info_2->sharename));
7203
free_a_printer(&printer, 2);
7204
return WERR_PRINTER_ALREADY_EXISTS;
7207
/* FIXME!!! smbd should check to see if the driver is installed before
7208
trying to add a printer like this --jerry */
7210
if (*lp_addprinter_cmd() ) {
7211
if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7213
free_a_printer(&printer,2);
7214
return WERR_ACCESS_DENIED;
7217
DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7218
"smb.conf parameter \"addprinter command\" is defined. This"
7219
"parameter must exist for this call to succeed\n",
7220
printer->info_2->sharename ));
7223
/* use our primary netbios name since get_a_printer() will convert
7224
it to what the client expects on a case by case basis */
7226
slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7227
printer->info_2->sharename);
7230
if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7231
free_a_printer(&printer,2);
7232
return WERR_ACCESS_DENIED;
7235
/* you must be a printer admin to add a new printer */
7236
if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7237
free_a_printer(&printer,2);
7238
return WERR_ACCESS_DENIED;
7242
* Do sanity check on the requested changes for Samba.
7245
if (!check_printer_ok(printer->info_2, snum)) {
7246
free_a_printer(&printer,2);
7247
return WERR_INVALID_PARAM;
7251
* When a printer is created, the drivername bound to the printer is used
7252
* to lookup previously saved driver initialization info, which is then
7253
* bound to the new printer, simulating what happens in the Windows arch.
7258
set_driver_init(printer, 2);
7262
/* A valid devmode was included, convert and link it
7264
DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7266
if (!convert_devicemode(printer->info_2->printername, devmode,
7267
&printer->info_2->devmode)) {
7272
/* write the ASCII on disk */
7273
err = mod_a_printer(printer, 2);
7274
if (!W_ERROR_IS_OK(err)) {
7275
free_a_printer(&printer,2);
7279
if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7280
/* Handle open failed - remove addition. */
7281
del_a_printer(printer->info_2->sharename);
7282
free_a_printer(&printer,2);
7283
ZERO_STRUCTP(handle);
7284
return WERR_ACCESS_DENIED;
7287
update_c_setprinter(false);
7288
free_a_printer(&printer,2);
7293
/****************************************************************
7294
_spoolss_AddPrinterEx
7295
****************************************************************/
7297
WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7298
struct spoolss_AddPrinterEx *r)
7300
switch (r->in.info_ctr->level) {
7302
/* we don't handle yet */
7303
/* but I know what to do ... */
7304
return WERR_UNKNOWN_LEVEL;
7306
return spoolss_addprinterex_level_2(p, r->in.server,
7308
r->in.devmode_ctr->devmode,
7309
r->in.secdesc_ctr->sd,
7310
r->in.userlevel_ctr,
7313
return WERR_UNKNOWN_LEVEL;
7317
/****************************************************************
7319
****************************************************************/
7321
WERROR _spoolss_AddPrinter(pipes_struct *p,
7322
struct spoolss_AddPrinter *r)
7324
struct spoolss_AddPrinterEx a;
7325
struct spoolss_UserLevelCtr userlevel_ctr;
7327
ZERO_STRUCT(userlevel_ctr);
7329
userlevel_ctr.level = 1;
7331
a.in.server = r->in.server;
7332
a.in.info_ctr = r->in.info_ctr;
7333
a.in.devmode_ctr = r->in.devmode_ctr;
7334
a.in.secdesc_ctr = r->in.secdesc_ctr;
7335
a.in.userlevel_ctr = &userlevel_ctr;
7336
a.out.handle = r->out.handle;
7338
return _spoolss_AddPrinterEx(p, &a);
7341
/****************************************************************
7342
_spoolss_AddPrinterDriver
7343
****************************************************************/
7345
WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7346
struct spoolss_AddPrinterDriver *r)
7348
WERROR err = WERR_OK;
7349
char *driver_name = NULL;
7353
switch (p->hdr_req.opnum) {
7354
case NDR_SPOOLSS_ADDPRINTERDRIVER:
7355
fn = "_spoolss_AddPrinterDriver";
7357
case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7358
fn = "_spoolss_AddPrinterDriverEx";
7361
return WERR_INVALID_PARAM;
7366
if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7367
/* Clever hack from Martin Zielinski <mz@seh.de>
7368
* to allow downgrade from level 8 (Vista).
7370
DEBUG(0,("%s: level %d not yet implemented\n", fn,
7371
r->in.info_ctr->level));
7372
return WERR_UNKNOWN_LEVEL;
7375
DEBUG(5,("Cleaning driver's information\n"));
7376
err = clean_up_driver_struct(p, r->in.info_ctr);
7377
if (!W_ERROR_IS_OK(err))
7380
DEBUG(5,("Moving driver to final destination\n"));
7381
if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7386
if (add_a_printer_driver(p->mem_ctx, r->in.info_ctr, &driver_name, &version)!=0) {
7387
err = WERR_ACCESS_DENIED;
7392
* I think this is where he DrvUpgradePrinter() hook would be
7393
* be called in a driver's interface DLL on a Windows NT 4.0/2k
7394
* server. Right now, we just need to send ourselves a message
7395
* to update each printer bound to this driver. --jerry
7398
if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7399
DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7404
* Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7405
* decide if the driver init data should be deleted. The rules are:
7406
* 1) never delete init data if it is a 9x driver, they don't use it anyway
7407
* 2) delete init data only if there is no 2k/Xp driver
7408
* 3) always delete init data
7409
* The generalized rule is always use init data from the highest order driver.
7410
* It is necessary to follow the driver install by an initialization step to
7411
* finish off this process.
7416
* 9x printer driver - never delete init data
7419
DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7424
* Nt or 2k (compatiblity mode) printer driver - only delete init data if
7425
* there is no 2k/Xp driver init data for this driver name.
7429
struct spoolss_DriverInfo8 *driver1;
7431
if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &driver1, driver_name, "Windows NT x86", 3))) {
7433
* No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7435
if (!del_driver_init(driver_name))
7436
DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7440
* a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7442
free_a_printer_driver(driver1);
7443
DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7450
* 2k or Xp printer driver - always delete init data
7453
if (!del_driver_init(driver_name))
7454
DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7459
DEBUG(0,("%s: invalid level=%d\n", fn,
7460
r->in.info_ctr->level));
7469
/****************************************************************
7470
_spoolss_AddPrinterDriverEx
7471
****************************************************************/
7473
WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7474
struct spoolss_AddPrinterDriverEx *r)
7476
struct spoolss_AddPrinterDriver a;
7479
* we only support the semantics of AddPrinterDriver()
7480
* i.e. only copy files that are newer than existing ones
7483
if (r->in.flags == 0) {
7484
return WERR_INVALID_PARAM;
7487
if (r->in.flags != APD_COPY_NEW_FILES) {
7488
return WERR_ACCESS_DENIED;
7491
a.in.servername = r->in.servername;
7492
a.in.info_ctr = r->in.info_ctr;
7494
return _spoolss_AddPrinterDriver(p, &a);
7497
/****************************************************************************
7498
****************************************************************************/
7500
struct _spoolss_paths {
7506
enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7508
static const struct _spoolss_paths spoolss_paths[]= {
7509
{ SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7510
{ SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7513
static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7514
const char *servername,
7515
const char *environment,
7519
const char *pservername = NULL;
7520
const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7521
const char *short_archi;
7525
/* environment may be empty */
7526
if (environment && strlen(environment)) {
7527
long_archi = environment;
7530
/* servername may be empty */
7531
if (servername && strlen(servername)) {
7532
pservername = canon_servername(servername);
7534
if (!is_myname_or_ipaddr(pservername)) {
7535
return WERR_INVALID_PARAM;
7539
if (!(short_archi = get_short_archi(long_archi))) {
7540
return WERR_INVALID_ENVIRONMENT;
7543
switch (component) {
7544
case SPOOLSS_PRTPROCS_PATH:
7545
case SPOOLSS_DRIVER_PATH:
7547
*path = talloc_asprintf(mem_ctx,
7550
spoolss_paths[component].share,
7553
*path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7554
SPOOLSS_DEFAULT_SERVER_PATH,
7555
spoolss_paths[component].dir,
7560
return WERR_INVALID_PARAM;
7570
/****************************************************************************
7571
****************************************************************************/
7573
static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7574
const char *servername,
7575
const char *environment,
7576
struct spoolss_DriverDirectoryInfo1 *r)
7581
werr = compose_spoolss_server_path(mem_ctx,
7584
SPOOLSS_DRIVER_PATH,
7586
if (!W_ERROR_IS_OK(werr)) {
7590
DEBUG(4,("printer driver directory: [%s]\n", path));
7592
r->directory_name = path;
7597
/****************************************************************
7598
_spoolss_GetPrinterDriverDirectory
7599
****************************************************************/
7601
WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
7602
struct spoolss_GetPrinterDriverDirectory *r)
7606
/* that's an [in out] buffer */
7608
if (!r->in.buffer && (r->in.offered != 0)) {
7609
return WERR_INVALID_PARAM;
7612
DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7617
/* r->in.level is ignored */
7619
werror = getprinterdriverdir_level_1(p->mem_ctx,
7622
&r->out.info->info1);
7623
if (!W_ERROR_IS_OK(werror)) {
7624
TALLOC_FREE(r->out.info);
7628
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo, NULL,
7629
r->out.info, r->in.level);
7630
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7632
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7635
/****************************************************************
7636
_spoolss_EnumPrinterData
7637
****************************************************************/
7639
WERROR _spoolss_EnumPrinterData(pipes_struct *p,
7640
struct spoolss_EnumPrinterData *r)
7642
NT_PRINTER_INFO_LEVEL *printer = NULL;
7643
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7646
struct regval_blob *val = NULL;
7647
NT_PRINTER_DATA *p_data;
7648
int i, key_index, num_values;
7651
*r->out.value_needed = 0;
7652
*r->out.type = REG_NONE;
7653
*r->out.data_needed = 0;
7655
DEBUG(5,("_spoolss_EnumPrinterData\n"));
7658
DEBUG(2,("_spoolss_EnumPrinterData: Invalid handle (%s:%u:%u).\n",
7659
OUR_HANDLE(r->in.handle)));
7663
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7667
result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7668
if (!W_ERROR_IS_OK(result)) {
7672
p_data = printer->info_2->data;
7673
key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
7678
* The NT machine wants to know the biggest size of value and data
7680
* cf: MSDN EnumPrinterData remark section
7683
if (!r->in.value_offered && !r->in.data_offered && (key_index != -1)) {
7685
uint32_t biggest_valuesize = 0;
7686
uint32_t biggest_datasize = 0;
7688
DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7690
num_values = regval_ctr_numvals( p_data->keys[key_index].values );
7692
for ( i=0; i<num_values; i++ )
7694
val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
7696
name_length = strlen(val->valuename);
7697
if ( strlen(val->valuename) > biggest_valuesize )
7698
biggest_valuesize = name_length;
7700
if ( val->size > biggest_datasize )
7701
biggest_datasize = val->size;
7703
DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7707
/* the value is an UNICODE string but real_value_size is the length
7708
in bytes including the trailing 0 */
7710
*r->out.value_needed = 2 * (1 + biggest_valuesize);
7711
*r->out.data_needed = biggest_datasize;
7713
DEBUG(6,("final values: [%d], [%d]\n",
7714
*r->out.value_needed, *r->out.data_needed));
7720
* the value len is wrong in NT sp3
7721
* that's the number of bytes not the number of unicode chars
7724
if (key_index != -1) {
7725
val = regval_ctr_specific_value(p_data->keys[key_index].values,
7731
/* out_value should default to "" or else NT4 has
7732
problems unmarshalling the response */
7734
if (r->in.value_offered) {
7735
*r->out.value_needed = 1;
7736
r->out.value_name = talloc_strdup(r, "");
7737
if (!r->out.value_name) {
7738
result = WERR_NOMEM;
7742
r->out.value_name = NULL;
7743
*r->out.value_needed = 0;
7746
/* the data is counted in bytes */
7748
*r->out.data_needed = r->in.data_offered;
7750
result = WERR_NO_MORE_ITEMS;
7754
* - counted in bytes in the request
7755
* - counted in UNICODE chars in the max reply
7756
* - counted in bytes in the real size
7758
* take a pause *before* coding not *during* coding
7762
if (r->in.value_offered) {
7763
r->out.value_name = talloc_strdup(r, regval_name(val));
7764
if (!r->out.value_name) {
7765
result = WERR_NOMEM;
7768
*r->out.value_needed = strlen_m_term(regval_name(val)) * 2;
7770
r->out.value_name = NULL;
7771
*r->out.value_needed = 0;
7776
*r->out.type = regval_type(val);
7778
/* data - counted in bytes */
7781
* See the section "Dynamically Typed Query Parameters"
7785
if (r->out.data && regval_data_p(val) &&
7786
regval_size(val) && r->in.data_offered) {
7787
memcpy(r->out.data, regval_data_p(val),
7788
MIN(regval_size(val),r->in.data_offered));
7791
*r->out.data_needed = regval_size(val);
7795
free_a_printer(&printer, 2);
7799
/****************************************************************
7800
_spoolss_SetPrinterData
7801
****************************************************************/
7803
WERROR _spoolss_SetPrinterData(pipes_struct *p,
7804
struct spoolss_SetPrinterData *r)
7806
struct spoolss_SetPrinterDataEx r2;
7808
r2.in.handle = r->in.handle;
7809
r2.in.key_name = "PrinterDriverData";
7810
r2.in.value_name = r->in.value_name;
7811
r2.in.type = r->in.type;
7812
r2.in.data = r->in.data;
7813
r2.in.offered = r->in.offered;
7815
return _spoolss_SetPrinterDataEx(p, &r2);
7818
/****************************************************************
7819
_spoolss_ResetPrinter
7820
****************************************************************/
7822
WERROR _spoolss_ResetPrinter(pipes_struct *p,
7823
struct spoolss_ResetPrinter *r)
7825
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7828
DEBUG(5,("_spoolss_ResetPrinter\n"));
7831
* All we do is to check to see if the handle and queue is valid.
7832
* This call really doesn't mean anything to us because we only
7833
* support RAW printing. --jerry
7837
DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7838
OUR_HANDLE(r->in.handle)));
7842
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7846
/* blindly return success */
7850
/****************************************************************
7851
_spoolss_DeletePrinterData
7852
****************************************************************/
7854
WERROR _spoolss_DeletePrinterData(pipes_struct *p,
7855
struct spoolss_DeletePrinterData *r)
7857
struct spoolss_DeletePrinterDataEx r2;
7859
r2.in.handle = r->in.handle;
7860
r2.in.key_name = "PrinterDriverData";
7861
r2.in.value_name = r->in.value_name;
7863
return _spoolss_DeletePrinterDataEx(p, &r2);
7866
/****************************************************************
7868
****************************************************************/
7870
WERROR _spoolss_AddForm(pipes_struct *p,
7871
struct spoolss_AddForm *r)
7873
struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7874
nt_forms_struct tmpForm;
7876
WERROR status = WERR_OK;
7877
NT_PRINTER_INFO_LEVEL *printer = NULL;
7878
SE_PRIV se_printop = SE_PRINT_OPERATOR;
7881
nt_forms_struct *list=NULL;
7882
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7884
DEBUG(5,("_spoolss_AddForm\n"));
7887
DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7888
OUR_HANDLE(r->in.handle)));
7893
/* forms can be added on printer of on the print server handle */
7895
if ( Printer->printer_type == SPLHND_PRINTER )
7897
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7900
status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7901
if (!W_ERROR_IS_OK(status))
7905
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7906
and not a printer admin, then fail */
7908
if ((p->server_info->utok.uid != sec_initial_uid()) &&
7909
!user_has_privileges(p->server_info->ptok, &se_printop) &&
7910
!token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7911
pdb_get_domain(p->server_info->sam_account),
7913
p->server_info->ptok,
7914
lp_printer_admin(snum))) {
7915
DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7916
return WERR_ACCESS_DENIED;
7919
/* can't add if builtin */
7921
if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
7922
status = WERR_FILE_EXISTS;
7926
count = get_ntforms(&list);
7928
if(!add_a_form(&list, form, &count)) {
7929
status = WERR_NOMEM;
7934
write_ntforms(&list, count);
7938
* ChangeID must always be set if this is a printer
7941
if ( Printer->printer_type == SPLHND_PRINTER )
7942
status = mod_a_printer(printer, 2);
7946
free_a_printer(&printer, 2);
7952
/****************************************************************
7954
****************************************************************/
7956
WERROR _spoolss_DeleteForm(pipes_struct *p,
7957
struct spoolss_DeleteForm *r)
7959
const char *form_name = r->in.form_name;
7960
nt_forms_struct tmpForm;
7962
nt_forms_struct *list=NULL;
7963
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7965
WERROR status = WERR_OK;
7966
NT_PRINTER_INFO_LEVEL *printer = NULL;
7967
SE_PRIV se_printop = SE_PRINT_OPERATOR;
7970
DEBUG(5,("_spoolss_DeleteForm\n"));
7973
DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7974
OUR_HANDLE(r->in.handle)));
7978
/* forms can be deleted on printer of on the print server handle */
7980
if ( Printer->printer_type == SPLHND_PRINTER )
7982
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7985
status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
7986
if (!W_ERROR_IS_OK(status))
7990
if ((p->server_info->utok.uid != sec_initial_uid()) &&
7991
!user_has_privileges(p->server_info->ptok, &se_printop) &&
7992
!token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7993
pdb_get_domain(p->server_info->sam_account),
7995
p->server_info->ptok,
7996
lp_printer_admin(snum))) {
7997
DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7998
return WERR_ACCESS_DENIED;
8002
/* can't delete if builtin */
8004
if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8005
status = WERR_INVALID_PARAM;
8009
count = get_ntforms(&list);
8012
ret = delete_a_form(&list, form_name, &count, &status);
8019
* ChangeID must always be set if this is a printer
8022
if ( Printer->printer_type == SPLHND_PRINTER )
8023
status = mod_a_printer(printer, 2);
8027
free_a_printer(&printer, 2);
8033
/****************************************************************
8035
****************************************************************/
8037
WERROR _spoolss_SetForm(pipes_struct *p,
8038
struct spoolss_SetForm *r)
8040
struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8041
nt_forms_struct tmpForm;
8043
WERROR status = WERR_OK;
8044
NT_PRINTER_INFO_LEVEL *printer = NULL;
8045
SE_PRIV se_printop = SE_PRINT_OPERATOR;
8048
nt_forms_struct *list=NULL;
8049
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8051
DEBUG(5,("_spoolss_SetForm\n"));
8054
DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8055
OUR_HANDLE(r->in.handle)));
8059
/* forms can be modified on printer of on the print server handle */
8061
if ( Printer->printer_type == SPLHND_PRINTER )
8063
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8066
status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8067
if (!W_ERROR_IS_OK(status))
8071
/* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
8072
and not a printer admin, then fail */
8074
if ((p->server_info->utok.uid != sec_initial_uid()) &&
8075
!user_has_privileges(p->server_info->ptok, &se_printop) &&
8076
!token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
8077
pdb_get_domain(p->server_info->sam_account),
8079
p->server_info->ptok,
8080
lp_printer_admin(snum))) {
8081
DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
8082
return WERR_ACCESS_DENIED;
8085
/* can't set if builtin */
8086
if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8087
status = WERR_INVALID_PARAM;
8091
count = get_ntforms(&list);
8092
update_a_form(&list, form, count);
8094
write_ntforms(&list, count);
8098
* ChangeID must always be set if this is a printer
8101
if ( Printer->printer_type == SPLHND_PRINTER )
8102
status = mod_a_printer(printer, 2);
8107
free_a_printer(&printer, 2);
8113
/****************************************************************************
8114
fill_print_processor1
8115
****************************************************************************/
8117
static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8118
struct spoolss_PrintProcessorInfo1 *r,
8119
const char *print_processor_name)
8121
r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8122
W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8127
/****************************************************************************
8128
enumprintprocessors level 1.
8129
****************************************************************************/
8131
static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8132
union spoolss_PrintProcessorInfo **info_p,
8135
union spoolss_PrintProcessorInfo *info;
8138
info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8139
W_ERROR_HAVE_NO_MEMORY(info);
8143
result = fill_print_processor1(info, &info[0].info1, "winprint");
8144
if (!W_ERROR_IS_OK(result)) {
8149
if (!W_ERROR_IS_OK(result)) {
8160
/****************************************************************
8161
_spoolss_EnumPrintProcessors
8162
****************************************************************/
8164
WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
8165
struct spoolss_EnumPrintProcessors *r)
8169
/* that's an [in out] buffer */
8171
if (!r->in.buffer && (r->in.offered != 0)) {
8172
return WERR_INVALID_PARAM;
8175
DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8178
* Enumerate the print processors ...
8180
* Just reply with "winprint", to keep NT happy
8181
* and I can use my nice printer checker.
8186
*r->out.info = NULL;
8188
switch (r->in.level) {
8190
result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8194
return WERR_UNKNOWN_LEVEL;
8197
if (!W_ERROR_IS_OK(result)) {
8201
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8202
spoolss_EnumPrintProcessors, NULL,
8203
*r->out.info, r->in.level,
8205
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8206
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8208
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8211
/****************************************************************************
8212
fill_printprocdatatype1
8213
****************************************************************************/
8215
static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8216
struct spoolss_PrintProcDataTypesInfo1 *r,
8217
const char *name_array)
8219
r->name_array = talloc_strdup(mem_ctx, name_array);
8220
W_ERROR_HAVE_NO_MEMORY(r->name_array);
8225
/****************************************************************************
8226
enumprintprocdatatypes level 1.
8227
****************************************************************************/
8229
static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8230
union spoolss_PrintProcDataTypesInfo **info_p,
8234
union spoolss_PrintProcDataTypesInfo *info;
8236
info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8237
W_ERROR_HAVE_NO_MEMORY(info);
8241
result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8242
if (!W_ERROR_IS_OK(result)) {
8247
if (!W_ERROR_IS_OK(result)) {
8258
/****************************************************************
8259
_spoolss_EnumPrintProcDataTypes
8260
****************************************************************/
8262
WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
8263
struct spoolss_EnumPrintProcDataTypes *r)
8267
/* that's an [in out] buffer */
8269
if (!r->in.buffer && (r->in.offered != 0)) {
8270
return WERR_INVALID_PARAM;
8273
DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8277
*r->out.info = NULL;
8279
switch (r->in.level) {
8281
result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8285
return WERR_UNKNOWN_LEVEL;
8288
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8289
spoolss_EnumPrintProcDataTypes, NULL,
8290
*r->out.info, r->in.level,
8292
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8293
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8295
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8298
/****************************************************************************
8300
****************************************************************************/
8302
static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8303
struct spoolss_MonitorInfo1 *r,
8304
const char *monitor_name)
8306
r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8307
W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8312
/****************************************************************************
8314
****************************************************************************/
8316
static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8317
struct spoolss_MonitorInfo2 *r,
8318
const char *monitor_name,
8319
const char *environment,
8320
const char *dll_name)
8322
r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8323
W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8324
r->environment = talloc_strdup(mem_ctx, environment);
8325
W_ERROR_HAVE_NO_MEMORY(r->environment);
8326
r->dll_name = talloc_strdup(mem_ctx, dll_name);
8327
W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8332
/****************************************************************************
8333
enumprintmonitors level 1.
8334
****************************************************************************/
8336
static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8337
union spoolss_MonitorInfo **info_p,
8340
union spoolss_MonitorInfo *info;
8341
WERROR result = WERR_OK;
8343
info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8344
W_ERROR_HAVE_NO_MEMORY(info);
8348
result = fill_monitor_1(info, &info[0].info1,
8350
if (!W_ERROR_IS_OK(result)) {
8354
result = fill_monitor_1(info, &info[1].info1,
8356
if (!W_ERROR_IS_OK(result)) {
8361
if (!W_ERROR_IS_OK(result)) {
8372
/****************************************************************************
8373
enumprintmonitors level 2.
8374
****************************************************************************/
8376
static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8377
union spoolss_MonitorInfo **info_p,
8380
union spoolss_MonitorInfo *info;
8381
WERROR result = WERR_OK;
8383
info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8384
W_ERROR_HAVE_NO_MEMORY(info);
8388
result = fill_monitor_2(info, &info[0].info2,
8390
"Windows NT X86", /* FIXME */
8392
if (!W_ERROR_IS_OK(result)) {
8396
result = fill_monitor_2(info, &info[1].info2,
8398
"Windows NT X86", /* FIXME */
8400
if (!W_ERROR_IS_OK(result)) {
8405
if (!W_ERROR_IS_OK(result)) {
8416
/****************************************************************
8417
_spoolss_EnumMonitors
8418
****************************************************************/
8420
WERROR _spoolss_EnumMonitors(pipes_struct *p,
8421
struct spoolss_EnumMonitors *r)
8425
/* that's an [in out] buffer */
8427
if (!r->in.buffer && (r->in.offered != 0)) {
8428
return WERR_INVALID_PARAM;
8431
DEBUG(5,("_spoolss_EnumMonitors\n"));
8434
* Enumerate the print monitors ...
8436
* Just reply with "Local Port", to keep NT happy
8437
* and I can use my nice printer checker.
8442
*r->out.info = NULL;
8444
switch (r->in.level) {
8446
result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8450
result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8454
return WERR_UNKNOWN_LEVEL;
8457
if (!W_ERROR_IS_OK(result)) {
8461
*r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8462
spoolss_EnumMonitors, NULL,
8463
*r->out.info, r->in.level,
8465
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8466
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8468
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8471
/****************************************************************************
8472
****************************************************************************/
8474
static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8475
const print_queue_struct *queue,
8476
int count, int snum,
8477
const NT_PRINTER_INFO_LEVEL *ntprinter,
8479
struct spoolss_JobInfo1 *r)
8484
for (i=0; i<count && found == false; i++) {
8485
if (queue[i].job == (int)jobid) {
8490
if (found == false) {
8491
/* NT treats not found as bad param... yet another bad choice */
8492
return WERR_INVALID_PARAM;
8495
return fill_job_info1(mem_ctx,
8503
/****************************************************************************
8504
****************************************************************************/
8506
static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8507
const print_queue_struct *queue,
8508
int count, int snum,
8509
const NT_PRINTER_INFO_LEVEL *ntprinter,
8511
struct spoolss_JobInfo2 *r)
8515
struct spoolss_DeviceMode *devmode;
8516
NT_DEVICEMODE *nt_devmode;
8519
for (i=0; i<count && found == false; i++) {
8520
if (queue[i].job == (int)jobid) {
8525
if (found == false) {
8526
/* NT treats not found as bad param... yet another bad
8528
return WERR_INVALID_PARAM;
8532
* if the print job does not have a DEVMODE associated with it,
8533
* just use the one for the printer. A NULL devicemode is not
8534
* a failure condition
8537
nt_devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8539
devmode = TALLOC_ZERO_P(mem_ctx, struct spoolss_DeviceMode);
8540
W_ERROR_HAVE_NO_MEMORY(devmode);
8541
result = convert_nt_devicemode(devmode, devmode, nt_devmode);
8542
if (!W_ERROR_IS_OK(result)) {
8546
devmode = construct_dev_mode(mem_ctx, lp_const_servicename(snum));
8547
W_ERROR_HAVE_NO_MEMORY(devmode);
8550
return fill_job_info2(mem_ctx,
8559
/****************************************************************
8561
****************************************************************/
8563
WERROR _spoolss_GetJob(pipes_struct *p,
8564
struct spoolss_GetJob *r)
8566
WERROR result = WERR_OK;
8567
NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
8570
print_queue_struct *queue = NULL;
8571
print_status_struct prt_status;
8573
/* that's an [in out] buffer */
8575
if (!r->in.buffer && (r->in.offered != 0)) {
8576
return WERR_INVALID_PARAM;
8579
DEBUG(5,("_spoolss_GetJob\n"));
8583
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8587
result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
8588
if (!W_ERROR_IS_OK(result)) {
8592
count = print_queue_status(snum, &queue, &prt_status);
8594
DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8595
count, prt_status.status, prt_status.message));
8597
switch (r->in.level) {
8599
result = getjob_level_1(p->mem_ctx,
8600
queue, count, snum, ntprinter,
8601
r->in.job_id, &r->out.info->info1);
8604
result = getjob_level_2(p->mem_ctx,
8605
queue, count, snum, ntprinter,
8606
r->in.job_id, &r->out.info->info2);
8609
result = WERR_UNKNOWN_LEVEL;
8614
free_a_printer(&ntprinter, 2);
8616
if (!W_ERROR_IS_OK(result)) {
8617
TALLOC_FREE(r->out.info);
8621
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, NULL,
8622
r->out.info, r->in.level);
8623
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8625
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8628
/****************************************************************
8629
_spoolss_GetPrinterDataEx
8630
****************************************************************/
8632
WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
8633
struct spoolss_GetPrinterDataEx *r)
8636
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8637
struct regval_blob *val = NULL;
8638
NT_PRINTER_INFO_LEVEL *printer = NULL;
8640
WERROR result = WERR_OK;
8643
DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8645
DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8646
r->in.key_name, r->in.value_name));
8648
/* in case of problem, return some default values */
8651
*r->out.type = REG_NONE;
8654
DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8655
OUR_HANDLE(r->in.handle)));
8656
result = WERR_BADFID;
8660
/* Is the handle to a printer or to the server? */
8662
if (Printer->printer_type == SPLHND_SERVER) {
8664
union spoolss_PrinterData data;
8666
result = getprinterdata_printer_server(p->mem_ctx,
8670
if (!W_ERROR_IS_OK(result)) {
8674
result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8675
*r->out.type, &data);
8676
if (!W_ERROR_IS_OK(result)) {
8680
*r->out.needed = blob.length;
8682
if (r->in.offered >= *r->out.needed) {
8683
memcpy(r->out.data, blob.data, blob.length);
8686
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8689
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8690
result = WERR_BADFID;
8694
result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8695
if (!W_ERROR_IS_OK(result)) {
8699
/* check to see if the keyname is valid */
8700
if (!strlen(r->in.key_name)) {
8701
result = WERR_INVALID_PARAM;
8705
/* XP sends this and wants to change id value from the PRINTER_INFO_0 */
8707
if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8708
strequal(r->in.value_name, "ChangeId")) {
8709
*r->out.type = REG_DWORD;
8711
if (r->in.offered >= *r->out.needed) {
8712
SIVAL(r->out.data, 0, printer->info_2->changeid);
8718
if (lookup_printerkey(printer->info_2->data, r->in.key_name) == -1) {
8719
DEBUG(4,("_spoolss_GetPrinterDataEx: "
8720
"Invalid keyname [%s]\n", r->in.key_name ));
8721
result = WERR_BADFILE;
8725
val = get_printer_data(printer->info_2,
8726
r->in.key_name, r->in.value_name);
8728
result = WERR_BADFILE;
8732
*r->out.needed = regval_size(val);
8733
*r->out.type = regval_type(val);
8735
if (r->in.offered >= *r->out.needed) {
8736
memcpy(r->out.data, regval_data_p(val), regval_size(val));
8740
free_a_printer(&printer, 2);
8743
if (!W_ERROR_IS_OK(result)) {
8747
*r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8748
r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8750
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8753
/****************************************************************
8754
_spoolss_SetPrinterDataEx
8755
****************************************************************/
8757
WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
8758
struct spoolss_SetPrinterDataEx *r)
8760
NT_PRINTER_INFO_LEVEL *printer = NULL;
8762
WERROR result = WERR_OK;
8763
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8766
DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8768
/* From MSDN documentation of SetPrinterDataEx: pass request to
8769
SetPrinterData if key is "PrinterDriverData" */
8772
DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8773
OUR_HANDLE(r->in.handle)));
8777
if (Printer->printer_type == SPLHND_SERVER) {
8778
DEBUG(10,("_spoolss_SetPrinterDataEx: "
8779
"Not implemented for server handles yet\n"));
8780
return WERR_INVALID_PARAM;
8783
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8788
* Access check : NT returns "access denied" if you make a
8789
* SetPrinterData call without the necessary privildge.
8790
* we were originally returning OK if nothing changed
8791
* which made Win2k issue **a lot** of SetPrinterData
8792
* when connecting to a printer --jerry
8795
if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8796
DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8797
"change denied by handle access permissions\n"));
8798
return WERR_ACCESS_DENIED;
8801
result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
8802
if (!W_ERROR_IS_OK(result)) {
8806
/* check for OID in valuename */
8808
oid_string = strchr(r->in.value_name, ',');
8815
* When client side code sets a magic printer data key, detect it and save
8816
* the current printer data and the magic key's data (its the DEVMODE) for
8817
* future printer/driver initializations.
8819
if ((r->in.type == REG_BINARY) && strequal(r->in.value_name, PHANTOM_DEVMODE_KEY)) {
8820
/* Set devmode and printer initialization info */
8821
result = save_driver_init(printer, 2, r->in.data, r->in.offered);
8823
srv_spoolss_reset_printerdata(printer->info_2->drivername);
8828
/* save the registry data */
8830
result = set_printer_dataex(printer, r->in.key_name, r->in.value_name,
8831
r->in.type, r->in.data, r->in.offered);
8833
if (W_ERROR_IS_OK(result)) {
8834
/* save the OID if one was specified */
8836
char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8837
r->in.key_name, SPOOL_OID_KEY);
8839
result = WERR_NOMEM;
8844
* I'm not checking the status here on purpose. Don't know
8845
* if this is right, but I'm returning the status from the
8846
* previous set_printer_dataex() call. I have no idea if
8847
* this is right. --jerry
8850
set_printer_dataex(printer, str, r->in.value_name,
8851
REG_SZ, (uint8_t *)oid_string,
8852
strlen(oid_string)+1);
8855
result = mod_a_printer(printer, 2);
8859
free_a_printer(&printer, 2);
8864
/****************************************************************
8865
_spoolss_DeletePrinterDataEx
8866
****************************************************************/
8868
WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
8869
struct spoolss_DeletePrinterDataEx *r)
8871
NT_PRINTER_INFO_LEVEL *printer = NULL;
8873
WERROR status = WERR_OK;
8874
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8876
DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8879
DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8880
"Invalid handle (%s:%u:%u).\n",
8881
OUR_HANDLE(r->in.handle)));
8885
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
8888
if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8889
DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8890
"printer properties change denied by handle\n"));
8891
return WERR_ACCESS_DENIED;
8894
if (!r->in.value_name || !r->in.key_name) {
8898
status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8899
if (!W_ERROR_IS_OK(status))
8902
status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
8904
if ( W_ERROR_IS_OK(status) )
8905
mod_a_printer( printer, 2 );
8907
free_a_printer(&printer, 2);
8912
/****************************************************************
8913
_spoolss_EnumPrinterKey
8914
****************************************************************/
8916
WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
8917
struct spoolss_EnumPrinterKey *r)
8919
fstring *keynames = NULL;
8921
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8922
NT_PRINTER_DATA *data;
8923
NT_PRINTER_INFO_LEVEL *printer = NULL;
8925
WERROR result = WERR_BADFILE;
8927
const char **array = NULL;
8930
DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8933
DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8934
OUR_HANDLE(r->in.handle)));
8938
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8942
result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8943
if (!W_ERROR_IS_OK(result)) {
8947
/* get the list of subkey names */
8949
data = printer->info_2->data;
8951
num_keys = get_printer_subkeys(data, r->in.key_name, &keynames);
8952
if (num_keys == -1) {
8953
result = WERR_BADFILE;
8957
array = talloc_zero_array(r->out.key_buffer, const char *, num_keys + 2);
8959
result = WERR_NOMEM;
8964
array[0] = talloc_strdup(array, "");
8966
result = WERR_NOMEM;
8971
for (i=0; i < num_keys; i++) {
8973
DEBUG(10,("_spoolss_EnumPrinterKey: adding keyname: %s\n",
8976
array[i] = talloc_strdup(array, keynames[i]);
8978
result = WERR_NOMEM;
8983
if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8984
result = WERR_NOMEM;
8988
*r->out._ndr_size = r->in.offered / 2;
8989
*r->out.needed = blob.length;
8991
if (r->in.offered < *r->out.needed) {
8992
result = WERR_MORE_DATA;
8995
r->out.key_buffer->string_array = array;
8999
if (!W_ERROR_IS_OK(result)) {
9001
if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
9006
free_a_printer(&printer, 2);
9007
SAFE_FREE(keynames);
9012
/****************************************************************
9013
_spoolss_DeletePrinterKey
9014
****************************************************************/
9016
WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9017
struct spoolss_DeletePrinterKey *r)
9019
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9020
NT_PRINTER_INFO_LEVEL *printer = NULL;
9024
DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9027
DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9028
OUR_HANDLE(r->in.handle)));
9032
/* if keyname == NULL, return error */
9034
if ( !r->in.key_name )
9035
return WERR_INVALID_PARAM;
9037
if (!get_printer_snum(p, r->in.handle, &snum, NULL))
9040
if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9041
DEBUG(3, ("_spoolss_DeletePrinterKey: "
9042
"printer properties change denied by handle\n"));
9043
return WERR_ACCESS_DENIED;
9046
status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9047
if (!W_ERROR_IS_OK(status))
9050
/* delete the key and all subneys */
9052
status = delete_all_printer_data( printer->info_2, r->in.key_name );
9054
if ( W_ERROR_IS_OK(status) )
9055
status = mod_a_printer(printer, 2);
9057
free_a_printer( &printer, 2 );
9062
/****************************************************************
9063
****************************************************************/
9065
static WERROR registry_value_to_printer_enum_value(TALLOC_CTX *mem_ctx,
9066
struct regval_blob *v,
9067
struct spoolss_PrinterEnumValues *r)
9069
r->data = TALLOC_ZERO_P(mem_ctx, DATA_BLOB);
9070
W_ERROR_HAVE_NO_MEMORY(r->data);
9072
r->value_name = talloc_strdup(mem_ctx, regval_name(v));
9073
W_ERROR_HAVE_NO_MEMORY(r->value_name);
9075
r->type = regval_type(v);
9076
r->data_length = regval_size(v);
9078
if (r->data_length) {
9079
*r->data = data_blob_talloc(r->data, regval_data_p(v), regval_size(v));
9085
/****************************************************************
9086
_spoolss_EnumPrinterDataEx
9087
****************************************************************/
9089
WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
9090
struct spoolss_EnumPrinterDataEx *r)
9093
NT_PRINTER_INFO_LEVEL *printer = NULL;
9094
struct spoolss_PrinterEnumValues *info = NULL;
9095
NT_PRINTER_DATA *p_data;
9096
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9102
DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
9106
*r->out.info = NULL;
9109
DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
9110
OUR_HANDLE(r->in.handle)));
9115
* first check for a keyname of NULL or "". Win2k seems to send
9116
* this a lot and we should send back WERR_INVALID_PARAM
9117
* no need to spend time looking up the printer in this case.
9121
if (!strlen(r->in.key_name)) {
9122
result = WERR_INVALID_PARAM;
9126
/* get the printer off of disk */
9128
if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
9132
ZERO_STRUCT(printer);
9133
result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9134
if (!W_ERROR_IS_OK(result)) {
9138
/* now look for a match on the key name */
9140
p_data = printer->info_2->data;
9142
key_index = lookup_printerkey(p_data, r->in.key_name);
9143
if (key_index == -1) {
9144
DEBUG(10,("_spoolss_EnumPrinterDataEx: Unknown keyname [%s]\n",
9146
result = WERR_INVALID_PARAM;
9150
/* allocate the memory for the array of pointers -- if necessary */
9152
count = regval_ctr_numvals(p_data->keys[key_index].values);
9154
result = WERR_OK; /* ??? */
9158
info = TALLOC_ZERO_ARRAY(p->mem_ctx,
9159
struct spoolss_PrinterEnumValues,
9162
DEBUG(0,("_spoolss_EnumPrinterDataEx: talloc() failed\n"));
9163
result = WERR_NOMEM;
9168
* loop through all params and build the array to pass
9169
* back to the client
9172
for (i=0; i < count; i++) {
9174
struct regval_blob *val;
9176
/* lookup the registry value */
9178
val = regval_ctr_specific_value(p_data->keys[key_index].values, i);
9180
DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val)));
9184
result = registry_value_to_printer_enum_value(info, val, &info[i]);
9185
if (!W_ERROR_IS_OK(result)) {
9190
#if 0 /* FIXME - gd */
9191
/* housekeeping information in the reply */
9193
/* Fix from Martin Zielinski <mz@seh.de> - ensure
9194
* the hand marshalled container size is a multiple
9195
* of 4 bytes for RPC alignment.
9199
needed += 4-(needed % 4);
9202
*r->out.count = count;
9203
*r->out.info = info;
9208
free_a_printer(&printer, 2);
9211
if (!W_ERROR_IS_OK(result)) {
9215
*r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
9216
spoolss_EnumPrinterDataEx, NULL,
9219
*r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
9220
*r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
9222
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
9225
/****************************************************************************
9226
****************************************************************************/
9228
static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9229
const char *servername,
9230
const char *environment,
9231
struct spoolss_PrintProcessorDirectoryInfo1 *r)
9236
werr = compose_spoolss_server_path(mem_ctx,
9239
SPOOLSS_PRTPROCS_PATH,
9241
if (!W_ERROR_IS_OK(werr)) {
9245
DEBUG(4,("print processor directory: [%s]\n", path));
9247
r->directory_name = path;
9252
/****************************************************************
9253
_spoolss_GetPrintProcessorDirectory
9254
****************************************************************/
9256
WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9257
struct spoolss_GetPrintProcessorDirectory *r)
9261
/* that's an [in out] buffer */
9263
if (!r->in.buffer && (r->in.offered != 0)) {
9264
return WERR_INVALID_PARAM;
9267
DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9272
/* r->in.level is ignored */
9274
/* We always should reply with a local print processor directory so that
9275
* users are not forced to have a [prnproc$] share on the Samba spoolss
9276
* server - Guenther */
9278
result = getprintprocessordirectory_level_1(p->mem_ctx,
9279
NULL, /* r->in.server */
9281
&r->out.info->info1);
9282
if (!W_ERROR_IS_OK(result)) {
9283
TALLOC_FREE(r->out.info);
9287
*r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo, NULL,
9288
r->out.info, r->in.level);
9289
r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9291
return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9294
/*******************************************************************
9295
********************************************************************/
9297
static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9298
const char *dllname)
9300
enum ndr_err_code ndr_err;
9301
struct spoolss_MonitorUi ui;
9303
ui.dll_name = dllname;
9305
ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9306
(ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9307
if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9308
NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9310
return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9313
/*******************************************************************
9314
Streams the monitor UI DLL name in UNICODE
9315
*******************************************************************/
9317
static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9318
NT_USER_TOKEN *token, DATA_BLOB *in,
9319
DATA_BLOB *out, uint32_t *needed)
9321
const char *dllname = "tcpmonui.dll";
9323
*needed = (strlen(dllname)+1) * 2;
9325
if (out->length < *needed) {
9326
return WERR_INSUFFICIENT_BUFFER;
9329
if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9336
/*******************************************************************
9337
********************************************************************/
9339
static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9340
struct spoolss_PortData1 *port1,
9341
const DATA_BLOB *buf)
9343
enum ndr_err_code ndr_err;
9344
ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9345
(ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9346
if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9347
NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9349
return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9352
/*******************************************************************
9353
********************************************************************/
9355
static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9356
struct spoolss_PortData2 *port2,
9357
const DATA_BLOB *buf)
9359
enum ndr_err_code ndr_err;
9360
ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9361
(ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9362
if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9363
NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9365
return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9368
/*******************************************************************
9369
Create a new TCP/IP port
9370
*******************************************************************/
9372
static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9373
NT_USER_TOKEN *token, DATA_BLOB *in,
9374
DATA_BLOB *out, uint32_t *needed)
9376
struct spoolss_PortData1 port1;
9377
struct spoolss_PortData2 port2;
9378
char *device_uri = NULL;
9381
const char *portname;
9382
const char *hostaddress;
9384
uint32_t port_number;
9387
/* peek for spoolss_PortData version */
9389
if (!in || (in->length < (128 + 4))) {
9390
return WERR_GENERAL_FAILURE;
9393
version = IVAL(in->data, 128);
9399
if (!pull_port_data_1(mem_ctx, &port1, in)) {
9403
portname = port1.portname;
9404
hostaddress = port1.hostaddress;
9405
queue = port1.queue;
9406
protocol = port1.protocol;
9407
port_number = port1.port_number;
9413
if (!pull_port_data_2(mem_ctx, &port2, in)) {
9417
portname = port2.portname;
9418
hostaddress = port2.hostaddress;
9419
queue = port2.queue;
9420
protocol = port2.protocol;
9421
port_number = port2.port_number;
9425
DEBUG(1,("xcvtcp_addport: "
9426
"unknown version of port_data: %d\n", version));
9427
return WERR_UNKNOWN_PORT;
9430
/* create the device URI and call the add_port_hook() */
9433
case PROTOCOL_RAWTCP_TYPE:
9434
device_uri = talloc_asprintf(mem_ctx,
9435
"socket://%s:%d/", hostaddress,
9439
case PROTOCOL_LPR_TYPE:
9440
device_uri = talloc_asprintf(mem_ctx,
9441
"lpr://%s/%s", hostaddress, queue );
9445
return WERR_UNKNOWN_PORT;
9452
return add_port_hook(mem_ctx, token, portname, device_uri);
9455
/*******************************************************************
9456
*******************************************************************/
9458
struct xcv_api_table xcvtcp_cmds[] = {
9459
{ "MonitorUI", xcvtcp_monitorui },
9460
{ "AddPort", xcvtcp_addport},
9464
static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9465
NT_USER_TOKEN *token, const char *command,
9472
DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9474
for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9475
if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9476
return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9479
return WERR_BADFUNC;
9482
/*******************************************************************
9483
*******************************************************************/
9484
#if 0 /* don't support management using the "Local Port" monitor */
9486
static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9487
NT_USER_TOKEN *token, DATA_BLOB *in,
9488
DATA_BLOB *out, uint32_t *needed)
9490
const char *dllname = "localui.dll";
9492
*needed = (strlen(dllname)+1) * 2;
9494
if (out->length < *needed) {
9495
return WERR_INSUFFICIENT_BUFFER;
9498
if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9505
/*******************************************************************
9506
*******************************************************************/
9508
struct xcv_api_table xcvlocal_cmds[] = {
9509
{ "MonitorUI", xcvlocal_monitorui },
9513
struct xcv_api_table xcvlocal_cmds[] = {
9520
/*******************************************************************
9521
*******************************************************************/
9523
static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9524
NT_USER_TOKEN *token, const char *command,
9525
DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9530
DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9532
for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9533
if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9534
return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9536
return WERR_BADFUNC;
9539
/****************************************************************
9541
****************************************************************/
9543
WERROR _spoolss_XcvData(pipes_struct *p,
9544
struct spoolss_XcvData *r)
9546
Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9547
DATA_BLOB out_data = data_blob_null;
9551
DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9552
OUR_HANDLE(r->in.handle)));
9556
/* Has to be a handle to the TCP/IP port monitor */
9558
if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9559
DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9563
/* requires administrative access to the server */
9565
if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9566
DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9567
return WERR_ACCESS_DENIED;
9570
/* Allocate the outgoing buffer */
9572
if (r->in.out_data_size) {
9573
out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9574
if (out_data.data == NULL) {
9579
switch ( Printer->printer_type ) {
9580
case SPLHND_PORTMON_TCP:
9581
werror = process_xcvtcp_command(p->mem_ctx,
9582
p->server_info->ptok,
9583
r->in.function_name,
9584
&r->in.in_data, &out_data,
9587
case SPLHND_PORTMON_LOCAL:
9588
werror = process_xcvlocal_command(p->mem_ctx,
9589
p->server_info->ptok,
9590
r->in.function_name,
9591
&r->in.in_data, &out_data,
9595
werror = WERR_INVALID_PRINT_MONITOR;
9598
if (!W_ERROR_IS_OK(werror)) {
9602
*r->out.status_code = 0;
9604
if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9605
memcpy(r->out.out_data, out_data.data,
9606
MIN(r->in.out_data_size, out_data.length));
9612
/****************************************************************
9613
_spoolss_AddPrintProcessor
9614
****************************************************************/
9616
WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
9617
struct spoolss_AddPrintProcessor *r)
9619
/* for now, just indicate success and ignore the add. We'll
9620
automatically set the winprint processor for printer
9621
entries later. Used to debug the LexMark Optra S 1855 PCL
9627
/****************************************************************
9629
****************************************************************/
9631
WERROR _spoolss_AddPort(pipes_struct *p,
9632
struct spoolss_AddPort *r)
9634
/* do what w2k3 does */
9636
return WERR_NOT_SUPPORTED;
9639
/****************************************************************
9640
_spoolss_GetPrinterDriver
9641
****************************************************************/
9643
WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
9644
struct spoolss_GetPrinterDriver *r)
9646
p->rng_fault_state = true;
9647
return WERR_NOT_SUPPORTED;
9650
/****************************************************************
9651
_spoolss_ReadPrinter
9652
****************************************************************/
9654
WERROR _spoolss_ReadPrinter(pipes_struct *p,
9655
struct spoolss_ReadPrinter *r)
9657
p->rng_fault_state = true;
9658
return WERR_NOT_SUPPORTED;
9661
/****************************************************************
9662
_spoolss_WaitForPrinterChange
9663
****************************************************************/
9665
WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
9666
struct spoolss_WaitForPrinterChange *r)
9668
p->rng_fault_state = true;
9669
return WERR_NOT_SUPPORTED;
9672
/****************************************************************
9673
_spoolss_ConfigurePort
9674
****************************************************************/
9676
WERROR _spoolss_ConfigurePort(pipes_struct *p,
9677
struct spoolss_ConfigurePort *r)
9679
p->rng_fault_state = true;
9680
return WERR_NOT_SUPPORTED;
9683
/****************************************************************
9685
****************************************************************/
9687
WERROR _spoolss_DeletePort(pipes_struct *p,
9688
struct spoolss_DeletePort *r)
9690
p->rng_fault_state = true;
9691
return WERR_NOT_SUPPORTED;
9694
/****************************************************************
9695
_spoolss_CreatePrinterIC
9696
****************************************************************/
9698
WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
9699
struct spoolss_CreatePrinterIC *r)
9701
p->rng_fault_state = true;
9702
return WERR_NOT_SUPPORTED;
9705
/****************************************************************
9706
_spoolss_PlayGDIScriptOnPrinterIC
9707
****************************************************************/
9709
WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
9710
struct spoolss_PlayGDIScriptOnPrinterIC *r)
9712
p->rng_fault_state = true;
9713
return WERR_NOT_SUPPORTED;
9716
/****************************************************************
9717
_spoolss_DeletePrinterIC
9718
****************************************************************/
9720
WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
9721
struct spoolss_DeletePrinterIC *r)
9723
p->rng_fault_state = true;
9724
return WERR_NOT_SUPPORTED;
9727
/****************************************************************
9728
_spoolss_AddPrinterConnection
9729
****************************************************************/
9731
WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
9732
struct spoolss_AddPrinterConnection *r)
9734
p->rng_fault_state = true;
9735
return WERR_NOT_SUPPORTED;
9738
/****************************************************************
9739
_spoolss_DeletePrinterConnection
9740
****************************************************************/
9742
WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
9743
struct spoolss_DeletePrinterConnection *r)
9745
p->rng_fault_state = true;
9746
return WERR_NOT_SUPPORTED;
9749
/****************************************************************
9750
_spoolss_PrinterMessageBox
9751
****************************************************************/
9753
WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
9754
struct spoolss_PrinterMessageBox *r)
9756
p->rng_fault_state = true;
9757
return WERR_NOT_SUPPORTED;
9760
/****************************************************************
9762
****************************************************************/
9764
WERROR _spoolss_AddMonitor(pipes_struct *p,
9765
struct spoolss_AddMonitor *r)
9767
p->rng_fault_state = true;
9768
return WERR_NOT_SUPPORTED;
9771
/****************************************************************
9772
_spoolss_DeleteMonitor
9773
****************************************************************/
9775
WERROR _spoolss_DeleteMonitor(pipes_struct *p,
9776
struct spoolss_DeleteMonitor *r)
9778
p->rng_fault_state = true;
9779
return WERR_NOT_SUPPORTED;
9782
/****************************************************************
9783
_spoolss_DeletePrintProcessor
9784
****************************************************************/
9786
WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
9787
struct spoolss_DeletePrintProcessor *r)
9789
p->rng_fault_state = true;
9790
return WERR_NOT_SUPPORTED;
9793
/****************************************************************
9794
_spoolss_AddPrintProvidor
9795
****************************************************************/
9797
WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
9798
struct spoolss_AddPrintProvidor *r)
9800
p->rng_fault_state = true;
9801
return WERR_NOT_SUPPORTED;
9804
/****************************************************************
9805
_spoolss_DeletePrintProvidor
9806
****************************************************************/
9808
WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
9809
struct spoolss_DeletePrintProvidor *r)
9811
p->rng_fault_state = true;
9812
return WERR_NOT_SUPPORTED;
9815
/****************************************************************
9816
_spoolss_FindFirstPrinterChangeNotification
9817
****************************************************************/
9819
WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
9820
struct spoolss_FindFirstPrinterChangeNotification *r)
9822
p->rng_fault_state = true;
9823
return WERR_NOT_SUPPORTED;
9826
/****************************************************************
9827
_spoolss_FindNextPrinterChangeNotification
9828
****************************************************************/
9830
WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
9831
struct spoolss_FindNextPrinterChangeNotification *r)
9833
p->rng_fault_state = true;
9834
return WERR_NOT_SUPPORTED;
9837
/****************************************************************
9838
_spoolss_RouterFindFirstPrinterChangeNotificationOld
9839
****************************************************************/
9841
WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
9842
struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9844
p->rng_fault_state = true;
9845
return WERR_NOT_SUPPORTED;
9848
/****************************************************************
9849
_spoolss_ReplyOpenPrinter
9850
****************************************************************/
9852
WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
9853
struct spoolss_ReplyOpenPrinter *r)
9855
p->rng_fault_state = true;
9856
return WERR_NOT_SUPPORTED;
9859
/****************************************************************
9860
_spoolss_RouterReplyPrinter
9861
****************************************************************/
9863
WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
9864
struct spoolss_RouterReplyPrinter *r)
9866
p->rng_fault_state = true;
9867
return WERR_NOT_SUPPORTED;
9870
/****************************************************************
9871
_spoolss_ReplyClosePrinter
9872
****************************************************************/
9874
WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
9875
struct spoolss_ReplyClosePrinter *r)
9877
p->rng_fault_state = true;
9878
return WERR_NOT_SUPPORTED;
9881
/****************************************************************
9883
****************************************************************/
9885
WERROR _spoolss_AddPortEx(pipes_struct *p,
9886
struct spoolss_AddPortEx *r)
9888
p->rng_fault_state = true;
9889
return WERR_NOT_SUPPORTED;
9892
/****************************************************************
9893
_spoolss_RouterFindFirstPrinterChangeNotification
9894
****************************************************************/
9896
WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
9897
struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9899
p->rng_fault_state = true;
9900
return WERR_NOT_SUPPORTED;
9903
/****************************************************************
9904
_spoolss_SpoolerInit
9905
****************************************************************/
9907
WERROR _spoolss_SpoolerInit(pipes_struct *p,
9908
struct spoolss_SpoolerInit *r)
9910
p->rng_fault_state = true;
9911
return WERR_NOT_SUPPORTED;
9914
/****************************************************************
9915
_spoolss_ResetPrinterEx
9916
****************************************************************/
9918
WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
9919
struct spoolss_ResetPrinterEx *r)
9921
p->rng_fault_state = true;
9922
return WERR_NOT_SUPPORTED;
9925
/****************************************************************
9926
_spoolss_RouterReplyPrinterEx
9927
****************************************************************/
9929
WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
9930
struct spoolss_RouterReplyPrinterEx *r)
9932
p->rng_fault_state = true;
9933
return WERR_NOT_SUPPORTED;
9936
/****************************************************************
9938
****************************************************************/
9940
WERROR _spoolss_44(pipes_struct *p,
9941
struct spoolss_44 *r)
9943
p->rng_fault_state = true;
9944
return WERR_NOT_SUPPORTED;
9947
/****************************************************************
9949
****************************************************************/
9951
WERROR _spoolss_47(pipes_struct *p,
9952
struct spoolss_47 *r)
9954
p->rng_fault_state = true;
9955
return WERR_NOT_SUPPORTED;
9958
/****************************************************************
9960
****************************************************************/
9962
WERROR _spoolss_4a(pipes_struct *p,
9963
struct spoolss_4a *r)
9965
p->rng_fault_state = true;
9966
return WERR_NOT_SUPPORTED;
9969
/****************************************************************
9971
****************************************************************/
9973
WERROR _spoolss_4b(pipes_struct *p,
9974
struct spoolss_4b *r)
9976
p->rng_fault_state = true;
9977
return WERR_NOT_SUPPORTED;
9980
/****************************************************************
9982
****************************************************************/
9984
WERROR _spoolss_4c(pipes_struct *p,
9985
struct spoolss_4c *r)
9987
p->rng_fault_state = true;
9988
return WERR_NOT_SUPPORTED;
9991
/****************************************************************
9993
****************************************************************/
9995
WERROR _spoolss_53(pipes_struct *p,
9996
struct spoolss_53 *r)
9998
p->rng_fault_state = true;
9999
return WERR_NOT_SUPPORTED;
10002
/****************************************************************
10004
****************************************************************/
10006
WERROR _spoolss_55(pipes_struct *p,
10007
struct spoolss_55 *r)
10009
p->rng_fault_state = true;
10010
return WERR_NOT_SUPPORTED;
10013
/****************************************************************
10015
****************************************************************/
10017
WERROR _spoolss_56(pipes_struct *p,
10018
struct spoolss_56 *r)
10020
p->rng_fault_state = true;
10021
return WERR_NOT_SUPPORTED;
10024
/****************************************************************
10026
****************************************************************/
10028
WERROR _spoolss_57(pipes_struct *p,
10029
struct spoolss_57 *r)
10031
p->rng_fault_state = true;
10032
return WERR_NOT_SUPPORTED;
10035
/****************************************************************
10037
****************************************************************/
10039
WERROR _spoolss_5a(pipes_struct *p,
10040
struct spoolss_5a *r)
10042
p->rng_fault_state = true;
10043
return WERR_NOT_SUPPORTED;
10046
/****************************************************************
10048
****************************************************************/
10050
WERROR _spoolss_5b(pipes_struct *p,
10051
struct spoolss_5b *r)
10053
p->rng_fault_state = true;
10054
return WERR_NOT_SUPPORTED;
10057
/****************************************************************
10059
****************************************************************/
10061
WERROR _spoolss_5c(pipes_struct *p,
10062
struct spoolss_5c *r)
10064
p->rng_fault_state = true;
10065
return WERR_NOT_SUPPORTED;
10068
/****************************************************************
10070
****************************************************************/
10072
WERROR _spoolss_5d(pipes_struct *p,
10073
struct spoolss_5d *r)
10075
p->rng_fault_state = true;
10076
return WERR_NOT_SUPPORTED;
10079
/****************************************************************
10081
****************************************************************/
10083
WERROR _spoolss_5e(pipes_struct *p,
10084
struct spoolss_5e *r)
10086
p->rng_fault_state = true;
10087
return WERR_NOT_SUPPORTED;
10090
/****************************************************************
10092
****************************************************************/
10094
WERROR _spoolss_5f(pipes_struct *p,
10095
struct spoolss_5f *r)
10097
p->rng_fault_state = true;
10098
return WERR_NOT_SUPPORTED;
10101
/****************************************************************
10103
****************************************************************/
10105
WERROR _spoolss_60(pipes_struct *p,
10106
struct spoolss_60 *r)
10108
p->rng_fault_state = true;
10109
return WERR_NOT_SUPPORTED;
10112
/****************************************************************
10114
****************************************************************/
10116
WERROR _spoolss_61(pipes_struct *p,
10117
struct spoolss_61 *r)
10119
p->rng_fault_state = true;
10120
return WERR_NOT_SUPPORTED;
10123
/****************************************************************
10125
****************************************************************/
10127
WERROR _spoolss_62(pipes_struct *p,
10128
struct spoolss_62 *r)
10130
p->rng_fault_state = true;
10131
return WERR_NOT_SUPPORTED;
10134
/****************************************************************
10136
****************************************************************/
10138
WERROR _spoolss_63(pipes_struct *p,
10139
struct spoolss_63 *r)
10141
p->rng_fault_state = true;
10142
return WERR_NOT_SUPPORTED;
10145
/****************************************************************
10147
****************************************************************/
10149
WERROR _spoolss_64(pipes_struct *p,
10150
struct spoolss_64 *r)
10152
p->rng_fault_state = true;
10153
return WERR_NOT_SUPPORTED;
10156
/****************************************************************
10158
****************************************************************/
10160
WERROR _spoolss_65(pipes_struct *p,
10161
struct spoolss_65 *r)
10163
p->rng_fault_state = true;
10164
return WERR_NOT_SUPPORTED;
10167
/****************************************************************
10168
_spoolss_GetCorePrinterDrivers
10169
****************************************************************/
10171
WERROR _spoolss_GetCorePrinterDrivers(pipes_struct *p,
10172
struct spoolss_GetCorePrinterDrivers *r)
10174
p->rng_fault_state = true;
10175
return WERR_NOT_SUPPORTED;
10178
/****************************************************************
10180
****************************************************************/
10182
WERROR _spoolss_67(pipes_struct *p,
10183
struct spoolss_67 *r)
10185
p->rng_fault_state = true;
10186
return WERR_NOT_SUPPORTED;
10189
/****************************************************************
10190
_spoolss_GetPrinterDriverPackagePath
10191
****************************************************************/
10193
WERROR _spoolss_GetPrinterDriverPackagePath(pipes_struct *p,
10194
struct spoolss_GetPrinterDriverPackagePath *r)
10196
p->rng_fault_state = true;
10197
return WERR_NOT_SUPPORTED;
10200
/****************************************************************
10202
****************************************************************/
10204
WERROR _spoolss_69(pipes_struct *p,
10205
struct spoolss_69 *r)
10207
p->rng_fault_state = true;
10208
return WERR_NOT_SUPPORTED;
10211
/****************************************************************
10213
****************************************************************/
10215
WERROR _spoolss_6a(pipes_struct *p,
10216
struct spoolss_6a *r)
10218
p->rng_fault_state = true;
10219
return WERR_NOT_SUPPORTED;
10222
/****************************************************************
10224
****************************************************************/
10226
WERROR _spoolss_6b(pipes_struct *p,
10227
struct spoolss_6b *r)
10229
p->rng_fault_state = true;
10230
return WERR_NOT_SUPPORTED;
10233
/****************************************************************
10235
****************************************************************/
10237
WERROR _spoolss_6c(pipes_struct *p,
10238
struct spoolss_6c *r)
10240
p->rng_fault_state = true;
10241
return WERR_NOT_SUPPORTED;
10244
/****************************************************************
10246
****************************************************************/
10248
WERROR _spoolss_6d(pipes_struct *p,
10249
struct spoolss_6d *r)
10251
p->rng_fault_state = true;
10252
return WERR_NOT_SUPPORTED;