2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
26 up, all the errors returned are DOS errors, not NT status codes. */
30 extern userdom_struct current_user_info;
33 #define DBGC_CLASS DBGC_RPC_SRV
35 #ifndef MAX_OPEN_PRINTER_EXS
36 #define MAX_OPEN_PRINTER_EXS 50
39 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
40 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
43 const char *long_archi;
44 const char *short_archi;
48 static Printer_entry *printers_list;
50 typedef struct _counter_printer_0 {
51 struct _counter_printer_0 *next;
52 struct _counter_printer_0 *prev;
58 static counter_printer_0 *counter_list;
60 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
61 static uint32 smb_connections=0;
64 /* in printing/nt_printing.c */
66 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
68 /* API table for Xcv Monitor functions */
70 struct xcv_api_table {
72 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
75 /********************************************************************
76 * Canonicalize servername.
77 ********************************************************************/
79 static const char *canon_servername(const char *servername)
81 const char *pservername = servername;
82 while (*pservername == '\\') {
88 /* translate between internal status numbers and NT status numbers */
89 static int nt_printj_status(int v)
95 return JOB_STATUS_PAUSED;
97 return JOB_STATUS_SPOOLING;
99 return JOB_STATUS_PRINTING;
101 return JOB_STATUS_ERROR;
103 return JOB_STATUS_DELETING;
105 return JOB_STATUS_OFFLINE;
107 return JOB_STATUS_PAPEROUT;
109 return JOB_STATUS_PRINTED;
111 return JOB_STATUS_DELETED;
113 return JOB_STATUS_BLOCKED;
114 case LPQ_USER_INTERVENTION:
115 return JOB_STATUS_USER_INTERVENTION;
120 static int nt_printq_status(int v)
124 return PRINTER_STATUS_PAUSED;
133 /****************************************************************************
134 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
135 ****************************************************************************/
137 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
142 SAFE_FREE((*pp)->ctr.type);
146 /***************************************************************************
147 Disconnect from the client
148 ****************************************************************************/
150 static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
156 * Tell the specific printing tdb we no longer want messages for this printer
157 * by deregistering our PID.
160 if (!print_notify_deregister_pid(snum))
161 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
163 /* weird if the test succeds !!! */
164 if (smb_connections==0) {
165 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
169 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
172 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
173 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
174 win_errstr(result)));
176 /* if it's the last connection, deconnect the IPC$ share */
177 if (smb_connections==1) {
179 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
180 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
182 messaging_deregister(smbd_messaging_context(),
183 MSG_PRINTER_NOTIFY2, NULL);
185 /* Tell the connections db we're no longer interested in
186 * printer notify messages. */
188 register_message_flags( False, FLAG_MSG_PRINT_NOTIFY );
194 /****************************************************************************
195 Functions to free a printer entry datastruct.
196 ****************************************************************************/
198 static int printer_entry_destructor(Printer_entry *Printer)
200 if (Printer->notify.client_connected==True) {
203 if ( Printer->printer_type == SPLHND_SERVER) {
205 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
206 } else if (Printer->printer_type == SPLHND_PRINTER) {
207 snum = print_queue_snum(Printer->sharename);
209 srv_spoolss_replycloseprinter(snum,
210 &Printer->notify.client_hnd);
214 Printer->notify.flags=0;
215 Printer->notify.options=0;
216 Printer->notify.localmachine[0]='\0';
217 Printer->notify.printerlocal=0;
218 free_spool_notify_option(&Printer->notify.option);
219 Printer->notify.option=NULL;
220 Printer->notify.client_connected=False;
222 free_nt_devicemode( &Printer->nt_devmode );
223 free_a_printer( &Printer->printer_info, 2 );
225 /* Remove from the internal list. */
226 DLIST_REMOVE(printers_list, Printer);
230 /****************************************************************************
231 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
232 ****************************************************************************/
234 static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
236 SPOOL_NOTIFY_OPTION *new_sp = NULL;
241 new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION);
248 new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
250 if (!new_sp->ctr.type) {
259 /****************************************************************************
260 find printer index by handle
261 ****************************************************************************/
263 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
265 Printer_entry *find_printer = NULL;
267 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
268 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
275 /****************************************************************************
276 Close printer index by handle.
277 ****************************************************************************/
279 static bool close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
281 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
284 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
288 close_policy_hnd(p, hnd);
293 /****************************************************************************
294 Delete a printer given a handle.
295 ****************************************************************************/
297 WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename )
299 char *cmd = lp_deleteprinter_cmd();
300 char *command = NULL;
302 SE_PRIV se_printop = SE_PRINT_OPERATOR;
303 bool is_print_op = False;
305 /* can't fail if we don't try */
310 command = talloc_asprintf(ctx,
317 is_print_op = user_has_privileges( token, &se_printop );
319 DEBUG(10,("Running [%s]\n", command));
321 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
326 if ( (ret = smbrun(command, NULL)) == 0 ) {
327 /* Tell everyone we updated smb.conf. */
328 message_send_all(smbd_messaging_context(),
329 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
335 /********** END SePrintOperatorPrivlege BLOCK **********/
337 DEBUGADD(10,("returned [%d]\n", ret));
339 TALLOC_FREE(command);
342 return WERR_BADFID; /* What to return here? */
344 /* go ahead and re-read the services immediately */
345 reload_services( False );
347 if ( lp_servicenumber( sharename ) < 0 )
348 return WERR_ACCESS_DENIED;
353 /****************************************************************************
354 Delete a printer given a handle.
355 ****************************************************************************/
357 static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
359 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
362 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
367 * It turns out that Windows allows delete printer on a handle
368 * opened by an admin user, then used on a pipe handle created
369 * by an anonymous user..... but they're working on security.... riiight !
373 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
374 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
375 return WERR_ACCESS_DENIED;
378 /* this does not need a become root since the access check has been
379 done on the handle already */
381 if (del_a_printer( Printer->sharename ) != 0) {
382 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
386 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
387 Printer->sharename );
390 /****************************************************************************
391 Return the snum of a printer corresponding to an handle.
392 ****************************************************************************/
394 static bool get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number,
395 struct share_params **params)
397 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
400 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
404 switch (Printer->printer_type) {
406 DEBUG(4,("short name:%s\n", Printer->sharename));
407 *number = print_queue_snum(Printer->sharename);
408 return (*number != -1);
416 /****************************************************************************
417 Set printer handle type.
418 Check if it's \\server or \\server\printer
419 ****************************************************************************/
421 static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
423 DEBUG(3,("Setting printer type=%s\n", handlename));
425 if ( strlen(handlename) < 3 ) {
426 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
430 /* it's a print server */
431 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
432 DEBUGADD(4,("Printer is a print server\n"));
433 Printer->printer_type = SPLHND_SERVER;
435 /* it's a printer (set_printer_hnd_name() will handle port monitors */
437 DEBUGADD(4,("Printer is a printer\n"));
438 Printer->printer_type = SPLHND_PRINTER;
444 /****************************************************************************
445 Set printer handle name.. Accept names like \\server, \\server\printer,
446 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
447 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
448 XcvDataPort() interface.
449 ****************************************************************************/
451 static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
454 int n_services=lp_numservices();
455 char *aprinter, *printername;
456 const char *servername;
459 NT_PRINTER_INFO_LEVEL *printer = NULL;
462 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
464 aprinter = handlename;
465 if ( *handlename == '\\' ) {
466 servername = canon_servername(handlename);
467 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
475 /* save the servername to fill in replies on this handle */
477 if ( !is_myname_or_ipaddr( servername ) )
480 fstrcpy( Printer->servername, servername );
482 if ( Printer->printer_type == SPLHND_SERVER )
485 if ( Printer->printer_type != SPLHND_PRINTER )
488 DEBUGADD(5, ("searching for [%s]\n", aprinter ));
490 /* check for the Port Monitor Interface */
492 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
493 Printer->printer_type = SPLHND_PORTMON_TCP;
494 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
497 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
498 Printer->printer_type = SPLHND_PORTMON_LOCAL;
499 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
503 /* Search all sharenames first as this is easier than pulling
504 the printer_info_2 off of disk. Don't use find_service() since
505 that calls out to map_username() */
507 /* do another loop to look for printernames */
509 for (snum=0; !found && snum<n_services; snum++) {
511 /* no point going on if this is not a printer */
513 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
516 fstrcpy(sname, lp_servicename(snum));
517 if ( strequal( aprinter, sname ) ) {
522 /* no point looking up the printer object if
523 we aren't allowing printername != sharename */
525 if ( lp_force_printername(snum) )
528 fstrcpy(sname, lp_servicename(snum));
532 /* This call doesn't fill in the location or comment from
533 * a CUPS server for efficiency with large numbers of printers.
537 result = get_a_printer_search( NULL, &printer, 2, sname );
538 if ( !W_ERROR_IS_OK(result) ) {
539 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
540 sname, win_errstr(result)));
544 /* printername is always returned as \\server\printername */
545 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
546 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
547 printer->info_2->printername));
548 free_a_printer( &printer, 2);
554 if ( strequal(printername, aprinter) ) {
555 free_a_printer( &printer, 2);
560 DEBUGADD(10, ("printername: %s\n", printername));
562 free_a_printer( &printer, 2);
565 free_a_printer( &printer, 2);
568 DEBUGADD(4,("Printer not found\n"));
572 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
574 fstrcpy(Printer->sharename, sname);
579 /****************************************************************************
580 Find first available printer slot. creates a printer handle for you.
581 ****************************************************************************/
583 static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted)
585 Printer_entry *new_printer;
587 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
589 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
590 if (new_printer == NULL) {
593 talloc_set_destructor(new_printer, printer_entry_destructor);
595 if (!create_policy_hnd(p, hnd, new_printer)) {
596 TALLOC_FREE(new_printer);
600 /* Add to the internal list. */
601 DLIST_ADD(printers_list, new_printer);
603 new_printer->notify.option=NULL;
605 if (!set_printer_hnd_printertype(new_printer, name)) {
606 close_printer_handle(p, hnd);
610 if (!set_printer_hnd_name(new_printer, name)) {
611 close_printer_handle(p, hnd);
615 new_printer->access_granted = access_granted;
617 DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
622 /***************************************************************************
623 check to see if the client motify handle is monitoring the notification
624 given by (notify_type, notify_field).
625 **************************************************************************/
627 static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type,
633 static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
636 SPOOL_NOTIFY_OPTION *option = p->notify.option;
640 * Flags should always be zero when the change notify
641 * is registered by the client's spooler. A user Win32 app
642 * might use the flags though instead of the NOTIFY_OPTION_INFO
651 return is_monitoring_event_flags(
652 p->notify.flags, notify_type, notify_field);
654 for (i = 0; i < option->count; i++) {
656 /* Check match for notify_type */
658 if (option->ctr.type[i].type != notify_type)
661 /* Check match for field */
663 for (j = 0; j < option->ctr.type[i].count; j++) {
664 if (option->ctr.type[i].fields[j] == notify_field) {
670 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
671 p->servername, p->sharename, notify_type, notify_field));
676 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
677 _data->data.integer[0] = _integer; \
678 _data->data.integer[1] = 0;
681 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
682 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
683 if (!_data->data.string.string) {\
684 _data->data.string.size = 0; \
686 _data->data.string.size = strlen_m_term(_p) * 2;
688 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
689 _data->data.devmode.devmode = _devmode;
691 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
692 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
693 if (!_data->data.sd.sd) { \
694 _data->data.sd.sd_size = 0; \
696 _data->data.sd.sd_size = _size;
698 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
703 struct spoolss_Time st;
707 if (!init_systemtime(&st, t)) {
711 p = talloc_array(mem_ctx, char, len);
717 * Systemtime must be linearized as a set of UINT16's.
718 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
721 SSVAL(p, 0, st.year);
722 SSVAL(p, 2, st.month);
723 SSVAL(p, 4, st.day_of_week);
725 SSVAL(p, 8, st.hour);
726 SSVAL(p, 10, st.minute);
727 SSVAL(p, 12, st.second);
728 SSVAL(p, 14, st.millisecond);
734 /* Convert a notification message to a struct spoolss_Notify */
736 static void notify_one_value(struct spoolss_notify_msg *msg,
737 struct spoolss_Notify *data,
740 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
743 static void notify_string(struct spoolss_notify_msg *msg,
744 struct spoolss_Notify *data,
747 /* The length of the message includes the trailing \0 */
749 data->data.string.size = msg->len * 2;
750 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
751 if (!data->data.string.string) {
752 data->data.string.size = 0;
757 static void notify_system_time(struct spoolss_notify_msg *msg,
758 struct spoolss_Notify *data,
761 data->data.string.string = NULL;
762 data->data.string.size = 0;
764 if (msg->len != sizeof(time_t)) {
765 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
770 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
771 &data->data.string.string,
772 &data->data.string.size);
775 struct notify2_message_table {
777 void (*fn)(struct spoolss_notify_msg *msg,
778 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
781 static struct notify2_message_table printer_notify_table[] = {
782 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
783 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
784 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
785 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string },
786 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
787 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string },
788 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string },
789 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
790 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
791 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
792 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
793 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
794 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
795 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
796 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
797 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
798 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
799 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
800 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
803 static struct notify2_message_table job_notify_table[] = {
804 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
805 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
806 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
807 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
808 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
809 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
810 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
811 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
812 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
813 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
814 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
815 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
816 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
817 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
818 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
819 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
820 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
821 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
822 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
823 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
824 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
825 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
826 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
827 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
831 /***********************************************************************
832 Allocate talloc context for container object
833 **********************************************************************/
835 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
840 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
845 /***********************************************************************
846 release all allocated memory and zero out structure
847 **********************************************************************/
849 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
855 talloc_destroy(ctr->ctx);
862 /***********************************************************************
863 **********************************************************************/
865 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
873 /***********************************************************************
874 **********************************************************************/
876 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
878 if ( !ctr || !ctr->msg_groups )
881 if ( idx >= ctr->num_groups )
884 return &ctr->msg_groups[idx];
888 /***********************************************************************
889 How many groups of change messages do we have ?
890 **********************************************************************/
892 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
897 return ctr->num_groups;
900 /***********************************************************************
901 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
902 **********************************************************************/
904 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
906 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
907 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
908 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
914 /* loop over all groups looking for a matching printer name */
916 for ( i=0; i<ctr->num_groups; i++ ) {
917 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
921 /* add a new group? */
923 if ( i == ctr->num_groups ) {
926 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
927 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
930 ctr->msg_groups = groups;
932 /* clear the new entry and set the printer name */
934 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
935 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
938 /* add the change messages; 'i' is the correct index now regardless */
940 msg_grp = &ctr->msg_groups[i];
944 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
945 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
948 msg_grp->msgs = msg_list;
950 new_slot = msg_grp->num_msgs-1;
951 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
953 /* need to allocate own copy of data */
956 msg_grp->msgs[new_slot].notify.data = (char *)
957 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
959 return ctr->num_groups;
962 /***********************************************************************
963 Send a change notication message on all handles which have a call
965 **********************************************************************/
967 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
970 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
971 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
972 SPOOLSS_NOTIFY_MSG *messages;
973 int sending_msg_count;
976 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
980 messages = msg_group->msgs;
983 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
987 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
989 /* loop over all printers */
991 for (p = printers_list; p; p = p->next) {
992 struct spoolss_Notify *notifies;
997 /* Is there notification on this handle? */
999 if ( !p->notify.client_connected )
1002 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1004 /* For this printer? Print servers always receive
1007 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1008 ( !strequal(msg_group->printername, p->sharename) ) )
1011 DEBUG(10,("Our printer\n"));
1013 /* allocate the max entries possible */
1015 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1020 /* build the array of change notifications */
1022 sending_msg_count = 0;
1024 for ( i=0; i<msg_group->num_msgs; i++ ) {
1025 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1027 /* Are we monitoring this event? */
1029 if (!is_monitoring_event(p, msg->type, msg->field))
1032 sending_msg_count++;
1035 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1036 msg->type, msg->field, p->sharename));
1039 * if the is a printer notification handle and not a job notification
1040 * type, then set the id to 0. Other wise just use what was specified
1043 * When registering change notification on a print server handle
1044 * we always need to send back the id (snum) matching the printer
1045 * for which the change took place. For change notify registered
1046 * on a printer handle, this does not matter and the id should be 0.
1051 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1057 /* Convert unix jobid to smb jobid */
1059 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1060 id = sysjob_to_jobid(msg->id);
1063 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1068 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1071 case PRINTER_NOTIFY_TYPE:
1072 if ( printer_notify_table[msg->field].fn )
1073 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1076 case JOB_NOTIFY_TYPE:
1077 if ( job_notify_table[msg->field].fn )
1078 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1082 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1089 if ( sending_msg_count ) {
1092 union spoolss_ReplyPrinterInfo info;
1093 struct spoolss_NotifyInfo info0;
1094 uint32_t reply_result;
1096 info0.version = 0x2;
1097 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1098 info0.count = count;
1099 info0.notifies = notifies;
1101 info.info0 = &info0;
1103 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1104 &p->notify.client_hnd,
1105 p->notify.change, /* color */
1108 0, /* reply_type, must be 0 */
1111 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1112 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1113 notify_cli_pipe->srv_name_slash,
1116 switch (reply_result) {
1119 case PRINTER_NOTIFY_INFO_DISCARDED:
1120 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1121 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1130 DEBUG(8,("send_notify2_changes: Exit...\n"));
1134 /***********************************************************************
1135 **********************************************************************/
1137 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1140 uint32 tv_sec, tv_usec;
1143 /* Unpack message */
1145 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f",
1148 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd",
1150 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1153 tdb_unpack((uint8 *)buf + offset, len - offset, "dd",
1154 &msg->notify.value[0], &msg->notify.value[1]);
1156 tdb_unpack((uint8 *)buf + offset, len - offset, "B",
1157 &msg->len, &msg->notify.data);
1159 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1160 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1162 tv->tv_sec = tv_sec;
1163 tv->tv_usec = tv_usec;
1166 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1167 msg->notify.value[1]));
1169 dump_data(3, (uint8 *)msg->notify.data, msg->len);
1174 /********************************************************************
1175 Receive a notify2 message list
1176 ********************************************************************/
1178 static void receive_notify2_message_list(struct messaging_context *msg,
1181 struct server_id server_id,
1184 size_t msg_count, i;
1185 char *buf = (char *)data->data;
1188 SPOOLSS_NOTIFY_MSG notify;
1189 SPOOLSS_NOTIFY_MSG_CTR messages;
1192 if (data->length < 4) {
1193 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1197 msg_count = IVAL(buf, 0);
1200 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1202 if (msg_count == 0) {
1203 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1207 /* initialize the container */
1209 ZERO_STRUCT( messages );
1210 notify_msg_ctr_init( &messages );
1213 * build message groups for each printer identified
1214 * in a change_notify msg. Remember that a PCN message
1215 * includes the handle returned for the srv_spoolss_replyopenprinter()
1216 * call. Therefore messages are grouped according to printer handle.
1219 for ( i=0; i<msg_count; i++ ) {
1220 struct timeval msg_tv;
1222 if (msg_ptr + 4 - buf > data->length) {
1223 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1227 msg_len = IVAL(msg_ptr,0);
1230 if (msg_ptr + msg_len - buf > data->length) {
1231 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1235 /* unpack messages */
1237 ZERO_STRUCT( notify );
1238 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1241 /* add to correct list in container */
1243 notify_msg_ctr_addmsg( &messages, ¬ify );
1245 /* free memory that might have been allocated by notify2_unpack_msg() */
1247 if ( notify.len != 0 )
1248 SAFE_FREE( notify.notify.data );
1251 /* process each group of messages */
1253 num_groups = notify_msg_ctr_numgroups( &messages );
1254 for ( i=0; i<num_groups; i++ )
1255 send_notify2_changes( &messages, i );
1260 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
1262 notify_msg_ctr_destroy( &messages );
1267 /********************************************************************
1268 Send a message to ourself about new driver being installed
1269 so we can upgrade the information for each printer bound to this
1271 ********************************************************************/
1273 static bool srv_spoolss_drv_upgrade_printer(char* drivername)
1275 int len = strlen(drivername);
1280 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1283 messaging_send_buf(smbd_messaging_context(), procid_self(),
1284 MSG_PRINTER_DRVUPGRADE,
1285 (uint8 *)drivername, len+1);
1290 /**********************************************************************
1291 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1292 over all printers, upgrading ones as necessary
1293 **********************************************************************/
1295 void do_drv_upgrade_printer(struct messaging_context *msg,
1298 struct server_id server_id,
1303 int n_services = lp_numservices();
1306 len = MIN(data->length,sizeof(drivername)-1);
1307 strncpy(drivername, (const char *)data->data, len);
1309 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1311 /* Iterate the printer list */
1313 for (snum=0; snum<n_services; snum++)
1315 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1318 NT_PRINTER_INFO_LEVEL *printer = NULL;
1320 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1321 if (!W_ERROR_IS_OK(result))
1324 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1326 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1328 /* all we care about currently is the change_id */
1330 result = mod_a_printer(printer, 2);
1331 if (!W_ERROR_IS_OK(result)) {
1332 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1333 win_errstr(result)));
1337 free_a_printer(&printer, 2);
1344 /********************************************************************
1345 Update the cache for all printq's with a registered client
1347 ********************************************************************/
1349 void update_monitored_printq_cache( void )
1351 Printer_entry *printer = printers_list;
1354 /* loop through all printers and update the cache where
1355 client_connected == True */
1358 if ( (printer->printer_type == SPLHND_PRINTER)
1359 && printer->notify.client_connected )
1361 snum = print_queue_snum(printer->sharename);
1362 print_queue_status( snum, NULL, NULL );
1365 printer = printer->next;
1370 /********************************************************************
1371 Send a message to ourself about new driver being installed
1372 so we can upgrade the information for each printer bound to this
1374 ********************************************************************/
1376 static bool srv_spoolss_reset_printerdata(char* drivername)
1378 int len = strlen(drivername);
1383 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1386 messaging_send_buf(smbd_messaging_context(), procid_self(),
1387 MSG_PRINTERDATA_INIT_RESET,
1388 (uint8 *)drivername, len+1);
1393 /**********************************************************************
1394 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1395 over all printers, resetting printer data as neessary
1396 **********************************************************************/
1398 void reset_all_printerdata(struct messaging_context *msg,
1401 struct server_id server_id,
1406 int n_services = lp_numservices();
1409 len = MIN( data->length, sizeof(drivername)-1 );
1410 strncpy( drivername, (const char *)data->data, len );
1412 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1414 /* Iterate the printer list */
1416 for ( snum=0; snum<n_services; snum++ )
1418 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1421 NT_PRINTER_INFO_LEVEL *printer = NULL;
1423 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1424 if ( !W_ERROR_IS_OK(result) )
1428 * if the printer is bound to the driver,
1429 * then reset to the new driver initdata
1432 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1434 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1436 if ( !set_driver_init(printer, 2) ) {
1437 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1438 printer->info_2->printername, printer->info_2->drivername));
1441 result = mod_a_printer( printer, 2 );
1442 if ( !W_ERROR_IS_OK(result) ) {
1443 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1444 get_dos_error_msg(result)));
1448 free_a_printer( &printer, 2 );
1457 /****************************************************************
1458 _spoolss_OpenPrinter
1459 ****************************************************************/
1461 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1462 struct spoolss_OpenPrinter *r)
1464 struct spoolss_OpenPrinterEx e;
1467 ZERO_STRUCT(e.in.userlevel);
1469 e.in.printername = r->in.printername;
1470 e.in.datatype = r->in.datatype;
1471 e.in.devmode_ctr = r->in.devmode_ctr;
1472 e.in.access_mask = r->in.access_mask;
1475 e.out.handle = r->out.handle;
1477 werr = _spoolss_OpenPrinterEx(p, &e);
1479 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1480 /* OpenPrinterEx returns this for a bad
1481 * printer name. We must return WERR_INVALID_PRINTER_NAME
1484 werr = WERR_INVALID_PRINTER_NAME;
1490 /********************************************************************
1491 FIXME: temporary convert_devicemode_new function
1492 ********************************************************************/
1494 static bool convert_devicemode_new(const char *printername,
1495 struct spoolss_DeviceMode *devmode,
1496 NT_DEVICEMODE **pp_nt_devmode)
1498 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1501 * Ensure nt_devmode is a valid pointer
1502 * as we will be overwriting it.
1505 if (nt_devmode == NULL) {
1506 DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
1507 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1511 rpcstr_push(nt_devmode->devicename, devmode->devicename, 31, 0);
1512 rpcstr_push(nt_devmode->formname, devmode->formname, 31, 0);
1514 nt_devmode->specversion = devmode->specversion;
1515 nt_devmode->driverversion = devmode->driverversion;
1516 nt_devmode->size = devmode->size;
1517 nt_devmode->fields = devmode->fields;
1518 nt_devmode->orientation = devmode->orientation;
1519 nt_devmode->papersize = devmode->papersize;
1520 nt_devmode->paperlength = devmode->paperlength;
1521 nt_devmode->paperwidth = devmode->paperwidth;
1522 nt_devmode->scale = devmode->scale;
1523 nt_devmode->copies = devmode->copies;
1524 nt_devmode->defaultsource = devmode->defaultsource;
1525 nt_devmode->printquality = devmode->printquality;
1526 nt_devmode->color = devmode->color;
1527 nt_devmode->duplex = devmode->duplex;
1528 nt_devmode->yresolution = devmode->yresolution;
1529 nt_devmode->ttoption = devmode->ttoption;
1530 nt_devmode->collate = devmode->collate;
1532 nt_devmode->logpixels = devmode->logpixels;
1533 nt_devmode->bitsperpel = devmode->bitsperpel;
1534 nt_devmode->pelswidth = devmode->pelswidth;
1535 nt_devmode->pelsheight = devmode->pelsheight;
1536 nt_devmode->displayflags = devmode->displayflags;
1537 nt_devmode->displayfrequency = devmode->displayfrequency;
1538 nt_devmode->icmmethod = devmode->icmmethod;
1539 nt_devmode->icmintent = devmode->icmintent;
1540 nt_devmode->mediatype = devmode->mediatype;
1541 nt_devmode->dithertype = devmode->dithertype;
1542 nt_devmode->reserved1 = devmode->reserved1;
1543 nt_devmode->reserved2 = devmode->reserved2;
1544 nt_devmode->panningwidth = devmode->panningwidth;
1545 nt_devmode->panningheight = devmode->panningheight;
1548 * Only change private and driverextra if the incoming devmode
1549 * has a new one. JRA.
1552 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1553 SAFE_FREE(nt_devmode->nt_dev_private);
1554 nt_devmode->driverextra = devmode->__driverextra_length;
1555 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1557 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1560 *pp_nt_devmode = nt_devmode;
1565 /****************************************************************
1566 _spoolss_OpenPrinterEx
1567 ****************************************************************/
1569 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1570 struct spoolss_OpenPrinterEx *r)
1572 POLICY_HND *handle = r->out.handle;
1573 char *name = CONST_DISCARD(char *, r->in.printername);
1575 Printer_entry *Printer=NULL;
1578 return WERR_INVALID_PARAM;
1581 /* some sanity check because you can open a printer or a print server */
1582 /* aka: \\server\printer or \\server */
1584 DEBUGADD(3,("checking name: %s\n",name));
1586 if (!open_printer_hnd(p, handle, name, 0)) {
1587 ZERO_STRUCTP(r->out.handle);
1588 return WERR_INVALID_PARAM;
1591 Printer=find_printer_index_by_hnd(p, handle);
1593 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1594 "handle we created for printer %s\n", name ));
1595 close_printer_handle(p,handle);
1596 ZERO_STRUCTP(r->out.handle);
1597 return WERR_INVALID_PARAM;
1601 * First case: the user is opening the print server:
1603 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1604 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1606 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1607 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1608 * or if the user is listed in the smb.conf printer admin parameter.
1610 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1611 * client view printer folder, but does not show the MSAPW.
1613 * Note: this test needs code to check access rights here too. Jeremy
1614 * could you look at this?
1616 * Second case: the user is opening a printer:
1617 * NT doesn't let us connect to a printer if the connecting user
1618 * doesn't have print permission.
1620 * Third case: user is opening a Port Monitor
1621 * access checks same as opening a handle to the print server.
1624 switch (Printer->printer_type )
1627 case SPLHND_PORTMON_TCP:
1628 case SPLHND_PORTMON_LOCAL:
1629 /* Printserver handles use global struct... */
1633 /* Map standard access rights to object specific access rights */
1635 se_map_standard(&r->in.access_mask,
1636 &printserver_std_mapping);
1638 /* Deny any object specific bits that don't apply to print
1639 servers (i.e printer and job specific bits) */
1641 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1643 if (r->in.access_mask &
1644 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1645 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1646 close_printer_handle(p, handle);
1647 ZERO_STRUCTP(r->out.handle);
1648 return WERR_ACCESS_DENIED;
1651 /* Allow admin access */
1653 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1655 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1657 if (!lp_ms_add_printer_wizard()) {
1658 close_printer_handle(p, handle);
1659 ZERO_STRUCTP(r->out.handle);
1660 return WERR_ACCESS_DENIED;
1663 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1664 and not a printer admin, then fail */
1666 if ((p->server_info->utok.uid != 0) &&
1667 !user_has_privileges(p->server_info->ptok,
1669 !token_contains_name_in_list(
1670 uidtoname(p->server_info->utok.uid),
1672 p->server_info->ptok,
1673 lp_printer_admin(snum))) {
1674 close_printer_handle(p, handle);
1675 ZERO_STRUCTP(r->out.handle);
1676 return WERR_ACCESS_DENIED;
1679 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1683 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1686 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1687 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1689 /* We fall through to return WERR_OK */
1692 case SPLHND_PRINTER:
1693 /* NT doesn't let us connect to a printer if the connecting user
1694 doesn't have print permission. */
1696 if (!get_printer_snum(p, handle, &snum, NULL)) {
1697 close_printer_handle(p, handle);
1698 ZERO_STRUCTP(r->out.handle);
1702 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1704 /* map an empty access mask to the minimum access mask */
1705 if (r->in.access_mask == 0x0)
1706 r->in.access_mask = PRINTER_ACCESS_USE;
1709 * If we are not serving the printer driver for this printer,
1710 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1711 * will keep NT clients happy --jerry
1714 if (lp_use_client_driver(snum)
1715 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1717 r->in.access_mask = PRINTER_ACCESS_USE;
1720 /* check smb.conf parameters and the the sec_desc */
1722 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1723 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1724 ZERO_STRUCTP(r->out.handle);
1725 return WERR_ACCESS_DENIED;
1728 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1729 p->server_info->ptok, snum) ||
1730 !print_access_check(p->server_info, snum,
1731 r->in.access_mask)) {
1732 DEBUG(3, ("access DENIED for printer open\n"));
1733 close_printer_handle(p, handle);
1734 ZERO_STRUCTP(r->out.handle);
1735 return WERR_ACCESS_DENIED;
1738 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1739 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1740 close_printer_handle(p, handle);
1741 ZERO_STRUCTP(r->out.handle);
1742 return WERR_ACCESS_DENIED;
1745 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1746 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1748 r->in.access_mask = PRINTER_ACCESS_USE;
1750 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1751 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1756 /* sanity check to prevent programmer error */
1757 ZERO_STRUCTP(r->out.handle);
1761 Printer->access_granted = r->in.access_mask;
1764 * If the client sent a devmode in the OpenPrinter() call, then
1765 * save it here in case we get a job submission on this handle
1768 if ( (Printer->printer_type != SPLHND_SERVER)
1769 && r->in.devmode_ctr.devmode )
1771 convert_devicemode_new(Printer->sharename,
1772 r->in.devmode_ctr.devmode,
1773 &Printer->nt_devmode);
1776 #if 0 /* JERRY -- I'm doubtful this is really effective */
1777 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1778 optimization in Windows 2000 clients --jerry */
1780 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1781 && (RA_WIN2K == get_remote_arch()) )
1783 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1784 sys_usleep( 500000 );
1791 /****************************************************************************
1792 ****************************************************************************/
1794 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1795 NT_PRINTER_INFO_LEVEL_2 *d)
1797 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1803 d->attributes = r->attributes;
1804 d->priority = r->priority;
1805 d->default_priority = r->defaultpriority;
1806 d->starttime = r->starttime;
1807 d->untiltime = r->untiltime;
1808 d->status = r->status;
1809 d->cjobs = r->cjobs;
1811 fstrcpy(d->servername, r->servername);
1812 fstrcpy(d->printername, r->printername);
1813 fstrcpy(d->sharename, r->sharename);
1814 fstrcpy(d->portname, r->portname);
1815 fstrcpy(d->drivername, r->drivername);
1816 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1817 fstrcpy(d->location, r->location);
1818 fstrcpy(d->sepfile, r->sepfile);
1819 fstrcpy(d->printprocessor, r->printprocessor);
1820 fstrcpy(d->datatype, r->datatype);
1821 fstrcpy(d->parameters, r->parameters);
1826 /****************************************************************************
1827 ****************************************************************************/
1829 static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
1830 NT_PRINTER_INFO_LEVEL *printer)
1834 switch (info_ctr->level) {
1836 /* allocate memory if needed. Messy because
1837 convert_printer_info is used to update an existing
1838 printer or build a new one */
1840 if (!printer->info_2) {
1841 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1842 if (!printer->info_2) {
1843 DEBUG(0,("convert_printer_info_new: "
1844 "talloc() failed!\n"));
1849 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1851 printer->info_2->setuptime = time(NULL);
1858 /*******************************************************************
1859 ********************************************************************/
1861 static bool string_array_to_fstring_array(const char **sarray, fstring **farray)
1870 *farray = SMB_MALLOC_ARRAY(fstring, 1);
1875 for (i=0; sarray[i] != NULL; i++) {
1876 *farray = SMB_REALLOC_ARRAY(*farray, fstring, i+2);
1880 fstrcpy((*farray)[i], sarray[i]);
1883 fstrcpy((*farray)[i], "");
1888 /*******************************************************************
1889 ********************************************************************/
1891 static bool driver_info3_to_nt_driver_info3(struct spoolss_AddDriverInfo3 *r,
1892 NT_PRINTER_DRIVER_INFO_LEVEL_3 **p)
1894 NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
1896 DEBUG(7,("driver_info3_to_nt_driver_info3: Converting from UNICODE to ASCII\n"));
1899 *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
1908 d->cversion = r->version;
1910 fstrcpy(d->name, r->driver_name);
1911 fstrcpy(d->environment, r->architecture);
1912 fstrcpy(d->driverpath, r->driver_path);
1913 fstrcpy(d->datafile, r->data_file);
1914 fstrcpy(d->configfile, r->config_file);
1915 fstrcpy(d->helpfile, r->help_file);
1916 fstrcpy(d->monitorname, r->monitor_name);
1917 fstrcpy(d->defaultdatatype, r->default_datatype);
1919 DEBUGADD(8,( "version: %d\n", d->cversion));
1920 DEBUGADD(8,( "name: %s\n", d->name));
1921 DEBUGADD(8,( "environment: %s\n", d->environment));
1922 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
1923 DEBUGADD(8,( "datafile: %s\n", d->datafile));
1924 DEBUGADD(8,( "configfile: %s\n", d->configfile));
1925 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
1926 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
1927 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
1929 if (r->dependent_files) {
1930 if (!string_array_to_fstring_array(r->dependent_files->string,
1931 &d->dependentfiles)) {
1940 /*******************************************************************
1941 ********************************************************************/
1943 static bool driver_info6_to_nt_driver_info6(struct spoolss_AddDriverInfo6 *r,
1944 NT_PRINTER_DRIVER_INFO_LEVEL_6 **p)
1946 NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
1948 DEBUG(7,("driver_info6_to_nt_driver_info6: Converting from UNICODE to ASCII\n"));
1951 *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
1960 d->version = r->version;
1962 fstrcpy(d->name, r->driver_name);
1963 fstrcpy(d->environment, r->architecture);
1964 fstrcpy(d->driverpath, r->driver_path);
1965 fstrcpy(d->datafile, r->data_file);
1966 fstrcpy(d->configfile, r->config_file);
1967 fstrcpy(d->helpfile, r->help_file);
1968 fstrcpy(d->monitorname, r->monitor_name);
1969 fstrcpy(d->defaultdatatype, r->default_datatype);
1971 DEBUGADD(8,( "version: %d\n", d->version));
1972 DEBUGADD(8,( "name: %s\n", d->name));
1973 DEBUGADD(8,( "environment: %s\n", d->environment));
1974 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
1975 DEBUGADD(8,( "datafile: %s\n", d->datafile));
1976 DEBUGADD(8,( "configfile: %s\n", d->configfile));
1977 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
1978 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
1979 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
1981 if (r->dependent_files) {
1982 if (!string_array_to_fstring_array(r->dependent_files->string,
1983 &d->dependentfiles)) {
1988 if (r->previous_names) {
1989 if (!string_array_to_fstring_array(r->previous_names->string,
1990 &d->previousnames)) {
2002 /********************************************************************
2003 ********************************************************************/
2005 static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr *r,
2006 NT_PRINTER_DRIVER_INFO_LEVEL *printer,
2011 printer->info_3 = NULL;
2012 if (!driver_info3_to_nt_driver_info3(r->info.info3, &printer->info_3)) {
2017 printer->info_6 = NULL;
2018 if (!driver_info6_to_nt_driver_info6(r->info.info6, &printer->info_6)) {
2029 bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
2030 NT_DEVICEMODE **pp_nt_devmode)
2032 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
2035 * Ensure nt_devmode is a valid pointer
2036 * as we will be overwriting it.
2039 if (nt_devmode == NULL) {
2040 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
2041 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
2045 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
2046 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
2048 nt_devmode->specversion=devmode->specversion;
2049 nt_devmode->driverversion=devmode->driverversion;
2050 nt_devmode->size=devmode->size;
2051 nt_devmode->fields=devmode->fields;
2052 nt_devmode->orientation=devmode->orientation;
2053 nt_devmode->papersize=devmode->papersize;
2054 nt_devmode->paperlength=devmode->paperlength;
2055 nt_devmode->paperwidth=devmode->paperwidth;
2056 nt_devmode->scale=devmode->scale;
2057 nt_devmode->copies=devmode->copies;
2058 nt_devmode->defaultsource=devmode->defaultsource;
2059 nt_devmode->printquality=devmode->printquality;
2060 nt_devmode->color=devmode->color;
2061 nt_devmode->duplex=devmode->duplex;
2062 nt_devmode->yresolution=devmode->yresolution;
2063 nt_devmode->ttoption=devmode->ttoption;
2064 nt_devmode->collate=devmode->collate;
2066 nt_devmode->logpixels=devmode->logpixels;
2067 nt_devmode->bitsperpel=devmode->bitsperpel;
2068 nt_devmode->pelswidth=devmode->pelswidth;
2069 nt_devmode->pelsheight=devmode->pelsheight;
2070 nt_devmode->displayflags=devmode->displayflags;
2071 nt_devmode->displayfrequency=devmode->displayfrequency;
2072 nt_devmode->icmmethod=devmode->icmmethod;
2073 nt_devmode->icmintent=devmode->icmintent;
2074 nt_devmode->mediatype=devmode->mediatype;
2075 nt_devmode->dithertype=devmode->dithertype;
2076 nt_devmode->reserved1=devmode->reserved1;
2077 nt_devmode->reserved2=devmode->reserved2;
2078 nt_devmode->panningwidth=devmode->panningwidth;
2079 nt_devmode->panningheight=devmode->panningheight;
2082 * Only change private and driverextra if the incoming devmode
2083 * has a new one. JRA.
2086 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
2087 SAFE_FREE(nt_devmode->nt_dev_private);
2088 nt_devmode->driverextra=devmode->driverextra;
2089 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
2091 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
2094 *pp_nt_devmode = nt_devmode;
2099 /********************************************************************
2100 * _spoolss_enddocprinter_internal.
2101 ********************************************************************/
2103 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
2105 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2109 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
2113 if (!get_printer_snum(p, handle, &snum, NULL))
2116 Printer->document_started=False;
2117 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
2118 /* error codes unhandled so far ... */
2123 /****************************************************************
2124 _spoolss_ClosePrinter
2125 ****************************************************************/
2127 WERROR _spoolss_ClosePrinter(pipes_struct *p,
2128 struct spoolss_ClosePrinter *r)
2130 POLICY_HND *handle = r->in.handle;
2132 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2134 if (Printer && Printer->document_started)
2135 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2137 if (!close_printer_handle(p, handle))
2140 /* clear the returned printer handle. Observed behavior
2141 from Win2k server. Don't think this really matters.
2142 Previous code just copied the value of the closed
2145 ZERO_STRUCTP(r->out.handle);
2150 /****************************************************************
2151 _spoolss_DeletePrinter
2152 ****************************************************************/
2154 WERROR _spoolss_DeletePrinter(pipes_struct *p,
2155 struct spoolss_DeletePrinter *r)
2157 POLICY_HND *handle = r->in.handle;
2158 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2161 if (Printer && Printer->document_started)
2162 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2164 result = delete_printer_handle(p, handle);
2166 update_c_setprinter(False);
2171 /*******************************************************************
2172 * static function to lookup the version id corresponding to an
2173 * long architecture string
2174 ******************************************************************/
2176 static int get_version_id (char * arch)
2179 struct table_node archi_table[]= {
2181 {"Windows 4.0", "WIN40", 0 },
2182 {"Windows NT x86", "W32X86", 2 },
2183 {"Windows NT R4000", "W32MIPS", 2 },
2184 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
2185 {"Windows NT PowerPC", "W32PPC", 2 },
2186 {"Windows IA64", "IA64", 3 },
2187 {"Windows x64", "x64", 3 },
2191 for (i=0; archi_table[i].long_archi != NULL; i++)
2193 if (strcmp(arch, archi_table[i].long_archi) == 0)
2194 return (archi_table[i].version);
2200 /****************************************************************
2201 _spoolss_DeletePrinterDriver
2202 ****************************************************************/
2204 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
2205 struct spoolss_DeletePrinterDriver *r)
2209 NT_PRINTER_DRIVER_INFO_LEVEL info;
2210 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2213 WERROR status_win2k = WERR_ACCESS_DENIED;
2214 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2216 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2217 and not a printer admin, then fail */
2219 if ( (p->server_info->utok.uid != 0)
2220 && !user_has_privileges(p->server_info->ptok, &se_printop )
2221 && !token_contains_name_in_list(
2222 uidtoname(p->server_info->utok.uid), NULL,
2223 NULL, p->server_info->ptok,
2224 lp_printer_admin(-1)) )
2226 return WERR_ACCESS_DENIED;
2229 driver = CONST_DISCARD(char *, r->in.driver);
2230 arch = CONST_DISCARD(char *, r->in.architecture);
2232 /* check that we have a valid driver name first */
2234 if ((version=get_version_id(arch)) == -1)
2235 return WERR_INVALID_ENVIRONMENT;
2238 ZERO_STRUCT(info_win2k);
2240 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2242 /* try for Win2k driver if "Windows NT x86" */
2244 if ( version == 2 ) {
2246 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2247 status = WERR_UNKNOWN_PRINTER_DRIVER;
2251 /* otherwise it was a failure */
2253 status = WERR_UNKNOWN_PRINTER_DRIVER;
2259 if (printer_driver_in_use(info.info_3)) {
2260 status = WERR_PRINTER_DRIVER_IN_USE;
2266 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2268 /* if we get to here, we now have 2 driver info structures to remove */
2269 /* remove the Win2k driver first*/
2271 status_win2k = delete_printer_driver(
2272 p, info_win2k.info_3, 3, False );
2273 free_a_printer_driver( info_win2k, 3 );
2275 /* this should not have failed---if it did, report to client */
2276 if ( !W_ERROR_IS_OK(status_win2k) )
2278 status = status_win2k;
2284 status = delete_printer_driver(p, info.info_3, version, False);
2286 /* if at least one of the deletes succeeded return OK */
2288 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2292 free_a_printer_driver( info, 3 );
2297 /****************************************************************
2298 _spoolss_DeletePrinterDriverEx
2299 ****************************************************************/
2301 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2302 struct spoolss_DeletePrinterDriverEx *r)
2306 NT_PRINTER_DRIVER_INFO_LEVEL info;
2307 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2309 uint32_t flags = r->in.delete_flags;
2312 WERROR status_win2k = WERR_ACCESS_DENIED;
2313 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2315 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2316 and not a printer admin, then fail */
2318 if ( (p->server_info->utok.uid != 0)
2319 && !user_has_privileges(p->server_info->ptok, &se_printop )
2320 && !token_contains_name_in_list(
2321 uidtoname(p->server_info->utok.uid), NULL, NULL,
2322 p->server_info->ptok, lp_printer_admin(-1)) )
2324 return WERR_ACCESS_DENIED;
2327 driver = CONST_DISCARD(char *, r->in.driver);
2328 arch = CONST_DISCARD(char *, r->in.architecture);
2330 /* check that we have a valid driver name first */
2331 if ((version=get_version_id(arch)) == -1) {
2332 /* this is what NT returns */
2333 return WERR_INVALID_ENVIRONMENT;
2336 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2337 version = r->in.version;
2340 ZERO_STRUCT(info_win2k);
2342 status = get_a_printer_driver(&info, 3, driver, arch, version);
2344 if ( !W_ERROR_IS_OK(status) )
2347 * if the client asked for a specific version,
2348 * or this is something other than Windows NT x86,
2352 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2355 /* try for Win2k driver if "Windows NT x86" */
2358 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2359 status = WERR_UNKNOWN_PRINTER_DRIVER;
2364 if ( printer_driver_in_use(info.info_3) ) {
2365 status = WERR_PRINTER_DRIVER_IN_USE;
2370 * we have a couple of cases to consider.
2371 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2372 * then the delete should fail if **any** files overlap with
2374 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2375 * non-overlapping files
2376 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2377 * is set, the do not delete any files
2378 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2381 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2383 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2385 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2386 /* no idea of the correct error here */
2387 status = WERR_ACCESS_DENIED;
2392 /* also check for W32X86/3 if necessary; maybe we already have? */
2394 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2395 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2398 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2399 /* no idea of the correct error here */
2400 free_a_printer_driver( info_win2k, 3 );
2401 status = WERR_ACCESS_DENIED;
2405 /* if we get to here, we now have 2 driver info structures to remove */
2406 /* remove the Win2k driver first*/
2408 status_win2k = delete_printer_driver(
2409 p, info_win2k.info_3, 3, delete_files);
2410 free_a_printer_driver( info_win2k, 3 );
2412 /* this should not have failed---if it did, report to client */
2414 if ( !W_ERROR_IS_OK(status_win2k) )
2419 status = delete_printer_driver(p, info.info_3, version, delete_files);
2421 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2424 free_a_printer_driver( info, 3 );
2430 /****************************************************************************
2431 Internal routine for retreiving printerdata
2432 ***************************************************************************/
2434 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2435 const char *key, const char *value, uint32 *type, uint8 **data,
2436 uint32 *needed, uint32 in_size )
2438 REGISTRY_VALUE *val;
2442 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2443 return WERR_BADFILE;
2445 *type = regval_type( val );
2447 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2449 size = regval_size( val );
2451 /* copy the min(in_size, len) */
2454 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2456 /* special case for 0 length values */
2458 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2462 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2471 DEBUG(5,("get_printer_dataex: copy done\n"));
2476 /****************************************************************************
2477 Internal routine for removing printerdata
2478 ***************************************************************************/
2480 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2482 return delete_printer_data( printer->info_2, key, value );
2485 /****************************************************************************
2486 Internal routine for storing printerdata
2487 ***************************************************************************/
2489 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2490 uint32 type, uint8 *data, int real_len )
2492 /* the registry objects enforce uniqueness based on value name */
2494 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2497 /********************************************************************
2498 GetPrinterData on a printer server Handle.
2499 ********************************************************************/
2501 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2505 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2507 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2509 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2511 SIVAL(*data, 0, 0x00);
2516 if (!StrCaseCmp(value, "BeepEnabled")) {
2518 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2520 SIVAL(*data, 0, 0x00);
2525 if (!StrCaseCmp(value, "EventLog")) {
2527 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2529 /* formally was 0x1b */
2530 SIVAL(*data, 0, 0x0);
2535 if (!StrCaseCmp(value, "NetPopup")) {
2537 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2539 SIVAL(*data, 0, 0x00);
2544 if (!StrCaseCmp(value, "MajorVersion")) {
2546 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2549 /* Windows NT 4.0 seems to not allow uploading of drivers
2550 to a server that reports 0x3 as the MajorVersion.
2551 need to investigate more how Win2k gets around this .
2554 if ( RA_WINNT == get_remote_arch() )
2563 if (!StrCaseCmp(value, "MinorVersion")) {
2565 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2573 * uint32 size = 0x114
2575 * uint32 minor = [0|1]
2576 * uint32 build = [2195|2600]
2577 * extra unicode string = e.g. "Service Pack 3"
2579 if (!StrCaseCmp(value, "OSVersion")) {
2583 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2586 SIVAL(*data, 0, *needed); /* size */
2587 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2589 SIVAL(*data, 12, 2195); /* build */
2591 /* leave extra string empty */
2597 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2598 const char *string="C:\\PRINTERS";
2600 *needed = 2*(strlen(string)+1);
2601 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2603 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2605 /* it's done by hand ready to go on the wire */
2606 for (i=0; i<strlen(string); i++) {
2607 (*data)[2*i]=string[i];
2608 (*data)[2*i+1]='\0';
2613 if (!StrCaseCmp(value, "Architecture")) {
2614 const char *string="Windows NT x86";
2616 *needed = 2*(strlen(string)+1);
2617 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2619 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2620 for (i=0; i<strlen(string); i++) {
2621 (*data)[2*i]=string[i];
2622 (*data)[2*i+1]='\0';
2627 if (!StrCaseCmp(value, "DsPresent")) {
2629 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2632 /* only show the publish check box if we are a
2633 memeber of a AD domain */
2635 if ( lp_security() == SEC_ADS )
2636 SIVAL(*data, 0, 0x01);
2638 SIVAL(*data, 0, 0x00);
2644 if (!StrCaseCmp(value, "DNSMachineName")) {
2645 const char *hostname = get_mydnsfullname();
2648 return WERR_BADFILE;
2650 *needed = 2*(strlen(hostname)+1);
2651 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2653 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2654 for (i=0; i<strlen(hostname); i++) {
2655 (*data)[2*i]=hostname[i];
2656 (*data)[2*i+1]='\0';
2662 return WERR_BADFILE;
2665 /********************************************************************
2666 * spoolss_getprinterdata
2667 ********************************************************************/
2669 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2671 POLICY_HND *handle = &q_u->handle;
2672 UNISTR2 *valuename = &q_u->valuename;
2673 uint32 in_size = q_u->size;
2674 uint32 *type = &r_u->type;
2675 uint32 *out_size = &r_u->size;
2676 uint8 **data = &r_u->data;
2677 uint32 *needed = &r_u->needed;
2680 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2681 NT_PRINTER_INFO_LEVEL *printer = NULL;
2685 * Reminder: when it's a string, the length is in BYTES
2686 * even if UNICODE is negociated.
2691 *out_size = in_size;
2693 /* in case of problem, return some default values */
2698 DEBUG(4,("_spoolss_getprinterdata\n"));
2701 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2702 status = WERR_BADFID;
2706 unistr2_to_ascii(value, valuename, sizeof(value));
2708 if ( Printer->printer_type == SPLHND_SERVER )
2709 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2712 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2713 status = WERR_BADFID;
2717 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2718 if ( !W_ERROR_IS_OK(status) )
2721 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2723 if ( strequal(value, "ChangeId") ) {
2725 *needed = sizeof(uint32);
2726 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2727 status = WERR_NOMEM;
2730 SIVAL( *data, 0, printer->info_2->changeid );
2734 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2737 if (*needed > *out_size)
2738 status = WERR_MORE_DATA;
2741 if ( !W_ERROR_IS_OK(status) )
2743 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2745 /* reply this param doesn't exist */
2748 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2750 free_a_printer( &printer, 2 );
2758 /* cleanup & exit */
2761 free_a_printer( &printer, 2 );
2766 /*********************************************************
2767 Connect to the client machine.
2768 **********************************************************/
2770 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2771 struct sockaddr_storage *client_ss, const char *remote_machine)
2774 struct cli_state *the_cli;
2775 struct sockaddr_storage rm_addr;
2777 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2778 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2779 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2783 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2784 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2788 char addr[INET6_ADDRSTRLEN];
2789 rm_addr = *client_ss;
2790 print_sockaddr(addr, sizeof(addr), &rm_addr);
2791 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2795 /* setup the connection */
2797 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2798 &rm_addr, 0, "IPC$", "IPC",
2802 0, lp_client_signing(), NULL );
2804 if ( !NT_STATUS_IS_OK( ret ) ) {
2805 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2810 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2811 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2812 cli_shutdown(the_cli);
2817 * Ok - we have an anonymous connection to the IPC$ share.
2818 * Now start the NT Domain stuff :-).
2821 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2822 if (!NT_STATUS_IS_OK(ret)) {
2823 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2824 remote_machine, nt_errstr(ret)));
2825 cli_shutdown(the_cli);
2832 /***************************************************************************
2833 Connect to the client.
2834 ****************************************************************************/
2836 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2837 uint32 localprinter, uint32 type,
2838 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2844 * If it's the first connection, contact the client
2845 * and connect to the IPC$ share anonymously
2847 if (smb_connections==0) {
2848 fstring unix_printer;
2850 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2852 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2855 messaging_register(smbd_messaging_context(), NULL,
2856 MSG_PRINTER_NOTIFY2,
2857 receive_notify2_message_list);
2858 /* Tell the connections db we're now interested in printer
2859 * notify messages. */
2860 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2864 * Tell the specific printing tdb we want messages for this printer
2865 * by registering our PID.
2868 if (!print_notify_register_pid(snum))
2869 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2873 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2881 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2882 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2883 win_errstr(result)));
2885 return (W_ERROR_IS_OK(result));
2888 /********************************************************************
2890 * ReplyFindFirstPrinterChangeNotifyEx
2892 * before replying OK: status=0 a rpc call is made to the workstation
2893 * asking ReplyOpenPrinter
2895 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2896 * called from api_spoolss_rffpcnex
2897 ********************************************************************/
2899 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2901 POLICY_HND *handle = &q_u->handle;
2902 uint32 flags = q_u->flags;
2903 uint32 options = q_u->options;
2904 UNISTR2 *localmachine = &q_u->localmachine;
2905 uint32 printerlocal = q_u->printerlocal;
2907 SPOOL_NOTIFY_OPTION *option = q_u->option;
2908 struct sockaddr_storage client_ss;
2910 /* store the notify value in the printer struct */
2912 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2915 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2919 Printer->notify.flags=flags;
2920 Printer->notify.options=options;
2921 Printer->notify.printerlocal=printerlocal;
2923 if (Printer->notify.option)
2924 free_spool_notify_option(&Printer->notify.option);
2926 Printer->notify.option=dup_spool_notify_option(option);
2928 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
2929 sizeof(Printer->notify.localmachine));
2931 /* Connect to the client machine and send a ReplyOpenPrinter */
2933 if ( Printer->printer_type == SPLHND_SERVER)
2935 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2936 !get_printer_snum(p, handle, &snum, NULL) )
2939 if (!interpret_string_addr(&client_ss, p->client_address,
2941 return WERR_SERVER_UNAVAILABLE;
2944 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2945 Printer->notify.printerlocal, 1,
2946 &Printer->notify.client_hnd, &client_ss))
2947 return WERR_SERVER_UNAVAILABLE;
2949 Printer->notify.client_connected=True;
2954 /*******************************************************************
2955 * fill a notify_info_data with the servername
2956 ********************************************************************/
2958 void spoolss_notify_server_name(int snum,
2959 struct spoolss_Notify *data,
2960 print_queue_struct *queue,
2961 NT_PRINTER_INFO_LEVEL *printer,
2962 TALLOC_CTX *mem_ctx)
2964 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2967 /*******************************************************************
2968 * fill a notify_info_data with the printername (not including the servername).
2969 ********************************************************************/
2971 void spoolss_notify_printer_name(int snum,
2972 struct spoolss_Notify *data,
2973 print_queue_struct *queue,
2974 NT_PRINTER_INFO_LEVEL *printer,
2975 TALLOC_CTX *mem_ctx)
2977 /* the notify name should not contain the \\server\ part */
2978 char *p = strrchr(printer->info_2->printername, '\\');
2981 p = printer->info_2->printername;
2986 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2989 /*******************************************************************
2990 * fill a notify_info_data with the servicename
2991 ********************************************************************/
2993 void spoolss_notify_share_name(int snum,
2994 struct spoolss_Notify *data,
2995 print_queue_struct *queue,
2996 NT_PRINTER_INFO_LEVEL *printer,
2997 TALLOC_CTX *mem_ctx)
2999 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
3002 /*******************************************************************
3003 * fill a notify_info_data with the port name
3004 ********************************************************************/
3006 void spoolss_notify_port_name(int snum,
3007 struct spoolss_Notify *data,
3008 print_queue_struct *queue,
3009 NT_PRINTER_INFO_LEVEL *printer,
3010 TALLOC_CTX *mem_ctx)
3012 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
3015 /*******************************************************************
3016 * fill a notify_info_data with the printername
3017 * but it doesn't exist, have to see what to do
3018 ********************************************************************/
3020 void spoolss_notify_driver_name(int snum,
3021 struct spoolss_Notify *data,
3022 print_queue_struct *queue,
3023 NT_PRINTER_INFO_LEVEL *printer,
3024 TALLOC_CTX *mem_ctx)
3026 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
3029 /*******************************************************************
3030 * fill a notify_info_data with the comment
3031 ********************************************************************/
3033 void spoolss_notify_comment(int snum,
3034 struct spoolss_Notify *data,
3035 print_queue_struct *queue,
3036 NT_PRINTER_INFO_LEVEL *printer,
3037 TALLOC_CTX *mem_ctx)
3041 if (*printer->info_2->comment == '\0') {
3042 p = lp_comment(snum);
3044 p = printer->info_2->comment;
3047 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
3050 /*******************************************************************
3051 * fill a notify_info_data with the comment
3052 * location = "Room 1, floor 2, building 3"
3053 ********************************************************************/
3055 void spoolss_notify_location(int snum,
3056 struct spoolss_Notify *data,
3057 print_queue_struct *queue,
3058 NT_PRINTER_INFO_LEVEL *printer,
3059 TALLOC_CTX *mem_ctx)
3061 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
3064 /*******************************************************************
3065 * fill a notify_info_data with the device mode
3066 * jfm:xxxx don't to it for know but that's a real problem !!!
3067 ********************************************************************/
3069 static void spoolss_notify_devmode(int snum,
3070 struct spoolss_Notify *data,
3071 print_queue_struct *queue,
3072 NT_PRINTER_INFO_LEVEL *printer,
3073 TALLOC_CTX *mem_ctx)
3075 /* for a dummy implementation we have to zero the fields */
3076 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
3079 /*******************************************************************
3080 * fill a notify_info_data with the separator file name
3081 ********************************************************************/
3083 void spoolss_notify_sepfile(int snum,
3084 struct spoolss_Notify *data,
3085 print_queue_struct *queue,
3086 NT_PRINTER_INFO_LEVEL *printer,
3087 TALLOC_CTX *mem_ctx)
3089 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
3092 /*******************************************************************
3093 * fill a notify_info_data with the print processor
3094 * jfm:xxxx return always winprint to indicate we don't do anything to it
3095 ********************************************************************/
3097 void spoolss_notify_print_processor(int snum,
3098 struct spoolss_Notify *data,
3099 print_queue_struct *queue,
3100 NT_PRINTER_INFO_LEVEL *printer,
3101 TALLOC_CTX *mem_ctx)
3103 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
3106 /*******************************************************************
3107 * fill a notify_info_data with the print processor options
3108 * jfm:xxxx send an empty string
3109 ********************************************************************/
3111 void spoolss_notify_parameters(int snum,
3112 struct spoolss_Notify *data,
3113 print_queue_struct *queue,
3114 NT_PRINTER_INFO_LEVEL *printer,
3115 TALLOC_CTX *mem_ctx)
3117 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
3120 /*******************************************************************
3121 * fill a notify_info_data with the data type
3122 * jfm:xxxx always send RAW as data type
3123 ********************************************************************/
3125 void spoolss_notify_datatype(int snum,
3126 struct spoolss_Notify *data,
3127 print_queue_struct *queue,
3128 NT_PRINTER_INFO_LEVEL *printer,
3129 TALLOC_CTX *mem_ctx)
3131 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
3134 /*******************************************************************
3135 * fill a notify_info_data with the security descriptor
3136 * jfm:xxxx send an null pointer to say no security desc
3137 * have to implement security before !
3138 ********************************************************************/
3140 static void spoolss_notify_security_desc(int snum,
3141 struct spoolss_Notify *data,
3142 print_queue_struct *queue,
3143 NT_PRINTER_INFO_LEVEL *printer,
3144 TALLOC_CTX *mem_ctx)
3146 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
3147 printer->info_2->secdesc_buf->sd_size,
3148 printer->info_2->secdesc_buf->sd);
3151 /*******************************************************************
3152 * fill a notify_info_data with the attributes
3153 * jfm:xxxx a samba printer is always shared
3154 ********************************************************************/
3156 void spoolss_notify_attributes(int snum,
3157 struct spoolss_Notify *data,
3158 print_queue_struct *queue,
3159 NT_PRINTER_INFO_LEVEL *printer,
3160 TALLOC_CTX *mem_ctx)
3162 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
3165 /*******************************************************************
3166 * fill a notify_info_data with the priority
3167 ********************************************************************/
3169 static void spoolss_notify_priority(int snum,
3170 struct spoolss_Notify *data,
3171 print_queue_struct *queue,
3172 NT_PRINTER_INFO_LEVEL *printer,
3173 TALLOC_CTX *mem_ctx)
3175 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
3178 /*******************************************************************
3179 * fill a notify_info_data with the default priority
3180 ********************************************************************/
3182 static void spoolss_notify_default_priority(int snum,
3183 struct spoolss_Notify *data,
3184 print_queue_struct *queue,
3185 NT_PRINTER_INFO_LEVEL *printer,
3186 TALLOC_CTX *mem_ctx)
3188 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
3191 /*******************************************************************
3192 * fill a notify_info_data with the start time
3193 ********************************************************************/
3195 static void spoolss_notify_start_time(int snum,
3196 struct spoolss_Notify *data,
3197 print_queue_struct *queue,
3198 NT_PRINTER_INFO_LEVEL *printer,
3199 TALLOC_CTX *mem_ctx)
3201 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
3204 /*******************************************************************
3205 * fill a notify_info_data with the until time
3206 ********************************************************************/
3208 static void spoolss_notify_until_time(int snum,
3209 struct spoolss_Notify *data,
3210 print_queue_struct *queue,
3211 NT_PRINTER_INFO_LEVEL *printer,
3212 TALLOC_CTX *mem_ctx)
3214 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
3217 /*******************************************************************
3218 * fill a notify_info_data with the status
3219 ********************************************************************/
3221 static void spoolss_notify_status(int snum,
3222 struct spoolss_Notify *data,
3223 print_queue_struct *queue,
3224 NT_PRINTER_INFO_LEVEL *printer,
3225 TALLOC_CTX *mem_ctx)
3227 print_status_struct status;
3229 print_queue_length(snum, &status);
3230 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
3233 /*******************************************************************
3234 * fill a notify_info_data with the number of jobs queued
3235 ********************************************************************/
3237 void spoolss_notify_cjobs(int snum,
3238 struct spoolss_Notify *data,
3239 print_queue_struct *queue,
3240 NT_PRINTER_INFO_LEVEL *printer,
3241 TALLOC_CTX *mem_ctx)
3243 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
3246 /*******************************************************************
3247 * fill a notify_info_data with the average ppm
3248 ********************************************************************/
3250 static void spoolss_notify_average_ppm(int snum,
3251 struct spoolss_Notify *data,
3252 print_queue_struct *queue,
3253 NT_PRINTER_INFO_LEVEL *printer,
3254 TALLOC_CTX *mem_ctx)
3256 /* always respond 8 pages per minutes */
3257 /* a little hard ! */
3258 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
3261 /*******************************************************************
3262 * fill a notify_info_data with username
3263 ********************************************************************/
3265 static void spoolss_notify_username(int snum,
3266 struct spoolss_Notify *data,
3267 print_queue_struct *queue,
3268 NT_PRINTER_INFO_LEVEL *printer,
3269 TALLOC_CTX *mem_ctx)
3271 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
3274 /*******************************************************************
3275 * fill a notify_info_data with job status
3276 ********************************************************************/
3278 static void spoolss_notify_job_status(int snum,
3279 struct spoolss_Notify *data,
3280 print_queue_struct *queue,
3281 NT_PRINTER_INFO_LEVEL *printer,
3282 TALLOC_CTX *mem_ctx)
3284 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
3287 /*******************************************************************
3288 * fill a notify_info_data with job name
3289 ********************************************************************/
3291 static void spoolss_notify_job_name(int snum,
3292 struct spoolss_Notify *data,
3293 print_queue_struct *queue,
3294 NT_PRINTER_INFO_LEVEL *printer,
3295 TALLOC_CTX *mem_ctx)
3297 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
3300 /*******************************************************************
3301 * fill a notify_info_data with job status
3302 ********************************************************************/
3304 static void spoolss_notify_job_status_string(int snum,
3305 struct spoolss_Notify *data,
3306 print_queue_struct *queue,
3307 NT_PRINTER_INFO_LEVEL *printer,
3308 TALLOC_CTX *mem_ctx)
3311 * Now we're returning job status codes we just return a "" here. JRA.
3316 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3319 switch (queue->status) {
3324 p = ""; /* NT provides the paused string */
3333 #endif /* NO LONGER NEEDED. */
3335 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3338 /*******************************************************************
3339 * fill a notify_info_data with job time
3340 ********************************************************************/
3342 static void spoolss_notify_job_time(int snum,
3343 struct spoolss_Notify *data,
3344 print_queue_struct *queue,
3345 NT_PRINTER_INFO_LEVEL *printer,
3346 TALLOC_CTX *mem_ctx)
3348 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3351 /*******************************************************************
3352 * fill a notify_info_data with job size
3353 ********************************************************************/
3355 static void spoolss_notify_job_size(int snum,
3356 struct spoolss_Notify *data,
3357 print_queue_struct *queue,
3358 NT_PRINTER_INFO_LEVEL *printer,
3359 TALLOC_CTX *mem_ctx)
3361 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3364 /*******************************************************************
3365 * fill a notify_info_data with page info
3366 ********************************************************************/
3367 static void spoolss_notify_total_pages(int snum,
3368 struct spoolss_Notify *data,
3369 print_queue_struct *queue,
3370 NT_PRINTER_INFO_LEVEL *printer,
3371 TALLOC_CTX *mem_ctx)
3373 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3376 /*******************************************************************
3377 * fill a notify_info_data with pages printed info.
3378 ********************************************************************/
3379 static void spoolss_notify_pages_printed(int snum,
3380 struct spoolss_Notify *data,
3381 print_queue_struct *queue,
3382 NT_PRINTER_INFO_LEVEL *printer,
3383 TALLOC_CTX *mem_ctx)
3385 /* Add code when back-end tracks this */
3386 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3389 /*******************************************************************
3390 Fill a notify_info_data with job position.
3391 ********************************************************************/
3393 static void spoolss_notify_job_position(int snum,
3394 struct spoolss_Notify *data,
3395 print_queue_struct *queue,
3396 NT_PRINTER_INFO_LEVEL *printer,
3397 TALLOC_CTX *mem_ctx)
3399 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3402 /*******************************************************************
3403 Fill a notify_info_data with submitted time.
3404 ********************************************************************/
3406 static void spoolss_notify_submitted_time(int snum,
3407 struct spoolss_Notify *data,
3408 print_queue_struct *queue,
3409 NT_PRINTER_INFO_LEVEL *printer,
3410 TALLOC_CTX *mem_ctx)
3412 data->data.string.string = NULL;
3413 data->data.string.size = 0;
3415 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3416 &data->data.string.string,
3417 &data->data.string.size);
3421 struct s_notify_info_data_table
3423 enum spoolss_NotifyType type;
3424 enum spoolss_Field field;
3426 enum spoolss_NotifyTable variable_type;
3427 void (*fn) (int snum, struct spoolss_Notify *data,
3428 print_queue_struct *queue,
3429 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3432 /* A table describing the various print notification constants and
3433 whether the notification data is a pointer to a variable sized
3434 buffer, a one value uint32 or a two value uint32. */
3436 static const struct s_notify_info_data_table notify_info_data_table[] =
3438 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3439 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3440 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3441 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3442 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3443 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3444 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3445 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3446 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3447 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3448 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3449 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3450 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3451 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3452 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3453 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3454 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3455 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3456 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3457 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3458 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3459 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3460 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3461 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3462 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3463 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3464 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3465 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3466 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3467 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3468 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3469 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3470 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3471 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3472 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3473 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3474 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3475 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3476 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3477 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3478 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3479 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3480 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3481 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3482 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3483 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3484 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3485 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3486 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3487 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3490 /*******************************************************************
3491 Return the variable_type of info_data structure.
3492 ********************************************************************/
3494 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3495 enum spoolss_Field field)
3499 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3500 if ( (notify_info_data_table[i].type == type) &&
3501 (notify_info_data_table[i].field == field) ) {
3502 return notify_info_data_table[i].variable_type;
3506 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3511 /****************************************************************************
3512 ****************************************************************************/
3514 static bool search_notify(uint16 type, uint16 field, int *value)
3518 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3519 if (notify_info_data_table[i].type == type &&
3520 notify_info_data_table[i].field == field &&
3521 notify_info_data_table[i].fn != NULL) {
3530 /****************************************************************************
3531 ****************************************************************************/
3533 void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id)
3535 info_data->type = type;
3536 info_data->field = field;
3537 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3538 info_data->job_id = id;
3541 /*******************************************************************
3543 * fill a notify_info struct with info asked
3545 ********************************************************************/
3547 static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spoolss_NotifyInfo *info, int
3548 snum, SPOOL_NOTIFY_OPTION_TYPE
3549 *option_type, uint32 id,
3550 TALLOC_CTX *mem_ctx)
3556 struct spoolss_Notify *current_data;
3557 NT_PRINTER_INFO_LEVEL *printer = NULL;
3558 print_queue_struct *queue=NULL;
3560 type=option_type->type;
3562 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3563 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3564 option_type->count, lp_servicename(snum)));
3566 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3569 for(field_num=0; field_num<option_type->count; field_num++) {
3570 field = option_type->fields[field_num];
3572 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3574 if (!search_notify(type, field, &j) )
3577 if((info->notifies = SMB_REALLOC_ARRAY(info->notifies, struct spoolss_Notify, info->count+1)) == NULL) {
3578 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3579 free_a_printer(&printer, 2);
3583 current_data = &info->notifies[info->count];
3585 construct_info_data(current_data, type, field, id);
3587 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3588 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3590 notify_info_data_table[j].fn(snum, current_data, queue,
3596 free_a_printer(&printer, 2);
3600 /*******************************************************************
3602 * fill a notify_info struct with info asked
3604 ********************************************************************/
3606 static bool construct_notify_jobs_info(print_queue_struct *queue,
3607 struct spoolss_NotifyInfo *info,
3608 NT_PRINTER_INFO_LEVEL *printer,
3609 int snum, SPOOL_NOTIFY_OPTION_TYPE
3610 *option_type, uint32 id,
3611 TALLOC_CTX *mem_ctx)
3617 struct spoolss_Notify *current_data;
3619 DEBUG(4,("construct_notify_jobs_info\n"));
3621 type = option_type->type;
3623 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3624 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3625 option_type->count));
3627 for(field_num=0; field_num<option_type->count; field_num++) {
3628 field = option_type->fields[field_num];
3630 if (!search_notify(type, field, &j) )
3633 if((info->notifies = SMB_REALLOC_ARRAY(info->notifies, struct spoolss_Notify, info->count+1)) == NULL) {
3634 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3638 current_data=&(info->notifies[info->count]);
3640 construct_info_data(current_data, type, field, id);
3641 notify_info_data_table[j].fn(snum, current_data, queue,
3650 * JFM: The enumeration is not that simple, it's even non obvious.
3652 * let's take an example: I want to monitor the PRINTER SERVER for
3653 * the printer's name and the number of jobs currently queued.
3654 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3655 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3657 * I have 3 printers on the back of my server.
3659 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3662 * 1 printer 1 name 1
3663 * 2 printer 1 cjob 1
3664 * 3 printer 2 name 2
3665 * 4 printer 2 cjob 2
3666 * 5 printer 3 name 3
3667 * 6 printer 3 name 3
3669 * that's the print server case, the printer case is even worse.
3672 /*******************************************************************
3674 * enumerate all printers on the printserver
3675 * fill a notify_info struct with info asked
3677 ********************************************************************/
3679 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3680 struct spoolss_NotifyInfo *info,
3681 TALLOC_CTX *mem_ctx)
3684 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3685 int n_services=lp_numservices();
3687 SPOOL_NOTIFY_OPTION *option;
3688 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3690 DEBUG(4,("printserver_notify_info\n"));
3695 option=Printer->notify.option;
3698 info->notifies = NULL;
3701 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3702 sending a ffpcn() request first */
3707 for (i=0; i<option->count; i++) {
3708 option_type=&(option->ctr.type[i]);
3710 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3713 for (snum=0; snum<n_services; snum++)
3715 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3716 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3722 * Debugging information, don't delete.
3725 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3726 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3727 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3729 for (i=0; i<info->count; i++) {
3730 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3731 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3732 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3739 /*******************************************************************
3741 * fill a notify_info struct with info asked
3743 ********************************************************************/
3745 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info,
3746 TALLOC_CTX *mem_ctx)
3749 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3752 SPOOL_NOTIFY_OPTION *option;
3753 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3755 print_queue_struct *queue=NULL;
3756 print_status_struct status;
3758 DEBUG(4,("printer_notify_info\n"));
3763 option=Printer->notify.option;
3767 info->notifies = NULL;
3770 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3771 sending a ffpcn() request first */
3776 get_printer_snum(p, hnd, &snum, NULL);
3778 for (i=0; i<option->count; i++) {
3779 option_type=&option->ctr.type[i];
3781 switch ( option_type->type ) {
3782 case PRINTER_NOTIFY_TYPE:
3783 if(construct_notify_printer_info(Printer, info, snum,
3789 case JOB_NOTIFY_TYPE: {
3790 NT_PRINTER_INFO_LEVEL *printer = NULL;
3792 count = print_queue_status(snum, &queue, &status);
3794 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3797 for (j=0; j<count; j++) {
3798 construct_notify_jobs_info(&queue[j], info,
3805 free_a_printer(&printer, 2);
3815 * Debugging information, don't delete.
3818 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3819 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3820 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3822 for (i=0; i<info->count; i++) {
3823 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3824 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3825 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3831 /****************************************************************
3832 _spoolss_RouterRefreshPrinterChangeNotify
3833 ****************************************************************/
3835 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3836 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3838 POLICY_HND *handle = r->in.handle;
3839 struct spoolss_NotifyInfo *info;
3841 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3842 WERROR result = WERR_BADFID;
3844 /* we always have a spoolss_NotifyInfo struct */
3845 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3847 result = WERR_NOMEM;
3851 *r->out.info = info;
3854 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3855 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
3859 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3862 * We are now using the change value, and
3863 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3864 * I don't have a global notification system, I'm sending back all the
3865 * informations even when _NOTHING_ has changed.
3868 /* We need to keep track of the change value to send back in
3869 RRPCN replies otherwise our updates are ignored. */
3871 Printer->notify.fnpcn = True;
3873 if (Printer->notify.client_connected) {
3874 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3875 "Saving change value in request [%x]\n",
3877 Printer->notify.change = r->in.change_low;
3880 /* just ignore the SPOOL_NOTIFY_OPTION */
3882 switch (Printer->printer_type) {
3884 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3887 case SPLHND_PRINTER:
3888 result = printer_notify_info(p, handle, info, p->mem_ctx);
3892 Printer->notify.fnpcn = False;
3898 /********************************************************************
3899 * construct_printer_info_0
3900 * fill a printer_info_0 struct
3901 ********************************************************************/
3903 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3905 char *chaine = NULL;
3907 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3908 counter_printer_0 *session_counter;
3909 uint32 global_counter;
3912 print_status_struct status;
3913 TALLOC_CTX *ctx = talloc_tos();
3915 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3918 init_unistr(&printer->printername, ntprinter->info_2->printername);
3920 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3922 free_a_printer(&ntprinter,2);
3926 count = print_queue_length(snum, &status);
3928 /* check if we already have a counter for this printer */
3929 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3930 if (session_counter->snum == snum)
3934 init_unistr(&printer->servername, chaine);
3936 /* it's the first time, add it to the list */
3937 if (session_counter==NULL) {
3938 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3939 free_a_printer(&ntprinter, 2);
3942 ZERO_STRUCTP(session_counter);
3943 session_counter->snum=snum;
3944 session_counter->counter=0;
3945 DLIST_ADD(counter_list, session_counter);
3949 session_counter->counter++;
3952 * the global_counter should be stored in a TDB as it's common to all the clients
3953 * and should be zeroed on samba startup
3955 global_counter=session_counter->counter;
3956 printer->cjobs = count;
3957 printer->total_jobs = 0;
3958 printer->total_bytes = 0;
3960 setuptime = (time_t)ntprinter->info_2->setuptime;
3961 t=gmtime(&setuptime);
3963 printer->year = t->tm_year+1900;
3964 printer->month = t->tm_mon+1;
3965 printer->dayofweek = t->tm_wday;
3966 printer->day = t->tm_mday;
3967 printer->hour = t->tm_hour;
3968 printer->minute = t->tm_min;
3969 printer->second = t->tm_sec;
3970 printer->milliseconds = 0;
3972 printer->global_counter = global_counter;
3973 printer->total_pages = 0;
3975 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3976 printer->major_version = 0x0005; /* NT 5 */
3977 printer->build_version = 0x0893; /* build 2195 */
3979 printer->unknown7 = 0x1;
3980 printer->unknown8 = 0x0;
3981 printer->unknown9 = 0x0;
3982 printer->session_counter = session_counter->counter;
3983 printer->unknown11 = 0x0;
3984 printer->printer_errors = 0x0; /* number of print failure */
3985 printer->unknown13 = 0x0;
3986 printer->unknown14 = 0x1;
3987 printer->unknown15 = 0x024a; /* 586 Pentium ? */
3988 printer->unknown16 = 0x0;
3989 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3990 printer->unknown18 = 0x0;
3991 printer->status = nt_printq_status(status.status);
3992 printer->unknown20 = 0x0;
3993 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3994 printer->unknown22 = 0x0;
3995 printer->unknown23 = 0x6; /* 6 ???*/
3996 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
3997 printer->unknown25 = 0;
3998 printer->unknown26 = 0;
3999 printer->unknown27 = 0;
4000 printer->unknown28 = 0;
4001 printer->unknown29 = 0;
4003 free_a_printer(&ntprinter,2);
4007 /********************************************************************
4008 * construct_printer_info_1
4009 * fill a printer_info_1 struct
4010 ********************************************************************/
4011 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4013 char *chaine = NULL;
4014 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4015 TALLOC_CTX *ctx = talloc_tos();
4017 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4020 printer->flags=flags;
4022 if (*ntprinter->info_2->comment == '\0') {
4023 init_unistr(&printer->comment, lp_comment(snum));
4024 chaine = talloc_asprintf(ctx,
4025 "%s,%s,%s", ntprinter->info_2->printername,
4026 ntprinter->info_2->drivername, lp_comment(snum));
4029 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4030 chaine = talloc_asprintf(ctx,
4031 "%s,%s,%s", ntprinter->info_2->printername,
4032 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4036 free_a_printer(&ntprinter,2);
4040 init_unistr(&printer->description, chaine);
4041 init_unistr(&printer->name, ntprinter->info_2->printername);
4043 free_a_printer(&ntprinter,2);
4048 /****************************************************************************
4049 Free a DEVMODE struct.
4050 ****************************************************************************/
4052 static void free_dev_mode(DEVICEMODE *dev)
4057 SAFE_FREE(dev->dev_private);
4062 /****************************************************************************
4063 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4064 should be valid upon entry
4065 ****************************************************************************/
4067 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4069 if ( !devmode || !ntdevmode )
4072 init_unistr(&devmode->devicename, ntdevmode->devicename);
4074 init_unistr(&devmode->formname, ntdevmode->formname);
4076 devmode->specversion = ntdevmode->specversion;
4077 devmode->driverversion = ntdevmode->driverversion;
4078 devmode->size = ntdevmode->size;
4079 devmode->driverextra = ntdevmode->driverextra;
4080 devmode->fields = ntdevmode->fields;
4082 devmode->orientation = ntdevmode->orientation;
4083 devmode->papersize = ntdevmode->papersize;
4084 devmode->paperlength = ntdevmode->paperlength;
4085 devmode->paperwidth = ntdevmode->paperwidth;
4086 devmode->scale = ntdevmode->scale;
4087 devmode->copies = ntdevmode->copies;
4088 devmode->defaultsource = ntdevmode->defaultsource;
4089 devmode->printquality = ntdevmode->printquality;
4090 devmode->color = ntdevmode->color;
4091 devmode->duplex = ntdevmode->duplex;
4092 devmode->yresolution = ntdevmode->yresolution;
4093 devmode->ttoption = ntdevmode->ttoption;
4094 devmode->collate = ntdevmode->collate;
4095 devmode->icmmethod = ntdevmode->icmmethod;
4096 devmode->icmintent = ntdevmode->icmintent;
4097 devmode->mediatype = ntdevmode->mediatype;
4098 devmode->dithertype = ntdevmode->dithertype;
4100 if (ntdevmode->nt_dev_private != NULL) {
4101 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4108 /****************************************************************************
4109 Create a DEVMODE struct. Returns malloced memory.
4110 ****************************************************************************/
4112 DEVICEMODE *construct_dev_mode(const char *servicename)
4114 NT_PRINTER_INFO_LEVEL *printer = NULL;
4115 DEVICEMODE *devmode = NULL;
4117 DEBUG(7,("construct_dev_mode\n"));
4119 DEBUGADD(8,("getting printer characteristics\n"));
4121 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4124 if ( !printer->info_2->devmode ) {
4125 DEBUG(5, ("BONG! There was no device mode!\n"));
4129 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4130 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4134 ZERO_STRUCTP(devmode);
4136 DEBUGADD(8,("loading DEVICEMODE\n"));
4138 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4139 free_dev_mode( devmode );
4144 free_a_printer(&printer,2);
4149 /********************************************************************
4150 * construct_printer_info_2
4151 * fill a printer_info_2 struct
4152 ********************************************************************/
4154 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4157 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4159 print_status_struct status;
4161 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4164 count = print_queue_length(snum, &status);
4166 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4167 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4168 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4169 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4170 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4172 if (*ntprinter->info_2->comment == '\0')
4173 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4175 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4177 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4178 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4179 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4180 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4181 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4183 printer->attributes = ntprinter->info_2->attributes;
4185 printer->priority = ntprinter->info_2->priority; /* priority */
4186 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4187 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4188 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4189 printer->status = nt_printq_status(status.status); /* status */
4190 printer->cjobs = count; /* jobs */
4191 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4193 if ( !(printer->devmode = construct_dev_mode(
4194 lp_const_servicename(snum))) )
4195 DEBUG(8, ("Returning NULL Devicemode!\n"));
4197 printer->secdesc = NULL;
4199 if ( ntprinter->info_2->secdesc_buf
4200 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4202 /* don't use talloc_steal() here unless you do a deep steal of all
4203 the SEC_DESC members */
4205 printer->secdesc = dup_sec_desc( talloc_tos(),
4206 ntprinter->info_2->secdesc_buf->sd );
4209 free_a_printer(&ntprinter, 2);
4214 /********************************************************************
4215 * construct_printer_info_3
4216 * fill a printer_info_3 struct
4217 ********************************************************************/
4219 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4221 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4222 PRINTER_INFO_3 *printer = NULL;
4224 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4228 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4229 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4230 free_a_printer(&ntprinter, 2);
4234 ZERO_STRUCTP(printer);
4236 /* These are the components of the SD we are returning. */
4238 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4239 /* don't use talloc_steal() here unless you do a deep steal of all
4240 the SEC_DESC members */
4242 printer->secdesc = dup_sec_desc( talloc_tos(),
4243 ntprinter->info_2->secdesc_buf->sd );
4246 free_a_printer(&ntprinter, 2);
4248 *pp_printer = printer;
4252 /********************************************************************
4253 * construct_printer_info_4
4254 * fill a printer_info_4 struct
4255 ********************************************************************/
4257 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4259 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4261 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4264 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4265 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4266 printer->attributes = ntprinter->info_2->attributes;
4268 free_a_printer(&ntprinter, 2);
4272 /********************************************************************
4273 * construct_printer_info_5
4274 * fill a printer_info_5 struct
4275 ********************************************************************/
4277 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4279 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4281 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4284 init_unistr(&printer->printername, ntprinter->info_2->printername);
4285 init_unistr(&printer->portname, ntprinter->info_2->portname);
4286 printer->attributes = ntprinter->info_2->attributes;
4288 /* these two are not used by NT+ according to MSDN */
4290 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4291 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4293 free_a_printer(&ntprinter, 2);
4298 /********************************************************************
4299 * construct_printer_info_6
4300 * fill a printer_info_6 struct
4301 ********************************************************************/
4303 static bool construct_printer_info_6(Printer_entry *print_hnd,
4304 PRINTER_INFO_6 *printer,
4307 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4309 print_status_struct status;
4311 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4312 lp_const_servicename(snum))))
4315 count = print_queue_length(snum, &status);
4317 printer->status = nt_printq_status(status.status);
4319 free_a_printer(&ntprinter, 2);
4324 /********************************************************************
4325 * construct_printer_info_7
4326 * fill a printer_info_7 struct
4327 ********************************************************************/
4329 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4331 char *guid_str = NULL;
4334 if (is_printer_published(print_hnd, snum, &guid)) {
4335 if (asprintf(&guid_str, "{%s}",
4336 GUID_string(talloc_tos(), &guid)) == -1) {
4339 strupper_m(guid_str);
4340 init_unistr(&printer->guid, guid_str);
4341 SAFE_FREE(guid_str);
4342 printer->action = SPOOL_DS_PUBLISH;
4344 init_unistr(&printer->guid, "");
4345 printer->action = SPOOL_DS_UNPUBLISH;
4351 /********************************************************************
4352 Spoolss_enumprinters.
4353 ********************************************************************/
4355 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4359 int n_services=lp_numservices();
4360 PRINTER_INFO_1 *printers=NULL;
4361 PRINTER_INFO_1 current_prt;
4362 WERROR result = WERR_OK;
4364 DEBUG(4,("enum_all_printers_info_1\n"));
4366 for (snum=0; snum<n_services; snum++) {
4367 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4368 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4370 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4371 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4372 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4376 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4378 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4384 /* check the required size. */
4385 for (i=0; i<*returned; i++)
4386 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4388 if (*needed > offered) {
4389 result = WERR_INSUFFICIENT_BUFFER;
4393 if (!rpcbuf_alloc_size(buffer, *needed)) {
4394 result = WERR_NOMEM;
4398 /* fill the buffer with the structures */
4399 for (i=0; i<*returned; i++)
4400 smb_io_printer_info_1("", buffer, &printers[i], 0);
4405 SAFE_FREE(printers);
4407 if ( !W_ERROR_IS_OK(result) )
4413 /********************************************************************
4414 enum_all_printers_info_1_local.
4415 *********************************************************************/
4417 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4419 DEBUG(4,("enum_all_printers_info_1_local\n"));
4421 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4424 /********************************************************************
4425 enum_all_printers_info_1_name.
4426 *********************************************************************/
4428 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4432 DEBUG(4,("enum_all_printers_info_1_name\n"));
4434 if ((name[0] == '\\') && (name[1] == '\\'))
4437 if (is_myname_or_ipaddr(s)) {
4438 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4441 return WERR_INVALID_NAME;
4444 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4445 /********************************************************************
4446 enum_all_printers_info_1_remote.
4447 *********************************************************************/
4449 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4451 PRINTER_INFO_1 *printer;
4452 fstring printername;
4455 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4456 WERROR result = WERR_OK;
4458 /* JFM: currently it's more a place holder than anything else.
4459 * In the spooler world there is a notion of server registration.
4460 * the print servers are registered on the PDC (in the same domain)
4462 * We should have a TDB here. The registration is done thru an
4463 * undocumented RPC call.
4466 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4471 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4472 slprintf(desc, sizeof(desc)-1,"%s", name);
4473 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4475 init_unistr(&printer->description, desc);
4476 init_unistr(&printer->name, printername);
4477 init_unistr(&printer->comment, comment);
4478 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4480 /* check the required size. */
4481 *needed += spoolss_size_printer_info_1(printer);
4483 if (*needed > offered) {
4484 result = WERR_INSUFFICIENT_BUFFER;
4488 if (!rpcbuf_alloc_size(buffer, *needed)) {
4489 result = WERR_NOMEM;
4493 /* fill the buffer with the structures */
4494 smb_io_printer_info_1("", buffer, printer, 0);
4500 if ( !W_ERROR_IS_OK(result) )
4508 /********************************************************************
4509 enum_all_printers_info_1_network.
4510 *********************************************************************/
4512 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4516 DEBUG(4,("enum_all_printers_info_1_network\n"));
4518 /* If we respond to a enum_printers level 1 on our name with flags
4519 set to PRINTER_ENUM_REMOTE with a list of printers then these
4520 printers incorrectly appear in the APW browse list.
4521 Specifically the printers for the server appear at the workgroup
4522 level where all the other servers in the domain are
4523 listed. Windows responds to this call with a
4524 WERR_CAN_NOT_COMPLETE so we should do the same. */
4526 if (name[0] == '\\' && name[1] == '\\')
4529 if (is_myname_or_ipaddr(s))
4530 return WERR_CAN_NOT_COMPLETE;
4532 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4535 /********************************************************************
4536 * api_spoolss_enumprinters
4538 * called from api_spoolss_enumprinters (see this to understand)
4539 ********************************************************************/
4541 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4545 int n_services=lp_numservices();
4546 PRINTER_INFO_2 *printers=NULL;
4547 PRINTER_INFO_2 current_prt;
4548 WERROR result = WERR_OK;
4552 for (snum=0; snum<n_services; snum++) {
4553 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4554 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4556 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4557 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4558 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4563 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4565 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4572 /* check the required size. */
4573 for (i=0; i<*returned; i++)
4574 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4576 if (*needed > offered) {
4577 result = WERR_INSUFFICIENT_BUFFER;
4581 if (!rpcbuf_alloc_size(buffer, *needed)) {
4582 result = WERR_NOMEM;
4586 /* fill the buffer with the structures */
4587 for (i=0; i<*returned; i++)
4588 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4593 for (i=0; i<*returned; i++)
4594 free_devmode(printers[i].devmode);
4596 SAFE_FREE(printers);
4598 if ( !W_ERROR_IS_OK(result) )
4604 /********************************************************************
4605 * handle enumeration of printers at level 1
4606 ********************************************************************/
4608 static WERROR enumprinters_level1( uint32 flags, fstring name,
4609 RPC_BUFFER *buffer, uint32 offered,
4610 uint32 *needed, uint32 *returned)
4612 /* Not all the flags are equals */
4614 if (flags & PRINTER_ENUM_LOCAL)
4615 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4617 if (flags & PRINTER_ENUM_NAME)
4618 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4620 #if 0 /* JERRY - disabled for now */
4621 if (flags & PRINTER_ENUM_REMOTE)
4622 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4625 if (flags & PRINTER_ENUM_NETWORK)
4626 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4628 return WERR_OK; /* NT4sp5 does that */
4631 /********************************************************************
4632 * handle enumeration of printers at level 2
4633 ********************************************************************/
4635 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4636 RPC_BUFFER *buffer, uint32 offered,
4637 uint32 *needed, uint32 *returned)
4639 if (flags & PRINTER_ENUM_LOCAL) {
4640 return enum_all_printers_info_2(buffer, offered, needed, returned);
4643 if (flags & PRINTER_ENUM_NAME) {
4644 if (is_myname_or_ipaddr(canon_servername(servername)))
4645 return enum_all_printers_info_2(buffer, offered, needed, returned);
4647 return WERR_INVALID_NAME;
4650 if (flags & PRINTER_ENUM_REMOTE)
4651 return WERR_UNKNOWN_LEVEL;
4656 /********************************************************************
4657 * handle enumeration of printers at level 5
4658 ********************************************************************/
4660 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4661 RPC_BUFFER *buffer, uint32 offered,
4662 uint32 *needed, uint32 *returned)
4664 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4668 /********************************************************************
4669 * api_spoolss_enumprinters
4671 * called from api_spoolss_enumprinters (see this to understand)
4672 ********************************************************************/
4674 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4676 uint32 flags = q_u->flags;
4677 UNISTR2 *servername = &q_u->servername;
4678 uint32 level = q_u->level;
4679 RPC_BUFFER *buffer = NULL;
4680 uint32 offered = q_u->offered;
4681 uint32 *needed = &r_u->needed;
4682 uint32 *returned = &r_u->returned;
4686 /* that's an [in out] buffer */
4688 if (!q_u->buffer && (offered!=0)) {
4689 return WERR_INVALID_PARAM;
4692 if (offered > MAX_RPC_DATA_SIZE) {
4693 return WERR_INVALID_PARAM;
4696 rpcbuf_move(q_u->buffer, &r_u->buffer);
4697 buffer = r_u->buffer;
4699 DEBUG(4,("_spoolss_enumprinters\n"));
4706 * flags==PRINTER_ENUM_NAME
4707 * if name=="" then enumerates all printers
4708 * if name!="" then enumerate the printer
4709 * flags==PRINTER_ENUM_REMOTE
4710 * name is NULL, enumerate printers
4711 * Level 2: name!="" enumerates printers, name can't be NULL
4712 * Level 3: doesn't exist
4713 * Level 4: does a local registry lookup
4714 * Level 5: same as Level 2
4717 unistr2_to_ascii(name, servername, sizeof(name));
4722 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4724 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4726 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4731 return WERR_UNKNOWN_LEVEL;
4734 /****************************************************************************
4735 ****************************************************************************/
4737 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4739 PRINTER_INFO_0 *printer=NULL;
4740 WERROR result = WERR_OK;
4742 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4745 construct_printer_info_0(print_hnd, printer, snum);
4747 /* check the required size. */
4748 *needed += spoolss_size_printer_info_0(printer);
4750 if (*needed > offered) {
4751 result = WERR_INSUFFICIENT_BUFFER;
4755 if (!rpcbuf_alloc_size(buffer, *needed)) {
4756 result = WERR_NOMEM;
4760 /* fill the buffer with the structures */
4761 smb_io_printer_info_0("", buffer, printer, 0);
4771 /****************************************************************************
4772 ****************************************************************************/
4774 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4776 PRINTER_INFO_1 *printer=NULL;
4777 WERROR result = WERR_OK;
4779 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4782 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4784 /* check the required size. */
4785 *needed += spoolss_size_printer_info_1(printer);
4787 if (*needed > offered) {
4788 result = WERR_INSUFFICIENT_BUFFER;
4792 if (!rpcbuf_alloc_size(buffer, *needed)) {
4793 result = WERR_NOMEM;
4797 /* fill the buffer with the structures */
4798 smb_io_printer_info_1("", buffer, printer, 0);
4807 /****************************************************************************
4808 ****************************************************************************/
4810 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4812 PRINTER_INFO_2 *printer=NULL;
4813 WERROR result = WERR_OK;
4815 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4818 construct_printer_info_2(print_hnd, printer, snum);
4820 /* check the required size. */
4821 *needed += spoolss_size_printer_info_2(printer);
4823 if (*needed > offered) {
4824 result = WERR_INSUFFICIENT_BUFFER;
4828 if (!rpcbuf_alloc_size(buffer, *needed)) {
4829 result = WERR_NOMEM;
4833 /* fill the buffer with the structures */
4834 if (!smb_io_printer_info_2("", buffer, printer, 0))
4835 result = WERR_NOMEM;
4839 free_printer_info_2(printer);
4844 /****************************************************************************
4845 ****************************************************************************/
4847 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4849 PRINTER_INFO_3 *printer=NULL;
4850 WERROR result = WERR_OK;
4852 if (!construct_printer_info_3(print_hnd, &printer, snum))
4855 /* check the required size. */
4856 *needed += spoolss_size_printer_info_3(printer);
4858 if (*needed > offered) {
4859 result = WERR_INSUFFICIENT_BUFFER;
4863 if (!rpcbuf_alloc_size(buffer, *needed)) {
4864 result = WERR_NOMEM;
4868 /* fill the buffer with the structures */
4869 smb_io_printer_info_3("", buffer, printer, 0);
4873 free_printer_info_3(printer);
4878 /****************************************************************************
4879 ****************************************************************************/
4881 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4883 PRINTER_INFO_4 *printer=NULL;
4884 WERROR result = WERR_OK;
4886 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4889 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4894 /* check the required size. */
4895 *needed += spoolss_size_printer_info_4(printer);
4897 if (*needed > offered) {
4898 result = WERR_INSUFFICIENT_BUFFER;
4902 if (!rpcbuf_alloc_size(buffer, *needed)) {
4903 result = WERR_NOMEM;
4907 /* fill the buffer with the structures */
4908 smb_io_printer_info_4("", buffer, printer, 0);
4912 free_printer_info_4(printer);
4917 /****************************************************************************
4918 ****************************************************************************/
4920 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4922 PRINTER_INFO_5 *printer=NULL;
4923 WERROR result = WERR_OK;
4925 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4928 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4929 free_printer_info_5(printer);
4933 /* check the required size. */
4934 *needed += spoolss_size_printer_info_5(printer);
4936 if (*needed > offered) {
4937 result = WERR_INSUFFICIENT_BUFFER;
4941 if (!rpcbuf_alloc_size(buffer, *needed)) {
4942 result = WERR_NOMEM;
4946 /* fill the buffer with the structures */
4947 smb_io_printer_info_5("", buffer, printer, 0);
4951 free_printer_info_5(printer);
4956 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4958 RPC_BUFFER *buffer, uint32 offered,
4961 PRINTER_INFO_6 *printer;
4962 WERROR result = WERR_OK;
4964 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4968 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4969 free_printer_info_6(printer);
4973 /* check the required size. */
4974 *needed += spoolss_size_printer_info_6(printer);
4976 if (*needed > offered) {
4977 result = WERR_INSUFFICIENT_BUFFER;
4981 if (!rpcbuf_alloc_size(buffer, *needed)) {
4982 result = WERR_NOMEM;
4986 /* fill the buffer with the structures */
4987 smb_io_printer_info_6("", buffer, printer, 0);
4991 free_printer_info_6(printer);
4996 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4998 PRINTER_INFO_7 *printer=NULL;
4999 WERROR result = WERR_OK;
5001 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5004 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5005 result = WERR_NOMEM;
5009 /* check the required size. */
5010 *needed += spoolss_size_printer_info_7(printer);
5012 if (*needed > offered) {
5013 result = WERR_INSUFFICIENT_BUFFER;
5017 if (!rpcbuf_alloc_size(buffer, *needed)) {
5018 result = WERR_NOMEM;
5023 /* fill the buffer with the structures */
5024 smb_io_printer_info_7("", buffer, printer, 0);
5028 free_printer_info_7(printer);
5033 /****************************************************************************
5034 ****************************************************************************/
5036 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5038 POLICY_HND *handle = &q_u->handle;
5039 uint32 level = q_u->level;
5040 RPC_BUFFER *buffer = NULL;
5041 uint32 offered = q_u->offered;
5042 uint32 *needed = &r_u->needed;
5043 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5047 /* that's an [in out] buffer */
5049 if (!q_u->buffer && (offered!=0)) {
5050 return WERR_INVALID_PARAM;
5053 if (offered > MAX_RPC_DATA_SIZE) {
5054 return WERR_INVALID_PARAM;
5057 rpcbuf_move(q_u->buffer, &r_u->buffer);
5058 buffer = r_u->buffer;
5062 if (!get_printer_snum(p, handle, &snum, NULL))
5067 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5069 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5071 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5073 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5075 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5077 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5079 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5081 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5083 return WERR_UNKNOWN_LEVEL;
5086 /********************************************************************
5087 * fill a DRIVER_INFO_1 struct
5088 ********************************************************************/
5090 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5092 init_unistr( &info->name, driver.info_3->name);
5095 /********************************************************************
5096 * construct_printer_driver_info_1
5097 ********************************************************************/
5099 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5101 NT_PRINTER_INFO_LEVEL *printer = NULL;
5102 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5104 ZERO_STRUCT(driver);
5106 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5107 return WERR_INVALID_PRINTER_NAME;
5109 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5110 free_a_printer(&printer, 2);
5111 return WERR_UNKNOWN_PRINTER_DRIVER;
5114 fill_printer_driver_info_1(info, driver, servername, architecture);
5116 free_a_printer(&printer,2);
5121 /********************************************************************
5122 * construct_printer_driver_info_2
5123 * fill a printer_info_2 struct
5124 ********************************************************************/
5126 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5128 TALLOC_CTX *ctx = talloc_tos();
5130 const char *cservername = canon_servername(servername);
5132 info->version=driver.info_3->cversion;
5134 init_unistr( &info->name, driver.info_3->name );
5135 init_unistr( &info->architecture, driver.info_3->environment );
5137 if (strlen(driver.info_3->driverpath)) {
5138 temp = talloc_asprintf(ctx,
5141 driver.info_3->driverpath);
5142 init_unistr( &info->driverpath, temp );
5144 init_unistr( &info->driverpath, "" );
5148 if (strlen(driver.info_3->datafile)) {
5149 temp = talloc_asprintf(ctx,
5152 driver.info_3->datafile);
5153 init_unistr( &info->datafile, temp );
5155 init_unistr( &info->datafile, "" );
5158 if (strlen(driver.info_3->configfile)) {
5159 temp = talloc_asprintf(ctx,
5162 driver.info_3->configfile);
5163 init_unistr( &info->configfile, temp );
5165 init_unistr( &info->configfile, "" );
5168 /********************************************************************
5169 * construct_printer_driver_info_2
5170 * fill a printer_info_2 struct
5171 ********************************************************************/
5173 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5175 NT_PRINTER_INFO_LEVEL *printer = NULL;
5176 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5178 ZERO_STRUCT(printer);
5179 ZERO_STRUCT(driver);
5181 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5182 return WERR_INVALID_PRINTER_NAME;
5184 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5185 free_a_printer(&printer, 2);
5186 return WERR_UNKNOWN_PRINTER_DRIVER;
5189 fill_printer_driver_info_2(info, driver, servername);
5191 free_a_printer(&printer,2);
5196 /********************************************************************
5197 * copy a strings array and convert to UNICODE
5199 * convert an array of ascii string to a UNICODE string
5200 ********************************************************************/
5202 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5208 TALLOC_CTX *ctx = talloc_tos();
5210 DEBUG(6,("init_unistr_array\n"));
5214 if ( !char_array ) {
5219 v = ""; /* hack to handle null lists */
5222 /* hack to allow this to be used in places other than when generating
5223 the list of dependent files */
5227 line = talloc_asprintf(ctx,
5229 canon_servername(servername),
5232 line = talloc_strdup(ctx, v);
5236 SAFE_FREE(*uni_array);
5239 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5241 /* add one extra unit16 for the second terminating NULL */
5243 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5244 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5251 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5256 /* special case for ""; we need to add both NULL's here */
5258 (*uni_array)[j++]=0x0000;
5259 (*uni_array)[j]=0x0000;
5262 DEBUGADD(6,("last one:done\n"));
5264 /* return size of array in uint16's */
5269 /********************************************************************
5270 * construct_printer_info_3
5271 * fill a printer_info_3 struct
5272 ********************************************************************/
5274 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5277 TALLOC_CTX *ctx = talloc_tos();
5278 const char *cservername = canon_servername(servername);
5282 info->version=driver.info_3->cversion;
5284 init_unistr( &info->name, driver.info_3->name );
5285 init_unistr( &info->architecture, driver.info_3->environment );
5287 if (strlen(driver.info_3->driverpath)) {
5288 temp = talloc_asprintf(ctx,
5291 driver.info_3->driverpath);
5292 init_unistr( &info->driverpath, temp );
5294 init_unistr( &info->driverpath, "" );
5297 if (strlen(driver.info_3->datafile)) {
5298 temp = talloc_asprintf(ctx,
5301 driver.info_3->datafile);
5302 init_unistr( &info->datafile, temp );
5304 init_unistr( &info->datafile, "" );
5307 if (strlen(driver.info_3->configfile)) {
5308 temp = talloc_asprintf(ctx,
5311 driver.info_3->configfile);
5312 init_unistr( &info->configfile, temp );
5314 init_unistr( &info->configfile, "" );
5317 if (strlen(driver.info_3->helpfile)) {
5318 temp = talloc_asprintf(ctx,
5321 driver.info_3->helpfile);
5322 init_unistr( &info->helpfile, temp );
5324 init_unistr( &info->helpfile, "" );
5327 init_unistr( &info->monitorname, driver.info_3->monitorname );
5328 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5330 info->dependentfiles=NULL;
5331 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5334 /********************************************************************
5335 * construct_printer_info_3
5336 * fill a printer_info_3 struct
5337 ********************************************************************/
5339 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5341 NT_PRINTER_INFO_LEVEL *printer = NULL;
5342 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5344 ZERO_STRUCT(driver);
5346 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5347 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5348 if (!W_ERROR_IS_OK(status))
5349 return WERR_INVALID_PRINTER_NAME;
5351 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5352 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5357 * I put this code in during testing. Helpful when commenting out the
5358 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5359 * as win2k always queries the driver using an infor level of 6.
5360 * I've left it in (but ifdef'd out) because I'll probably
5361 * use it in experimentation again in the future. --jerry 22/01/2002
5364 if (!W_ERROR_IS_OK(status)) {
5366 * Is this a W2k client ?
5369 /* Yes - try again with a WinNT driver. */
5371 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5372 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5376 if (!W_ERROR_IS_OK(status)) {
5377 free_a_printer(&printer,2);
5378 return WERR_UNKNOWN_PRINTER_DRIVER;
5386 fill_printer_driver_info_3(info, driver, servername);
5388 free_a_printer(&printer,2);
5393 /********************************************************************
5394 * construct_printer_info_6
5395 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5396 ********************************************************************/
5398 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5402 TALLOC_CTX *ctx = talloc_tos();
5403 const char *cservername = canon_servername(servername);
5406 memset(&nullstr, '\0', sizeof(fstring));
5408 info->version=driver.info_3->cversion;
5410 init_unistr( &info->name, driver.info_3->name );
5411 init_unistr( &info->architecture, driver.info_3->environment );
5413 if (strlen(driver.info_3->driverpath)) {
5414 temp = talloc_asprintf(ctx,
5417 driver.info_3->driverpath);
5418 init_unistr( &info->driverpath, temp );
5420 init_unistr( &info->driverpath, "" );
5423 if (strlen(driver.info_3->datafile)) {
5424 temp = talloc_asprintf(ctx,
5427 driver.info_3->datafile);
5428 init_unistr( &info->datafile, temp );
5430 init_unistr( &info->datafile, "" );
5433 if (strlen(driver.info_3->configfile)) {
5434 temp = talloc_asprintf(ctx,
5437 driver.info_3->configfile);
5438 init_unistr( &info->configfile, temp );
5440 init_unistr( &info->configfile, "" );
5443 if (strlen(driver.info_3->helpfile)) {
5444 temp = talloc_asprintf(ctx,
5447 driver.info_3->helpfile);
5448 init_unistr( &info->helpfile, temp );
5450 init_unistr( &info->helpfile, "" );
5453 init_unistr( &info->monitorname, driver.info_3->monitorname );
5454 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5456 info->dependentfiles = NULL;
5457 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5459 info->previousdrivernames=NULL;
5460 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5462 info->driver_date=0;
5465 info->driver_version_low=0;
5466 info->driver_version_high=0;
5468 init_unistr( &info->mfgname, "");
5469 init_unistr( &info->oem_url, "");
5470 init_unistr( &info->hardware_id, "");
5471 init_unistr( &info->provider, "");
5474 /********************************************************************
5475 * construct_printer_info_6
5476 * fill a printer_info_6 struct
5477 ********************************************************************/
5479 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5480 const char *servername, fstring architecture, uint32 version)
5482 NT_PRINTER_INFO_LEVEL *printer = NULL;
5483 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5486 ZERO_STRUCT(driver);
5488 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5490 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5492 if (!W_ERROR_IS_OK(status))
5493 return WERR_INVALID_PRINTER_NAME;
5495 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5497 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5499 if (!W_ERROR_IS_OK(status))
5502 * Is this a W2k client ?
5506 free_a_printer(&printer,2);
5507 return WERR_UNKNOWN_PRINTER_DRIVER;
5510 /* Yes - try again with a WinNT driver. */
5512 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5513 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5514 if (!W_ERROR_IS_OK(status)) {
5515 free_a_printer(&printer,2);
5516 return WERR_UNKNOWN_PRINTER_DRIVER;
5520 fill_printer_driver_info_6(info, driver, servername);
5522 free_a_printer(&printer,2);
5523 free_a_printer_driver(driver, 3);
5528 /****************************************************************************
5529 ****************************************************************************/
5531 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5533 SAFE_FREE(info->dependentfiles);
5536 /****************************************************************************
5537 ****************************************************************************/
5539 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5541 SAFE_FREE(info->dependentfiles);
5544 /****************************************************************************
5545 ****************************************************************************/
5547 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5549 DRIVER_INFO_1 *info=NULL;
5552 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5555 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5556 if (!W_ERROR_IS_OK(result))
5559 /* check the required size. */
5560 *needed += spoolss_size_printer_driver_info_1(info);
5562 if (*needed > offered) {
5563 result = WERR_INSUFFICIENT_BUFFER;
5567 if (!rpcbuf_alloc_size(buffer, *needed)) {
5568 result = WERR_NOMEM;
5572 /* fill the buffer with the structures */
5573 smb_io_printer_driver_info_1("", buffer, info, 0);
5582 /****************************************************************************
5583 ****************************************************************************/
5585 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5587 DRIVER_INFO_2 *info=NULL;
5590 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5593 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5594 if (!W_ERROR_IS_OK(result))
5597 /* check the required size. */
5598 *needed += spoolss_size_printer_driver_info_2(info);
5600 if (*needed > offered) {
5601 result = WERR_INSUFFICIENT_BUFFER;
5605 if (!rpcbuf_alloc_size(buffer, *needed)) {
5606 result = WERR_NOMEM;
5610 /* fill the buffer with the structures */
5611 smb_io_printer_driver_info_2("", buffer, info, 0);
5620 /****************************************************************************
5621 ****************************************************************************/
5623 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5630 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5631 if (!W_ERROR_IS_OK(result))
5634 /* check the required size. */
5635 *needed += spoolss_size_printer_driver_info_3(&info);
5637 if (*needed > offered) {
5638 result = WERR_INSUFFICIENT_BUFFER;
5642 if (!rpcbuf_alloc_size(buffer, *needed)) {
5643 result = WERR_NOMEM;
5647 /* fill the buffer with the structures */
5648 smb_io_printer_driver_info_3("", buffer, &info, 0);
5651 free_printer_driver_info_3(&info);
5656 /****************************************************************************
5657 ****************************************************************************/
5659 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5666 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5667 if (!W_ERROR_IS_OK(result))
5670 /* check the required size. */
5671 *needed += spoolss_size_printer_driver_info_6(&info);
5673 if (*needed > offered) {
5674 result = WERR_INSUFFICIENT_BUFFER;
5678 if (!rpcbuf_alloc_size(buffer, *needed)) {
5679 result = WERR_NOMEM;
5683 /* fill the buffer with the structures */
5684 smb_io_printer_driver_info_6("", buffer, &info, 0);
5687 free_printer_driver_info_6(&info);
5692 /****************************************************************************
5693 ****************************************************************************/
5695 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5697 POLICY_HND *handle = &q_u->handle;
5698 UNISTR2 *uni_arch = &q_u->architecture;
5699 uint32 level = q_u->level;
5700 uint32 clientmajorversion = q_u->clientmajorversion;
5701 RPC_BUFFER *buffer = NULL;
5702 uint32 offered = q_u->offered;
5703 uint32 *needed = &r_u->needed;
5704 uint32 *servermajorversion = &r_u->servermajorversion;
5705 uint32 *serverminorversion = &r_u->serverminorversion;
5706 Printer_entry *printer;
5709 fstring architecture;
5712 /* that's an [in out] buffer */
5714 if (!q_u->buffer && (offered!=0)) {
5715 return WERR_INVALID_PARAM;
5718 if (offered > MAX_RPC_DATA_SIZE) {
5719 return WERR_INVALID_PARAM;
5722 rpcbuf_move(q_u->buffer, &r_u->buffer);
5723 buffer = r_u->buffer;
5725 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5727 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5728 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5729 return WERR_INVALID_PRINTER_NAME;
5733 *servermajorversion = 0;
5734 *serverminorversion = 0;
5736 fstrcpy(servername, get_server_name( printer ));
5737 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5739 if (!get_printer_snum(p, handle, &snum, NULL))
5744 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5746 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5748 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5750 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5753 /* apparently this call is the equivalent of
5754 EnumPrinterDataEx() for the DsDriver key */
5759 return WERR_UNKNOWN_LEVEL;
5763 /****************************************************************
5764 _spoolss_StartPagePrinter
5765 ****************************************************************/
5767 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5768 struct spoolss_StartPagePrinter *r)
5770 POLICY_HND *handle = r->in.handle;
5772 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5775 DEBUG(3,("_spoolss_StartPagePrinter: "
5776 "Error in startpageprinter printer handle\n"));
5780 Printer->page_started=True;
5784 /****************************************************************
5785 _spoolss_EndPagePrinter
5786 ****************************************************************/
5788 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5789 struct spoolss_EndPagePrinter *r)
5791 POLICY_HND *handle = r->in.handle;
5794 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5797 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5798 OUR_HANDLE(handle)));
5802 if (!get_printer_snum(p, handle, &snum, NULL))
5805 Printer->page_started=False;
5806 print_job_endpage(snum, Printer->jobid);
5811 /****************************************************************
5812 _spoolss_StartDocPrinter
5813 ****************************************************************/
5815 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5816 struct spoolss_StartDocPrinter *r)
5818 POLICY_HND *handle = r->in.handle;
5819 uint32_t *jobid = r->out.job_id;
5820 struct spoolss_DocumentInfo1 *info_1;
5822 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5825 DEBUG(2,("_spoolss_StartDocPrinter: "
5826 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5830 if (r->in.level != 1) {
5831 return WERR_UNKNOWN_LEVEL;
5834 info_1 = r->in.info.info1;
5837 * a nice thing with NT is it doesn't listen to what you tell it.
5838 * when asked to send _only_ RAW datas, it tries to send datas
5841 * So I add checks like in NT Server ...
5844 if (info_1->datatype) {
5845 if (strcmp(info_1->datatype, "RAW") != 0) {
5847 return WERR_INVALID_DATATYPE;
5851 /* get the share number of the printer */
5852 if (!get_printer_snum(p, handle, &snum, NULL)) {
5856 Printer->jobid = print_job_start(p->server_info, snum,
5857 CONST_DISCARD(char *,info_1->document_name),
5858 Printer->nt_devmode);
5860 /* An error occured in print_job_start() so return an appropriate
5863 if (Printer->jobid == -1) {
5864 return map_werror_from_unix(errno);
5867 Printer->document_started=True;
5868 (*jobid) = Printer->jobid;
5873 /****************************************************************
5874 _spoolss_EndDocPrinter
5875 ****************************************************************/
5877 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5878 struct spoolss_EndDocPrinter *r)
5880 POLICY_HND *handle = r->in.handle;
5882 return _spoolss_enddocprinter_internal(p, handle);
5885 /****************************************************************
5886 _spoolss_WritePrinter
5887 ****************************************************************/
5889 WERROR _spoolss_WritePrinter(pipes_struct *p,
5890 struct spoolss_WritePrinter *r)
5892 POLICY_HND *handle = r->in.handle;
5893 uint32 buffer_size = r->in._data_size;
5894 uint8 *buffer = r->in.data.data;
5895 uint32 *buffer_written = &r->in._data_size;
5897 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5900 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5901 OUR_HANDLE(handle)));
5902 *r->out.num_written = r->in._data_size;
5906 if (!get_printer_snum(p, handle, &snum, NULL))
5909 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5910 (SMB_OFF_T)-1, (size_t)buffer_size);
5911 if (*buffer_written == (uint32)-1) {
5912 *r->out.num_written = 0;
5913 if (errno == ENOSPC)
5914 return WERR_NO_SPOOL_SPACE;
5916 return WERR_ACCESS_DENIED;
5919 *r->out.num_written = r->in._data_size;
5924 /********************************************************************
5925 * api_spoolss_getprinter
5926 * called from the spoolss dispatcher
5928 ********************************************************************/
5930 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5934 WERROR errcode = WERR_BADFUNC;
5935 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5938 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5942 if (!get_printer_snum(p, handle, &snum, NULL))
5946 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5947 if (print_queue_pause(p->server_info, snum, &errcode)) {
5951 case SPOOLSS_PRINTER_CONTROL_RESUME:
5952 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5953 if (print_queue_resume(p->server_info, snum, &errcode)) {
5957 case SPOOLSS_PRINTER_CONTROL_PURGE:
5958 if (print_queue_purge(p->server_info, snum, &errcode)) {
5963 return WERR_UNKNOWN_LEVEL;
5970 /****************************************************************
5971 _spoolss_AbortPrinter
5972 * From MSDN: "Deletes printer's spool file if printer is configured
5974 ****************************************************************/
5976 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5977 struct spoolss_AbortPrinter *r)
5979 POLICY_HND *handle = r->in.handle;
5980 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5982 WERROR errcode = WERR_OK;
5985 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5986 OUR_HANDLE(handle)));
5990 if (!get_printer_snum(p, handle, &snum, NULL))
5993 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5998 /********************************************************************
5999 * called by spoolss_api_setprinter
6000 * when updating a printer description
6001 ********************************************************************/
6003 static WERROR update_printer_sec(POLICY_HND *handle,
6004 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6006 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6010 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6012 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6013 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6014 OUR_HANDLE(handle)));
6016 result = WERR_BADFID;
6021 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6022 result = WERR_INVALID_PARAM;
6026 /* Check the user has permissions to change the security
6027 descriptor. By experimentation with two NT machines, the user
6028 requires Full Access to the printer to change security
6031 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6032 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6033 result = WERR_ACCESS_DENIED;
6037 /* NT seems to like setting the security descriptor even though
6038 nothing may have actually changed. */
6040 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6041 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6042 result = WERR_BADFID;
6046 if (DEBUGLEVEL >= 10) {
6050 the_acl = old_secdesc_ctr->sd->dacl;
6051 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6052 PRINTERNAME(snum), the_acl->num_aces));
6054 for (i = 0; i < the_acl->num_aces; i++) {
6055 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6056 &the_acl->aces[i].trustee),
6057 the_acl->aces[i].access_mask));
6060 the_acl = secdesc_ctr->sd->dacl;
6063 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6064 PRINTERNAME(snum), the_acl->num_aces));
6066 for (i = 0; i < the_acl->num_aces; i++) {
6067 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6068 &the_acl->aces[i].trustee),
6069 the_acl->aces[i].access_mask));
6072 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6076 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6077 if (!new_secdesc_ctr) {
6078 result = WERR_NOMEM;
6082 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6087 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6094 /********************************************************************
6095 Canonicalize printer info from a client
6097 ATTN: It does not matter what we set the servername to hear
6098 since we do the necessary work in get_a_printer() to set it to
6099 the correct value based on what the client sent in the
6100 _spoolss_open_printer_ex().
6101 ********************************************************************/
6103 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6105 fstring printername;
6108 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6109 "portname=%s drivername=%s comment=%s location=%s\n",
6110 info->servername, info->printername, info->sharename,
6111 info->portname, info->drivername, info->comment, info->location));
6113 /* we force some elements to "correct" values */
6114 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6115 fstrcpy(info->sharename, lp_servicename(snum));
6117 /* check to see if we allow printername != sharename */
6119 if ( lp_force_printername(snum) ) {
6120 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6121 global_myname(), info->sharename );
6124 /* make sure printername is in \\server\printername format */
6126 fstrcpy( printername, info->printername );
6128 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6129 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6133 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6134 global_myname(), p );
6137 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6138 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6145 /****************************************************************************
6146 ****************************************************************************/
6148 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6150 char *cmd = lp_addport_cmd();
6151 char *command = NULL;
6153 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6154 bool is_print_op = False;
6157 return WERR_ACCESS_DENIED;
6160 command = talloc_asprintf(ctx,
6161 "%s \"%s\" \"%s\"", cmd, portname, uri );
6167 is_print_op = user_has_privileges( token, &se_printop );
6169 DEBUG(10,("Running [%s]\n", command));
6171 /********* BEGIN SePrintOperatorPrivilege **********/
6176 ret = smbrun(command, NULL);
6181 /********* END SePrintOperatorPrivilege **********/
6183 DEBUGADD(10,("returned [%d]\n", ret));
6185 TALLOC_FREE(command);
6188 return WERR_ACCESS_DENIED;
6194 /****************************************************************************
6195 ****************************************************************************/
6197 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6199 char *cmd = lp_addprinter_cmd();
6201 char *command = NULL;
6205 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6206 bool is_print_op = False;
6207 char *remote_machine = talloc_strdup(ctx, "%m");
6209 if (!remote_machine) {
6212 remote_machine = talloc_sub_basic(ctx,
6213 current_user_info.smb_name,
6214 current_user_info.domain,
6216 if (!remote_machine) {
6220 command = talloc_asprintf(ctx,
6221 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6222 cmd, printer->info_2->printername, printer->info_2->sharename,
6223 printer->info_2->portname, printer->info_2->drivername,
6224 printer->info_2->location, printer->info_2->comment, remote_machine);
6230 is_print_op = user_has_privileges( token, &se_printop );
6232 DEBUG(10,("Running [%s]\n", command));
6234 /********* BEGIN SePrintOperatorPrivilege **********/
6239 if ( (ret = smbrun(command, &fd)) == 0 ) {
6240 /* Tell everyone we updated smb.conf. */
6241 message_send_all(smbd_messaging_context(),
6242 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6248 /********* END SePrintOperatorPrivilege **********/
6250 DEBUGADD(10,("returned [%d]\n", ret));
6252 TALLOC_FREE(command);
6253 TALLOC_FREE(remote_machine);
6261 /* reload our services immediately */
6262 reload_services( False );
6265 /* Get lines and convert them back to dos-codepage */
6266 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6267 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6270 /* Set the portname to what the script says the portname should be. */
6271 /* but don't require anything to be return from the script exit a good error code */
6274 /* Set the portname to what the script says the portname should be. */
6275 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6276 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6279 TALLOC_FREE(qlines);
6284 /********************************************************************
6285 * Called by spoolss_api_setprinter
6286 * when updating a printer description.
6287 ********************************************************************/
6289 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6290 struct spoolss_SetPrinterInfoCtr *info_ctr,
6291 struct spoolss_DeviceMode *devmode)
6294 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6295 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6300 DEBUG(8,("update_printer\n"));
6305 result = WERR_BADFID;
6309 if (!get_printer_snum(p, handle, &snum, NULL)) {
6310 result = WERR_BADFID;
6314 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6315 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6316 result = WERR_BADFID;
6320 DEBUGADD(8,("Converting info_2 struct\n"));
6323 * convert_printer_info converts the incoming
6324 * info from the client and overwrites the info
6325 * just read from the tdb in the pointer 'printer'.
6328 if (!convert_printer_info_new(info_ctr, printer)) {
6329 result = WERR_NOMEM;
6334 /* we have a valid devmode
6335 convert it and link it*/
6337 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6338 if (!convert_devicemode_new(printer->info_2->printername,
6340 &printer->info_2->devmode)) {
6341 result = WERR_NOMEM;
6346 /* Do sanity check on the requested changes for Samba */
6348 if (!check_printer_ok(printer->info_2, snum)) {
6349 result = WERR_INVALID_PARAM;
6353 /* FIXME!!! If the driver has changed we really should verify that
6354 it is installed before doing much else --jerry */
6356 /* Check calling user has permission to update printer description */
6358 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6359 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6360 result = WERR_ACCESS_DENIED;
6364 /* Call addprinter hook */
6365 /* Check changes to see if this is really needed */
6367 if ( *lp_addprinter_cmd()
6368 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6369 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6370 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6371 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6373 /* add_printer_hook() will call reload_services() */
6375 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6377 result = WERR_ACCESS_DENIED;
6383 * When a *new* driver is bound to a printer, the drivername is used to
6384 * lookup previously saved driver initialization info, which is then
6385 * bound to the printer, simulating what happens in the Windows arch.
6387 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6389 if (!set_driver_init(printer, 2))
6391 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6392 printer->info_2->drivername));
6395 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6396 printer->info_2->drivername));
6398 notify_printer_driver(snum, printer->info_2->drivername);
6402 * flag which changes actually occured. This is a small subset of
6403 * all the possible changes. We also have to update things in the
6407 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6408 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6409 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6410 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6412 notify_printer_comment(snum, printer->info_2->comment);
6415 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6416 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6417 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6418 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6420 notify_printer_sharename(snum, printer->info_2->sharename);
6423 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6426 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6429 pname = printer->info_2->printername;
6432 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6433 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6434 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6436 notify_printer_printername( snum, pname );
6439 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6440 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6441 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6442 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6444 notify_printer_port(snum, printer->info_2->portname);
6447 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6448 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6449 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6450 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6452 notify_printer_location(snum, printer->info_2->location);
6455 /* here we need to update some more DsSpooler keys */
6456 /* uNCName, serverName, shortServerName */
6458 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6459 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6460 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6461 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6462 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6464 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6465 global_myname(), printer->info_2->sharename );
6466 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6467 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6468 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6470 /* Update printer info */
6471 result = mod_a_printer(printer, 2);
6474 free_a_printer(&printer, 2);
6475 free_a_printer(&old_printer, 2);
6481 /****************************************************************************
6482 ****************************************************************************/
6483 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6484 struct spoolss_SetPrinterInfo7 *info7)
6488 Printer_entry *Printer;
6490 if ( lp_security() != SEC_ADS ) {
6491 return WERR_UNKNOWN_LEVEL;
6494 Printer = find_printer_index_by_hnd(p, handle);
6496 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6501 if (!get_printer_snum(p, handle, &snum, NULL))
6504 nt_printer_publish(Printer, snum, info7->action);
6508 return WERR_UNKNOWN_LEVEL;
6512 /****************************************************************
6514 ****************************************************************/
6516 WERROR _spoolss_SetPrinter(pipes_struct *p,
6517 struct spoolss_SetPrinter *r)
6519 POLICY_HND *handle = r->in.handle;
6522 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6525 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6526 OUR_HANDLE(handle)));
6530 /* check the level */
6531 switch (r->in.info_ctr->level) {
6533 return control_printer(handle, r->in.command, p);
6535 result = update_printer(p, handle,
6537 r->in.devmode_ctr->devmode);
6538 if (!W_ERROR_IS_OK(result))
6540 if (r->in.secdesc_ctr->sd)
6541 result = update_printer_sec(handle, p,
6545 return update_printer_sec(handle, p,
6548 return publish_or_unpublish_printer(p, handle,
6549 r->in.info_ctr->info.info7);
6551 return WERR_UNKNOWN_LEVEL;
6555 /****************************************************************
6556 _spoolss_FindClosePrinterNotify
6557 ****************************************************************/
6559 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6560 struct spoolss_FindClosePrinterNotify *r)
6562 POLICY_HND *handle = r->in.handle;
6563 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6566 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6567 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6571 if (Printer->notify.client_connected==True) {
6574 if ( Printer->printer_type == SPLHND_SERVER)
6576 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6577 !get_printer_snum(p, handle, &snum, NULL) )
6580 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6583 Printer->notify.flags=0;
6584 Printer->notify.options=0;
6585 Printer->notify.localmachine[0]='\0';
6586 Printer->notify.printerlocal=0;
6587 if (Printer->notify.option)
6588 free_spool_notify_option(&Printer->notify.option);
6589 Printer->notify.client_connected=False;
6594 /****************************************************************
6596 ****************************************************************/
6598 WERROR _spoolss_AddJob(pipes_struct *p,
6599 struct spoolss_AddJob *r)
6601 if (!r->in.buffer && (r->in.offered != 0)) {
6602 return WERR_INVALID_PARAM;
6605 /* this is what a NT server returns for AddJob. AddJob must fail on
6606 * non-local printers */
6608 return WERR_INVALID_PARAM;
6611 /****************************************************************************
6612 ****************************************************************************/
6614 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6615 int position, int snum,
6616 const NT_PRINTER_INFO_LEVEL *ntprinter)
6620 t=gmtime(&queue->time);
6622 job_info->jobid=queue->job;
6623 init_unistr(&job_info->printername, lp_servicename(snum));
6624 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6625 init_unistr(&job_info->username, queue->fs_user);
6626 init_unistr(&job_info->document, queue->fs_file);
6627 init_unistr(&job_info->datatype, "RAW");
6628 init_unistr(&job_info->text_status, "");
6629 job_info->status=nt_printj_status(queue->status);
6630 job_info->priority=queue->priority;
6631 job_info->position=position;
6632 job_info->totalpages=queue->page_count;
6633 job_info->pagesprinted=0;
6635 make_systemtime(&job_info->submitted, t);
6638 /****************************************************************************
6639 ****************************************************************************/
6641 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6642 int position, int snum,
6643 const NT_PRINTER_INFO_LEVEL *ntprinter,
6644 DEVICEMODE *devmode)
6648 t=gmtime(&queue->time);
6650 job_info->jobid=queue->job;
6652 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6654 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6655 init_unistr(&job_info->username, queue->fs_user);
6656 init_unistr(&job_info->document, queue->fs_file);
6657 init_unistr(&job_info->notifyname, queue->fs_user);
6658 init_unistr(&job_info->datatype, "RAW");
6659 init_unistr(&job_info->printprocessor, "winprint");
6660 init_unistr(&job_info->parameters, "");
6661 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6662 init_unistr(&job_info->text_status, "");
6664 /* and here the security descriptor */
6666 job_info->status=nt_printj_status(queue->status);
6667 job_info->priority=queue->priority;
6668 job_info->position=position;
6669 job_info->starttime=0;
6670 job_info->untiltime=0;
6671 job_info->totalpages=queue->page_count;
6672 job_info->size=queue->size;
6673 make_systemtime(&(job_info->submitted), t);
6674 job_info->timeelapsed=0;
6675 job_info->pagesprinted=0;
6677 job_info->devmode = devmode;
6682 /****************************************************************************
6683 Enumjobs at level 1.
6684 ****************************************************************************/
6686 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6687 const NT_PRINTER_INFO_LEVEL *ntprinter,
6688 RPC_BUFFER *buffer, uint32 offered,
6689 uint32 *needed, uint32 *returned)
6693 WERROR result = WERR_OK;
6695 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6701 for (i=0; i<*returned; i++)
6702 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6704 /* check the required size. */
6705 for (i=0; i<*returned; i++)
6706 (*needed) += spoolss_size_job_info_1(&info[i]);
6708 if (*needed > offered) {
6709 result = WERR_INSUFFICIENT_BUFFER;
6713 if (!rpcbuf_alloc_size(buffer, *needed)) {
6714 result = WERR_NOMEM;
6718 /* fill the buffer with the structures */
6719 for (i=0; i<*returned; i++)
6720 smb_io_job_info_1("", buffer, &info[i], 0);
6726 if ( !W_ERROR_IS_OK(result) )
6732 /****************************************************************************
6733 Enumjobs at level 2.
6734 ****************************************************************************/
6736 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6737 const NT_PRINTER_INFO_LEVEL *ntprinter,
6738 RPC_BUFFER *buffer, uint32 offered,
6739 uint32 *needed, uint32 *returned)
6741 JOB_INFO_2 *info = NULL;
6743 WERROR result = WERR_OK;
6744 DEVICEMODE *devmode = NULL;
6746 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6751 /* this should not be a failure condition if the devmode is NULL */
6753 devmode = construct_dev_mode(lp_const_servicename(snum));
6755 for (i=0; i<*returned; i++)
6756 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6758 /* check the required size. */
6759 for (i=0; i<*returned; i++)
6760 (*needed) += spoolss_size_job_info_2(&info[i]);
6762 if (*needed > offered) {
6763 result = WERR_INSUFFICIENT_BUFFER;
6767 if (!rpcbuf_alloc_size(buffer, *needed)) {
6768 result = WERR_NOMEM;
6772 /* fill the buffer with the structures */
6773 for (i=0; i<*returned; i++)
6774 smb_io_job_info_2("", buffer, &info[i], 0);
6777 free_devmode(devmode);
6780 if ( !W_ERROR_IS_OK(result) )
6787 /****************************************************************************
6789 ****************************************************************************/
6791 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6793 POLICY_HND *handle = &q_u->handle;
6794 uint32 level = q_u->level;
6795 RPC_BUFFER *buffer = NULL;
6796 uint32 offered = q_u->offered;
6797 uint32 *needed = &r_u->needed;
6798 uint32 *returned = &r_u->returned;
6800 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6802 print_status_struct prt_status;
6803 print_queue_struct *queue=NULL;
6805 /* that's an [in out] buffer */
6807 if (!q_u->buffer && (offered!=0)) {
6808 return WERR_INVALID_PARAM;
6811 if (offered > MAX_RPC_DATA_SIZE) {
6812 return WERR_INVALID_PARAM;
6815 rpcbuf_move(q_u->buffer, &r_u->buffer);
6816 buffer = r_u->buffer;
6818 DEBUG(4,("_spoolss_enumjobs\n"));
6823 /* lookup the printer snum and tdb entry */
6825 if (!get_printer_snum(p, handle, &snum, NULL))
6828 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6829 if ( !W_ERROR_IS_OK(wret) )
6832 *returned = print_queue_status(snum, &queue, &prt_status);
6833 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6835 if (*returned == 0) {
6837 free_a_printer(&ntprinter, 2);
6843 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6846 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6850 wret = WERR_UNKNOWN_LEVEL;
6855 free_a_printer( &ntprinter, 2 );
6859 /****************************************************************
6860 _spoolss_ScheduleJob
6861 ****************************************************************/
6863 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6864 struct spoolss_ScheduleJob *r)
6869 /****************************************************************
6871 ****************************************************************/
6873 WERROR _spoolss_SetJob(pipes_struct *p,
6874 struct spoolss_SetJob *r)
6876 POLICY_HND *handle = r->in.handle;
6877 uint32 jobid = r->in.job_id;
6878 uint32 command = r->in.command;
6881 WERROR errcode = WERR_BADFUNC;
6883 if (!get_printer_snum(p, handle, &snum, NULL)) {
6887 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6888 return WERR_INVALID_PRINTER_NAME;
6892 case SPOOLSS_JOB_CONTROL_CANCEL:
6893 case SPOOLSS_JOB_CONTROL_DELETE:
6894 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6898 case SPOOLSS_JOB_CONTROL_PAUSE:
6899 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6903 case SPOOLSS_JOB_CONTROL_RESTART:
6904 case SPOOLSS_JOB_CONTROL_RESUME:
6905 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6910 return WERR_UNKNOWN_LEVEL;
6916 /****************************************************************************
6917 Enumerates all printer drivers at level 1.
6918 ****************************************************************************/
6920 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6925 fstring *list = NULL;
6926 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6927 DRIVER_INFO_1 *driver_info_1=NULL;
6928 WERROR result = WERR_OK;
6932 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6934 ndrivers=get_ntdrivers(&list, architecture, version);
6935 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6937 if(ndrivers == -1) {
6938 SAFE_FREE(driver_info_1);
6943 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6944 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6950 for (i=0; i<ndrivers; i++) {
6952 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6953 ZERO_STRUCT(driver);
6954 status = get_a_printer_driver(&driver, 3, list[i],
6955 architecture, version);
6956 if (!W_ERROR_IS_OK(status)) {
6958 SAFE_FREE(driver_info_1);
6961 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6962 free_a_printer_driver(driver, 3);
6965 *returned+=ndrivers;
6969 /* check the required size. */
6970 for (i=0; i<*returned; i++) {
6971 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6972 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6975 if (*needed > offered) {
6976 result = WERR_INSUFFICIENT_BUFFER;
6980 if (!rpcbuf_alloc_size(buffer, *needed)) {
6981 result = WERR_NOMEM;
6985 /* fill the buffer with the driver structures */
6986 for (i=0; i<*returned; i++) {
6987 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
6988 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
6992 SAFE_FREE(driver_info_1);
6994 if ( !W_ERROR_IS_OK(result) )
7000 /****************************************************************************
7001 Enumerates all printer drivers at level 2.
7002 ****************************************************************************/
7004 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7009 fstring *list = NULL;
7010 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7011 DRIVER_INFO_2 *driver_info_2=NULL;
7012 WERROR result = WERR_OK;
7016 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7018 ndrivers=get_ntdrivers(&list, architecture, version);
7019 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7021 if(ndrivers == -1) {
7022 SAFE_FREE(driver_info_2);
7027 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7028 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7034 for (i=0; i<ndrivers; i++) {
7037 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7038 ZERO_STRUCT(driver);
7039 status = get_a_printer_driver(&driver, 3, list[i],
7040 architecture, version);
7041 if (!W_ERROR_IS_OK(status)) {
7043 SAFE_FREE(driver_info_2);
7046 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7047 free_a_printer_driver(driver, 3);
7050 *returned+=ndrivers;
7054 /* check the required size. */
7055 for (i=0; i<*returned; i++) {
7056 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7057 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7060 if (*needed > offered) {
7061 result = WERR_INSUFFICIENT_BUFFER;
7065 if (!rpcbuf_alloc_size(buffer, *needed)) {
7066 result = WERR_NOMEM;
7070 /* fill the buffer with the form structures */
7071 for (i=0; i<*returned; i++) {
7072 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7073 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7077 SAFE_FREE(driver_info_2);
7079 if ( !W_ERROR_IS_OK(result) )
7085 /****************************************************************************
7086 Enumerates all printer drivers at level 3.
7087 ****************************************************************************/
7089 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7094 fstring *list = NULL;
7095 DRIVER_INFO_3 *driver_info_3=NULL;
7096 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7097 WERROR result = WERR_OK;
7101 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7103 ndrivers=get_ntdrivers(&list, architecture, version);
7104 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7106 if(ndrivers == -1) {
7107 SAFE_FREE(driver_info_3);
7112 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7113 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7119 for (i=0; i<ndrivers; i++) {
7122 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7123 ZERO_STRUCT(driver);
7124 status = get_a_printer_driver(&driver, 3, list[i],
7125 architecture, version);
7126 if (!W_ERROR_IS_OK(status)) {
7128 SAFE_FREE(driver_info_3);
7131 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7132 free_a_printer_driver(driver, 3);
7135 *returned+=ndrivers;
7139 /* check the required size. */
7140 for (i=0; i<*returned; i++) {
7141 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7142 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7145 if (*needed > offered) {
7146 result = WERR_INSUFFICIENT_BUFFER;
7150 if (!rpcbuf_alloc_size(buffer, *needed)) {
7151 result = WERR_NOMEM;
7155 /* fill the buffer with the driver structures */
7156 for (i=0; i<*returned; i++) {
7157 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7158 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7162 for (i=0; i<*returned; i++) {
7163 SAFE_FREE(driver_info_3[i].dependentfiles);
7166 SAFE_FREE(driver_info_3);
7168 if ( !W_ERROR_IS_OK(result) )
7174 /****************************************************************************
7175 Enumerates all printer drivers.
7176 ****************************************************************************/
7178 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7180 uint32 level = q_u->level;
7181 RPC_BUFFER *buffer = NULL;
7182 uint32 offered = q_u->offered;
7183 uint32 *needed = &r_u->needed;
7184 uint32 *returned = &r_u->returned;
7185 const char *cservername;
7187 fstring architecture;
7189 /* that's an [in out] buffer */
7191 if (!q_u->buffer && (offered!=0)) {
7192 return WERR_INVALID_PARAM;
7195 if (offered > MAX_RPC_DATA_SIZE) {
7196 return WERR_INVALID_PARAM;
7199 rpcbuf_move(q_u->buffer, &r_u->buffer);
7200 buffer = r_u->buffer;
7202 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7207 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7208 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7210 cservername = canon_servername(servername);
7212 if (!is_myname_or_ipaddr(cservername))
7213 return WERR_UNKNOWN_PRINTER_DRIVER;
7217 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7219 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7221 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7223 return WERR_UNKNOWN_LEVEL;
7227 /****************************************************************************
7228 ****************************************************************************/
7230 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7232 form->flag=list->flag;
7233 init_unistr(&form->name, list->name);
7234 form->width=list->width;
7235 form->length=list->length;
7236 form->left=list->left;
7237 form->top=list->top;
7238 form->right=list->right;
7239 form->bottom=list->bottom;
7242 /****************************************************************************
7243 ****************************************************************************/
7245 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7246 struct spoolss_FormInfo1 *form,
7247 nt_forms_struct *list)
7249 form->form_name = talloc_strdup(mem_ctx, list->name);
7250 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7252 form->flags = list->flag;
7253 form->size.width = list->width;
7254 form->size.height = list->length;
7255 form->area.left = list->left;
7256 form->area.top = list->top;
7257 form->area.right = list->right;
7258 form->area.bottom = list->bottom;
7263 /****************************************************************************
7264 ****************************************************************************/
7266 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7268 uint32 level = q_u->level;
7269 RPC_BUFFER *buffer = NULL;
7270 uint32 offered = q_u->offered;
7271 uint32 *needed = &r_u->needed;
7272 uint32 *numofforms = &r_u->numofforms;
7273 uint32 numbuiltinforms;
7275 nt_forms_struct *list=NULL;
7276 nt_forms_struct *builtinlist=NULL;
7281 /* that's an [in out] buffer */
7283 if (!q_u->buffer && (offered!=0) ) {
7284 return WERR_INVALID_PARAM;
7287 if (offered > MAX_RPC_DATA_SIZE) {
7288 return WERR_INVALID_PARAM;
7291 rpcbuf_move(q_u->buffer, &r_u->buffer);
7292 buffer = r_u->buffer;
7294 DEBUG(4,("_spoolss_enumforms\n"));
7295 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7296 DEBUGADD(5,("Info level [%d]\n", level));
7298 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7299 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7300 *numofforms = get_ntforms(&list);
7301 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7302 *numofforms += numbuiltinforms;
7304 if (*numofforms == 0) {
7305 SAFE_FREE(builtinlist);
7307 return WERR_NO_MORE_ITEMS;
7312 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7313 SAFE_FREE(builtinlist);
7319 /* construct the list of form structures */
7320 for (i=0; i<numbuiltinforms; i++) {
7321 DEBUGADD(6,("Filling form number [%d]\n",i));
7322 fill_form_1(&forms_1[i], &builtinlist[i]);
7325 SAFE_FREE(builtinlist);
7327 for (; i<*numofforms; i++) {
7328 DEBUGADD(6,("Filling form number [%d]\n",i));
7329 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7334 /* check the required size. */
7335 for (i=0; i<numbuiltinforms; i++) {
7336 DEBUGADD(6,("adding form [%d]'s size\n",i));
7337 buffer_size += spoolss_size_form_1(&forms_1[i]);
7339 for (; i<*numofforms; i++) {
7340 DEBUGADD(6,("adding form [%d]'s size\n",i));
7341 buffer_size += spoolss_size_form_1(&forms_1[i]);
7344 *needed=buffer_size;
7346 if (*needed > offered) {
7349 return WERR_INSUFFICIENT_BUFFER;
7352 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7358 /* fill the buffer with the form structures */
7359 for (i=0; i<numbuiltinforms; i++) {
7360 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7361 smb_io_form_1("", buffer, &forms_1[i], 0);
7363 for (; i<*numofforms; i++) {
7364 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7365 smb_io_form_1("", buffer, &forms_1[i], 0);
7374 SAFE_FREE(builtinlist);
7375 return WERR_UNKNOWN_LEVEL;
7379 /****************************************************************
7381 ****************************************************************/
7383 WERROR _spoolss_GetForm(pipes_struct *p,
7384 struct spoolss_GetForm *r)
7386 uint32 level = r->in.level;
7387 uint32 offered = r->in.offered;
7388 uint32 *needed = r->out.needed;
7390 nt_forms_struct *list=NULL;
7391 nt_forms_struct builtin_form;
7393 union spoolss_FormInfo info;
7394 struct spoolss_FormInfo1 form_1;
7395 int numofforms=0, i=0;
7397 /* that's an [in out] buffer */
7399 if (!r->in.buffer && (offered!=0)) {
7400 return WERR_INVALID_PARAM;
7403 DEBUG(4,("_spoolss_GetForm\n"));
7404 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7405 DEBUGADD(5,("Info level [%d]\n", level));
7407 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7408 if (!foundBuiltin) {
7409 numofforms = get_ntforms(&list);
7410 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7412 if (numofforms == 0)
7416 ZERO_STRUCT(form_1);
7421 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7424 /* Check if the requested name is in the list of form structures */
7425 for (i=0; i<numofforms; i++) {
7427 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7428 list[i].name, r->in.form_name));
7430 if (strequal(r->in.form_name, list[i].name)) {
7431 DEBUGADD(6,("Found form %s number [%d]\n",
7432 r->in.form_name, i));
7433 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7439 if (i == numofforms) {
7443 /* check the required size. */
7445 info.info1 = form_1;
7447 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7449 if (*needed > offered) {
7451 return WERR_INSUFFICIENT_BUFFER;
7454 r->out.info->info1 = form_1;
7456 /* fill the buffer with the form structures */
7457 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7458 r->in.form_name, i));
7464 return WERR_UNKNOWN_LEVEL;
7468 /****************************************************************************
7469 ****************************************************************************/
7471 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7473 init_unistr(&port->port_name, name);
7476 /****************************************************************************
7477 TODO: This probably needs distinguish between TCP/IP and Local ports
7479 ****************************************************************************/
7481 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7483 init_unistr(&port->port_name, name);
7484 init_unistr(&port->monitor_name, "Local Monitor");
7485 init_unistr(&port->description, SPL_LOCAL_PORT );
7486 port->port_type=PORT_TYPE_WRITE;
7491 /****************************************************************************
7492 wrapper around the enumer ports command
7493 ****************************************************************************/
7495 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7497 char *cmd = lp_enumports_cmd();
7498 char **qlines = NULL;
7499 char *command = NULL;
7507 /* if no hook then just fill in the default port */
7510 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7513 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7514 TALLOC_FREE(qlines);
7521 /* we have a valid enumport command */
7523 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7528 DEBUG(10,("Running [%s]\n", command));
7529 ret = smbrun(command, &fd);
7530 DEBUG(10,("Returned [%d]\n", ret));
7531 TALLOC_FREE(command);
7536 return WERR_ACCESS_DENIED;
7540 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7541 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7551 /****************************************************************************
7553 ****************************************************************************/
7555 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7557 PORT_INFO_1 *ports=NULL;
7559 WERROR result = WERR_OK;
7560 char **qlines = NULL;
7563 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7564 if (!W_ERROR_IS_OK(result)) {
7565 TALLOC_FREE(qlines);
7570 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7571 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7572 win_errstr(WERR_NOMEM)));
7573 TALLOC_FREE(qlines);
7577 for (i=0; i<numlines; i++) {
7578 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7579 fill_port_1(&ports[i], qlines[i]);
7582 TALLOC_FREE(qlines);
7584 *returned = numlines;
7586 /* check the required size. */
7587 for (i=0; i<*returned; i++) {
7588 DEBUGADD(6,("adding port [%d]'s size\n", i));
7589 *needed += spoolss_size_port_info_1(&ports[i]);
7592 if (*needed > offered) {
7593 result = WERR_INSUFFICIENT_BUFFER;
7597 if (!rpcbuf_alloc_size(buffer, *needed)) {
7598 result = WERR_NOMEM;
7602 /* fill the buffer with the ports structures */
7603 for (i=0; i<*returned; i++) {
7604 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7605 smb_io_port_1("", buffer, &ports[i], 0);
7611 if ( !W_ERROR_IS_OK(result) )
7617 /****************************************************************************
7619 ****************************************************************************/
7621 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7623 PORT_INFO_2 *ports=NULL;
7625 WERROR result = WERR_OK;
7626 char **qlines = NULL;
7629 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7630 if ( !W_ERROR_IS_OK(result)) {
7631 TALLOC_FREE(qlines);
7636 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7637 TALLOC_FREE(qlines);
7641 for (i=0; i<numlines; i++) {
7642 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7643 fill_port_2(&(ports[i]), qlines[i]);
7647 TALLOC_FREE(qlines);
7649 *returned = numlines;
7651 /* check the required size. */
7652 for (i=0; i<*returned; i++) {
7653 DEBUGADD(6,("adding port [%d]'s size\n", i));
7654 *needed += spoolss_size_port_info_2(&ports[i]);
7657 if (*needed > offered) {
7658 result = WERR_INSUFFICIENT_BUFFER;
7662 if (!rpcbuf_alloc_size(buffer, *needed)) {
7663 result = WERR_NOMEM;
7667 /* fill the buffer with the ports structures */
7668 for (i=0; i<*returned; i++) {
7669 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7670 smb_io_port_2("", buffer, &ports[i], 0);
7676 if ( !W_ERROR_IS_OK(result) )
7682 /****************************************************************************
7684 ****************************************************************************/
7686 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7688 uint32 level = q_u->level;
7689 RPC_BUFFER *buffer = NULL;
7690 uint32 offered = q_u->offered;
7691 uint32 *needed = &r_u->needed;
7692 uint32 *returned = &r_u->returned;
7694 /* that's an [in out] buffer */
7696 if (!q_u->buffer && (offered!=0)) {
7697 return WERR_INVALID_PARAM;
7700 if (offered > MAX_RPC_DATA_SIZE) {
7701 return WERR_INVALID_PARAM;
7704 rpcbuf_move(q_u->buffer, &r_u->buffer);
7705 buffer = r_u->buffer;
7707 DEBUG(4,("_spoolss_enumports\n"));
7714 return enumports_level_1(buffer, offered, needed, returned);
7716 return enumports_level_2(buffer, offered, needed, returned);
7718 return WERR_UNKNOWN_LEVEL;
7722 /****************************************************************************
7723 ****************************************************************************/
7725 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7727 struct spoolss_SetPrinterInfoCtr *info_ctr,
7728 struct spoolss_DeviceMode *devmode,
7729 struct security_descriptor *sec_desc,
7730 struct spoolss_UserLevelCtr *user_ctr,
7733 NT_PRINTER_INFO_LEVEL *printer = NULL;
7736 WERROR err = WERR_OK;
7738 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7739 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7743 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7744 if (!convert_printer_info_new(info_ctr, printer)) {
7745 free_a_printer(&printer, 2);
7749 /* check to see if the printer already exists */
7751 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7752 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7753 printer->info_2->sharename));
7754 free_a_printer(&printer, 2);
7755 return WERR_PRINTER_ALREADY_EXISTS;
7758 /* FIXME!!! smbd should check to see if the driver is installed before
7759 trying to add a printer like this --jerry */
7761 if (*lp_addprinter_cmd() ) {
7762 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7764 free_a_printer(&printer,2);
7765 return WERR_ACCESS_DENIED;
7768 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7769 "smb.conf parameter \"addprinter command\" is defined. This"
7770 "parameter must exist for this call to succeed\n",
7771 printer->info_2->sharename ));
7774 /* use our primary netbios name since get_a_printer() will convert
7775 it to what the client expects on a case by case basis */
7777 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7778 printer->info_2->sharename);
7781 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7782 free_a_printer(&printer,2);
7783 return WERR_ACCESS_DENIED;
7786 /* you must be a printer admin to add a new printer */
7787 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7788 free_a_printer(&printer,2);
7789 return WERR_ACCESS_DENIED;
7793 * Do sanity check on the requested changes for Samba.
7796 if (!check_printer_ok(printer->info_2, snum)) {
7797 free_a_printer(&printer,2);
7798 return WERR_INVALID_PARAM;
7802 * When a printer is created, the drivername bound to the printer is used
7803 * to lookup previously saved driver initialization info, which is then
7804 * bound to the new printer, simulating what happens in the Windows arch.
7809 set_driver_init(printer, 2);
7813 /* A valid devmode was included, convert and link it
7815 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7817 if (!convert_devicemode_new(printer->info_2->printername,
7819 &printer->info_2->devmode))
7823 /* write the ASCII on disk */
7824 err = mod_a_printer(printer, 2);
7825 if (!W_ERROR_IS_OK(err)) {
7826 free_a_printer(&printer,2);
7830 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7831 /* Handle open failed - remove addition. */
7832 del_a_printer(printer->info_2->sharename);
7833 free_a_printer(&printer,2);
7834 ZERO_STRUCTP(handle);
7835 return WERR_ACCESS_DENIED;
7838 update_c_setprinter(False);
7839 free_a_printer(&printer,2);
7844 /****************************************************************
7845 _spoolss_AddPrinterEx
7846 ****************************************************************/
7848 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7849 struct spoolss_AddPrinterEx *r)
7851 switch (r->in.info_ctr->level) {
7853 /* we don't handle yet */
7854 /* but I know what to do ... */
7855 return WERR_UNKNOWN_LEVEL;
7857 return spoolss_addprinterex_level_2(p, r->in.server,
7859 r->in.devmode_ctr->devmode,
7860 r->in.secdesc_ctr->sd,
7861 r->in.userlevel_ctr,
7864 return WERR_UNKNOWN_LEVEL;
7868 /****************************************************************
7869 _spoolss_AddPrinterDriver
7870 ****************************************************************/
7872 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7873 struct spoolss_AddPrinterDriver *r)
7875 uint32_t level = r->in.info_ctr->level;
7876 struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
7877 WERROR err = WERR_OK;
7878 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7879 fstring driver_name;
7883 switch (p->hdr_req.opnum) {
7884 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7885 fn = "_spoolss_AddPrinterDriver";
7887 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7888 fn = "_spoolss_AddPrinterDriverEx";
7891 return WERR_INVALID_PARAM;
7896 if (level != 3 && level != 6) {
7897 /* Clever hack from Martin Zielinski <mz@seh.de>
7898 * to allow downgrade from level 8 (Vista).
7900 DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
7901 return WERR_UNKNOWN_LEVEL;
7904 ZERO_STRUCT(driver);
7906 if (!convert_printer_driver_info(info, &driver, level)) {
7911 DEBUG(5,("Cleaning driver's information\n"));
7912 err = clean_up_driver_struct(p, driver, level);
7913 if (!W_ERROR_IS_OK(err))
7916 DEBUG(5,("Moving driver to final destination\n"));
7917 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7922 if (add_a_printer_driver(driver, level)!=0) {
7923 err = WERR_ACCESS_DENIED;
7929 fstrcpy(driver_name,
7930 driver.info_3->name ? driver.info_3->name : "");
7933 fstrcpy(driver_name,
7934 driver.info_6->name ? driver.info_6->name : "");
7939 * I think this is where he DrvUpgradePrinter() hook would be
7940 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7941 * server. Right now, we just need to send ourselves a message
7942 * to update each printer bound to this driver. --jerry
7945 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7946 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7951 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7952 * decide if the driver init data should be deleted. The rules are:
7953 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7954 * 2) delete init data only if there is no 2k/Xp driver
7955 * 3) always delete init data
7956 * The generalized rule is always use init data from the highest order driver.
7957 * It is necessary to follow the driver install by an initialization step to
7958 * finish off this process.
7961 version = driver.info_3->cversion;
7962 else if (level == 6)
7963 version = driver.info_6->version;
7968 * 9x printer driver - never delete init data
7971 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7976 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7977 * there is no 2k/Xp driver init data for this driver name.
7981 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7983 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7985 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7987 if (!del_driver_init(driver_name))
7988 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7992 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7994 free_a_printer_driver(driver1,3);
7995 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
8002 * 2k or Xp printer driver - always delete init data
8005 if (!del_driver_init(driver_name))
8006 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
8011 DEBUG(0,("%s: invalid level=%d\n", fn, level));
8017 free_a_printer_driver(driver, level);
8021 /****************************************************************
8022 _spoolss_AddPrinterDriverEx
8023 ****************************************************************/
8025 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
8026 struct spoolss_AddPrinterDriverEx *r)
8028 struct spoolss_AddPrinterDriver a;
8031 * we only support the semantics of AddPrinterDriver()
8032 * i.e. only copy files that are newer than existing ones
8035 if (r->in.flags != APD_COPY_NEW_FILES) {
8036 return WERR_ACCESS_DENIED;
8039 a.in.servername = r->in.servername;
8040 a.in.info_ctr = r->in.info_ctr;
8042 return _spoolss_AddPrinterDriver(p, &a);
8045 /****************************************************************************
8046 ****************************************************************************/
8048 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8049 const char *servername,
8050 const char *environment,
8051 struct spoolss_DriverDirectoryInfo1 *info1,
8056 const char *pservername = NULL;
8057 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
8058 const char *short_archi;
8061 long_archi = environment;
8064 pservername = canon_servername(servername);
8066 if ( !is_myname_or_ipaddr(pservername))
8067 return WERR_INVALID_PARAM;
8069 if (!(short_archi = get_short_archi(long_archi)))
8070 return WERR_INVALID_ENVIRONMENT;
8072 path = talloc_asprintf(mem_ctx,
8073 "\\\\%s\\print$\\%s", pservername, short_archi);
8078 DEBUG(4,("printer driver directory: [%s]\n", path));
8080 info1->directory_name = path;
8082 *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0);
8084 if (*needed > offered) {
8086 ZERO_STRUCTP(info1);
8087 return WERR_INSUFFICIENT_BUFFER;
8093 /****************************************************************
8094 _spoolss_GetPrinterDriverDirectory
8095 ****************************************************************/
8097 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8098 struct spoolss_GetPrinterDriverDirectory *r)
8102 /* that's an [in out] buffer */
8104 if (!r->in.buffer && (r->in.offered != 0)) {
8105 return WERR_INVALID_PARAM;
8108 if (r->in.offered > MAX_RPC_DATA_SIZE) {
8109 return WERR_INVALID_PARAM;
8112 DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n"));
8116 switch (r->in.level) {
8118 werror = getprinterdriverdir_level_1(p->mem_ctx,
8121 &r->out.info->info1,
8124 if (!W_ERROR_IS_OK(werror)) {
8125 TALLOC_FREE(r->out.info);
8129 return WERR_UNKNOWN_LEVEL;
8135 /****************************************************************************
8136 ****************************************************************************/
8138 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8140 POLICY_HND *handle = &q_u->handle;
8141 uint32 idx = q_u->index;
8142 uint32 in_value_len = q_u->valuesize;
8143 uint32 in_data_len = q_u->datasize;
8144 uint32 *out_max_value_len = &r_u->valuesize;
8145 uint16 **out_value = &r_u->value;
8146 uint32 *out_value_len = &r_u->realvaluesize;
8147 uint32 *out_type = &r_u->type;
8148 uint32 *out_max_data_len = &r_u->datasize;
8149 uint8 **data_out = &r_u->data;
8150 uint32 *out_data_len = &r_u->realdatasize;
8152 NT_PRINTER_INFO_LEVEL *printer = NULL;
8154 uint32 biggest_valuesize;
8155 uint32 biggest_datasize;
8157 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8160 REGISTRY_VALUE *val = NULL;
8161 NT_PRINTER_DATA *p_data;
8162 int i, key_index, num_values;
8167 *out_max_data_len = 0;
8171 DEBUG(5,("spoolss_enumprinterdata\n"));
8174 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8178 if (!get_printer_snum(p,handle, &snum, NULL))
8181 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8182 if (!W_ERROR_IS_OK(result))
8185 p_data = printer->info_2->data;
8186 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8191 * The NT machine wants to know the biggest size of value and data
8193 * cf: MSDN EnumPrinterData remark section
8196 if ( !in_value_len && !in_data_len && (key_index != -1) )
8198 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8200 biggest_valuesize = 0;
8201 biggest_datasize = 0;
8203 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8205 for ( i=0; i<num_values; i++ )
8207 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8209 name_length = strlen(val->valuename);
8210 if ( strlen(val->valuename) > biggest_valuesize )
8211 biggest_valuesize = name_length;
8213 if ( val->size > biggest_datasize )
8214 biggest_datasize = val->size;
8216 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8220 /* the value is an UNICODE string but real_value_size is the length
8221 in bytes including the trailing 0 */
8223 *out_value_len = 2 * (1+biggest_valuesize);
8224 *out_data_len = biggest_datasize;
8226 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8232 * the value len is wrong in NT sp3
8233 * that's the number of bytes not the number of unicode chars
8236 if ( key_index != -1 )
8237 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8242 /* out_value should default to "" or else NT4 has
8243 problems unmarshalling the response */
8245 *out_max_value_len=(in_value_len/sizeof(uint16));
8248 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8250 result = WERR_NOMEM;
8253 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8259 /* the data is counted in bytes */
8261 *out_max_data_len = in_data_len;
8262 *out_data_len = in_data_len;
8264 /* only allocate when given a non-zero data_len */
8266 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8268 result = WERR_NOMEM;
8272 result = WERR_NO_MORE_ITEMS;
8278 * - counted in bytes in the request
8279 * - counted in UNICODE chars in the max reply
8280 * - counted in bytes in the real size
8282 * take a pause *before* coding not *during* coding
8286 *out_max_value_len=(in_value_len/sizeof(uint16));
8288 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8290 result = WERR_NOMEM;
8294 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8302 *out_type = regval_type( val );
8304 /* data - counted in bytes */
8306 *out_max_data_len = in_data_len;
8307 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8309 result = WERR_NOMEM;
8312 data_len = regval_size(val);
8313 if ( *data_out && data_len )
8314 memcpy( *data_out, regval_data_p(val), data_len );
8315 *out_data_len = data_len;
8319 free_a_printer(&printer, 2);
8323 /****************************************************************************
8324 ****************************************************************************/
8326 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8328 POLICY_HND *handle = &q_u->handle;
8329 UNISTR2 *value = &q_u->value;
8330 uint32 type = q_u->type;
8331 uint8 *data = q_u->data;
8332 uint32 real_len = q_u->real_len;
8334 NT_PRINTER_INFO_LEVEL *printer = NULL;
8336 WERROR status = WERR_OK;
8337 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8340 DEBUG(5,("spoolss_setprinterdata\n"));
8343 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8347 if ( Printer->printer_type == SPLHND_SERVER ) {
8348 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8349 return WERR_INVALID_PARAM;
8352 if (!get_printer_snum(p,handle, &snum, NULL))
8356 * Access check : NT returns "access denied" if you make a
8357 * SetPrinterData call without the necessary privildge.
8358 * we were originally returning OK if nothing changed
8359 * which made Win2k issue **a lot** of SetPrinterData
8360 * when connecting to a printer --jerry
8363 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8365 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8366 status = WERR_ACCESS_DENIED;
8370 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8371 if (!W_ERROR_IS_OK(status))
8374 unistr2_to_ascii(valuename, value, sizeof(valuename));
8377 * When client side code sets a magic printer data key, detect it and save
8378 * the current printer data and the magic key's data (its the DEVMODE) for
8379 * future printer/driver initializations.
8381 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8383 /* Set devmode and printer initialization info */
8384 status = save_driver_init( printer, 2, data, real_len );
8386 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8390 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8391 type, data, real_len );
8392 if ( W_ERROR_IS_OK(status) )
8393 status = mod_a_printer(printer, 2);
8397 free_a_printer(&printer, 2);
8402 /****************************************************************
8403 _spoolss_ResetPrinter
8404 ****************************************************************/
8406 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8407 struct spoolss_ResetPrinter *r)
8409 POLICY_HND *handle = r->in.handle;
8410 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8413 DEBUG(5,("_spoolss_ResetPrinter\n"));
8416 * All we do is to check to see if the handle and queue is valid.
8417 * This call really doesn't mean anything to us because we only
8418 * support RAW printing. --jerry
8422 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8423 OUR_HANDLE(handle)));
8427 if (!get_printer_snum(p,handle, &snum, NULL))
8431 /* blindly return success */
8435 /****************************************************************
8436 _spoolss_DeletePrinterData
8437 ****************************************************************/
8439 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8440 struct spoolss_DeletePrinterData *r)
8442 POLICY_HND *handle = r->in.handle;
8443 NT_PRINTER_INFO_LEVEL *printer = NULL;
8445 WERROR status = WERR_OK;
8446 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8448 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8451 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8452 OUR_HANDLE(handle)));
8456 if (!get_printer_snum(p, handle, &snum, NULL))
8459 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8460 DEBUG(3, ("_spoolss_DeletePrinterData: "
8461 "printer properties change denied by handle\n"));
8462 return WERR_ACCESS_DENIED;
8465 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8466 if (!W_ERROR_IS_OK(status))
8469 if (!r->in.value_name) {
8470 free_a_printer(&printer, 2);
8474 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8477 if ( W_ERROR_IS_OK(status) )
8478 mod_a_printer( printer, 2 );
8480 free_a_printer(&printer, 2);
8485 /****************************************************************
8487 ****************************************************************/
8489 WERROR _spoolss_AddForm(pipes_struct *p,
8490 struct spoolss_AddForm *r)
8492 POLICY_HND *handle = r->in.handle;
8493 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8494 nt_forms_struct tmpForm;
8496 WERROR status = WERR_OK;
8497 NT_PRINTER_INFO_LEVEL *printer = NULL;
8500 nt_forms_struct *list=NULL;
8501 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8503 DEBUG(5,("_spoolss_AddForm\n"));
8506 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8507 OUR_HANDLE(handle)));
8512 /* forms can be added on printer of on the print server handle */
8514 if ( Printer->printer_type == SPLHND_PRINTER )
8516 if (!get_printer_snum(p,handle, &snum, NULL))
8519 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8520 if (!W_ERROR_IS_OK(status))
8524 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8525 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8526 status = WERR_ACCESS_DENIED;
8530 /* can't add if builtin */
8532 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8533 status = WERR_FILE_EXISTS;
8537 count = get_ntforms(&list);
8539 if(!add_a_form(&list, form, &count)) {
8540 status = WERR_NOMEM;
8544 write_ntforms(&list, count);
8547 * ChangeID must always be set if this is a printer
8550 if ( Printer->printer_type == SPLHND_PRINTER )
8551 status = mod_a_printer(printer, 2);
8555 free_a_printer(&printer, 2);
8561 /****************************************************************
8563 ****************************************************************/
8565 WERROR _spoolss_DeleteForm(pipes_struct *p,
8566 struct spoolss_DeleteForm *r)
8568 POLICY_HND *handle = r->in.handle;
8569 const char *form_name = r->in.form_name;
8570 nt_forms_struct tmpForm;
8572 nt_forms_struct *list=NULL;
8573 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8575 WERROR status = WERR_OK;
8576 NT_PRINTER_INFO_LEVEL *printer = NULL;
8578 DEBUG(5,("_spoolss_DeleteForm\n"));
8581 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8582 OUR_HANDLE(handle)));
8586 /* forms can be deleted on printer of on the print server handle */
8588 if ( Printer->printer_type == SPLHND_PRINTER )
8590 if (!get_printer_snum(p,handle, &snum, NULL))
8593 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8594 if (!W_ERROR_IS_OK(status))
8598 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8599 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8600 status = WERR_ACCESS_DENIED;
8604 /* can't delete if builtin */
8606 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8607 status = WERR_INVALID_PARAM;
8611 count = get_ntforms(&list);
8613 if ( !delete_a_form(&list, form_name, &count, &status ))
8617 * ChangeID must always be set if this is a printer
8620 if ( Printer->printer_type == SPLHND_PRINTER )
8621 status = mod_a_printer(printer, 2);
8625 free_a_printer(&printer, 2);
8631 /****************************************************************
8633 ****************************************************************/
8635 WERROR _spoolss_SetForm(pipes_struct *p,
8636 struct spoolss_SetForm *r)
8638 POLICY_HND *handle = r->in.handle;
8639 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8640 nt_forms_struct tmpForm;
8642 WERROR status = WERR_OK;
8643 NT_PRINTER_INFO_LEVEL *printer = NULL;
8646 nt_forms_struct *list=NULL;
8647 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8649 DEBUG(5,("_spoolss_SetForm\n"));
8652 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8653 OUR_HANDLE(handle)));
8657 /* forms can be modified on printer of on the print server handle */
8659 if ( Printer->printer_type == SPLHND_PRINTER )
8661 if (!get_printer_snum(p,handle, &snum, NULL))
8664 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8665 if (!W_ERROR_IS_OK(status))
8669 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8670 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8671 status = WERR_ACCESS_DENIED;
8675 /* can't set if builtin */
8676 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8677 status = WERR_INVALID_PARAM;
8681 count = get_ntforms(&list);
8682 update_a_form(&list, form, count);
8683 write_ntforms(&list, count);
8686 * ChangeID must always be set if this is a printer
8689 if ( Printer->printer_type == SPLHND_PRINTER )
8690 status = mod_a_printer(printer, 2);
8695 free_a_printer(&printer, 2);
8701 /****************************************************************************
8702 enumprintprocessors level 1.
8703 ****************************************************************************/
8705 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8707 PRINTPROCESSOR_1 *info_1=NULL;
8708 WERROR result = WERR_OK;
8710 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8715 init_unistr(&info_1->name, "winprint");
8717 *needed += spoolss_size_printprocessor_info_1(info_1);
8719 if (*needed > offered) {
8720 result = WERR_INSUFFICIENT_BUFFER;
8724 if (!rpcbuf_alloc_size(buffer, *needed)) {
8725 result = WERR_NOMEM;
8729 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8734 if ( !W_ERROR_IS_OK(result) )
8740 /****************************************************************************
8741 ****************************************************************************/
8743 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8745 uint32 level = q_u->level;
8746 RPC_BUFFER *buffer = NULL;
8747 uint32 offered = q_u->offered;
8748 uint32 *needed = &r_u->needed;
8749 uint32 *returned = &r_u->returned;
8751 /* that's an [in out] buffer */
8753 if (!q_u->buffer && (offered!=0)) {
8754 return WERR_INVALID_PARAM;
8757 if (offered > MAX_RPC_DATA_SIZE) {
8758 return WERR_INVALID_PARAM;
8761 rpcbuf_move(q_u->buffer, &r_u->buffer);
8762 buffer = r_u->buffer;
8764 DEBUG(5,("spoolss_enumprintprocessors\n"));
8767 * Enumerate the print processors ...
8769 * Just reply with "winprint", to keep NT happy
8770 * and I can use my nice printer checker.
8778 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8780 return WERR_UNKNOWN_LEVEL;
8784 /****************************************************************************
8785 enumprintprocdatatypes level 1.
8786 ****************************************************************************/
8788 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8790 PRINTPROCDATATYPE_1 *info_1=NULL;
8791 WERROR result = WERR_OK;
8793 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8798 init_unistr(&info_1->name, "RAW");
8800 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8802 if (*needed > offered) {
8803 result = WERR_INSUFFICIENT_BUFFER;
8807 if (!rpcbuf_alloc_size(buffer, *needed)) {
8808 result = WERR_NOMEM;
8812 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8817 if ( !W_ERROR_IS_OK(result) )
8823 /****************************************************************************
8824 ****************************************************************************/
8826 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8828 uint32 level = q_u->level;
8829 RPC_BUFFER *buffer = NULL;
8830 uint32 offered = q_u->offered;
8831 uint32 *needed = &r_u->needed;
8832 uint32 *returned = &r_u->returned;
8834 /* that's an [in out] buffer */
8836 if (!q_u->buffer && (offered!=0)) {
8837 return WERR_INVALID_PARAM;
8840 if (offered > MAX_RPC_DATA_SIZE) {
8841 return WERR_INVALID_PARAM;
8844 rpcbuf_move(q_u->buffer, &r_u->buffer);
8845 buffer = r_u->buffer;
8847 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8854 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8856 return WERR_UNKNOWN_LEVEL;
8860 /****************************************************************************
8861 enumprintmonitors level 1.
8862 ****************************************************************************/
8864 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8866 PRINTMONITOR_1 *info_1;
8867 WERROR result = WERR_OK;
8870 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8875 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8876 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8878 for ( i=0; i<*returned; i++ ) {
8879 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8882 if (*needed > offered) {
8883 result = WERR_INSUFFICIENT_BUFFER;
8887 if (!rpcbuf_alloc_size(buffer, *needed)) {
8888 result = WERR_NOMEM;
8892 for ( i=0; i<*returned; i++ ) {
8893 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8899 if ( !W_ERROR_IS_OK(result) )
8905 /****************************************************************************
8906 enumprintmonitors level 2.
8907 ****************************************************************************/
8909 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8911 PRINTMONITOR_2 *info_2;
8912 WERROR result = WERR_OK;
8915 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8920 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8921 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8922 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8924 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8925 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8926 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8928 for ( i=0; i<*returned; i++ ) {
8929 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8932 if (*needed > offered) {
8933 result = WERR_INSUFFICIENT_BUFFER;
8937 if (!rpcbuf_alloc_size(buffer, *needed)) {
8938 result = WERR_NOMEM;
8942 for ( i=0; i<*returned; i++ ) {
8943 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8949 if ( !W_ERROR_IS_OK(result) )
8955 /****************************************************************************
8956 ****************************************************************************/
8958 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8960 uint32 level = q_u->level;
8961 RPC_BUFFER *buffer = NULL;
8962 uint32 offered = q_u->offered;
8963 uint32 *needed = &r_u->needed;
8964 uint32 *returned = &r_u->returned;
8966 /* that's an [in out] buffer */
8968 if (!q_u->buffer && (offered!=0)) {
8969 return WERR_INVALID_PARAM;
8972 if (offered > MAX_RPC_DATA_SIZE) {
8973 return WERR_INVALID_PARAM;
8976 rpcbuf_move(q_u->buffer, &r_u->buffer);
8977 buffer = r_u->buffer;
8979 DEBUG(5,("spoolss_enumprintmonitors\n"));
8982 * Enumerate the print monitors ...
8984 * Just reply with "Local Port", to keep NT happy
8985 * and I can use my nice printer checker.
8993 return enumprintmonitors_level_1(buffer, offered, needed, returned);
8995 return enumprintmonitors_level_2(buffer, offered, needed, returned);
8997 return WERR_UNKNOWN_LEVEL;
9001 /****************************************************************************
9002 ****************************************************************************/
9004 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9005 NT_PRINTER_INFO_LEVEL *ntprinter,
9006 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9011 JOB_INFO_1 *info_1=NULL;
9012 WERROR result = WERR_OK;
9014 info_1=SMB_MALLOC_P(JOB_INFO_1);
9016 if (info_1 == NULL) {
9020 for (i=0; i<count && found==False; i++) {
9021 if ((*queue)[i].job==(int)jobid)
9027 /* NT treats not found as bad param... yet another bad choice */
9028 return WERR_INVALID_PARAM;
9031 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9033 *needed += spoolss_size_job_info_1(info_1);
9035 if (*needed > offered) {
9036 result = WERR_INSUFFICIENT_BUFFER;
9040 if (!rpcbuf_alloc_size(buffer, *needed)) {
9041 result = WERR_NOMEM;
9045 smb_io_job_info_1("", buffer, info_1, 0);
9053 /****************************************************************************
9054 ****************************************************************************/
9056 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9057 NT_PRINTER_INFO_LEVEL *ntprinter,
9058 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9065 DEVICEMODE *devmode = NULL;
9066 NT_DEVICEMODE *nt_devmode = NULL;
9068 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9071 ZERO_STRUCTP(info_2);
9073 for ( i=0; i<count && found==False; i++ )
9075 if ((*queue)[i].job == (int)jobid)
9080 /* NT treats not found as bad param... yet another bad
9082 result = WERR_INVALID_PARAM;
9087 * if the print job does not have a DEVMODE associated with it,
9088 * just use the one for the printer. A NULL devicemode is not
9089 * a failure condition
9092 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9093 devmode = construct_dev_mode(lp_const_servicename(snum));
9095 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9096 ZERO_STRUCTP( devmode );
9097 convert_nt_devicemode( devmode, nt_devmode );
9101 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9103 *needed += spoolss_size_job_info_2(info_2);
9105 if (*needed > offered) {
9106 result = WERR_INSUFFICIENT_BUFFER;
9110 if (!rpcbuf_alloc_size(buffer, *needed)) {
9111 result = WERR_NOMEM;
9115 smb_io_job_info_2("", buffer, info_2, 0);
9120 /* Cleanup allocated memory */
9122 free_job_info_2(info_2); /* Also frees devmode */
9128 /****************************************************************************
9129 ****************************************************************************/
9131 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9133 POLICY_HND *handle = &q_u->handle;
9134 uint32 jobid = q_u->jobid;
9135 uint32 level = q_u->level;
9136 RPC_BUFFER *buffer = NULL;
9137 uint32 offered = q_u->offered;
9138 uint32 *needed = &r_u->needed;
9139 WERROR wstatus = WERR_OK;
9140 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9143 print_queue_struct *queue = NULL;
9144 print_status_struct prt_status;
9146 /* that's an [in out] buffer */
9148 if (!q_u->buffer && (offered!=0)) {
9149 return WERR_INVALID_PARAM;
9152 if (offered > MAX_RPC_DATA_SIZE) {
9153 return WERR_INVALID_PARAM;
9156 rpcbuf_move(q_u->buffer, &r_u->buffer);
9157 buffer = r_u->buffer;
9159 DEBUG(5,("spoolss_getjob\n"));
9163 if (!get_printer_snum(p, handle, &snum, NULL))
9166 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9167 if ( !W_ERROR_IS_OK(wstatus) )
9170 count = print_queue_status(snum, &queue, &prt_status);
9172 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9173 count, prt_status.status, prt_status.message));
9177 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9178 buffer, offered, needed);
9181 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9182 buffer, offered, needed);
9185 wstatus = WERR_UNKNOWN_LEVEL;
9190 free_a_printer( &ntprinter, 2 );
9195 /****************************************************************
9196 _spoolss_GetPrinterDataEx
9198 From MSDN documentation of GetPrinterDataEx: pass request
9199 to GetPrinterData if key is "PrinterDriverData".
9200 ****************************************************************/
9202 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9203 struct spoolss_GetPrinterDataEx *r)
9205 POLICY_HND *handle = r->in.handle;
9207 const char *keyname = r->in.key_name;
9208 const char *valuename = r->in.value_name;
9210 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9212 NT_PRINTER_INFO_LEVEL *printer = NULL;
9214 WERROR status = WERR_OK;
9216 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9218 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9219 keyname, valuename));
9221 /* in case of problem, return some default values */
9227 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9228 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9229 status = WERR_BADFID;
9233 /* Is the handle to a printer or to the server? */
9235 if (Printer->printer_type == SPLHND_SERVER) {
9236 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9237 "Not implemented for server handles yet\n"));
9238 status = WERR_INVALID_PARAM;
9242 if ( !get_printer_snum(p,handle, &snum, NULL) )
9245 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9246 if ( !W_ERROR_IS_OK(status) )
9249 /* check to see if the keyname is valid */
9250 if ( !strlen(keyname) ) {
9251 status = WERR_INVALID_PARAM;
9255 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9256 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9257 "Invalid keyname [%s]\n", keyname ));
9258 free_a_printer( &printer, 2 );
9259 status = WERR_BADFILE;
9263 /* When given a new keyname, we should just create it */
9265 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9266 r->out.type, &data, r->out.needed,
9269 if (*r->out.needed > r->in.offered) {
9270 status = WERR_MORE_DATA;
9273 if (W_ERROR_IS_OK(status)) {
9274 memcpy(r->out.buffer, data, r->in.offered);
9279 free_a_printer( &printer, 2 );
9284 /****************************************************************
9285 _spoolss_SetPrinterDataEx
9286 ****************************************************************/
9288 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9289 struct spoolss_SetPrinterDataEx *r)
9291 POLICY_HND *handle = r->in.handle;
9292 NT_PRINTER_INFO_LEVEL *printer = NULL;
9294 WERROR status = WERR_OK;
9295 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9298 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9300 /* From MSDN documentation of SetPrinterDataEx: pass request to
9301 SetPrinterData if key is "PrinterDriverData" */
9304 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9305 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9309 if ( Printer->printer_type == SPLHND_SERVER ) {
9310 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9311 "Not implemented for server handles yet\n"));
9312 return WERR_INVALID_PARAM;
9315 if ( !get_printer_snum(p,handle, &snum, NULL) )
9319 * Access check : NT returns "access denied" if you make a
9320 * SetPrinterData call without the necessary privildge.
9321 * we were originally returning OK if nothing changed
9322 * which made Win2k issue **a lot** of SetPrinterData
9323 * when connecting to a printer --jerry
9326 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9328 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9329 "change denied by handle access permissions\n"));
9330 return WERR_ACCESS_DENIED;
9333 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9334 if (!W_ERROR_IS_OK(status))
9337 /* check for OID in valuename */
9339 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9345 /* save the registry data */
9347 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9348 r->in.type, r->in.buffer, r->in.offered );
9350 if ( W_ERROR_IS_OK(status) )
9352 /* save the OID if one was specified */
9354 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9355 r->in.key_name, SPOOL_OID_KEY);
9361 * I'm not checking the status here on purpose. Don't know
9362 * if this is right, but I'm returning the status from the
9363 * previous set_printer_dataex() call. I have no idea if
9364 * this is right. --jerry
9367 set_printer_dataex( printer, str, r->in.value_name,
9368 REG_SZ, (uint8 *)oid_string,
9369 strlen(oid_string)+1 );
9372 status = mod_a_printer(printer, 2);
9375 free_a_printer(&printer, 2);
9380 /****************************************************************
9381 _spoolss_DeletePrinterDataEx
9382 ****************************************************************/
9384 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9385 struct spoolss_DeletePrinterDataEx *r)
9387 POLICY_HND *handle = r->in.handle;
9388 NT_PRINTER_INFO_LEVEL *printer = NULL;
9390 WERROR status = WERR_OK;
9391 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9393 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9396 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9397 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9401 if (!get_printer_snum(p, handle, &snum, NULL))
9404 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9405 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9406 "printer properties change denied by handle\n"));
9407 return WERR_ACCESS_DENIED;
9410 if (!r->in.value_name || !r->in.key_name) {
9414 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9415 if (!W_ERROR_IS_OK(status))
9418 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9420 if ( W_ERROR_IS_OK(status) )
9421 mod_a_printer( printer, 2 );
9423 free_a_printer(&printer, 2);
9428 /********************************************************************
9429 * spoolss_enumprinterkey
9430 ********************************************************************/
9433 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9436 fstring *keynames = NULL;
9437 uint16 *enumkeys = NULL;
9440 POLICY_HND *handle = &q_u->handle;
9441 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9442 NT_PRINTER_DATA *data;
9443 NT_PRINTER_INFO_LEVEL *printer = NULL;
9445 WERROR status = WERR_BADFILE;
9448 DEBUG(4,("_spoolss_enumprinterkey\n"));
9451 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9455 if ( !get_printer_snum(p,handle, &snum, NULL) )
9458 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9459 if (!W_ERROR_IS_OK(status))
9462 /* get the list of subkey names */
9464 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9465 data = printer->info_2->data;
9467 num_keys = get_printer_subkeys( data, key, &keynames );
9469 if ( num_keys == -1 ) {
9470 status = WERR_BADFILE;
9474 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9476 r_u->needed = printerkey_len*2;
9478 if ( q_u->size < r_u->needed ) {
9479 status = WERR_MORE_DATA;
9483 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9484 status = WERR_NOMEM;
9490 if ( q_u->size < r_u->needed )
9491 status = WERR_MORE_DATA;
9494 free_a_printer( &printer, 2 );
9495 SAFE_FREE( keynames );
9500 /****************************************************************
9501 _spoolss_DeletePrinterKey
9502 ****************************************************************/
9504 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9505 struct spoolss_DeletePrinterKey *r)
9507 POLICY_HND *handle = r->in.handle;
9508 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9509 NT_PRINTER_INFO_LEVEL *printer = NULL;
9513 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9516 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9517 OUR_HANDLE(handle)));
9521 /* if keyname == NULL, return error */
9523 if ( !r->in.key_name )
9524 return WERR_INVALID_PARAM;
9526 if (!get_printer_snum(p, handle, &snum, NULL))
9529 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9530 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9531 "printer properties change denied by handle\n"));
9532 return WERR_ACCESS_DENIED;
9535 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9536 if (!W_ERROR_IS_OK(status))
9539 /* delete the key and all subneys */
9541 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9543 if ( W_ERROR_IS_OK(status) )
9544 status = mod_a_printer(printer, 2);
9546 free_a_printer( &printer, 2 );
9552 /********************************************************************
9553 * spoolss_enumprinterdataex
9554 ********************************************************************/
9556 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9558 POLICY_HND *handle = &q_u->handle;
9559 uint32 in_size = q_u->size;
9562 NT_PRINTER_INFO_LEVEL *printer = NULL;
9563 PRINTER_ENUM_VALUES *enum_values = NULL;
9564 NT_PRINTER_DATA *p_data;
9566 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9571 REGISTRY_VALUE *val;
9576 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9579 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9584 * first check for a keyname of NULL or "". Win2k seems to send
9585 * this a lot and we should send back WERR_INVALID_PARAM
9586 * no need to spend time looking up the printer in this case.
9590 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9591 if ( !strlen(key) ) {
9592 result = WERR_INVALID_PARAM;
9596 /* get the printer off of disk */
9598 if (!get_printer_snum(p,handle, &snum, NULL))
9601 ZERO_STRUCT(printer);
9602 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9603 if (!W_ERROR_IS_OK(result))
9606 /* now look for a match on the key name */
9608 p_data = printer->info_2->data;
9610 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9611 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9613 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9614 result = WERR_INVALID_PARAM;
9621 /* allocate the memory for the array of pointers -- if necessary */
9623 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9626 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9628 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9629 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9630 result = WERR_NOMEM;
9634 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9638 * loop through all params and build the array to pass
9639 * back to the client
9642 for ( i=0; i<num_entries; i++ )
9644 /* lookup the registry value */
9646 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9647 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9651 value_name = regval_name( val );
9652 init_unistr( &enum_values[i].valuename, value_name );
9653 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9654 enum_values[i].type = regval_type( val );
9656 data_len = regval_size( val );
9658 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9660 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9662 result = WERR_NOMEM;
9666 enum_values[i].data_len = data_len;
9668 /* keep track of the size of the array in bytes */
9670 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9673 /* housekeeping information in the reply */
9675 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9676 * the hand marshalled container size is a multiple
9677 * of 4 bytes for RPC alignment.
9681 needed += 4-(needed % 4);
9684 r_u->needed = needed;
9685 r_u->returned = num_entries;
9687 if (needed > in_size) {
9688 result = WERR_MORE_DATA;
9692 /* copy data into the reply */
9694 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9695 response buffer size is != the offered buffer size
9697 r_u->ctr.size = r_u->needed;
9699 r_u->ctr.size = in_size;
9701 r_u->ctr.size_of_array = r_u->returned;
9702 r_u->ctr.values = enum_values;
9706 free_a_printer(&printer, 2);
9711 /****************************************************************************
9712 ****************************************************************************/
9714 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9715 const char *servername,
9716 const char *environment,
9717 struct spoolss_PrintProcessorDirectoryInfo1 *info1,
9721 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
9722 const char *short_archi;
9725 long_archi = environment;
9728 short_archi = get_short_archi(long_archi);
9730 return WERR_INVALID_ENVIRONMENT;
9733 /* I think this should look like this - gd
9734 info1->directory_name = talloc_asprintf(mem_ctx,
9735 "C:\\WINNT\\System32\\spool\\PRTPROCS\\%s", short_archi);
9737 info1->directory_name = talloc_strdup(mem_ctx,
9738 "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9740 if (!info1->directory_name) {
9744 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(info1, NULL, 0);
9746 if (*needed > offered) {
9747 return WERR_INSUFFICIENT_BUFFER;
9753 /****************************************************************
9754 _spoolss_GetPrintProcessorDirectory
9755 ****************************************************************/
9757 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9758 struct spoolss_GetPrintProcessorDirectory *r)
9762 /* that's an [in out] buffer */
9764 if (!r->in.buffer && (r->in.offered != 0)) {
9765 return WERR_INVALID_PARAM;
9768 if (r->in.offered > MAX_RPC_DATA_SIZE) {
9769 return WERR_INVALID_PARAM;
9772 DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n"));
9776 switch (r->in.level) {
9778 result = getprintprocessordirectory_level_1(p->mem_ctx,
9781 &r->out.info->info1,
9784 if (!W_ERROR_IS_OK(result)) {
9785 TALLOC_FREE(r->out.info);
9789 result = WERR_UNKNOWN_LEVEL;
9795 /*******************************************************************
9796 ********************************************************************/
9798 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9799 const char *dllname)
9801 enum ndr_err_code ndr_err;
9802 struct spoolss_MonitorUi ui;
9804 ui.dll_name = dllname;
9806 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9807 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9808 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9809 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9811 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9814 /*******************************************************************
9815 Streams the monitor UI DLL name in UNICODE
9816 *******************************************************************/
9818 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9819 NT_USER_TOKEN *token, DATA_BLOB *in,
9820 DATA_BLOB *out, uint32_t *needed)
9822 const char *dllname = "tcpmonui.dll";
9824 *needed = (strlen(dllname)+1) * 2;
9826 if (out->length < *needed) {
9827 return WERR_INSUFFICIENT_BUFFER;
9830 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9837 /*******************************************************************
9838 ********************************************************************/
9840 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9841 struct spoolss_PortData1 *port1,
9842 const DATA_BLOB *buf)
9844 enum ndr_err_code ndr_err;
9845 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9846 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9847 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9848 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9850 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9853 /*******************************************************************
9854 ********************************************************************/
9856 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9857 struct spoolss_PortData2 *port2,
9858 const DATA_BLOB *buf)
9860 enum ndr_err_code ndr_err;
9861 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9862 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9863 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9864 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9866 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9869 /*******************************************************************
9870 Create a new TCP/IP port
9871 *******************************************************************/
9873 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9874 NT_USER_TOKEN *token, DATA_BLOB *in,
9875 DATA_BLOB *out, uint32_t *needed)
9877 struct spoolss_PortData1 port1;
9878 struct spoolss_PortData2 port2;
9879 char *device_uri = NULL;
9882 const char *portname;
9883 const char *hostaddress;
9885 uint32_t port_number;
9888 /* peek for spoolss_PortData version */
9890 if (!in || (in->length < (128 + 4))) {
9891 return WERR_GENERAL_FAILURE;
9894 version = IVAL(in->data, 128);
9900 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9904 portname = port1.portname;
9905 hostaddress = port1.hostaddress;
9906 queue = port1.queue;
9907 protocol = port1.protocol;
9908 port_number = port1.port_number;
9914 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9918 portname = port2.portname;
9919 hostaddress = port2.hostaddress;
9920 queue = port2.queue;
9921 protocol = port2.protocol;
9922 port_number = port2.port_number;
9926 DEBUG(1,("xcvtcp_addport: "
9927 "unknown version of port_data: %d\n", version));
9928 return WERR_UNKNOWN_PORT;
9931 /* create the device URI and call the add_port_hook() */
9934 case PROTOCOL_RAWTCP_TYPE:
9935 device_uri = talloc_asprintf(mem_ctx,
9936 "socket://%s:%d/", hostaddress,
9940 case PROTOCOL_LPR_TYPE:
9941 device_uri = talloc_asprintf(mem_ctx,
9942 "lpr://%s/%s", hostaddress, queue );
9946 return WERR_UNKNOWN_PORT;
9953 return add_port_hook(mem_ctx, token, portname, device_uri);
9956 /*******************************************************************
9957 *******************************************************************/
9959 struct xcv_api_table xcvtcp_cmds[] = {
9960 { "MonitorUI", xcvtcp_monitorui },
9961 { "AddPort", xcvtcp_addport},
9965 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9966 NT_USER_TOKEN *token, const char *command,
9973 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9975 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9976 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9977 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9980 return WERR_BADFUNC;
9983 /*******************************************************************
9984 *******************************************************************/
9985 #if 0 /* don't support management using the "Local Port" monitor */
9987 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9988 NT_USER_TOKEN *token, DATA_BLOB *in,
9989 DATA_BLOB *out, uint32_t *needed)
9991 const char *dllname = "localui.dll";
9993 *needed = (strlen(dllname)+1) * 2;
9995 if (out->length < *needed) {
9996 return WERR_INSUFFICIENT_BUFFER;
9999 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10006 /*******************************************************************
10007 *******************************************************************/
10009 struct xcv_api_table xcvlocal_cmds[] = {
10010 { "MonitorUI", xcvlocal_monitorui },
10014 struct xcv_api_table xcvlocal_cmds[] = {
10021 /*******************************************************************
10022 *******************************************************************/
10024 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10025 NT_USER_TOKEN *token, const char *command,
10026 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10031 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10033 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10034 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10035 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10037 return WERR_BADFUNC;
10040 /****************************************************************
10042 ****************************************************************/
10044 WERROR _spoolss_XcvData(pipes_struct *p,
10045 struct spoolss_XcvData *r)
10047 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10048 DATA_BLOB out_data;
10052 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10053 OUR_HANDLE(r->in.handle)));
10054 return WERR_BADFID;
10057 /* Has to be a handle to the TCP/IP port monitor */
10059 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10060 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10061 return WERR_BADFID;
10064 /* requires administrative access to the server */
10066 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10067 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10068 return WERR_ACCESS_DENIED;
10071 /* Allocate the outgoing buffer */
10073 if (r->in.out_data_size) {
10074 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10075 if (out_data.data == NULL) {
10080 switch ( Printer->printer_type ) {
10081 case SPLHND_PORTMON_TCP:
10082 werror = process_xcvtcp_command(p->mem_ctx,
10083 p->server_info->ptok,
10084 r->in.function_name,
10085 &r->in.in_data, &out_data,
10088 case SPLHND_PORTMON_LOCAL:
10089 werror = process_xcvlocal_command(p->mem_ctx,
10090 p->server_info->ptok,
10091 r->in.function_name,
10092 &r->in.in_data, &out_data,
10096 werror = WERR_INVALID_PRINT_MONITOR;
10099 if (!W_ERROR_IS_OK(werror)) {
10103 *r->out.status_code = 0;
10105 memcpy(r->out.out_data, out_data.data, out_data.length);
10110 /****************************************************************
10111 _spoolss_AddPrintProcessor
10112 ****************************************************************/
10114 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10115 struct spoolss_AddPrintProcessor *r)
10117 /* for now, just indicate success and ignore the add. We'll
10118 automatically set the winprint processor for printer
10119 entries later. Used to debug the LexMark Optra S 1855 PCL
10125 /****************************************************************
10126 _spoolss_EnumPrinters
10127 ****************************************************************/
10129 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10130 struct spoolss_EnumPrinters *r)
10132 p->rng_fault_state = true;
10133 return WERR_NOT_SUPPORTED;
10136 /****************************************************************
10138 ****************************************************************/
10140 WERROR _spoolss_GetJob(pipes_struct *p,
10141 struct spoolss_GetJob *r)
10143 p->rng_fault_state = true;
10144 return WERR_NOT_SUPPORTED;
10147 /****************************************************************
10149 ****************************************************************/
10151 WERROR _spoolss_EnumJobs(pipes_struct *p,
10152 struct spoolss_EnumJobs *r)
10154 p->rng_fault_state = true;
10155 return WERR_NOT_SUPPORTED;
10158 /****************************************************************
10159 _spoolss_AddPrinter
10160 ****************************************************************/
10162 WERROR _spoolss_AddPrinter(pipes_struct *p,
10163 struct spoolss_AddPrinter *r)
10165 p->rng_fault_state = true;
10166 return WERR_NOT_SUPPORTED;
10169 /****************************************************************
10170 _spoolss_GetPrinter
10171 ****************************************************************/
10173 WERROR _spoolss_GetPrinter(pipes_struct *p,
10174 struct spoolss_GetPrinter *r)
10176 p->rng_fault_state = true;
10177 return WERR_NOT_SUPPORTED;
10180 /****************************************************************
10181 _spoolss_EnumPrinterDrivers
10182 ****************************************************************/
10184 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10185 struct spoolss_EnumPrinterDrivers *r)
10187 p->rng_fault_state = true;
10188 return WERR_NOT_SUPPORTED;
10191 /****************************************************************
10192 _spoolss_GetPrinterDriver
10193 ****************************************************************/
10195 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10196 struct spoolss_GetPrinterDriver *r)
10198 p->rng_fault_state = true;
10199 return WERR_NOT_SUPPORTED;
10202 /****************************************************************
10203 _spoolss_EnumPrintProcessors
10204 ****************************************************************/
10206 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10207 struct spoolss_EnumPrintProcessors *r)
10209 p->rng_fault_state = true;
10210 return WERR_NOT_SUPPORTED;
10213 /****************************************************************
10214 _spoolss_ReadPrinter
10215 ****************************************************************/
10217 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10218 struct spoolss_ReadPrinter *r)
10220 p->rng_fault_state = true;
10221 return WERR_NOT_SUPPORTED;
10224 /****************************************************************
10225 _spoolss_GetPrinterData
10226 ****************************************************************/
10228 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10229 struct spoolss_GetPrinterData *r)
10231 p->rng_fault_state = true;
10232 return WERR_NOT_SUPPORTED;
10235 /****************************************************************
10236 _spoolss_SetPrinterData
10237 ****************************************************************/
10239 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10240 struct spoolss_SetPrinterData *r)
10242 p->rng_fault_state = true;
10243 return WERR_NOT_SUPPORTED;
10246 /****************************************************************
10247 _spoolss_WaitForPrinterChange
10248 ****************************************************************/
10250 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10251 struct spoolss_WaitForPrinterChange *r)
10253 p->rng_fault_state = true;
10254 return WERR_NOT_SUPPORTED;
10257 /****************************************************************
10259 ****************************************************************/
10261 WERROR _spoolss_EnumForms(pipes_struct *p,
10262 struct spoolss_EnumForms *r)
10264 p->rng_fault_state = true;
10265 return WERR_NOT_SUPPORTED;
10268 /****************************************************************
10270 ****************************************************************/
10272 WERROR _spoolss_EnumPorts(pipes_struct *p,
10273 struct spoolss_EnumPorts *r)
10275 p->rng_fault_state = true;
10276 return WERR_NOT_SUPPORTED;
10279 /****************************************************************
10280 _spoolss_EnumMonitors
10281 ****************************************************************/
10283 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10284 struct spoolss_EnumMonitors *r)
10286 p->rng_fault_state = true;
10287 return WERR_NOT_SUPPORTED;
10290 /****************************************************************
10292 ****************************************************************/
10294 WERROR _spoolss_AddPort(pipes_struct *p,
10295 struct spoolss_AddPort *r)
10297 p->rng_fault_state = true;
10298 return WERR_NOT_SUPPORTED;
10301 /****************************************************************
10302 _spoolss_ConfigurePort
10303 ****************************************************************/
10305 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10306 struct spoolss_ConfigurePort *r)
10308 p->rng_fault_state = true;
10309 return WERR_NOT_SUPPORTED;
10312 /****************************************************************
10313 _spoolss_DeletePort
10314 ****************************************************************/
10316 WERROR _spoolss_DeletePort(pipes_struct *p,
10317 struct spoolss_DeletePort *r)
10319 p->rng_fault_state = true;
10320 return WERR_NOT_SUPPORTED;
10323 /****************************************************************
10324 _spoolss_CreatePrinterIC
10325 ****************************************************************/
10327 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10328 struct spoolss_CreatePrinterIC *r)
10330 p->rng_fault_state = true;
10331 return WERR_NOT_SUPPORTED;
10334 /****************************************************************
10335 _spoolss_PlayGDIScriptOnPrinterIC
10336 ****************************************************************/
10338 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10339 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10341 p->rng_fault_state = true;
10342 return WERR_NOT_SUPPORTED;
10345 /****************************************************************
10346 _spoolss_DeletePrinterIC
10347 ****************************************************************/
10349 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10350 struct spoolss_DeletePrinterIC *r)
10352 p->rng_fault_state = true;
10353 return WERR_NOT_SUPPORTED;
10356 /****************************************************************
10357 _spoolss_AddPrinterConnection
10358 ****************************************************************/
10360 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10361 struct spoolss_AddPrinterConnection *r)
10363 p->rng_fault_state = true;
10364 return WERR_NOT_SUPPORTED;
10367 /****************************************************************
10368 _spoolss_DeletePrinterConnection
10369 ****************************************************************/
10371 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10372 struct spoolss_DeletePrinterConnection *r)
10374 p->rng_fault_state = true;
10375 return WERR_NOT_SUPPORTED;
10378 /****************************************************************
10379 _spoolss_PrinterMessageBox
10380 ****************************************************************/
10382 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10383 struct spoolss_PrinterMessageBox *r)
10385 p->rng_fault_state = true;
10386 return WERR_NOT_SUPPORTED;
10389 /****************************************************************
10390 _spoolss_AddMonitor
10391 ****************************************************************/
10393 WERROR _spoolss_AddMonitor(pipes_struct *p,
10394 struct spoolss_AddMonitor *r)
10396 p->rng_fault_state = true;
10397 return WERR_NOT_SUPPORTED;
10400 /****************************************************************
10401 _spoolss_DeleteMonitor
10402 ****************************************************************/
10404 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10405 struct spoolss_DeleteMonitor *r)
10407 p->rng_fault_state = true;
10408 return WERR_NOT_SUPPORTED;
10411 /****************************************************************
10412 _spoolss_DeletePrintProcessor
10413 ****************************************************************/
10415 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10416 struct spoolss_DeletePrintProcessor *r)
10418 p->rng_fault_state = true;
10419 return WERR_NOT_SUPPORTED;
10422 /****************************************************************
10423 _spoolss_AddPrintProvidor
10424 ****************************************************************/
10426 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10427 struct spoolss_AddPrintProvidor *r)
10429 p->rng_fault_state = true;
10430 return WERR_NOT_SUPPORTED;
10433 /****************************************************************
10434 _spoolss_DeletePrintProvidor
10435 ****************************************************************/
10437 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10438 struct spoolss_DeletePrintProvidor *r)
10440 p->rng_fault_state = true;
10441 return WERR_NOT_SUPPORTED;
10444 /****************************************************************
10445 _spoolss_EnumPrintProcDataTypes
10446 ****************************************************************/
10448 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10449 struct spoolss_EnumPrintProcDataTypes *r)
10451 p->rng_fault_state = true;
10452 return WERR_NOT_SUPPORTED;
10455 /****************************************************************
10456 _spoolss_GetPrinterDriver2
10457 ****************************************************************/
10459 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10460 struct spoolss_GetPrinterDriver2 *r)
10462 p->rng_fault_state = true;
10463 return WERR_NOT_SUPPORTED;
10466 /****************************************************************
10467 _spoolss_FindFirstPrinterChangeNotification
10468 ****************************************************************/
10470 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10471 struct spoolss_FindFirstPrinterChangeNotification *r)
10473 p->rng_fault_state = true;
10474 return WERR_NOT_SUPPORTED;
10477 /****************************************************************
10478 _spoolss_FindNextPrinterChangeNotification
10479 ****************************************************************/
10481 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10482 struct spoolss_FindNextPrinterChangeNotification *r)
10484 p->rng_fault_state = true;
10485 return WERR_NOT_SUPPORTED;
10488 /****************************************************************
10489 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10490 ****************************************************************/
10492 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10493 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10495 p->rng_fault_state = true;
10496 return WERR_NOT_SUPPORTED;
10499 /****************************************************************
10500 _spoolss_ReplyOpenPrinter
10501 ****************************************************************/
10503 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10504 struct spoolss_ReplyOpenPrinter *r)
10506 p->rng_fault_state = true;
10507 return WERR_NOT_SUPPORTED;
10510 /****************************************************************
10511 _spoolss_RouterReplyPrinter
10512 ****************************************************************/
10514 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10515 struct spoolss_RouterReplyPrinter *r)
10517 p->rng_fault_state = true;
10518 return WERR_NOT_SUPPORTED;
10521 /****************************************************************
10522 _spoolss_ReplyClosePrinter
10523 ****************************************************************/
10525 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10526 struct spoolss_ReplyClosePrinter *r)
10528 p->rng_fault_state = true;
10529 return WERR_NOT_SUPPORTED;
10532 /****************************************************************
10534 ****************************************************************/
10536 WERROR _spoolss_AddPortEx(pipes_struct *p,
10537 struct spoolss_AddPortEx *r)
10539 p->rng_fault_state = true;
10540 return WERR_NOT_SUPPORTED;
10543 /****************************************************************
10544 _spoolss_RouterFindFirstPrinterChangeNotification
10545 ****************************************************************/
10547 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10548 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10550 p->rng_fault_state = true;
10551 return WERR_NOT_SUPPORTED;
10554 /****************************************************************
10555 _spoolss_SpoolerInit
10556 ****************************************************************/
10558 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10559 struct spoolss_SpoolerInit *r)
10561 p->rng_fault_state = true;
10562 return WERR_NOT_SUPPORTED;
10565 /****************************************************************
10566 _spoolss_ResetPrinterEx
10567 ****************************************************************/
10569 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10570 struct spoolss_ResetPrinterEx *r)
10572 p->rng_fault_state = true;
10573 return WERR_NOT_SUPPORTED;
10576 /****************************************************************
10577 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10578 ****************************************************************/
10580 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10581 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10583 p->rng_fault_state = true;
10584 return WERR_NOT_SUPPORTED;
10587 /****************************************************************
10588 _spoolss_RouterReplyPrinterEx
10589 ****************************************************************/
10591 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10592 struct spoolss_RouterReplyPrinterEx *r)
10594 p->rng_fault_state = true;
10595 return WERR_NOT_SUPPORTED;
10598 /****************************************************************
10600 ****************************************************************/
10602 WERROR _spoolss_44(pipes_struct *p,
10603 struct spoolss_44 *r)
10605 p->rng_fault_state = true;
10606 return WERR_NOT_SUPPORTED;
10609 /****************************************************************
10611 ****************************************************************/
10613 WERROR _spoolss_47(pipes_struct *p,
10614 struct spoolss_47 *r)
10616 p->rng_fault_state = true;
10617 return WERR_NOT_SUPPORTED;
10620 /****************************************************************
10621 _spoolss_EnumPrinterData
10622 ****************************************************************/
10624 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10625 struct spoolss_EnumPrinterData *r)
10627 p->rng_fault_state = true;
10628 return WERR_NOT_SUPPORTED;
10631 /****************************************************************
10633 ****************************************************************/
10635 WERROR _spoolss_4a(pipes_struct *p,
10636 struct spoolss_4a *r)
10638 p->rng_fault_state = true;
10639 return WERR_NOT_SUPPORTED;
10642 /****************************************************************
10644 ****************************************************************/
10646 WERROR _spoolss_4b(pipes_struct *p,
10647 struct spoolss_4b *r)
10649 p->rng_fault_state = true;
10650 return WERR_NOT_SUPPORTED;
10653 /****************************************************************
10655 ****************************************************************/
10657 WERROR _spoolss_4c(pipes_struct *p,
10658 struct spoolss_4c *r)
10660 p->rng_fault_state = true;
10661 return WERR_NOT_SUPPORTED;
10664 /****************************************************************
10665 _spoolss_EnumPrinterDataEx
10666 ****************************************************************/
10668 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10669 struct spoolss_EnumPrinterDataEx *r)
10671 p->rng_fault_state = true;
10672 return WERR_NOT_SUPPORTED;
10675 /****************************************************************
10676 _spoolss_EnumPrinterKey
10677 ****************************************************************/
10679 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10680 struct spoolss_EnumPrinterKey *r)
10682 p->rng_fault_state = true;
10683 return WERR_NOT_SUPPORTED;
10686 /****************************************************************
10688 ****************************************************************/
10690 WERROR _spoolss_53(pipes_struct *p,
10691 struct spoolss_53 *r)
10693 p->rng_fault_state = true;
10694 return WERR_NOT_SUPPORTED;
10697 /****************************************************************
10699 ****************************************************************/
10701 WERROR _spoolss_55(pipes_struct *p,
10702 struct spoolss_55 *r)
10704 p->rng_fault_state = true;
10705 return WERR_NOT_SUPPORTED;
10708 /****************************************************************
10710 ****************************************************************/
10712 WERROR _spoolss_56(pipes_struct *p,
10713 struct spoolss_56 *r)
10715 p->rng_fault_state = true;
10716 return WERR_NOT_SUPPORTED;
10719 /****************************************************************
10721 ****************************************************************/
10723 WERROR _spoolss_57(pipes_struct *p,
10724 struct spoolss_57 *r)
10726 p->rng_fault_state = true;
10727 return WERR_NOT_SUPPORTED;
10730 /****************************************************************
10732 ****************************************************************/
10734 WERROR _spoolss_5a(pipes_struct *p,
10735 struct spoolss_5a *r)
10737 p->rng_fault_state = true;
10738 return WERR_NOT_SUPPORTED;
10741 /****************************************************************
10743 ****************************************************************/
10745 WERROR _spoolss_5b(pipes_struct *p,
10746 struct spoolss_5b *r)
10748 p->rng_fault_state = true;
10749 return WERR_NOT_SUPPORTED;
10752 /****************************************************************
10754 ****************************************************************/
10756 WERROR _spoolss_5c(pipes_struct *p,
10757 struct spoolss_5c *r)
10759 p->rng_fault_state = true;
10760 return WERR_NOT_SUPPORTED;
10763 /****************************************************************
10765 ****************************************************************/
10767 WERROR _spoolss_5d(pipes_struct *p,
10768 struct spoolss_5d *r)
10770 p->rng_fault_state = true;
10771 return WERR_NOT_SUPPORTED;
10774 /****************************************************************
10776 ****************************************************************/
10778 WERROR _spoolss_5e(pipes_struct *p,
10779 struct spoolss_5e *r)
10781 p->rng_fault_state = true;
10782 return WERR_NOT_SUPPORTED;
10785 /****************************************************************
10787 ****************************************************************/
10789 WERROR _spoolss_5f(pipes_struct *p,
10790 struct spoolss_5f *r)
10792 p->rng_fault_state = true;
10793 return WERR_NOT_SUPPORTED;