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-2010.
11 * Copyright (C) Andreas Schneider 2010.
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation; either version 3 of the License, or
16 * (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, see <http://www.gnu.org/licenses/>.
27 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
28 up, all the errors returned are DOS errors, not NT status codes. */
31 #include "nt_printing.h"
32 #include "srv_spoolss_util.h"
33 #include "../librpc/gen_ndr/srv_spoolss.h"
34 #include "../librpc/gen_ndr/cli_spoolss.h"
35 #include "rpc_client/init_spoolss.h"
36 #include "librpc/gen_ndr/messaging.h"
37 #include "librpc/gen_ndr/ndr_security.h"
39 #include "registry/reg_objects.h"
40 #include "include/printing.h"
43 /* macros stolen from s4 spoolss server */
44 #define SPOOLSS_BUFFER_UNION(fn,info,level) \
45 ((info)?ndr_size_##fn(info, level, 0):0)
47 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,info,level,count) \
48 ((info)?ndr_size_##fn##_info(mem_ctx, level, count, info):0)
50 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,info,count) \
51 ((info)?ndr_size_##fn##_info(mem_ctx, count, info):0)
53 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
56 #define DBGC_CLASS DBGC_RPC_SRV
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 /* Map generic permissions to printer object specific permissions */
76 const struct standard_mapping printer_std_mapping = {
83 /* Map generic permissions to print server object specific permissions */
85 const struct standard_mapping printserver_std_mapping = {
92 /* API table for Xcv Monitor functions */
94 struct xcv_api_table {
96 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
99 /********************************************************************
100 * Canonicalize servername.
101 ********************************************************************/
103 static const char *canon_servername(const char *servername)
105 const char *pservername = servername;
106 while (*pservername == '\\') {
112 /* translate between internal status numbers and NT status numbers */
113 static int nt_printj_status(int v)
119 return JOB_STATUS_PAUSED;
121 return JOB_STATUS_SPOOLING;
123 return JOB_STATUS_PRINTING;
125 return JOB_STATUS_ERROR;
127 return JOB_STATUS_DELETING;
129 return JOB_STATUS_OFFLINE;
131 return JOB_STATUS_PAPEROUT;
133 return JOB_STATUS_PRINTED;
135 return JOB_STATUS_DELETED;
137 return JOB_STATUS_BLOCKED_DEVQ;
138 case LPQ_USER_INTERVENTION:
139 return JOB_STATUS_USER_INTERVENTION;
144 static int nt_printq_status(int v)
148 return PRINTER_STATUS_PAUSED;
157 /***************************************************************************
158 Disconnect from the client
159 ****************************************************************************/
161 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
167 * Tell the specific printing tdb we no longer want messages for this printer
168 * by deregistering our PID.
171 if (!print_notify_deregister_pid(snum))
172 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
174 /* weird if the test succeds !!! */
175 if (smb_connections==0) {
176 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
180 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
183 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
184 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
185 win_errstr(result)));
187 /* if it's the last connection, deconnect the IPC$ share */
188 if (smb_connections==1) {
190 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
191 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
193 messaging_deregister(smbd_messaging_context(),
194 MSG_PRINTER_NOTIFY2, NULL);
196 /* Tell the connections db we're no longer interested in
197 * printer notify messages. */
199 serverid_register_msg_flags(
200 messaging_server_id(smbd_messaging_context()),
201 false, FLAG_MSG_PRINT_NOTIFY);
207 /****************************************************************************
208 Functions to free a printer entry datastruct.
209 ****************************************************************************/
211 static int printer_entry_destructor(Printer_entry *Printer)
213 if (Printer->notify.client_connected == true) {
216 if ( Printer->printer_type == SPLHND_SERVER) {
218 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
219 } else if (Printer->printer_type == SPLHND_PRINTER) {
220 snum = print_queue_snum(Printer->sharename);
222 srv_spoolss_replycloseprinter(snum,
223 &Printer->notify.client_hnd);
227 Printer->notify.flags=0;
228 Printer->notify.options=0;
229 Printer->notify.localmachine[0]='\0';
230 Printer->notify.printerlocal=0;
231 TALLOC_FREE(Printer->notify.option);
232 Printer->notify.client_connected = false;
234 TALLOC_FREE(Printer->devmode);
236 /* Remove from the internal list. */
237 DLIST_REMOVE(printers_list, Printer);
241 /****************************************************************************
242 find printer index by handle
243 ****************************************************************************/
245 static Printer_entry *find_printer_index_by_hnd(struct pipes_struct *p,
246 struct policy_handle *hnd)
248 Printer_entry *find_printer = NULL;
250 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
251 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
258 /****************************************************************************
259 Close printer index by handle.
260 ****************************************************************************/
262 static bool close_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
264 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
267 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
272 close_policy_hnd(p, hnd);
277 /****************************************************************************
278 Delete a printer given a handle.
279 ****************************************************************************/
281 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
283 char *cmd = lp_deleteprinter_cmd();
284 char *command = NULL;
286 SE_PRIV se_printop = SE_PRINT_OPERATOR;
287 bool is_print_op = false;
289 /* can't fail if we don't try */
294 command = talloc_asprintf(ctx,
301 is_print_op = user_has_privileges( token, &se_printop );
303 DEBUG(10,("Running [%s]\n", command));
305 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
310 if ( (ret = smbrun(command, NULL)) == 0 ) {
311 /* Tell everyone we updated smb.conf. */
312 message_send_all(smbd_messaging_context(),
313 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
319 /********** END SePrintOperatorPrivlege BLOCK **********/
321 DEBUGADD(10,("returned [%d]\n", ret));
323 TALLOC_FREE(command);
326 return WERR_BADFID; /* What to return here? */
328 /* go ahead and re-read the services immediately */
330 reload_services(false);
333 if ( lp_servicenumber( sharename ) > 0 )
334 return WERR_ACCESS_DENIED;
339 /****************************************************************************
340 Delete a printer given a handle.
341 ****************************************************************************/
343 static WERROR delete_printer_handle(struct pipes_struct *p, struct policy_handle *hnd)
345 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
349 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
355 * It turns out that Windows allows delete printer on a handle
356 * opened by an admin user, then used on a pipe handle created
357 * by an anonymous user..... but they're working on security.... riiight !
361 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
362 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
363 return WERR_ACCESS_DENIED;
366 /* this does not need a become root since the access check has been
367 done on the handle already */
369 result = winreg_delete_printer_key(p->mem_ctx, p->server_info,
370 Printer->sharename, "");
371 if (!W_ERROR_IS_OK(result)) {
372 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
376 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
377 Printer->sharename );
380 /****************************************************************************
381 Return the snum of a printer corresponding to an handle.
382 ****************************************************************************/
384 static bool get_printer_snum(struct pipes_struct *p, struct policy_handle *hnd,
385 int *number, struct share_params **params)
387 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
390 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
395 switch (Printer->printer_type) {
397 DEBUG(4,("short name:%s\n", Printer->sharename));
398 *number = print_queue_snum(Printer->sharename);
399 return (*number != -1);
407 /****************************************************************************
408 Set printer handle type.
409 Check if it's \\server or \\server\printer
410 ****************************************************************************/
412 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
414 DEBUG(3,("Setting printer type=%s\n", handlename));
416 if ( strlen(handlename) < 3 ) {
417 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
421 /* it's a print server */
422 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
423 DEBUGADD(4,("Printer is a print server\n"));
424 Printer->printer_type = SPLHND_SERVER;
426 /* it's a printer (set_printer_hnd_name() will handle port monitors */
428 DEBUGADD(4,("Printer is a printer\n"));
429 Printer->printer_type = SPLHND_PRINTER;
435 /****************************************************************************
436 Set printer handle name.. Accept names like \\server, \\server\printer,
437 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
438 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
439 XcvDataPort() interface.
440 ****************************************************************************/
442 static bool set_printer_hnd_name(TALLOC_CTX *mem_ctx,
443 struct auth_serversupplied_info *server_info,
444 Printer_entry *Printer,
445 const char *handlename)
448 int n_services=lp_numservices();
450 const char *printername;
451 const char *servername = NULL;
454 struct spoolss_PrinterInfo2 *info2 = NULL;
457 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
458 (unsigned long)strlen(handlename)));
460 aprinter = CONST_DISCARD(char *, handlename);
461 if ( *handlename == '\\' ) {
462 servername = canon_servername(handlename);
463 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
467 if (!is_myname_or_ipaddr(servername)) {
471 fstrcpy(Printer->servername, servername);
474 if (Printer->printer_type == SPLHND_SERVER) {
478 if (Printer->printer_type != SPLHND_PRINTER) {
482 DEBUGADD(5, ("searching for [%s]\n", aprinter));
484 /* check for the Port Monitor Interface */
485 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
486 Printer->printer_type = SPLHND_PORTMON_TCP;
487 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
490 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
491 Printer->printer_type = SPLHND_PORTMON_LOCAL;
492 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
496 /* Search all sharenames first as this is easier than pulling
497 the printer_info_2 off of disk. Don't use find_service() since
498 that calls out to map_username() */
500 /* do another loop to look for printernames */
501 for (snum = 0; !found && snum < n_services; snum++) {
502 const char *printer = lp_const_servicename(snum);
504 /* no point going on if this is not a printer */
505 if (!(lp_snum_ok(snum) && lp_print_ok(snum))) {
509 /* ignore [printers] share */
510 if (strequal(printer, "printers")) {
514 fstrcpy(sname, printer);
515 if (strequal(aprinter, printer)) {
520 /* no point looking up the printer object if
521 we aren't allowing printername != sharename */
522 if (lp_force_printername(snum)) {
526 result = winreg_get_printer(mem_ctx,
531 if ( !W_ERROR_IS_OK(result) ) {
532 DEBUG(2,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
533 sname, win_errstr(result)));
537 printername = strrchr(info2->printername, '\\');
538 if (printername == NULL) {
539 printername = info2->printername;
544 if (strequal(printername, aprinter)) {
549 DEBUGADD(10, ("printername: %s\n", printername));
555 DEBUGADD(4,("Printer not found\n"));
559 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
561 fstrcpy(Printer->sharename, sname);
566 /****************************************************************************
567 Find first available printer slot. creates a printer handle for you.
568 ****************************************************************************/
570 static bool open_printer_hnd(struct pipes_struct *p, struct policy_handle *hnd,
571 const char *name, uint32_t access_granted)
573 Printer_entry *new_printer;
575 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
577 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
578 if (new_printer == NULL) {
581 talloc_set_destructor(new_printer, printer_entry_destructor);
583 if (!create_policy_hnd(p, hnd, new_printer)) {
584 TALLOC_FREE(new_printer);
588 /* Add to the internal list. */
589 DLIST_ADD(printers_list, new_printer);
591 new_printer->notify.option=NULL;
593 if (!set_printer_hnd_printertype(new_printer, name)) {
594 close_printer_handle(p, hnd);
598 if (!set_printer_hnd_name(p->mem_ctx, p->server_info, new_printer, name)) {
599 close_printer_handle(p, hnd);
603 new_printer->access_granted = access_granted;
605 DEBUG(5, ("%d printer handles active\n",
606 (int)num_pipe_handles(p)));
611 /***************************************************************************
612 check to see if the client motify handle is monitoring the notification
613 given by (notify_type, notify_field).
614 **************************************************************************/
616 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
617 uint16_t notify_field)
622 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
623 uint16_t notify_field)
625 struct spoolss_NotifyOption *option = p->notify.option;
629 * Flags should always be zero when the change notify
630 * is registered by the client's spooler. A user Win32 app
631 * might use the flags though instead of the NOTIFY_OPTION_INFO
640 return is_monitoring_event_flags(
641 p->notify.flags, notify_type, notify_field);
643 for (i = 0; i < option->count; i++) {
645 /* Check match for notify_type */
647 if (option->types[i].type != notify_type)
650 /* Check match for field */
652 for (j = 0; j < option->types[i].count; j++) {
653 if (option->types[i].fields[j].field == notify_field) {
659 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
660 p->servername, p->sharename, notify_type, notify_field));
665 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
666 _data->data.integer[0] = _integer; \
667 _data->data.integer[1] = 0;
670 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
671 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
672 if (!_data->data.string.string) {\
673 _data->data.string.size = 0; \
675 _data->data.string.size = strlen_m_term(_p) * 2;
677 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
678 _data->data.devmode.devmode = _devmode;
680 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _sd) \
681 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
682 if (!_data->data.sd.sd) { \
683 _data->data.sd.sd_size = 0; \
685 _data->data.sd.sd_size = \
686 ndr_size_security_descriptor(_data->data.sd.sd, 0);
688 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
693 struct spoolss_Time st;
697 if (!init_systemtime(&st, t)) {
701 p = talloc_array(mem_ctx, char, len);
707 * Systemtime must be linearized as a set of UINT16's.
708 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
711 SSVAL(p, 0, st.year);
712 SSVAL(p, 2, st.month);
713 SSVAL(p, 4, st.day_of_week);
715 SSVAL(p, 8, st.hour);
716 SSVAL(p, 10, st.minute);
717 SSVAL(p, 12, st.second);
718 SSVAL(p, 14, st.millisecond);
724 /* Convert a notification message to a struct spoolss_Notify */
726 static void notify_one_value(struct spoolss_notify_msg *msg,
727 struct spoolss_Notify *data,
730 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
733 static void notify_string(struct spoolss_notify_msg *msg,
734 struct spoolss_Notify *data,
737 /* The length of the message includes the trailing \0 */
739 data->data.string.size = msg->len * 2;
740 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
741 if (!data->data.string.string) {
742 data->data.string.size = 0;
747 static void notify_system_time(struct spoolss_notify_msg *msg,
748 struct spoolss_Notify *data,
751 data->data.string.string = NULL;
752 data->data.string.size = 0;
754 if (msg->len != sizeof(time_t)) {
755 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
760 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
761 &data->data.string.string,
762 &data->data.string.size);
765 struct notify2_message_table {
767 void (*fn)(struct spoolss_notify_msg *msg,
768 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
771 static struct notify2_message_table printer_notify_table[] = {
772 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
773 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
774 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
775 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
776 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
777 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
778 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
779 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
780 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
781 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
782 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
783 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
784 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
785 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
786 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
787 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
788 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
789 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
790 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
793 static struct notify2_message_table job_notify_table[] = {
794 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
795 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
796 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
797 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
798 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
799 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
800 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
801 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
802 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
803 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
804 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
805 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
806 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
807 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
808 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
809 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
810 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
811 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
812 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
813 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
814 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
815 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
816 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
817 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
821 /***********************************************************************
822 Allocate talloc context for container object
823 **********************************************************************/
825 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
830 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
835 /***********************************************************************
836 release all allocated memory and zero out structure
837 **********************************************************************/
839 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
845 talloc_destroy(ctr->ctx);
852 /***********************************************************************
853 **********************************************************************/
855 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
863 /***********************************************************************
864 **********************************************************************/
866 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
868 if ( !ctr || !ctr->msg_groups )
871 if ( idx >= ctr->num_groups )
874 return &ctr->msg_groups[idx];
878 /***********************************************************************
879 How many groups of change messages do we have ?
880 **********************************************************************/
882 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
887 return ctr->num_groups;
890 /***********************************************************************
891 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
892 **********************************************************************/
894 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
896 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
897 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
898 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
904 /* loop over all groups looking for a matching printer name */
906 for ( i=0; i<ctr->num_groups; i++ ) {
907 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
911 /* add a new group? */
913 if ( i == ctr->num_groups ) {
916 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
917 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
920 ctr->msg_groups = groups;
922 /* clear the new entry and set the printer name */
924 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
925 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
928 /* add the change messages; 'i' is the correct index now regardless */
930 msg_grp = &ctr->msg_groups[i];
934 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
935 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
938 msg_grp->msgs = msg_list;
940 new_slot = msg_grp->num_msgs-1;
941 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
943 /* need to allocate own copy of data */
946 msg_grp->msgs[new_slot].notify.data = (char *)
947 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
949 return ctr->num_groups;
952 static void construct_info_data(struct spoolss_Notify *info_data,
953 enum spoolss_NotifyType type,
954 uint16_t field, int id);
956 /***********************************************************************
957 Send a change notication message on all handles which have a call
959 **********************************************************************/
961 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
964 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
965 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
966 SPOOLSS_NOTIFY_MSG *messages;
967 int sending_msg_count;
970 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
974 messages = msg_group->msgs;
977 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
981 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
983 /* loop over all printers */
985 for (p = printers_list; p; p = p->next) {
986 struct spoolss_Notify *notifies;
991 /* Is there notification on this handle? */
993 if ( !p->notify.client_connected )
996 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
998 /* For this printer? Print servers always receive
1001 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1002 ( !strequal(msg_group->printername, p->sharename) ) )
1005 DEBUG(10,("Our printer\n"));
1007 /* allocate the max entries possible */
1009 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1014 /* build the array of change notifications */
1016 sending_msg_count = 0;
1018 for ( i=0; i<msg_group->num_msgs; i++ ) {
1019 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1021 /* Are we monitoring this event? */
1023 if (!is_monitoring_event(p, msg->type, msg->field))
1026 sending_msg_count++;
1029 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1030 msg->type, msg->field, p->sharename));
1033 * if the is a printer notification handle and not a job notification
1034 * type, then set the id to 0. Other wise just use what was specified
1037 * When registering change notification on a print server handle
1038 * we always need to send back the id (snum) matching the printer
1039 * for which the change took place. For change notify registered
1040 * on a printer handle, this does not matter and the id should be 0.
1045 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1051 /* Convert unix jobid to smb jobid */
1053 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1054 id = sysjob_to_jobid(msg->id);
1057 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1062 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1065 case PRINTER_NOTIFY_TYPE:
1066 if ( printer_notify_table[msg->field].fn )
1067 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1070 case JOB_NOTIFY_TYPE:
1071 if ( job_notify_table[msg->field].fn )
1072 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1076 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1083 if ( sending_msg_count ) {
1086 union spoolss_ReplyPrinterInfo info;
1087 struct spoolss_NotifyInfo info0;
1088 uint32_t reply_result;
1090 info0.version = 0x2;
1091 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1092 info0.count = count;
1093 info0.notifies = notifies;
1095 info.info0 = &info0;
1097 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1098 &p->notify.client_hnd,
1099 p->notify.change, /* color */
1102 0, /* reply_type, must be 0 */
1105 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1106 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1107 notify_cli_pipe->srv_name_slash,
1110 switch (reply_result) {
1113 case PRINTER_NOTIFY_INFO_DISCARDED:
1114 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1115 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1124 DEBUG(8,("send_notify2_changes: Exit...\n"));
1128 /***********************************************************************
1129 **********************************************************************/
1131 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1134 uint32_t tv_sec, tv_usec;
1137 /* Unpack message */
1139 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1142 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1144 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1147 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1148 &msg->notify.value[0], &msg->notify.value[1]);
1150 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1151 &msg->len, &msg->notify.data);
1153 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1154 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1156 tv->tv_sec = tv_sec;
1157 tv->tv_usec = tv_usec;
1160 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1161 msg->notify.value[1]));
1163 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1168 /********************************************************************
1169 Receive a notify2 message list
1170 ********************************************************************/
1172 static void receive_notify2_message_list(struct messaging_context *msg,
1175 struct server_id server_id,
1178 size_t msg_count, i;
1179 char *buf = (char *)data->data;
1182 SPOOLSS_NOTIFY_MSG notify;
1183 SPOOLSS_NOTIFY_MSG_CTR messages;
1186 if (data->length < 4) {
1187 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1191 msg_count = IVAL(buf, 0);
1194 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1196 if (msg_count == 0) {
1197 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1201 /* initialize the container */
1203 ZERO_STRUCT( messages );
1204 notify_msg_ctr_init( &messages );
1207 * build message groups for each printer identified
1208 * in a change_notify msg. Remember that a PCN message
1209 * includes the handle returned for the srv_spoolss_replyopenprinter()
1210 * call. Therefore messages are grouped according to printer handle.
1213 for ( i=0; i<msg_count; i++ ) {
1214 struct timeval msg_tv;
1216 if (msg_ptr + 4 - buf > data->length) {
1217 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1221 msg_len = IVAL(msg_ptr,0);
1224 if (msg_ptr + msg_len - buf > data->length) {
1225 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1229 /* unpack messages */
1231 ZERO_STRUCT( notify );
1232 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1235 /* add to correct list in container */
1237 notify_msg_ctr_addmsg( &messages, ¬ify );
1239 /* free memory that might have been allocated by notify2_unpack_msg() */
1241 if ( notify.len != 0 )
1242 SAFE_FREE( notify.notify.data );
1245 /* process each group of messages */
1247 num_groups = notify_msg_ctr_numgroups( &messages );
1248 for ( i=0; i<num_groups; i++ )
1249 send_notify2_changes( &messages, i );
1254 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1255 (uint32_t)msg_count ));
1257 notify_msg_ctr_destroy( &messages );
1262 /********************************************************************
1263 Send a message to ourself about new driver being installed
1264 so we can upgrade the information for each printer bound to this
1266 ********************************************************************/
1268 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1270 int len = strlen(drivername);
1275 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1278 messaging_send_buf(smbd_messaging_context(),
1279 messaging_server_id(smbd_messaging_context()),
1280 MSG_PRINTER_DRVUPGRADE,
1281 (uint8_t *)drivername, len+1);
1286 /**********************************************************************
1287 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1288 over all printers, upgrading ones as necessary
1289 **********************************************************************/
1291 void do_drv_upgrade_printer(struct messaging_context *msg,
1294 struct server_id server_id,
1297 TALLOC_CTX *tmp_ctx;
1298 struct auth_serversupplied_info *server_info = NULL;
1299 struct spoolss_PrinterInfo2 *pinfo2;
1302 const char *drivername;
1304 int n_services = lp_numservices();
1307 tmp_ctx = talloc_new(NULL);
1308 if (!tmp_ctx) return;
1310 status = make_server_info_system(tmp_ctx, &server_info);
1311 if (!NT_STATUS_IS_OK(status)) {
1312 DEBUG(0, ("do_drv_upgrade_printer: "
1313 "Could not create system server_info\n"));
1317 len = MIN(data->length,sizeof(drivername)-1);
1318 drivername = talloc_strndup(tmp_ctx, (const char *)data->data, len);
1320 DEBUG(0, ("do_drv_upgrade_printer: Out of memoery ?!\n"));
1324 DEBUG(10, ("do_drv_upgrade_printer: "
1325 "Got message for new driver [%s]\n", drivername));
1327 /* Iterate the printer list */
1329 for (snum = 0; snum < n_services; snum++) {
1330 if (!lp_snum_ok(snum) || !lp_print_ok(snum)) {
1334 result = winreg_get_printer(tmp_ctx, server_info, NULL,
1335 lp_const_servicename(snum),
1338 if (!W_ERROR_IS_OK(result)) {
1342 if (!pinfo2->drivername) {
1346 if (strcmp(drivername, pinfo2->drivername) != 0) {
1350 DEBUG(6,("Updating printer [%s]\n", pinfo2->printername));
1352 /* all we care about currently is the change_id */
1353 result = winreg_printer_update_changeid(tmp_ctx,
1355 pinfo2->printername);
1357 if (!W_ERROR_IS_OK(result)) {
1358 DEBUG(3, ("do_drv_upgrade_printer: "
1359 "Failed to update changeid [%s]\n",
1360 win_errstr(result)));
1366 talloc_free(tmp_ctx);
1369 /********************************************************************
1370 Update the cache for all printq's with a registered client
1372 ********************************************************************/
1374 void update_monitored_printq_cache( void )
1376 Printer_entry *printer = printers_list;
1379 /* loop through all printers and update the cache where
1380 client_connected == true */
1383 if ( (printer->printer_type == SPLHND_PRINTER)
1384 && printer->notify.client_connected )
1386 snum = print_queue_snum(printer->sharename);
1387 print_queue_status( snum, NULL, NULL );
1390 printer = printer->next;
1396 /****************************************************************
1397 _spoolss_OpenPrinter
1398 ****************************************************************/
1400 WERROR _spoolss_OpenPrinter(struct pipes_struct *p,
1401 struct spoolss_OpenPrinter *r)
1403 struct spoolss_OpenPrinterEx e;
1406 ZERO_STRUCT(e.in.userlevel);
1408 e.in.printername = r->in.printername;
1409 e.in.datatype = r->in.datatype;
1410 e.in.devmode_ctr = r->in.devmode_ctr;
1411 e.in.access_mask = r->in.access_mask;
1414 e.out.handle = r->out.handle;
1416 werr = _spoolss_OpenPrinterEx(p, &e);
1418 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1419 /* OpenPrinterEx returns this for a bad
1420 * printer name. We must return WERR_INVALID_PRINTER_NAME
1423 werr = WERR_INVALID_PRINTER_NAME;
1429 static WERROR copy_devicemode(TALLOC_CTX *mem_ctx,
1430 struct spoolss_DeviceMode *orig,
1431 struct spoolss_DeviceMode **dest)
1433 struct spoolss_DeviceMode *dm;
1435 dm = talloc(mem_ctx, struct spoolss_DeviceMode);
1440 /* copy all values, then duplicate strings and structs */
1443 dm->devicename = talloc_strdup(dm, orig->devicename);
1444 if (!dm->devicename) {
1447 dm->formname = talloc_strdup(dm, orig->formname);
1448 if (!dm->formname) {
1451 if (orig->driverextra_data.data) {
1452 dm->driverextra_data.data =
1453 (uint8_t *) talloc_memdup(dm, orig->driverextra_data.data,
1454 orig->driverextra_data.length);
1455 if (!dm->driverextra_data.data) {
1464 /****************************************************************
1465 _spoolss_OpenPrinterEx
1466 ****************************************************************/
1468 WERROR _spoolss_OpenPrinterEx(struct pipes_struct *p,
1469 struct spoolss_OpenPrinterEx *r)
1472 Printer_entry *Printer=NULL;
1474 if (!r->in.printername) {
1475 return WERR_INVALID_PARAM;
1478 /* some sanity check because you can open a printer or a print server */
1479 /* aka: \\server\printer or \\server */
1481 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1483 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1484 DEBUG(0,("_spoolss_OpenPrinterEx: Cannot open a printer handle "
1485 " for printer %s\n", r->in.printername));
1486 ZERO_STRUCTP(r->out.handle);
1487 return WERR_INVALID_PARAM;
1490 Printer = find_printer_index_by_hnd(p, r->out.handle);
1492 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1493 "handle we created for printer %s\n", r->in.printername));
1494 close_printer_handle(p, r->out.handle);
1495 ZERO_STRUCTP(r->out.handle);
1496 return WERR_INVALID_PARAM;
1500 * First case: the user is opening the print server:
1502 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1503 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1505 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1506 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1507 * or if the user is listed in the smb.conf printer admin parameter.
1509 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1510 * client view printer folder, but does not show the MSAPW.
1512 * Note: this test needs code to check access rights here too. Jeremy
1513 * could you look at this?
1515 * Second case: the user is opening a printer:
1516 * NT doesn't let us connect to a printer if the connecting user
1517 * doesn't have print permission.
1519 * Third case: user is opening a Port Monitor
1520 * access checks same as opening a handle to the print server.
1523 switch (Printer->printer_type )
1526 case SPLHND_PORTMON_TCP:
1527 case SPLHND_PORTMON_LOCAL:
1528 /* Printserver handles use global struct... */
1532 /* Map standard access rights to object specific access rights */
1534 se_map_standard(&r->in.access_mask,
1535 &printserver_std_mapping);
1537 /* Deny any object specific bits that don't apply to print
1538 servers (i.e printer and job specific bits) */
1540 r->in.access_mask &= SEC_MASK_SPECIFIC;
1542 if (r->in.access_mask &
1543 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1544 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1545 close_printer_handle(p, r->out.handle);
1546 ZERO_STRUCTP(r->out.handle);
1547 return WERR_ACCESS_DENIED;
1550 /* Allow admin access */
1552 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1554 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1556 if (!lp_ms_add_printer_wizard()) {
1557 close_printer_handle(p, r->out.handle);
1558 ZERO_STRUCTP(r->out.handle);
1559 return WERR_ACCESS_DENIED;
1562 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1563 and not a printer admin, then fail */
1565 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1566 !user_has_privileges(p->server_info->ptok,
1568 !token_contains_name_in_list(
1569 uidtoname(p->server_info->utok.uid),
1570 p->server_info->info3->base.domain.string,
1572 p->server_info->ptok,
1573 lp_printer_admin(snum))) {
1574 close_printer_handle(p, r->out.handle);
1575 ZERO_STRUCTP(r->out.handle);
1576 return WERR_ACCESS_DENIED;
1579 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1583 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1586 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1587 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1589 /* We fall through to return WERR_OK */
1592 case SPLHND_PRINTER:
1593 /* NT doesn't let us connect to a printer if the connecting user
1594 doesn't have print permission. */
1596 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1597 close_printer_handle(p, r->out.handle);
1598 ZERO_STRUCTP(r->out.handle);
1602 if (r->in.access_mask == SEC_FLAG_MAXIMUM_ALLOWED) {
1603 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1606 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1608 /* map an empty access mask to the minimum access mask */
1609 if (r->in.access_mask == 0x0)
1610 r->in.access_mask = PRINTER_ACCESS_USE;
1613 * If we are not serving the printer driver for this printer,
1614 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1615 * will keep NT clients happy --jerry
1618 if (lp_use_client_driver(snum)
1619 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1621 r->in.access_mask = PRINTER_ACCESS_USE;
1624 /* check smb.conf parameters and the the sec_desc */
1626 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1627 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1628 ZERO_STRUCTP(r->out.handle);
1629 return WERR_ACCESS_DENIED;
1632 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1633 p->server_info->ptok, snum) ||
1634 !print_access_check(p->server_info, snum,
1635 r->in.access_mask)) {
1636 DEBUG(3, ("access DENIED for printer open\n"));
1637 close_printer_handle(p, r->out.handle);
1638 ZERO_STRUCTP(r->out.handle);
1639 return WERR_ACCESS_DENIED;
1642 if ((r->in.access_mask & SEC_MASK_SPECIFIC)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1643 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1644 close_printer_handle(p, r->out.handle);
1645 ZERO_STRUCTP(r->out.handle);
1646 return WERR_ACCESS_DENIED;
1649 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1650 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1652 r->in.access_mask = PRINTER_ACCESS_USE;
1654 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1655 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1657 winreg_create_printer(p->mem_ctx,
1659 Printer->servername,
1660 lp_const_servicename(snum));
1665 /* sanity check to prevent programmer error */
1666 ZERO_STRUCTP(r->out.handle);
1670 Printer->access_granted = r->in.access_mask;
1673 * If the client sent a devmode in the OpenPrinter() call, then
1674 * save it here in case we get a job submission on this handle
1677 if ((Printer->printer_type != SPLHND_SERVER) &&
1678 r->in.devmode_ctr.devmode) {
1679 copy_devicemode(NULL, r->in.devmode_ctr.devmode,
1683 #if 0 /* JERRY -- I'm doubtful this is really effective */
1684 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1685 optimization in Windows 2000 clients --jerry */
1687 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1688 && (RA_WIN2K == get_remote_arch()) )
1690 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1691 sys_usleep( 500000 );
1698 /****************************************************************
1699 _spoolss_ClosePrinter
1700 ****************************************************************/
1702 WERROR _spoolss_ClosePrinter(struct pipes_struct *p,
1703 struct spoolss_ClosePrinter *r)
1705 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1707 if (Printer && Printer->document_started) {
1708 struct spoolss_EndDocPrinter e;
1710 e.in.handle = r->in.handle;
1712 _spoolss_EndDocPrinter(p, &e);
1715 if (!close_printer_handle(p, r->in.handle))
1718 /* clear the returned printer handle. Observed behavior
1719 from Win2k server. Don't think this really matters.
1720 Previous code just copied the value of the closed
1723 ZERO_STRUCTP(r->out.handle);
1728 /****************************************************************
1729 _spoolss_DeletePrinter
1730 ****************************************************************/
1732 WERROR _spoolss_DeletePrinter(struct pipes_struct *p,
1733 struct spoolss_DeletePrinter *r)
1735 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1739 if (Printer && Printer->document_started) {
1740 struct spoolss_EndDocPrinter e;
1742 e.in.handle = r->in.handle;
1744 _spoolss_EndDocPrinter(p, &e);
1747 if (get_printer_snum(p, r->in.handle, &snum, NULL)) {
1748 winreg_delete_printer_key(p->mem_ctx,
1750 lp_const_servicename(snum),
1754 result = delete_printer_handle(p, r->in.handle);
1759 /*******************************************************************
1760 * static function to lookup the version id corresponding to an
1761 * long architecture string
1762 ******************************************************************/
1764 static const struct print_architecture_table_node archi_table[]= {
1766 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1767 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1768 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1769 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1770 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1771 {"Windows IA64", SPL_ARCH_IA64, 3 },
1772 {"Windows x64", SPL_ARCH_X64, 3 },
1776 static int get_version_id(const char *arch)
1780 for (i=0; archi_table[i].long_archi != NULL; i++)
1782 if (strcmp(arch, archi_table[i].long_archi) == 0)
1783 return (archi_table[i].version);
1789 /****************************************************************
1790 _spoolss_DeletePrinterDriver
1791 ****************************************************************/
1793 WERROR _spoolss_DeletePrinterDriver(struct pipes_struct *p,
1794 struct spoolss_DeletePrinterDriver *r)
1797 struct spoolss_DriverInfo8 *info = NULL;
1798 struct spoolss_DriverInfo8 *info_win2k = NULL;
1801 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1803 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1804 and not a printer admin, then fail */
1806 if ( (p->server_info->utok.uid != sec_initial_uid())
1807 && !user_has_privileges(p->server_info->ptok, &se_printop )
1808 && !token_contains_name_in_list(
1809 uidtoname(p->server_info->utok.uid),
1810 p->server_info->info3->base.domain.string,
1812 p->server_info->ptok,
1813 lp_printer_admin(-1)) )
1815 return WERR_ACCESS_DENIED;
1818 /* check that we have a valid driver name first */
1820 if ((version = get_version_id(r->in.architecture)) == -1)
1821 return WERR_INVALID_ENVIRONMENT;
1823 status = winreg_get_driver(p->mem_ctx, p->server_info,
1824 r->in.architecture, r->in.driver,
1826 if (!W_ERROR_IS_OK(status)) {
1827 /* try for Win2k driver if "Windows NT x86" */
1829 if ( version == 2 ) {
1832 status = winreg_get_driver(p->mem_ctx, p->server_info,
1836 if (!W_ERROR_IS_OK(status)) {
1837 status = WERR_UNKNOWN_PRINTER_DRIVER;
1841 /* otherwise it was a failure */
1843 status = WERR_UNKNOWN_PRINTER_DRIVER;
1849 if (printer_driver_in_use(p->mem_ctx, p->server_info, info)) {
1850 status = WERR_PRINTER_DRIVER_IN_USE;
1855 status = winreg_get_driver(p->mem_ctx, p->server_info,
1857 r->in.driver, 3, &info_win2k);
1858 if (W_ERROR_IS_OK(status)) {
1859 /* if we get to here, we now have 2 driver info structures to remove */
1860 /* remove the Win2k driver first*/
1862 status = winreg_del_driver(p->mem_ctx,
1865 talloc_free(info_win2k);
1867 /* this should not have failed---if it did, report to client */
1868 if (!W_ERROR_IS_OK(status)) {
1874 status = winreg_del_driver(p->mem_ctx, p->server_info, info, version);
1882 /****************************************************************
1883 _spoolss_DeletePrinterDriverEx
1884 ****************************************************************/
1886 WERROR _spoolss_DeletePrinterDriverEx(struct pipes_struct *p,
1887 struct spoolss_DeletePrinterDriverEx *r)
1889 struct spoolss_DriverInfo8 *info = NULL;
1890 struct spoolss_DriverInfo8 *info_win2k = NULL;
1894 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1896 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1897 and not a printer admin, then fail */
1899 if ( (p->server_info->utok.uid != sec_initial_uid())
1900 && !user_has_privileges(p->server_info->ptok, &se_printop )
1901 && !token_contains_name_in_list(
1902 uidtoname(p->server_info->utok.uid),
1903 p->server_info->info3->base.domain.string,
1905 p->server_info->ptok, lp_printer_admin(-1)) )
1907 return WERR_ACCESS_DENIED;
1910 /* check that we have a valid driver name first */
1911 if ((version = get_version_id(r->in.architecture)) == -1) {
1912 /* this is what NT returns */
1913 return WERR_INVALID_ENVIRONMENT;
1916 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
1917 version = r->in.version;
1919 status = winreg_get_driver(p->mem_ctx, p->server_info,
1920 r->in.architecture, r->in.driver,
1922 if (!W_ERROR_IS_OK(status)) {
1923 status = WERR_UNKNOWN_PRINTER_DRIVER;
1926 * if the client asked for a specific version,
1927 * or this is something other than Windows NT x86,
1931 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
1934 /* try for Win2k driver if "Windows NT x86" */
1937 status = winreg_get_driver(info, p->server_info,
1941 if (!W_ERROR_IS_OK(status)) {
1942 status = WERR_UNKNOWN_PRINTER_DRIVER;
1947 if (printer_driver_in_use(info, p->server_info, info)) {
1948 status = WERR_PRINTER_DRIVER_IN_USE;
1953 * we have a couple of cases to consider.
1954 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
1955 * then the delete should fail if **any** files overlap with
1957 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
1958 * non-overlapping files
1959 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
1960 * is set, the do not delete any files
1961 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
1964 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
1966 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
1969 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1970 printer_driver_files_in_use(info, p->server_info, info)) {
1971 /* no idea of the correct error here */
1972 status = WERR_ACCESS_DENIED;
1977 /* also check for W32X86/3 if necessary; maybe we already have? */
1979 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
1980 status = winreg_get_driver(info, p->server_info,
1982 r->in.driver, 3, &info_win2k);
1983 if (W_ERROR_IS_OK(status)) {
1986 (r->in.delete_flags & DPD_DELETE_ALL_FILES) &&
1987 printer_driver_files_in_use(info, p->server_info,
1989 /* no idea of the correct error here */
1990 talloc_free(info_win2k);
1991 status = WERR_ACCESS_DENIED;
1995 /* if we get to here, we now have 2 driver info structures to remove */
1996 /* remove the Win2k driver first*/
1998 status = winreg_del_driver(info, p->server_info,
2001 /* this should not have failed---if it did, report to client */
2003 if (!W_ERROR_IS_OK(status)) {
2008 * now delete any associated files if delete_files is
2009 * true. Even if this part failes, we return succes
2010 * because the driver doesn not exist any more
2013 delete_driver_files(p->server_info,
2019 status = winreg_del_driver(info, p->server_info, info, version);
2020 if (!W_ERROR_IS_OK(status)) {
2025 * now delete any associated files if delete_files is
2026 * true. Even if this part failes, we return succes
2027 * because the driver doesn not exist any more
2030 delete_driver_files(p->server_info, info);
2039 /********************************************************************
2040 GetPrinterData on a printer server Handle.
2041 ********************************************************************/
2043 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2045 enum winreg_Type *type,
2046 union spoolss_PrinterData *data)
2048 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2050 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2056 if (!StrCaseCmp(value, "BeepEnabled")) {
2062 if (!StrCaseCmp(value, "EventLog")) {
2064 /* formally was 0x1b */
2069 if (!StrCaseCmp(value, "NetPopup")) {
2075 if (!StrCaseCmp(value, "MajorVersion")) {
2078 /* Windows NT 4.0 seems to not allow uploading of drivers
2079 to a server that reports 0x3 as the MajorVersion.
2080 need to investigate more how Win2k gets around this .
2083 if (RA_WINNT == get_remote_arch()) {
2092 if (!StrCaseCmp(value, "MinorVersion")) {
2099 * uint32_t size = 0x114
2100 * uint32_t major = 5
2101 * uint32_t minor = [0|1]
2102 * uint32_t build = [2195|2600]
2103 * extra unicode string = e.g. "Service Pack 3"
2105 if (!StrCaseCmp(value, "OSVersion")) {
2107 enum ndr_err_code ndr_err;
2108 struct spoolss_OSVersion os;
2110 os.major = 5; /* Windows 2000 == 5.0 */
2112 os.build = 2195; /* build */
2113 os.extra_string = ""; /* leave extra string empty */
2115 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, &os,
2116 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2117 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2118 return WERR_GENERAL_FAILURE;
2122 data->binary = blob;
2128 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2131 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2132 W_ERROR_HAVE_NO_MEMORY(data->string);
2137 if (!StrCaseCmp(value, "Architecture")) {
2139 data->string = talloc_strdup(mem_ctx,
2140 lp_parm_const_string(GLOBAL_SECTION_SNUM, "spoolss", "architecture", SPOOLSS_ARCHITECTURE_NT_X86));
2141 W_ERROR_HAVE_NO_MEMORY(data->string);
2146 if (!StrCaseCmp(value, "DsPresent")) {
2149 /* only show the publish check box if we are a
2150 member of a AD domain */
2152 if (lp_security() == SEC_ADS) {
2160 if (!StrCaseCmp(value, "DNSMachineName")) {
2161 const char *hostname = get_mydnsfullname();
2164 return WERR_BADFILE;
2168 data->string = talloc_strdup(mem_ctx, hostname);
2169 W_ERROR_HAVE_NO_MEMORY(data->string);
2176 return WERR_INVALID_PARAM;
2179 /****************************************************************
2180 _spoolss_GetPrinterData
2181 ****************************************************************/
2183 WERROR _spoolss_GetPrinterData(struct pipes_struct *p,
2184 struct spoolss_GetPrinterData *r)
2186 struct spoolss_GetPrinterDataEx r2;
2188 r2.in.handle = r->in.handle;
2189 r2.in.key_name = "PrinterDriverData";
2190 r2.in.value_name = r->in.value_name;
2191 r2.in.offered = r->in.offered;
2192 r2.out.type = r->out.type;
2193 r2.out.data = r->out.data;
2194 r2.out.needed = r->out.needed;
2196 return _spoolss_GetPrinterDataEx(p, &r2);
2199 /*********************************************************
2200 Connect to the client machine.
2201 **********************************************************/
2203 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2204 struct sockaddr_storage *client_ss, const char *remote_machine)
2207 struct cli_state *the_cli;
2208 struct sockaddr_storage rm_addr;
2209 char addr[INET6_ADDRSTRLEN];
2211 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2212 DEBUG(2,("spoolss_connect_to_client: resolving %s\n",
2214 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2215 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2218 print_sockaddr(addr, sizeof(addr), &rm_addr);
2220 rm_addr = *client_ss;
2221 print_sockaddr(addr, sizeof(addr), &rm_addr);
2222 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2226 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2227 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n",
2232 /* setup the connection */
2233 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2234 &rm_addr, 0, "IPC$", "IPC",
2238 0, lp_client_signing(), NULL );
2240 if ( !NT_STATUS_IS_OK( ret ) ) {
2241 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2246 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2247 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2248 cli_shutdown(the_cli);
2253 * Ok - we have an anonymous connection to the IPC$ share.
2254 * Now start the NT Domain stuff :-).
2257 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2258 if (!NT_STATUS_IS_OK(ret)) {
2259 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2260 remote_machine, nt_errstr(ret)));
2261 cli_shutdown(the_cli);
2268 /***************************************************************************
2269 Connect to the client.
2270 ****************************************************************************/
2272 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2273 uint32_t localprinter, uint32_t type,
2274 struct policy_handle *handle,
2275 struct sockaddr_storage *client_ss)
2281 * If it's the first connection, contact the client
2282 * and connect to the IPC$ share anonymously
2284 if (smb_connections==0) {
2285 fstring unix_printer;
2287 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2289 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2292 messaging_register(smbd_messaging_context(), NULL,
2293 MSG_PRINTER_NOTIFY2,
2294 receive_notify2_message_list);
2295 /* Tell the connections db we're now interested in printer
2296 * notify messages. */
2297 serverid_register_msg_flags(
2298 messaging_server_id(smbd_messaging_context()),
2299 true, FLAG_MSG_PRINT_NOTIFY);
2303 * Tell the specific printing tdb we want messages for this printer
2304 * by registering our PID.
2307 if (!print_notify_register_pid(snum))
2308 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2312 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2320 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2321 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2322 win_errstr(result)));
2324 return (W_ERROR_IS_OK(result));
2327 /****************************************************************
2328 ****************************************************************/
2330 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2331 const struct spoolss_NotifyOption *r)
2333 struct spoolss_NotifyOption *option;
2340 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2347 if (!option->count) {
2351 option->types = talloc_zero_array(option,
2352 struct spoolss_NotifyOptionType, option->count);
2353 if (!option->types) {
2354 talloc_free(option);
2358 for (i=0; i < option->count; i++) {
2359 option->types[i] = r->types[i];
2361 if (option->types[i].count) {
2362 option->types[i].fields = talloc_zero_array(option,
2363 union spoolss_Field, option->types[i].count);
2364 if (!option->types[i].fields) {
2365 talloc_free(option);
2368 for (k=0; k<option->types[i].count; k++) {
2369 option->types[i].fields[k] =
2370 r->types[i].fields[k];
2378 /****************************************************************
2379 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2381 * before replying OK: status=0 a rpc call is made to the workstation
2382 * asking ReplyOpenPrinter
2384 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2385 * called from api_spoolss_rffpcnex
2386 ****************************************************************/
2388 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(struct pipes_struct *p,
2389 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2392 struct spoolss_NotifyOption *option = r->in.notify_options;
2393 struct sockaddr_storage client_ss;
2395 /* store the notify value in the printer struct */
2397 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2400 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2401 "Invalid handle (%s:%u:%u).\n",
2402 OUR_HANDLE(r->in.handle)));
2406 Printer->notify.flags = r->in.flags;
2407 Printer->notify.options = r->in.options;
2408 Printer->notify.printerlocal = r->in.printer_local;
2410 TALLOC_FREE(Printer->notify.option);
2411 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2413 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2415 /* Connect to the client machine and send a ReplyOpenPrinter */
2417 if ( Printer->printer_type == SPLHND_SERVER)
2419 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2420 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2423 DEBUG(10,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2424 "client_address is %s\n", p->client_address));
2426 if (!interpret_string_addr(&client_ss, p->client_address,
2428 return WERR_SERVER_UNAVAILABLE;
2431 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2432 Printer->notify.printerlocal, 1,
2433 &Printer->notify.client_hnd, &client_ss))
2434 return WERR_SERVER_UNAVAILABLE;
2436 Printer->notify.client_connected = true;
2441 /*******************************************************************
2442 * fill a notify_info_data with the servername
2443 ********************************************************************/
2445 static void spoolss_notify_server_name(int snum,
2446 struct spoolss_Notify *data,
2447 print_queue_struct *queue,
2448 struct spoolss_PrinterInfo2 *pinfo2,
2449 TALLOC_CTX *mem_ctx)
2451 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->servername);
2454 /*******************************************************************
2455 * fill a notify_info_data with the printername (not including the servername).
2456 ********************************************************************/
2458 static void spoolss_notify_printer_name(int snum,
2459 struct spoolss_Notify *data,
2460 print_queue_struct *queue,
2461 struct spoolss_PrinterInfo2 *pinfo2,
2462 TALLOC_CTX *mem_ctx)
2464 /* the notify name should not contain the \\server\ part */
2465 const char *p = strrchr(pinfo2->printername, '\\');
2468 p = pinfo2->printername;
2473 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2476 /*******************************************************************
2477 * fill a notify_info_data with the servicename
2478 ********************************************************************/
2480 static void spoolss_notify_share_name(int snum,
2481 struct spoolss_Notify *data,
2482 print_queue_struct *queue,
2483 struct spoolss_PrinterInfo2 *pinfo2,
2484 TALLOC_CTX *mem_ctx)
2486 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2489 /*******************************************************************
2490 * fill a notify_info_data with the port name
2491 ********************************************************************/
2493 static void spoolss_notify_port_name(int snum,
2494 struct spoolss_Notify *data,
2495 print_queue_struct *queue,
2496 struct spoolss_PrinterInfo2 *pinfo2,
2497 TALLOC_CTX *mem_ctx)
2499 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->portname);
2502 /*******************************************************************
2503 * fill a notify_info_data with the printername
2504 * but it doesn't exist, have to see what to do
2505 ********************************************************************/
2507 static void spoolss_notify_driver_name(int snum,
2508 struct spoolss_Notify *data,
2509 print_queue_struct *queue,
2510 struct spoolss_PrinterInfo2 *pinfo2,
2511 TALLOC_CTX *mem_ctx)
2513 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->drivername);
2516 /*******************************************************************
2517 * fill a notify_info_data with the comment
2518 ********************************************************************/
2520 static void spoolss_notify_comment(int snum,
2521 struct spoolss_Notify *data,
2522 print_queue_struct *queue,
2523 struct spoolss_PrinterInfo2 *pinfo2,
2524 TALLOC_CTX *mem_ctx)
2528 if (*pinfo2->comment == '\0') {
2529 p = lp_comment(snum);
2531 p = pinfo2->comment;
2534 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2537 /*******************************************************************
2538 * fill a notify_info_data with the comment
2539 * location = "Room 1, floor 2, building 3"
2540 ********************************************************************/
2542 static void spoolss_notify_location(int snum,
2543 struct spoolss_Notify *data,
2544 print_queue_struct *queue,
2545 struct spoolss_PrinterInfo2 *pinfo2,
2546 TALLOC_CTX *mem_ctx)
2548 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->location);
2551 /*******************************************************************
2552 * fill a notify_info_data with the device mode
2553 * jfm:xxxx don't to it for know but that's a real problem !!!
2554 ********************************************************************/
2556 static void spoolss_notify_devmode(int snum,
2557 struct spoolss_Notify *data,
2558 print_queue_struct *queue,
2559 struct spoolss_PrinterInfo2 *pinfo2,
2560 TALLOC_CTX *mem_ctx)
2562 /* for a dummy implementation we have to zero the fields */
2563 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2566 /*******************************************************************
2567 * fill a notify_info_data with the separator file name
2568 ********************************************************************/
2570 static void spoolss_notify_sepfile(int snum,
2571 struct spoolss_Notify *data,
2572 print_queue_struct *queue,
2573 struct spoolss_PrinterInfo2 *pinfo2,
2574 TALLOC_CTX *mem_ctx)
2576 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->sepfile);
2579 /*******************************************************************
2580 * fill a notify_info_data with the print processor
2581 * jfm:xxxx return always winprint to indicate we don't do anything to it
2582 ********************************************************************/
2584 static void spoolss_notify_print_processor(int snum,
2585 struct spoolss_Notify *data,
2586 print_queue_struct *queue,
2587 struct spoolss_PrinterInfo2 *pinfo2,
2588 TALLOC_CTX *mem_ctx)
2590 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->printprocessor);
2593 /*******************************************************************
2594 * fill a notify_info_data with the print processor options
2595 * jfm:xxxx send an empty string
2596 ********************************************************************/
2598 static void spoolss_notify_parameters(int snum,
2599 struct spoolss_Notify *data,
2600 print_queue_struct *queue,
2601 struct spoolss_PrinterInfo2 *pinfo2,
2602 TALLOC_CTX *mem_ctx)
2604 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->parameters);
2607 /*******************************************************************
2608 * fill a notify_info_data with the data type
2609 * jfm:xxxx always send RAW as data type
2610 ********************************************************************/
2612 static void spoolss_notify_datatype(int snum,
2613 struct spoolss_Notify *data,
2614 print_queue_struct *queue,
2615 struct spoolss_PrinterInfo2 *pinfo2,
2616 TALLOC_CTX *mem_ctx)
2618 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, pinfo2->datatype);
2621 /*******************************************************************
2622 * fill a notify_info_data with the security descriptor
2623 * jfm:xxxx send an null pointer to say no security desc
2624 * have to implement security before !
2625 ********************************************************************/
2627 static void spoolss_notify_security_desc(int snum,
2628 struct spoolss_Notify *data,
2629 print_queue_struct *queue,
2630 struct spoolss_PrinterInfo2 *pinfo2,
2631 TALLOC_CTX *mem_ctx)
2633 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data, pinfo2->secdesc);
2636 /*******************************************************************
2637 * fill a notify_info_data with the attributes
2638 * jfm:xxxx a samba printer is always shared
2639 ********************************************************************/
2641 static void spoolss_notify_attributes(int snum,
2642 struct spoolss_Notify *data,
2643 print_queue_struct *queue,
2644 struct spoolss_PrinterInfo2 *pinfo2,
2645 TALLOC_CTX *mem_ctx)
2647 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->attributes);
2650 /*******************************************************************
2651 * fill a notify_info_data with the priority
2652 ********************************************************************/
2654 static void spoolss_notify_priority(int snum,
2655 struct spoolss_Notify *data,
2656 print_queue_struct *queue,
2657 struct spoolss_PrinterInfo2 *pinfo2,
2658 TALLOC_CTX *mem_ctx)
2660 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->priority);
2663 /*******************************************************************
2664 * fill a notify_info_data with the default priority
2665 ********************************************************************/
2667 static void spoolss_notify_default_priority(int snum,
2668 struct spoolss_Notify *data,
2669 print_queue_struct *queue,
2670 struct spoolss_PrinterInfo2 *pinfo2,
2671 TALLOC_CTX *mem_ctx)
2673 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->defaultpriority);
2676 /*******************************************************************
2677 * fill a notify_info_data with the start time
2678 ********************************************************************/
2680 static void spoolss_notify_start_time(int snum,
2681 struct spoolss_Notify *data,
2682 print_queue_struct *queue,
2683 struct spoolss_PrinterInfo2 *pinfo2,
2684 TALLOC_CTX *mem_ctx)
2686 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->starttime);
2689 /*******************************************************************
2690 * fill a notify_info_data with the until time
2691 ********************************************************************/
2693 static void spoolss_notify_until_time(int snum,
2694 struct spoolss_Notify *data,
2695 print_queue_struct *queue,
2696 struct spoolss_PrinterInfo2 *pinfo2,
2697 TALLOC_CTX *mem_ctx)
2699 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->untiltime);
2702 /*******************************************************************
2703 * fill a notify_info_data with the status
2704 ********************************************************************/
2706 static void spoolss_notify_status(int snum,
2707 struct spoolss_Notify *data,
2708 print_queue_struct *queue,
2709 struct spoolss_PrinterInfo2 *pinfo2,
2710 TALLOC_CTX *mem_ctx)
2712 print_status_struct status;
2714 print_queue_length(snum, &status);
2715 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2718 /*******************************************************************
2719 * fill a notify_info_data with the number of jobs queued
2720 ********************************************************************/
2722 static void spoolss_notify_cjobs(int snum,
2723 struct spoolss_Notify *data,
2724 print_queue_struct *queue,
2725 struct spoolss_PrinterInfo2 *pinfo2,
2726 TALLOC_CTX *mem_ctx)
2728 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2731 /*******************************************************************
2732 * fill a notify_info_data with the average ppm
2733 ********************************************************************/
2735 static void spoolss_notify_average_ppm(int snum,
2736 struct spoolss_Notify *data,
2737 print_queue_struct *queue,
2738 struct spoolss_PrinterInfo2 *pinfo2,
2739 TALLOC_CTX *mem_ctx)
2741 /* always respond 8 pages per minutes */
2742 /* a little hard ! */
2743 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, pinfo2->averageppm);
2746 /*******************************************************************
2747 * fill a notify_info_data with username
2748 ********************************************************************/
2750 static void spoolss_notify_username(int snum,
2751 struct spoolss_Notify *data,
2752 print_queue_struct *queue,
2753 struct spoolss_PrinterInfo2 *pinfo2,
2754 TALLOC_CTX *mem_ctx)
2756 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2759 /*******************************************************************
2760 * fill a notify_info_data with job status
2761 ********************************************************************/
2763 static void spoolss_notify_job_status(int snum,
2764 struct spoolss_Notify *data,
2765 print_queue_struct *queue,
2766 struct spoolss_PrinterInfo2 *pinfo2,
2767 TALLOC_CTX *mem_ctx)
2769 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2772 /*******************************************************************
2773 * fill a notify_info_data with job name
2774 ********************************************************************/
2776 static void spoolss_notify_job_name(int snum,
2777 struct spoolss_Notify *data,
2778 print_queue_struct *queue,
2779 struct spoolss_PrinterInfo2 *pinfo2,
2780 TALLOC_CTX *mem_ctx)
2782 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2785 /*******************************************************************
2786 * fill a notify_info_data with job status
2787 ********************************************************************/
2789 static void spoolss_notify_job_status_string(int snum,
2790 struct spoolss_Notify *data,
2791 print_queue_struct *queue,
2792 struct spoolss_PrinterInfo2 *pinfo2,
2793 TALLOC_CTX *mem_ctx)
2796 * Now we're returning job status codes we just return a "" here. JRA.
2801 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2804 switch (queue->status) {
2809 p = ""; /* NT provides the paused string */
2818 #endif /* NO LONGER NEEDED. */
2820 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2823 /*******************************************************************
2824 * fill a notify_info_data with job time
2825 ********************************************************************/
2827 static void spoolss_notify_job_time(int snum,
2828 struct spoolss_Notify *data,
2829 print_queue_struct *queue,
2830 struct spoolss_PrinterInfo2 *pinfo2,
2831 TALLOC_CTX *mem_ctx)
2833 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2836 /*******************************************************************
2837 * fill a notify_info_data with job size
2838 ********************************************************************/
2840 static void spoolss_notify_job_size(int snum,
2841 struct spoolss_Notify *data,
2842 print_queue_struct *queue,
2843 struct spoolss_PrinterInfo2 *pinfo2,
2844 TALLOC_CTX *mem_ctx)
2846 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
2849 /*******************************************************************
2850 * fill a notify_info_data with page info
2851 ********************************************************************/
2852 static void spoolss_notify_total_pages(int snum,
2853 struct spoolss_Notify *data,
2854 print_queue_struct *queue,
2855 struct spoolss_PrinterInfo2 *pinfo2,
2856 TALLOC_CTX *mem_ctx)
2858 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
2861 /*******************************************************************
2862 * fill a notify_info_data with pages printed info.
2863 ********************************************************************/
2864 static void spoolss_notify_pages_printed(int snum,
2865 struct spoolss_Notify *data,
2866 print_queue_struct *queue,
2867 struct spoolss_PrinterInfo2 *pinfo2,
2868 TALLOC_CTX *mem_ctx)
2870 /* Add code when back-end tracks this */
2871 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
2874 /*******************************************************************
2875 Fill a notify_info_data with job position.
2876 ********************************************************************/
2878 static void spoolss_notify_job_position(int snum,
2879 struct spoolss_Notify *data,
2880 print_queue_struct *queue,
2881 struct spoolss_PrinterInfo2 *pinfo2,
2882 TALLOC_CTX *mem_ctx)
2884 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
2887 /*******************************************************************
2888 Fill a notify_info_data with submitted time.
2889 ********************************************************************/
2891 static void spoolss_notify_submitted_time(int snum,
2892 struct spoolss_Notify *data,
2893 print_queue_struct *queue,
2894 struct spoolss_PrinterInfo2 *pinfo2,
2895 TALLOC_CTX *mem_ctx)
2897 data->data.string.string = NULL;
2898 data->data.string.size = 0;
2900 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
2901 &data->data.string.string,
2902 &data->data.string.size);
2906 struct s_notify_info_data_table
2908 enum spoolss_NotifyType type;
2911 enum spoolss_NotifyTable variable_type;
2912 void (*fn) (int snum, struct spoolss_Notify *data,
2913 print_queue_struct *queue,
2914 struct spoolss_PrinterInfo2 *pinfo2,
2915 TALLOC_CTX *mem_ctx);
2918 /* A table describing the various print notification constants and
2919 whether the notification data is a pointer to a variable sized
2920 buffer, a one value uint32_t or a two value uint32_t. */
2922 static const struct s_notify_info_data_table notify_info_data_table[] =
2924 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2925 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINTER_NAME, "PRINTER_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2926 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SHARE_NAME, "PRINTER_NOTIFY_FIELD_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
2927 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PORT_NAME, "PRINTER_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2928 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DRIVER_NAME, "PRINTER_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2929 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_COMMENT, "PRINTER_NOTIFY_FIELD_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
2930 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_LOCATION, "PRINTER_NOTIFY_FIELD_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
2931 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEVMODE, "PRINTER_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2932 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SEPFILE, "PRINTER_NOTIFY_FIELD_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
2933 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR, "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2934 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PARAMETERS, "PRINTER_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2935 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DATATYPE, "PRINTER_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2936 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
2937 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_ATTRIBUTES, "PRINTER_NOTIFY_FIELD_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
2938 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PRIORITY, "PRINTER_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2939 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY, "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
2940 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_START_TIME, "PRINTER_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2941 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_UNTIL_TIME, "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2942 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS, "PRINTER_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
2943 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_STATUS_STRING, "PRINTER_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
2944 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_CJOBS, "PRINTER_NOTIFY_FIELD_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
2945 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_AVERAGE_PPM, "PRINTER_NOTIFY_FIELD_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
2946 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_PAGES, "PRINTER_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
2947 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_PAGES_PRINTED, "PRINTER_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2948 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_TOTAL_BYTES, "PRINTER_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
2949 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_BYTES_PRINTED, "PRINTER_NOTIFY_FIELD_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
2950 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINTER_NAME, "JOB_NOTIFY_FIELD_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
2951 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_MACHINE_NAME, "JOB_NOTIFY_FIELD_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
2952 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PORT_NAME, "JOB_NOTIFY_FIELD_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
2953 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_USER_NAME, "JOB_NOTIFY_FIELD_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2954 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_NOTIFY_NAME, "JOB_NOTIFY_FIELD_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
2955 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DATATYPE, "JOB_NOTIFY_FIELD_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
2956 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRINT_PROCESSOR, "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
2957 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PARAMETERS, "JOB_NOTIFY_FIELD_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
2958 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DRIVER_NAME, "JOB_NOTIFY_FIELD_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
2959 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DEVMODE, "JOB_NOTIFY_FIELD_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
2960 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS, "JOB_NOTIFY_FIELD_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
2961 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_STATUS_STRING, "JOB_NOTIFY_FIELD_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
2962 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR, "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
2963 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_DOCUMENT, "JOB_NOTIFY_FIELD_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
2964 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PRIORITY, "JOB_NOTIFY_FIELD_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
2965 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_POSITION, "JOB_NOTIFY_FIELD_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
2966 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_SUBMITTED, "JOB_NOTIFY_FIELD_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
2967 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_START_TIME, "JOB_NOTIFY_FIELD_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
2968 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_UNTIL_TIME, "JOB_NOTIFY_FIELD_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
2969 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TIME, "JOB_NOTIFY_FIELD_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
2970 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_PAGES, "JOB_NOTIFY_FIELD_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
2971 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_PAGES_PRINTED, "JOB_NOTIFY_FIELD_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
2972 { JOB_NOTIFY_TYPE, JOB_NOTIFY_FIELD_TOTAL_BYTES, "JOB_NOTIFY_FIELD_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
2975 /*******************************************************************
2976 Return the variable_type of info_data structure.
2977 ********************************************************************/
2979 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
2984 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
2985 if ( (notify_info_data_table[i].type == type) &&
2986 (notify_info_data_table[i].field == field) ) {
2987 return notify_info_data_table[i].variable_type;
2991 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
2996 /****************************************************************************
2997 ****************************************************************************/
2999 static bool search_notify(enum spoolss_NotifyType type,
3005 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3006 if (notify_info_data_table[i].type == type &&
3007 notify_info_data_table[i].field == field &&
3008 notify_info_data_table[i].fn != NULL) {
3017 /****************************************************************************
3018 ****************************************************************************/
3020 static void construct_info_data(struct spoolss_Notify *info_data,
3021 enum spoolss_NotifyType type,
3022 uint16_t field, int id)
3024 info_data->type = type;
3025 info_data->field.field = field;
3026 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3027 info_data->job_id = id;
3030 /*******************************************************************
3032 * fill a notify_info struct with info asked
3034 ********************************************************************/
3036 static bool construct_notify_printer_info(Printer_entry *print_hnd,
3037 struct spoolss_NotifyInfo *info,
3038 struct spoolss_PrinterInfo2 *pinfo2,
3040 const struct spoolss_NotifyOptionType *option_type,
3042 TALLOC_CTX *mem_ctx)
3045 enum spoolss_NotifyType type;
3048 struct spoolss_Notify *current_data;
3049 print_queue_struct *queue=NULL;
3051 type = option_type->type;
3053 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3054 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3055 option_type->count, lp_servicename(snum)));
3057 for(field_num=0; field_num < option_type->count; field_num++) {
3058 field = option_type->fields[field_num].field;
3060 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3062 if (!search_notify(type, field, &j) )
3065 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3066 struct spoolss_Notify,
3068 if (info->notifies == NULL) {
3069 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3073 current_data = &info->notifies[info->count];
3075 construct_info_data(current_data, type, field, id);
3077 DEBUG(10, ("construct_notify_printer_info: "
3078 "calling [%s] snum=%d printername=[%s])\n",
3079 notify_info_data_table[j].name, snum,
3080 pinfo2->printername));
3082 notify_info_data_table[j].fn(snum, current_data, queue,
3091 /*******************************************************************
3093 * fill a notify_info struct with info asked
3095 ********************************************************************/
3097 static bool construct_notify_jobs_info(print_queue_struct *queue,
3098 struct spoolss_NotifyInfo *info,
3099 struct spoolss_PrinterInfo2 *pinfo2,
3101 const struct spoolss_NotifyOptionType *option_type,
3103 TALLOC_CTX *mem_ctx)
3106 enum spoolss_NotifyType type;
3108 struct spoolss_Notify *current_data;
3110 DEBUG(4,("construct_notify_jobs_info\n"));
3112 type = option_type->type;
3114 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3115 (type == PRINTER_NOTIFY_TYPE ? "PRINTER_NOTIFY_TYPE" : "JOB_NOTIFY_TYPE"),
3116 option_type->count));
3118 for(field_num=0; field_num<option_type->count; field_num++) {
3119 field = option_type->fields[field_num].field;
3121 if (!search_notify(type, field, &j) )
3124 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3125 struct spoolss_Notify,
3127 if (info->notifies == NULL) {
3128 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3132 current_data=&(info->notifies[info->count]);
3134 construct_info_data(current_data, type, field, id);
3135 notify_info_data_table[j].fn(snum, current_data, queue,
3144 * JFM: The enumeration is not that simple, it's even non obvious.
3146 * let's take an example: I want to monitor the PRINTER SERVER for
3147 * the printer's name and the number of jobs currently queued.
3148 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3149 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3151 * I have 3 printers on the back of my server.
3153 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3156 * 1 printer 1 name 1
3157 * 2 printer 1 cjob 1
3158 * 3 printer 2 name 2
3159 * 4 printer 2 cjob 2
3160 * 5 printer 3 name 3
3161 * 6 printer 3 name 3
3163 * that's the print server case, the printer case is even worse.
3166 /*******************************************************************
3168 * enumerate all printers on the printserver
3169 * fill a notify_info struct with info asked
3171 ********************************************************************/
3173 static WERROR printserver_notify_info(struct pipes_struct *p,
3174 struct policy_handle *hnd,
3175 struct spoolss_NotifyInfo *info,
3176 TALLOC_CTX *mem_ctx)
3179 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3180 int n_services=lp_numservices();
3182 struct spoolss_NotifyOption *option;
3183 struct spoolss_NotifyOptionType option_type;
3184 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3187 DEBUG(4,("printserver_notify_info\n"));
3192 option = Printer->notify.option;
3195 info->notifies = NULL;
3198 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3199 sending a ffpcn() request first */
3204 for (i=0; i<option->count; i++) {
3205 option_type = option->types[i];
3207 if (option_type.type != PRINTER_NOTIFY_TYPE)
3210 for (snum = 0; snum < n_services; snum++) {
3211 if (!lp_browseable(snum) ||
3212 !lp_snum_ok(snum) ||
3213 !lp_print_ok(snum)) {
3214 continue; /* skip */
3217 /* Maybe we should use the SYSTEM server_info here... */
3218 result = winreg_get_printer(mem_ctx, p->server_info,
3219 Printer->servername,
3220 lp_servicename(snum),
3222 if (!W_ERROR_IS_OK(result)) {
3223 DEBUG(4, ("printserver_notify_info: "
3224 "Failed to get printer [%s]\n",
3225 lp_servicename(snum)));
3230 construct_notify_printer_info(Printer, info,
3235 TALLOC_FREE(pinfo2);
3241 * Debugging information, don't delete.
3244 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3245 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3246 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3248 for (i=0; i<info->count; i++) {
3249 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3250 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3251 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3258 /*******************************************************************
3260 * fill a notify_info struct with info asked
3262 ********************************************************************/
3264 static WERROR printer_notify_info(struct pipes_struct *p,
3265 struct policy_handle *hnd,
3266 struct spoolss_NotifyInfo *info,
3267 TALLOC_CTX *mem_ctx)
3270 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
3273 struct spoolss_NotifyOption *option;
3274 struct spoolss_NotifyOptionType option_type;
3276 print_queue_struct *queue=NULL;
3277 print_status_struct status;
3278 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
3281 DEBUG(4,("printer_notify_info\n"));
3286 option = Printer->notify.option;
3290 info->notifies = NULL;
3293 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3294 sending a ffpcn() request first */
3299 get_printer_snum(p, hnd, &snum, NULL);
3301 /* Maybe we should use the SYSTEM server_info here... */
3302 result = winreg_get_printer(mem_ctx, p->server_info,
3303 Printer->servername,
3304 lp_servicename(snum), &pinfo2);
3305 if (!W_ERROR_IS_OK(result)) {
3309 for (i=0; i<option->count; i++) {
3310 option_type = option->types[i];
3312 switch (option_type.type) {
3313 case PRINTER_NOTIFY_TYPE:
3314 if (construct_notify_printer_info(Printer, info,
3322 case JOB_NOTIFY_TYPE:
3324 count = print_queue_status(snum, &queue, &status);
3326 for (j=0; j<count; j++) {
3327 construct_notify_jobs_info(&queue[j], info,
3340 * Debugging information, don't delete.
3343 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3344 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3345 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3347 for (i=0; i<info->count; i++) {
3348 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3349 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3350 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3354 talloc_free(pinfo2);
3358 /****************************************************************
3359 _spoolss_RouterRefreshPrinterChangeNotify
3360 ****************************************************************/
3362 WERROR _spoolss_RouterRefreshPrinterChangeNotify(struct pipes_struct *p,
3363 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3365 struct spoolss_NotifyInfo *info;
3367 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
3368 WERROR result = WERR_BADFID;
3370 /* we always have a spoolss_NotifyInfo struct */
3371 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3373 result = WERR_NOMEM;
3377 *r->out.info = info;
3380 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3381 "Invalid handle (%s:%u:%u).\n",
3382 OUR_HANDLE(r->in.handle)));
3386 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3389 * We are now using the change value, and
3390 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3391 * I don't have a global notification system, I'm sending back all the
3392 * informations even when _NOTHING_ has changed.
3395 /* We need to keep track of the change value to send back in
3396 RRPCN replies otherwise our updates are ignored. */
3398 Printer->notify.fnpcn = true;
3400 if (Printer->notify.client_connected) {
3401 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3402 "Saving change value in request [%x]\n",
3404 Printer->notify.change = r->in.change_low;
3407 /* just ignore the spoolss_NotifyOption */
3409 switch (Printer->printer_type) {
3411 result = printserver_notify_info(p, r->in.handle,
3415 case SPLHND_PRINTER:
3416 result = printer_notify_info(p, r->in.handle,
3421 Printer->notify.fnpcn = false;
3427 /********************************************************************
3428 * construct_printer_info_0
3429 * fill a printer_info_0 struct
3430 ********************************************************************/
3432 static WERROR construct_printer_info0(TALLOC_CTX *mem_ctx,
3433 struct auth_serversupplied_info *server_info,
3434 struct spoolss_PrinterInfo2 *info2,
3435 struct spoolss_PrinterInfo0 *r,
3439 counter_printer_0 *session_counter;
3440 struct timeval setuptime;
3441 print_status_struct status;
3443 r->printername = talloc_strdup(mem_ctx, info2->printername);
3444 W_ERROR_HAVE_NO_MEMORY(r->printername);
3446 r->servername = talloc_strdup(mem_ctx, info2->servername);
3447 W_ERROR_HAVE_NO_MEMORY(r->servername);
3449 count = print_queue_length(snum, &status);
3451 /* check if we already have a counter for this printer */
3452 for (session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3453 if (session_counter->snum == snum)
3457 /* it's the first time, add it to the list */
3458 if (session_counter == NULL) {
3459 session_counter = SMB_MALLOC_P(counter_printer_0);
3460 W_ERROR_HAVE_NO_MEMORY(session_counter);
3461 ZERO_STRUCTP(session_counter);
3462 session_counter->snum = snum;
3463 session_counter->counter = 0;
3464 DLIST_ADD(counter_list, session_counter);
3468 session_counter->counter++;
3474 get_startup_time(&setuptime);
3475 init_systemtime(&r->time, gmtime(&setuptime.tv_sec));
3478 * the global_counter should be stored in a TDB as it's common to all the clients
3479 * and should be zeroed on samba startup
3481 r->global_counter = session_counter->counter;
3483 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3484 SSVAL(&r->version, 0, 0x0005); /* NT 5 */
3485 SSVAL(&r->version, 2, 0x0893); /* build 2195 */
3486 r->free_build = SPOOLSS_RELEASE_BUILD;
3488 r->max_spooling = 0;
3489 r->session_counter = session_counter->counter;
3490 r->num_error_out_of_paper = 0x0;
3491 r->num_error_not_ready = 0x0; /* number of print failure */
3493 r->number_of_processors = 0x1;
3494 r->processor_type = PROCESSOR_INTEL_PENTIUM; /* 586 Pentium ? */
3495 r->high_part_total_bytes = 0x0;
3496 winreg_printer_get_changeid(mem_ctx, server_info, info2->sharename, &r->change_id); /* ChangeID in milliseconds*/
3497 r->last_error = WERR_OK;
3498 r->status = nt_printq_status(status.status);
3499 r->enumerate_network_printers = 0x0;
3500 r->c_setprinter = 0x0;
3501 r->processor_architecture = 0x0;
3502 r->processor_level = 0x6; /* 6 ???*/
3511 /********************************************************************
3512 * construct_printer_info1
3513 * fill a spoolss_PrinterInfo1 struct
3514 ********************************************************************/
3516 static WERROR construct_printer_info1(TALLOC_CTX *mem_ctx,
3517 const struct spoolss_PrinterInfo2 *info2,
3519 struct spoolss_PrinterInfo1 *r,
3524 r->description = talloc_asprintf(mem_ctx, "%s,%s,%s",
3528 W_ERROR_HAVE_NO_MEMORY(r->description);
3530 if (info2->comment == NULL || info2->comment[0] == '\0') {
3531 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3533 r->comment = talloc_strdup(mem_ctx, info2->comment); /* saved comment */
3535 W_ERROR_HAVE_NO_MEMORY(r->comment);
3537 r->name = talloc_strdup(mem_ctx, info2->printername);
3538 W_ERROR_HAVE_NO_MEMORY(r->name);
3543 /********************************************************************
3544 * construct_printer_info2
3545 * fill a spoolss_PrinterInfo2 struct
3546 ********************************************************************/
3548 static WERROR construct_printer_info2(TALLOC_CTX *mem_ctx,
3549 const struct spoolss_PrinterInfo2 *info2,
3550 struct spoolss_PrinterInfo2 *r,
3554 print_status_struct status;
3556 count = print_queue_length(snum, &status);
3558 r->servername = talloc_strdup(mem_ctx, info2->servername);
3559 W_ERROR_HAVE_NO_MEMORY(r->servername);
3560 r->printername = talloc_strdup(mem_ctx, info2->printername);
3561 W_ERROR_HAVE_NO_MEMORY(r->printername);
3562 r->sharename = talloc_strdup(mem_ctx, lp_servicename(snum));
3563 W_ERROR_HAVE_NO_MEMORY(r->sharename);
3564 r->portname = talloc_strdup(mem_ctx, info2->portname);
3565 W_ERROR_HAVE_NO_MEMORY(r->portname);
3566 r->drivername = talloc_strdup(mem_ctx, info2->drivername);
3567 W_ERROR_HAVE_NO_MEMORY(r->drivername);
3569 if (info2->comment[0] == '\0') {
3570 r->comment = talloc_strdup(mem_ctx, lp_comment(snum));
3572 r->comment = talloc_strdup(mem_ctx, info2->comment);
3574 W_ERROR_HAVE_NO_MEMORY(r->comment);
3576 r->location = talloc_strdup(mem_ctx, info2->location);
3577 W_ERROR_HAVE_NO_MEMORY(r->location);
3578 r->sepfile = talloc_strdup(mem_ctx, info2->sepfile);
3579 W_ERROR_HAVE_NO_MEMORY(r->sepfile);
3580 r->printprocessor = talloc_strdup(mem_ctx, info2->printprocessor);
3581 W_ERROR_HAVE_NO_MEMORY(r->printprocessor);
3582 r->datatype = talloc_strdup(mem_ctx, info2->datatype);
3583 W_ERROR_HAVE_NO_MEMORY(r->datatype);
3584 r->parameters = talloc_strdup(mem_ctx, info2->parameters);
3585 W_ERROR_HAVE_NO_MEMORY(r->parameters);
3587 r->attributes = info2->attributes;
3589 r->priority = info2->priority;
3590 r->defaultpriority = info2->defaultpriority;
3591 r->starttime = info2->starttime;
3592 r->untiltime = info2->untiltime;
3593 r->status = nt_printq_status(status.status);
3595 r->averageppm = info2->averageppm;
3597 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3599 DEBUG(8,("Returning NULL Devicemode!\n"));
3604 if (info2->secdesc != NULL) {
3605 /* don't use talloc_steal() here unless you do a deep steal of all
3606 the SEC_DESC members */
3608 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3614 /********************************************************************
3615 * construct_printer_info3
3616 * fill a spoolss_PrinterInfo3 struct
3617 ********************************************************************/
3619 static WERROR construct_printer_info3(TALLOC_CTX *mem_ctx,
3620 const struct spoolss_PrinterInfo2 *info2,
3621 struct spoolss_PrinterInfo3 *r,
3624 /* These are the components of the SD we are returning. */
3626 if (info2->secdesc != NULL) {
3627 /* don't use talloc_steal() here unless you do a deep steal of all
3628 the SEC_DESC members */
3630 r->secdesc = dup_sec_desc(mem_ctx, info2->secdesc);
3631 W_ERROR_HAVE_NO_MEMORY(r->secdesc);
3637 /********************************************************************
3638 * construct_printer_info4
3639 * fill a spoolss_PrinterInfo4 struct
3640 ********************************************************************/
3642 static WERROR construct_printer_info4(TALLOC_CTX *mem_ctx,
3643 const struct spoolss_PrinterInfo2 *info2,
3644 struct spoolss_PrinterInfo4 *r,
3647 r->printername = talloc_strdup(mem_ctx, info2->printername);
3648 W_ERROR_HAVE_NO_MEMORY(r->printername);
3649 r->servername = talloc_strdup(mem_ctx, info2->servername);
3650 W_ERROR_HAVE_NO_MEMORY(r->servername);
3652 r->attributes = info2->attributes;
3657 /********************************************************************
3658 * construct_printer_info5
3659 * fill a spoolss_PrinterInfo5 struct
3660 ********************************************************************/
3662 static WERROR construct_printer_info5(TALLOC_CTX *mem_ctx,
3663 const struct spoolss_PrinterInfo2 *info2,
3664 struct spoolss_PrinterInfo5 *r,
3667 r->printername = talloc_strdup(mem_ctx, info2->printername);
3668 W_ERROR_HAVE_NO_MEMORY(r->printername);
3669 r->portname = talloc_strdup(mem_ctx, info2->portname);
3670 W_ERROR_HAVE_NO_MEMORY(r->portname);
3672 r->attributes = info2->attributes;
3674 /* these two are not used by NT+ according to MSDN */
3675 r->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
3676 r->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
3681 /********************************************************************
3682 * construct_printer_info_6
3683 * fill a spoolss_PrinterInfo6 struct
3684 ********************************************************************/
3686 static WERROR construct_printer_info6(TALLOC_CTX *mem_ctx,
3687 const struct spoolss_PrinterInfo2 *info2,
3688 struct spoolss_PrinterInfo6 *r,
3692 print_status_struct status;
3694 count = print_queue_length(snum, &status);
3696 r->status = nt_printq_status(status.status);
3701 /********************************************************************
3702 * construct_printer_info7
3703 * fill a spoolss_PrinterInfo7 struct
3704 ********************************************************************/
3706 static WERROR construct_printer_info7(TALLOC_CTX *mem_ctx,
3707 Printer_entry *print_hnd,
3708 struct spoolss_PrinterInfo7 *r,
3711 struct auth_serversupplied_info *server_info;
3715 status = make_server_info_system(mem_ctx, &server_info);
3716 if (!NT_STATUS_IS_OK(status)) {
3717 DEBUG(0, ("construct_printer_info7: "
3718 "Could not create system server_info\n"));
3722 if (is_printer_published(mem_ctx, server_info, print_hnd->servername,
3723 lp_servicename(snum), &guid, NULL)) {
3724 r->guid = talloc_strdup_upper(mem_ctx, GUID_string2(mem_ctx, &guid));
3725 r->action = DSPRINT_PUBLISH;
3727 r->guid = talloc_strdup(mem_ctx, "");
3728 r->action = DSPRINT_UNPUBLISH;
3730 W_ERROR_HAVE_NO_MEMORY(r->guid);
3732 TALLOC_FREE(server_info);
3736 /********************************************************************
3737 * construct_printer_info8
3738 * fill a spoolss_PrinterInfo8 struct
3739 ********************************************************************/
3741 static WERROR construct_printer_info8(TALLOC_CTX *mem_ctx,
3742 const struct spoolss_PrinterInfo2 *info2,
3743 struct spoolss_DeviceModeInfo *r,
3746 copy_devicemode(mem_ctx, info2->devmode, &r->devmode);
3748 DEBUG(8,("Returning NULL Devicemode!\n"));
3755 /********************************************************************
3756 ********************************************************************/
3758 static bool snum_is_shared_printer(int snum)
3760 return (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum));
3763 /********************************************************************
3764 Spoolss_enumprinters.
3765 ********************************************************************/
3767 static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx,
3768 struct auth_serversupplied_info *server_info,
3771 union spoolss_PrinterInfo **info_p,
3775 int n_services = lp_numservices();
3776 union spoolss_PrinterInfo *info = NULL;
3778 WERROR result = WERR_OK;
3783 for (snum = 0; snum < n_services; snum++) {
3785 const char *printer;
3786 struct spoolss_PrinterInfo2 *info2;
3788 if (!snum_is_shared_printer(snum)) {
3792 printer = lp_const_servicename(snum);
3794 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n",
3797 result = winreg_create_printer(mem_ctx,
3801 if (!W_ERROR_IS_OK(result)) {
3805 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
3806 union spoolss_PrinterInfo,
3809 result = WERR_NOMEM;
3813 result = winreg_get_printer(mem_ctx, server_info,
3814 NULL, printer, &info2);
3815 if (!W_ERROR_IS_OK(result)) {
3821 result = construct_printer_info0(info, server_info, info2,
3822 &info[count].info0, snum);
3825 result = construct_printer_info1(info, info2, flags,
3826 &info[count].info1, snum);
3829 result = construct_printer_info2(info, info2,
3830 &info[count].info2, snum);
3833 result = construct_printer_info4(info, info2,
3834 &info[count].info4, snum);
3837 result = construct_printer_info5(info, info2,
3838 &info[count].info5, snum);
3842 result = WERR_UNKNOWN_LEVEL;
3846 if (!W_ERROR_IS_OK(result)) {
3857 if (!W_ERROR_IS_OK(result)) {
3867 /********************************************************************
3868 * handle enumeration of printers at level 0
3869 ********************************************************************/
3871 static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx,
3872 struct auth_serversupplied_info *server_info,
3874 const char *servername,
3875 union spoolss_PrinterInfo **info,
3878 DEBUG(4,("enum_all_printers_info_0\n"));
3880 return enum_all_printers_info_level(mem_ctx, server_info, 0, flags, info, count);
3884 /********************************************************************
3885 ********************************************************************/
3887 static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx,
3888 struct auth_serversupplied_info *server_info,
3890 union spoolss_PrinterInfo **info,
3893 DEBUG(4,("enum_all_printers_info_1\n"));
3895 return enum_all_printers_info_level(mem_ctx, server_info, 1, flags, info, count);
3898 /********************************************************************
3899 enum_all_printers_info_1_local.
3900 *********************************************************************/
3902 static WERROR enum_all_printers_info_1_local(TALLOC_CTX *mem_ctx,
3903 struct auth_serversupplied_info *server_info,
3904 union spoolss_PrinterInfo **info,
3907 DEBUG(4,("enum_all_printers_info_1_local\n"));
3909 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3912 /********************************************************************
3913 enum_all_printers_info_1_name.
3914 *********************************************************************/
3916 static WERROR enum_all_printers_info_1_name(TALLOC_CTX *mem_ctx,
3917 struct auth_serversupplied_info *server_info,
3919 union spoolss_PrinterInfo **info,
3922 const char *s = name;
3924 DEBUG(4,("enum_all_printers_info_1_name\n"));
3926 if ((name[0] == '\\') && (name[1] == '\\')) {
3930 if (!is_myname_or_ipaddr(s)) {
3931 return WERR_INVALID_NAME;
3934 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_ICON8, info, count);
3937 /********************************************************************
3938 enum_all_printers_info_1_network.
3939 *********************************************************************/
3941 static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx,
3942 struct auth_serversupplied_info *server_info,
3944 union spoolss_PrinterInfo **info,
3947 const char *s = name;
3949 DEBUG(4,("enum_all_printers_info_1_network\n"));
3951 /* If we respond to a enum_printers level 1 on our name with flags
3952 set to PRINTER_ENUM_REMOTE with a list of printers then these
3953 printers incorrectly appear in the APW browse list.
3954 Specifically the printers for the server appear at the workgroup
3955 level where all the other servers in the domain are
3956 listed. Windows responds to this call with a
3957 WERR_CAN_NOT_COMPLETE so we should do the same. */
3959 if (name[0] == '\\' && name[1] == '\\') {
3963 if (is_myname_or_ipaddr(s)) {
3964 return WERR_CAN_NOT_COMPLETE;
3967 return enum_all_printers_info_1(mem_ctx, server_info, PRINTER_ENUM_NAME, info, count);
3970 /********************************************************************
3971 * api_spoolss_enumprinters
3973 * called from api_spoolss_enumprinters (see this to understand)
3974 ********************************************************************/
3976 static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx,
3977 struct auth_serversupplied_info *server_info,
3978 union spoolss_PrinterInfo **info,
3981 DEBUG(4,("enum_all_printers_info_2\n"));
3983 return enum_all_printers_info_level(mem_ctx, server_info, 2, 0, info, count);
3986 /********************************************************************
3987 * handle enumeration of printers at level 1
3988 ********************************************************************/
3990 static WERROR enumprinters_level1(TALLOC_CTX *mem_ctx,
3991 struct auth_serversupplied_info *server_info,
3994 union spoolss_PrinterInfo **info,
3997 /* Not all the flags are equals */
3999 if (flags & PRINTER_ENUM_LOCAL) {
4000 return enum_all_printers_info_1_local(mem_ctx, server_info, info, count);
4003 if (flags & PRINTER_ENUM_NAME) {
4004 return enum_all_printers_info_1_name(mem_ctx, server_info, name, info, count);
4007 if (flags & PRINTER_ENUM_NETWORK) {
4008 return enum_all_printers_info_1_network(mem_ctx, server_info, name, info, count);
4011 return WERR_OK; /* NT4sp5 does that */
4014 /********************************************************************
4015 * handle enumeration of printers at level 2
4016 ********************************************************************/
4018 static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx,
4019 struct auth_serversupplied_info *server_info,
4021 const char *servername,
4022 union spoolss_PrinterInfo **info,
4025 if (flags & PRINTER_ENUM_LOCAL) {
4026 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4029 if (flags & PRINTER_ENUM_NAME) {
4030 if (!is_myname_or_ipaddr(canon_servername(servername))) {
4031 return WERR_INVALID_NAME;
4034 return enum_all_printers_info_2(mem_ctx, server_info, info, count);
4037 if (flags & PRINTER_ENUM_REMOTE) {
4038 return WERR_UNKNOWN_LEVEL;
4044 /********************************************************************
4045 * handle enumeration of printers at level 4
4046 ********************************************************************/
4048 static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx,
4049 struct auth_serversupplied_info *server_info,
4051 const char *servername,
4052 union spoolss_PrinterInfo **info,
4055 DEBUG(4,("enum_all_printers_info_4\n"));
4057 return enum_all_printers_info_level(mem_ctx, server_info, 4, flags, info, count);
4061 /********************************************************************
4062 * handle enumeration of printers at level 5
4063 ********************************************************************/
4065 static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx,
4066 struct auth_serversupplied_info *server_info,
4068 const char *servername,
4069 union spoolss_PrinterInfo **info,
4072 DEBUG(4,("enum_all_printers_info_5\n"));
4074 return enum_all_printers_info_level(mem_ctx, server_info, 5, flags, info, count);
4077 /****************************************************************
4078 _spoolss_EnumPrinters
4079 ****************************************************************/
4081 WERROR _spoolss_EnumPrinters(struct pipes_struct *p,
4082 struct spoolss_EnumPrinters *r)
4084 const char *name = NULL;
4087 /* that's an [in out] buffer */
4089 if (!r->in.buffer && (r->in.offered != 0)) {
4090 return WERR_INVALID_PARAM;
4093 DEBUG(4,("_spoolss_EnumPrinters\n"));
4097 *r->out.info = NULL;
4101 * flags==PRINTER_ENUM_NAME
4102 * if name=="" then enumerates all printers
4103 * if name!="" then enumerate the printer
4104 * flags==PRINTER_ENUM_REMOTE
4105 * name is NULL, enumerate printers
4106 * Level 2: name!="" enumerates printers, name can't be NULL
4107 * Level 3: doesn't exist
4108 * Level 4: does a local registry lookup
4109 * Level 5: same as Level 2
4113 name = talloc_strdup_upper(p->mem_ctx, r->in.server);
4114 W_ERROR_HAVE_NO_MEMORY(name);
4117 switch (r->in.level) {
4119 result = enumprinters_level0(p->mem_ctx, p->server_info,
4121 r->out.info, r->out.count);
4124 result = enumprinters_level1(p->mem_ctx, p->server_info,
4126 r->out.info, r->out.count);
4129 result = enumprinters_level2(p->mem_ctx, p->server_info,
4131 r->out.info, r->out.count);
4134 result = enumprinters_level4(p->mem_ctx, p->server_info,
4136 r->out.info, r->out.count);
4139 result = enumprinters_level5(p->mem_ctx, p->server_info,
4141 r->out.info, r->out.count);
4144 return WERR_UNKNOWN_LEVEL;
4147 if (!W_ERROR_IS_OK(result)) {
4151 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
4152 spoolss_EnumPrinters,
4153 *r->out.info, r->in.level,
4155 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
4156 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
4158 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4161 /****************************************************************
4163 ****************************************************************/
4165 WERROR _spoolss_GetPrinter(struct pipes_struct *p,
4166 struct spoolss_GetPrinter *r)
4168 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
4169 struct spoolss_PrinterInfo2 *info2 = NULL;
4170 WERROR result = WERR_OK;
4171 const char *servername = NULL;
4174 /* that's an [in out] buffer */
4176 if (!r->in.buffer && (r->in.offered != 0)) {
4177 return WERR_INVALID_PARAM;
4182 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
4186 if (Printer != NULL || Printer->servername != NULL) {
4187 servername = Printer->servername;
4190 result = winreg_get_printer(p->mem_ctx,
4193 lp_const_servicename(snum),
4195 if (!W_ERROR_IS_OK(result)) {
4199 switch (r->in.level) {
4201 result = construct_printer_info0(p->mem_ctx, p->server_info,
4203 &r->out.info->info0, snum);
4206 result = construct_printer_info1(p->mem_ctx, info2,
4208 &r->out.info->info1, snum);
4211 result = construct_printer_info2(p->mem_ctx, info2,
4212 &r->out.info->info2, snum);
4215 result = construct_printer_info3(p->mem_ctx, info2,
4216 &r->out.info->info3, snum);
4219 result = construct_printer_info4(p->mem_ctx, info2,
4220 &r->out.info->info4, snum);
4223 result = construct_printer_info5(p->mem_ctx, info2,
4224 &r->out.info->info5, snum);
4227 result = construct_printer_info6(p->mem_ctx, info2,
4228 &r->out.info->info6, snum);
4231 result = construct_printer_info7(p->mem_ctx, Printer,
4232 &r->out.info->info7, snum);
4235 result = construct_printer_info8(p->mem_ctx, info2,
4236 &r->out.info->info8, snum);
4239 result = WERR_UNKNOWN_LEVEL;
4243 if (!W_ERROR_IS_OK(result)) {
4244 DEBUG(0, ("_spoolss_GetPrinter: failed to construct printer info level %d - %s\n",
4245 r->in.level, win_errstr(result)));
4246 TALLOC_FREE(r->out.info);
4250 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrinterInfo,
4251 r->out.info, r->in.level);
4252 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
4254 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
4257 /********************************************************************
4258 ********************************************************************/
4260 #define FILL_DRIVER_STRING(mem_ctx, in, out) \
4262 if (in && strlen(in)) { \
4263 out = talloc_strdup(mem_ctx, in); \
4265 out = talloc_strdup(mem_ctx, ""); \
4267 W_ERROR_HAVE_NO_MEMORY(out); \
4270 #define FILL_DRIVER_UNC_STRING(mem_ctx, server, arch, ver, in, out) \
4272 if (in && strlen(in)) { \
4273 out = talloc_asprintf(mem_ctx, "\\\\%s\\print$\\%s\\%d\\%s", server, get_short_archi(arch), ver, in); \
4275 out = talloc_strdup(mem_ctx, ""); \
4277 W_ERROR_HAVE_NO_MEMORY(out); \
4280 static WERROR string_array_from_driver_info(TALLOC_CTX *mem_ctx,
4281 const char **string_array,
4282 const char ***presult,
4283 const char *cservername,
4287 int i, num_strings = 0;
4288 const char **array = NULL;
4290 if (string_array == NULL) {
4291 return WERR_INVALID_PARAMETER;;
4294 for (i=0; string_array[i] && string_array[i][0] != '\0'; i++) {
4295 const char *str = NULL;
4297 if (cservername == NULL || arch == NULL) {
4298 FILL_DRIVER_STRING(mem_ctx, string_array[i], str);
4300 FILL_DRIVER_UNC_STRING(mem_ctx, cservername, arch, version, string_array[i], str);
4303 if (!add_string_to_array(mem_ctx, str, &array, &num_strings)) {
4310 ADD_TO_ARRAY(mem_ctx, const char *, NULL,
4311 &array, &num_strings);
4321 /********************************************************************
4322 * fill a spoolss_DriverInfo1 struct
4323 ********************************************************************/
4325 static WERROR fill_printer_driver_info1(TALLOC_CTX *mem_ctx,
4326 struct spoolss_DriverInfo1 *r,
4327 const struct spoolss_DriverInfo8 *driver,
4328 const char *servername)
4330 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4331 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4336 /********************************************************************
4337 * fill a spoolss_DriverInfo2 struct
4338 ********************************************************************/
4340 static WERROR fill_printer_driver_info2(TALLOC_CTX *mem_ctx,
4341 struct spoolss_DriverInfo2 *r,
4342 const struct spoolss_DriverInfo8 *driver,
4343 const char *servername)
4346 const char *cservername = canon_servername(servername);
4348 r->version = driver->version;
4350 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4351 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4352 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4353 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4355 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4356 driver->architecture,
4358 driver->driver_path,
4361 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4362 driver->architecture,
4367 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4368 driver->architecture,
4370 driver->config_file,
4376 /********************************************************************
4377 * fill a spoolss_DriverInfo3 struct
4378 ********************************************************************/
4380 static WERROR fill_printer_driver_info3(TALLOC_CTX *mem_ctx,
4381 struct spoolss_DriverInfo3 *r,
4382 const struct spoolss_DriverInfo8 *driver,
4383 const char *servername)
4385 const char *cservername = canon_servername(servername);
4387 r->version = driver->version;
4389 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4390 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4391 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4392 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4394 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4395 driver->architecture,
4397 driver->driver_path,
4400 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4401 driver->architecture,
4406 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4407 driver->architecture,
4409 driver->config_file,
4412 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4413 driver->architecture,
4418 FILL_DRIVER_STRING(mem_ctx,
4419 driver->monitor_name,
4422 FILL_DRIVER_STRING(mem_ctx,
4423 driver->default_datatype,
4424 r->default_datatype);
4426 return string_array_from_driver_info(mem_ctx,
4427 driver->dependent_files,
4428 &r->dependent_files,
4430 driver->architecture,
4434 /********************************************************************
4435 * fill a spoolss_DriverInfo4 struct
4436 ********************************************************************/
4438 static WERROR fill_printer_driver_info4(TALLOC_CTX *mem_ctx,
4439 struct spoolss_DriverInfo4 *r,
4440 const struct spoolss_DriverInfo8 *driver,
4441 const char *servername)
4443 const char *cservername = canon_servername(servername);
4446 r->version = driver->version;
4448 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4449 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4450 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4451 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4453 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4454 driver->architecture,
4456 driver->driver_path,
4459 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4460 driver->architecture,
4465 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4466 driver->architecture,
4468 driver->config_file,
4471 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4472 driver->architecture,
4477 result = string_array_from_driver_info(mem_ctx,
4478 driver->dependent_files,
4479 &r->dependent_files,
4481 driver->architecture,
4483 if (!W_ERROR_IS_OK(result)) {
4487 FILL_DRIVER_STRING(mem_ctx,
4488 driver->monitor_name,
4491 FILL_DRIVER_STRING(mem_ctx,
4492 driver->default_datatype,
4493 r->default_datatype);
4496 result = string_array_from_driver_info(mem_ctx,
4497 driver->previous_names,
4504 /********************************************************************
4505 * fill a spoolss_DriverInfo5 struct
4506 ********************************************************************/
4508 static WERROR fill_printer_driver_info5(TALLOC_CTX *mem_ctx,
4509 struct spoolss_DriverInfo5 *r,
4510 const struct spoolss_DriverInfo8 *driver,
4511 const char *servername)
4513 const char *cservername = canon_servername(servername);
4515 r->version = driver->version;
4517 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4518 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4519 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4520 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4522 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4523 driver->architecture,
4525 driver->driver_path,
4528 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4529 driver->architecture,
4534 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4535 driver->architecture,
4537 driver->config_file,
4540 r->driver_attributes = 0;
4541 r->config_version = 0;
4542 r->driver_version = 0;
4546 /********************************************************************
4547 * fill a spoolss_DriverInfo6 struct
4548 ********************************************************************/
4550 static WERROR fill_printer_driver_info6(TALLOC_CTX *mem_ctx,
4551 struct spoolss_DriverInfo6 *r,
4552 const struct spoolss_DriverInfo8 *driver,
4553 const char *servername)
4555 const char *cservername = canon_servername(servername);
4558 r->version = driver->version;
4560 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4561 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4562 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4563 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4565 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4566 driver->architecture,
4568 driver->driver_path,
4571 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4572 driver->architecture,
4577 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4578 driver->architecture,
4580 driver->config_file,
4583 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4584 driver->architecture,
4589 FILL_DRIVER_STRING(mem_ctx,
4590 driver->monitor_name,
4593 FILL_DRIVER_STRING(mem_ctx,
4594 driver->default_datatype,
4595 r->default_datatype);
4597 result = string_array_from_driver_info(mem_ctx,
4598 driver->dependent_files,
4599 &r->dependent_files,
4601 driver->architecture,
4603 if (!W_ERROR_IS_OK(result)) {
4607 result = string_array_from_driver_info(mem_ctx,
4608 driver->previous_names,
4611 if (!W_ERROR_IS_OK(result)) {
4615 r->driver_date = driver->driver_date;
4616 r->driver_version = driver->driver_version;
4618 FILL_DRIVER_STRING(mem_ctx,
4619 driver->manufacturer_name,
4620 r->manufacturer_name);
4621 FILL_DRIVER_STRING(mem_ctx,
4622 driver->manufacturer_url,
4623 r->manufacturer_url);
4624 FILL_DRIVER_STRING(mem_ctx,
4625 driver->hardware_id,
4627 FILL_DRIVER_STRING(mem_ctx,
4634 /********************************************************************
4635 * fill a spoolss_DriverInfo8 struct
4636 ********************************************************************/
4638 static WERROR fill_printer_driver_info8(TALLOC_CTX *mem_ctx,
4639 struct spoolss_DriverInfo8 *r,
4640 const struct spoolss_DriverInfo8 *driver,
4641 const char *servername)
4643 const char *cservername = canon_servername(servername);
4646 r->version = driver->version;
4648 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4649 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4650 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4651 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4653 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4654 driver->architecture,
4656 driver->driver_path,
4659 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4660 driver->architecture,
4665 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4666 driver->architecture,
4668 driver->config_file,
4671 FILL_DRIVER_UNC_STRING(mem_ctx, cservername,
4672 driver->architecture,
4677 FILL_DRIVER_STRING(mem_ctx,
4678 driver->monitor_name,
4681 FILL_DRIVER_STRING(mem_ctx,
4682 driver->default_datatype,
4683 r->default_datatype);
4685 result = string_array_from_driver_info(mem_ctx,
4686 driver->dependent_files,
4687 &r->dependent_files,
4689 driver->architecture,
4691 if (!W_ERROR_IS_OK(result)) {
4695 result = string_array_from_driver_info(mem_ctx,
4696 driver->previous_names,
4699 if (!W_ERROR_IS_OK(result)) {
4703 r->driver_date = driver->driver_date;
4704 r->driver_version = driver->driver_version;
4706 FILL_DRIVER_STRING(mem_ctx,
4707 driver->manufacturer_name,
4708 r->manufacturer_name);
4709 FILL_DRIVER_STRING(mem_ctx,
4710 driver->manufacturer_url,
4711 r->manufacturer_url);
4712 FILL_DRIVER_STRING(mem_ctx,
4713 driver->hardware_id,
4715 FILL_DRIVER_STRING(mem_ctx,
4719 FILL_DRIVER_STRING(mem_ctx,
4720 driver->print_processor,
4721 r->print_processor);
4722 FILL_DRIVER_STRING(mem_ctx,
4723 driver->vendor_setup,
4726 result = string_array_from_driver_info(mem_ctx,
4727 driver->color_profiles,
4730 if (!W_ERROR_IS_OK(result)) {
4734 FILL_DRIVER_STRING(mem_ctx,
4738 r->printer_driver_attributes = driver->printer_driver_attributes;
4740 result = string_array_from_driver_info(mem_ctx,
4741 driver->core_driver_dependencies,
4742 &r->core_driver_dependencies,
4744 if (!W_ERROR_IS_OK(result)) {
4748 r->min_inbox_driver_ver_date = driver->min_inbox_driver_ver_date;
4749 r->min_inbox_driver_ver_version = driver->min_inbox_driver_ver_version;
4754 #if 0 /* disabled until marshalling issues are resolved - gd */
4755 /********************************************************************
4756 ********************************************************************/
4758 static WERROR fill_spoolss_DriverFileInfo(TALLOC_CTX *mem_ctx,
4759 struct spoolss_DriverFileInfo *r,
4760 const char *cservername,
4761 const char *file_name,
4762 enum spoolss_DriverFileType file_type,
4763 uint32_t file_version)
4765 r->file_name = talloc_asprintf(mem_ctx, "\\\\%s%s",
4766 cservername, file_name);
4767 W_ERROR_HAVE_NO_MEMORY(r->file_name);
4768 r->file_type = file_type;
4769 r->file_version = file_version;
4774 /********************************************************************
4775 ********************************************************************/
4777 static WERROR spoolss_DriverFileInfo_from_driver(TALLOC_CTX *mem_ctx,
4778 const struct spoolss_DriverInfo8 *driver,
4779 const char *cservername,
4780 struct spoolss_DriverFileInfo **info_p,
4783 struct spoolss_DriverFileInfo *info = NULL;
4791 if (strlen(driver->driver_path)) {
4792 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4793 struct spoolss_DriverFileInfo,
4795 W_ERROR_HAVE_NO_MEMORY(info);
4796 result = fill_spoolss_DriverFileInfo(info,
4799 driver->driver_path,
4800 SPOOLSS_DRIVER_FILE_TYPE_RENDERING,
4802 W_ERROR_NOT_OK_RETURN(result);
4806 if (strlen(driver->config_file)) {
4807 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4808 struct spoolss_DriverFileInfo,
4810 W_ERROR_HAVE_NO_MEMORY(info);
4811 result = fill_spoolss_DriverFileInfo(info,
4814 driver->config_file,
4815 SPOOLSS_DRIVER_FILE_TYPE_CONFIGURATION,
4817 W_ERROR_NOT_OK_RETURN(result);
4821 if (strlen(driver->data_file)) {
4822 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4823 struct spoolss_DriverFileInfo,
4825 W_ERROR_HAVE_NO_MEMORY(info);
4826 result = fill_spoolss_DriverFileInfo(info,
4830 SPOOLSS_DRIVER_FILE_TYPE_DATA,
4832 W_ERROR_NOT_OK_RETURN(result);
4836 if (strlen(driver->help_file)) {
4837 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4838 struct spoolss_DriverFileInfo,
4840 W_ERROR_HAVE_NO_MEMORY(info);
4841 result = fill_spoolss_DriverFileInfo(info,
4845 SPOOLSS_DRIVER_FILE_TYPE_HELP,
4847 W_ERROR_NOT_OK_RETURN(result);
4851 for (i=0; driver->dependent_files[i] && driver->dependent_files[i][0] != '\0'; i++) {
4852 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
4853 struct spoolss_DriverFileInfo,
4855 W_ERROR_HAVE_NO_MEMORY(info);
4856 result = fill_spoolss_DriverFileInfo(info,
4859 driver->dependent_files[i],
4860 SPOOLSS_DRIVER_FILE_TYPE_OTHER,
4862 W_ERROR_NOT_OK_RETURN(result);
4872 /********************************************************************
4873 * fill a spoolss_DriverInfo101 struct
4874 ********************************************************************/
4876 static WERROR fill_printer_driver_info101(TALLOC_CTX *mem_ctx,
4877 struct spoolss_DriverInfo101 *r,
4878 const struct spoolss_DriverInfo8 *driver,
4879 const char *servername)
4881 const char *cservername = canon_servername(servername);
4884 r->version = driver->version;
4886 r->driver_name = talloc_strdup(mem_ctx, driver->driver_name);
4887 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
4888 r->architecture = talloc_strdup(mem_ctx, driver->architecture);
4889 W_ERROR_HAVE_NO_MEMORY(r->architecture);
4891 result = spoolss_DriverFileInfo_from_driver(mem_ctx, driver,
4895 if (!W_ERROR_IS_OK(result)) {
4899 FILL_DRIVER_STRING(mem_ctx,
4900 driver->monitor_name,
4903 FILL_DRIVER_STRING(mem_ctx,
4904 driver->default_datatype,
4905 r->default_datatype);
4907 result = string_array_from_driver_info(mem_ctx,
4908 driver->previous_names,
4911 if (!W_ERROR_IS_OK(result)) {
4915 r->driver_date = driver->driver_date;
4916 r->driver_version = driver->driver_version;
4918 FILL_DRIVER_STRING(mem_ctx,
4919 driver->manufacturer_name,
4920 r->manufacturer_name);
4921 FILL_DRIVER_STRING(mem_ctx,
4922 driver->manufacturer_url,
4923 r->manufacturer_url);
4924 FILL_DRIVER_STRING(mem_ctx,
4925 driver->hardware_id,
4927 FILL_DRIVER_STRING(mem_ctx,
4934 /********************************************************************
4935 ********************************************************************/
4937 static WERROR construct_printer_driver_info_level(TALLOC_CTX *mem_ctx,
4938 struct auth_serversupplied_info *server_info,
4940 union spoolss_DriverInfo *r,
4942 const char *servername,
4943 const char *architecture,
4946 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
4947 struct spoolss_DriverInfo8 *driver;
4950 result = winreg_get_printer(mem_ctx,
4953 lp_const_servicename(snum),
4956 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4957 win_errstr(result)));
4959 if (!W_ERROR_IS_OK(result)) {
4960 return WERR_INVALID_PRINTER_NAME;
4963 result = winreg_get_driver(mem_ctx, server_info, architecture,
4964 pinfo2->drivername, version, &driver);
4966 DEBUG(8,("construct_printer_driver_info_level: status: %s\n",
4967 win_errstr(result)));
4969 if (!W_ERROR_IS_OK(result)) {
4971 * Is this a W2k client ?
4975 talloc_free(pinfo2);
4976 return WERR_UNKNOWN_PRINTER_DRIVER;
4979 /* Yes - try again with a WinNT driver. */
4981 result = winreg_get_driver(mem_ctx, server_info, architecture,
4984 DEBUG(8,("construct_printer_driver_level: status: %s\n",
4985 win_errstr(result)));
4986 if (!W_ERROR_IS_OK(result)) {
4987 talloc_free(pinfo2);
4988 return WERR_UNKNOWN_PRINTER_DRIVER;
4994 result = fill_printer_driver_info1(mem_ctx, &r->info1, driver, servername);
4997 result = fill_printer_driver_info2(mem_ctx, &r->info2, driver, servername);
5000 result = fill_printer_driver_info3(mem_ctx, &r->info3, driver, servername);
5003 result = fill_printer_driver_info4(mem_ctx, &r->info4, driver, servername);
5006 result = fill_printer_driver_info5(mem_ctx, &r->info5, driver, servername);
5009 result = fill_printer_driver_info6(mem_ctx, &r->info6, driver, servername);
5012 result = fill_printer_driver_info8(mem_ctx, &r->info8, driver, servername);
5014 #if 0 /* disabled until marshalling issues are resolved - gd */
5016 result = fill_printer_driver_info101(mem_ctx, &r->info101, driver, servername);
5020 result = WERR_UNKNOWN_LEVEL;
5024 talloc_free(pinfo2);
5025 talloc_free(driver);
5030 /****************************************************************
5031 _spoolss_GetPrinterDriver2
5032 ****************************************************************/
5034 WERROR _spoolss_GetPrinterDriver2(struct pipes_struct *p,
5035 struct spoolss_GetPrinterDriver2 *r)
5037 Printer_entry *printer;
5042 /* that's an [in out] buffer */
5044 if (!r->in.buffer && (r->in.offered != 0)) {
5045 return WERR_INVALID_PARAM;
5048 DEBUG(4,("_spoolss_GetPrinterDriver2\n"));
5050 if (!(printer = find_printer_index_by_hnd(p, r->in.handle))) {
5051 DEBUG(0,("_spoolss_GetPrinterDriver2: invalid printer handle!\n"));
5052 return WERR_INVALID_PRINTER_NAME;
5056 *r->out.server_major_version = 0;
5057 *r->out.server_minor_version = 0;
5059 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5063 result = construct_printer_driver_info_level(p->mem_ctx, p->server_info,
5064 r->in.level, r->out.info,
5065 snum, printer->servername,
5067 r->in.client_major_version);
5068 if (!W_ERROR_IS_OK(result)) {
5069 TALLOC_FREE(r->out.info);
5073 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverInfo,
5074 r->out.info, r->in.level);
5075 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
5077 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
5081 /****************************************************************
5082 _spoolss_StartPagePrinter
5083 ****************************************************************/
5085 WERROR _spoolss_StartPagePrinter(struct pipes_struct *p,
5086 struct spoolss_StartPagePrinter *r)
5088 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5091 DEBUG(3,("_spoolss_StartPagePrinter: "
5092 "Error in startpageprinter printer handle\n"));
5096 Printer->page_started = true;
5100 /****************************************************************
5101 _spoolss_EndPagePrinter
5102 ****************************************************************/
5104 WERROR _spoolss_EndPagePrinter(struct pipes_struct *p,
5105 struct spoolss_EndPagePrinter *r)
5109 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5112 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5113 OUR_HANDLE(r->in.handle)));
5117 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5120 Printer->page_started = false;
5121 print_job_endpage(snum, Printer->jobid);
5126 /****************************************************************
5127 _spoolss_StartDocPrinter
5128 ****************************************************************/
5130 WERROR _spoolss_StartDocPrinter(struct pipes_struct *p,
5131 struct spoolss_StartDocPrinter *r)
5133 struct spoolss_DocumentInfo1 *info_1;
5135 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5139 DEBUG(2,("_spoolss_StartDocPrinter: "
5140 "Invalid handle (%s:%u:%u)\n",
5141 OUR_HANDLE(r->in.handle)));
5145 if (Printer->jobid) {
5146 DEBUG(2, ("_spoolss_StartDocPrinter: "
5147 "StartDocPrinter called twice! "
5148 "(existing jobid = %d)\n", Printer->jobid));
5149 return WERR_INVALID_HANDLE;
5152 if (r->in.level != 1) {
5153 return WERR_UNKNOWN_LEVEL;
5156 info_1 = r->in.info.info1;
5159 * a nice thing with NT is it doesn't listen to what you tell it.
5160 * when asked to send _only_ RAW datas, it tries to send datas
5163 * So I add checks like in NT Server ...
5166 if (info_1->datatype) {
5167 if (strcmp(info_1->datatype, "RAW") != 0) {
5169 return WERR_INVALID_DATATYPE;
5173 /* get the share number of the printer */
5174 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5178 werr = print_job_start(p->server_info, snum,
5179 info_1->document_name, info_1->output_file,
5180 Printer->devmode, &Printer->jobid);
5182 /* An error occured in print_job_start() so return an appropriate
5185 if (!W_ERROR_IS_OK(werr)) {
5189 Printer->document_started = true;
5190 *r->out.job_id = Printer->jobid;
5195 /****************************************************************
5196 _spoolss_EndDocPrinter
5197 ****************************************************************/
5199 WERROR _spoolss_EndDocPrinter(struct pipes_struct *p,
5200 struct spoolss_EndDocPrinter *r)
5202 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5207 DEBUG(2,("_spoolss_EndDocPrinter: Invalid handle (%s:%u:%u)\n",
5208 OUR_HANDLE(r->in.handle)));
5212 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
5216 Printer->document_started = false;
5217 status = print_job_end(snum, Printer->jobid, NORMAL_CLOSE);
5218 if (!NT_STATUS_IS_OK(status)) {
5219 DEBUG(2, ("_spoolss_EndDocPrinter: "
5220 "print_job_end failed [%s]\n",
5221 nt_errstr(status)));
5225 return ntstatus_to_werror(status);
5228 /****************************************************************
5229 _spoolss_WritePrinter
5230 ****************************************************************/
5232 WERROR _spoolss_WritePrinter(struct pipes_struct *p,
5233 struct spoolss_WritePrinter *r)
5235 ssize_t buffer_written;
5237 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5240 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5241 OUR_HANDLE(r->in.handle)));
5242 *r->out.num_written = r->in._data_size;
5246 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5249 /* print_job_write takes care of checking for PJOB_SMBD_SPOOLING */
5250 buffer_written = print_job_write(snum, Printer->jobid,
5251 (const char *)r->in.data.data,
5253 (size_t)r->in._data_size);
5254 if (buffer_written == (ssize_t)-1) {
5255 *r->out.num_written = 0;
5256 if (errno == ENOSPC)
5257 return WERR_NO_SPOOL_SPACE;
5259 return WERR_ACCESS_DENIED;
5262 *r->out.num_written = r->in._data_size;
5267 /********************************************************************
5268 * api_spoolss_getprinter
5269 * called from the spoolss dispatcher
5271 ********************************************************************/
5273 static WERROR control_printer(struct policy_handle *handle, uint32_t command,
5274 struct pipes_struct *p)
5277 WERROR errcode = WERR_BADFUNC;
5278 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5281 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n",
5282 OUR_HANDLE(handle)));
5286 if (!get_printer_snum(p, handle, &snum, NULL))
5290 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5291 errcode = print_queue_pause(p->server_info, snum);
5293 case SPOOLSS_PRINTER_CONTROL_RESUME:
5294 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5295 errcode = print_queue_resume(p->server_info, snum);
5297 case SPOOLSS_PRINTER_CONTROL_PURGE:
5298 errcode = print_queue_purge(p->server_info, snum);
5301 return WERR_UNKNOWN_LEVEL;
5308 /****************************************************************
5309 _spoolss_AbortPrinter
5310 * From MSDN: "Deletes printer's spool file if printer is configured
5312 ****************************************************************/
5314 WERROR _spoolss_AbortPrinter(struct pipes_struct *p,
5315 struct spoolss_AbortPrinter *r)
5317 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
5319 WERROR errcode = WERR_OK;
5322 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5323 OUR_HANDLE(r->in.handle)));
5327 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
5330 if (!Printer->document_started) {
5331 return WERR_SPL_NO_STARTDOC;
5334 errcode = print_job_delete(p->server_info, snum, Printer->jobid);
5339 /********************************************************************
5340 * called by spoolss_api_setprinter
5341 * when updating a printer description
5342 ********************************************************************/
5344 static WERROR update_printer_sec(struct policy_handle *handle,
5345 struct pipes_struct *p,
5346 struct sec_desc_buf *secdesc_ctr)
5348 struct spoolss_security_descriptor *new_secdesc = NULL;
5349 struct spoolss_security_descriptor *old_secdesc = NULL;
5350 const char *printer;
5354 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5356 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5357 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5358 OUR_HANDLE(handle)));
5360 result = WERR_BADFID;
5364 if (secdesc_ctr == NULL) {
5365 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5366 result = WERR_INVALID_PARAM;
5369 printer = lp_const_servicename(snum);
5371 /* Check the user has permissions to change the security
5372 descriptor. By experimentation with two NT machines, the user
5373 requires Full Access to the printer to change security
5376 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5377 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5378 result = WERR_ACCESS_DENIED;
5382 /* NT seems to like setting the security descriptor even though
5383 nothing may have actually changed. */
5384 result = winreg_get_printer_secdesc(p->mem_ctx,
5388 if (!W_ERROR_IS_OK(result)) {
5389 DEBUG(2,("update_printer_sec: winreg_get_printer_secdesc() failed\n"));
5390 result = WERR_BADFID;
5394 if (DEBUGLEVEL >= 10) {
5395 struct security_acl *the_acl;
5398 the_acl = old_secdesc->dacl;
5399 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
5400 printer, the_acl->num_aces));
5402 for (i = 0; i < the_acl->num_aces; i++) {
5403 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5404 &the_acl->aces[i].trustee),
5405 the_acl->aces[i].access_mask));
5408 the_acl = secdesc_ctr->sd->dacl;
5411 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
5412 printer, the_acl->num_aces));
5414 for (i = 0; i < the_acl->num_aces; i++) {
5415 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
5416 &the_acl->aces[i].trustee),
5417 the_acl->aces[i].access_mask));
5420 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
5424 new_secdesc = sec_desc_merge(p->mem_ctx, secdesc_ctr->sd, old_secdesc);
5425 if (new_secdesc == NULL) {
5426 result = WERR_NOMEM;
5430 if (security_descriptor_equal(new_secdesc, old_secdesc)) {
5435 result = winreg_set_printer_secdesc(p->mem_ctx,
5444 /********************************************************************
5445 Canonicalize printer info from a client
5446 ********************************************************************/
5448 static bool check_printer_ok(TALLOC_CTX *mem_ctx,
5449 struct spoolss_SetPrinterInfo2 *info2,
5452 fstring printername;
5455 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
5456 "portname=%s drivername=%s comment=%s location=%s\n",
5457 info2->servername, info2->printername, info2->sharename,
5458 info2->portname, info2->drivername, info2->comment,
5461 /* we force some elements to "correct" values */
5462 info2->servername = talloc_asprintf(mem_ctx, "\\\\%s", global_myname());
5463 if (info2->servername == NULL) {
5466 info2->sharename = talloc_strdup(mem_ctx, lp_const_servicename(snum));
5467 if (info2->sharename == NULL) {
5471 /* check to see if we allow printername != sharename */
5472 if (lp_force_printername(snum)) {
5473 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5474 global_myname(), info2->sharename);
5476 /* make sure printername is in \\server\printername format */
5477 fstrcpy(printername, info2->printername);
5479 if ( printername[0] == '\\' && printername[1] == '\\' ) {
5480 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
5484 info2->printername = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5485 global_myname(), p);
5487 if (info2->printername == NULL) {
5491 info2->attributes |= PRINTER_ATTRIBUTE_SAMBA;
5492 info2->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
5497 /****************************************************************************
5498 ****************************************************************************/
5500 static WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri)
5502 char *cmd = lp_addport_cmd();
5503 char *command = NULL;
5505 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5506 bool is_print_op = false;
5509 return WERR_ACCESS_DENIED;
5512 command = talloc_asprintf(ctx,
5513 "%s \"%s\" \"%s\"", cmd, portname, uri );
5519 is_print_op = user_has_privileges( token, &se_printop );
5521 DEBUG(10,("Running [%s]\n", command));
5523 /********* BEGIN SePrintOperatorPrivilege **********/
5528 ret = smbrun(command, NULL);
5533 /********* END SePrintOperatorPrivilege **********/
5535 DEBUGADD(10,("returned [%d]\n", ret));
5537 TALLOC_FREE(command);
5540 return WERR_ACCESS_DENIED;
5546 /****************************************************************************
5547 ****************************************************************************/
5549 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token,
5550 struct spoolss_SetPrinterInfo2 *info2,
5551 const char *remote_machine)
5553 char *cmd = lp_addprinter_cmd();
5555 char *command = NULL;
5559 SE_PRIV se_printop = SE_PRINT_OPERATOR;
5560 bool is_print_op = false;
5562 if (!remote_machine) {
5566 command = talloc_asprintf(ctx,
5567 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
5568 cmd, info2->printername, info2->sharename,
5569 info2->portname, info2->drivername,
5570 info2->location, info2->comment, remote_machine);
5576 is_print_op = user_has_privileges( token, &se_printop );
5578 DEBUG(10,("Running [%s]\n", command));
5580 /********* BEGIN SePrintOperatorPrivilege **********/
5585 if ( (ret = smbrun(command, &fd)) == 0 ) {
5586 /* Tell everyone we updated smb.conf. */
5587 message_send_all(smbd_messaging_context(),
5588 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
5594 /********* END SePrintOperatorPrivilege **********/
5596 DEBUGADD(10,("returned [%d]\n", ret));
5598 TALLOC_FREE(command);
5606 /* reload our services immediately */
5608 reload_services(false);
5612 /* Get lines and convert them back to dos-codepage */
5613 qlines = fd_lines_load(fd, &numlines, 0, NULL);
5614 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
5617 /* Set the portname to what the script says the portname should be. */
5618 /* but don't require anything to be return from the script exit a good error code */
5621 /* Set the portname to what the script says the portname should be. */
5622 info2->portname = talloc_strdup(ctx, qlines[0]);
5623 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
5626 TALLOC_FREE(qlines);
5630 static WERROR update_dsspooler(TALLOC_CTX *mem_ctx,
5631 struct auth_serversupplied_info *server_info,
5633 struct spoolss_SetPrinterInfo2 *printer,
5634 struct spoolss_PrinterInfo2 *old_printer)
5636 bool force_update = (old_printer == NULL);
5637 const char *dnsdomname;
5638 const char *longname;
5639 const char *uncname;
5640 const char *spooling;
5642 WERROR result = WERR_OK;
5644 if (force_update || !strequal(printer->drivername, old_printer->drivername)) {
5645 push_reg_sz(mem_ctx, &buffer, printer->drivername);
5646 winreg_set_printer_dataex(mem_ctx,
5649 SPOOL_DSSPOOLER_KEY,
5650 SPOOL_REG_DRIVERNAME,
5655 if (!force_update) {
5656 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
5657 printer->drivername));
5659 notify_printer_driver(snum, printer->drivername);
5663 if (force_update || !strequal(printer->comment, old_printer->comment)) {
5664 push_reg_sz(mem_ctx, &buffer, printer->comment);
5665 winreg_set_printer_dataex(mem_ctx,
5668 SPOOL_DSSPOOLER_KEY,
5669 SPOOL_REG_DESCRIPTION,
5674 if (!force_update) {
5675 notify_printer_comment(snum, printer->comment);
5679 if (force_update || !strequal(printer->sharename, old_printer->sharename)) {
5680 push_reg_sz(mem_ctx, &buffer, printer->sharename);
5681 winreg_set_printer_dataex(mem_ctx,
5684 SPOOL_DSSPOOLER_KEY,
5685 SPOOL_REG_PRINTSHARENAME,
5690 if (!force_update) {
5691 notify_printer_sharename(snum, printer->sharename);
5695 if (force_update || !strequal(printer->printername, old_printer->printername)) {
5698 p = strrchr(printer->printername, '\\' );
5702 p = printer->printername;
5705 push_reg_sz(mem_ctx, &buffer, p);
5706 winreg_set_printer_dataex(mem_ctx,
5709 SPOOL_DSSPOOLER_KEY,
5710 SPOOL_REG_PRINTERNAME,
5715 if (!force_update) {
5716 notify_printer_printername(snum, p);
5720 if (force_update || !strequal(printer->portname, old_printer->portname)) {
5721 push_reg_sz(mem_ctx, &buffer, printer->portname);
5722 winreg_set_printer_dataex(mem_ctx,
5725 SPOOL_DSSPOOLER_KEY,
5731 if (!force_update) {
5732 notify_printer_port(snum, printer->portname);
5736 if (force_update || !strequal(printer->location, old_printer->location)) {
5737 push_reg_sz(mem_ctx, &buffer, printer->location);
5738 winreg_set_printer_dataex(mem_ctx,
5741 SPOOL_DSSPOOLER_KEY,
5747 if (!force_update) {
5748 notify_printer_location(snum, printer->location);
5752 if (force_update || !strequal(printer->sepfile, old_printer->sepfile)) {
5753 push_reg_sz(mem_ctx, &buffer, printer->sepfile);
5754 winreg_set_printer_dataex(mem_ctx,
5757 SPOOL_DSSPOOLER_KEY,
5758 SPOOL_REG_PRINTSEPARATORFILE,
5763 if (!force_update) {
5764 notify_printer_location(snum, printer->location);
5768 if (force_update || printer->starttime != old_printer->starttime) {
5769 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5770 SIVAL(buffer.data, 0, printer->starttime);
5771 winreg_set_printer_dataex(mem_ctx,
5774 SPOOL_DSSPOOLER_KEY,
5775 SPOOL_REG_PRINTSTARTTIME,
5781 if (force_update || printer->untiltime != old_printer->untiltime) {
5782 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5783 SIVAL(buffer.data, 0, printer->untiltime);
5784 winreg_set_printer_dataex(mem_ctx,
5787 SPOOL_DSSPOOLER_KEY,
5788 SPOOL_REG_PRINTENDTIME,
5794 if (force_update || printer->priority != old_printer->priority) {
5795 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5796 SIVAL(buffer.data, 0, printer->priority);
5797 winreg_set_printer_dataex(mem_ctx,
5800 SPOOL_DSSPOOLER_KEY,
5807 if (force_update || printer->attributes != old_printer->attributes) {
5808 buffer = data_blob_talloc(mem_ctx, NULL, 4);
5809 SIVAL(buffer.data, 0, (printer->attributes &
5810 PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
5811 winreg_set_printer_dataex(mem_ctx,
5814 SPOOL_DSSPOOLER_KEY,
5815 SPOOL_REG_PRINTKEEPPRINTEDJOBS,
5820 switch (printer->attributes & 0x3) {
5822 spooling = SPOOL_REGVAL_PRINTWHILESPOOLING;
5825 spooling = SPOOL_REGVAL_PRINTAFTERSPOOLED;
5828 spooling = SPOOL_REGVAL_PRINTDIRECT;
5831 spooling = "unknown";
5833 push_reg_sz(mem_ctx, &buffer, spooling);
5834 winreg_set_printer_dataex(mem_ctx,
5837 SPOOL_DSSPOOLER_KEY,
5838 SPOOL_REG_PRINTSPOOLING,
5844 push_reg_sz(mem_ctx, &buffer, global_myname());
5845 winreg_set_printer_dataex(mem_ctx,
5848 SPOOL_DSSPOOLER_KEY,
5849 SPOOL_REG_SHORTSERVERNAME,
5854 dnsdomname = get_mydnsfullname();
5855 if (dnsdomname != NULL && dnsdomname[0] != '\0') {
5856 longname = talloc_strdup(mem_ctx, dnsdomname);
5858 longname = talloc_strdup(mem_ctx, global_myname());
5860 if (longname == NULL) {
5861 result = WERR_NOMEM;
5865 push_reg_sz(mem_ctx, &buffer, longname);
5866 winreg_set_printer_dataex(mem_ctx,
5869 SPOOL_DSSPOOLER_KEY,
5870 SPOOL_REG_SERVERNAME,
5875 uncname = talloc_asprintf(mem_ctx, "\\\\%s\\%s",
5876 global_myname(), printer->sharename);
5877 push_reg_sz(mem_ctx, &buffer, uncname);
5878 winreg_set_printer_dataex(mem_ctx,
5881 SPOOL_DSSPOOLER_KEY,
5891 /********************************************************************
5892 * Called by spoolss_api_setprinter
5893 * when updating a printer description.
5894 ********************************************************************/
5896 static WERROR update_printer(struct pipes_struct *p,
5897 struct policy_handle *handle,
5898 struct spoolss_SetPrinterInfoCtr *info_ctr,
5899 struct spoolss_DeviceMode *devmode)
5901 uint32_t printer_mask = SPOOLSS_PRINTER_INFO_ALL;
5902 struct spoolss_SetPrinterInfo2 *printer = info_ctr->info.info2;
5903 struct spoolss_PrinterInfo2 *old_printer;
5904 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5905 const char *servername = NULL;
5907 WERROR result = WERR_OK;
5908 TALLOC_CTX *tmp_ctx;
5910 DEBUG(8,("update_printer\n"));
5912 tmp_ctx = talloc_new(p->mem_ctx);
5913 if (tmp_ctx == NULL) {
5918 result = WERR_BADFID;
5922 if (!get_printer_snum(p, handle, &snum, NULL)) {
5923 result = WERR_BADFID;
5927 if (Printer != NULL || Printer->servername != NULL) {
5928 servername = Printer->servername;
5931 result = winreg_get_printer(tmp_ctx,
5934 lp_const_servicename(snum),
5936 if (!W_ERROR_IS_OK(result)) {
5937 result = WERR_BADFID;
5941 /* Do sanity check on the requested changes for Samba */
5942 if (!check_printer_ok(tmp_ctx, printer, snum)) {
5943 result = WERR_INVALID_PARAM;
5947 /* FIXME!!! If the driver has changed we really should verify that
5948 it is installed before doing much else --jerry */
5950 /* Check calling user has permission to update printer description */
5951 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
5952 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
5953 result = WERR_ACCESS_DENIED;
5957 /* Call addprinter hook */
5958 /* Check changes to see if this is really needed */
5960 if (*lp_addprinter_cmd() &&
5961 (!strequal(printer->drivername, old_printer->drivername) ||
5962 !strequal(printer->comment, old_printer->comment) ||
5963 !strequal(printer->portname, old_printer->portname) ||
5964 !strequal(printer->location, old_printer->location)) )
5966 /* add_printer_hook() will call reload_services() */
5967 if (!add_printer_hook(tmp_ctx, p->server_info->ptok,
5968 printer, p->client_address) ) {
5969 result = WERR_ACCESS_DENIED;
5974 update_dsspooler(tmp_ctx,
5980 printer_mask &= ~SPOOLSS_PRINTER_INFO_SECDESC;
5982 if (devmode == NULL) {
5983 printer_mask &= ~SPOOLSS_PRINTER_INFO_DEVMODE;
5985 result = winreg_update_printer(tmp_ctx,
5994 talloc_free(tmp_ctx);
5999 /****************************************************************************
6000 ****************************************************************************/
6001 static WERROR publish_or_unpublish_printer(struct pipes_struct *p,
6002 struct policy_handle *handle,
6003 struct spoolss_SetPrinterInfo7 *info7)
6006 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6009 Printer_entry *Printer;
6011 if ( lp_security() != SEC_ADS ) {
6012 return WERR_UNKNOWN_LEVEL;
6015 Printer = find_printer_index_by_hnd(p, handle);
6017 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6022 if (!get_printer_snum(p, handle, &snum, NULL))
6025 result = winreg_get_printer(p->mem_ctx, p->server_info,
6026 Printer->servername,
6027 lp_servicename(snum), &pinfo2);
6028 if (!W_ERROR_IS_OK(result)) {
6032 nt_printer_publish(pinfo2, p->server_info, pinfo2, info7->action);
6034 TALLOC_FREE(pinfo2);
6037 return WERR_UNKNOWN_LEVEL;
6041 /********************************************************************
6042 ********************************************************************/
6044 static WERROR update_printer_devmode(struct pipes_struct *p,
6045 struct policy_handle *handle,
6046 struct spoolss_DeviceMode *devmode)
6049 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6050 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_DEVMODE;
6052 DEBUG(8,("update_printer_devmode\n"));
6058 if (!get_printer_snum(p, handle, &snum, NULL)) {
6062 /* Check calling user has permission to update printer description */
6063 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6064 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6065 return WERR_ACCESS_DENIED;
6068 return winreg_update_printer(p->mem_ctx,
6070 lp_const_servicename(snum),
6078 /****************************************************************
6080 ****************************************************************/
6082 WERROR _spoolss_SetPrinter(struct pipes_struct *p,
6083 struct spoolss_SetPrinter *r)
6087 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6090 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6091 OUR_HANDLE(r->in.handle)));
6095 /* check the level */
6096 switch (r->in.info_ctr->level) {
6098 return control_printer(r->in.handle, r->in.command, p);
6100 result = update_printer(p, r->in.handle,
6102 r->in.devmode_ctr->devmode);
6103 if (!W_ERROR_IS_OK(result))
6105 if (r->in.secdesc_ctr->sd)
6106 result = update_printer_sec(r->in.handle, p,
6110 return update_printer_sec(r->in.handle, p,
6113 return publish_or_unpublish_printer(p, r->in.handle,
6114 r->in.info_ctr->info.info7);
6116 return update_printer_devmode(p, r->in.handle,
6117 r->in.devmode_ctr->devmode);
6119 return WERR_UNKNOWN_LEVEL;
6123 /****************************************************************
6124 _spoolss_FindClosePrinterNotify
6125 ****************************************************************/
6127 WERROR _spoolss_FindClosePrinterNotify(struct pipes_struct *p,
6128 struct spoolss_FindClosePrinterNotify *r)
6130 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
6133 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6134 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(r->in.handle)));
6138 if (Printer->notify.client_connected == true) {
6141 if ( Printer->printer_type == SPLHND_SERVER)
6143 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6144 !get_printer_snum(p, r->in.handle, &snum, NULL) )
6147 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6150 Printer->notify.flags=0;
6151 Printer->notify.options=0;
6152 Printer->notify.localmachine[0]='\0';
6153 Printer->notify.printerlocal=0;
6154 TALLOC_FREE(Printer->notify.option);
6155 Printer->notify.client_connected = false;
6160 /****************************************************************
6162 ****************************************************************/
6164 WERROR _spoolss_AddJob(struct pipes_struct *p,
6165 struct spoolss_AddJob *r)
6167 if (!r->in.buffer && (r->in.offered != 0)) {
6168 return WERR_INVALID_PARAM;
6171 /* this is what a NT server returns for AddJob. AddJob must fail on
6172 * non-local printers */
6174 if (r->in.level != 1) {
6175 return WERR_UNKNOWN_LEVEL;
6178 return WERR_INVALID_PARAM;
6181 /****************************************************************************
6183 ****************************************************************************/
6185 static WERROR fill_job_info1(TALLOC_CTX *mem_ctx,
6186 struct spoolss_JobInfo1 *r,
6187 const print_queue_struct *queue,
6188 int position, int snum,
6189 struct spoolss_PrinterInfo2 *pinfo2)
6193 t = gmtime(&queue->time);
6195 r->job_id = queue->job;
6197 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6198 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6199 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6200 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6201 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6202 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6203 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6204 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6205 r->data_type = talloc_strdup(mem_ctx, "RAW");
6206 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6207 r->text_status = talloc_strdup(mem_ctx, "");
6208 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6210 r->status = nt_printj_status(queue->status);
6211 r->priority = queue->priority;
6212 r->position = position;
6213 r->total_pages = queue->page_count;
6214 r->pages_printed = 0; /* ??? */
6216 init_systemtime(&r->submitted, t);
6221 /****************************************************************************
6223 ****************************************************************************/
6225 static WERROR fill_job_info2(TALLOC_CTX *mem_ctx,
6226 struct spoolss_JobInfo2 *r,
6227 const print_queue_struct *queue,
6228 int position, int snum,
6229 struct spoolss_PrinterInfo2 *pinfo2,
6230 struct spoolss_DeviceMode *devmode)
6234 t = gmtime(&queue->time);
6236 r->job_id = queue->job;
6238 r->printer_name = talloc_strdup(mem_ctx, lp_servicename(snum));
6239 W_ERROR_HAVE_NO_MEMORY(r->printer_name);
6240 r->server_name = talloc_strdup(mem_ctx, pinfo2->servername);
6241 W_ERROR_HAVE_NO_MEMORY(r->server_name);
6242 r->user_name = talloc_strdup(mem_ctx, queue->fs_user);
6243 W_ERROR_HAVE_NO_MEMORY(r->user_name);
6244 r->document_name = talloc_strdup(mem_ctx, queue->fs_file);
6245 W_ERROR_HAVE_NO_MEMORY(r->document_name);
6246 r->notify_name = talloc_strdup(mem_ctx, queue->fs_user);
6247 W_ERROR_HAVE_NO_MEMORY(r->notify_name);
6248 r->data_type = talloc_strdup(mem_ctx, "RAW");
6249 W_ERROR_HAVE_NO_MEMORY(r->data_type);
6250 r->print_processor = talloc_strdup(mem_ctx, "winprint");
6251 W_ERROR_HAVE_NO_MEMORY(r->print_processor);
6252 r->parameters = talloc_strdup(mem_ctx, "");
6253 W_ERROR_HAVE_NO_MEMORY(r->parameters);
6254 r->driver_name = talloc_strdup(mem_ctx, pinfo2->drivername);
6255 W_ERROR_HAVE_NO_MEMORY(r->driver_name);
6257 r->devmode = devmode;
6259 r->text_status = talloc_strdup(mem_ctx, "");
6260 W_ERROR_HAVE_NO_MEMORY(r->text_status);
6264 r->status = nt_printj_status(queue->status);
6265 r->priority = queue->priority;
6266 r->position = position;
6269 r->total_pages = queue->page_count;
6270 r->size = queue->size;
6271 init_systemtime(&r->submitted, t);
6273 r->pages_printed = 0; /* ??? */
6278 /****************************************************************************
6280 ****************************************************************************/
6282 static WERROR fill_job_info3(TALLOC_CTX *mem_ctx,
6283 struct spoolss_JobInfo3 *r,
6284 const print_queue_struct *queue,
6285 const print_queue_struct *next_queue,
6286 int position, int snum,
6287 struct spoolss_PrinterInfo2 *pinfo2)
6289 r->job_id = queue->job;
6292 r->next_job_id = next_queue->job;
6299 /****************************************************************************
6300 Enumjobs at level 1.
6301 ****************************************************************************/
6303 static WERROR enumjobs_level1(TALLOC_CTX *mem_ctx,
6304 const print_queue_struct *queue,
6305 uint32_t num_queues, int snum,
6306 struct spoolss_PrinterInfo2 *pinfo2,
6307 union spoolss_JobInfo **info_p,
6310 union spoolss_JobInfo *info;
6312 WERROR result = WERR_OK;
6314 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6315 W_ERROR_HAVE_NO_MEMORY(info);
6317 *count = num_queues;
6319 for (i=0; i<*count; i++) {
6320 result = fill_job_info1(info,
6326 if (!W_ERROR_IS_OK(result)) {
6332 if (!W_ERROR_IS_OK(result)) {
6343 /****************************************************************************
6344 Enumjobs at level 2.
6345 ****************************************************************************/
6347 static WERROR enumjobs_level2(TALLOC_CTX *mem_ctx,
6348 const print_queue_struct *queue,
6349 uint32_t num_queues, int snum,
6350 struct spoolss_PrinterInfo2 *pinfo2,
6351 union spoolss_JobInfo **info_p,
6354 union spoolss_JobInfo *info;
6356 WERROR result = WERR_OK;
6358 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6359 W_ERROR_HAVE_NO_MEMORY(info);
6361 *count = num_queues;
6363 for (i=0; i<*count; i++) {
6364 struct spoolss_DeviceMode *devmode;
6366 result = spoolss_create_default_devmode(info,
6367 pinfo2->printername,
6369 if (!W_ERROR_IS_OK(result)) {
6370 DEBUG(3, ("Can't proceed w/o a devmode!"));
6374 result = fill_job_info2(info,
6381 if (!W_ERROR_IS_OK(result)) {
6387 if (!W_ERROR_IS_OK(result)) {
6398 /****************************************************************************
6399 Enumjobs at level 3.
6400 ****************************************************************************/
6402 static WERROR enumjobs_level3(TALLOC_CTX *mem_ctx,
6403 const print_queue_struct *queue,
6404 uint32_t num_queues, int snum,
6405 struct spoolss_PrinterInfo2 *pinfo2,
6406 union spoolss_JobInfo **info_p,
6409 union spoolss_JobInfo *info;
6411 WERROR result = WERR_OK;
6413 info = TALLOC_ARRAY(mem_ctx, union spoolss_JobInfo, num_queues);
6414 W_ERROR_HAVE_NO_MEMORY(info);
6416 *count = num_queues;
6418 for (i=0; i<*count; i++) {
6419 const print_queue_struct *next_queue = NULL;
6422 next_queue = &queue[i+1];
6425 result = fill_job_info3(info,
6432 if (!W_ERROR_IS_OK(result)) {
6438 if (!W_ERROR_IS_OK(result)) {
6449 /****************************************************************
6451 ****************************************************************/
6453 WERROR _spoolss_EnumJobs(struct pipes_struct *p,
6454 struct spoolss_EnumJobs *r)
6457 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
6459 print_status_struct prt_status;
6460 print_queue_struct *queue = NULL;
6463 /* that's an [in out] buffer */
6465 if (!r->in.buffer && (r->in.offered != 0)) {
6466 return WERR_INVALID_PARAM;
6469 DEBUG(4,("_spoolss_EnumJobs\n"));
6473 *r->out.info = NULL;
6475 /* lookup the printer snum and tdb entry */
6477 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6481 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
6482 lp_servicename(snum), &pinfo2);
6483 if (!W_ERROR_IS_OK(result)) {
6487 count = print_queue_status(snum, &queue, &prt_status);
6488 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n",
6489 count, prt_status.status, prt_status.message));
6493 TALLOC_FREE(pinfo2);
6497 switch (r->in.level) {
6499 result = enumjobs_level1(p->mem_ctx, queue, count, snum,
6500 pinfo2, r->out.info, r->out.count);
6503 result = enumjobs_level2(p->mem_ctx, queue, count, snum,
6504 pinfo2, r->out.info, r->out.count);
6507 result = enumjobs_level3(p->mem_ctx, queue, count, snum,
6508 pinfo2, r->out.info, r->out.count);
6511 result = WERR_UNKNOWN_LEVEL;
6516 TALLOC_FREE(pinfo2);
6518 if (!W_ERROR_IS_OK(result)) {
6522 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6524 *r->out.info, r->in.level,
6526 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6527 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6529 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6532 /****************************************************************
6533 _spoolss_ScheduleJob
6534 ****************************************************************/
6536 WERROR _spoolss_ScheduleJob(struct pipes_struct *p,
6537 struct spoolss_ScheduleJob *r)
6542 /****************************************************************
6543 ****************************************************************/
6545 static WERROR spoolss_setjob_1(TALLOC_CTX *mem_ctx,
6546 const char *printer_name,
6548 struct spoolss_SetJobInfo1 *r)
6552 if (!print_job_get_name(mem_ctx, printer_name, job_id, &old_doc_name)) {
6556 if (strequal(old_doc_name, r->document_name)) {
6560 if (!print_job_set_name(printer_name, job_id, r->document_name)) {
6567 /****************************************************************
6569 ****************************************************************/
6571 WERROR _spoolss_SetJob(struct pipes_struct *p,
6572 struct spoolss_SetJob *r)
6575 WERROR errcode = WERR_BADFUNC;
6577 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
6581 if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) {
6582 return WERR_INVALID_PRINTER_NAME;
6585 switch (r->in.command) {
6586 case SPOOLSS_JOB_CONTROL_CANCEL:
6587 case SPOOLSS_JOB_CONTROL_DELETE:
6588 errcode = print_job_delete(p->server_info,
6589 snum, r->in.job_id);
6590 if (W_ERROR_EQUAL(errcode, WERR_PRINTER_HAS_JOBS_QUEUED)) {
6594 case SPOOLSS_JOB_CONTROL_PAUSE:
6595 if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) {
6599 case SPOOLSS_JOB_CONTROL_RESTART:
6600 case SPOOLSS_JOB_CONTROL_RESUME:
6601 if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) {
6609 return WERR_UNKNOWN_LEVEL;
6612 if (!W_ERROR_IS_OK(errcode)) {
6616 if (r->in.ctr == NULL) {
6620 switch (r->in.ctr->level) {
6622 errcode = spoolss_setjob_1(p->mem_ctx, lp_const_servicename(snum),
6624 r->in.ctr->info.info1);
6630 return WERR_UNKNOWN_LEVEL;
6636 /****************************************************************************
6637 Enumerates all printer drivers by level and architecture.
6638 ****************************************************************************/
6640 static WERROR enumprinterdrivers_level_by_architecture(TALLOC_CTX *mem_ctx,
6641 struct auth_serversupplied_info *server_info,
6642 const char *servername,
6643 const char *architecture,
6645 union spoolss_DriverInfo **info_p,
6650 struct spoolss_DriverInfo8 *driver;
6651 union spoolss_DriverInfo *info = NULL;
6653 WERROR result = WERR_OK;
6654 uint32_t num_drivers;
6655 const char **drivers;
6660 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6661 result = winreg_get_driver_list(mem_ctx, server_info,
6662 architecture, version,
6663 &num_drivers, &drivers);
6664 if (!W_ERROR_IS_OK(result)) {
6667 DEBUG(4, ("we have:[%d] drivers in environment"
6668 " [%s] and version [%d]\n",
6669 num_drivers, architecture, version));
6671 if (num_drivers != 0) {
6672 info = TALLOC_REALLOC_ARRAY(mem_ctx, info,
6673 union spoolss_DriverInfo,
6674 count + num_drivers);
6676 DEBUG(0,("enumprinterdrivers_level_by_architecture: "
6677 "failed to enlarge driver info buffer!\n"));
6678 result = WERR_NOMEM;
6683 for (i = 0; i < num_drivers; i++) {
6684 DEBUG(5, ("\tdriver: [%s]\n", drivers[i]));
6686 result = winreg_get_driver(mem_ctx, server_info,
6687 architecture, drivers[i],
6689 if (!W_ERROR_IS_OK(result)) {
6695 result = fill_printer_driver_info1(info, &info[count+i].info1,
6696 driver, servername);
6699 result = fill_printer_driver_info2(info, &info[count+i].info2,
6700 driver, servername);
6703 result = fill_printer_driver_info3(info, &info[count+i].info3,
6704 driver, servername);
6707 result = fill_printer_driver_info4(info, &info[count+i].info4,
6708 driver, servername);
6711 result = fill_printer_driver_info5(info, &info[count+i].info5,
6712 driver, servername);
6715 result = fill_printer_driver_info6(info, &info[count+i].info6,
6716 driver, servername);
6719 result = fill_printer_driver_info8(info, &info[count+i].info8,
6720 driver, servername);
6723 result = WERR_UNKNOWN_LEVEL;
6727 TALLOC_FREE(driver);
6729 if (!W_ERROR_IS_OK(result)) {
6734 count += num_drivers;
6735 TALLOC_FREE(drivers);
6739 TALLOC_FREE(drivers);
6741 if (!W_ERROR_IS_OK(result)) {
6752 /****************************************************************************
6753 Enumerates all printer drivers by level.
6754 ****************************************************************************/
6756 static WERROR enumprinterdrivers_level(TALLOC_CTX *mem_ctx,
6757 struct auth_serversupplied_info *server_info,
6758 const char *servername,
6759 const char *architecture,
6761 union spoolss_DriverInfo **info_p,
6765 WERROR result = WERR_OK;
6767 if (strequal(architecture, SPOOLSS_ARCHITECTURE_ALL)) {
6769 for (a=0; archi_table[a].long_archi != NULL; a++) {
6771 union spoolss_DriverInfo *info = NULL;
6774 result = enumprinterdrivers_level_by_architecture(mem_ctx,
6777 archi_table[a].long_archi,
6781 if (!W_ERROR_IS_OK(result)) {
6785 for (i=0; i < count; i++) {
6786 ADD_TO_ARRAY(mem_ctx, union spoolss_DriverInfo,
6787 info[i], info_p, count_p);
6794 return enumprinterdrivers_level_by_architecture(mem_ctx,
6803 /****************************************************************
6804 _spoolss_EnumPrinterDrivers
6805 ****************************************************************/
6807 WERROR _spoolss_EnumPrinterDrivers(struct pipes_struct *p,
6808 struct spoolss_EnumPrinterDrivers *r)
6810 const char *cservername;
6813 /* that's an [in out] buffer */
6815 if (!r->in.buffer && (r->in.offered != 0)) {
6816 return WERR_INVALID_PARAM;
6819 DEBUG(4,("_spoolss_EnumPrinterDrivers\n"));
6823 *r->out.info = NULL;
6825 cservername = canon_servername(r->in.server);
6827 if (!is_myname_or_ipaddr(cservername)) {
6828 return WERR_UNKNOWN_PRINTER_DRIVER;
6831 result = enumprinterdrivers_level(p->mem_ctx,
6838 if (!W_ERROR_IS_OK(result)) {
6842 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6843 spoolss_EnumPrinterDrivers,
6844 *r->out.info, r->in.level,
6846 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6847 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6849 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6852 /****************************************************************
6854 ****************************************************************/
6856 WERROR _spoolss_EnumForms(struct pipes_struct *p,
6857 struct spoolss_EnumForms *r)
6863 *r->out.info = NULL;
6865 /* that's an [in out] buffer */
6867 if (!r->in.buffer && (r->in.offered != 0) ) {
6868 return WERR_INVALID_PARAM;
6871 DEBUG(4,("_spoolss_EnumForms\n"));
6872 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6873 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6875 switch (r->in.level) {
6877 result = winreg_printer_enumforms1(p->mem_ctx,
6883 result = WERR_UNKNOWN_LEVEL;
6887 if (!W_ERROR_IS_OK(result)) {
6891 if (*r->out.count == 0) {
6892 return WERR_NO_MORE_ITEMS;
6895 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
6897 *r->out.info, r->in.level,
6899 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
6900 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
6902 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6905 /****************************************************************
6907 ****************************************************************/
6909 WERROR _spoolss_GetForm(struct pipes_struct *p,
6910 struct spoolss_GetForm *r)
6914 /* that's an [in out] buffer */
6916 if (!r->in.buffer && (r->in.offered != 0)) {
6917 return WERR_INVALID_PARAM;
6920 DEBUG(4,("_spoolss_GetForm\n"));
6921 DEBUGADD(5,("Offered buffer size [%d]\n", r->in.offered));
6922 DEBUGADD(5,("Info level [%d]\n", r->in.level));
6924 switch (r->in.level) {
6926 result = winreg_printer_getform1(p->mem_ctx,
6929 &r->out.info->info1);
6932 result = WERR_UNKNOWN_LEVEL;
6936 if (!W_ERROR_IS_OK(result)) {
6937 TALLOC_FREE(r->out.info);
6941 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_FormInfo,
6942 r->out.info, r->in.level);
6943 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
6945 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
6948 /****************************************************************************
6949 ****************************************************************************/
6951 static WERROR fill_port_1(TALLOC_CTX *mem_ctx,
6952 struct spoolss_PortInfo1 *r,
6955 r->port_name = talloc_strdup(mem_ctx, name);
6956 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6961 /****************************************************************************
6962 TODO: This probably needs distinguish between TCP/IP and Local ports
6964 ****************************************************************************/
6966 static WERROR fill_port_2(TALLOC_CTX *mem_ctx,
6967 struct spoolss_PortInfo2 *r,
6970 r->port_name = talloc_strdup(mem_ctx, name);
6971 W_ERROR_HAVE_NO_MEMORY(r->port_name);
6973 r->monitor_name = talloc_strdup(mem_ctx, "Local Monitor");
6974 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
6976 r->description = talloc_strdup(mem_ctx, SPL_LOCAL_PORT);
6977 W_ERROR_HAVE_NO_MEMORY(r->description);
6979 r->port_type = SPOOLSS_PORT_TYPE_WRITE;
6986 /****************************************************************************
6987 wrapper around the enumer ports command
6988 ****************************************************************************/
6990 static WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines)
6992 char *cmd = lp_enumports_cmd();
6993 char **qlines = NULL;
6994 char *command = NULL;
7002 /* if no hook then just fill in the default port */
7005 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7008 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7009 TALLOC_FREE(qlines);
7016 /* we have a valid enumport command */
7018 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7023 DEBUG(10,("Running [%s]\n", command));
7024 ret = smbrun(command, &fd);
7025 DEBUG(10,("Returned [%d]\n", ret));
7026 TALLOC_FREE(command);
7031 return WERR_ACCESS_DENIED;
7035 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7036 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7046 /****************************************************************************
7048 ****************************************************************************/
7050 static WERROR enumports_level_1(TALLOC_CTX *mem_ctx,
7051 union spoolss_PortInfo **info_p,
7054 union spoolss_PortInfo *info = NULL;
7056 WERROR result = WERR_OK;
7057 char **qlines = NULL;
7060 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7061 if (!W_ERROR_IS_OK(result)) {
7066 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7068 DEBUG(10,("Returning WERR_NOMEM\n"));
7069 result = WERR_NOMEM;
7073 for (i=0; i<numlines; i++) {
7074 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7075 result = fill_port_1(info, &info[i].info1, qlines[i]);
7076 if (!W_ERROR_IS_OK(result)) {
7081 TALLOC_FREE(qlines);
7084 if (!W_ERROR_IS_OK(result)) {
7086 TALLOC_FREE(qlines);
7098 /****************************************************************************
7100 ****************************************************************************/
7102 static WERROR enumports_level_2(TALLOC_CTX *mem_ctx,
7103 union spoolss_PortInfo **info_p,
7106 union spoolss_PortInfo *info = NULL;
7108 WERROR result = WERR_OK;
7109 char **qlines = NULL;
7112 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7113 if (!W_ERROR_IS_OK(result)) {
7118 info = TALLOC_ARRAY(mem_ctx, union spoolss_PortInfo, numlines);
7120 DEBUG(10,("Returning WERR_NOMEM\n"));
7121 result = WERR_NOMEM;
7125 for (i=0; i<numlines; i++) {
7126 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7127 result = fill_port_2(info, &info[i].info2, qlines[i]);
7128 if (!W_ERROR_IS_OK(result)) {
7133 TALLOC_FREE(qlines);
7136 if (!W_ERROR_IS_OK(result)) {
7138 TALLOC_FREE(qlines);
7150 /****************************************************************
7152 ****************************************************************/
7154 WERROR _spoolss_EnumPorts(struct pipes_struct *p,
7155 struct spoolss_EnumPorts *r)
7159 /* that's an [in out] buffer */
7161 if (!r->in.buffer && (r->in.offered != 0)) {
7162 return WERR_INVALID_PARAM;
7165 DEBUG(4,("_spoolss_EnumPorts\n"));
7169 *r->out.info = NULL;
7171 switch (r->in.level) {
7173 result = enumports_level_1(p->mem_ctx, r->out.info,
7177 result = enumports_level_2(p->mem_ctx, r->out.info,
7181 return WERR_UNKNOWN_LEVEL;
7184 if (!W_ERROR_IS_OK(result)) {
7188 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
7190 *r->out.info, r->in.level,
7192 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
7193 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
7195 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7198 /****************************************************************************
7199 ****************************************************************************/
7201 static WERROR spoolss_addprinterex_level_2(struct pipes_struct *p,
7203 struct spoolss_SetPrinterInfoCtr *info_ctr,
7204 struct spoolss_DeviceMode *devmode,
7205 struct security_descriptor *secdesc,
7206 struct spoolss_UserLevelCtr *user_ctr,
7207 struct policy_handle *handle)
7209 struct spoolss_SetPrinterInfo2 *info2 = info_ctr->info.info2;
7210 uint32_t info2_mask = SPOOLSS_PRINTER_INFO_ALL;
7212 WERROR err = WERR_OK;
7214 /* samba does not have a concept of local, non-shared printers yet, so
7215 * make sure we always setup sharename - gd */
7216 if ((info2->sharename == NULL || info2->sharename[0] == '\0') &&
7217 (info2->printername != NULL && info2->printername[0] != '\0')) {
7218 DEBUG(5, ("spoolss_addprinterex_level_2: "
7219 "no sharename has been set, setting printername %s as sharename\n",
7220 info2->printername));
7221 info2->sharename = info2->printername;
7224 /* check to see if the printer already exists */
7225 if ((snum = print_queue_snum(info2->sharename)) != -1) {
7226 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7228 return WERR_PRINTER_ALREADY_EXISTS;
7231 if (!lp_force_printername(GLOBAL_SECTION_SNUM)) {
7232 if ((snum = print_queue_snum(info2->printername)) != -1) {
7233 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7234 info2->printername));
7235 return WERR_PRINTER_ALREADY_EXISTS;
7239 /* validate printer info struct */
7240 if (!info2->printername || strlen(info2->printername) == 0) {
7241 return WERR_INVALID_PRINTER_NAME;
7243 if (!info2->portname || strlen(info2->portname) == 0) {
7244 return WERR_UNKNOWN_PORT;
7246 if (!info2->drivername || strlen(info2->drivername) == 0) {
7247 return WERR_UNKNOWN_PRINTER_DRIVER;
7249 if (!info2->printprocessor || strlen(info2->printprocessor) == 0) {
7250 return WERR_UNKNOWN_PRINTPROCESSOR;
7253 /* FIXME!!! smbd should check to see if the driver is installed before
7254 trying to add a printer like this --jerry */
7256 if (*lp_addprinter_cmd() ) {
7257 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7258 info2, p->client_address) ) {
7259 return WERR_ACCESS_DENIED;
7262 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7263 "smb.conf parameter \"addprinter command\" is defined. This"
7264 "parameter must exist for this call to succeed\n",
7265 info2->sharename ));
7268 if ((snum = print_queue_snum(info2->sharename)) == -1) {
7269 return WERR_ACCESS_DENIED;
7272 /* you must be a printer admin to add a new printer */
7273 if (!print_access_check(p->server_info, snum, PRINTER_ACCESS_ADMINISTER)) {
7274 return WERR_ACCESS_DENIED;
7278 * Do sanity check on the requested changes for Samba.
7281 if (!check_printer_ok(p->mem_ctx, info2, snum)) {
7282 return WERR_INVALID_PARAM;
7285 if (devmode == NULL) {
7286 info2_mask = ~SPOOLSS_PRINTER_INFO_DEVMODE;
7289 update_dsspooler(p->mem_ctx,
7295 err = winreg_update_printer(p->mem_ctx,
7302 if (!W_ERROR_IS_OK(err)) {
7306 if (!open_printer_hnd(p, handle, info2->printername, PRINTER_ACCESS_ADMINISTER)) {
7307 /* Handle open failed - remove addition. */
7308 ZERO_STRUCTP(handle);
7309 return WERR_ACCESS_DENIED;
7315 /****************************************************************
7316 _spoolss_AddPrinterEx
7317 ****************************************************************/
7319 WERROR _spoolss_AddPrinterEx(struct pipes_struct *p,
7320 struct spoolss_AddPrinterEx *r)
7322 switch (r->in.info_ctr->level) {
7324 /* we don't handle yet */
7325 /* but I know what to do ... */
7326 return WERR_UNKNOWN_LEVEL;
7328 return spoolss_addprinterex_level_2(p, r->in.server,
7330 r->in.devmode_ctr->devmode,
7331 r->in.secdesc_ctr->sd,
7332 r->in.userlevel_ctr,
7335 return WERR_UNKNOWN_LEVEL;
7339 /****************************************************************
7341 ****************************************************************/
7343 WERROR _spoolss_AddPrinter(struct pipes_struct *p,
7344 struct spoolss_AddPrinter *r)
7346 struct spoolss_AddPrinterEx a;
7347 struct spoolss_UserLevelCtr userlevel_ctr;
7349 ZERO_STRUCT(userlevel_ctr);
7351 userlevel_ctr.level = 1;
7353 a.in.server = r->in.server;
7354 a.in.info_ctr = r->in.info_ctr;
7355 a.in.devmode_ctr = r->in.devmode_ctr;
7356 a.in.secdesc_ctr = r->in.secdesc_ctr;
7357 a.in.userlevel_ctr = &userlevel_ctr;
7358 a.out.handle = r->out.handle;
7360 return _spoolss_AddPrinterEx(p, &a);
7363 /****************************************************************
7364 _spoolss_AddPrinterDriverEx
7365 ****************************************************************/
7367 WERROR _spoolss_AddPrinterDriverEx(struct pipes_struct *p,
7368 struct spoolss_AddPrinterDriverEx *r)
7370 WERROR err = WERR_OK;
7371 const char *driver_name = NULL;
7376 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7377 fn = "_spoolss_AddPrinterDriver";
7379 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7380 fn = "_spoolss_AddPrinterDriverEx";
7383 return WERR_INVALID_PARAM;
7387 * we only support the semantics of AddPrinterDriver()
7388 * i.e. only copy files that are newer than existing ones
7391 if (r->in.flags == 0) {
7392 return WERR_INVALID_PARAM;
7395 if (r->in.flags != APD_COPY_NEW_FILES) {
7396 return WERR_ACCESS_DENIED;
7400 if (r->in.info_ctr->level != 3 && r->in.info_ctr->level != 6) {
7401 /* Clever hack from Martin Zielinski <mz@seh.de>
7402 * to allow downgrade from level 8 (Vista).
7404 DEBUG(0,("%s: level %d not yet implemented\n", fn,
7405 r->in.info_ctr->level));
7406 return WERR_UNKNOWN_LEVEL;
7409 DEBUG(5,("Cleaning driver's information\n"));
7410 err = clean_up_driver_struct(p->mem_ctx, p, r->in.info_ctr);
7411 if (!W_ERROR_IS_OK(err))
7414 DEBUG(5,("Moving driver to final destination\n"));
7415 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, r->in.info_ctr,
7420 err = winreg_add_driver(p->mem_ctx, p->server_info,
7421 r->in.info_ctr, &driver_name, &version);
7422 if (!W_ERROR_IS_OK(err)) {
7427 * I think this is where he DrvUpgradePrinter() hook would be
7428 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7429 * server. Right now, we just need to send ourselves a message
7430 * to update each printer bound to this driver. --jerry
7433 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7434 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7442 /****************************************************************
7443 _spoolss_AddPrinterDriver
7444 ****************************************************************/
7446 WERROR _spoolss_AddPrinterDriver(struct pipes_struct *p,
7447 struct spoolss_AddPrinterDriver *r)
7449 struct spoolss_AddPrinterDriverEx a;
7451 switch (r->in.info_ctr->level) {
7458 return WERR_UNKNOWN_LEVEL;
7461 a.in.servername = r->in.servername;
7462 a.in.info_ctr = r->in.info_ctr;
7463 a.in.flags = APD_COPY_NEW_FILES;
7465 return _spoolss_AddPrinterDriverEx(p, &a);
7468 /****************************************************************************
7469 ****************************************************************************/
7471 struct _spoolss_paths {
7477 enum { SPOOLSS_DRIVER_PATH, SPOOLSS_PRTPROCS_PATH };
7479 static const struct _spoolss_paths spoolss_paths[]= {
7480 { SPOOLSS_DRIVER_PATH, "print$", "DRIVERS" },
7481 { SPOOLSS_PRTPROCS_PATH, "prnproc$", "PRTPROCS" }
7484 static WERROR compose_spoolss_server_path(TALLOC_CTX *mem_ctx,
7485 const char *servername,
7486 const char *environment,
7490 const char *pservername = NULL;
7491 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
7492 const char *short_archi;
7496 /* environment may be empty */
7497 if (environment && strlen(environment)) {
7498 long_archi = environment;
7501 /* servername may be empty */
7502 if (servername && strlen(servername)) {
7503 pservername = canon_servername(servername);
7505 if (!is_myname_or_ipaddr(pservername)) {
7506 return WERR_INVALID_PARAM;
7510 if (!(short_archi = get_short_archi(long_archi))) {
7511 return WERR_INVALID_ENVIRONMENT;
7514 switch (component) {
7515 case SPOOLSS_PRTPROCS_PATH:
7516 case SPOOLSS_DRIVER_PATH:
7518 *path = talloc_asprintf(mem_ctx,
7521 spoolss_paths[component].share,
7524 *path = talloc_asprintf(mem_ctx, "%s\\%s\\%s",
7525 SPOOLSS_DEFAULT_SERVER_PATH,
7526 spoolss_paths[component].dir,
7531 return WERR_INVALID_PARAM;
7541 /****************************************************************************
7542 ****************************************************************************/
7544 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
7545 const char *servername,
7546 const char *environment,
7547 struct spoolss_DriverDirectoryInfo1 *r)
7552 werr = compose_spoolss_server_path(mem_ctx,
7555 SPOOLSS_DRIVER_PATH,
7557 if (!W_ERROR_IS_OK(werr)) {
7561 DEBUG(4,("printer driver directory: [%s]\n", path));
7563 r->directory_name = path;
7568 /****************************************************************
7569 _spoolss_GetPrinterDriverDirectory
7570 ****************************************************************/
7572 WERROR _spoolss_GetPrinterDriverDirectory(struct pipes_struct *p,
7573 struct spoolss_GetPrinterDriverDirectory *r)
7577 /* that's an [in out] buffer */
7579 if (!r->in.buffer && (r->in.offered != 0)) {
7580 return WERR_INVALID_PARAM;
7583 DEBUG(5,("_spoolss_GetPrinterDriverDirectory: level %d\n",
7588 /* r->in.level is ignored */
7590 werror = getprinterdriverdir_level_1(p->mem_ctx,
7593 &r->out.info->info1);
7594 if (!W_ERROR_IS_OK(werror)) {
7595 TALLOC_FREE(r->out.info);
7599 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_DriverDirectoryInfo,
7600 r->out.info, r->in.level);
7601 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
7603 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
7606 /****************************************************************
7607 _spoolss_EnumPrinterData
7608 ****************************************************************/
7610 WERROR _spoolss_EnumPrinterData(struct pipes_struct *p,
7611 struct spoolss_EnumPrinterData *r)
7614 struct spoolss_EnumPrinterDataEx r2;
7616 struct spoolss_PrinterEnumValues *info, *val = NULL;
7619 r2.in.handle = r->in.handle;
7620 r2.in.key_name = "PrinterDriverData";
7622 r2.out.count = &count;
7623 r2.out.info = &info;
7624 r2.out.needed = &needed;
7626 result = _spoolss_EnumPrinterDataEx(p, &r2);
7627 if (W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
7628 r2.in.offered = needed;
7629 result = _spoolss_EnumPrinterDataEx(p, &r2);
7631 if (!W_ERROR_IS_OK(result)) {
7636 * The NT machine wants to know the biggest size of value and data
7638 * cf: MSDN EnumPrinterData remark section
7641 if (!r->in.value_offered && !r->in.data_offered) {
7642 uint32_t biggest_valuesize = 0;
7643 uint32_t biggest_datasize = 0;
7646 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
7648 for (i=0; i<count; i++) {
7650 name_length = strlen(info[i].value_name);
7651 if (strlen(info[i].value_name) > biggest_valuesize) {
7652 biggest_valuesize = name_length;
7655 if (info[i].data_length > biggest_datasize) {
7656 biggest_datasize = info[i].data_length;
7659 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
7663 /* the value is an UNICODE string but real_value_size is the length
7664 in bytes including the trailing 0 */
7666 *r->out.value_needed = 2 * (1 + biggest_valuesize);
7667 *r->out.data_needed = biggest_datasize;
7669 DEBUG(6,("final values: [%d], [%d]\n",
7670 *r->out.value_needed, *r->out.data_needed));
7675 if (r->in.enum_index < count) {
7676 val = &info[r->in.enum_index];
7680 /* out_value should default to "" or else NT4 has
7681 problems unmarshalling the response */
7683 if (r->in.value_offered) {
7684 *r->out.value_needed = 1;
7685 r->out.value_name = talloc_strdup(r, "");
7686 if (!r->out.value_name) {
7690 r->out.value_name = NULL;
7691 *r->out.value_needed = 0;
7694 /* the data is counted in bytes */
7696 *r->out.data_needed = r->in.data_offered;
7698 result = WERR_NO_MORE_ITEMS;
7702 * - counted in bytes in the request
7703 * - counted in UNICODE chars in the max reply
7704 * - counted in bytes in the real size
7706 * take a pause *before* coding not *during* coding
7710 if (r->in.value_offered) {
7711 r->out.value_name = talloc_strdup(r, val->value_name);
7712 if (!r->out.value_name) {
7715 *r->out.value_needed = val->value_name_len;
7717 r->out.value_name = NULL;
7718 *r->out.value_needed = 0;
7723 *r->out.type = val->type;
7725 /* data - counted in bytes */
7728 * See the section "Dynamically Typed Query Parameters"
7732 if (r->out.data && val->data && val->data->data &&
7733 val->data_length && r->in.data_offered) {
7734 memcpy(r->out.data, val->data->data,
7735 MIN(val->data_length,r->in.data_offered));
7738 *r->out.data_needed = val->data_length;
7746 /****************************************************************
7747 _spoolss_SetPrinterData
7748 ****************************************************************/
7750 WERROR _spoolss_SetPrinterData(struct pipes_struct *p,
7751 struct spoolss_SetPrinterData *r)
7753 struct spoolss_SetPrinterDataEx r2;
7755 r2.in.handle = r->in.handle;
7756 r2.in.key_name = "PrinterDriverData";
7757 r2.in.value_name = r->in.value_name;
7758 r2.in.type = r->in.type;
7759 r2.in.data = r->in.data;
7760 r2.in.offered = r->in.offered;
7762 return _spoolss_SetPrinterDataEx(p, &r2);
7765 /****************************************************************
7766 _spoolss_ResetPrinter
7767 ****************************************************************/
7769 WERROR _spoolss_ResetPrinter(struct pipes_struct *p,
7770 struct spoolss_ResetPrinter *r)
7772 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7775 DEBUG(5,("_spoolss_ResetPrinter\n"));
7778 * All we do is to check to see if the handle and queue is valid.
7779 * This call really doesn't mean anything to us because we only
7780 * support RAW printing. --jerry
7784 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
7785 OUR_HANDLE(r->in.handle)));
7789 if (!get_printer_snum(p, r->in.handle, &snum, NULL))
7793 /* blindly return success */
7797 /****************************************************************
7798 _spoolss_DeletePrinterData
7799 ****************************************************************/
7801 WERROR _spoolss_DeletePrinterData(struct pipes_struct *p,
7802 struct spoolss_DeletePrinterData *r)
7804 struct spoolss_DeletePrinterDataEx r2;
7806 r2.in.handle = r->in.handle;
7807 r2.in.key_name = "PrinterDriverData";
7808 r2.in.value_name = r->in.value_name;
7810 return _spoolss_DeletePrinterDataEx(p, &r2);
7813 /****************************************************************
7815 ****************************************************************/
7817 WERROR _spoolss_AddForm(struct pipes_struct *p,
7818 struct spoolss_AddForm *r)
7820 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7822 WERROR status = WERR_OK;
7823 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7825 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7827 DEBUG(5,("_spoolss_AddForm\n"));
7830 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
7831 OUR_HANDLE(r->in.handle)));
7835 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7836 and not a printer admin, then fail */
7838 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7839 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7840 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7841 p->server_info->info3->base.domain.string,
7843 p->server_info->ptok,
7844 lp_printer_admin(snum))) {
7845 DEBUG(2,("_spoolss_Addform: denied by insufficient permissions.\n"));
7846 return WERR_ACCESS_DENIED;
7849 switch (form->flags) {
7850 case SPOOLSS_FORM_USER:
7851 case SPOOLSS_FORM_BUILTIN:
7852 case SPOOLSS_FORM_PRINTER:
7855 return WERR_INVALID_PARAM;
7858 status = winreg_printer_addform1(p->mem_ctx, p->server_info, form);
7859 if (!W_ERROR_IS_OK(status)) {
7864 * ChangeID must always be set if this is a printer
7866 if (Printer->printer_type == SPLHND_PRINTER) {
7867 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7871 status = winreg_printer_update_changeid(p->mem_ctx,
7873 lp_const_servicename(snum));
7874 if (!W_ERROR_IS_OK(status)) {
7882 /****************************************************************
7884 ****************************************************************/
7886 WERROR _spoolss_DeleteForm(struct pipes_struct *p,
7887 struct spoolss_DeleteForm *r)
7889 const char *form_name = r->in.form_name;
7890 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7892 WERROR status = WERR_OK;
7893 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7895 DEBUG(5,("_spoolss_DeleteForm\n"));
7898 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
7899 OUR_HANDLE(r->in.handle)));
7903 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7904 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7905 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7906 p->server_info->info3->base.domain.string,
7908 p->server_info->ptok,
7909 lp_printer_admin(snum))) {
7910 DEBUG(2,("_spoolss_DeleteForm: denied by insufficient permissions.\n"));
7911 return WERR_ACCESS_DENIED;
7914 status = winreg_printer_deleteform1(p->mem_ctx,
7917 if (!W_ERROR_IS_OK(status)) {
7922 * ChangeID must always be set if this is a printer
7924 if (Printer->printer_type == SPLHND_PRINTER) {
7925 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7929 status = winreg_printer_update_changeid(p->mem_ctx,
7931 lp_const_servicename(snum));
7932 if (!W_ERROR_IS_OK(status)) {
7940 /****************************************************************
7942 ****************************************************************/
7944 WERROR _spoolss_SetForm(struct pipes_struct *p,
7945 struct spoolss_SetForm *r)
7947 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
7948 const char *form_name = r->in.form_name;
7950 WERROR status = WERR_OK;
7951 SE_PRIV se_printop = SE_PRINT_OPERATOR;
7953 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
7955 DEBUG(5,("_spoolss_SetForm\n"));
7958 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
7959 OUR_HANDLE(r->in.handle)));
7963 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
7964 and not a printer admin, then fail */
7966 if ((p->server_info->utok.uid != sec_initial_uid()) &&
7967 !user_has_privileges(p->server_info->ptok, &se_printop) &&
7968 !token_contains_name_in_list(uidtoname(p->server_info->utok.uid),
7969 p->server_info->info3->base.domain.string,
7971 p->server_info->ptok,
7972 lp_printer_admin(snum))) {
7973 DEBUG(2,("_spoolss_Setform: denied by insufficient permissions.\n"));
7974 return WERR_ACCESS_DENIED;
7977 status = winreg_printer_setform1(p->mem_ctx,
7981 if (!W_ERROR_IS_OK(status)) {
7986 * ChangeID must always be set if this is a printer
7988 if (Printer->printer_type == SPLHND_PRINTER) {
7989 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
7993 status = winreg_printer_update_changeid(p->mem_ctx,
7995 lp_const_servicename(snum));
7996 if (!W_ERROR_IS_OK(status)) {
8004 /****************************************************************************
8005 fill_print_processor1
8006 ****************************************************************************/
8008 static WERROR fill_print_processor1(TALLOC_CTX *mem_ctx,
8009 struct spoolss_PrintProcessorInfo1 *r,
8010 const char *print_processor_name)
8012 r->print_processor_name = talloc_strdup(mem_ctx, print_processor_name);
8013 W_ERROR_HAVE_NO_MEMORY(r->print_processor_name);
8018 /****************************************************************************
8019 enumprintprocessors level 1.
8020 ****************************************************************************/
8022 static WERROR enumprintprocessors_level_1(TALLOC_CTX *mem_ctx,
8023 union spoolss_PrintProcessorInfo **info_p,
8026 union spoolss_PrintProcessorInfo *info;
8029 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcessorInfo, 1);
8030 W_ERROR_HAVE_NO_MEMORY(info);
8034 result = fill_print_processor1(info, &info[0].info1, "winprint");
8035 if (!W_ERROR_IS_OK(result)) {
8040 if (!W_ERROR_IS_OK(result)) {
8051 /****************************************************************
8052 _spoolss_EnumPrintProcessors
8053 ****************************************************************/
8055 WERROR _spoolss_EnumPrintProcessors(struct pipes_struct *p,
8056 struct spoolss_EnumPrintProcessors *r)
8060 /* that's an [in out] buffer */
8062 if (!r->in.buffer && (r->in.offered != 0)) {
8063 return WERR_INVALID_PARAM;
8066 DEBUG(5,("_spoolss_EnumPrintProcessors\n"));
8069 * Enumerate the print processors ...
8071 * Just reply with "winprint", to keep NT happy
8072 * and I can use my nice printer checker.
8077 *r->out.info = NULL;
8079 switch (r->in.level) {
8081 result = enumprintprocessors_level_1(p->mem_ctx, r->out.info,
8085 return WERR_UNKNOWN_LEVEL;
8088 if (!W_ERROR_IS_OK(result)) {
8092 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8093 spoolss_EnumPrintProcessors,
8094 *r->out.info, r->in.level,
8096 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8097 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8099 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8102 /****************************************************************************
8103 fill_printprocdatatype1
8104 ****************************************************************************/
8106 static WERROR fill_printprocdatatype1(TALLOC_CTX *mem_ctx,
8107 struct spoolss_PrintProcDataTypesInfo1 *r,
8108 const char *name_array)
8110 r->name_array = talloc_strdup(mem_ctx, name_array);
8111 W_ERROR_HAVE_NO_MEMORY(r->name_array);
8116 /****************************************************************************
8117 enumprintprocdatatypes level 1.
8118 ****************************************************************************/
8120 static WERROR enumprintprocdatatypes_level_1(TALLOC_CTX *mem_ctx,
8121 union spoolss_PrintProcDataTypesInfo **info_p,
8125 union spoolss_PrintProcDataTypesInfo *info;
8127 info = TALLOC_ARRAY(mem_ctx, union spoolss_PrintProcDataTypesInfo, 1);
8128 W_ERROR_HAVE_NO_MEMORY(info);
8132 result = fill_printprocdatatype1(info, &info[0].info1, "RAW");
8133 if (!W_ERROR_IS_OK(result)) {
8138 if (!W_ERROR_IS_OK(result)) {
8149 /****************************************************************
8150 _spoolss_EnumPrintProcDataTypes
8151 ****************************************************************/
8153 WERROR _spoolss_EnumPrintProcDataTypes(struct pipes_struct *p,
8154 struct spoolss_EnumPrintProcDataTypes *r)
8158 /* that's an [in out] buffer */
8160 if (!r->in.buffer && (r->in.offered != 0)) {
8161 return WERR_INVALID_PARAM;
8164 DEBUG(5,("_spoolss_EnumPrintProcDataTypes\n"));
8168 *r->out.info = NULL;
8170 switch (r->in.level) {
8172 result = enumprintprocdatatypes_level_1(p->mem_ctx, r->out.info,
8176 return WERR_UNKNOWN_LEVEL;
8179 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8180 spoolss_EnumPrintProcDataTypes,
8181 *r->out.info, r->in.level,
8183 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8184 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8186 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8189 /****************************************************************************
8191 ****************************************************************************/
8193 static WERROR fill_monitor_1(TALLOC_CTX *mem_ctx,
8194 struct spoolss_MonitorInfo1 *r,
8195 const char *monitor_name)
8197 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8198 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8203 /****************************************************************************
8205 ****************************************************************************/
8207 static WERROR fill_monitor_2(TALLOC_CTX *mem_ctx,
8208 struct spoolss_MonitorInfo2 *r,
8209 const char *monitor_name,
8210 const char *environment,
8211 const char *dll_name)
8213 r->monitor_name = talloc_strdup(mem_ctx, monitor_name);
8214 W_ERROR_HAVE_NO_MEMORY(r->monitor_name);
8215 r->environment = talloc_strdup(mem_ctx, environment);
8216 W_ERROR_HAVE_NO_MEMORY(r->environment);
8217 r->dll_name = talloc_strdup(mem_ctx, dll_name);
8218 W_ERROR_HAVE_NO_MEMORY(r->dll_name);
8223 /****************************************************************************
8224 enumprintmonitors level 1.
8225 ****************************************************************************/
8227 static WERROR enumprintmonitors_level_1(TALLOC_CTX *mem_ctx,
8228 union spoolss_MonitorInfo **info_p,
8231 union spoolss_MonitorInfo *info;
8232 WERROR result = WERR_OK;
8234 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8235 W_ERROR_HAVE_NO_MEMORY(info);
8239 result = fill_monitor_1(info, &info[0].info1,
8241 if (!W_ERROR_IS_OK(result)) {
8245 result = fill_monitor_1(info, &info[1].info1,
8247 if (!W_ERROR_IS_OK(result)) {
8252 if (!W_ERROR_IS_OK(result)) {
8263 /****************************************************************************
8264 enumprintmonitors level 2.
8265 ****************************************************************************/
8267 static WERROR enumprintmonitors_level_2(TALLOC_CTX *mem_ctx,
8268 union spoolss_MonitorInfo **info_p,
8271 union spoolss_MonitorInfo *info;
8272 WERROR result = WERR_OK;
8274 info = TALLOC_ARRAY(mem_ctx, union spoolss_MonitorInfo, 2);
8275 W_ERROR_HAVE_NO_MEMORY(info);
8279 result = fill_monitor_2(info, &info[0].info2,
8281 "Windows NT X86", /* FIXME */
8283 if (!W_ERROR_IS_OK(result)) {
8287 result = fill_monitor_2(info, &info[1].info2,
8289 "Windows NT X86", /* FIXME */
8291 if (!W_ERROR_IS_OK(result)) {
8296 if (!W_ERROR_IS_OK(result)) {
8307 /****************************************************************
8308 _spoolss_EnumMonitors
8309 ****************************************************************/
8311 WERROR _spoolss_EnumMonitors(struct pipes_struct *p,
8312 struct spoolss_EnumMonitors *r)
8316 /* that's an [in out] buffer */
8318 if (!r->in.buffer && (r->in.offered != 0)) {
8319 return WERR_INVALID_PARAM;
8322 DEBUG(5,("_spoolss_EnumMonitors\n"));
8325 * Enumerate the print monitors ...
8327 * Just reply with "Local Port", to keep NT happy
8328 * and I can use my nice printer checker.
8333 *r->out.info = NULL;
8335 switch (r->in.level) {
8337 result = enumprintmonitors_level_1(p->mem_ctx, r->out.info,
8341 result = enumprintmonitors_level_2(p->mem_ctx, r->out.info,
8345 return WERR_UNKNOWN_LEVEL;
8348 if (!W_ERROR_IS_OK(result)) {
8352 *r->out.needed = SPOOLSS_BUFFER_UNION_ARRAY(p->mem_ctx,
8353 spoolss_EnumMonitors,
8354 *r->out.info, r->in.level,
8356 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8357 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, 0);
8359 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8362 /****************************************************************************
8363 ****************************************************************************/
8365 static WERROR getjob_level_1(TALLOC_CTX *mem_ctx,
8366 const print_queue_struct *queue,
8367 int count, int snum,
8368 struct spoolss_PrinterInfo2 *pinfo2,
8370 struct spoolss_JobInfo1 *r)
8375 for (i=0; i<count; i++) {
8376 if (queue[i].job == (int)jobid) {
8382 if (found == false) {
8383 /* NT treats not found as bad param... yet another bad choice */
8384 return WERR_INVALID_PARAM;
8387 return fill_job_info1(mem_ctx,
8395 /****************************************************************************
8396 ****************************************************************************/
8398 static WERROR getjob_level_2(TALLOC_CTX *mem_ctx,
8399 const print_queue_struct *queue,
8400 int count, int snum,
8401 struct spoolss_PrinterInfo2 *pinfo2,
8403 struct spoolss_JobInfo2 *r)
8407 struct spoolss_DeviceMode *devmode;
8410 for (i=0; i<count; i++) {
8411 if (queue[i].job == (int)jobid) {
8417 if (found == false) {
8418 /* NT treats not found as bad param... yet another bad
8420 return WERR_INVALID_PARAM;
8424 * if the print job does not have a DEVMODE associated with it,
8425 * just use the one for the printer. A NULL devicemode is not
8426 * a failure condition
8429 devmode = print_job_devmode(lp_const_servicename(snum), jobid);
8431 result = spoolss_create_default_devmode(mem_ctx,
8432 pinfo2->printername,
8434 if (!W_ERROR_IS_OK(result)) {
8435 DEBUG(3, ("Can't proceed w/o a devmode!"));
8440 return fill_job_info2(mem_ctx,
8449 /****************************************************************
8451 ****************************************************************/
8453 WERROR _spoolss_GetJob(struct pipes_struct *p,
8454 struct spoolss_GetJob *r)
8456 WERROR result = WERR_OK;
8457 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8460 print_queue_struct *queue = NULL;
8461 print_status_struct prt_status;
8463 /* that's an [in out] buffer */
8465 if (!r->in.buffer && (r->in.offered != 0)) {
8466 return WERR_INVALID_PARAM;
8469 DEBUG(5,("_spoolss_GetJob\n"));
8473 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8477 result = winreg_get_printer(p->mem_ctx, p->server_info, NULL,
8478 lp_servicename(snum), &pinfo2);
8479 if (!W_ERROR_IS_OK(result)) {
8483 count = print_queue_status(snum, &queue, &prt_status);
8485 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
8486 count, prt_status.status, prt_status.message));
8488 switch (r->in.level) {
8490 result = getjob_level_1(p->mem_ctx,
8491 queue, count, snum, pinfo2,
8492 r->in.job_id, &r->out.info->info1);
8495 result = getjob_level_2(p->mem_ctx,
8496 queue, count, snum, pinfo2,
8497 r->in.job_id, &r->out.info->info2);
8500 result = WERR_UNKNOWN_LEVEL;
8505 TALLOC_FREE(pinfo2);
8507 if (!W_ERROR_IS_OK(result)) {
8508 TALLOC_FREE(r->out.info);
8512 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_JobInfo, r->out.info,
8514 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
8516 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
8519 /****************************************************************
8520 _spoolss_GetPrinterDataEx
8521 ****************************************************************/
8523 WERROR _spoolss_GetPrinterDataEx(struct pipes_struct *p,
8524 struct spoolss_GetPrinterDataEx *r)
8527 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8528 const char *printer;
8530 WERROR result = WERR_OK;
8532 enum winreg_Type val_type;
8537 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
8539 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
8540 r->in.key_name, r->in.value_name));
8542 /* in case of problem, return some default values */
8545 *r->out.type = REG_NONE;
8548 DEBUG(2,("_spoolss_GetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8549 OUR_HANDLE(r->in.handle)));
8550 result = WERR_BADFID;
8554 /* Is the handle to a printer or to the server? */
8556 if (Printer->printer_type == SPLHND_SERVER) {
8558 union spoolss_PrinterData data;
8560 result = getprinterdata_printer_server(p->mem_ctx,
8564 if (!W_ERROR_IS_OK(result)) {
8568 result = push_spoolss_PrinterData(p->mem_ctx, &blob,
8569 *r->out.type, &data);
8570 if (!W_ERROR_IS_OK(result)) {
8574 *r->out.needed = blob.length;
8576 if (r->in.offered >= *r->out.needed) {
8577 memcpy(r->out.data, blob.data, blob.length);
8580 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8583 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8586 printer = lp_const_servicename(snum);
8588 /* check to see if the keyname is valid */
8589 if (!strlen(r->in.key_name)) {
8590 return WERR_INVALID_PARAM;
8593 /* XP sends this and wants the ChangeID value from PRINTER_INFO_0 */
8594 if (strequal(r->in.key_name, SPOOL_PRINTERDATA_KEY) &&
8595 strequal(r->in.value_name, "ChangeId")) {
8596 *r->out.type = REG_DWORD;
8598 if (r->in.offered >= *r->out.needed) {
8599 uint32_t changeid = 0;
8601 result = winreg_printer_get_changeid(p->mem_ctx,
8605 if (!W_ERROR_IS_OK(result)) {
8609 SIVAL(r->out.data, 0, changeid);
8615 result = winreg_get_printer_dataex(p->mem_ctx,
8623 if (!W_ERROR_IS_OK(result)) {
8627 *r->out.needed = val_size;
8628 *r->out.type = val_type;
8630 if (r->in.offered >= *r->out.needed) {
8631 memcpy(r->out.data, val_data, val_size);
8635 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
8636 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
8638 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8641 /****************************************************************
8642 _spoolss_SetPrinterDataEx
8643 ****************************************************************/
8645 WERROR _spoolss_SetPrinterDataEx(struct pipes_struct *p,
8646 struct spoolss_SetPrinterDataEx *r)
8648 struct spoolss_PrinterInfo2 *pinfo2 = NULL;
8650 WERROR result = WERR_OK;
8651 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8654 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
8656 /* From MSDN documentation of SetPrinterDataEx: pass request to
8657 SetPrinterData if key is "PrinterDriverData" */
8660 DEBUG(2,("_spoolss_SetPrinterDataEx: Invalid handle (%s:%u:%u).\n",
8661 OUR_HANDLE(r->in.handle)));
8665 if (Printer->printer_type == SPLHND_SERVER) {
8666 DEBUG(10,("_spoolss_SetPrinterDataEx: "
8667 "Not implemented for server handles yet\n"));
8668 return WERR_INVALID_PARAM;
8671 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8676 * Access check : NT returns "access denied" if you make a
8677 * SetPrinterData call without the necessary privildge.
8678 * we were originally returning OK if nothing changed
8679 * which made Win2k issue **a lot** of SetPrinterData
8680 * when connecting to a printer --jerry
8683 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8684 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
8685 "change denied by handle access permissions\n"));
8686 return WERR_ACCESS_DENIED;
8689 result = winreg_get_printer(Printer, p->server_info,
8690 Printer->servername,
8691 lp_servicename(snum),
8693 if (!W_ERROR_IS_OK(result)) {
8697 /* check for OID in valuename */
8699 oid_string = strchr(r->in.value_name, ',');
8705 /* save the registry data */
8707 result = winreg_set_printer_dataex(p->mem_ctx,
8716 if (W_ERROR_IS_OK(result)) {
8717 /* save the OID if one was specified */
8719 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
8720 r->in.key_name, SPOOL_OID_KEY);
8722 result = WERR_NOMEM;
8727 * I'm not checking the status here on purpose. Don't know
8728 * if this is right, but I'm returning the status from the
8729 * previous set_printer_dataex() call. I have no idea if
8730 * this is right. --jerry
8732 winreg_set_printer_dataex(p->mem_ctx,
8738 (uint8_t *) oid_string,
8739 strlen(oid_string) + 1);
8742 result = winreg_printer_update_changeid(p->mem_ctx,
8744 lp_const_servicename(snum));
8749 talloc_free(pinfo2);
8753 /****************************************************************
8754 _spoolss_DeletePrinterDataEx
8755 ****************************************************************/
8757 WERROR _spoolss_DeletePrinterDataEx(struct pipes_struct *p,
8758 struct spoolss_DeletePrinterDataEx *r)
8760 const char *printer;
8762 WERROR status = WERR_OK;
8763 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8765 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
8768 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
8769 "Invalid handle (%s:%u:%u).\n",
8770 OUR_HANDLE(r->in.handle)));
8774 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8775 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
8776 "printer properties change denied by handle\n"));
8777 return WERR_ACCESS_DENIED;
8780 if (!r->in.value_name || !r->in.key_name) {
8784 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8787 printer = lp_const_servicename(snum);
8789 status = winreg_delete_printer_dataex(p->mem_ctx,
8794 if (W_ERROR_IS_OK(status)) {
8795 status = winreg_printer_update_changeid(p->mem_ctx,
8803 /****************************************************************
8804 _spoolss_EnumPrinterKey
8805 ****************************************************************/
8807 WERROR _spoolss_EnumPrinterKey(struct pipes_struct *p,
8808 struct spoolss_EnumPrinterKey *r)
8811 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8813 WERROR result = WERR_BADFILE;
8814 const char **array = NULL;
8817 DEBUG(4,("_spoolss_EnumPrinterKey\n"));
8820 DEBUG(2,("_spoolss_EnumPrinterKey: Invalid handle (%s:%u:%u).\n",
8821 OUR_HANDLE(r->in.handle)));
8825 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8829 result = winreg_enum_printer_key(p->mem_ctx,
8831 lp_const_servicename(snum),
8835 if (!W_ERROR_IS_OK(result)) {
8839 if (!push_reg_multi_sz(p->mem_ctx, &blob, array)) {
8840 result = WERR_NOMEM;
8844 *r->out._ndr_size = r->in.offered / 2;
8845 *r->out.needed = blob.length;
8847 if (r->in.offered < *r->out.needed) {
8848 result = WERR_MORE_DATA;
8851 r->out.key_buffer->string_array = array;
8855 if (!W_ERROR_IS_OK(result)) {
8857 if (!W_ERROR_EQUAL(result, WERR_MORE_DATA)) {
8865 /****************************************************************
8866 _spoolss_DeletePrinterKey
8867 ****************************************************************/
8869 WERROR _spoolss_DeletePrinterKey(struct pipes_struct *p,
8870 struct spoolss_DeletePrinterKey *r)
8872 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8875 const char *printer;
8877 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
8880 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
8881 OUR_HANDLE(r->in.handle)));
8885 /* if keyname == NULL, return error */
8886 if ( !r->in.key_name )
8887 return WERR_INVALID_PARAM;
8889 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8893 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8894 DEBUG(3, ("_spoolss_DeletePrinterKey: "
8895 "printer properties change denied by handle\n"));
8896 return WERR_ACCESS_DENIED;
8899 printer = lp_const_servicename(snum);
8901 /* delete the key and all subkeys */
8902 status = winreg_delete_printer_key(p->mem_ctx,
8906 if (W_ERROR_IS_OK(status)) {
8907 status = winreg_printer_update_changeid(p->mem_ctx,
8915 /****************************************************************
8916 _spoolss_EnumPrinterDataEx
8917 ****************************************************************/
8919 WERROR _spoolss_EnumPrinterDataEx(struct pipes_struct *p,
8920 struct spoolss_EnumPrinterDataEx *r)
8923 struct spoolss_PrinterEnumValues *info = NULL;
8924 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
8928 DEBUG(4,("_spoolss_EnumPrinterDataEx\n"));
8932 *r->out.info = NULL;
8935 DEBUG(2,("_spoolss_EnumPrinterDataEx: Invalid handle (%s:%u:%u1<).\n",
8936 OUR_HANDLE(r->in.handle)));
8941 * first check for a keyname of NULL or "". Win2k seems to send
8942 * this a lot and we should send back WERR_INVALID_PARAM
8943 * no need to spend time looking up the printer in this case.
8947 if (!strlen(r->in.key_name)) {
8948 result = WERR_INVALID_PARAM;
8952 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
8956 /* now look for a match on the key name */
8957 result = winreg_enum_printer_dataex(p->mem_ctx,
8959 lp_const_servicename(snum),
8963 if (!W_ERROR_IS_OK(result)) {
8967 #if 0 /* FIXME - gd */
8968 /* housekeeping information in the reply */
8970 /* Fix from Martin Zielinski <mz@seh.de> - ensure
8971 * the hand marshalled container size is a multiple
8972 * of 4 bytes for RPC alignment.
8976 needed += 4-(needed % 4);
8979 *r->out.count = count;
8980 *r->out.info = info;
8983 if (!W_ERROR_IS_OK(result)) {
8987 *r->out.needed = SPOOLSS_BUFFER_ARRAY(p->mem_ctx,
8988 spoolss_EnumPrinterDataEx,
8991 *r->out.info = SPOOLSS_BUFFER_OK(*r->out.info, NULL);
8992 *r->out.count = SPOOLSS_BUFFER_OK(*r->out.count, *r->out.count);
8994 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
8997 /****************************************************************************
8998 ****************************************************************************/
9000 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9001 const char *servername,
9002 const char *environment,
9003 struct spoolss_PrintProcessorDirectoryInfo1 *r)
9008 werr = compose_spoolss_server_path(mem_ctx,
9011 SPOOLSS_PRTPROCS_PATH,
9013 if (!W_ERROR_IS_OK(werr)) {
9017 DEBUG(4,("print processor directory: [%s]\n", path));
9019 r->directory_name = path;
9024 /****************************************************************
9025 _spoolss_GetPrintProcessorDirectory
9026 ****************************************************************/
9028 WERROR _spoolss_GetPrintProcessorDirectory(struct pipes_struct *p,
9029 struct spoolss_GetPrintProcessorDirectory *r)
9033 /* that's an [in out] buffer */
9035 if (!r->in.buffer && (r->in.offered != 0)) {
9036 return WERR_INVALID_PARAM;
9039 DEBUG(5,("_spoolss_GetPrintProcessorDirectory: level %d\n",
9044 /* r->in.level is ignored */
9046 /* We always should reply with a local print processor directory so that
9047 * users are not forced to have a [prnproc$] share on the Samba spoolss
9048 * server - Guenther */
9050 result = getprintprocessordirectory_level_1(p->mem_ctx,
9051 NULL, /* r->in.server */
9053 &r->out.info->info1);
9054 if (!W_ERROR_IS_OK(result)) {
9055 TALLOC_FREE(r->out.info);
9059 *r->out.needed = SPOOLSS_BUFFER_UNION(spoolss_PrintProcessorDirectoryInfo,
9060 r->out.info, r->in.level);
9061 r->out.info = SPOOLSS_BUFFER_OK(r->out.info, NULL);
9063 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_INSUFFICIENT_BUFFER);
9066 /*******************************************************************
9067 ********************************************************************/
9069 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9070 const char *dllname)
9072 enum ndr_err_code ndr_err;
9073 struct spoolss_MonitorUi ui;
9075 ui.dll_name = dllname;
9077 ndr_err = ndr_push_struct_blob(buf, mem_ctx, &ui,
9078 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9079 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9080 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9082 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9085 /*******************************************************************
9086 Streams the monitor UI DLL name in UNICODE
9087 *******************************************************************/
9089 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9090 NT_USER_TOKEN *token, DATA_BLOB *in,
9091 DATA_BLOB *out, uint32_t *needed)
9093 const char *dllname = "tcpmonui.dll";
9095 *needed = (strlen(dllname)+1) * 2;
9097 if (out->length < *needed) {
9098 return WERR_INSUFFICIENT_BUFFER;
9101 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9108 /*******************************************************************
9109 ********************************************************************/
9111 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9112 struct spoolss_PortData1 *port1,
9113 const DATA_BLOB *buf)
9115 enum ndr_err_code ndr_err;
9116 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port1,
9117 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9118 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9119 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9121 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9124 /*******************************************************************
9125 ********************************************************************/
9127 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9128 struct spoolss_PortData2 *port2,
9129 const DATA_BLOB *buf)
9131 enum ndr_err_code ndr_err;
9132 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, port2,
9133 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9134 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9135 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9137 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9140 /*******************************************************************
9141 Create a new TCP/IP port
9142 *******************************************************************/
9144 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9145 NT_USER_TOKEN *token, DATA_BLOB *in,
9146 DATA_BLOB *out, uint32_t *needed)
9148 struct spoolss_PortData1 port1;
9149 struct spoolss_PortData2 port2;
9150 char *device_uri = NULL;
9153 const char *portname;
9154 const char *hostaddress;
9156 uint32_t port_number;
9159 /* peek for spoolss_PortData version */
9161 if (!in || (in->length < (128 + 4))) {
9162 return WERR_GENERAL_FAILURE;
9165 version = IVAL(in->data, 128);
9171 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9175 portname = port1.portname;
9176 hostaddress = port1.hostaddress;
9177 queue = port1.queue;
9178 protocol = port1.protocol;
9179 port_number = port1.port_number;
9185 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9189 portname = port2.portname;
9190 hostaddress = port2.hostaddress;
9191 queue = port2.queue;
9192 protocol = port2.protocol;
9193 port_number = port2.port_number;
9197 DEBUG(1,("xcvtcp_addport: "
9198 "unknown version of port_data: %d\n", version));
9199 return WERR_UNKNOWN_PORT;
9202 /* create the device URI and call the add_port_hook() */
9205 case PROTOCOL_RAWTCP_TYPE:
9206 device_uri = talloc_asprintf(mem_ctx,
9207 "socket://%s:%d/", hostaddress,
9211 case PROTOCOL_LPR_TYPE:
9212 device_uri = talloc_asprintf(mem_ctx,
9213 "lpr://%s/%s", hostaddress, queue );
9217 return WERR_UNKNOWN_PORT;
9224 return add_port_hook(mem_ctx, token, portname, device_uri);
9227 /*******************************************************************
9228 *******************************************************************/
9230 struct xcv_api_table xcvtcp_cmds[] = {
9231 { "MonitorUI", xcvtcp_monitorui },
9232 { "AddPort", xcvtcp_addport},
9236 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9237 NT_USER_TOKEN *token, const char *command,
9244 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9246 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9247 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9248 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9251 return WERR_BADFUNC;
9254 /*******************************************************************
9255 *******************************************************************/
9256 #if 0 /* don't support management using the "Local Port" monitor */
9258 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9259 NT_USER_TOKEN *token, DATA_BLOB *in,
9260 DATA_BLOB *out, uint32_t *needed)
9262 const char *dllname = "localui.dll";
9264 *needed = (strlen(dllname)+1) * 2;
9266 if (out->length < *needed) {
9267 return WERR_INSUFFICIENT_BUFFER;
9270 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9277 /*******************************************************************
9278 *******************************************************************/
9280 struct xcv_api_table xcvlocal_cmds[] = {
9281 { "MonitorUI", xcvlocal_monitorui },
9285 struct xcv_api_table xcvlocal_cmds[] = {
9292 /*******************************************************************
9293 *******************************************************************/
9295 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9296 NT_USER_TOKEN *token, const char *command,
9297 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9302 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9304 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9305 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9306 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9308 return WERR_BADFUNC;
9311 /****************************************************************
9313 ****************************************************************/
9315 WERROR _spoolss_XcvData(struct pipes_struct *p,
9316 struct spoolss_XcvData *r)
9318 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
9319 DATA_BLOB out_data = data_blob_null;
9323 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
9324 OUR_HANDLE(r->in.handle)));
9328 /* Has to be a handle to the TCP/IP port monitor */
9330 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9331 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
9335 /* requires administrative access to the server */
9337 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9338 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
9339 return WERR_ACCESS_DENIED;
9342 /* Allocate the outgoing buffer */
9344 if (r->in.out_data_size) {
9345 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
9346 if (out_data.data == NULL) {
9351 switch ( Printer->printer_type ) {
9352 case SPLHND_PORTMON_TCP:
9353 werror = process_xcvtcp_command(p->mem_ctx,
9354 p->server_info->ptok,
9355 r->in.function_name,
9356 &r->in.in_data, &out_data,
9359 case SPLHND_PORTMON_LOCAL:
9360 werror = process_xcvlocal_command(p->mem_ctx,
9361 p->server_info->ptok,
9362 r->in.function_name,
9363 &r->in.in_data, &out_data,
9367 werror = WERR_INVALID_PRINT_MONITOR;
9370 if (!W_ERROR_IS_OK(werror)) {
9374 *r->out.status_code = 0;
9376 if (r->out.out_data && out_data.data && r->in.out_data_size && out_data.length) {
9377 memcpy(r->out.out_data, out_data.data,
9378 MIN(r->in.out_data_size, out_data.length));
9384 /****************************************************************
9385 _spoolss_AddPrintProcessor
9386 ****************************************************************/
9388 WERROR _spoolss_AddPrintProcessor(struct pipes_struct *p,
9389 struct spoolss_AddPrintProcessor *r)
9391 /* for now, just indicate success and ignore the add. We'll
9392 automatically set the winprint processor for printer
9393 entries later. Used to debug the LexMark Optra S 1855 PCL
9399 /****************************************************************
9401 ****************************************************************/
9403 WERROR _spoolss_AddPort(struct pipes_struct *p,
9404 struct spoolss_AddPort *r)
9406 /* do what w2k3 does */
9408 return WERR_NOT_SUPPORTED;
9411 /****************************************************************
9412 _spoolss_GetPrinterDriver
9413 ****************************************************************/
9415 WERROR _spoolss_GetPrinterDriver(struct pipes_struct *p,
9416 struct spoolss_GetPrinterDriver *r)
9418 p->rng_fault_state = true;
9419 return WERR_NOT_SUPPORTED;
9422 /****************************************************************
9423 _spoolss_ReadPrinter
9424 ****************************************************************/
9426 WERROR _spoolss_ReadPrinter(struct pipes_struct *p,
9427 struct spoolss_ReadPrinter *r)
9429 p->rng_fault_state = true;
9430 return WERR_NOT_SUPPORTED;
9433 /****************************************************************
9434 _spoolss_WaitForPrinterChange
9435 ****************************************************************/
9437 WERROR _spoolss_WaitForPrinterChange(struct pipes_struct *p,
9438 struct spoolss_WaitForPrinterChange *r)
9440 p->rng_fault_state = true;
9441 return WERR_NOT_SUPPORTED;
9444 /****************************************************************
9445 _spoolss_ConfigurePort
9446 ****************************************************************/
9448 WERROR _spoolss_ConfigurePort(struct pipes_struct *p,
9449 struct spoolss_ConfigurePort *r)
9451 p->rng_fault_state = true;
9452 return WERR_NOT_SUPPORTED;
9455 /****************************************************************
9457 ****************************************************************/
9459 WERROR _spoolss_DeletePort(struct pipes_struct *p,
9460 struct spoolss_DeletePort *r)
9462 p->rng_fault_state = true;
9463 return WERR_NOT_SUPPORTED;
9466 /****************************************************************
9467 _spoolss_CreatePrinterIC
9468 ****************************************************************/
9470 WERROR _spoolss_CreatePrinterIC(struct pipes_struct *p,
9471 struct spoolss_CreatePrinterIC *r)
9473 p->rng_fault_state = true;
9474 return WERR_NOT_SUPPORTED;
9477 /****************************************************************
9478 _spoolss_PlayGDIScriptOnPrinterIC
9479 ****************************************************************/
9481 WERROR _spoolss_PlayGDIScriptOnPrinterIC(struct pipes_struct *p,
9482 struct spoolss_PlayGDIScriptOnPrinterIC *r)
9484 p->rng_fault_state = true;
9485 return WERR_NOT_SUPPORTED;
9488 /****************************************************************
9489 _spoolss_DeletePrinterIC
9490 ****************************************************************/
9492 WERROR _spoolss_DeletePrinterIC(struct pipes_struct *p,
9493 struct spoolss_DeletePrinterIC *r)
9495 p->rng_fault_state = true;
9496 return WERR_NOT_SUPPORTED;
9499 /****************************************************************
9500 _spoolss_AddPrinterConnection
9501 ****************************************************************/
9503 WERROR _spoolss_AddPrinterConnection(struct pipes_struct *p,
9504 struct spoolss_AddPrinterConnection *r)
9506 p->rng_fault_state = true;
9507 return WERR_NOT_SUPPORTED;
9510 /****************************************************************
9511 _spoolss_DeletePrinterConnection
9512 ****************************************************************/
9514 WERROR _spoolss_DeletePrinterConnection(struct pipes_struct *p,
9515 struct spoolss_DeletePrinterConnection *r)
9517 p->rng_fault_state = true;
9518 return WERR_NOT_SUPPORTED;
9521 /****************************************************************
9522 _spoolss_PrinterMessageBox
9523 ****************************************************************/
9525 WERROR _spoolss_PrinterMessageBox(struct pipes_struct *p,
9526 struct spoolss_PrinterMessageBox *r)
9528 p->rng_fault_state = true;
9529 return WERR_NOT_SUPPORTED;
9532 /****************************************************************
9534 ****************************************************************/
9536 WERROR _spoolss_AddMonitor(struct pipes_struct *p,
9537 struct spoolss_AddMonitor *r)
9539 p->rng_fault_state = true;
9540 return WERR_NOT_SUPPORTED;
9543 /****************************************************************
9544 _spoolss_DeleteMonitor
9545 ****************************************************************/
9547 WERROR _spoolss_DeleteMonitor(struct pipes_struct *p,
9548 struct spoolss_DeleteMonitor *r)
9550 p->rng_fault_state = true;
9551 return WERR_NOT_SUPPORTED;
9554 /****************************************************************
9555 _spoolss_DeletePrintProcessor
9556 ****************************************************************/
9558 WERROR _spoolss_DeletePrintProcessor(struct pipes_struct *p,
9559 struct spoolss_DeletePrintProcessor *r)
9561 p->rng_fault_state = true;
9562 return WERR_NOT_SUPPORTED;
9565 /****************************************************************
9566 _spoolss_AddPrintProvidor
9567 ****************************************************************/
9569 WERROR _spoolss_AddPrintProvidor(struct pipes_struct *p,
9570 struct spoolss_AddPrintProvidor *r)
9572 p->rng_fault_state = true;
9573 return WERR_NOT_SUPPORTED;
9576 /****************************************************************
9577 _spoolss_DeletePrintProvidor
9578 ****************************************************************/
9580 WERROR _spoolss_DeletePrintProvidor(struct pipes_struct *p,
9581 struct spoolss_DeletePrintProvidor *r)
9583 p->rng_fault_state = true;
9584 return WERR_NOT_SUPPORTED;
9587 /****************************************************************
9588 _spoolss_FindFirstPrinterChangeNotification
9589 ****************************************************************/
9591 WERROR _spoolss_FindFirstPrinterChangeNotification(struct pipes_struct *p,
9592 struct spoolss_FindFirstPrinterChangeNotification *r)
9594 p->rng_fault_state = true;
9595 return WERR_NOT_SUPPORTED;
9598 /****************************************************************
9599 _spoolss_FindNextPrinterChangeNotification
9600 ****************************************************************/
9602 WERROR _spoolss_FindNextPrinterChangeNotification(struct pipes_struct *p,
9603 struct spoolss_FindNextPrinterChangeNotification *r)
9605 p->rng_fault_state = true;
9606 return WERR_NOT_SUPPORTED;
9609 /****************************************************************
9610 _spoolss_RouterFindFirstPrinterChangeNotificationOld
9611 ****************************************************************/
9613 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(struct pipes_struct *p,
9614 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
9616 p->rng_fault_state = true;
9617 return WERR_NOT_SUPPORTED;
9620 /****************************************************************
9621 _spoolss_ReplyOpenPrinter
9622 ****************************************************************/
9624 WERROR _spoolss_ReplyOpenPrinter(struct pipes_struct *p,
9625 struct spoolss_ReplyOpenPrinter *r)
9627 p->rng_fault_state = true;
9628 return WERR_NOT_SUPPORTED;
9631 /****************************************************************
9632 _spoolss_RouterReplyPrinter
9633 ****************************************************************/
9635 WERROR _spoolss_RouterReplyPrinter(struct pipes_struct *p,
9636 struct spoolss_RouterReplyPrinter *r)
9638 p->rng_fault_state = true;
9639 return WERR_NOT_SUPPORTED;
9642 /****************************************************************
9643 _spoolss_ReplyClosePrinter
9644 ****************************************************************/
9646 WERROR _spoolss_ReplyClosePrinter(struct pipes_struct *p,
9647 struct spoolss_ReplyClosePrinter *r)
9649 p->rng_fault_state = true;
9650 return WERR_NOT_SUPPORTED;
9653 /****************************************************************
9655 ****************************************************************/
9657 WERROR _spoolss_AddPortEx(struct pipes_struct *p,
9658 struct spoolss_AddPortEx *r)
9660 p->rng_fault_state = true;
9661 return WERR_NOT_SUPPORTED;
9664 /****************************************************************
9665 _spoolss_RouterFindFirstPrinterChangeNotification
9666 ****************************************************************/
9668 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(struct pipes_struct *p,
9669 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
9671 p->rng_fault_state = true;
9672 return WERR_NOT_SUPPORTED;
9675 /****************************************************************
9676 _spoolss_SpoolerInit
9677 ****************************************************************/
9679 WERROR _spoolss_SpoolerInit(struct pipes_struct *p,
9680 struct spoolss_SpoolerInit *r)
9682 p->rng_fault_state = true;
9683 return WERR_NOT_SUPPORTED;
9686 /****************************************************************
9687 _spoolss_ResetPrinterEx
9688 ****************************************************************/
9690 WERROR _spoolss_ResetPrinterEx(struct pipes_struct *p,
9691 struct spoolss_ResetPrinterEx *r)
9693 p->rng_fault_state = true;
9694 return WERR_NOT_SUPPORTED;
9697 /****************************************************************
9698 _spoolss_RouterReplyPrinterEx
9699 ****************************************************************/
9701 WERROR _spoolss_RouterReplyPrinterEx(struct pipes_struct *p,
9702 struct spoolss_RouterReplyPrinterEx *r)
9704 p->rng_fault_state = true;
9705 return WERR_NOT_SUPPORTED;
9708 /****************************************************************
9710 ****************************************************************/
9712 WERROR _spoolss_44(struct pipes_struct *p,
9713 struct spoolss_44 *r)
9715 p->rng_fault_state = true;
9716 return WERR_NOT_SUPPORTED;
9719 /****************************************************************
9721 ****************************************************************/
9723 WERROR _spoolss_47(struct pipes_struct *p,
9724 struct spoolss_47 *r)
9726 p->rng_fault_state = true;
9727 return WERR_NOT_SUPPORTED;
9730 /****************************************************************
9732 ****************************************************************/
9734 WERROR _spoolss_4a(struct pipes_struct *p,
9735 struct spoolss_4a *r)
9737 p->rng_fault_state = true;
9738 return WERR_NOT_SUPPORTED;
9741 /****************************************************************
9743 ****************************************************************/
9745 WERROR _spoolss_4b(struct pipes_struct *p,
9746 struct spoolss_4b *r)
9748 p->rng_fault_state = true;
9749 return WERR_NOT_SUPPORTED;
9752 /****************************************************************
9754 ****************************************************************/
9756 WERROR _spoolss_4c(struct pipes_struct *p,
9757 struct spoolss_4c *r)
9759 p->rng_fault_state = true;
9760 return WERR_NOT_SUPPORTED;
9763 /****************************************************************
9765 ****************************************************************/
9767 WERROR _spoolss_53(struct pipes_struct *p,
9768 struct spoolss_53 *r)
9770 p->rng_fault_state = true;
9771 return WERR_NOT_SUPPORTED;
9774 /****************************************************************
9776 ****************************************************************/
9778 WERROR _spoolss_55(struct pipes_struct *p,
9779 struct spoolss_55 *r)
9781 p->rng_fault_state = true;
9782 return WERR_NOT_SUPPORTED;
9785 /****************************************************************
9787 ****************************************************************/
9789 WERROR _spoolss_56(struct pipes_struct *p,
9790 struct spoolss_56 *r)
9792 p->rng_fault_state = true;
9793 return WERR_NOT_SUPPORTED;
9796 /****************************************************************
9798 ****************************************************************/
9800 WERROR _spoolss_57(struct pipes_struct *p,
9801 struct spoolss_57 *r)
9803 p->rng_fault_state = true;
9804 return WERR_NOT_SUPPORTED;
9807 /****************************************************************
9809 ****************************************************************/
9811 WERROR _spoolss_5a(struct pipes_struct *p,
9812 struct spoolss_5a *r)
9814 p->rng_fault_state = true;
9815 return WERR_NOT_SUPPORTED;
9818 /****************************************************************
9820 ****************************************************************/
9822 WERROR _spoolss_5b(struct pipes_struct *p,
9823 struct spoolss_5b *r)
9825 p->rng_fault_state = true;
9826 return WERR_NOT_SUPPORTED;
9829 /****************************************************************
9831 ****************************************************************/
9833 WERROR _spoolss_5c(struct pipes_struct *p,
9834 struct spoolss_5c *r)
9836 p->rng_fault_state = true;
9837 return WERR_NOT_SUPPORTED;
9840 /****************************************************************
9842 ****************************************************************/
9844 WERROR _spoolss_5d(struct pipes_struct *p,
9845 struct spoolss_5d *r)
9847 p->rng_fault_state = true;
9848 return WERR_NOT_SUPPORTED;
9851 /****************************************************************
9853 ****************************************************************/
9855 WERROR _spoolss_5e(struct pipes_struct *p,
9856 struct spoolss_5e *r)
9858 p->rng_fault_state = true;
9859 return WERR_NOT_SUPPORTED;
9862 /****************************************************************
9864 ****************************************************************/
9866 WERROR _spoolss_5f(struct pipes_struct *p,
9867 struct spoolss_5f *r)
9869 p->rng_fault_state = true;
9870 return WERR_NOT_SUPPORTED;
9873 /****************************************************************
9875 ****************************************************************/
9877 WERROR _spoolss_60(struct pipes_struct *p,
9878 struct spoolss_60 *r)
9880 p->rng_fault_state = true;
9881 return WERR_NOT_SUPPORTED;
9884 /****************************************************************
9886 ****************************************************************/
9888 WERROR _spoolss_61(struct pipes_struct *p,
9889 struct spoolss_61 *r)
9891 p->rng_fault_state = true;
9892 return WERR_NOT_SUPPORTED;
9895 /****************************************************************
9897 ****************************************************************/
9899 WERROR _spoolss_62(struct pipes_struct *p,
9900 struct spoolss_62 *r)
9902 p->rng_fault_state = true;
9903 return WERR_NOT_SUPPORTED;
9906 /****************************************************************
9908 ****************************************************************/
9910 WERROR _spoolss_63(struct pipes_struct *p,
9911 struct spoolss_63 *r)
9913 p->rng_fault_state = true;
9914 return WERR_NOT_SUPPORTED;
9917 /****************************************************************
9919 ****************************************************************/
9921 WERROR _spoolss_64(struct pipes_struct *p,
9922 struct spoolss_64 *r)
9924 p->rng_fault_state = true;
9925 return WERR_NOT_SUPPORTED;
9928 /****************************************************************
9930 ****************************************************************/
9932 WERROR _spoolss_65(struct pipes_struct *p,
9933 struct spoolss_65 *r)
9935 p->rng_fault_state = true;
9936 return WERR_NOT_SUPPORTED;
9939 /****************************************************************
9940 _spoolss_GetCorePrinterDrivers
9941 ****************************************************************/
9943 WERROR _spoolss_GetCorePrinterDrivers(struct pipes_struct *p,
9944 struct spoolss_GetCorePrinterDrivers *r)
9946 p->rng_fault_state = true;
9947 return WERR_NOT_SUPPORTED;
9950 /****************************************************************
9952 ****************************************************************/
9954 WERROR _spoolss_67(struct pipes_struct *p,
9955 struct spoolss_67 *r)
9957 p->rng_fault_state = true;
9958 return WERR_NOT_SUPPORTED;
9961 /****************************************************************
9962 _spoolss_GetPrinterDriverPackagePath
9963 ****************************************************************/
9965 WERROR _spoolss_GetPrinterDriverPackagePath(struct pipes_struct *p,
9966 struct spoolss_GetPrinterDriverPackagePath *r)
9968 p->rng_fault_state = true;
9969 return WERR_NOT_SUPPORTED;
9972 /****************************************************************
9974 ****************************************************************/
9976 WERROR _spoolss_69(struct pipes_struct *p,
9977 struct spoolss_69 *r)
9979 p->rng_fault_state = true;
9980 return WERR_NOT_SUPPORTED;
9983 /****************************************************************
9985 ****************************************************************/
9987 WERROR _spoolss_6a(struct pipes_struct *p,
9988 struct spoolss_6a *r)
9990 p->rng_fault_state = true;
9991 return WERR_NOT_SUPPORTED;
9994 /****************************************************************
9996 ****************************************************************/
9998 WERROR _spoolss_6b(struct pipes_struct *p,
9999 struct spoolss_6b *r)
10001 p->rng_fault_state = true;
10002 return WERR_NOT_SUPPORTED;
10005 /****************************************************************
10007 ****************************************************************/
10009 WERROR _spoolss_6c(struct pipes_struct *p,
10010 struct spoolss_6c *r)
10012 p->rng_fault_state = true;
10013 return WERR_NOT_SUPPORTED;
10016 /****************************************************************
10018 ****************************************************************/
10020 WERROR _spoolss_6d(struct pipes_struct *p,
10021 struct spoolss_6d *r)
10023 p->rng_fault_state = true;
10024 return WERR_NOT_SUPPORTED;