2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
10 * Copyright (C) Guenther Deschner 2009.
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <http://www.gnu.org/licenses/>.
26 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
27 up, all the errors returned are DOS errors, not NT status codes. */
31 /* macros stolen from s4 spoolss server */
32 #define SPOOLSS_BUFFER_UNION(fn,ic,info,level) \
33 ((info)?ndr_size_##fn(info, level, ic, 0):0)
35 #define SPOOLSS_BUFFER_UNION_ARRAY(mem_ctx,fn,ic,info,level,count) \
36 ((info)?ndr_size_##fn##_info(mem_ctx, ic, level, count, info):0)
38 #define SPOOLSS_BUFFER_ARRAY(mem_ctx,fn,ic,info,count) \
39 ((info)?ndr_size_##fn##_info(mem_ctx, ic, count, info):0)
41 #define SPOOLSS_BUFFER_OK(val_true,val_false) ((r->in.offered >= *r->out.needed)?val_true:val_false)
44 extern userdom_struct current_user_info;
47 #define DBGC_CLASS DBGC_RPC_SRV
49 #ifndef MAX_OPEN_PRINTER_EXS
50 #define MAX_OPEN_PRINTER_EXS 50
53 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
54 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
56 static Printer_entry *printers_list;
58 typedef struct _counter_printer_0 {
59 struct _counter_printer_0 *next;
60 struct _counter_printer_0 *prev;
66 static counter_printer_0 *counter_list;
68 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
69 static uint32_t smb_connections = 0;
72 /* in printing/nt_printing.c */
74 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
76 /* API table for Xcv Monitor functions */
78 struct xcv_api_table {
80 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
83 /********************************************************************
84 * Canonicalize servername.
85 ********************************************************************/
87 static const char *canon_servername(const char *servername)
89 const char *pservername = servername;
90 while (*pservername == '\\') {
96 /* translate between internal status numbers and NT status numbers */
97 static int nt_printj_status(int v)
103 return JOB_STATUS_PAUSED;
105 return JOB_STATUS_SPOOLING;
107 return JOB_STATUS_PRINTING;
109 return JOB_STATUS_ERROR;
111 return JOB_STATUS_DELETING;
113 return JOB_STATUS_OFFLINE;
115 return JOB_STATUS_PAPEROUT;
117 return JOB_STATUS_PRINTED;
119 return JOB_STATUS_DELETED;
121 return JOB_STATUS_BLOCKED_DEVQ;
122 case LPQ_USER_INTERVENTION:
123 return JOB_STATUS_USER_INTERVENTION;
128 static int nt_printq_status(int v)
132 return PRINTER_STATUS_PAUSED;
141 /***************************************************************************
142 Disconnect from the client
143 ****************************************************************************/
145 static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle)
151 * Tell the specific printing tdb we no longer want messages for this printer
152 * by deregistering our PID.
155 if (!print_notify_deregister_pid(snum))
156 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
158 /* weird if the test succeds !!! */
159 if (smb_connections==0) {
160 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
164 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
167 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
168 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
169 win_errstr(result)));
171 /* if it's the last connection, deconnect the IPC$ share */
172 if (smb_connections==1) {
174 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
175 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
177 messaging_deregister(smbd_messaging_context(),
178 MSG_PRINTER_NOTIFY2, NULL);
180 /* Tell the connections db we're no longer interested in
181 * printer notify messages. */
183 register_message_flags(false, FLAG_MSG_PRINT_NOTIFY);
189 /****************************************************************************
190 Functions to free a printer entry datastruct.
191 ****************************************************************************/
193 static int printer_entry_destructor(Printer_entry *Printer)
195 if (Printer->notify.client_connected == true) {
198 if ( Printer->printer_type == SPLHND_SERVER) {
200 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
201 } else if (Printer->printer_type == SPLHND_PRINTER) {
202 snum = print_queue_snum(Printer->sharename);
204 srv_spoolss_replycloseprinter(snum,
205 &Printer->notify.client_hnd);
209 Printer->notify.flags=0;
210 Printer->notify.options=0;
211 Printer->notify.localmachine[0]='\0';
212 Printer->notify.printerlocal=0;
213 TALLOC_FREE(Printer->notify.option);
214 Printer->notify.client_connected = false;
216 free_nt_devicemode( &Printer->nt_devmode );
217 free_a_printer( &Printer->printer_info, 2 );
219 /* Remove from the internal list. */
220 DLIST_REMOVE(printers_list, Printer);
224 /****************************************************************************
225 find printer index by handle
226 ****************************************************************************/
228 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p,
229 struct policy_handle *hnd)
231 Printer_entry *find_printer = NULL;
233 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
234 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
241 /****************************************************************************
242 Close printer index by handle.
243 ****************************************************************************/
245 static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd)
247 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
250 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n",
255 close_policy_hnd(p, hnd);
260 /****************************************************************************
261 Delete a printer given a handle.
262 ****************************************************************************/
264 static WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename)
266 char *cmd = lp_deleteprinter_cmd();
267 char *command = NULL;
269 SE_PRIV se_printop = SE_PRINT_OPERATOR;
270 bool is_print_op = false;
272 /* can't fail if we don't try */
277 command = talloc_asprintf(ctx,
284 is_print_op = user_has_privileges( token, &se_printop );
286 DEBUG(10,("Running [%s]\n", command));
288 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
293 if ( (ret = smbrun(command, NULL)) == 0 ) {
294 /* Tell everyone we updated smb.conf. */
295 message_send_all(smbd_messaging_context(),
296 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
302 /********** END SePrintOperatorPrivlege BLOCK **********/
304 DEBUGADD(10,("returned [%d]\n", ret));
306 TALLOC_FREE(command);
309 return WERR_BADFID; /* What to return here? */
311 /* go ahead and re-read the services immediately */
313 reload_services(false);
316 if ( lp_servicenumber( sharename ) < 0 )
317 return WERR_ACCESS_DENIED;
322 /****************************************************************************
323 Delete a printer given a handle.
324 ****************************************************************************/
326 static WERROR delete_printer_handle(pipes_struct *p, struct policy_handle *hnd)
328 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
331 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n",
337 * It turns out that Windows allows delete printer on a handle
338 * opened by an admin user, then used on a pipe handle created
339 * by an anonymous user..... but they're working on security.... riiight !
343 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
344 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
345 return WERR_ACCESS_DENIED;
348 /* this does not need a become root since the access check has been
349 done on the handle already */
351 if (del_a_printer( Printer->sharename ) != 0) {
352 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
356 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
357 Printer->sharename );
360 /****************************************************************************
361 Return the snum of a printer corresponding to an handle.
362 ****************************************************************************/
364 static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd,
365 int *number, struct share_params **params)
367 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
370 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n",
375 switch (Printer->printer_type) {
377 DEBUG(4,("short name:%s\n", Printer->sharename));
378 *number = print_queue_snum(Printer->sharename);
379 return (*number != -1);
387 /****************************************************************************
388 Set printer handle type.
389 Check if it's \\server or \\server\printer
390 ****************************************************************************/
392 static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename)
394 DEBUG(3,("Setting printer type=%s\n", handlename));
396 if ( strlen(handlename) < 3 ) {
397 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
401 /* it's a print server */
402 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
403 DEBUGADD(4,("Printer is a print server\n"));
404 Printer->printer_type = SPLHND_SERVER;
406 /* it's a printer (set_printer_hnd_name() will handle port monitors */
408 DEBUGADD(4,("Printer is a printer\n"));
409 Printer->printer_type = SPLHND_PRINTER;
415 /****************************************************************************
416 Set printer handle name.. Accept names like \\server, \\server\printer,
417 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
418 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
419 XcvDataPort() interface.
420 ****************************************************************************/
422 static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename)
425 int n_services=lp_numservices();
426 char *aprinter, *printername;
427 const char *servername;
430 NT_PRINTER_INFO_LEVEL *printer = NULL;
433 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename,
434 (unsigned long)strlen(handlename)));
436 aprinter = CONST_DISCARD(char *, handlename);
437 if ( *handlename == '\\' ) {
438 servername = canon_servername(handlename);
439 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
444 servername = global_myname();
447 /* save the servername to fill in replies on this handle */
449 if ( !is_myname_or_ipaddr( servername ) )
452 fstrcpy( Printer->servername, servername );
454 if ( Printer->printer_type == SPLHND_SERVER )
457 if ( Printer->printer_type != SPLHND_PRINTER )
460 DEBUGADD(5, ("searching for [%s]\n", aprinter ));
462 /* check for the Port Monitor Interface */
464 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
465 Printer->printer_type = SPLHND_PORTMON_TCP;
466 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
469 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
470 Printer->printer_type = SPLHND_PORTMON_LOCAL;
471 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
475 /* Search all sharenames first as this is easier than pulling
476 the printer_info_2 off of disk. Don't use find_service() since
477 that calls out to map_username() */
479 /* do another loop to look for printernames */
481 for (snum=0; !found && snum<n_services; snum++) {
483 /* no point going on if this is not a printer */
485 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
488 fstrcpy(sname, lp_servicename(snum));
489 if ( strequal( aprinter, sname ) ) {
494 /* no point looking up the printer object if
495 we aren't allowing printername != sharename */
497 if ( lp_force_printername(snum) )
500 fstrcpy(sname, lp_servicename(snum));
504 /* This call doesn't fill in the location or comment from
505 * a CUPS server for efficiency with large numbers of printers.
509 result = get_a_printer_search( NULL, &printer, 2, sname );
510 if ( !W_ERROR_IS_OK(result) ) {
511 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
512 sname, win_errstr(result)));
516 /* printername is always returned as \\server\printername */
517 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
518 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
519 printer->info_2->printername));
520 free_a_printer( &printer, 2);
526 if ( strequal(printername, aprinter) ) {
527 free_a_printer( &printer, 2);
532 DEBUGADD(10, ("printername: %s\n", printername));
534 free_a_printer( &printer, 2);
537 free_a_printer( &printer, 2);
540 DEBUGADD(4,("Printer not found\n"));
544 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
546 fstrcpy(Printer->sharename, sname);
551 /****************************************************************************
552 Find first available printer slot. creates a printer handle for you.
553 ****************************************************************************/
555 static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd,
556 const char *name, uint32_t access_granted)
558 Printer_entry *new_printer;
560 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
562 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
563 if (new_printer == NULL) {
566 talloc_set_destructor(new_printer, printer_entry_destructor);
568 if (!create_policy_hnd(p, hnd, new_printer)) {
569 TALLOC_FREE(new_printer);
573 /* Add to the internal list. */
574 DLIST_ADD(printers_list, new_printer);
576 new_printer->notify.option=NULL;
578 if (!set_printer_hnd_printertype(new_printer, name)) {
579 close_printer_handle(p, hnd);
583 if (!set_printer_hnd_name(new_printer, name)) {
584 close_printer_handle(p, hnd);
588 new_printer->access_granted = access_granted;
590 DEBUG(5, ("%d printer handles active\n",
591 (int)num_pipe_handles(p->pipe_handles)));
596 /***************************************************************************
597 check to see if the client motify handle is monitoring the notification
598 given by (notify_type, notify_field).
599 **************************************************************************/
601 static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type,
602 uint16_t notify_field)
607 static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type,
608 uint16_t notify_field)
610 struct spoolss_NotifyOption *option = p->notify.option;
614 * Flags should always be zero when the change notify
615 * is registered by the client's spooler. A user Win32 app
616 * might use the flags though instead of the NOTIFY_OPTION_INFO
625 return is_monitoring_event_flags(
626 p->notify.flags, notify_type, notify_field);
628 for (i = 0; i < option->count; i++) {
630 /* Check match for notify_type */
632 if (option->types[i].type != notify_type)
635 /* Check match for field */
637 for (j = 0; j < option->types[i].count; j++) {
638 if (option->types[i].fields[j].field == notify_field) {
644 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
645 p->servername, p->sharename, notify_type, notify_field));
650 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
651 _data->data.integer[0] = _integer; \
652 _data->data.integer[1] = 0;
655 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
656 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
657 if (!_data->data.string.string) {\
658 _data->data.string.size = 0; \
660 _data->data.string.size = strlen_m_term(_p) * 2;
662 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
663 _data->data.devmode.devmode = _devmode;
665 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
666 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
667 if (!_data->data.sd.sd) { \
668 _data->data.sd.sd_size = 0; \
670 _data->data.sd.sd_size = _size;
672 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
677 struct spoolss_Time st;
681 if (!init_systemtime(&st, t)) {
685 p = talloc_array(mem_ctx, char, len);
691 * Systemtime must be linearized as a set of UINT16's.
692 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
695 SSVAL(p, 0, st.year);
696 SSVAL(p, 2, st.month);
697 SSVAL(p, 4, st.day_of_week);
699 SSVAL(p, 8, st.hour);
700 SSVAL(p, 10, st.minute);
701 SSVAL(p, 12, st.second);
702 SSVAL(p, 14, st.millisecond);
708 /* Convert a notification message to a struct spoolss_Notify */
710 static void notify_one_value(struct spoolss_notify_msg *msg,
711 struct spoolss_Notify *data,
714 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
717 static void notify_string(struct spoolss_notify_msg *msg,
718 struct spoolss_Notify *data,
721 /* The length of the message includes the trailing \0 */
723 data->data.string.size = msg->len * 2;
724 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
725 if (!data->data.string.string) {
726 data->data.string.size = 0;
731 static void notify_system_time(struct spoolss_notify_msg *msg,
732 struct spoolss_Notify *data,
735 data->data.string.string = NULL;
736 data->data.string.size = 0;
738 if (msg->len != sizeof(time_t)) {
739 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
744 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
745 &data->data.string.string,
746 &data->data.string.size);
749 struct notify2_message_table {
751 void (*fn)(struct spoolss_notify_msg *msg,
752 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
755 static struct notify2_message_table printer_notify_table[] = {
756 /* 0x00 */ { "PRINTER_NOTIFY_FIELD_SERVER_NAME", notify_string },
757 /* 0x01 */ { "PRINTER_NOTIFY_FIELD_PRINTER_NAME", notify_string },
758 /* 0x02 */ { "PRINTER_NOTIFY_FIELD_SHARE_NAME", notify_string },
759 /* 0x03 */ { "PRINTER_NOTIFY_FIELD_PORT_NAME", notify_string },
760 /* 0x04 */ { "PRINTER_NOTIFY_FIELD_DRIVER_NAME", notify_string },
761 /* 0x05 */ { "PRINTER_NOTIFY_FIELD_COMMENT", notify_string },
762 /* 0x06 */ { "PRINTER_NOTIFY_FIELD_LOCATION", notify_string },
763 /* 0x07 */ { "PRINTER_NOTIFY_FIELD_DEVMODE", NULL },
764 /* 0x08 */ { "PRINTER_NOTIFY_FIELD_SEPFILE", notify_string },
765 /* 0x09 */ { "PRINTER_NOTIFY_FIELD_PRINT_PROCESSOR", notify_string },
766 /* 0x0a */ { "PRINTER_NOTIFY_FIELD_PARAMETERS", NULL },
767 /* 0x0b */ { "PRINTER_NOTIFY_FIELD_DATATYPE", notify_string },
768 /* 0x0c */ { "PRINTER_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
769 /* 0x0d */ { "PRINTER_NOTIFY_FIELD_ATTRIBUTES", notify_one_value },
770 /* 0x0e */ { "PRINTER_NOTIFY_FIELD_PRIORITY", notify_one_value },
771 /* 0x0f */ { "PRINTER_NOTIFY_FIELD_DEFAULT_PRIORITY", NULL },
772 /* 0x10 */ { "PRINTER_NOTIFY_FIELD_START_TIME", NULL },
773 /* 0x11 */ { "PRINTER_NOTIFY_FIELD_UNTIL_TIME", NULL },
774 /* 0x12 */ { "PRINTER_NOTIFY_FIELD_STATUS", notify_one_value },
777 static struct notify2_message_table job_notify_table[] = {
778 /* 0x00 */ { "JOB_NOTIFY_FIELD_PRINTER_NAME", NULL },
779 /* 0x01 */ { "JOB_NOTIFY_FIELD_MACHINE_NAME", NULL },
780 /* 0x02 */ { "JOB_NOTIFY_FIELD_PORT_NAME", NULL },
781 /* 0x03 */ { "JOB_NOTIFY_FIELD_USER_NAME", notify_string },
782 /* 0x04 */ { "JOB_NOTIFY_FIELD_NOTIFY_NAME", NULL },
783 /* 0x05 */ { "JOB_NOTIFY_FIELD_DATATYPE", NULL },
784 /* 0x06 */ { "JOB_NOTIFY_FIELD_PRINT_PROCESSOR", NULL },
785 /* 0x07 */ { "JOB_NOTIFY_FIELD_PARAMETERS", NULL },
786 /* 0x08 */ { "JOB_NOTIFY_FIELD_DRIVER_NAME", NULL },
787 /* 0x09 */ { "JOB_NOTIFY_FIELD_DEVMODE", NULL },
788 /* 0x0a */ { "JOB_NOTIFY_FIELD_STATUS", notify_one_value },
789 /* 0x0b */ { "JOB_NOTIFY_FIELD_STATUS_STRING", NULL },
790 /* 0x0c */ { "JOB_NOTIFY_FIELD_SECURITY_DESCRIPTOR", NULL },
791 /* 0x0d */ { "JOB_NOTIFY_FIELD_DOCUMENT", notify_string },
792 /* 0x0e */ { "JOB_NOTIFY_FIELD_PRIORITY", NULL },
793 /* 0x0f */ { "JOB_NOTIFY_FIELD_POSITION", NULL },
794 /* 0x10 */ { "JOB_NOTIFY_FIELD_SUBMITTED", notify_system_time },
795 /* 0x11 */ { "JOB_NOTIFY_FIELD_START_TIME", NULL },
796 /* 0x12 */ { "JOB_NOTIFY_FIELD_UNTIL_TIME", NULL },
797 /* 0x13 */ { "JOB_NOTIFY_FIELD_TIME", NULL },
798 /* 0x14 */ { "JOB_NOTIFY_FIELD_TOTAL_PAGES", notify_one_value },
799 /* 0x15 */ { "JOB_NOTIFY_FIELD_PAGES_PRINTED", NULL },
800 /* 0x16 */ { "JOB_NOTIFY_FIELD_TOTAL_BYTES", notify_one_value },
801 /* 0x17 */ { "JOB_NOTIFY_FIELD_BYTES_PRINTED", NULL },
805 /***********************************************************************
806 Allocate talloc context for container object
807 **********************************************************************/
809 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
814 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
819 /***********************************************************************
820 release all allocated memory and zero out structure
821 **********************************************************************/
823 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
829 talloc_destroy(ctr->ctx);
836 /***********************************************************************
837 **********************************************************************/
839 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
847 /***********************************************************************
848 **********************************************************************/
850 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
852 if ( !ctr || !ctr->msg_groups )
855 if ( idx >= ctr->num_groups )
858 return &ctr->msg_groups[idx];
862 /***********************************************************************
863 How many groups of change messages do we have ?
864 **********************************************************************/
866 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
871 return ctr->num_groups;
874 /***********************************************************************
875 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
876 **********************************************************************/
878 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
880 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
881 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
882 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
888 /* loop over all groups looking for a matching printer name */
890 for ( i=0; i<ctr->num_groups; i++ ) {
891 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
895 /* add a new group? */
897 if ( i == ctr->num_groups ) {
900 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
901 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
904 ctr->msg_groups = groups;
906 /* clear the new entry and set the printer name */
908 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
909 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
912 /* add the change messages; 'i' is the correct index now regardless */
914 msg_grp = &ctr->msg_groups[i];
918 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
919 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
922 msg_grp->msgs = msg_list;
924 new_slot = msg_grp->num_msgs-1;
925 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
927 /* need to allocate own copy of data */
930 msg_grp->msgs[new_slot].notify.data = (char *)
931 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
933 return ctr->num_groups;
936 /***********************************************************************
937 Send a change notication message on all handles which have a call
939 **********************************************************************/
941 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx )
944 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
945 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
946 SPOOLSS_NOTIFY_MSG *messages;
947 int sending_msg_count;
950 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
954 messages = msg_group->msgs;
957 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
961 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
963 /* loop over all printers */
965 for (p = printers_list; p; p = p->next) {
966 struct spoolss_Notify *notifies;
971 /* Is there notification on this handle? */
973 if ( !p->notify.client_connected )
976 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
978 /* For this printer? Print servers always receive
981 if ( ( p->printer_type == SPLHND_PRINTER ) &&
982 ( !strequal(msg_group->printername, p->sharename) ) )
985 DEBUG(10,("Our printer\n"));
987 /* allocate the max entries possible */
989 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
994 /* build the array of change notifications */
996 sending_msg_count = 0;
998 for ( i=0; i<msg_group->num_msgs; i++ ) {
999 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1001 /* Are we monitoring this event? */
1003 if (!is_monitoring_event(p, msg->type, msg->field))
1006 sending_msg_count++;
1009 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1010 msg->type, msg->field, p->sharename));
1013 * if the is a printer notification handle and not a job notification
1014 * type, then set the id to 0. Other wise just use what was specified
1017 * When registering change notification on a print server handle
1018 * we always need to send back the id (snum) matching the printer
1019 * for which the change took place. For change notify registered
1020 * on a printer handle, this does not matter and the id should be 0.
1025 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1031 /* Convert unix jobid to smb jobid */
1033 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1034 id = sysjob_to_jobid(msg->id);
1037 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1042 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1045 case PRINTER_NOTIFY_TYPE:
1046 if ( printer_notify_table[msg->field].fn )
1047 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1050 case JOB_NOTIFY_TYPE:
1051 if ( job_notify_table[msg->field].fn )
1052 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1056 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1063 if ( sending_msg_count ) {
1066 union spoolss_ReplyPrinterInfo info;
1067 struct spoolss_NotifyInfo info0;
1068 uint32_t reply_result;
1070 info0.version = 0x2;
1071 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1072 info0.count = count;
1073 info0.notifies = notifies;
1075 info.info0 = &info0;
1077 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1078 &p->notify.client_hnd,
1079 p->notify.change, /* color */
1082 0, /* reply_type, must be 0 */
1085 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1086 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1087 notify_cli_pipe->srv_name_slash,
1090 switch (reply_result) {
1093 case PRINTER_NOTIFY_INFO_DISCARDED:
1094 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1095 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1104 DEBUG(8,("send_notify2_changes: Exit...\n"));
1108 /***********************************************************************
1109 **********************************************************************/
1111 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1114 uint32_t tv_sec, tv_usec;
1117 /* Unpack message */
1119 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f",
1122 offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd",
1124 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1127 tdb_unpack((uint8_t *)buf + offset, len - offset, "dd",
1128 &msg->notify.value[0], &msg->notify.value[1]);
1130 tdb_unpack((uint8_t *)buf + offset, len - offset, "B",
1131 &msg->len, &msg->notify.data);
1133 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1134 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1136 tv->tv_sec = tv_sec;
1137 tv->tv_usec = tv_usec;
1140 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1141 msg->notify.value[1]));
1143 dump_data(3, (uint8_t *)msg->notify.data, msg->len);
1148 /********************************************************************
1149 Receive a notify2 message list
1150 ********************************************************************/
1152 static void receive_notify2_message_list(struct messaging_context *msg,
1155 struct server_id server_id,
1158 size_t msg_count, i;
1159 char *buf = (char *)data->data;
1162 SPOOLSS_NOTIFY_MSG notify;
1163 SPOOLSS_NOTIFY_MSG_CTR messages;
1166 if (data->length < 4) {
1167 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1171 msg_count = IVAL(buf, 0);
1174 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1176 if (msg_count == 0) {
1177 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1181 /* initialize the container */
1183 ZERO_STRUCT( messages );
1184 notify_msg_ctr_init( &messages );
1187 * build message groups for each printer identified
1188 * in a change_notify msg. Remember that a PCN message
1189 * includes the handle returned for the srv_spoolss_replyopenprinter()
1190 * call. Therefore messages are grouped according to printer handle.
1193 for ( i=0; i<msg_count; i++ ) {
1194 struct timeval msg_tv;
1196 if (msg_ptr + 4 - buf > data->length) {
1197 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1201 msg_len = IVAL(msg_ptr,0);
1204 if (msg_ptr + msg_len - buf > data->length) {
1205 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1209 /* unpack messages */
1211 ZERO_STRUCT( notify );
1212 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1215 /* add to correct list in container */
1217 notify_msg_ctr_addmsg( &messages, ¬ify );
1219 /* free memory that might have been allocated by notify2_unpack_msg() */
1221 if ( notify.len != 0 )
1222 SAFE_FREE( notify.notify.data );
1225 /* process each group of messages */
1227 num_groups = notify_msg_ctr_numgroups( &messages );
1228 for ( i=0; i<num_groups; i++ )
1229 send_notify2_changes( &messages, i );
1234 DEBUG(10,("receive_notify2_message_list: processed %u messages\n",
1235 (uint32_t)msg_count ));
1237 notify_msg_ctr_destroy( &messages );
1242 /********************************************************************
1243 Send a message to ourself about new driver being installed
1244 so we can upgrade the information for each printer bound to this
1246 ********************************************************************/
1248 static bool srv_spoolss_drv_upgrade_printer(const char *drivername)
1250 int len = strlen(drivername);
1255 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1258 messaging_send_buf(smbd_messaging_context(), procid_self(),
1259 MSG_PRINTER_DRVUPGRADE,
1260 (uint8_t *)drivername, len+1);
1265 /**********************************************************************
1266 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1267 over all printers, upgrading ones as necessary
1268 **********************************************************************/
1270 void do_drv_upgrade_printer(struct messaging_context *msg,
1273 struct server_id server_id,
1278 int n_services = lp_numservices();
1281 len = MIN(data->length,sizeof(drivername)-1);
1282 strncpy(drivername, (const char *)data->data, len);
1284 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1286 /* Iterate the printer list */
1288 for (snum=0; snum<n_services; snum++)
1290 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1293 NT_PRINTER_INFO_LEVEL *printer = NULL;
1295 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1296 if (!W_ERROR_IS_OK(result))
1299 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1301 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1303 /* all we care about currently is the change_id */
1305 result = mod_a_printer(printer, 2);
1306 if (!W_ERROR_IS_OK(result)) {
1307 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1308 win_errstr(result)));
1312 free_a_printer(&printer, 2);
1319 /********************************************************************
1320 Update the cache for all printq's with a registered client
1322 ********************************************************************/
1324 void update_monitored_printq_cache( void )
1326 Printer_entry *printer = printers_list;
1329 /* loop through all printers and update the cache where
1330 client_connected == true */
1333 if ( (printer->printer_type == SPLHND_PRINTER)
1334 && printer->notify.client_connected )
1336 snum = print_queue_snum(printer->sharename);
1337 print_queue_status( snum, NULL, NULL );
1340 printer = printer->next;
1345 /********************************************************************
1346 Send a message to ourself about new driver being installed
1347 so we can upgrade the information for each printer bound to this
1349 ********************************************************************/
1351 static bool srv_spoolss_reset_printerdata(char* drivername)
1353 int len = strlen(drivername);
1358 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1361 messaging_send_buf(smbd_messaging_context(), procid_self(),
1362 MSG_PRINTERDATA_INIT_RESET,
1363 (uint8_t *)drivername, len+1);
1368 /**********************************************************************
1369 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1370 over all printers, resetting printer data as neessary
1371 **********************************************************************/
1373 void reset_all_printerdata(struct messaging_context *msg,
1376 struct server_id server_id,
1381 int n_services = lp_numservices();
1384 len = MIN( data->length, sizeof(drivername)-1 );
1385 strncpy( drivername, (const char *)data->data, len );
1387 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1389 /* Iterate the printer list */
1391 for ( snum=0; snum<n_services; snum++ )
1393 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1396 NT_PRINTER_INFO_LEVEL *printer = NULL;
1398 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1399 if ( !W_ERROR_IS_OK(result) )
1403 * if the printer is bound to the driver,
1404 * then reset to the new driver initdata
1407 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1409 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1411 if ( !set_driver_init(printer, 2) ) {
1412 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1413 printer->info_2->printername, printer->info_2->drivername));
1416 result = mod_a_printer( printer, 2 );
1417 if ( !W_ERROR_IS_OK(result) ) {
1418 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1419 get_dos_error_msg(result)));
1423 free_a_printer( &printer, 2 );
1432 /****************************************************************
1433 _spoolss_OpenPrinter
1434 ****************************************************************/
1436 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1437 struct spoolss_OpenPrinter *r)
1439 struct spoolss_OpenPrinterEx e;
1442 ZERO_STRUCT(e.in.userlevel);
1444 e.in.printername = r->in.printername;
1445 e.in.datatype = r->in.datatype;
1446 e.in.devmode_ctr = r->in.devmode_ctr;
1447 e.in.access_mask = r->in.access_mask;
1450 e.out.handle = r->out.handle;
1452 werr = _spoolss_OpenPrinterEx(p, &e);
1454 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1455 /* OpenPrinterEx returns this for a bad
1456 * printer name. We must return WERR_INVALID_PRINTER_NAME
1459 werr = WERR_INVALID_PRINTER_NAME;
1465 /********************************************************************
1466 ********************************************************************/
1468 bool convert_devicemode(const char *printername,
1469 const struct spoolss_DeviceMode *devmode,
1470 NT_DEVICEMODE **pp_nt_devmode)
1472 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1475 * Ensure nt_devmode is a valid pointer
1476 * as we will be overwriting it.
1479 if (nt_devmode == NULL) {
1480 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1481 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1485 rpcstr_push(nt_devmode->devicename, devmode->devicename, 31, 0);
1486 rpcstr_push(nt_devmode->formname, devmode->formname, 31, 0);
1488 nt_devmode->specversion = devmode->specversion;
1489 nt_devmode->driverversion = devmode->driverversion;
1490 nt_devmode->size = devmode->size;
1491 nt_devmode->fields = devmode->fields;
1492 nt_devmode->orientation = devmode->orientation;
1493 nt_devmode->papersize = devmode->papersize;
1494 nt_devmode->paperlength = devmode->paperlength;
1495 nt_devmode->paperwidth = devmode->paperwidth;
1496 nt_devmode->scale = devmode->scale;
1497 nt_devmode->copies = devmode->copies;
1498 nt_devmode->defaultsource = devmode->defaultsource;
1499 nt_devmode->printquality = devmode->printquality;
1500 nt_devmode->color = devmode->color;
1501 nt_devmode->duplex = devmode->duplex;
1502 nt_devmode->yresolution = devmode->yresolution;
1503 nt_devmode->ttoption = devmode->ttoption;
1504 nt_devmode->collate = devmode->collate;
1506 nt_devmode->logpixels = devmode->logpixels;
1507 nt_devmode->bitsperpel = devmode->bitsperpel;
1508 nt_devmode->pelswidth = devmode->pelswidth;
1509 nt_devmode->pelsheight = devmode->pelsheight;
1510 nt_devmode->displayflags = devmode->displayflags;
1511 nt_devmode->displayfrequency = devmode->displayfrequency;
1512 nt_devmode->icmmethod = devmode->icmmethod;
1513 nt_devmode->icmintent = devmode->icmintent;
1514 nt_devmode->mediatype = devmode->mediatype;
1515 nt_devmode->dithertype = devmode->dithertype;
1516 nt_devmode->reserved1 = devmode->reserved1;
1517 nt_devmode->reserved2 = devmode->reserved2;
1518 nt_devmode->panningwidth = devmode->panningwidth;
1519 nt_devmode->panningheight = devmode->panningheight;
1522 * Only change private and driverextra if the incoming devmode
1523 * has a new one. JRA.
1526 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1527 SAFE_FREE(nt_devmode->nt_dev_private);
1528 nt_devmode->driverextra = devmode->__driverextra_length;
1529 if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL)
1531 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1534 *pp_nt_devmode = nt_devmode;
1539 /****************************************************************
1540 _spoolss_OpenPrinterEx
1541 ****************************************************************/
1543 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1544 struct spoolss_OpenPrinterEx *r)
1547 Printer_entry *Printer=NULL;
1549 if (!r->in.printername) {
1550 return WERR_INVALID_PARAM;
1553 /* some sanity check because you can open a printer or a print server */
1554 /* aka: \\server\printer or \\server */
1556 DEBUGADD(3,("checking name: %s\n", r->in.printername));
1558 if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) {
1559 ZERO_STRUCTP(r->out.handle);
1560 return WERR_INVALID_PARAM;
1563 Printer = find_printer_index_by_hnd(p, r->out.handle);
1565 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1566 "handle we created for printer %s\n", r->in.printername));
1567 close_printer_handle(p, r->out.handle);
1568 ZERO_STRUCTP(r->out.handle);
1569 return WERR_INVALID_PARAM;
1573 * First case: the user is opening the print server:
1575 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1576 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1578 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1579 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1580 * or if the user is listed in the smb.conf printer admin parameter.
1582 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1583 * client view printer folder, but does not show the MSAPW.
1585 * Note: this test needs code to check access rights here too. Jeremy
1586 * could you look at this?
1588 * Second case: the user is opening a printer:
1589 * NT doesn't let us connect to a printer if the connecting user
1590 * doesn't have print permission.
1592 * Third case: user is opening a Port Monitor
1593 * access checks same as opening a handle to the print server.
1596 switch (Printer->printer_type )
1599 case SPLHND_PORTMON_TCP:
1600 case SPLHND_PORTMON_LOCAL:
1601 /* Printserver handles use global struct... */
1605 /* Map standard access rights to object specific access rights */
1607 se_map_standard(&r->in.access_mask,
1608 &printserver_std_mapping);
1610 /* Deny any object specific bits that don't apply to print
1611 servers (i.e printer and job specific bits) */
1613 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1615 if (r->in.access_mask &
1616 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1617 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1618 close_printer_handle(p, r->out.handle);
1619 ZERO_STRUCTP(r->out.handle);
1620 return WERR_ACCESS_DENIED;
1623 /* Allow admin access */
1625 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1627 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1629 if (!lp_ms_add_printer_wizard()) {
1630 close_printer_handle(p, r->out.handle);
1631 ZERO_STRUCTP(r->out.handle);
1632 return WERR_ACCESS_DENIED;
1635 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1636 and not a printer admin, then fail */
1638 if ((p->server_info->utok.uid != sec_initial_uid()) &&
1639 !user_has_privileges(p->server_info->ptok,
1641 !token_contains_name_in_list(
1642 uidtoname(p->server_info->utok.uid),
1644 p->server_info->ptok,
1645 lp_printer_admin(snum))) {
1646 close_printer_handle(p, r->out.handle);
1647 ZERO_STRUCTP(r->out.handle);
1648 return WERR_ACCESS_DENIED;
1651 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1655 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1658 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1659 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1661 /* We fall through to return WERR_OK */
1664 case SPLHND_PRINTER:
1665 /* NT doesn't let us connect to a printer if the connecting user
1666 doesn't have print permission. */
1668 if (!get_printer_snum(p, r->out.handle, &snum, NULL)) {
1669 close_printer_handle(p, r->out.handle);
1670 ZERO_STRUCTP(r->out.handle);
1674 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1676 /* map an empty access mask to the minimum access mask */
1677 if (r->in.access_mask == 0x0)
1678 r->in.access_mask = PRINTER_ACCESS_USE;
1681 * If we are not serving the printer driver for this printer,
1682 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1683 * will keep NT clients happy --jerry
1686 if (lp_use_client_driver(snum)
1687 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1689 r->in.access_mask = PRINTER_ACCESS_USE;
1692 /* check smb.conf parameters and the the sec_desc */
1694 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1695 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1696 ZERO_STRUCTP(r->out.handle);
1697 return WERR_ACCESS_DENIED;
1700 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1701 p->server_info->ptok, snum) ||
1702 !print_access_check(p->server_info, snum,
1703 r->in.access_mask)) {
1704 DEBUG(3, ("access DENIED for printer open\n"));
1705 close_printer_handle(p, r->out.handle);
1706 ZERO_STRUCTP(r->out.handle);
1707 return WERR_ACCESS_DENIED;
1710 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1711 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1712 close_printer_handle(p, r->out.handle);
1713 ZERO_STRUCTP(r->out.handle);
1714 return WERR_ACCESS_DENIED;
1717 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1718 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1720 r->in.access_mask = PRINTER_ACCESS_USE;
1722 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1723 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1728 /* sanity check to prevent programmer error */
1729 ZERO_STRUCTP(r->out.handle);
1733 Printer->access_granted = r->in.access_mask;
1736 * If the client sent a devmode in the OpenPrinter() call, then
1737 * save it here in case we get a job submission on this handle
1740 if ((Printer->printer_type != SPLHND_SERVER) &&
1741 r->in.devmode_ctr.devmode) {
1742 convert_devicemode(Printer->sharename,
1743 r->in.devmode_ctr.devmode,
1744 &Printer->nt_devmode);
1747 #if 0 /* JERRY -- I'm doubtful this is really effective */
1748 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1749 optimization in Windows 2000 clients --jerry */
1751 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1752 && (RA_WIN2K == get_remote_arch()) )
1754 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1755 sys_usleep( 500000 );
1762 /****************************************************************************
1763 ****************************************************************************/
1765 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1766 NT_PRINTER_INFO_LEVEL_2 *d)
1768 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1774 d->attributes = r->attributes;
1775 d->priority = r->priority;
1776 d->default_priority = r->defaultpriority;
1777 d->starttime = r->starttime;
1778 d->untiltime = r->untiltime;
1779 d->status = r->status;
1780 d->cjobs = r->cjobs;
1782 fstrcpy(d->servername, r->servername);
1783 fstrcpy(d->printername, r->printername);
1784 fstrcpy(d->sharename, r->sharename);
1785 fstrcpy(d->portname, r->portname);
1786 fstrcpy(d->drivername, r->drivername);
1787 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1788 fstrcpy(d->location, r->location);
1789 fstrcpy(d->sepfile, r->sepfile);
1790 fstrcpy(d->printprocessor, r->printprocessor);
1791 fstrcpy(d->datatype, r->datatype);
1792 fstrcpy(d->parameters, r->parameters);
1797 /****************************************************************************
1798 ****************************************************************************/
1800 static bool convert_printer_info(struct spoolss_SetPrinterInfoCtr *info_ctr,
1801 NT_PRINTER_INFO_LEVEL *printer)
1805 switch (info_ctr->level) {
1807 /* allocate memory if needed. Messy because
1808 convert_printer_info is used to update an existing
1809 printer or build a new one */
1811 if (!printer->info_2) {
1812 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1813 if (!printer->info_2) {
1814 DEBUG(0,("convert_printer_info: "
1815 "talloc() failed!\n"));
1820 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1822 printer->info_2->setuptime = time(NULL);
1829 /****************************************************************
1830 _spoolss_ClosePrinter
1831 ****************************************************************/
1833 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1834 struct spoolss_ClosePrinter *r)
1836 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1838 if (Printer && Printer->document_started) {
1839 struct spoolss_EndDocPrinter e;
1841 e.in.handle = r->in.handle;
1843 _spoolss_EndDocPrinter(p, &e);
1846 if (!close_printer_handle(p, r->in.handle))
1849 /* clear the returned printer handle. Observed behavior
1850 from Win2k server. Don't think this really matters.
1851 Previous code just copied the value of the closed
1854 ZERO_STRUCTP(r->out.handle);
1859 /****************************************************************
1860 _spoolss_DeletePrinter
1861 ****************************************************************/
1863 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1864 struct spoolss_DeletePrinter *r)
1866 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
1869 if (Printer && Printer->document_started) {
1870 struct spoolss_EndDocPrinter e;
1872 e.in.handle = r->in.handle;
1874 _spoolss_EndDocPrinter(p, &e);
1877 result = delete_printer_handle(p, r->in.handle);
1879 update_c_setprinter(false);
1884 /*******************************************************************
1885 * static function to lookup the version id corresponding to an
1886 * long architecture string
1887 ******************************************************************/
1889 static const struct print_architecture_table_node archi_table[]= {
1891 {"Windows 4.0", SPL_ARCH_WIN40, 0 },
1892 {"Windows NT x86", SPL_ARCH_W32X86, 2 },
1893 {"Windows NT R4000", SPL_ARCH_W32MIPS, 2 },
1894 {"Windows NT Alpha_AXP", SPL_ARCH_W32ALPHA, 2 },
1895 {"Windows NT PowerPC", SPL_ARCH_W32PPC, 2 },
1896 {"Windows IA64", SPL_ARCH_IA64, 3 },
1897 {"Windows x64", SPL_ARCH_X64, 3 },
1901 static int get_version_id(const char *arch)
1905 for (i=0; archi_table[i].long_archi != NULL; i++)
1907 if (strcmp(arch, archi_table[i].long_archi) == 0)
1908 return (archi_table[i].version);
1914 /****************************************************************
1915 _spoolss_DeletePrinterDriver
1916 ****************************************************************/
1918 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1919 struct spoolss_DeletePrinterDriver *r)
1922 union spoolss_DriverInfo *info = NULL;
1923 union spoolss_DriverInfo *info_win2k = NULL;
1926 WERROR status_win2k = WERR_ACCESS_DENIED;
1927 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1929 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1930 and not a printer admin, then fail */
1932 if ( (p->server_info->utok.uid != sec_initial_uid())
1933 && !user_has_privileges(p->server_info->ptok, &se_printop )
1934 && !token_contains_name_in_list(
1935 uidtoname(p->server_info->utok.uid), NULL,
1936 NULL, p->server_info->ptok,
1937 lp_printer_admin(-1)) )
1939 return WERR_ACCESS_DENIED;
1942 /* check that we have a valid driver name first */
1944 if ((version = get_version_id(r->in.architecture)) == -1)
1945 return WERR_INVALID_ENVIRONMENT;
1947 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, 3, r->in.driver,
1951 /* try for Win2k driver if "Windows NT x86" */
1953 if ( version == 2 ) {
1955 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
1960 status = WERR_UNKNOWN_PRINTER_DRIVER;
1964 /* otherwise it was a failure */
1966 status = WERR_UNKNOWN_PRINTER_DRIVER;
1972 if (printer_driver_in_use(&info->info3)) {
1973 status = WERR_PRINTER_DRIVER_IN_USE;
1979 if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx,
1982 r->in.architecture, 3)))
1984 /* if we get to here, we now have 2 driver info structures to remove */
1985 /* remove the Win2k driver first*/
1987 status_win2k = delete_printer_driver(
1988 p, &info_win2k->info3, 3, false);
1989 free_a_printer_driver(info_win2k);
1991 /* this should not have failed---if it did, report to client */
1992 if ( !W_ERROR_IS_OK(status_win2k) )
1994 status = status_win2k;
2000 status = delete_printer_driver(p, &info->info3, version, false);
2002 /* if at least one of the deletes succeeded return OK */
2004 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2008 free_a_printer_driver(info);
2013 /****************************************************************
2014 _spoolss_DeletePrinterDriverEx
2015 ****************************************************************/
2017 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2018 struct spoolss_DeletePrinterDriverEx *r)
2020 union spoolss_DriverInfo *info = NULL;
2021 union spoolss_DriverInfo *info_win2k = NULL;
2025 WERROR status_win2k = WERR_ACCESS_DENIED;
2026 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2028 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2029 and not a printer admin, then fail */
2031 if ( (p->server_info->utok.uid != sec_initial_uid())
2032 && !user_has_privileges(p->server_info->ptok, &se_printop )
2033 && !token_contains_name_in_list(
2034 uidtoname(p->server_info->utok.uid), NULL, NULL,
2035 p->server_info->ptok, lp_printer_admin(-1)) )
2037 return WERR_ACCESS_DENIED;
2040 /* check that we have a valid driver name first */
2041 if ((version = get_version_id(r->in.architecture)) == -1) {
2042 /* this is what NT returns */
2043 return WERR_INVALID_ENVIRONMENT;
2046 if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION)
2047 version = r->in.version;
2049 status = get_a_printer_driver(p->mem_ctx, &info, 3, r->in.driver,
2050 r->in.architecture, version);
2052 if ( !W_ERROR_IS_OK(status) )
2055 * if the client asked for a specific version,
2056 * or this is something other than Windows NT x86,
2060 if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2063 /* try for Win2k driver if "Windows NT x86" */
2066 if (!W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info, 3, r->in.driver,
2069 status = WERR_UNKNOWN_PRINTER_DRIVER;
2074 if ( printer_driver_in_use(&info->info3) ) {
2075 status = WERR_PRINTER_DRIVER_IN_USE;
2080 * we have a couple of cases to consider.
2081 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2082 * then the delete should fail if **any** files overlap with
2084 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2085 * non-overlapping files
2086 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2087 * is set, the do not delete any files
2088 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2091 delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2093 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2095 if ( delete_files && printer_driver_files_in_use(info, &info->info3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
2096 /* no idea of the correct error here */
2097 status = WERR_ACCESS_DENIED;
2102 /* also check for W32X86/3 if necessary; maybe we already have? */
2104 if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2105 if (W_ERROR_IS_OK(get_a_printer_driver(p->mem_ctx, &info_win2k, 3,
2107 r->in.architecture, 3)))
2110 if ( delete_files && printer_driver_files_in_use(info, &info_win2k->info3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) {
2111 /* no idea of the correct error here */
2112 free_a_printer_driver(info_win2k);
2113 status = WERR_ACCESS_DENIED;
2117 /* if we get to here, we now have 2 driver info structures to remove */
2118 /* remove the Win2k driver first*/
2120 status_win2k = delete_printer_driver(
2121 p, &info_win2k->info3, 3, delete_files);
2122 free_a_printer_driver(info_win2k);
2124 /* this should not have failed---if it did, report to client */
2126 if ( !W_ERROR_IS_OK(status_win2k) )
2131 status = delete_printer_driver(p, &info->info3, version, delete_files);
2133 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2136 free_a_printer_driver(info);
2142 /****************************************************************************
2143 Internal routine for removing printerdata
2144 ***************************************************************************/
2146 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2148 return delete_printer_data( printer->info_2, key, value );
2151 /****************************************************************************
2152 Internal routine for storing printerdata
2153 ***************************************************************************/
2155 WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer,
2156 const char *key, const char *value,
2157 uint32_t type, uint8_t *data, int real_len)
2159 /* the registry objects enforce uniqueness based on value name */
2161 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2164 /********************************************************************
2165 GetPrinterData on a printer server Handle.
2166 ********************************************************************/
2168 static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx,
2170 enum winreg_Type *type,
2171 union spoolss_PrinterData *data)
2173 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2175 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2181 if (!StrCaseCmp(value, "BeepEnabled")) {
2187 if (!StrCaseCmp(value, "EventLog")) {
2189 /* formally was 0x1b */
2194 if (!StrCaseCmp(value, "NetPopup")) {
2200 if (!StrCaseCmp(value, "MajorVersion")) {
2203 /* Windows NT 4.0 seems to not allow uploading of drivers
2204 to a server that reports 0x3 as the MajorVersion.
2205 need to investigate more how Win2k gets around this .
2208 if (RA_WINNT == get_remote_arch()) {
2217 if (!StrCaseCmp(value, "MinorVersion")) {
2224 * uint32_t size = 0x114
2225 * uint32_t major = 5
2226 * uint32_t minor = [0|1]
2227 * uint32_t build = [2195|2600]
2228 * extra unicode string = e.g. "Service Pack 3"
2230 if (!StrCaseCmp(value, "OSVersion")) {
2232 enum ndr_err_code ndr_err;
2233 struct spoolss_OSVersion os;
2235 os.major = 5; /* Windows 2000 == 5.0 */
2237 os.build = 2195; /* build */
2238 os.extra_string = ""; /* leave extra string empty */
2240 ndr_err = ndr_push_struct_blob(&blob, mem_ctx, NULL, &os,
2241 (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion);
2242 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2243 return WERR_GENERAL_FAILURE;
2247 data->binary = blob;
2253 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2256 data->string = talloc_strdup(mem_ctx, "C:\\PRINTERS");
2257 W_ERROR_HAVE_NO_MEMORY(data->string);
2262 if (!StrCaseCmp(value, "Architecture")) {
2265 data->string = talloc_strdup(mem_ctx, "Windows NT x86");
2266 W_ERROR_HAVE_NO_MEMORY(data->string);
2271 if (!StrCaseCmp(value, "DsPresent")) {
2274 /* only show the publish check box if we are a
2275 member of a AD domain */
2277 if (lp_security() == SEC_ADS) {
2285 if (!StrCaseCmp(value, "DNSMachineName")) {
2286 const char *hostname = get_mydnsfullname();
2289 return WERR_BADFILE;
2293 data->string = talloc_strdup(mem_ctx, hostname);
2294 W_ERROR_HAVE_NO_MEMORY(data->string);
2299 return WERR_INVALID_PARAM;
2302 /****************************************************************
2303 _spoolss_GetPrinterData
2304 ****************************************************************/
2306 WERROR _spoolss_GetPrinterData(pipes_struct *p,
2307 struct spoolss_GetPrinterData *r)
2310 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2311 NT_PRINTER_INFO_LEVEL *printer = NULL;
2315 * Reminder: when it's a string, the length is in BYTES
2316 * even if UNICODE is negociated.
2321 /* in case of problem, return some default values */
2326 DEBUG(4,("_spoolss_GetPrinterData\n"));
2329 DEBUG(2,("_spoolss_GetPrinterData: Invalid handle (%s:%u:%u).\n",
2330 OUR_HANDLE(r->in.handle)));
2331 result = WERR_BADFID;
2335 if (Printer->printer_type == SPLHND_SERVER) {
2336 result = getprinterdata_printer_server(p->mem_ctx,
2341 if (!get_printer_snum(p, r->in.handle, &snum, NULL)) {
2342 result = WERR_BADFID;
2346 result = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2347 if (!W_ERROR_IS_OK(result)) {
2351 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2353 if (strequal(r->in.value_name, "ChangeId")) {
2354 *r->out.type = REG_DWORD;
2355 r->out.data->value = printer->info_2->changeid;
2358 struct regval_blob *v;
2361 v = get_printer_data(printer->info_2,
2362 SPOOL_PRINTERDATA_KEY,
2365 result = WERR_BADFILE;
2369 *r->out.type = v->type;
2371 blob = data_blob_const(v->data_p, v->size);
2373 result = pull_spoolss_PrinterData(p->mem_ctx, &blob,
2380 /* cleanup & exit */
2383 free_a_printer(&printer, 2);
2386 if (!W_ERROR_IS_OK(result)) {
2390 *r->out.needed = ndr_size_spoolss_PrinterData(r->out.data, *r->out.type, NULL, 0);
2391 *r->out.type = SPOOLSS_BUFFER_OK(*r->out.type, REG_NONE);
2392 r->out.data = SPOOLSS_BUFFER_OK(r->out.data, r->out.data);
2394 return SPOOLSS_BUFFER_OK(WERR_OK, WERR_MORE_DATA);
2397 /*********************************************************
2398 Connect to the client machine.
2399 **********************************************************/
2401 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2402 struct sockaddr_storage *client_ss, const char *remote_machine)
2405 struct cli_state *the_cli;
2406 struct sockaddr_storage rm_addr;
2408 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2409 if ( !resolve_name( remote_machine, &rm_addr, 0x20, false) ) {
2410 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2414 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2415 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2419 char addr[INET6_ADDRSTRLEN];
2420 rm_addr = *client_ss;
2421 print_sockaddr(addr, sizeof(addr), &rm_addr);
2422 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2426 /* setup the connection */
2428 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2429 &rm_addr, 0, "IPC$", "IPC",
2433 0, lp_client_signing(), NULL );
2435 if ( !NT_STATUS_IS_OK( ret ) ) {
2436 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2441 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2442 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2443 cli_shutdown(the_cli);
2448 * Ok - we have an anonymous connection to the IPC$ share.
2449 * Now start the NT Domain stuff :-).
2452 ret = cli_rpc_pipe_open_noauth(the_cli, &ndr_table_spoolss.syntax_id, pp_pipe);
2453 if (!NT_STATUS_IS_OK(ret)) {
2454 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2455 remote_machine, nt_errstr(ret)));
2456 cli_shutdown(the_cli);
2463 /***************************************************************************
2464 Connect to the client.
2465 ****************************************************************************/
2467 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2468 uint32_t localprinter, uint32_t type,
2469 struct policy_handle *handle,
2470 struct sockaddr_storage *client_ss)
2476 * If it's the first connection, contact the client
2477 * and connect to the IPC$ share anonymously
2479 if (smb_connections==0) {
2480 fstring unix_printer;
2482 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2484 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2487 messaging_register(smbd_messaging_context(), NULL,
2488 MSG_PRINTER_NOTIFY2,
2489 receive_notify2_message_list);
2490 /* Tell the connections db we're now interested in printer
2491 * notify messages. */
2492 register_message_flags(true, FLAG_MSG_PRINT_NOTIFY);
2496 * Tell the specific printing tdb we want messages for this printer
2497 * by registering our PID.
2500 if (!print_notify_register_pid(snum))
2501 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2505 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2513 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2514 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2515 win_errstr(result)));
2517 return (W_ERROR_IS_OK(result));
2520 /****************************************************************
2521 ****************************************************************/
2523 static struct spoolss_NotifyOption *dup_spoolss_NotifyOption(TALLOC_CTX *mem_ctx,
2524 const struct spoolss_NotifyOption *r)
2526 struct spoolss_NotifyOption *option;
2533 option = talloc_zero(mem_ctx, struct spoolss_NotifyOption);
2540 if (!option->count) {
2544 option->types = talloc_zero_array(option,
2545 struct spoolss_NotifyOptionType, option->count);
2546 if (!option->types) {
2547 talloc_free(option);
2551 for (i=0; i < option->count; i++) {
2552 option->types[i] = r->types[i];
2554 if (option->types[i].count) {
2555 option->types[i].fields = talloc_zero_array(option,
2556 union spoolss_Field, option->types[i].count);
2557 if (!option->types[i].fields) {
2558 talloc_free(option);
2561 for (k=0; k<option->types[i].count; k++) {
2562 option->types[i].fields[k] =
2563 r->types[i].fields[k];
2571 /****************************************************************
2572 * _spoolss_RemoteFindFirstPrinterChangeNotifyEx
2574 * before replying OK: status=0 a rpc call is made to the workstation
2575 * asking ReplyOpenPrinter
2577 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2578 * called from api_spoolss_rffpcnex
2579 ****************************************************************/
2581 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
2582 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
2585 struct spoolss_NotifyOption *option = r->in.notify_options;
2586 struct sockaddr_storage client_ss;
2588 /* store the notify value in the printer struct */
2590 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
2593 DEBUG(2,("_spoolss_RemoteFindFirstPrinterChangeNotifyEx: "
2594 "Invalid handle (%s:%u:%u).\n",
2595 OUR_HANDLE(r->in.handle)));
2599 Printer->notify.flags = r->in.flags;
2600 Printer->notify.options = r->in.options;
2601 Printer->notify.printerlocal = r->in.printer_local;
2603 TALLOC_FREE(Printer->notify.option);
2604 Printer->notify.option = dup_spoolss_NotifyOption(Printer, option);
2606 fstrcpy(Printer->notify.localmachine, r->in.local_machine);
2608 /* Connect to the client machine and send a ReplyOpenPrinter */
2610 if ( Printer->printer_type == SPLHND_SERVER)
2612 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2613 !get_printer_snum(p, r->in.handle, &snum, NULL) )
2616 if (!interpret_string_addr(&client_ss, p->client_address,
2618 return WERR_SERVER_UNAVAILABLE;
2621 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2622 Printer->notify.printerlocal, 1,
2623 &Printer->notify.client_hnd, &client_ss))
2624 return WERR_SERVER_UNAVAILABLE;
2626 Printer->notify.client_connected = true;
2631 /*******************************************************************
2632 * fill a notify_info_data with the servername
2633 ********************************************************************/
2635 void spoolss_notify_server_name(int snum,
2636 struct spoolss_Notify *data,
2637 print_queue_struct *queue,
2638 NT_PRINTER_INFO_LEVEL *printer,
2639 TALLOC_CTX *mem_ctx)
2641 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2644 /*******************************************************************
2645 * fill a notify_info_data with the printername (not including the servername).
2646 ********************************************************************/
2648 void spoolss_notify_printer_name(int snum,
2649 struct spoolss_Notify *data,
2650 print_queue_struct *queue,
2651 NT_PRINTER_INFO_LEVEL *printer,
2652 TALLOC_CTX *mem_ctx)
2654 /* the notify name should not contain the \\server\ part */
2655 char *p = strrchr(printer->info_2->printername, '\\');
2658 p = printer->info_2->printername;
2663 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2666 /*******************************************************************
2667 * fill a notify_info_data with the servicename
2668 ********************************************************************/
2670 void spoolss_notify_share_name(int snum,
2671 struct spoolss_Notify *data,
2672 print_queue_struct *queue,
2673 NT_PRINTER_INFO_LEVEL *printer,
2674 TALLOC_CTX *mem_ctx)
2676 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2679 /*******************************************************************
2680 * fill a notify_info_data with the port name
2681 ********************************************************************/
2683 void spoolss_notify_port_name(int snum,
2684 struct spoolss_Notify *data,
2685 print_queue_struct *queue,
2686 NT_PRINTER_INFO_LEVEL *printer,
2687 TALLOC_CTX *mem_ctx)
2689 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
2692 /*******************************************************************
2693 * fill a notify_info_data with the printername
2694 * but it doesn't exist, have to see what to do
2695 ********************************************************************/
2697 void spoolss_notify_driver_name(int snum,
2698 struct spoolss_Notify *data,
2699 print_queue_struct *queue,
2700 NT_PRINTER_INFO_LEVEL *printer,
2701 TALLOC_CTX *mem_ctx)
2703 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
2706 /*******************************************************************
2707 * fill a notify_info_data with the comment
2708 ********************************************************************/
2710 void spoolss_notify_comment(int snum,
2711 struct spoolss_Notify *data,
2712 print_queue_struct *queue,
2713 NT_PRINTER_INFO_LEVEL *printer,
2714 TALLOC_CTX *mem_ctx)
2718 if (*printer->info_2->comment == '\0') {
2719 p = lp_comment(snum);
2721 p = printer->info_2->comment;
2724 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
2727 /*******************************************************************
2728 * fill a notify_info_data with the comment
2729 * location = "Room 1, floor 2, building 3"
2730 ********************************************************************/
2732 void spoolss_notify_location(int snum,
2733 struct spoolss_Notify *data,
2734 print_queue_struct *queue,
2735 NT_PRINTER_INFO_LEVEL *printer,
2736 TALLOC_CTX *mem_ctx)
2738 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
2741 /*******************************************************************
2742 * fill a notify_info_data with the device mode
2743 * jfm:xxxx don't to it for know but that's a real problem !!!
2744 ********************************************************************/
2746 static void spoolss_notify_devmode(int snum,
2747 struct spoolss_Notify *data,
2748 print_queue_struct *queue,
2749 NT_PRINTER_INFO_LEVEL *printer,
2750 TALLOC_CTX *mem_ctx)
2752 /* for a dummy implementation we have to zero the fields */
2753 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
2756 /*******************************************************************
2757 * fill a notify_info_data with the separator file name
2758 ********************************************************************/
2760 void spoolss_notify_sepfile(int snum,
2761 struct spoolss_Notify *data,
2762 print_queue_struct *queue,
2763 NT_PRINTER_INFO_LEVEL *printer,
2764 TALLOC_CTX *mem_ctx)
2766 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
2769 /*******************************************************************
2770 * fill a notify_info_data with the print processor
2771 * jfm:xxxx return always winprint to indicate we don't do anything to it
2772 ********************************************************************/
2774 void spoolss_notify_print_processor(int snum,
2775 struct spoolss_Notify *data,
2776 print_queue_struct *queue,
2777 NT_PRINTER_INFO_LEVEL *printer,
2778 TALLOC_CTX *mem_ctx)
2780 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
2783 /*******************************************************************
2784 * fill a notify_info_data with the print processor options
2785 * jfm:xxxx send an empty string
2786 ********************************************************************/
2788 void spoolss_notify_parameters(int snum,
2789 struct spoolss_Notify *data,
2790 print_queue_struct *queue,
2791 NT_PRINTER_INFO_LEVEL *printer,
2792 TALLOC_CTX *mem_ctx)
2794 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
2797 /*******************************************************************
2798 * fill a notify_info_data with the data type
2799 * jfm:xxxx always send RAW as data type
2800 ********************************************************************/
2802 void spoolss_notify_datatype(int snum,
2803 struct spoolss_Notify *data,
2804 print_queue_struct *queue,
2805 NT_PRINTER_INFO_LEVEL *printer,
2806 TALLOC_CTX *mem_ctx)
2808 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
2811 /*******************************************************************
2812 * fill a notify_info_data with the security descriptor
2813 * jfm:xxxx send an null pointer to say no security desc
2814 * have to implement security before !
2815 ********************************************************************/
2817 static void spoolss_notify_security_desc(int snum,
2818 struct spoolss_Notify *data,
2819 print_queue_struct *queue,
2820 NT_PRINTER_INFO_LEVEL *printer,
2821 TALLOC_CTX *mem_ctx)
2823 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
2824 printer->info_2->secdesc_buf->sd_size,
2825 printer->info_2->secdesc_buf->sd);
2828 /*******************************************************************
2829 * fill a notify_info_data with the attributes
2830 * jfm:xxxx a samba printer is always shared
2831 ********************************************************************/
2833 void spoolss_notify_attributes(int snum,
2834 struct spoolss_Notify *data,
2835 print_queue_struct *queue,
2836 NT_PRINTER_INFO_LEVEL *printer,
2837 TALLOC_CTX *mem_ctx)
2839 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
2842 /*******************************************************************
2843 * fill a notify_info_data with the priority
2844 ********************************************************************/
2846 static void spoolss_notify_priority(int snum,
2847 struct spoolss_Notify *data,
2848 print_queue_struct *queue,
2849 NT_PRINTER_INFO_LEVEL *printer,
2850 TALLOC_CTX *mem_ctx)
2852 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
2855 /*******************************************************************
2856 * fill a notify_info_data with the default priority
2857 ********************************************************************/
2859 static void spoolss_notify_default_priority(int snum,
2860 struct spoolss_Notify *data,
2861 print_queue_struct *queue,
2862 NT_PRINTER_INFO_LEVEL *printer,
2863 TALLOC_CTX *mem_ctx)
2865 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
2868 /*******************************************************************
2869 * fill a notify_info_data with the start time
2870 ********************************************************************/
2872 static void spoolss_notify_start_time(int snum,
2873 struct spoolss_Notify *data,
2874 print_queue_struct *queue,
2875 NT_PRINTER_INFO_LEVEL *printer,
2876 TALLOC_CTX *mem_ctx)
2878 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
2881 /*******************************************************************
2882 * fill a notify_info_data with the until time
2883 ********************************************************************/
2885 static void spoolss_notify_until_time(int snum,
2886 struct spoolss_Notify *data,
2887 print_queue_struct *queue,
2888 NT_PRINTER_INFO_LEVEL *printer,
2889 TALLOC_CTX *mem_ctx)
2891 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
2894 /*******************************************************************
2895 * fill a notify_info_data with the status
2896 ********************************************************************/
2898 static void spoolss_notify_status(int snum,
2899 struct spoolss_Notify *data,
2900 print_queue_struct *queue,
2901 NT_PRINTER_INFO_LEVEL *printer,
2902 TALLOC_CTX *mem_ctx)
2904 print_status_struct status;
2906 print_queue_length(snum, &status);
2907 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
2910 /*******************************************************************
2911 * fill a notify_info_data with the number of jobs queued
2912 ********************************************************************/
2914 void spoolss_notify_cjobs(int snum,
2915 struct spoolss_Notify *data,
2916 print_queue_struct *queue,
2917 NT_PRINTER_INFO_LEVEL *printer,
2918 TALLOC_CTX *mem_ctx)
2920 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
2923 /*******************************************************************
2924 * fill a notify_info_data with the average ppm
2925 ********************************************************************/
2927 static void spoolss_notify_average_ppm(int snum,
2928 struct spoolss_Notify *data,
2929 print_queue_struct *queue,
2930 NT_PRINTER_INFO_LEVEL *printer,
2931 TALLOC_CTX *mem_ctx)
2933 /* always respond 8 pages per minutes */
2934 /* a little hard ! */
2935 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
2938 /*******************************************************************
2939 * fill a notify_info_data with username
2940 ********************************************************************/
2942 static void spoolss_notify_username(int snum,
2943 struct spoolss_Notify *data,
2944 print_queue_struct *queue,
2945 NT_PRINTER_INFO_LEVEL *printer,
2946 TALLOC_CTX *mem_ctx)
2948 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
2951 /*******************************************************************
2952 * fill a notify_info_data with job status
2953 ********************************************************************/
2955 static void spoolss_notify_job_status(int snum,
2956 struct spoolss_Notify *data,
2957 print_queue_struct *queue,
2958 NT_PRINTER_INFO_LEVEL *printer,
2959 TALLOC_CTX *mem_ctx)
2961 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
2964 /*******************************************************************
2965 * fill a notify_info_data with job name
2966 ********************************************************************/
2968 static void spoolss_notify_job_name(int snum,
2969 struct spoolss_Notify *data,
2970 print_queue_struct *queue,
2971 NT_PRINTER_INFO_LEVEL *printer,
2972 TALLOC_CTX *mem_ctx)
2974 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
2977 /*******************************************************************
2978 * fill a notify_info_data with job status
2979 ********************************************************************/
2981 static void spoolss_notify_job_status_string(int snum,
2982 struct spoolss_Notify *data,
2983 print_queue_struct *queue,
2984 NT_PRINTER_INFO_LEVEL *printer,
2985 TALLOC_CTX *mem_ctx)
2988 * Now we're returning job status codes we just return a "" here. JRA.
2993 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
2996 switch (queue->status) {
3001 p = ""; /* NT provides the paused string */
3010 #endif /* NO LONGER NEEDED. */
3012 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3015 /*******************************************************************
3016 * fill a notify_info_data with job time
3017 ********************************************************************/
3019 static void spoolss_notify_job_time(int snum,
3020 struct spoolss_Notify *data,
3021 print_queue_struct *queue,
3022 NT_PRINTER_INFO_LEVEL *printer,
3023 TALLOC_CTX *mem_ctx)
3025 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3028 /*******************************************************************
3029 * fill a notify_info_data with job size
3030 ********************************************************************/
3032 static void spoolss_notify_job_size(int snum,
3033 struct spoolss_Notify *data,
3034 print_queue_struct *queue,
3035 NT_PRINTER_INFO_LEVEL *printer,
3036 TALLOC_CTX *mem_ctx)
3038 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3041 /*******************************************************************
3042 * fill a notify_info_data with page info
3043 ********************************************************************/
3044 static void spoolss_notify_total_pages(int snum,
3045 struct spoolss_Notify *data,
3046 print_queue_struct *queue,
3047 NT_PRINTER_INFO_LEVEL *printer,
3048 TALLOC_CTX *mem_ctx)
3050 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3053 /*******************************************************************
3054 * fill a notify_info_data with pages printed info.
3055 ********************************************************************/
3056 static void spoolss_notify_pages_printed(int snum,
3057 struct spoolss_Notify *data,
3058 print_queue_struct *queue,
3059 NT_PRINTER_INFO_LEVEL *printer,
3060 TALLOC_CTX *mem_ctx)
3062 /* Add code when back-end tracks this */
3063 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3066 /*******************************************************************
3067 Fill a notify_info_data with job position.
3068 ********************************************************************/
3070 static void spoolss_notify_job_position(int snum,
3071 struct spoolss_Notify *data,
3072 print_queue_struct *queue,
3073 NT_PRINTER_INFO_LEVEL *printer,
3074 TALLOC_CTX *mem_ctx)
3076 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3079 /*******************************************************************
3080 Fill a notify_info_data with submitted time.
3081 ********************************************************************/
3083 static void spoolss_notify_submitted_time(int snum,
3084 struct spoolss_Notify *data,
3085 print_queue_struct *queue,
3086 NT_PRINTER_INFO_LEVEL *printer,
3087 TALLOC_CTX *mem_ctx)
3089 data->data.string.string = NULL;
3090 data->data.string.size = 0;
3092 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3093 &data->data.string.string,
3094 &data->data.string.size);
3098 struct s_notify_info_data_table
3100 enum spoolss_NotifyType type;
3103 enum spoolss_NotifyTable variable_type;
3104 void (*fn) (int snum, struct spoolss_Notify *data,
3105 print_queue_struct *queue,
3106 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3109 /* A table describing the various print notification constants and
3110 whether the notification data is a pointer to a variable sized
3111 buffer, a one value uint32_t or a two value uint32_t. */
3113 static const struct s_notify_info_data_table notify_info_data_table[] =
3115 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_FIELD_SERVER_NAME, "PRINTER_NOTIFY_FIELD_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },