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 /* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
678 static void notify_one_value(struct spoolss_notify_msg *msg,
679 SPOOL_NOTIFY_INFO_DATA *data,
682 data->notify_data.value[0] = msg->notify.value[0];
683 data->notify_data.value[1] = 0;
686 static void notify_string(struct spoolss_notify_msg *msg,
687 SPOOL_NOTIFY_INFO_DATA *data,
692 /* The length of the message includes the trailing \0 */
694 init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
696 data->notify_data.data.length = msg->len * 2;
697 data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len);
699 if (!data->notify_data.data.string) {
700 data->notify_data.data.length = 0;
704 memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);
707 static void notify_system_time(struct spoolss_notify_msg *msg,
708 SPOOL_NOTIFY_INFO_DATA *data,
714 if (msg->len != sizeof(time_t)) {
715 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
720 if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
721 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
725 if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) {
726 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
731 if (!spoolss_io_system_time("", &ps, 0, &systime)) {
736 data->notify_data.data.length = prs_offset(&ps);
737 if (prs_offset(&ps)) {
738 data->notify_data.data.string = (uint16 *)
739 TALLOC(mem_ctx, prs_offset(&ps));
740 if (!data->notify_data.data.string) {
744 prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
746 data->notify_data.data.string = NULL;
752 struct notify2_message_table {
754 void (*fn)(struct spoolss_notify_msg *msg,
755 SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx);
758 static struct notify2_message_table printer_notify_table[] = {
759 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
760 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
761 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
762 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string },
763 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
764 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string },
765 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string },
766 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
767 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
768 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
769 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
770 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
771 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
772 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
773 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
774 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
775 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
776 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
777 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
780 static struct notify2_message_table job_notify_table[] = {
781 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
782 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
783 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
784 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
785 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
786 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
787 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
788 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
789 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
790 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
791 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
792 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
793 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
794 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
795 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
796 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
797 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
798 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
799 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
800 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
801 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
802 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
803 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
804 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
808 /***********************************************************************
809 Allocate talloc context for container object
810 **********************************************************************/
812 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
817 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
822 /***********************************************************************
823 release all allocated memory and zero out structure
824 **********************************************************************/
826 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
832 talloc_destroy(ctr->ctx);
839 /***********************************************************************
840 **********************************************************************/
842 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
850 /***********************************************************************
851 **********************************************************************/
853 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
855 if ( !ctr || !ctr->msg_groups )
858 if ( idx >= ctr->num_groups )
861 return &ctr->msg_groups[idx];
865 /***********************************************************************
866 How many groups of change messages do we have ?
867 **********************************************************************/
869 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
874 return ctr->num_groups;
877 /***********************************************************************
878 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
879 **********************************************************************/
881 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
883 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
884 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
885 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
891 /* loop over all groups looking for a matching printer name */
893 for ( i=0; i<ctr->num_groups; i++ ) {
894 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
898 /* add a new group? */
900 if ( i == ctr->num_groups ) {
903 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
904 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
907 ctr->msg_groups = groups;
909 /* clear the new entry and set the printer name */
911 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
912 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
915 /* add the change messages; 'i' is the correct index now regardless */
917 msg_grp = &ctr->msg_groups[i];
921 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
922 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
925 msg_grp->msgs = msg_list;
927 new_slot = msg_grp->num_msgs-1;
928 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
930 /* need to allocate own copy of data */
933 msg_grp->msgs[new_slot].notify.data = (char *)
934 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
936 return ctr->num_groups;
939 /***********************************************************************
940 Send a change notication message on all handles which have a call
942 **********************************************************************/
944 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
947 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
948 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
949 SPOOLSS_NOTIFY_MSG *messages;
950 int sending_msg_count;
953 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
957 messages = msg_group->msgs;
960 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
964 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
966 /* loop over all printers */
968 for (p = printers_list; p; p = p->next) {
969 SPOOL_NOTIFY_INFO_DATA *data;
974 /* Is there notification on this handle? */
976 if ( !p->notify.client_connected )
979 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
981 /* For this printer? Print servers always receive
984 if ( ( p->printer_type == SPLHND_PRINTER ) &&
985 ( !strequal(msg_group->printername, p->sharename) ) )
988 DEBUG(10,("Our printer\n"));
990 /* allocate the max entries possible */
992 data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);
999 /* build the array of change notifications */
1001 sending_msg_count = 0;
1003 for ( i=0; i<msg_group->num_msgs; i++ ) {
1004 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1006 /* Are we monitoring this event? */
1008 if (!is_monitoring_event(p, msg->type, msg->field))
1011 sending_msg_count++;
1014 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1015 msg->type, msg->field, p->sharename));
1018 * if the is a printer notification handle and not a job notification
1019 * type, then set the id to 0. Other wise just use what was specified
1022 * When registering change notification on a print server handle
1023 * we always need to send back the id (snum) matching the printer
1024 * for which the change took place. For change notify registered
1025 * on a printer handle, this does not matter and the id should be 0.
1030 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1036 /* Convert unix jobid to smb jobid */
1038 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1039 id = sysjob_to_jobid(msg->id);
1042 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1047 construct_info_data( &data[data_len], msg->type, msg->field, id );
1050 case PRINTER_NOTIFY_TYPE:
1051 if ( printer_notify_table[msg->field].fn )
1052 printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
1055 case JOB_NOTIFY_TYPE:
1056 if ( job_notify_table[msg->field].fn )
1057 job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
1061 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1068 if ( sending_msg_count ) {
1069 rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd,
1070 data_len, data, p->notify.change, 0 );
1075 DEBUG(8,("send_notify2_changes: Exit...\n"));
1079 /***********************************************************************
1080 **********************************************************************/
1082 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1085 uint32 tv_sec, tv_usec;
1088 /* Unpack message */
1090 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f",
1093 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd",
1095 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1098 tdb_unpack((uint8 *)buf + offset, len - offset, "dd",
1099 &msg->notify.value[0], &msg->notify.value[1]);
1101 tdb_unpack((uint8 *)buf + offset, len - offset, "B",
1102 &msg->len, &msg->notify.data);
1104 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1105 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1107 tv->tv_sec = tv_sec;
1108 tv->tv_usec = tv_usec;
1111 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1112 msg->notify.value[1]));
1114 dump_data(3, (uint8 *)msg->notify.data, msg->len);
1119 /********************************************************************
1120 Receive a notify2 message list
1121 ********************************************************************/
1123 static void receive_notify2_message_list(struct messaging_context *msg,
1126 struct server_id server_id,
1129 size_t msg_count, i;
1130 char *buf = (char *)data->data;
1133 SPOOLSS_NOTIFY_MSG notify;
1134 SPOOLSS_NOTIFY_MSG_CTR messages;
1137 if (data->length < 4) {
1138 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1142 msg_count = IVAL(buf, 0);
1145 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1147 if (msg_count == 0) {
1148 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1152 /* initialize the container */
1154 ZERO_STRUCT( messages );
1155 notify_msg_ctr_init( &messages );
1158 * build message groups for each printer identified
1159 * in a change_notify msg. Remember that a PCN message
1160 * includes the handle returned for the srv_spoolss_replyopenprinter()
1161 * call. Therefore messages are grouped according to printer handle.
1164 for ( i=0; i<msg_count; i++ ) {
1165 struct timeval msg_tv;
1167 if (msg_ptr + 4 - buf > data->length) {
1168 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1172 msg_len = IVAL(msg_ptr,0);
1175 if (msg_ptr + msg_len - buf > data->length) {
1176 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1180 /* unpack messages */
1182 ZERO_STRUCT( notify );
1183 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1186 /* add to correct list in container */
1188 notify_msg_ctr_addmsg( &messages, ¬ify );
1190 /* free memory that might have been allocated by notify2_unpack_msg() */
1192 if ( notify.len != 0 )
1193 SAFE_FREE( notify.notify.data );
1196 /* process each group of messages */
1198 num_groups = notify_msg_ctr_numgroups( &messages );
1199 for ( i=0; i<num_groups; i++ )
1200 send_notify2_changes( &messages, i );
1205 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
1207 notify_msg_ctr_destroy( &messages );
1212 /********************************************************************
1213 Send a message to ourself about new driver being installed
1214 so we can upgrade the information for each printer bound to this
1216 ********************************************************************/
1218 static bool srv_spoolss_drv_upgrade_printer(char* drivername)
1220 int len = strlen(drivername);
1225 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1228 messaging_send_buf(smbd_messaging_context(), procid_self(),
1229 MSG_PRINTER_DRVUPGRADE,
1230 (uint8 *)drivername, len+1);
1235 /**********************************************************************
1236 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1237 over all printers, upgrading ones as necessary
1238 **********************************************************************/
1240 void do_drv_upgrade_printer(struct messaging_context *msg,
1243 struct server_id server_id,
1248 int n_services = lp_numservices();
1251 len = MIN(data->length,sizeof(drivername)-1);
1252 strncpy(drivername, (const char *)data->data, len);
1254 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1256 /* Iterate the printer list */
1258 for (snum=0; snum<n_services; snum++)
1260 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1263 NT_PRINTER_INFO_LEVEL *printer = NULL;
1265 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1266 if (!W_ERROR_IS_OK(result))
1269 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1271 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1273 /* all we care about currently is the change_id */
1275 result = mod_a_printer(printer, 2);
1276 if (!W_ERROR_IS_OK(result)) {
1277 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1278 win_errstr(result)));
1282 free_a_printer(&printer, 2);
1289 /********************************************************************
1290 Update the cache for all printq's with a registered client
1292 ********************************************************************/
1294 void update_monitored_printq_cache( void )
1296 Printer_entry *printer = printers_list;
1299 /* loop through all printers and update the cache where
1300 client_connected == True */
1303 if ( (printer->printer_type == SPLHND_PRINTER)
1304 && printer->notify.client_connected )
1306 snum = print_queue_snum(printer->sharename);
1307 print_queue_status( snum, NULL, NULL );
1310 printer = printer->next;
1315 /********************************************************************
1316 Send a message to ourself about new driver being installed
1317 so we can upgrade the information for each printer bound to this
1319 ********************************************************************/
1321 static bool srv_spoolss_reset_printerdata(char* drivername)
1323 int len = strlen(drivername);
1328 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1331 messaging_send_buf(smbd_messaging_context(), procid_self(),
1332 MSG_PRINTERDATA_INIT_RESET,
1333 (uint8 *)drivername, len+1);
1338 /**********************************************************************
1339 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1340 over all printers, resetting printer data as neessary
1341 **********************************************************************/
1343 void reset_all_printerdata(struct messaging_context *msg,
1346 struct server_id server_id,
1351 int n_services = lp_numservices();
1354 len = MIN( data->length, sizeof(drivername)-1 );
1355 strncpy( drivername, (const char *)data->data, len );
1357 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1359 /* Iterate the printer list */
1361 for ( snum=0; snum<n_services; snum++ )
1363 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1366 NT_PRINTER_INFO_LEVEL *printer = NULL;
1368 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1369 if ( !W_ERROR_IS_OK(result) )
1373 * if the printer is bound to the driver,
1374 * then reset to the new driver initdata
1377 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1379 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1381 if ( !set_driver_init(printer, 2) ) {
1382 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1383 printer->info_2->printername, printer->info_2->drivername));
1386 result = mod_a_printer( printer, 2 );
1387 if ( !W_ERROR_IS_OK(result) ) {
1388 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1389 get_dos_error_msg(result)));
1393 free_a_printer( &printer, 2 );
1402 /****************************************************************
1403 _spoolss_OpenPrinter
1404 ****************************************************************/
1406 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1407 struct spoolss_OpenPrinter *r)
1409 struct spoolss_OpenPrinterEx e;
1412 ZERO_STRUCT(e.in.userlevel);
1414 e.in.printername = r->in.printername;
1415 e.in.datatype = r->in.datatype;
1416 e.in.devmode_ctr = r->in.devmode_ctr;
1417 e.in.access_mask = r->in.access_mask;
1420 e.out.handle = r->out.handle;
1422 werr = _spoolss_OpenPrinterEx(p, &e);
1424 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1425 /* OpenPrinterEx returns this for a bad
1426 * printer name. We must return WERR_INVALID_PRINTER_NAME
1429 werr = WERR_INVALID_PRINTER_NAME;
1435 /********************************************************************
1436 FIXME: temporary convert_devicemode_new function
1437 ********************************************************************/
1439 static bool convert_devicemode_new(const char *printername,
1440 struct spoolss_DeviceMode *devmode,
1441 NT_DEVICEMODE **pp_nt_devmode)
1443 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1446 * Ensure nt_devmode is a valid pointer
1447 * as we will be overwriting it.
1450 if (nt_devmode == NULL) {
1451 DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
1452 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1456 rpcstr_push(nt_devmode->devicename, devmode->devicename, 31, 0);
1457 rpcstr_push(nt_devmode->formname, devmode->formname, 31, 0);
1459 nt_devmode->specversion = devmode->specversion;
1460 nt_devmode->driverversion = devmode->driverversion;
1461 nt_devmode->size = devmode->size;
1462 nt_devmode->fields = devmode->fields;
1463 nt_devmode->orientation = devmode->orientation;
1464 nt_devmode->papersize = devmode->papersize;
1465 nt_devmode->paperlength = devmode->paperlength;
1466 nt_devmode->paperwidth = devmode->paperwidth;
1467 nt_devmode->scale = devmode->scale;
1468 nt_devmode->copies = devmode->copies;
1469 nt_devmode->defaultsource = devmode->defaultsource;
1470 nt_devmode->printquality = devmode->printquality;
1471 nt_devmode->color = devmode->color;
1472 nt_devmode->duplex = devmode->duplex;
1473 nt_devmode->yresolution = devmode->yresolution;
1474 nt_devmode->ttoption = devmode->ttoption;
1475 nt_devmode->collate = devmode->collate;
1477 nt_devmode->logpixels = devmode->logpixels;
1478 nt_devmode->bitsperpel = devmode->bitsperpel;
1479 nt_devmode->pelswidth = devmode->pelswidth;
1480 nt_devmode->pelsheight = devmode->pelsheight;
1481 nt_devmode->displayflags = devmode->displayflags;
1482 nt_devmode->displayfrequency = devmode->displayfrequency;
1483 nt_devmode->icmmethod = devmode->icmmethod;
1484 nt_devmode->icmintent = devmode->icmintent;
1485 nt_devmode->mediatype = devmode->mediatype;
1486 nt_devmode->dithertype = devmode->dithertype;
1487 nt_devmode->reserved1 = devmode->reserved1;
1488 nt_devmode->reserved2 = devmode->reserved2;
1489 nt_devmode->panningwidth = devmode->panningwidth;
1490 nt_devmode->panningheight = devmode->panningheight;
1493 * Only change private and driverextra if the incoming devmode
1494 * has a new one. JRA.
1497 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1498 SAFE_FREE(nt_devmode->nt_dev_private);
1499 nt_devmode->driverextra = devmode->__driverextra_length;
1500 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1502 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1505 *pp_nt_devmode = nt_devmode;
1510 /****************************************************************
1511 _spoolss_OpenPrinterEx
1512 ****************************************************************/
1514 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1515 struct spoolss_OpenPrinterEx *r)
1517 POLICY_HND *handle = r->out.handle;
1518 char *name = CONST_DISCARD(char *, r->in.printername);
1520 Printer_entry *Printer=NULL;
1523 return WERR_INVALID_PARAM;
1526 /* some sanity check because you can open a printer or a print server */
1527 /* aka: \\server\printer or \\server */
1529 DEBUGADD(3,("checking name: %s\n",name));
1531 if (!open_printer_hnd(p, handle, name, 0)) {
1532 return WERR_INVALID_PARAM;
1535 Printer=find_printer_index_by_hnd(p, handle);
1537 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1538 "handle we created for printer %s\n", name ));
1539 close_printer_handle(p,handle);
1540 return WERR_INVALID_PARAM;
1544 * First case: the user is opening the print server:
1546 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1547 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1549 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1550 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1551 * or if the user is listed in the smb.conf printer admin parameter.
1553 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1554 * client view printer folder, but does not show the MSAPW.
1556 * Note: this test needs code to check access rights here too. Jeremy
1557 * could you look at this?
1559 * Second case: the user is opening a printer:
1560 * NT doesn't let us connect to a printer if the connecting user
1561 * doesn't have print permission.
1563 * Third case: user is opening a Port Monitor
1564 * access checks same as opening a handle to the print server.
1567 switch (Printer->printer_type )
1570 case SPLHND_PORTMON_TCP:
1571 case SPLHND_PORTMON_LOCAL:
1572 /* Printserver handles use global struct... */
1576 /* Map standard access rights to object specific access rights */
1578 se_map_standard(&r->in.access_mask,
1579 &printserver_std_mapping);
1581 /* Deny any object specific bits that don't apply to print
1582 servers (i.e printer and job specific bits) */
1584 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1586 if (r->in.access_mask &
1587 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1588 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1589 close_printer_handle(p, handle);
1590 return WERR_ACCESS_DENIED;
1593 /* Allow admin access */
1595 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1597 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1599 if (!lp_ms_add_printer_wizard()) {
1600 close_printer_handle(p, handle);
1601 return WERR_ACCESS_DENIED;
1604 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1605 and not a printer admin, then fail */
1607 if ((p->server_info->utok.uid != 0) &&
1608 !user_has_privileges(p->server_info->ptok,
1610 !token_contains_name_in_list(
1611 uidtoname(p->server_info->utok.uid),
1613 p->server_info->ptok,
1614 lp_printer_admin(snum))) {
1615 close_printer_handle(p, handle);
1616 return WERR_ACCESS_DENIED;
1619 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1623 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1626 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1627 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1629 /* We fall through to return WERR_OK */
1632 case SPLHND_PRINTER:
1633 /* NT doesn't let us connect to a printer if the connecting user
1634 doesn't have print permission. */
1636 if (!get_printer_snum(p, handle, &snum, NULL)) {
1637 close_printer_handle(p, handle);
1641 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1643 /* map an empty access mask to the minimum access mask */
1644 if (r->in.access_mask == 0x0)
1645 r->in.access_mask = PRINTER_ACCESS_USE;
1648 * If we are not serving the printer driver for this printer,
1649 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1650 * will keep NT clients happy --jerry
1653 if (lp_use_client_driver(snum)
1654 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1656 r->in.access_mask = PRINTER_ACCESS_USE;
1659 /* check smb.conf parameters and the the sec_desc */
1661 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1662 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1663 return WERR_ACCESS_DENIED;
1666 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1667 p->server_info->ptok, snum) ||
1668 !print_access_check(p->server_info, snum,
1669 r->in.access_mask)) {
1670 DEBUG(3, ("access DENIED for printer open\n"));
1671 close_printer_handle(p, handle);
1672 return WERR_ACCESS_DENIED;
1675 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1676 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1677 close_printer_handle(p, handle);
1678 return WERR_ACCESS_DENIED;
1681 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1682 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1684 r->in.access_mask = PRINTER_ACCESS_USE;
1686 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1687 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1692 /* sanity check to prevent programmer error */
1696 Printer->access_granted = r->in.access_mask;
1699 * If the client sent a devmode in the OpenPrinter() call, then
1700 * save it here in case we get a job submission on this handle
1703 if ( (Printer->printer_type != SPLHND_SERVER)
1704 && r->in.devmode_ctr.devmode )
1706 convert_devicemode_new(Printer->sharename,
1707 r->in.devmode_ctr.devmode,
1708 &Printer->nt_devmode);
1711 #if 0 /* JERRY -- I'm doubtful this is really effective */
1712 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1713 optimization in Windows 2000 clients --jerry */
1715 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1716 && (RA_WIN2K == get_remote_arch()) )
1718 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1719 sys_usleep( 500000 );
1726 /****************************************************************************
1727 ****************************************************************************/
1729 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1730 NT_PRINTER_INFO_LEVEL_2 *d)
1732 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1738 d->attributes = r->attributes;
1739 d->priority = r->priority;
1740 d->default_priority = r->defaultpriority;
1741 d->starttime = r->starttime;
1742 d->untiltime = r->untiltime;
1743 d->status = r->status;
1744 d->cjobs = r->cjobs;
1746 fstrcpy(d->servername, r->servername);
1747 fstrcpy(d->printername, r->printername);
1748 fstrcpy(d->sharename, r->sharename);
1749 fstrcpy(d->portname, r->portname);
1750 fstrcpy(d->drivername, r->drivername);
1751 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1752 fstrcpy(d->location, r->location);
1753 fstrcpy(d->sepfile, r->sepfile);
1754 fstrcpy(d->printprocessor, r->printprocessor);
1755 fstrcpy(d->datatype, r->datatype);
1756 fstrcpy(d->parameters, r->parameters);
1761 /****************************************************************************
1762 ****************************************************************************/
1764 static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
1765 NT_PRINTER_INFO_LEVEL *printer)
1769 switch (info_ctr->level) {
1771 /* allocate memory if needed. Messy because
1772 convert_printer_info is used to update an existing
1773 printer or build a new one */
1775 if (!printer->info_2) {
1776 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1777 if (!printer->info_2) {
1778 DEBUG(0,("convert_printer_info_new: "
1779 "talloc() failed!\n"));
1784 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1786 printer->info_2->setuptime = time(NULL);
1793 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
1794 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
1800 printer->info_3=NULL;
1801 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
1805 printer->info_6=NULL;
1806 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
1816 bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
1817 NT_DEVICEMODE **pp_nt_devmode)
1819 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1822 * Ensure nt_devmode is a valid pointer
1823 * as we will be overwriting it.
1826 if (nt_devmode == NULL) {
1827 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1828 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1832 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
1833 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
1835 nt_devmode->specversion=devmode->specversion;
1836 nt_devmode->driverversion=devmode->driverversion;
1837 nt_devmode->size=devmode->size;
1838 nt_devmode->fields=devmode->fields;
1839 nt_devmode->orientation=devmode->orientation;
1840 nt_devmode->papersize=devmode->papersize;
1841 nt_devmode->paperlength=devmode->paperlength;
1842 nt_devmode->paperwidth=devmode->paperwidth;
1843 nt_devmode->scale=devmode->scale;
1844 nt_devmode->copies=devmode->copies;
1845 nt_devmode->defaultsource=devmode->defaultsource;
1846 nt_devmode->printquality=devmode->printquality;
1847 nt_devmode->color=devmode->color;
1848 nt_devmode->duplex=devmode->duplex;
1849 nt_devmode->yresolution=devmode->yresolution;
1850 nt_devmode->ttoption=devmode->ttoption;
1851 nt_devmode->collate=devmode->collate;
1853 nt_devmode->logpixels=devmode->logpixels;
1854 nt_devmode->bitsperpel=devmode->bitsperpel;
1855 nt_devmode->pelswidth=devmode->pelswidth;
1856 nt_devmode->pelsheight=devmode->pelsheight;
1857 nt_devmode->displayflags=devmode->displayflags;
1858 nt_devmode->displayfrequency=devmode->displayfrequency;
1859 nt_devmode->icmmethod=devmode->icmmethod;
1860 nt_devmode->icmintent=devmode->icmintent;
1861 nt_devmode->mediatype=devmode->mediatype;
1862 nt_devmode->dithertype=devmode->dithertype;
1863 nt_devmode->reserved1=devmode->reserved1;
1864 nt_devmode->reserved2=devmode->reserved2;
1865 nt_devmode->panningwidth=devmode->panningwidth;
1866 nt_devmode->panningheight=devmode->panningheight;
1869 * Only change private and driverextra if the incoming devmode
1870 * has a new one. JRA.
1873 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
1874 SAFE_FREE(nt_devmode->nt_dev_private);
1875 nt_devmode->driverextra=devmode->driverextra;
1876 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1878 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
1881 *pp_nt_devmode = nt_devmode;
1886 /********************************************************************
1887 * _spoolss_enddocprinter_internal.
1888 ********************************************************************/
1890 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
1892 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1896 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
1900 if (!get_printer_snum(p, handle, &snum, NULL))
1903 Printer->document_started=False;
1904 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
1905 /* error codes unhandled so far ... */
1910 /****************************************************************
1911 _spoolss_ClosePrinter
1912 ****************************************************************/
1914 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1915 struct spoolss_ClosePrinter *r)
1917 POLICY_HND *handle = r->in.handle;
1919 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1921 if (Printer && Printer->document_started)
1922 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1924 if (!close_printer_handle(p, handle))
1927 /* clear the returned printer handle. Observed behavior
1928 from Win2k server. Don't think this really matters.
1929 Previous code just copied the value of the closed
1932 ZERO_STRUCTP(r->out.handle);
1937 /****************************************************************
1938 _spoolss_DeletePrinter
1939 ****************************************************************/
1941 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1942 struct spoolss_DeletePrinter *r)
1944 POLICY_HND *handle = r->in.handle;
1945 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1948 if (Printer && Printer->document_started)
1949 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1951 result = delete_printer_handle(p, handle);
1953 update_c_setprinter(False);
1958 /*******************************************************************
1959 * static function to lookup the version id corresponding to an
1960 * long architecture string
1961 ******************************************************************/
1963 static int get_version_id (char * arch)
1966 struct table_node archi_table[]= {
1968 {"Windows 4.0", "WIN40", 0 },
1969 {"Windows NT x86", "W32X86", 2 },
1970 {"Windows NT R4000", "W32MIPS", 2 },
1971 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1972 {"Windows NT PowerPC", "W32PPC", 2 },
1973 {"Windows IA64", "IA64", 3 },
1974 {"Windows x64", "x64", 3 },
1978 for (i=0; archi_table[i].long_archi != NULL; i++)
1980 if (strcmp(arch, archi_table[i].long_archi) == 0)
1981 return (archi_table[i].version);
1987 /****************************************************************
1988 _spoolss_DeletePrinterDriver
1989 ****************************************************************/
1991 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
1992 struct spoolss_DeletePrinterDriver *r)
1996 NT_PRINTER_DRIVER_INFO_LEVEL info;
1997 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2000 WERROR status_win2k = WERR_ACCESS_DENIED;
2001 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2003 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2004 and not a printer admin, then fail */
2006 if ( (p->server_info->utok.uid != 0)
2007 && !user_has_privileges(p->server_info->ptok, &se_printop )
2008 && !token_contains_name_in_list(
2009 uidtoname(p->server_info->utok.uid), NULL,
2010 NULL, p->server_info->ptok,
2011 lp_printer_admin(-1)) )
2013 return WERR_ACCESS_DENIED;
2016 driver = CONST_DISCARD(char *, r->in.driver);
2017 arch = CONST_DISCARD(char *, r->in.architecture);
2019 /* check that we have a valid driver name first */
2021 if ((version=get_version_id(arch)) == -1)
2022 return WERR_INVALID_ENVIRONMENT;
2025 ZERO_STRUCT(info_win2k);
2027 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2029 /* try for Win2k driver if "Windows NT x86" */
2031 if ( version == 2 ) {
2033 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2034 status = WERR_UNKNOWN_PRINTER_DRIVER;
2038 /* otherwise it was a failure */
2040 status = WERR_UNKNOWN_PRINTER_DRIVER;
2046 if (printer_driver_in_use(info.info_3)) {
2047 status = WERR_PRINTER_DRIVER_IN_USE;
2053 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2055 /* if we get to here, we now have 2 driver info structures to remove */
2056 /* remove the Win2k driver first*/
2058 status_win2k = delete_printer_driver(
2059 p, info_win2k.info_3, 3, False );
2060 free_a_printer_driver( info_win2k, 3 );
2062 /* this should not have failed---if it did, report to client */
2063 if ( !W_ERROR_IS_OK(status_win2k) )
2065 status = status_win2k;
2071 status = delete_printer_driver(p, info.info_3, version, False);
2073 /* if at least one of the deletes succeeded return OK */
2075 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2079 free_a_printer_driver( info, 3 );
2084 /****************************************************************
2085 _spoolss_DeletePrinterDriverEx
2086 ****************************************************************/
2088 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2089 struct spoolss_DeletePrinterDriverEx *r)
2093 NT_PRINTER_DRIVER_INFO_LEVEL info;
2094 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2096 uint32_t flags = r->in.delete_flags;
2099 WERROR status_win2k = WERR_ACCESS_DENIED;
2100 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2102 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2103 and not a printer admin, then fail */
2105 if ( (p->server_info->utok.uid != 0)
2106 && !user_has_privileges(p->server_info->ptok, &se_printop )
2107 && !token_contains_name_in_list(
2108 uidtoname(p->server_info->utok.uid), NULL, NULL,
2109 p->server_info->ptok, lp_printer_admin(-1)) )
2111 return WERR_ACCESS_DENIED;
2114 driver = CONST_DISCARD(char *, r->in.driver);
2115 arch = CONST_DISCARD(char *, r->in.architecture);
2117 /* check that we have a valid driver name first */
2118 if ((version=get_version_id(arch)) == -1) {
2119 /* this is what NT returns */
2120 return WERR_INVALID_ENVIRONMENT;
2123 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2124 version = r->in.version;
2127 ZERO_STRUCT(info_win2k);
2129 status = get_a_printer_driver(&info, 3, driver, arch, version);
2131 if ( !W_ERROR_IS_OK(status) )
2134 * if the client asked for a specific version,
2135 * or this is something other than Windows NT x86,
2139 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2142 /* try for Win2k driver if "Windows NT x86" */
2145 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2146 status = WERR_UNKNOWN_PRINTER_DRIVER;
2151 if ( printer_driver_in_use(info.info_3) ) {
2152 status = WERR_PRINTER_DRIVER_IN_USE;
2157 * we have a couple of cases to consider.
2158 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2159 * then the delete should fail if **any** files overlap with
2161 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2162 * non-overlapping files
2163 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2164 * is set, the do not delete any files
2165 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2168 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2170 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2172 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2173 /* no idea of the correct error here */
2174 status = WERR_ACCESS_DENIED;
2179 /* also check for W32X86/3 if necessary; maybe we already have? */
2181 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2182 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2185 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2186 /* no idea of the correct error here */
2187 free_a_printer_driver( info_win2k, 3 );
2188 status = WERR_ACCESS_DENIED;
2192 /* if we get to here, we now have 2 driver info structures to remove */
2193 /* remove the Win2k driver first*/
2195 status_win2k = delete_printer_driver(
2196 p, info_win2k.info_3, 3, delete_files);
2197 free_a_printer_driver( info_win2k, 3 );
2199 /* this should not have failed---if it did, report to client */
2201 if ( !W_ERROR_IS_OK(status_win2k) )
2206 status = delete_printer_driver(p, info.info_3, version, delete_files);
2208 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2211 free_a_printer_driver( info, 3 );
2217 /****************************************************************************
2218 Internal routine for retreiving printerdata
2219 ***************************************************************************/
2221 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2222 const char *key, const char *value, uint32 *type, uint8 **data,
2223 uint32 *needed, uint32 in_size )
2225 REGISTRY_VALUE *val;
2229 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2230 return WERR_BADFILE;
2232 *type = regval_type( val );
2234 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2236 size = regval_size( val );
2238 /* copy the min(in_size, len) */
2241 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2243 /* special case for 0 length values */
2245 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2249 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2258 DEBUG(5,("get_printer_dataex: copy done\n"));
2263 /****************************************************************************
2264 Internal routine for removing printerdata
2265 ***************************************************************************/
2267 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2269 return delete_printer_data( printer->info_2, key, value );
2272 /****************************************************************************
2273 Internal routine for storing printerdata
2274 ***************************************************************************/
2276 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2277 uint32 type, uint8 *data, int real_len )
2279 /* the registry objects enforce uniqueness based on value name */
2281 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2284 /********************************************************************
2285 GetPrinterData on a printer server Handle.
2286 ********************************************************************/
2288 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2292 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2294 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2296 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2298 SIVAL(*data, 0, 0x00);
2303 if (!StrCaseCmp(value, "BeepEnabled")) {
2305 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2307 SIVAL(*data, 0, 0x00);
2312 if (!StrCaseCmp(value, "EventLog")) {
2314 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2316 /* formally was 0x1b */
2317 SIVAL(*data, 0, 0x0);
2322 if (!StrCaseCmp(value, "NetPopup")) {
2324 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2326 SIVAL(*data, 0, 0x00);
2331 if (!StrCaseCmp(value, "MajorVersion")) {
2333 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2336 /* Windows NT 4.0 seems to not allow uploading of drivers
2337 to a server that reports 0x3 as the MajorVersion.
2338 need to investigate more how Win2k gets around this .
2341 if ( RA_WINNT == get_remote_arch() )
2350 if (!StrCaseCmp(value, "MinorVersion")) {
2352 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2360 * uint32 size = 0x114
2362 * uint32 minor = [0|1]
2363 * uint32 build = [2195|2600]
2364 * extra unicode string = e.g. "Service Pack 3"
2366 if (!StrCaseCmp(value, "OSVersion")) {
2370 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2373 SIVAL(*data, 0, *needed); /* size */
2374 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2376 SIVAL(*data, 12, 2195); /* build */
2378 /* leave extra string empty */
2384 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2385 const char *string="C:\\PRINTERS";
2387 *needed = 2*(strlen(string)+1);
2388 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2390 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2392 /* it's done by hand ready to go on the wire */
2393 for (i=0; i<strlen(string); i++) {
2394 (*data)[2*i]=string[i];
2395 (*data)[2*i+1]='\0';
2400 if (!StrCaseCmp(value, "Architecture")) {
2401 const char *string="Windows NT x86";
2403 *needed = 2*(strlen(string)+1);
2404 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2406 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2407 for (i=0; i<strlen(string); i++) {
2408 (*data)[2*i]=string[i];
2409 (*data)[2*i+1]='\0';
2414 if (!StrCaseCmp(value, "DsPresent")) {
2416 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2419 /* only show the publish check box if we are a
2420 memeber of a AD domain */
2422 if ( lp_security() == SEC_ADS )
2423 SIVAL(*data, 0, 0x01);
2425 SIVAL(*data, 0, 0x00);
2431 if (!StrCaseCmp(value, "DNSMachineName")) {
2432 const char *hostname = get_mydnsfullname();
2435 return WERR_BADFILE;
2437 *needed = 2*(strlen(hostname)+1);
2438 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2440 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2441 for (i=0; i<strlen(hostname); i++) {
2442 (*data)[2*i]=hostname[i];
2443 (*data)[2*i+1]='\0';
2449 return WERR_BADFILE;
2452 /********************************************************************
2453 * spoolss_getprinterdata
2454 ********************************************************************/
2456 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2458 POLICY_HND *handle = &q_u->handle;
2459 UNISTR2 *valuename = &q_u->valuename;
2460 uint32 in_size = q_u->size;
2461 uint32 *type = &r_u->type;
2462 uint32 *out_size = &r_u->size;
2463 uint8 **data = &r_u->data;
2464 uint32 *needed = &r_u->needed;
2467 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2468 NT_PRINTER_INFO_LEVEL *printer = NULL;
2472 * Reminder: when it's a string, the length is in BYTES
2473 * even if UNICODE is negociated.
2478 *out_size = in_size;
2480 /* in case of problem, return some default values */
2485 DEBUG(4,("_spoolss_getprinterdata\n"));
2488 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2489 status = WERR_BADFID;
2493 unistr2_to_ascii(value, valuename, sizeof(value));
2495 if ( Printer->printer_type == SPLHND_SERVER )
2496 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2499 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2500 status = WERR_BADFID;
2504 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2505 if ( !W_ERROR_IS_OK(status) )
2508 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2510 if ( strequal(value, "ChangeId") ) {
2512 *needed = sizeof(uint32);
2513 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2514 status = WERR_NOMEM;
2517 SIVAL( *data, 0, printer->info_2->changeid );
2521 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2524 if (*needed > *out_size)
2525 status = WERR_MORE_DATA;
2528 if ( !W_ERROR_IS_OK(status) )
2530 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2532 /* reply this param doesn't exist */
2535 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2537 free_a_printer( &printer, 2 );
2545 /* cleanup & exit */
2548 free_a_printer( &printer, 2 );
2553 /*********************************************************
2554 Connect to the client machine.
2555 **********************************************************/
2557 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2558 struct sockaddr_storage *client_ss, const char *remote_machine)
2561 struct cli_state *the_cli;
2562 struct sockaddr_storage rm_addr;
2564 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2565 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2566 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2570 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2571 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2575 char addr[INET6_ADDRSTRLEN];
2576 rm_addr = *client_ss;
2577 print_sockaddr(addr, sizeof(addr), &rm_addr);
2578 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2582 /* setup the connection */
2584 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2585 &rm_addr, 0, "IPC$", "IPC",
2589 0, lp_client_signing(), NULL );
2591 if ( !NT_STATUS_IS_OK( ret ) ) {
2592 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2597 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2598 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2599 cli_shutdown(the_cli);
2604 * Ok - we have an anonymous connection to the IPC$ share.
2605 * Now start the NT Domain stuff :-).
2608 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2609 if (!NT_STATUS_IS_OK(ret)) {
2610 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2611 remote_machine, nt_errstr(ret)));
2612 cli_shutdown(the_cli);
2619 /***************************************************************************
2620 Connect to the client.
2621 ****************************************************************************/
2623 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2624 uint32 localprinter, uint32 type,
2625 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2631 * If it's the first connection, contact the client
2632 * and connect to the IPC$ share anonymously
2634 if (smb_connections==0) {
2635 fstring unix_printer;
2637 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2639 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2642 messaging_register(smbd_messaging_context(), NULL,
2643 MSG_PRINTER_NOTIFY2,
2644 receive_notify2_message_list);
2645 /* Tell the connections db we're now interested in printer
2646 * notify messages. */
2647 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2651 * Tell the specific printing tdb we want messages for this printer
2652 * by registering our PID.
2655 if (!print_notify_register_pid(snum))
2656 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2660 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2668 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2669 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2670 win_errstr(result)));
2672 return (W_ERROR_IS_OK(result));
2675 /********************************************************************
2677 * ReplyFindFirstPrinterChangeNotifyEx
2679 * before replying OK: status=0 a rpc call is made to the workstation
2680 * asking ReplyOpenPrinter
2682 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2683 * called from api_spoolss_rffpcnex
2684 ********************************************************************/
2686 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2688 POLICY_HND *handle = &q_u->handle;
2689 uint32 flags = q_u->flags;
2690 uint32 options = q_u->options;
2691 UNISTR2 *localmachine = &q_u->localmachine;
2692 uint32 printerlocal = q_u->printerlocal;
2694 SPOOL_NOTIFY_OPTION *option = q_u->option;
2695 struct sockaddr_storage client_ss;
2697 /* store the notify value in the printer struct */
2699 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2702 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2706 Printer->notify.flags=flags;
2707 Printer->notify.options=options;
2708 Printer->notify.printerlocal=printerlocal;
2710 if (Printer->notify.option)
2711 free_spool_notify_option(&Printer->notify.option);
2713 Printer->notify.option=dup_spool_notify_option(option);
2715 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
2716 sizeof(Printer->notify.localmachine));
2718 /* Connect to the client machine and send a ReplyOpenPrinter */
2720 if ( Printer->printer_type == SPLHND_SERVER)
2722 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2723 !get_printer_snum(p, handle, &snum, NULL) )
2726 if (!interpret_string_addr(&client_ss, p->client_address,
2728 return WERR_SERVER_UNAVAILABLE;
2731 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2732 Printer->notify.printerlocal, 1,
2733 &Printer->notify.client_hnd, &client_ss))
2734 return WERR_SERVER_UNAVAILABLE;
2736 Printer->notify.client_connected=True;
2741 /*******************************************************************
2742 * fill a notify_info_data with the servername
2743 ********************************************************************/
2745 void spoolss_notify_server_name(int snum,
2746 SPOOL_NOTIFY_INFO_DATA *data,
2747 print_queue_struct *queue,
2748 NT_PRINTER_INFO_LEVEL *printer,
2749 TALLOC_CTX *mem_ctx)
2751 smb_ucs2_t *temp = NULL;
2754 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername);
2755 if (len == (uint32)-1) {
2759 data->notify_data.data.length = len;
2761 data->notify_data.data.string = (uint16 *)temp;
2763 data->notify_data.data.string = NULL;
2767 /*******************************************************************
2768 * fill a notify_info_data with the printername (not including the servername).
2769 ********************************************************************/
2771 void spoolss_notify_printer_name(int snum,
2772 SPOOL_NOTIFY_INFO_DATA *data,
2773 print_queue_struct *queue,
2774 NT_PRINTER_INFO_LEVEL *printer,
2775 TALLOC_CTX *mem_ctx)
2777 smb_ucs2_t *temp = NULL;
2780 /* the notify name should not contain the \\server\ part */
2781 char *p = strrchr(printer->info_2->printername, '\\');
2784 p = printer->info_2->printername;
2789 len = rpcstr_push_talloc(mem_ctx, &temp, p);
2790 if (len == (uint32)-1) {
2794 data->notify_data.data.length = len;
2796 data->notify_data.data.string = (uint16 *)temp;
2798 data->notify_data.data.string = NULL;
2802 /*******************************************************************
2803 * fill a notify_info_data with the servicename
2804 ********************************************************************/
2806 void spoolss_notify_share_name(int snum,
2807 SPOOL_NOTIFY_INFO_DATA *data,
2808 print_queue_struct *queue,
2809 NT_PRINTER_INFO_LEVEL *printer,
2810 TALLOC_CTX *mem_ctx)
2812 smb_ucs2_t *temp = NULL;
2815 len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum));
2816 if (len == (uint32)-1) {
2820 data->notify_data.data.length = len;
2822 data->notify_data.data.string = (uint16 *)temp;
2824 data->notify_data.data.string = NULL;
2829 /*******************************************************************
2830 * fill a notify_info_data with the port name
2831 ********************************************************************/
2833 void spoolss_notify_port_name(int snum,
2834 SPOOL_NOTIFY_INFO_DATA *data,
2835 print_queue_struct *queue,
2836 NT_PRINTER_INFO_LEVEL *printer,
2837 TALLOC_CTX *mem_ctx)
2839 smb_ucs2_t *temp = NULL;
2842 /* even if it's strange, that's consistant in all the code */
2844 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname);
2845 if (len == (uint32)-1) {
2849 data->notify_data.data.length = len;
2851 data->notify_data.data.string = (uint16 *)temp;
2853 data->notify_data.data.string = NULL;
2857 /*******************************************************************
2858 * fill a notify_info_data with the printername
2859 * but it doesn't exist, have to see what to do
2860 ********************************************************************/
2862 void spoolss_notify_driver_name(int snum,
2863 SPOOL_NOTIFY_INFO_DATA *data,
2864 print_queue_struct *queue,
2865 NT_PRINTER_INFO_LEVEL *printer,
2866 TALLOC_CTX *mem_ctx)
2868 smb_ucs2_t *temp = NULL;
2871 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername);
2872 if (len == (uint32)-1) {
2876 data->notify_data.data.length = len;
2878 data->notify_data.data.string = (uint16 *)temp;
2880 data->notify_data.data.string = NULL;
2884 /*******************************************************************
2885 * fill a notify_info_data with the comment
2886 ********************************************************************/
2888 void spoolss_notify_comment(int snum,
2889 SPOOL_NOTIFY_INFO_DATA *data,
2890 print_queue_struct *queue,
2891 NT_PRINTER_INFO_LEVEL *printer,
2892 TALLOC_CTX *mem_ctx)
2894 smb_ucs2_t *temp = NULL;
2897 if (*printer->info_2->comment == '\0')
2898 len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum));
2900 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment);
2902 if (len == (uint32)-1) {
2905 data->notify_data.data.length = len;
2907 data->notify_data.data.string = (uint16 *)temp;
2909 data->notify_data.data.string = NULL;
2913 /*******************************************************************
2914 * fill a notify_info_data with the comment
2915 * location = "Room 1, floor 2, building 3"
2916 ********************************************************************/
2918 void spoolss_notify_location(int snum,
2919 SPOOL_NOTIFY_INFO_DATA *data,
2920 print_queue_struct *queue,
2921 NT_PRINTER_INFO_LEVEL *printer,
2922 TALLOC_CTX *mem_ctx)
2924 smb_ucs2_t *temp = NULL;
2927 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location);
2928 if (len == (uint32)-1) {
2932 data->notify_data.data.length = len;
2934 data->notify_data.data.string = (uint16 *)temp;
2936 data->notify_data.data.string = NULL;
2940 /*******************************************************************
2941 * fill a notify_info_data with the device mode
2942 * jfm:xxxx don't to it for know but that's a real problem !!!
2943 ********************************************************************/
2945 static void spoolss_notify_devmode(int snum,
2946 SPOOL_NOTIFY_INFO_DATA *data,
2947 print_queue_struct *queue,
2948 NT_PRINTER_INFO_LEVEL *printer,
2949 TALLOC_CTX *mem_ctx)
2951 /* for a dummy implementation we have to zero the fields */
2952 data->notify_data.data.length = 0;
2953 data->notify_data.data.string = NULL;
2956 /*******************************************************************
2957 * fill a notify_info_data with the separator file name
2958 ********************************************************************/
2960 void spoolss_notify_sepfile(int snum,
2961 SPOOL_NOTIFY_INFO_DATA *data,
2962 print_queue_struct *queue,
2963 NT_PRINTER_INFO_LEVEL *printer,
2964 TALLOC_CTX *mem_ctx)
2966 smb_ucs2_t *temp = NULL;
2969 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile);
2970 if (len == (uint32)-1) {
2974 data->notify_data.data.length = len;
2976 data->notify_data.data.string = (uint16 *)temp;
2978 data->notify_data.data.string = NULL;
2982 /*******************************************************************
2983 * fill a notify_info_data with the print processor
2984 * jfm:xxxx return always winprint to indicate we don't do anything to it
2985 ********************************************************************/
2987 void spoolss_notify_print_processor(int snum,
2988 SPOOL_NOTIFY_INFO_DATA *data,
2989 print_queue_struct *queue,
2990 NT_PRINTER_INFO_LEVEL *printer,
2991 TALLOC_CTX *mem_ctx)
2993 smb_ucs2_t *temp = NULL;
2996 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor);
2997 if (len == (uint32)-1) {
3001 data->notify_data.data.length = len;
3003 data->notify_data.data.string = (uint16 *)temp;
3005 data->notify_data.data.string = NULL;
3009 /*******************************************************************
3010 * fill a notify_info_data with the print processor options
3011 * jfm:xxxx send an empty string
3012 ********************************************************************/
3014 void spoolss_notify_parameters(int snum,
3015 SPOOL_NOTIFY_INFO_DATA *data,
3016 print_queue_struct *queue,
3017 NT_PRINTER_INFO_LEVEL *printer,
3018 TALLOC_CTX *mem_ctx)
3020 smb_ucs2_t *temp = NULL;
3023 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters);
3024 if (len == (uint32)-1) {
3028 data->notify_data.data.length = len;
3030 data->notify_data.data.string = (uint16 *)temp;
3032 data->notify_data.data.string = NULL;
3036 /*******************************************************************
3037 * fill a notify_info_data with the data type
3038 * jfm:xxxx always send RAW as data type
3039 ********************************************************************/
3041 void spoolss_notify_datatype(int snum,
3042 SPOOL_NOTIFY_INFO_DATA *data,
3043 print_queue_struct *queue,
3044 NT_PRINTER_INFO_LEVEL *printer,
3045 TALLOC_CTX *mem_ctx)
3047 smb_ucs2_t *temp = NULL;
3050 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype);
3051 if (len == (uint32)-1) {
3055 data->notify_data.data.length = len;
3057 data->notify_data.data.string = (uint16 *)temp;
3059 data->notify_data.data.string = NULL;
3063 /*******************************************************************
3064 * fill a notify_info_data with the security descriptor
3065 * jfm:xxxx send an null pointer to say no security desc
3066 * have to implement security before !
3067 ********************************************************************/
3069 static void spoolss_notify_security_desc(int snum,
3070 SPOOL_NOTIFY_INFO_DATA *data,
3071 print_queue_struct *queue,
3072 NT_PRINTER_INFO_LEVEL *printer,
3073 TALLOC_CTX *mem_ctx)
3075 data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size;
3076 data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ;
3079 /*******************************************************************
3080 * fill a notify_info_data with the attributes
3081 * jfm:xxxx a samba printer is always shared
3082 ********************************************************************/
3084 void spoolss_notify_attributes(int snum,
3085 SPOOL_NOTIFY_INFO_DATA *data,
3086 print_queue_struct *queue,
3087 NT_PRINTER_INFO_LEVEL *printer,
3088 TALLOC_CTX *mem_ctx)
3090 data->notify_data.value[0] = printer->info_2->attributes;
3091 data->notify_data.value[1] = 0;
3094 /*******************************************************************
3095 * fill a notify_info_data with the priority
3096 ********************************************************************/
3098 static void spoolss_notify_priority(int snum,
3099 SPOOL_NOTIFY_INFO_DATA *data,
3100 print_queue_struct *queue,
3101 NT_PRINTER_INFO_LEVEL *printer,
3102 TALLOC_CTX *mem_ctx)
3104 data->notify_data.value[0] = printer->info_2->priority;
3105 data->notify_data.value[1] = 0;
3108 /*******************************************************************
3109 * fill a notify_info_data with the default priority
3110 ********************************************************************/
3112 static void spoolss_notify_default_priority(int snum,
3113 SPOOL_NOTIFY_INFO_DATA *data,
3114 print_queue_struct *queue,
3115 NT_PRINTER_INFO_LEVEL *printer,
3116 TALLOC_CTX *mem_ctx)
3118 data->notify_data.value[0] = printer->info_2->default_priority;
3119 data->notify_data.value[1] = 0;
3122 /*******************************************************************
3123 * fill a notify_info_data with the start time
3124 ********************************************************************/
3126 static void spoolss_notify_start_time(int snum,
3127 SPOOL_NOTIFY_INFO_DATA *data,
3128 print_queue_struct *queue,
3129 NT_PRINTER_INFO_LEVEL *printer,
3130 TALLOC_CTX *mem_ctx)
3132 data->notify_data.value[0] = printer->info_2->starttime;
3133 data->notify_data.value[1] = 0;
3136 /*******************************************************************
3137 * fill a notify_info_data with the until time
3138 ********************************************************************/
3140 static void spoolss_notify_until_time(int snum,
3141 SPOOL_NOTIFY_INFO_DATA *data,
3142 print_queue_struct *queue,
3143 NT_PRINTER_INFO_LEVEL *printer,
3144 TALLOC_CTX *mem_ctx)
3146 data->notify_data.value[0] = printer->info_2->untiltime;
3147 data->notify_data.value[1] = 0;
3150 /*******************************************************************
3151 * fill a notify_info_data with the status
3152 ********************************************************************/
3154 static void spoolss_notify_status(int snum,
3155 SPOOL_NOTIFY_INFO_DATA *data,
3156 print_queue_struct *queue,
3157 NT_PRINTER_INFO_LEVEL *printer,
3158 TALLOC_CTX *mem_ctx)
3160 print_status_struct status;
3162 print_queue_length(snum, &status);
3163 data->notify_data.value[0]=(uint32) status.status;
3164 data->notify_data.value[1] = 0;
3167 /*******************************************************************
3168 * fill a notify_info_data with the number of jobs queued
3169 ********************************************************************/
3171 void spoolss_notify_cjobs(int snum,
3172 SPOOL_NOTIFY_INFO_DATA *data,
3173 print_queue_struct *queue,
3174 NT_PRINTER_INFO_LEVEL *printer,
3175 TALLOC_CTX *mem_ctx)
3177 data->notify_data.value[0] = print_queue_length(snum, NULL);
3178 data->notify_data.value[1] = 0;
3181 /*******************************************************************
3182 * fill a notify_info_data with the average ppm
3183 ********************************************************************/
3185 static void spoolss_notify_average_ppm(int snum,
3186 SPOOL_NOTIFY_INFO_DATA *data,
3187 print_queue_struct *queue,
3188 NT_PRINTER_INFO_LEVEL *printer,
3189 TALLOC_CTX *mem_ctx)
3191 /* always respond 8 pages per minutes */
3192 /* a little hard ! */
3193 data->notify_data.value[0] = printer->info_2->averageppm;
3194 data->notify_data.value[1] = 0;
3197 /*******************************************************************
3198 * fill a notify_info_data with username
3199 ********************************************************************/
3201 static void spoolss_notify_username(int snum,
3202 SPOOL_NOTIFY_INFO_DATA *data,
3203 print_queue_struct *queue,
3204 NT_PRINTER_INFO_LEVEL *printer,
3205 TALLOC_CTX *mem_ctx)
3207 smb_ucs2_t *temp = NULL;
3210 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user);
3211 if (len == (uint32)-1) {
3215 data->notify_data.data.length = len;
3217 data->notify_data.data.string = (uint16 *)temp;
3219 data->notify_data.data.string = NULL;
3223 /*******************************************************************
3224 * fill a notify_info_data with job status
3225 ********************************************************************/
3227 static void spoolss_notify_job_status(int snum,
3228 SPOOL_NOTIFY_INFO_DATA *data,
3229 print_queue_struct *queue,
3230 NT_PRINTER_INFO_LEVEL *printer,
3231 TALLOC_CTX *mem_ctx)
3233 data->notify_data.value[0]=nt_printj_status(queue->status);
3234 data->notify_data.value[1] = 0;
3237 /*******************************************************************
3238 * fill a notify_info_data with job name
3239 ********************************************************************/
3241 static void spoolss_notify_job_name(int snum,
3242 SPOOL_NOTIFY_INFO_DATA *data,
3243 print_queue_struct *queue,
3244 NT_PRINTER_INFO_LEVEL *printer,
3245 TALLOC_CTX *mem_ctx)
3247 smb_ucs2_t *temp = NULL;
3250 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file);
3251 if (len == (uint32)-1) {
3255 data->notify_data.data.length = len;
3257 data->notify_data.data.string = (uint16 *)temp;
3259 data->notify_data.data.string = NULL;
3263 /*******************************************************************
3264 * fill a notify_info_data with job status
3265 ********************************************************************/
3267 static void spoolss_notify_job_status_string(int snum,
3268 SPOOL_NOTIFY_INFO_DATA *data,
3269 print_queue_struct *queue,
3270 NT_PRINTER_INFO_LEVEL *printer,
3271 TALLOC_CTX *mem_ctx)
3274 * Now we're returning job status codes we just return a "" here. JRA.
3278 smb_ucs2_t *temp = NULL;
3281 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3284 switch (queue->status) {
3289 p = ""; /* NT provides the paused string */
3298 #endif /* NO LONGER NEEDED. */
3300 len = rpcstr_push_talloc(mem_ctx, &temp, p);
3301 if (len == (uint32)-1) {
3305 data->notify_data.data.length = len;
3307 data->notify_data.data.string = (uint16 *)temp;
3309 data->notify_data.data.string = NULL;
3313 /*******************************************************************
3314 * fill a notify_info_data with job time
3315 ********************************************************************/
3317 static void spoolss_notify_job_time(int snum,
3318 SPOOL_NOTIFY_INFO_DATA *data,
3319 print_queue_struct *queue,
3320 NT_PRINTER_INFO_LEVEL *printer,
3321 TALLOC_CTX *mem_ctx)
3323 data->notify_data.value[0]=0x0;
3324 data->notify_data.value[1]=0;
3327 /*******************************************************************
3328 * fill a notify_info_data with job size
3329 ********************************************************************/
3331 static void spoolss_notify_job_size(int snum,
3332 SPOOL_NOTIFY_INFO_DATA *data,
3333 print_queue_struct *queue,
3334 NT_PRINTER_INFO_LEVEL *printer,
3335 TALLOC_CTX *mem_ctx)
3337 data->notify_data.value[0]=queue->size;
3338 data->notify_data.value[1]=0;
3341 /*******************************************************************
3342 * fill a notify_info_data with page info
3343 ********************************************************************/
3344 static void spoolss_notify_total_pages(int snum,
3345 SPOOL_NOTIFY_INFO_DATA *data,
3346 print_queue_struct *queue,
3347 NT_PRINTER_INFO_LEVEL *printer,
3348 TALLOC_CTX *mem_ctx)
3350 data->notify_data.value[0]=queue->page_count;
3351 data->notify_data.value[1]=0;
3354 /*******************************************************************
3355 * fill a notify_info_data with pages printed info.
3356 ********************************************************************/
3357 static void spoolss_notify_pages_printed(int snum,
3358 SPOOL_NOTIFY_INFO_DATA *data,
3359 print_queue_struct *queue,
3360 NT_PRINTER_INFO_LEVEL *printer,
3361 TALLOC_CTX *mem_ctx)
3363 data->notify_data.value[0]=0; /* Add code when back-end tracks this */
3364 data->notify_data.value[1]=0;
3367 /*******************************************************************
3368 Fill a notify_info_data with job position.
3369 ********************************************************************/
3371 static void spoolss_notify_job_position(int snum,
3372 SPOOL_NOTIFY_INFO_DATA *data,
3373 print_queue_struct *queue,
3374 NT_PRINTER_INFO_LEVEL *printer,
3375 TALLOC_CTX *mem_ctx)
3377 data->notify_data.value[0]=queue->job;
3378 data->notify_data.value[1]=0;
3381 /*******************************************************************
3382 Fill a notify_info_data with submitted time.
3383 ********************************************************************/
3385 static void spoolss_notify_submitted_time(int snum,
3386 SPOOL_NOTIFY_INFO_DATA *data,
3387 print_queue_struct *queue,
3388 NT_PRINTER_INFO_LEVEL *printer,
3389 TALLOC_CTX *mem_ctx)
3396 t=gmtime(&queue->time);
3398 len = sizeof(SYSTEMTIME);
3400 data->notify_data.data.length = len;
3401 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
3403 if (!data->notify_data.data.string) {
3404 data->notify_data.data.length = 0;
3408 make_systemtime(&st, t);
3411 * Systemtime must be linearized as a set of UINT16's.
3412 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3415 p = (char *)data->notify_data.data.string;
3416 SSVAL(p, 0, st.year);
3417 SSVAL(p, 2, st.month);
3418 SSVAL(p, 4, st.dayofweek);
3419 SSVAL(p, 6, st.day);
3420 SSVAL(p, 8, st.hour);
3421 SSVAL(p, 10, st.minute);
3422 SSVAL(p, 12, st.second);
3423 SSVAL(p, 14, st.milliseconds);
3426 struct s_notify_info_data_table
3432 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
3433 print_queue_struct *queue,
3434 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3437 /* A table describing the various print notification constants and
3438 whether the notification data is a pointer to a variable sized
3439 buffer, a one value uint32 or a two value uint32. */
3441 static const struct s_notify_info_data_table notify_info_data_table[] =
3443 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3444 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3445 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
3446 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3447 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3448 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
3449 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
3450 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3451 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
3452 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3453 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3454 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3455 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
3456 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
3457 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3458 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
3459 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3460 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3461 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
3462 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
3463 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
3464 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
3465 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
3466 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
3467 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
3468 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
3469 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3470 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3471 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3472 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
3473 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
3474 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3475 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3476 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3477 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3478 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3479 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
3480 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
3481 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
3482 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
3483 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3484 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
3485 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
3486 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3487 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3488 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
3489 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
3490 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
3491 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
3492 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3495 /*******************************************************************
3496 Return the size of info_data structure.
3497 ********************************************************************/
3499 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
3503 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3504 if ( (notify_info_data_table[i].type == type)
3505 && (notify_info_data_table[i].field == field) ) {
3506 switch(notify_info_data_table[i].size) {
3507 case NOTIFY_ONE_VALUE:
3508 case NOTIFY_TWO_VALUE:
3513 /* The only pointer notify data I have seen on
3514 the wire is the submitted time and this has
3515 the notify size set to 4. -tpot */
3517 case NOTIFY_POINTER:
3520 case NOTIFY_SECDESC:
3526 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3531 /*******************************************************************
3532 Return the type of notify_info_data.
3533 ********************************************************************/
3535 static uint32 type_of_notify_info_data(uint16 type, uint16 field)
3539 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3540 if (notify_info_data_table[i].type == type &&
3541 notify_info_data_table[i].field == field)
3542 return notify_info_data_table[i].size;
3548 /****************************************************************************
3549 ****************************************************************************/
3551 static bool search_notify(uint16 type, uint16 field, int *value)
3555 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3556 if (notify_info_data_table[i].type == type &&
3557 notify_info_data_table[i].field == field &&
3558 notify_info_data_table[i].fn != NULL) {
3567 /****************************************************************************
3568 ****************************************************************************/
3570 void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
3572 info_data->type = type;
3573 info_data->field = field;
3574 info_data->reserved = 0;
3576 info_data->size = size_of_notify_info_data(type, field);
3577 info_data->enc_type = type_of_notify_info_data(type, field);
3582 /*******************************************************************
3584 * fill a notify_info struct with info asked
3586 ********************************************************************/
3588 static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
3589 snum, SPOOL_NOTIFY_OPTION_TYPE
3590 *option_type, uint32 id,
3591 TALLOC_CTX *mem_ctx)
3597 SPOOL_NOTIFY_INFO_DATA *current_data;
3598 NT_PRINTER_INFO_LEVEL *printer = NULL;
3599 print_queue_struct *queue=NULL;
3601 type=option_type->type;
3603 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3604 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3605 option_type->count, lp_servicename(snum)));
3607 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3610 for(field_num=0; field_num<option_type->count; field_num++) {
3611 field = option_type->fields[field_num];
3613 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3615 if (!search_notify(type, field, &j) )
3618 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3619 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3620 free_a_printer(&printer, 2);
3624 current_data = &info->data[info->count];
3626 construct_info_data(current_data, type, field, id);
3628 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3629 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3631 notify_info_data_table[j].fn(snum, current_data, queue,
3637 free_a_printer(&printer, 2);
3641 /*******************************************************************
3643 * fill a notify_info struct with info asked
3645 ********************************************************************/
3647 static bool construct_notify_jobs_info(print_queue_struct *queue,
3648 SPOOL_NOTIFY_INFO *info,
3649 NT_PRINTER_INFO_LEVEL *printer,
3650 int snum, SPOOL_NOTIFY_OPTION_TYPE
3651 *option_type, uint32 id,
3652 TALLOC_CTX *mem_ctx)
3658 SPOOL_NOTIFY_INFO_DATA *current_data;
3660 DEBUG(4,("construct_notify_jobs_info\n"));
3662 type = option_type->type;
3664 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3665 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3666 option_type->count));
3668 for(field_num=0; field_num<option_type->count; field_num++) {
3669 field = option_type->fields[field_num];
3671 if (!search_notify(type, field, &j) )
3674 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3675 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3679 current_data=&(info->data[info->count]);
3681 construct_info_data(current_data, type, field, id);
3682 notify_info_data_table[j].fn(snum, current_data, queue,
3691 * JFM: The enumeration is not that simple, it's even non obvious.
3693 * let's take an example: I want to monitor the PRINTER SERVER for
3694 * the printer's name and the number of jobs currently queued.
3695 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3696 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3698 * I have 3 printers on the back of my server.
3700 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3703 * 1 printer 1 name 1
3704 * 2 printer 1 cjob 1
3705 * 3 printer 2 name 2
3706 * 4 printer 2 cjob 2
3707 * 5 printer 3 name 3
3708 * 6 printer 3 name 3
3710 * that's the print server case, the printer case is even worse.
3713 /*******************************************************************
3715 * enumerate all printers on the printserver
3716 * fill a notify_info struct with info asked
3718 ********************************************************************/
3720 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3721 SPOOL_NOTIFY_INFO *info,
3722 TALLOC_CTX *mem_ctx)
3725 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3726 int n_services=lp_numservices();
3728 SPOOL_NOTIFY_OPTION *option;
3729 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3731 DEBUG(4,("printserver_notify_info\n"));
3736 option=Printer->notify.option;
3741 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3742 sending a ffpcn() request first */
3747 for (i=0; i<option->count; i++) {
3748 option_type=&(option->ctr.type[i]);
3750 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3753 for (snum=0; snum<n_services; snum++)
3755 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3756 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3762 * Debugging information, don't delete.
3765 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3766 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3767 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3769 for (i=0; i<info->count; i++) {
3770 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3771 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3772 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3779 /*******************************************************************
3781 * fill a notify_info struct with info asked
3783 ********************************************************************/
3785 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
3786 TALLOC_CTX *mem_ctx)
3789 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3792 SPOOL_NOTIFY_OPTION *option;
3793 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3795 print_queue_struct *queue=NULL;
3796 print_status_struct status;
3798 DEBUG(4,("printer_notify_info\n"));
3803 option=Printer->notify.option;
3809 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3810 sending a ffpcn() request first */
3815 get_printer_snum(p, hnd, &snum, NULL);
3817 for (i=0; i<option->count; i++) {
3818 option_type=&option->ctr.type[i];
3820 switch ( option_type->type ) {
3821 case PRINTER_NOTIFY_TYPE:
3822 if(construct_notify_printer_info(Printer, info, snum,
3828 case JOB_NOTIFY_TYPE: {
3829 NT_PRINTER_INFO_LEVEL *printer = NULL;
3831 count = print_queue_status(snum, &queue, &status);
3833 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3836 for (j=0; j<count; j++) {
3837 construct_notify_jobs_info(&queue[j], info,
3844 free_a_printer(&printer, 2);
3854 * Debugging information, don't delete.
3857 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3858 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3859 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3861 for (i=0; i<info->count; i++) {
3862 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3863 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3864 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3870 /********************************************************************
3872 ********************************************************************/
3874 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
3876 POLICY_HND *handle = &q_u->handle;
3877 SPOOL_NOTIFY_INFO *info = &r_u->info;
3879 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3880 WERROR result = WERR_BADFID;
3882 /* we always have a NOTIFY_INFO struct */
3886 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3887 OUR_HANDLE(handle)));
3891 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3894 * We are now using the change value, and
3895 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3896 * I don't have a global notification system, I'm sending back all the
3897 * informations even when _NOTHING_ has changed.
3900 /* We need to keep track of the change value to send back in
3901 RRPCN replies otherwise our updates are ignored. */
3903 Printer->notify.fnpcn = True;
3905 if (Printer->notify.client_connected) {
3906 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
3907 Printer->notify.change = q_u->change;
3910 /* just ignore the SPOOL_NOTIFY_OPTION */
3912 switch (Printer->printer_type) {
3914 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3917 case SPLHND_PRINTER:
3918 result = printer_notify_info(p, handle, info, p->mem_ctx);
3922 Printer->notify.fnpcn = False;
3928 /********************************************************************
3929 * construct_printer_info_0
3930 * fill a printer_info_0 struct
3931 ********************************************************************/
3933 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3935 char *chaine = NULL;
3937 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3938 counter_printer_0 *session_counter;
3939 uint32 global_counter;
3942 print_status_struct status;
3943 TALLOC_CTX *ctx = talloc_tos();
3945 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3948 init_unistr(&printer->printername, ntprinter->info_2->printername);
3950 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3952 free_a_printer(&ntprinter,2);
3956 count = print_queue_length(snum, &status);
3958 /* check if we already have a counter for this printer */
3959 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3960 if (session_counter->snum == snum)
3964 init_unistr(&printer->servername, chaine);
3966 /* it's the first time, add it to the list */
3967 if (session_counter==NULL) {
3968 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3969 free_a_printer(&ntprinter, 2);
3972 ZERO_STRUCTP(session_counter);
3973 session_counter->snum=snum;
3974 session_counter->counter=0;
3975 DLIST_ADD(counter_list, session_counter);
3979 session_counter->counter++;
3982 * the global_counter should be stored in a TDB as it's common to all the clients
3983 * and should be zeroed on samba startup
3985 global_counter=session_counter->counter;
3986 printer->cjobs = count;
3987 printer->total_jobs = 0;
3988 printer->total_bytes = 0;
3990 setuptime = (time_t)ntprinter->info_2->setuptime;
3991 t=gmtime(&setuptime);
3993 printer->year = t->tm_year+1900;
3994 printer->month = t->tm_mon+1;
3995 printer->dayofweek = t->tm_wday;
3996 printer->day = t->tm_mday;
3997 printer->hour = t->tm_hour;
3998 printer->minute = t->tm_min;
3999 printer->second = t->tm_sec;
4000 printer->milliseconds = 0;
4002 printer->global_counter = global_counter;
4003 printer->total_pages = 0;
4005 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
4006 printer->major_version = 0x0005; /* NT 5 */
4007 printer->build_version = 0x0893; /* build 2195 */
4009 printer->unknown7 = 0x1;
4010 printer->unknown8 = 0x0;
4011 printer->unknown9 = 0x0;
4012 printer->session_counter = session_counter->counter;
4013 printer->unknown11 = 0x0;
4014 printer->printer_errors = 0x0; /* number of print failure */
4015 printer->unknown13 = 0x0;
4016 printer->unknown14 = 0x1;
4017 printer->unknown15 = 0x024a; /* 586 Pentium ? */
4018 printer->unknown16 = 0x0;
4019 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
4020 printer->unknown18 = 0x0;
4021 printer->status = nt_printq_status(status.status);
4022 printer->unknown20 = 0x0;
4023 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4024 printer->unknown22 = 0x0;
4025 printer->unknown23 = 0x6; /* 6 ???*/
4026 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
4027 printer->unknown25 = 0;
4028 printer->unknown26 = 0;
4029 printer->unknown27 = 0;
4030 printer->unknown28 = 0;
4031 printer->unknown29 = 0;
4033 free_a_printer(&ntprinter,2);
4037 /********************************************************************
4038 * construct_printer_info_1
4039 * fill a printer_info_1 struct
4040 ********************************************************************/
4041 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4043 char *chaine = NULL;
4044 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4045 TALLOC_CTX *ctx = talloc_tos();
4047 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4050 printer->flags=flags;
4052 if (*ntprinter->info_2->comment == '\0') {
4053 init_unistr(&printer->comment, lp_comment(snum));
4054 chaine = talloc_asprintf(ctx,
4055 "%s,%s,%s", ntprinter->info_2->printername,
4056 ntprinter->info_2->drivername, lp_comment(snum));
4059 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4060 chaine = talloc_asprintf(ctx,
4061 "%s,%s,%s", ntprinter->info_2->printername,
4062 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4066 free_a_printer(&ntprinter,2);
4070 init_unistr(&printer->description, chaine);
4071 init_unistr(&printer->name, ntprinter->info_2->printername);
4073 free_a_printer(&ntprinter,2);
4078 /****************************************************************************
4079 Free a DEVMODE struct.
4080 ****************************************************************************/
4082 static void free_dev_mode(DEVICEMODE *dev)
4087 SAFE_FREE(dev->dev_private);
4092 /****************************************************************************
4093 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4094 should be valid upon entry
4095 ****************************************************************************/
4097 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4099 if ( !devmode || !ntdevmode )
4102 init_unistr(&devmode->devicename, ntdevmode->devicename);
4104 init_unistr(&devmode->formname, ntdevmode->formname);
4106 devmode->specversion = ntdevmode->specversion;
4107 devmode->driverversion = ntdevmode->driverversion;
4108 devmode->size = ntdevmode->size;
4109 devmode->driverextra = ntdevmode->driverextra;
4110 devmode->fields = ntdevmode->fields;
4112 devmode->orientation = ntdevmode->orientation;
4113 devmode->papersize = ntdevmode->papersize;
4114 devmode->paperlength = ntdevmode->paperlength;
4115 devmode->paperwidth = ntdevmode->paperwidth;
4116 devmode->scale = ntdevmode->scale;
4117 devmode->copies = ntdevmode->copies;
4118 devmode->defaultsource = ntdevmode->defaultsource;
4119 devmode->printquality = ntdevmode->printquality;
4120 devmode->color = ntdevmode->color;
4121 devmode->duplex = ntdevmode->duplex;
4122 devmode->yresolution = ntdevmode->yresolution;
4123 devmode->ttoption = ntdevmode->ttoption;
4124 devmode->collate = ntdevmode->collate;
4125 devmode->icmmethod = ntdevmode->icmmethod;
4126 devmode->icmintent = ntdevmode->icmintent;
4127 devmode->mediatype = ntdevmode->mediatype;
4128 devmode->dithertype = ntdevmode->dithertype;
4130 if (ntdevmode->nt_dev_private != NULL) {
4131 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4138 /****************************************************************************
4139 Create a DEVMODE struct. Returns malloced memory.
4140 ****************************************************************************/
4142 DEVICEMODE *construct_dev_mode(const char *servicename)
4144 NT_PRINTER_INFO_LEVEL *printer = NULL;
4145 DEVICEMODE *devmode = NULL;
4147 DEBUG(7,("construct_dev_mode\n"));
4149 DEBUGADD(8,("getting printer characteristics\n"));
4151 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4154 if ( !printer->info_2->devmode ) {
4155 DEBUG(5, ("BONG! There was no device mode!\n"));
4159 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4160 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4164 ZERO_STRUCTP(devmode);
4166 DEBUGADD(8,("loading DEVICEMODE\n"));
4168 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4169 free_dev_mode( devmode );
4174 free_a_printer(&printer,2);
4179 /********************************************************************
4180 * construct_printer_info_2
4181 * fill a printer_info_2 struct
4182 ********************************************************************/
4184 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4187 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4189 print_status_struct status;
4191 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4194 count = print_queue_length(snum, &status);
4196 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4197 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4198 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4199 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4200 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4202 if (*ntprinter->info_2->comment == '\0')
4203 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4205 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4207 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4208 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4209 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4210 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4211 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4213 printer->attributes = ntprinter->info_2->attributes;
4215 printer->priority = ntprinter->info_2->priority; /* priority */
4216 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4217 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4218 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4219 printer->status = nt_printq_status(status.status); /* status */
4220 printer->cjobs = count; /* jobs */
4221 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4223 if ( !(printer->devmode = construct_dev_mode(
4224 lp_const_servicename(snum))) )
4225 DEBUG(8, ("Returning NULL Devicemode!\n"));
4227 printer->secdesc = NULL;
4229 if ( ntprinter->info_2->secdesc_buf
4230 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4232 /* don't use talloc_steal() here unless you do a deep steal of all
4233 the SEC_DESC members */
4235 printer->secdesc = dup_sec_desc( talloc_tos(),
4236 ntprinter->info_2->secdesc_buf->sd );
4239 free_a_printer(&ntprinter, 2);
4244 /********************************************************************
4245 * construct_printer_info_3
4246 * fill a printer_info_3 struct
4247 ********************************************************************/
4249 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4251 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4252 PRINTER_INFO_3 *printer = NULL;
4254 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4258 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4259 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4260 free_a_printer(&ntprinter, 2);
4264 ZERO_STRUCTP(printer);
4266 /* These are the components of the SD we are returning. */
4268 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4269 /* don't use talloc_steal() here unless you do a deep steal of all
4270 the SEC_DESC members */
4272 printer->secdesc = dup_sec_desc( talloc_tos(),
4273 ntprinter->info_2->secdesc_buf->sd );
4276 free_a_printer(&ntprinter, 2);
4278 *pp_printer = printer;
4282 /********************************************************************
4283 * construct_printer_info_4
4284 * fill a printer_info_4 struct
4285 ********************************************************************/
4287 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4289 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4291 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4294 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4295 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4296 printer->attributes = ntprinter->info_2->attributes;
4298 free_a_printer(&ntprinter, 2);
4302 /********************************************************************
4303 * construct_printer_info_5
4304 * fill a printer_info_5 struct
4305 ********************************************************************/
4307 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4309 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4311 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4314 init_unistr(&printer->printername, ntprinter->info_2->printername);
4315 init_unistr(&printer->portname, ntprinter->info_2->portname);
4316 printer->attributes = ntprinter->info_2->attributes;
4318 /* these two are not used by NT+ according to MSDN */
4320 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4321 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4323 free_a_printer(&ntprinter, 2);
4328 /********************************************************************
4329 * construct_printer_info_6
4330 * fill a printer_info_6 struct
4331 ********************************************************************/
4333 static bool construct_printer_info_6(Printer_entry *print_hnd,
4334 PRINTER_INFO_6 *printer,
4337 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4339 print_status_struct status;
4341 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4342 lp_const_servicename(snum))))
4345 count = print_queue_length(snum, &status);
4347 printer->status = nt_printq_status(status.status);
4349 free_a_printer(&ntprinter, 2);
4354 /********************************************************************
4355 * construct_printer_info_7
4356 * fill a printer_info_7 struct
4357 ********************************************************************/
4359 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4361 char *guid_str = NULL;
4364 if (is_printer_published(print_hnd, snum, &guid)) {
4365 if (asprintf(&guid_str, "{%s}",
4366 GUID_string(talloc_tos(), &guid)) == -1) {
4369 strupper_m(guid_str);
4370 init_unistr(&printer->guid, guid_str);
4371 SAFE_FREE(guid_str);
4372 printer->action = SPOOL_DS_PUBLISH;
4374 init_unistr(&printer->guid, "");
4375 printer->action = SPOOL_DS_UNPUBLISH;
4381 /********************************************************************
4382 Spoolss_enumprinters.
4383 ********************************************************************/
4385 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4389 int n_services=lp_numservices();
4390 PRINTER_INFO_1 *printers=NULL;
4391 PRINTER_INFO_1 current_prt;
4392 WERROR result = WERR_OK;
4394 DEBUG(4,("enum_all_printers_info_1\n"));
4396 for (snum=0; snum<n_services; snum++) {
4397 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4398 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4400 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4401 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4402 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4406 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4408 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4414 /* check the required size. */
4415 for (i=0; i<*returned; i++)
4416 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4418 if (*needed > offered) {
4419 result = WERR_INSUFFICIENT_BUFFER;
4423 if (!rpcbuf_alloc_size(buffer, *needed)) {
4424 result = WERR_NOMEM;
4428 /* fill the buffer with the structures */
4429 for (i=0; i<*returned; i++)
4430 smb_io_printer_info_1("", buffer, &printers[i], 0);
4435 SAFE_FREE(printers);
4437 if ( !W_ERROR_IS_OK(result) )
4443 /********************************************************************
4444 enum_all_printers_info_1_local.
4445 *********************************************************************/
4447 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4449 DEBUG(4,("enum_all_printers_info_1_local\n"));
4451 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4454 /********************************************************************
4455 enum_all_printers_info_1_name.
4456 *********************************************************************/
4458 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4462 DEBUG(4,("enum_all_printers_info_1_name\n"));
4464 if ((name[0] == '\\') && (name[1] == '\\'))
4467 if (is_myname_or_ipaddr(s)) {
4468 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4471 return WERR_INVALID_NAME;
4474 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4475 /********************************************************************
4476 enum_all_printers_info_1_remote.
4477 *********************************************************************/
4479 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4481 PRINTER_INFO_1 *printer;
4482 fstring printername;
4485 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4486 WERROR result = WERR_OK;
4488 /* JFM: currently it's more a place holder than anything else.
4489 * In the spooler world there is a notion of server registration.
4490 * the print servers are registered on the PDC (in the same domain)
4492 * We should have a TDB here. The registration is done thru an
4493 * undocumented RPC call.
4496 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4501 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4502 slprintf(desc, sizeof(desc)-1,"%s", name);
4503 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4505 init_unistr(&printer->description, desc);
4506 init_unistr(&printer->name, printername);
4507 init_unistr(&printer->comment, comment);
4508 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4510 /* check the required size. */
4511 *needed += spoolss_size_printer_info_1(printer);
4513 if (*needed > offered) {
4514 result = WERR_INSUFFICIENT_BUFFER;
4518 if (!rpcbuf_alloc_size(buffer, *needed)) {
4519 result = WERR_NOMEM;
4523 /* fill the buffer with the structures */
4524 smb_io_printer_info_1("", buffer, printer, 0);
4530 if ( !W_ERROR_IS_OK(result) )
4538 /********************************************************************
4539 enum_all_printers_info_1_network.
4540 *********************************************************************/
4542 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4546 DEBUG(4,("enum_all_printers_info_1_network\n"));
4548 /* If we respond to a enum_printers level 1 on our name with flags
4549 set to PRINTER_ENUM_REMOTE with a list of printers then these
4550 printers incorrectly appear in the APW browse list.
4551 Specifically the printers for the server appear at the workgroup
4552 level where all the other servers in the domain are
4553 listed. Windows responds to this call with a
4554 WERR_CAN_NOT_COMPLETE so we should do the same. */
4556 if (name[0] == '\\' && name[1] == '\\')
4559 if (is_myname_or_ipaddr(s))
4560 return WERR_CAN_NOT_COMPLETE;
4562 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4565 /********************************************************************
4566 * api_spoolss_enumprinters
4568 * called from api_spoolss_enumprinters (see this to understand)
4569 ********************************************************************/
4571 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4575 int n_services=lp_numservices();
4576 PRINTER_INFO_2 *printers=NULL;
4577 PRINTER_INFO_2 current_prt;
4578 WERROR result = WERR_OK;
4582 for (snum=0; snum<n_services; snum++) {
4583 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4584 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4586 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4587 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4588 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4593 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4595 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4602 /* check the required size. */
4603 for (i=0; i<*returned; i++)
4604 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4606 if (*needed > offered) {
4607 result = WERR_INSUFFICIENT_BUFFER;
4611 if (!rpcbuf_alloc_size(buffer, *needed)) {
4612 result = WERR_NOMEM;
4616 /* fill the buffer with the structures */
4617 for (i=0; i<*returned; i++)
4618 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4623 for (i=0; i<*returned; i++)
4624 free_devmode(printers[i].devmode);
4626 SAFE_FREE(printers);
4628 if ( !W_ERROR_IS_OK(result) )
4634 /********************************************************************
4635 * handle enumeration of printers at level 1
4636 ********************************************************************/
4638 static WERROR enumprinters_level1( uint32 flags, fstring name,
4639 RPC_BUFFER *buffer, uint32 offered,
4640 uint32 *needed, uint32 *returned)
4642 /* Not all the flags are equals */
4644 if (flags & PRINTER_ENUM_LOCAL)
4645 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4647 if (flags & PRINTER_ENUM_NAME)
4648 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4650 #if 0 /* JERRY - disabled for now */
4651 if (flags & PRINTER_ENUM_REMOTE)
4652 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4655 if (flags & PRINTER_ENUM_NETWORK)
4656 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4658 return WERR_OK; /* NT4sp5 does that */
4661 /********************************************************************
4662 * handle enumeration of printers at level 2
4663 ********************************************************************/
4665 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4666 RPC_BUFFER *buffer, uint32 offered,
4667 uint32 *needed, uint32 *returned)
4669 if (flags & PRINTER_ENUM_LOCAL) {
4670 return enum_all_printers_info_2(buffer, offered, needed, returned);
4673 if (flags & PRINTER_ENUM_NAME) {
4674 if (is_myname_or_ipaddr(canon_servername(servername)))
4675 return enum_all_printers_info_2(buffer, offered, needed, returned);
4677 return WERR_INVALID_NAME;
4680 if (flags & PRINTER_ENUM_REMOTE)
4681 return WERR_UNKNOWN_LEVEL;
4686 /********************************************************************
4687 * handle enumeration of printers at level 5
4688 ********************************************************************/
4690 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4691 RPC_BUFFER *buffer, uint32 offered,
4692 uint32 *needed, uint32 *returned)
4694 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4698 /********************************************************************
4699 * api_spoolss_enumprinters
4701 * called from api_spoolss_enumprinters (see this to understand)
4702 ********************************************************************/
4704 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4706 uint32 flags = q_u->flags;
4707 UNISTR2 *servername = &q_u->servername;
4708 uint32 level = q_u->level;
4709 RPC_BUFFER *buffer = NULL;
4710 uint32 offered = q_u->offered;
4711 uint32 *needed = &r_u->needed;
4712 uint32 *returned = &r_u->returned;
4716 /* that's an [in out] buffer */
4718 if (!q_u->buffer && (offered!=0)) {
4719 return WERR_INVALID_PARAM;
4722 if (offered > MAX_RPC_DATA_SIZE) {
4723 return WERR_INVALID_PARAM;
4726 rpcbuf_move(q_u->buffer, &r_u->buffer);
4727 buffer = r_u->buffer;
4729 DEBUG(4,("_spoolss_enumprinters\n"));
4736 * flags==PRINTER_ENUM_NAME
4737 * if name=="" then enumerates all printers
4738 * if name!="" then enumerate the printer
4739 * flags==PRINTER_ENUM_REMOTE
4740 * name is NULL, enumerate printers
4741 * Level 2: name!="" enumerates printers, name can't be NULL
4742 * Level 3: doesn't exist
4743 * Level 4: does a local registry lookup
4744 * Level 5: same as Level 2
4747 unistr2_to_ascii(name, servername, sizeof(name));
4752 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4754 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4756 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4761 return WERR_UNKNOWN_LEVEL;
4764 /****************************************************************************
4765 ****************************************************************************/
4767 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4769 PRINTER_INFO_0 *printer=NULL;
4770 WERROR result = WERR_OK;
4772 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4775 construct_printer_info_0(print_hnd, printer, snum);
4777 /* check the required size. */
4778 *needed += spoolss_size_printer_info_0(printer);
4780 if (*needed > offered) {
4781 result = WERR_INSUFFICIENT_BUFFER;
4785 if (!rpcbuf_alloc_size(buffer, *needed)) {
4786 result = WERR_NOMEM;
4790 /* fill the buffer with the structures */
4791 smb_io_printer_info_0("", buffer, printer, 0);
4801 /****************************************************************************
4802 ****************************************************************************/
4804 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4806 PRINTER_INFO_1 *printer=NULL;
4807 WERROR result = WERR_OK;
4809 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4812 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4814 /* check the required size. */
4815 *needed += spoolss_size_printer_info_1(printer);
4817 if (*needed > offered) {
4818 result = WERR_INSUFFICIENT_BUFFER;
4822 if (!rpcbuf_alloc_size(buffer, *needed)) {
4823 result = WERR_NOMEM;
4827 /* fill the buffer with the structures */
4828 smb_io_printer_info_1("", buffer, printer, 0);
4837 /****************************************************************************
4838 ****************************************************************************/
4840 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4842 PRINTER_INFO_2 *printer=NULL;
4843 WERROR result = WERR_OK;
4845 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4848 construct_printer_info_2(print_hnd, printer, snum);
4850 /* check the required size. */
4851 *needed += spoolss_size_printer_info_2(printer);
4853 if (*needed > offered) {
4854 result = WERR_INSUFFICIENT_BUFFER;
4858 if (!rpcbuf_alloc_size(buffer, *needed)) {
4859 result = WERR_NOMEM;
4863 /* fill the buffer with the structures */
4864 if (!smb_io_printer_info_2("", buffer, printer, 0))
4865 result = WERR_NOMEM;
4869 free_printer_info_2(printer);
4874 /****************************************************************************
4875 ****************************************************************************/
4877 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4879 PRINTER_INFO_3 *printer=NULL;
4880 WERROR result = WERR_OK;
4882 if (!construct_printer_info_3(print_hnd, &printer, snum))
4885 /* check the required size. */
4886 *needed += spoolss_size_printer_info_3(printer);
4888 if (*needed > offered) {
4889 result = WERR_INSUFFICIENT_BUFFER;
4893 if (!rpcbuf_alloc_size(buffer, *needed)) {
4894 result = WERR_NOMEM;
4898 /* fill the buffer with the structures */
4899 smb_io_printer_info_3("", buffer, printer, 0);
4903 free_printer_info_3(printer);
4908 /****************************************************************************
4909 ****************************************************************************/
4911 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4913 PRINTER_INFO_4 *printer=NULL;
4914 WERROR result = WERR_OK;
4916 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4919 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4924 /* check the required size. */
4925 *needed += spoolss_size_printer_info_4(printer);
4927 if (*needed > offered) {
4928 result = WERR_INSUFFICIENT_BUFFER;
4932 if (!rpcbuf_alloc_size(buffer, *needed)) {
4933 result = WERR_NOMEM;
4937 /* fill the buffer with the structures */
4938 smb_io_printer_info_4("", buffer, printer, 0);
4942 free_printer_info_4(printer);
4947 /****************************************************************************
4948 ****************************************************************************/
4950 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4952 PRINTER_INFO_5 *printer=NULL;
4953 WERROR result = WERR_OK;
4955 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4958 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4959 free_printer_info_5(printer);
4963 /* check the required size. */
4964 *needed += spoolss_size_printer_info_5(printer);
4966 if (*needed > offered) {
4967 result = WERR_INSUFFICIENT_BUFFER;
4971 if (!rpcbuf_alloc_size(buffer, *needed)) {
4972 result = WERR_NOMEM;
4976 /* fill the buffer with the structures */
4977 smb_io_printer_info_5("", buffer, printer, 0);
4981 free_printer_info_5(printer);
4986 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4988 RPC_BUFFER *buffer, uint32 offered,
4991 PRINTER_INFO_6 *printer;
4992 WERROR result = WERR_OK;
4994 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4998 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4999 free_printer_info_6(printer);
5003 /* check the required size. */
5004 *needed += spoolss_size_printer_info_6(printer);
5006 if (*needed > offered) {
5007 result = WERR_INSUFFICIENT_BUFFER;
5011 if (!rpcbuf_alloc_size(buffer, *needed)) {
5012 result = WERR_NOMEM;
5016 /* fill the buffer with the structures */
5017 smb_io_printer_info_6("", buffer, printer, 0);
5021 free_printer_info_6(printer);
5026 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5028 PRINTER_INFO_7 *printer=NULL;
5029 WERROR result = WERR_OK;
5031 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5034 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5035 result = WERR_NOMEM;
5039 /* check the required size. */
5040 *needed += spoolss_size_printer_info_7(printer);
5042 if (*needed > offered) {
5043 result = WERR_INSUFFICIENT_BUFFER;
5047 if (!rpcbuf_alloc_size(buffer, *needed)) {
5048 result = WERR_NOMEM;
5053 /* fill the buffer with the structures */
5054 smb_io_printer_info_7("", buffer, printer, 0);
5058 free_printer_info_7(printer);
5063 /****************************************************************************
5064 ****************************************************************************/
5066 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5068 POLICY_HND *handle = &q_u->handle;
5069 uint32 level = q_u->level;
5070 RPC_BUFFER *buffer = NULL;
5071 uint32 offered = q_u->offered;
5072 uint32 *needed = &r_u->needed;
5073 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5077 /* that's an [in out] buffer */
5079 if (!q_u->buffer && (offered!=0)) {
5080 return WERR_INVALID_PARAM;
5083 if (offered > MAX_RPC_DATA_SIZE) {
5084 return WERR_INVALID_PARAM;
5087 rpcbuf_move(q_u->buffer, &r_u->buffer);
5088 buffer = r_u->buffer;
5092 if (!get_printer_snum(p, handle, &snum, NULL))
5097 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5099 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5101 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5103 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5105 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5107 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5109 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5111 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5113 return WERR_UNKNOWN_LEVEL;
5116 /********************************************************************
5117 * fill a DRIVER_INFO_1 struct
5118 ********************************************************************/
5120 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5122 init_unistr( &info->name, driver.info_3->name);
5125 /********************************************************************
5126 * construct_printer_driver_info_1
5127 ********************************************************************/
5129 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5131 NT_PRINTER_INFO_LEVEL *printer = NULL;
5132 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5134 ZERO_STRUCT(driver);
5136 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5137 return WERR_INVALID_PRINTER_NAME;
5139 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5140 free_a_printer(&printer, 2);
5141 return WERR_UNKNOWN_PRINTER_DRIVER;
5144 fill_printer_driver_info_1(info, driver, servername, architecture);
5146 free_a_printer(&printer,2);
5151 /********************************************************************
5152 * construct_printer_driver_info_2
5153 * fill a printer_info_2 struct
5154 ********************************************************************/
5156 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5158 TALLOC_CTX *ctx = talloc_tos();
5160 const char *cservername = canon_servername(servername);
5162 info->version=driver.info_3->cversion;
5164 init_unistr( &info->name, driver.info_3->name );
5165 init_unistr( &info->architecture, driver.info_3->environment );
5167 if (strlen(driver.info_3->driverpath)) {
5168 temp = talloc_asprintf(ctx,
5171 driver.info_3->driverpath);
5172 init_unistr( &info->driverpath, temp );
5174 init_unistr( &info->driverpath, "" );
5178 if (strlen(driver.info_3->datafile)) {
5179 temp = talloc_asprintf(ctx,
5182 driver.info_3->datafile);
5183 init_unistr( &info->datafile, temp );
5185 init_unistr( &info->datafile, "" );
5188 if (strlen(driver.info_3->configfile)) {
5189 temp = talloc_asprintf(ctx,
5192 driver.info_3->configfile);
5193 init_unistr( &info->configfile, temp );
5195 init_unistr( &info->configfile, "" );
5198 /********************************************************************
5199 * construct_printer_driver_info_2
5200 * fill a printer_info_2 struct
5201 ********************************************************************/
5203 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5205 NT_PRINTER_INFO_LEVEL *printer = NULL;
5206 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5208 ZERO_STRUCT(printer);
5209 ZERO_STRUCT(driver);
5211 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5212 return WERR_INVALID_PRINTER_NAME;
5214 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5215 free_a_printer(&printer, 2);
5216 return WERR_UNKNOWN_PRINTER_DRIVER;
5219 fill_printer_driver_info_2(info, driver, servername);
5221 free_a_printer(&printer,2);
5226 /********************************************************************
5227 * copy a strings array and convert to UNICODE
5229 * convert an array of ascii string to a UNICODE string
5230 ********************************************************************/
5232 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5238 TALLOC_CTX *ctx = talloc_tos();
5240 DEBUG(6,("init_unistr_array\n"));
5244 if ( !char_array ) {
5249 v = ""; /* hack to handle null lists */
5252 /* hack to allow this to be used in places other than when generating
5253 the list of dependent files */
5257 line = talloc_asprintf(ctx,
5259 canon_servername(servername),
5262 line = talloc_strdup(ctx, v);
5266 SAFE_FREE(*uni_array);
5269 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5271 /* add one extra unit16 for the second terminating NULL */
5273 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5274 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5281 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5286 /* special case for ""; we need to add both NULL's here */
5288 (*uni_array)[j++]=0x0000;
5289 (*uni_array)[j]=0x0000;
5292 DEBUGADD(6,("last one:done\n"));
5294 /* return size of array in uint16's */
5299 /********************************************************************
5300 * construct_printer_info_3
5301 * fill a printer_info_3 struct
5302 ********************************************************************/
5304 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5307 TALLOC_CTX *ctx = talloc_tos();
5308 const char *cservername = canon_servername(servername);
5312 info->version=driver.info_3->cversion;
5314 init_unistr( &info->name, driver.info_3->name );
5315 init_unistr( &info->architecture, driver.info_3->environment );
5317 if (strlen(driver.info_3->driverpath)) {
5318 temp = talloc_asprintf(ctx,
5321 driver.info_3->driverpath);
5322 init_unistr( &info->driverpath, temp );
5324 init_unistr( &info->driverpath, "" );
5327 if (strlen(driver.info_3->datafile)) {
5328 temp = talloc_asprintf(ctx,
5331 driver.info_3->datafile);
5332 init_unistr( &info->datafile, temp );
5334 init_unistr( &info->datafile, "" );
5337 if (strlen(driver.info_3->configfile)) {
5338 temp = talloc_asprintf(ctx,
5341 driver.info_3->configfile);
5342 init_unistr( &info->configfile, temp );
5344 init_unistr( &info->configfile, "" );
5347 if (strlen(driver.info_3->helpfile)) {
5348 temp = talloc_asprintf(ctx,
5351 driver.info_3->helpfile);
5352 init_unistr( &info->helpfile, temp );
5354 init_unistr( &info->helpfile, "" );
5357 init_unistr( &info->monitorname, driver.info_3->monitorname );
5358 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5360 info->dependentfiles=NULL;
5361 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5364 /********************************************************************
5365 * construct_printer_info_3
5366 * fill a printer_info_3 struct
5367 ********************************************************************/
5369 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5371 NT_PRINTER_INFO_LEVEL *printer = NULL;
5372 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5374 ZERO_STRUCT(driver);
5376 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5377 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5378 if (!W_ERROR_IS_OK(status))
5379 return WERR_INVALID_PRINTER_NAME;
5381 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5382 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5387 * I put this code in during testing. Helpful when commenting out the
5388 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5389 * as win2k always queries the driver using an infor level of 6.
5390 * I've left it in (but ifdef'd out) because I'll probably
5391 * use it in experimentation again in the future. --jerry 22/01/2002
5394 if (!W_ERROR_IS_OK(status)) {
5396 * Is this a W2k client ?
5399 /* Yes - try again with a WinNT driver. */
5401 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5402 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5406 if (!W_ERROR_IS_OK(status)) {
5407 free_a_printer(&printer,2);
5408 return WERR_UNKNOWN_PRINTER_DRIVER;
5416 fill_printer_driver_info_3(info, driver, servername);
5418 free_a_printer(&printer,2);
5423 /********************************************************************
5424 * construct_printer_info_6
5425 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5426 ********************************************************************/
5428 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5432 TALLOC_CTX *ctx = talloc_tos();
5433 const char *cservername = canon_servername(servername);
5436 memset(&nullstr, '\0', sizeof(fstring));
5438 info->version=driver.info_3->cversion;
5440 init_unistr( &info->name, driver.info_3->name );
5441 init_unistr( &info->architecture, driver.info_3->environment );
5443 if (strlen(driver.info_3->driverpath)) {
5444 temp = talloc_asprintf(ctx,
5447 driver.info_3->driverpath);
5448 init_unistr( &info->driverpath, temp );
5450 init_unistr( &info->driverpath, "" );
5453 if (strlen(driver.info_3->datafile)) {
5454 temp = talloc_asprintf(ctx,
5457 driver.info_3->datafile);
5458 init_unistr( &info->datafile, temp );
5460 init_unistr( &info->datafile, "" );
5463 if (strlen(driver.info_3->configfile)) {
5464 temp = talloc_asprintf(ctx,
5467 driver.info_3->configfile);
5468 init_unistr( &info->configfile, temp );
5470 init_unistr( &info->configfile, "" );
5473 if (strlen(driver.info_3->helpfile)) {
5474 temp = talloc_asprintf(ctx,
5477 driver.info_3->helpfile);
5478 init_unistr( &info->helpfile, temp );
5480 init_unistr( &info->helpfile, "" );
5483 init_unistr( &info->monitorname, driver.info_3->monitorname );
5484 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5486 info->dependentfiles = NULL;
5487 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5489 info->previousdrivernames=NULL;
5490 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5492 info->driver_date=0;
5495 info->driver_version_low=0;
5496 info->driver_version_high=0;
5498 init_unistr( &info->mfgname, "");
5499 init_unistr( &info->oem_url, "");
5500 init_unistr( &info->hardware_id, "");
5501 init_unistr( &info->provider, "");
5504 /********************************************************************
5505 * construct_printer_info_6
5506 * fill a printer_info_6 struct
5507 ********************************************************************/
5509 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5510 const char *servername, fstring architecture, uint32 version)
5512 NT_PRINTER_INFO_LEVEL *printer = NULL;
5513 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5516 ZERO_STRUCT(driver);
5518 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5520 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5522 if (!W_ERROR_IS_OK(status))
5523 return WERR_INVALID_PRINTER_NAME;
5525 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5527 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5529 if (!W_ERROR_IS_OK(status))
5532 * Is this a W2k client ?
5536 free_a_printer(&printer,2);
5537 return WERR_UNKNOWN_PRINTER_DRIVER;
5540 /* Yes - try again with a WinNT driver. */
5542 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5543 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5544 if (!W_ERROR_IS_OK(status)) {
5545 free_a_printer(&printer,2);
5546 return WERR_UNKNOWN_PRINTER_DRIVER;
5550 fill_printer_driver_info_6(info, driver, servername);
5552 free_a_printer(&printer,2);
5553 free_a_printer_driver(driver, 3);
5558 /****************************************************************************
5559 ****************************************************************************/
5561 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5563 SAFE_FREE(info->dependentfiles);
5566 /****************************************************************************
5567 ****************************************************************************/
5569 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5571 SAFE_FREE(info->dependentfiles);
5574 /****************************************************************************
5575 ****************************************************************************/
5577 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5579 DRIVER_INFO_1 *info=NULL;
5582 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5585 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5586 if (!W_ERROR_IS_OK(result))
5589 /* check the required size. */
5590 *needed += spoolss_size_printer_driver_info_1(info);
5592 if (*needed > offered) {
5593 result = WERR_INSUFFICIENT_BUFFER;
5597 if (!rpcbuf_alloc_size(buffer, *needed)) {
5598 result = WERR_NOMEM;
5602 /* fill the buffer with the structures */
5603 smb_io_printer_driver_info_1("", buffer, info, 0);
5612 /****************************************************************************
5613 ****************************************************************************/
5615 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5617 DRIVER_INFO_2 *info=NULL;
5620 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5623 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5624 if (!W_ERROR_IS_OK(result))
5627 /* check the required size. */
5628 *needed += spoolss_size_printer_driver_info_2(info);
5630 if (*needed > offered) {
5631 result = WERR_INSUFFICIENT_BUFFER;
5635 if (!rpcbuf_alloc_size(buffer, *needed)) {
5636 result = WERR_NOMEM;
5640 /* fill the buffer with the structures */
5641 smb_io_printer_driver_info_2("", buffer, info, 0);
5650 /****************************************************************************
5651 ****************************************************************************/
5653 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5660 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5661 if (!W_ERROR_IS_OK(result))
5664 /* check the required size. */
5665 *needed += spoolss_size_printer_driver_info_3(&info);
5667 if (*needed > offered) {
5668 result = WERR_INSUFFICIENT_BUFFER;
5672 if (!rpcbuf_alloc_size(buffer, *needed)) {
5673 result = WERR_NOMEM;
5677 /* fill the buffer with the structures */
5678 smb_io_printer_driver_info_3("", buffer, &info, 0);
5681 free_printer_driver_info_3(&info);
5686 /****************************************************************************
5687 ****************************************************************************/
5689 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5696 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5697 if (!W_ERROR_IS_OK(result))
5700 /* check the required size. */
5701 *needed += spoolss_size_printer_driver_info_6(&info);
5703 if (*needed > offered) {
5704 result = WERR_INSUFFICIENT_BUFFER;
5708 if (!rpcbuf_alloc_size(buffer, *needed)) {
5709 result = WERR_NOMEM;
5713 /* fill the buffer with the structures */
5714 smb_io_printer_driver_info_6("", buffer, &info, 0);
5717 free_printer_driver_info_6(&info);
5722 /****************************************************************************
5723 ****************************************************************************/
5725 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5727 POLICY_HND *handle = &q_u->handle;
5728 UNISTR2 *uni_arch = &q_u->architecture;
5729 uint32 level = q_u->level;
5730 uint32 clientmajorversion = q_u->clientmajorversion;
5731 RPC_BUFFER *buffer = NULL;
5732 uint32 offered = q_u->offered;
5733 uint32 *needed = &r_u->needed;
5734 uint32 *servermajorversion = &r_u->servermajorversion;
5735 uint32 *serverminorversion = &r_u->serverminorversion;
5736 Printer_entry *printer;
5739 fstring architecture;
5742 /* that's an [in out] buffer */
5744 if (!q_u->buffer && (offered!=0)) {
5745 return WERR_INVALID_PARAM;
5748 if (offered > MAX_RPC_DATA_SIZE) {
5749 return WERR_INVALID_PARAM;
5752 rpcbuf_move(q_u->buffer, &r_u->buffer);
5753 buffer = r_u->buffer;
5755 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5757 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5758 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5759 return WERR_INVALID_PRINTER_NAME;
5763 *servermajorversion = 0;
5764 *serverminorversion = 0;
5766 fstrcpy(servername, get_server_name( printer ));
5767 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5769 if (!get_printer_snum(p, handle, &snum, NULL))
5774 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5776 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5778 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5780 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5783 /* apparently this call is the equivalent of
5784 EnumPrinterDataEx() for the DsDriver key */
5789 return WERR_UNKNOWN_LEVEL;
5793 /****************************************************************
5794 _spoolss_StartPagePrinter
5795 ****************************************************************/
5797 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5798 struct spoolss_StartPagePrinter *r)
5800 POLICY_HND *handle = r->in.handle;
5802 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5805 DEBUG(3,("_spoolss_StartPagePrinter: "
5806 "Error in startpageprinter printer handle\n"));
5810 Printer->page_started=True;
5814 /****************************************************************
5815 _spoolss_EndPagePrinter
5816 ****************************************************************/
5818 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5819 struct spoolss_EndPagePrinter *r)
5821 POLICY_HND *handle = r->in.handle;
5824 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5827 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5828 OUR_HANDLE(handle)));
5832 if (!get_printer_snum(p, handle, &snum, NULL))
5835 Printer->page_started=False;
5836 print_job_endpage(snum, Printer->jobid);
5841 /****************************************************************
5842 _spoolss_StartDocPrinter
5843 ****************************************************************/
5845 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5846 struct spoolss_StartDocPrinter *r)
5848 POLICY_HND *handle = r->in.handle;
5849 uint32_t *jobid = r->out.job_id;
5850 struct spoolss_DocumentInfo1 *info_1;
5852 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5855 DEBUG(2,("_spoolss_StartDocPrinter: "
5856 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5860 if (r->in.level != 1) {
5861 return WERR_UNKNOWN_LEVEL;
5864 info_1 = r->in.info.info1;
5867 * a nice thing with NT is it doesn't listen to what you tell it.
5868 * when asked to send _only_ RAW datas, it tries to send datas
5871 * So I add checks like in NT Server ...
5874 if (info_1->datatype) {
5875 if (strcmp(info_1->datatype, "RAW") != 0) {
5877 return WERR_INVALID_DATATYPE;
5881 /* get the share number of the printer */
5882 if (!get_printer_snum(p, handle, &snum, NULL)) {
5886 Printer->jobid = print_job_start(p->server_info, snum,
5887 CONST_DISCARD(char *,info_1->document_name),
5888 Printer->nt_devmode);
5890 /* An error occured in print_job_start() so return an appropriate
5893 if (Printer->jobid == -1) {
5894 return map_werror_from_unix(errno);
5897 Printer->document_started=True;
5898 (*jobid) = Printer->jobid;
5903 /****************************************************************
5904 _spoolss_EndDocPrinter
5905 ****************************************************************/
5907 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5908 struct spoolss_EndDocPrinter *r)
5910 POLICY_HND *handle = r->in.handle;
5912 return _spoolss_enddocprinter_internal(p, handle);
5915 /****************************************************************
5916 _spoolss_WritePrinter
5917 ****************************************************************/
5919 WERROR _spoolss_WritePrinter(pipes_struct *p,
5920 struct spoolss_WritePrinter *r)
5922 POLICY_HND *handle = r->in.handle;
5923 uint32 buffer_size = r->in._data_size;
5924 uint8 *buffer = r->in.data.data;
5925 uint32 *buffer_written = &r->in._data_size;
5927 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5930 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5931 OUR_HANDLE(handle)));
5932 *r->out.num_written = r->in._data_size;
5936 if (!get_printer_snum(p, handle, &snum, NULL))
5939 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5940 (SMB_OFF_T)-1, (size_t)buffer_size);
5941 if (*buffer_written == (uint32)-1) {
5942 *r->out.num_written = 0;
5943 if (errno == ENOSPC)
5944 return WERR_NO_SPOOL_SPACE;
5946 return WERR_ACCESS_DENIED;
5949 *r->out.num_written = r->in._data_size;
5954 /********************************************************************
5955 * api_spoolss_getprinter
5956 * called from the spoolss dispatcher
5958 ********************************************************************/
5960 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5964 WERROR errcode = WERR_BADFUNC;
5965 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5968 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5972 if (!get_printer_snum(p, handle, &snum, NULL))
5976 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5977 if (print_queue_pause(p->server_info, snum, &errcode)) {
5981 case SPOOLSS_PRINTER_CONTROL_RESUME:
5982 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5983 if (print_queue_resume(p->server_info, snum, &errcode)) {
5987 case SPOOLSS_PRINTER_CONTROL_PURGE:
5988 if (print_queue_purge(p->server_info, snum, &errcode)) {
5993 return WERR_UNKNOWN_LEVEL;
6000 /****************************************************************
6001 _spoolss_AbortPrinter
6002 * From MSDN: "Deletes printer's spool file if printer is configured
6004 ****************************************************************/
6006 WERROR _spoolss_AbortPrinter(pipes_struct *p,
6007 struct spoolss_AbortPrinter *r)
6009 POLICY_HND *handle = r->in.handle;
6010 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6012 WERROR errcode = WERR_OK;
6015 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6016 OUR_HANDLE(handle)));
6020 if (!get_printer_snum(p, handle, &snum, NULL))
6023 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6028 /********************************************************************
6029 * called by spoolss_api_setprinter
6030 * when updating a printer description
6031 ********************************************************************/
6033 static WERROR update_printer_sec(POLICY_HND *handle,
6034 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6036 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6040 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6042 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6043 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6044 OUR_HANDLE(handle)));
6046 result = WERR_BADFID;
6051 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6052 result = WERR_INVALID_PARAM;
6056 /* Check the user has permissions to change the security
6057 descriptor. By experimentation with two NT machines, the user
6058 requires Full Access to the printer to change security
6061 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6062 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6063 result = WERR_ACCESS_DENIED;
6067 /* NT seems to like setting the security descriptor even though
6068 nothing may have actually changed. */
6070 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6071 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6072 result = WERR_BADFID;
6076 if (DEBUGLEVEL >= 10) {
6080 the_acl = old_secdesc_ctr->sd->dacl;
6081 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6082 PRINTERNAME(snum), the_acl->num_aces));
6084 for (i = 0; i < the_acl->num_aces; i++) {
6085 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6086 &the_acl->aces[i].trustee),
6087 the_acl->aces[i].access_mask));
6090 the_acl = secdesc_ctr->sd->dacl;
6093 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6094 PRINTERNAME(snum), the_acl->num_aces));
6096 for (i = 0; i < the_acl->num_aces; i++) {
6097 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6098 &the_acl->aces[i].trustee),
6099 the_acl->aces[i].access_mask));
6102 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6106 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6107 if (!new_secdesc_ctr) {
6108 result = WERR_NOMEM;
6112 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6117 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6124 /********************************************************************
6125 Canonicalize printer info from a client
6127 ATTN: It does not matter what we set the servername to hear
6128 since we do the necessary work in get_a_printer() to set it to
6129 the correct value based on what the client sent in the
6130 _spoolss_open_printer_ex().
6131 ********************************************************************/
6133 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6135 fstring printername;
6138 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6139 "portname=%s drivername=%s comment=%s location=%s\n",
6140 info->servername, info->printername, info->sharename,
6141 info->portname, info->drivername, info->comment, info->location));
6143 /* we force some elements to "correct" values */
6144 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6145 fstrcpy(info->sharename, lp_servicename(snum));
6147 /* check to see if we allow printername != sharename */
6149 if ( lp_force_printername(snum) ) {
6150 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6151 global_myname(), info->sharename );
6154 /* make sure printername is in \\server\printername format */
6156 fstrcpy( printername, info->printername );
6158 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6159 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6163 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6164 global_myname(), p );
6167 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6168 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6175 /****************************************************************************
6176 ****************************************************************************/
6178 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6180 char *cmd = lp_addport_cmd();
6181 char *command = NULL;
6183 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6184 bool is_print_op = False;
6187 return WERR_ACCESS_DENIED;
6190 command = talloc_asprintf(ctx,
6191 "%s \"%s\" \"%s\"", cmd, portname, uri );
6197 is_print_op = user_has_privileges( token, &se_printop );
6199 DEBUG(10,("Running [%s]\n", command));
6201 /********* BEGIN SePrintOperatorPrivilege **********/
6206 ret = smbrun(command, NULL);
6211 /********* END SePrintOperatorPrivilege **********/
6213 DEBUGADD(10,("returned [%d]\n", ret));
6215 TALLOC_FREE(command);
6218 return WERR_ACCESS_DENIED;
6224 /****************************************************************************
6225 ****************************************************************************/
6227 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6229 char *cmd = lp_addprinter_cmd();
6231 char *command = NULL;
6235 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6236 bool is_print_op = False;
6237 char *remote_machine = talloc_strdup(ctx, "%m");
6239 if (!remote_machine) {
6242 remote_machine = talloc_sub_basic(ctx,
6243 current_user_info.smb_name,
6244 current_user_info.domain,
6246 if (!remote_machine) {
6250 command = talloc_asprintf(ctx,
6251 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6252 cmd, printer->info_2->printername, printer->info_2->sharename,
6253 printer->info_2->portname, printer->info_2->drivername,
6254 printer->info_2->location, printer->info_2->comment, remote_machine);
6260 is_print_op = user_has_privileges( token, &se_printop );
6262 DEBUG(10,("Running [%s]\n", command));
6264 /********* BEGIN SePrintOperatorPrivilege **********/
6269 if ( (ret = smbrun(command, &fd)) == 0 ) {
6270 /* Tell everyone we updated smb.conf. */
6271 message_send_all(smbd_messaging_context(),
6272 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6278 /********* END SePrintOperatorPrivilege **********/
6280 DEBUGADD(10,("returned [%d]\n", ret));
6282 TALLOC_FREE(command);
6283 TALLOC_FREE(remote_machine);
6291 /* reload our services immediately */
6292 reload_services( False );
6295 /* Get lines and convert them back to dos-codepage */
6296 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6297 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6300 /* Set the portname to what the script says the portname should be. */
6301 /* but don't require anything to be return from the script exit a good error code */
6304 /* Set the portname to what the script says the portname should be. */
6305 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6306 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6309 TALLOC_FREE(qlines);
6314 /********************************************************************
6315 * Called by spoolss_api_setprinter
6316 * when updating a printer description.
6317 ********************************************************************/
6319 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6320 struct spoolss_SetPrinterInfoCtr *info_ctr,
6321 struct spoolss_DeviceMode *devmode)
6324 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6325 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6330 DEBUG(8,("update_printer\n"));
6335 result = WERR_BADFID;
6339 if (!get_printer_snum(p, handle, &snum, NULL)) {
6340 result = WERR_BADFID;
6344 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6345 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6346 result = WERR_BADFID;
6350 DEBUGADD(8,("Converting info_2 struct\n"));
6353 * convert_printer_info converts the incoming
6354 * info from the client and overwrites the info
6355 * just read from the tdb in the pointer 'printer'.
6358 if (!convert_printer_info_new(info_ctr, printer)) {
6359 result = WERR_NOMEM;
6364 /* we have a valid devmode
6365 convert it and link it*/
6367 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6368 if (!convert_devicemode_new(printer->info_2->printername,
6370 &printer->info_2->devmode)) {
6371 result = WERR_NOMEM;
6376 /* Do sanity check on the requested changes for Samba */
6378 if (!check_printer_ok(printer->info_2, snum)) {
6379 result = WERR_INVALID_PARAM;
6383 /* FIXME!!! If the driver has changed we really should verify that
6384 it is installed before doing much else --jerry */
6386 /* Check calling user has permission to update printer description */
6388 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6389 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6390 result = WERR_ACCESS_DENIED;
6394 /* Call addprinter hook */
6395 /* Check changes to see if this is really needed */
6397 if ( *lp_addprinter_cmd()
6398 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6399 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6400 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6401 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6403 /* add_printer_hook() will call reload_services() */
6405 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6407 result = WERR_ACCESS_DENIED;
6413 * When a *new* driver is bound to a printer, the drivername is used to
6414 * lookup previously saved driver initialization info, which is then
6415 * bound to the printer, simulating what happens in the Windows arch.
6417 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6419 if (!set_driver_init(printer, 2))
6421 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6422 printer->info_2->drivername));
6425 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6426 printer->info_2->drivername));
6428 notify_printer_driver(snum, printer->info_2->drivername);
6432 * flag which changes actually occured. This is a small subset of
6433 * all the possible changes. We also have to update things in the
6437 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6438 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6439 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6440 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6442 notify_printer_comment(snum, printer->info_2->comment);
6445 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6446 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6447 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6448 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6450 notify_printer_sharename(snum, printer->info_2->sharename);
6453 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6456 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6459 pname = printer->info_2->printername;
6462 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6463 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6464 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6466 notify_printer_printername( snum, pname );
6469 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6470 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6471 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6472 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6474 notify_printer_port(snum, printer->info_2->portname);
6477 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6478 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6479 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6480 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6482 notify_printer_location(snum, printer->info_2->location);
6485 /* here we need to update some more DsSpooler keys */
6486 /* uNCName, serverName, shortServerName */
6488 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6489 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6490 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6491 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6492 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6494 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6495 global_myname(), printer->info_2->sharename );
6496 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6497 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6498 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6500 /* Update printer info */
6501 result = mod_a_printer(printer, 2);
6504 free_a_printer(&printer, 2);
6505 free_a_printer(&old_printer, 2);
6511 /****************************************************************************
6512 ****************************************************************************/
6513 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6514 struct spoolss_SetPrinterInfo7 *info7)
6518 Printer_entry *Printer;
6520 if ( lp_security() != SEC_ADS ) {
6521 return WERR_UNKNOWN_LEVEL;
6524 Printer = find_printer_index_by_hnd(p, handle);
6526 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6531 if (!get_printer_snum(p, handle, &snum, NULL))
6534 nt_printer_publish(Printer, snum, info7->action);
6538 return WERR_UNKNOWN_LEVEL;
6542 /****************************************************************
6544 ****************************************************************/
6546 WERROR _spoolss_SetPrinter(pipes_struct *p,
6547 struct spoolss_SetPrinter *r)
6549 POLICY_HND *handle = r->in.handle;
6552 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6555 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6556 OUR_HANDLE(handle)));
6560 /* check the level */
6561 switch (r->in.info_ctr->level) {
6563 return control_printer(handle, r->in.command, p);
6565 result = update_printer(p, handle,
6567 r->in.devmode_ctr->devmode);
6568 if (!W_ERROR_IS_OK(result))
6570 if (r->in.secdesc_ctr->sd)
6571 result = update_printer_sec(handle, p,
6575 return update_printer_sec(handle, p,
6578 return publish_or_unpublish_printer(p, handle,
6579 r->in.info_ctr->info.info7);
6581 return WERR_UNKNOWN_LEVEL;
6585 /****************************************************************
6586 _spoolss_FindClosePrinterNotify
6587 ****************************************************************/
6589 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6590 struct spoolss_FindClosePrinterNotify *r)
6592 POLICY_HND *handle = r->in.handle;
6593 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6596 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6597 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6601 if (Printer->notify.client_connected==True) {
6604 if ( Printer->printer_type == SPLHND_SERVER)
6606 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6607 !get_printer_snum(p, handle, &snum, NULL) )
6610 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6613 Printer->notify.flags=0;
6614 Printer->notify.options=0;
6615 Printer->notify.localmachine[0]='\0';
6616 Printer->notify.printerlocal=0;
6617 if (Printer->notify.option)
6618 free_spool_notify_option(&Printer->notify.option);
6619 Printer->notify.client_connected=False;
6624 /****************************************************************
6626 ****************************************************************/
6628 WERROR _spoolss_AddJob(pipes_struct *p,
6629 struct spoolss_AddJob *r)
6631 if (!r->in.buffer && (r->in.offered != 0)) {
6632 return WERR_INVALID_PARAM;
6635 /* this is what a NT server returns for AddJob. AddJob must fail on
6636 * non-local printers */
6638 return WERR_INVALID_PARAM;
6641 /****************************************************************************
6642 ****************************************************************************/
6644 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6645 int position, int snum,
6646 const NT_PRINTER_INFO_LEVEL *ntprinter)
6650 t=gmtime(&queue->time);
6652 job_info->jobid=queue->job;
6653 init_unistr(&job_info->printername, lp_servicename(snum));
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->datatype, "RAW");
6658 init_unistr(&job_info->text_status, "");
6659 job_info->status=nt_printj_status(queue->status);
6660 job_info->priority=queue->priority;
6661 job_info->position=position;
6662 job_info->totalpages=queue->page_count;
6663 job_info->pagesprinted=0;
6665 make_systemtime(&job_info->submitted, t);
6668 /****************************************************************************
6669 ****************************************************************************/
6671 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6672 int position, int snum,
6673 const NT_PRINTER_INFO_LEVEL *ntprinter,
6674 DEVICEMODE *devmode)
6678 t=gmtime(&queue->time);
6680 job_info->jobid=queue->job;
6682 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6684 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6685 init_unistr(&job_info->username, queue->fs_user);
6686 init_unistr(&job_info->document, queue->fs_file);
6687 init_unistr(&job_info->notifyname, queue->fs_user);
6688 init_unistr(&job_info->datatype, "RAW");
6689 init_unistr(&job_info->printprocessor, "winprint");
6690 init_unistr(&job_info->parameters, "");
6691 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6692 init_unistr(&job_info->text_status, "");
6694 /* and here the security descriptor */
6696 job_info->status=nt_printj_status(queue->status);
6697 job_info->priority=queue->priority;
6698 job_info->position=position;
6699 job_info->starttime=0;
6700 job_info->untiltime=0;
6701 job_info->totalpages=queue->page_count;
6702 job_info->size=queue->size;
6703 make_systemtime(&(job_info->submitted), t);
6704 job_info->timeelapsed=0;
6705 job_info->pagesprinted=0;
6707 job_info->devmode = devmode;
6712 /****************************************************************************
6713 Enumjobs at level 1.
6714 ****************************************************************************/
6716 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6717 const NT_PRINTER_INFO_LEVEL *ntprinter,
6718 RPC_BUFFER *buffer, uint32 offered,
6719 uint32 *needed, uint32 *returned)
6723 WERROR result = WERR_OK;
6725 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6731 for (i=0; i<*returned; i++)
6732 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6734 /* check the required size. */
6735 for (i=0; i<*returned; i++)
6736 (*needed) += spoolss_size_job_info_1(&info[i]);
6738 if (*needed > offered) {
6739 result = WERR_INSUFFICIENT_BUFFER;
6743 if (!rpcbuf_alloc_size(buffer, *needed)) {
6744 result = WERR_NOMEM;
6748 /* fill the buffer with the structures */
6749 for (i=0; i<*returned; i++)
6750 smb_io_job_info_1("", buffer, &info[i], 0);
6756 if ( !W_ERROR_IS_OK(result) )
6762 /****************************************************************************
6763 Enumjobs at level 2.
6764 ****************************************************************************/
6766 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6767 const NT_PRINTER_INFO_LEVEL *ntprinter,
6768 RPC_BUFFER *buffer, uint32 offered,
6769 uint32 *needed, uint32 *returned)
6771 JOB_INFO_2 *info = NULL;
6773 WERROR result = WERR_OK;
6774 DEVICEMODE *devmode = NULL;
6776 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6781 /* this should not be a failure condition if the devmode is NULL */
6783 devmode = construct_dev_mode(lp_const_servicename(snum));
6785 for (i=0; i<*returned; i++)
6786 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6788 /* check the required size. */
6789 for (i=0; i<*returned; i++)
6790 (*needed) += spoolss_size_job_info_2(&info[i]);
6792 if (*needed > offered) {
6793 result = WERR_INSUFFICIENT_BUFFER;
6797 if (!rpcbuf_alloc_size(buffer, *needed)) {
6798 result = WERR_NOMEM;
6802 /* fill the buffer with the structures */
6803 for (i=0; i<*returned; i++)
6804 smb_io_job_info_2("", buffer, &info[i], 0);
6807 free_devmode(devmode);
6810 if ( !W_ERROR_IS_OK(result) )
6817 /****************************************************************************
6819 ****************************************************************************/
6821 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6823 POLICY_HND *handle = &q_u->handle;
6824 uint32 level = q_u->level;
6825 RPC_BUFFER *buffer = NULL;
6826 uint32 offered = q_u->offered;
6827 uint32 *needed = &r_u->needed;
6828 uint32 *returned = &r_u->returned;
6830 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6832 print_status_struct prt_status;
6833 print_queue_struct *queue=NULL;
6835 /* that's an [in out] buffer */
6837 if (!q_u->buffer && (offered!=0)) {
6838 return WERR_INVALID_PARAM;
6841 if (offered > MAX_RPC_DATA_SIZE) {
6842 return WERR_INVALID_PARAM;
6845 rpcbuf_move(q_u->buffer, &r_u->buffer);
6846 buffer = r_u->buffer;
6848 DEBUG(4,("_spoolss_enumjobs\n"));
6853 /* lookup the printer snum and tdb entry */
6855 if (!get_printer_snum(p, handle, &snum, NULL))
6858 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6859 if ( !W_ERROR_IS_OK(wret) )
6862 *returned = print_queue_status(snum, &queue, &prt_status);
6863 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6865 if (*returned == 0) {
6867 free_a_printer(&ntprinter, 2);
6873 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6876 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6880 wret = WERR_UNKNOWN_LEVEL;
6885 free_a_printer( &ntprinter, 2 );
6889 /****************************************************************
6890 _spoolss_ScheduleJob
6891 ****************************************************************/
6893 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6894 struct spoolss_ScheduleJob *r)
6899 /****************************************************************
6901 ****************************************************************/
6903 WERROR _spoolss_SetJob(pipes_struct *p,
6904 struct spoolss_SetJob *r)
6906 POLICY_HND *handle = r->in.handle;
6907 uint32 jobid = r->in.job_id;
6908 uint32 command = r->in.command;
6911 WERROR errcode = WERR_BADFUNC;
6913 if (!get_printer_snum(p, handle, &snum, NULL)) {
6917 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6918 return WERR_INVALID_PRINTER_NAME;
6922 case SPOOLSS_JOB_CONTROL_CANCEL:
6923 case SPOOLSS_JOB_CONTROL_DELETE:
6924 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6928 case SPOOLSS_JOB_CONTROL_PAUSE:
6929 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6933 case SPOOLSS_JOB_CONTROL_RESTART:
6934 case SPOOLSS_JOB_CONTROL_RESUME:
6935 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6940 return WERR_UNKNOWN_LEVEL;
6946 /****************************************************************************
6947 Enumerates all printer drivers at level 1.
6948 ****************************************************************************/
6950 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6955 fstring *list = NULL;
6956 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6957 DRIVER_INFO_1 *driver_info_1=NULL;
6958 WERROR result = WERR_OK;
6962 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6964 ndrivers=get_ntdrivers(&list, architecture, version);
6965 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6967 if(ndrivers == -1) {
6968 SAFE_FREE(driver_info_1);
6973 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6974 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6980 for (i=0; i<ndrivers; i++) {
6982 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6983 ZERO_STRUCT(driver);
6984 status = get_a_printer_driver(&driver, 3, list[i],
6985 architecture, version);
6986 if (!W_ERROR_IS_OK(status)) {
6988 SAFE_FREE(driver_info_1);
6991 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6992 free_a_printer_driver(driver, 3);
6995 *returned+=ndrivers;
6999 /* check the required size. */
7000 for (i=0; i<*returned; i++) {
7001 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7002 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
7005 if (*needed > offered) {
7006 result = WERR_INSUFFICIENT_BUFFER;
7010 if (!rpcbuf_alloc_size(buffer, *needed)) {
7011 result = WERR_NOMEM;
7015 /* fill the buffer with the driver structures */
7016 for (i=0; i<*returned; i++) {
7017 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7018 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
7022 SAFE_FREE(driver_info_1);
7024 if ( !W_ERROR_IS_OK(result) )
7030 /****************************************************************************
7031 Enumerates all printer drivers at level 2.
7032 ****************************************************************************/
7034 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7039 fstring *list = NULL;
7040 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7041 DRIVER_INFO_2 *driver_info_2=NULL;
7042 WERROR result = WERR_OK;
7046 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7048 ndrivers=get_ntdrivers(&list, architecture, version);
7049 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7051 if(ndrivers == -1) {
7052 SAFE_FREE(driver_info_2);
7057 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7058 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7064 for (i=0; i<ndrivers; i++) {
7067 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7068 ZERO_STRUCT(driver);
7069 status = get_a_printer_driver(&driver, 3, list[i],
7070 architecture, version);
7071 if (!W_ERROR_IS_OK(status)) {
7073 SAFE_FREE(driver_info_2);
7076 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7077 free_a_printer_driver(driver, 3);
7080 *returned+=ndrivers;
7084 /* check the required size. */
7085 for (i=0; i<*returned; i++) {
7086 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7087 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7090 if (*needed > offered) {
7091 result = WERR_INSUFFICIENT_BUFFER;
7095 if (!rpcbuf_alloc_size(buffer, *needed)) {
7096 result = WERR_NOMEM;
7100 /* fill the buffer with the form structures */
7101 for (i=0; i<*returned; i++) {
7102 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7103 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7107 SAFE_FREE(driver_info_2);
7109 if ( !W_ERROR_IS_OK(result) )
7115 /****************************************************************************
7116 Enumerates all printer drivers at level 3.
7117 ****************************************************************************/
7119 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7124 fstring *list = NULL;
7125 DRIVER_INFO_3 *driver_info_3=NULL;
7126 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7127 WERROR result = WERR_OK;
7131 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7133 ndrivers=get_ntdrivers(&list, architecture, version);
7134 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7136 if(ndrivers == -1) {
7137 SAFE_FREE(driver_info_3);
7142 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7143 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7149 for (i=0; i<ndrivers; i++) {
7152 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7153 ZERO_STRUCT(driver);
7154 status = get_a_printer_driver(&driver, 3, list[i],
7155 architecture, version);
7156 if (!W_ERROR_IS_OK(status)) {
7158 SAFE_FREE(driver_info_3);
7161 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7162 free_a_printer_driver(driver, 3);
7165 *returned+=ndrivers;
7169 /* check the required size. */
7170 for (i=0; i<*returned; i++) {
7171 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7172 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7175 if (*needed > offered) {
7176 result = WERR_INSUFFICIENT_BUFFER;
7180 if (!rpcbuf_alloc_size(buffer, *needed)) {
7181 result = WERR_NOMEM;
7185 /* fill the buffer with the driver structures */
7186 for (i=0; i<*returned; i++) {
7187 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7188 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7192 for (i=0; i<*returned; i++) {
7193 SAFE_FREE(driver_info_3[i].dependentfiles);
7196 SAFE_FREE(driver_info_3);
7198 if ( !W_ERROR_IS_OK(result) )
7204 /****************************************************************************
7205 Enumerates all printer drivers.
7206 ****************************************************************************/
7208 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7210 uint32 level = q_u->level;
7211 RPC_BUFFER *buffer = NULL;
7212 uint32 offered = q_u->offered;
7213 uint32 *needed = &r_u->needed;
7214 uint32 *returned = &r_u->returned;
7215 const char *cservername;
7217 fstring architecture;
7219 /* that's an [in out] buffer */
7221 if (!q_u->buffer && (offered!=0)) {
7222 return WERR_INVALID_PARAM;
7225 if (offered > MAX_RPC_DATA_SIZE) {
7226 return WERR_INVALID_PARAM;
7229 rpcbuf_move(q_u->buffer, &r_u->buffer);
7230 buffer = r_u->buffer;
7232 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7237 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7238 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7240 cservername = canon_servername(servername);
7242 if (!is_myname_or_ipaddr(cservername))
7243 return WERR_UNKNOWN_PRINTER_DRIVER;
7247 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7249 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7251 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7253 return WERR_UNKNOWN_LEVEL;
7257 /****************************************************************************
7258 ****************************************************************************/
7260 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7262 form->flag=list->flag;
7263 init_unistr(&form->name, list->name);
7264 form->width=list->width;
7265 form->length=list->length;
7266 form->left=list->left;
7267 form->top=list->top;
7268 form->right=list->right;
7269 form->bottom=list->bottom;
7272 /****************************************************************************
7273 ****************************************************************************/
7275 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7276 struct spoolss_FormInfo1 *form,
7277 nt_forms_struct *list)
7279 form->form_name = talloc_strdup(mem_ctx, list->name);
7280 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7282 form->flags = list->flag;
7283 form->size.width = list->width;
7284 form->size.height = list->length;
7285 form->area.left = list->left;
7286 form->area.top = list->top;
7287 form->area.right = list->right;
7288 form->area.bottom = list->bottom;
7293 /****************************************************************************
7294 ****************************************************************************/
7296 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7298 uint32 level = q_u->level;
7299 RPC_BUFFER *buffer = NULL;
7300 uint32 offered = q_u->offered;
7301 uint32 *needed = &r_u->needed;
7302 uint32 *numofforms = &r_u->numofforms;
7303 uint32 numbuiltinforms;
7305 nt_forms_struct *list=NULL;
7306 nt_forms_struct *builtinlist=NULL;
7311 /* that's an [in out] buffer */
7313 if (!q_u->buffer && (offered!=0) ) {
7314 return WERR_INVALID_PARAM;
7317 if (offered > MAX_RPC_DATA_SIZE) {
7318 return WERR_INVALID_PARAM;
7321 rpcbuf_move(q_u->buffer, &r_u->buffer);
7322 buffer = r_u->buffer;
7324 DEBUG(4,("_spoolss_enumforms\n"));
7325 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7326 DEBUGADD(5,("Info level [%d]\n", level));
7328 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7329 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7330 *numofforms = get_ntforms(&list);
7331 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7332 *numofforms += numbuiltinforms;
7334 if (*numofforms == 0) {
7335 SAFE_FREE(builtinlist);
7337 return WERR_NO_MORE_ITEMS;
7342 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7343 SAFE_FREE(builtinlist);
7349 /* construct the list of form structures */
7350 for (i=0; i<numbuiltinforms; i++) {
7351 DEBUGADD(6,("Filling form number [%d]\n",i));
7352 fill_form_1(&forms_1[i], &builtinlist[i]);
7355 SAFE_FREE(builtinlist);
7357 for (; i<*numofforms; i++) {
7358 DEBUGADD(6,("Filling form number [%d]\n",i));
7359 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7364 /* check the required size. */
7365 for (i=0; i<numbuiltinforms; i++) {
7366 DEBUGADD(6,("adding form [%d]'s size\n",i));
7367 buffer_size += spoolss_size_form_1(&forms_1[i]);
7369 for (; i<*numofforms; i++) {
7370 DEBUGADD(6,("adding form [%d]'s size\n",i));
7371 buffer_size += spoolss_size_form_1(&forms_1[i]);
7374 *needed=buffer_size;
7376 if (*needed > offered) {
7379 return WERR_INSUFFICIENT_BUFFER;
7382 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7388 /* fill the buffer with the form structures */
7389 for (i=0; i<numbuiltinforms; i++) {
7390 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7391 smb_io_form_1("", buffer, &forms_1[i], 0);
7393 for (; i<*numofforms; i++) {
7394 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7395 smb_io_form_1("", buffer, &forms_1[i], 0);
7404 SAFE_FREE(builtinlist);
7405 return WERR_UNKNOWN_LEVEL;
7409 /****************************************************************
7411 ****************************************************************/
7413 WERROR _spoolss_GetForm(pipes_struct *p,
7414 struct spoolss_GetForm *r)
7416 uint32 level = r->in.level;
7417 uint32 offered = r->in.offered;
7418 uint32 *needed = r->out.needed;
7420 nt_forms_struct *list=NULL;
7421 nt_forms_struct builtin_form;
7423 union spoolss_FormInfo info;
7424 struct spoolss_FormInfo1 form_1;
7425 int numofforms=0, i=0;
7427 /* that's an [in out] buffer */
7429 if (!r->in.buffer && (offered!=0)) {
7430 return WERR_INVALID_PARAM;
7433 DEBUG(4,("_spoolss_GetForm\n"));
7434 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7435 DEBUGADD(5,("Info level [%d]\n", level));
7437 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7438 if (!foundBuiltin) {
7439 numofforms = get_ntforms(&list);
7440 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7442 if (numofforms == 0)
7446 ZERO_STRUCT(form_1);
7451 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7454 /* Check if the requested name is in the list of form structures */
7455 for (i=0; i<numofforms; i++) {
7457 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7458 list[i].name, r->in.form_name));
7460 if (strequal(r->in.form_name, list[i].name)) {
7461 DEBUGADD(6,("Found form %s number [%d]\n",
7462 r->in.form_name, i));
7463 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7469 if (i == numofforms) {
7473 /* check the required size. */
7475 info.info1 = form_1;
7477 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7479 if (*needed > offered) {
7481 return WERR_INSUFFICIENT_BUFFER;
7484 r->out.info->info1 = form_1;
7486 /* fill the buffer with the form structures */
7487 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7488 r->in.form_name, i));
7494 return WERR_UNKNOWN_LEVEL;
7498 /****************************************************************************
7499 ****************************************************************************/
7501 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7503 init_unistr(&port->port_name, name);
7506 /****************************************************************************
7507 TODO: This probably needs distinguish between TCP/IP and Local ports
7509 ****************************************************************************/
7511 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7513 init_unistr(&port->port_name, name);
7514 init_unistr(&port->monitor_name, "Local Monitor");
7515 init_unistr(&port->description, SPL_LOCAL_PORT );
7516 port->port_type=PORT_TYPE_WRITE;
7521 /****************************************************************************
7522 wrapper around the enumer ports command
7523 ****************************************************************************/
7525 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7527 char *cmd = lp_enumports_cmd();
7528 char **qlines = NULL;
7529 char *command = NULL;
7537 /* if no hook then just fill in the default port */
7540 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7543 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7544 TALLOC_FREE(qlines);
7551 /* we have a valid enumport command */
7553 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7558 DEBUG(10,("Running [%s]\n", command));
7559 ret = smbrun(command, &fd);
7560 DEBUG(10,("Returned [%d]\n", ret));
7561 TALLOC_FREE(command);
7566 return WERR_ACCESS_DENIED;
7570 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7571 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7581 /****************************************************************************
7583 ****************************************************************************/
7585 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7587 PORT_INFO_1 *ports=NULL;
7589 WERROR result = WERR_OK;
7590 char **qlines = NULL;
7593 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7594 if (!W_ERROR_IS_OK(result)) {
7595 TALLOC_FREE(qlines);
7600 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7601 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7602 win_errstr(WERR_NOMEM)));
7603 TALLOC_FREE(qlines);
7607 for (i=0; i<numlines; i++) {
7608 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7609 fill_port_1(&ports[i], qlines[i]);
7612 TALLOC_FREE(qlines);
7614 *returned = numlines;
7616 /* check the required size. */
7617 for (i=0; i<*returned; i++) {
7618 DEBUGADD(6,("adding port [%d]'s size\n", i));
7619 *needed += spoolss_size_port_info_1(&ports[i]);
7622 if (*needed > offered) {
7623 result = WERR_INSUFFICIENT_BUFFER;
7627 if (!rpcbuf_alloc_size(buffer, *needed)) {
7628 result = WERR_NOMEM;
7632 /* fill the buffer with the ports structures */
7633 for (i=0; i<*returned; i++) {
7634 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7635 smb_io_port_1("", buffer, &ports[i], 0);
7641 if ( !W_ERROR_IS_OK(result) )
7647 /****************************************************************************
7649 ****************************************************************************/
7651 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7653 PORT_INFO_2 *ports=NULL;
7655 WERROR result = WERR_OK;
7656 char **qlines = NULL;
7659 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7660 if ( !W_ERROR_IS_OK(result)) {
7661 TALLOC_FREE(qlines);
7666 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7667 TALLOC_FREE(qlines);
7671 for (i=0; i<numlines; i++) {
7672 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7673 fill_port_2(&(ports[i]), qlines[i]);
7677 TALLOC_FREE(qlines);
7679 *returned = numlines;
7681 /* check the required size. */
7682 for (i=0; i<*returned; i++) {
7683 DEBUGADD(6,("adding port [%d]'s size\n", i));
7684 *needed += spoolss_size_port_info_2(&ports[i]);
7687 if (*needed > offered) {
7688 result = WERR_INSUFFICIENT_BUFFER;
7692 if (!rpcbuf_alloc_size(buffer, *needed)) {
7693 result = WERR_NOMEM;
7697 /* fill the buffer with the ports structures */
7698 for (i=0; i<*returned; i++) {
7699 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7700 smb_io_port_2("", buffer, &ports[i], 0);
7706 if ( !W_ERROR_IS_OK(result) )
7712 /****************************************************************************
7714 ****************************************************************************/
7716 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7718 uint32 level = q_u->level;
7719 RPC_BUFFER *buffer = NULL;
7720 uint32 offered = q_u->offered;
7721 uint32 *needed = &r_u->needed;
7722 uint32 *returned = &r_u->returned;
7724 /* that's an [in out] buffer */
7726 if (!q_u->buffer && (offered!=0)) {
7727 return WERR_INVALID_PARAM;
7730 if (offered > MAX_RPC_DATA_SIZE) {
7731 return WERR_INVALID_PARAM;
7734 rpcbuf_move(q_u->buffer, &r_u->buffer);
7735 buffer = r_u->buffer;
7737 DEBUG(4,("_spoolss_enumports\n"));
7744 return enumports_level_1(buffer, offered, needed, returned);
7746 return enumports_level_2(buffer, offered, needed, returned);
7748 return WERR_UNKNOWN_LEVEL;
7752 /****************************************************************************
7753 ****************************************************************************/
7755 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7757 struct spoolss_SetPrinterInfoCtr *info_ctr,
7758 struct spoolss_DeviceMode *devmode,
7759 struct security_descriptor *sec_desc,
7760 struct spoolss_UserLevelCtr *user_ctr,
7763 NT_PRINTER_INFO_LEVEL *printer = NULL;
7766 WERROR err = WERR_OK;
7768 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7769 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7773 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7774 if (!convert_printer_info_new(info_ctr, printer)) {
7775 free_a_printer(&printer, 2);
7779 /* check to see if the printer already exists */
7781 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7782 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7783 printer->info_2->sharename));
7784 free_a_printer(&printer, 2);
7785 return WERR_PRINTER_ALREADY_EXISTS;
7788 /* FIXME!!! smbd should check to see if the driver is installed before
7789 trying to add a printer like this --jerry */
7791 if (*lp_addprinter_cmd() ) {
7792 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7794 free_a_printer(&printer,2);
7795 return WERR_ACCESS_DENIED;
7798 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7799 "smb.conf parameter \"addprinter command\" is defined. This"
7800 "parameter must exist for this call to succeed\n",
7801 printer->info_2->sharename ));
7804 /* use our primary netbios name since get_a_printer() will convert
7805 it to what the client expects on a case by case basis */
7807 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7808 printer->info_2->sharename);
7811 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7812 free_a_printer(&printer,2);
7813 return WERR_ACCESS_DENIED;
7816 /* you must be a printer admin to add a new printer */
7817 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7818 free_a_printer(&printer,2);
7819 return WERR_ACCESS_DENIED;
7823 * Do sanity check on the requested changes for Samba.
7826 if (!check_printer_ok(printer->info_2, snum)) {
7827 free_a_printer(&printer,2);
7828 return WERR_INVALID_PARAM;
7832 * When a printer is created, the drivername bound to the printer is used
7833 * to lookup previously saved driver initialization info, which is then
7834 * bound to the new printer, simulating what happens in the Windows arch.
7839 set_driver_init(printer, 2);
7843 /* A valid devmode was included, convert and link it
7845 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7847 if (!convert_devicemode_new(printer->info_2->printername,
7849 &printer->info_2->devmode))
7853 /* write the ASCII on disk */
7854 err = mod_a_printer(printer, 2);
7855 if (!W_ERROR_IS_OK(err)) {
7856 free_a_printer(&printer,2);
7860 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7861 /* Handle open failed - remove addition. */
7862 del_a_printer(printer->info_2->sharename);
7863 free_a_printer(&printer,2);
7864 return WERR_ACCESS_DENIED;
7867 update_c_setprinter(False);
7868 free_a_printer(&printer,2);
7873 /****************************************************************
7874 _spoolss_AddPrinterEx
7875 ****************************************************************/
7877 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7878 struct spoolss_AddPrinterEx *r)
7880 switch (r->in.info_ctr->level) {
7882 /* we don't handle yet */
7883 /* but I know what to do ... */
7884 return WERR_UNKNOWN_LEVEL;
7886 return spoolss_addprinterex_level_2(p, r->in.server,
7888 r->in.devmode_ctr->devmode,
7889 r->in.secdesc_ctr->sd,
7890 r->in.userlevel_ctr,
7893 return WERR_UNKNOWN_LEVEL;
7897 /****************************************************************************
7898 ****************************************************************************/
7900 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
7902 uint32 level = q_u->level;
7903 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
7904 WERROR err = WERR_OK;
7905 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7906 fstring driver_name;
7909 ZERO_STRUCT(driver);
7911 if (!convert_printer_driver_info(info, &driver, level)) {
7916 DEBUG(5,("Cleaning driver's information\n"));
7917 err = clean_up_driver_struct(p, driver, level);
7918 if (!W_ERROR_IS_OK(err))
7921 DEBUG(5,("Moving driver to final destination\n"));
7922 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7927 if (add_a_printer_driver(driver, level)!=0) {
7928 err = WERR_ACCESS_DENIED;
7934 fstrcpy(driver_name,
7935 driver.info_3->name ? driver.info_3->name : "");
7938 fstrcpy(driver_name,
7939 driver.info_6->name ? driver.info_6->name : "");
7944 * I think this is where he DrvUpgradePrinter() hook would be
7945 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7946 * server. Right now, we just need to send ourselves a message
7947 * to update each printer bound to this driver. --jerry
7950 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7951 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7956 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7957 * decide if the driver init data should be deleted. The rules are:
7958 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7959 * 2) delete init data only if there is no 2k/Xp driver
7960 * 3) always delete init data
7961 * The generalized rule is always use init data from the highest order driver.
7962 * It is necessary to follow the driver install by an initialization step to
7963 * finish off this process.
7966 version = driver.info_3->cversion;
7967 else if (level == 6)
7968 version = driver.info_6->version;
7973 * 9x printer driver - never delete init data
7976 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7981 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7982 * there is no 2k/Xp driver init data for this driver name.
7986 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7988 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7990 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7992 if (!del_driver_init(driver_name))
7993 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
7996 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7998 free_a_printer_driver(driver1,3);
7999 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
8006 * 2k or Xp printer driver - always delete init data
8009 if (!del_driver_init(driver_name))
8010 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
8014 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
8020 free_a_printer_driver(driver, level);
8024 /********************************************************************
8025 * spoolss_addprinterdriverex
8026 ********************************************************************/
8028 WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
8030 SPOOL_Q_ADDPRINTERDRIVER q_u_local;
8031 SPOOL_R_ADDPRINTERDRIVER r_u_local;
8034 * we only support the semantics of AddPrinterDriver()
8035 * i.e. only copy files that are newer than existing ones
8038 if ( q_u->copy_flags != APD_COPY_NEW_FILES )
8039 return WERR_ACCESS_DENIED;
8041 ZERO_STRUCT(q_u_local);
8042 ZERO_STRUCT(r_u_local);
8044 /* just pass the information off to _spoolss_addprinterdriver() */
8045 q_u_local.server_name_ptr = q_u->server_name_ptr;
8046 copy_unistr2(&q_u_local.server_name, &q_u->server_name);
8047 q_u_local.level = q_u->level;
8048 memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
8050 return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
8053 /****************************************************************************
8054 ****************************************************************************/
8056 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
8058 init_unistr(&info->name, name);
8061 /****************************************************************************
8062 ****************************************************************************/
8064 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
8067 char *long_archi = NULL;
8068 char *servername = NULL;
8069 const char *pservername = NULL;
8070 const char *short_archi;
8071 DRIVER_DIRECTORY_1 *info=NULL;
8072 WERROR result = WERR_OK;
8073 TALLOC_CTX *ctx = talloc_tos();
8075 servername = unistr2_to_ascii_talloc(ctx, name);
8079 long_archi = unistr2_to_ascii_talloc(ctx, uni_environment);
8084 pservername = canon_servername(servername);
8086 if ( !is_myname_or_ipaddr(pservername))
8087 return WERR_INVALID_PARAM;
8089 if (!(short_archi = get_short_archi(long_archi)))
8090 return WERR_INVALID_ENVIRONMENT;
8092 if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
8095 path = talloc_asprintf(ctx,
8096 "\\\\%s\\print$\\%s", pservername, short_archi);
8098 result = WERR_NOMEM;
8102 DEBUG(4,("printer driver directory: [%s]\n", path));
8104 fill_driverdir_1(info, path);
8106 *needed += spoolss_size_driverdir_info_1(info);
8108 if (*needed > offered) {
8109 result = WERR_INSUFFICIENT_BUFFER;
8113 if (!rpcbuf_alloc_size(buffer, *needed)) {
8114 result = WERR_NOMEM;
8118 smb_io_driverdir_1("", buffer, info, 0);
8126 /****************************************************************************
8127 ****************************************************************************/
8129 WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
8131 UNISTR2 *name = &q_u->name;
8132 UNISTR2 *uni_environment = &q_u->environment;
8133 uint32 level = q_u->level;
8134 RPC_BUFFER *buffer = NULL;
8135 uint32 offered = q_u->offered;
8136 uint32 *needed = &r_u->needed;
8138 /* that's an [in out] buffer */
8140 if (!q_u->buffer && (offered!=0)) {
8141 return WERR_INVALID_PARAM;
8144 if (offered > MAX_RPC_DATA_SIZE) {
8145 return WERR_INVALID_PARAM;
8148 rpcbuf_move(q_u->buffer, &r_u->buffer);
8149 buffer = r_u->buffer;
8151 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8157 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
8159 return WERR_UNKNOWN_LEVEL;
8163 /****************************************************************************
8164 ****************************************************************************/
8166 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8168 POLICY_HND *handle = &q_u->handle;
8169 uint32 idx = q_u->index;
8170 uint32 in_value_len = q_u->valuesize;
8171 uint32 in_data_len = q_u->datasize;
8172 uint32 *out_max_value_len = &r_u->valuesize;
8173 uint16 **out_value = &r_u->value;
8174 uint32 *out_value_len = &r_u->realvaluesize;
8175 uint32 *out_type = &r_u->type;
8176 uint32 *out_max_data_len = &r_u->datasize;
8177 uint8 **data_out = &r_u->data;
8178 uint32 *out_data_len = &r_u->realdatasize;
8180 NT_PRINTER_INFO_LEVEL *printer = NULL;
8182 uint32 biggest_valuesize;
8183 uint32 biggest_datasize;
8185 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8188 REGISTRY_VALUE *val = NULL;
8189 NT_PRINTER_DATA *p_data;
8190 int i, key_index, num_values;
8195 *out_max_data_len = 0;
8199 DEBUG(5,("spoolss_enumprinterdata\n"));
8202 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8206 if (!get_printer_snum(p,handle, &snum, NULL))
8209 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8210 if (!W_ERROR_IS_OK(result))
8213 p_data = printer->info_2->data;
8214 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8219 * The NT machine wants to know the biggest size of value and data
8221 * cf: MSDN EnumPrinterData remark section
8224 if ( !in_value_len && !in_data_len && (key_index != -1) )
8226 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8228 biggest_valuesize = 0;
8229 biggest_datasize = 0;
8231 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8233 for ( i=0; i<num_values; i++ )
8235 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8237 name_length = strlen(val->valuename);
8238 if ( strlen(val->valuename) > biggest_valuesize )
8239 biggest_valuesize = name_length;
8241 if ( val->size > biggest_datasize )
8242 biggest_datasize = val->size;
8244 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8248 /* the value is an UNICODE string but real_value_size is the length
8249 in bytes including the trailing 0 */
8251 *out_value_len = 2 * (1+biggest_valuesize);
8252 *out_data_len = biggest_datasize;
8254 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8260 * the value len is wrong in NT sp3
8261 * that's the number of bytes not the number of unicode chars
8264 if ( key_index != -1 )
8265 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8270 /* out_value should default to "" or else NT4 has
8271 problems unmarshalling the response */
8273 *out_max_value_len=(in_value_len/sizeof(uint16));
8276 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8278 result = WERR_NOMEM;
8281 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8287 /* the data is counted in bytes */
8289 *out_max_data_len = in_data_len;
8290 *out_data_len = in_data_len;
8292 /* only allocate when given a non-zero data_len */
8294 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8296 result = WERR_NOMEM;
8300 result = WERR_NO_MORE_ITEMS;
8306 * - counted in bytes in the request
8307 * - counted in UNICODE chars in the max reply
8308 * - counted in bytes in the real size
8310 * take a pause *before* coding not *during* coding
8314 *out_max_value_len=(in_value_len/sizeof(uint16));
8316 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8318 result = WERR_NOMEM;
8322 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8330 *out_type = regval_type( val );
8332 /* data - counted in bytes */
8334 *out_max_data_len = in_data_len;
8335 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8337 result = WERR_NOMEM;
8340 data_len = regval_size(val);
8341 if ( *data_out && data_len )
8342 memcpy( *data_out, regval_data_p(val), data_len );
8343 *out_data_len = data_len;
8347 free_a_printer(&printer, 2);
8351 /****************************************************************************
8352 ****************************************************************************/
8354 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8356 POLICY_HND *handle = &q_u->handle;
8357 UNISTR2 *value = &q_u->value;
8358 uint32 type = q_u->type;
8359 uint8 *data = q_u->data;
8360 uint32 real_len = q_u->real_len;
8362 NT_PRINTER_INFO_LEVEL *printer = NULL;
8364 WERROR status = WERR_OK;
8365 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8368 DEBUG(5,("spoolss_setprinterdata\n"));
8371 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8375 if ( Printer->printer_type == SPLHND_SERVER ) {
8376 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8377 return WERR_INVALID_PARAM;
8380 if (!get_printer_snum(p,handle, &snum, NULL))
8384 * Access check : NT returns "access denied" if you make a
8385 * SetPrinterData call without the necessary privildge.
8386 * we were originally returning OK if nothing changed
8387 * which made Win2k issue **a lot** of SetPrinterData
8388 * when connecting to a printer --jerry
8391 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8393 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8394 status = WERR_ACCESS_DENIED;
8398 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8399 if (!W_ERROR_IS_OK(status))
8402 unistr2_to_ascii(valuename, value, sizeof(valuename));
8405 * When client side code sets a magic printer data key, detect it and save
8406 * the current printer data and the magic key's data (its the DEVMODE) for
8407 * future printer/driver initializations.
8409 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8411 /* Set devmode and printer initialization info */
8412 status = save_driver_init( printer, 2, data, real_len );
8414 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8418 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8419 type, data, real_len );
8420 if ( W_ERROR_IS_OK(status) )
8421 status = mod_a_printer(printer, 2);
8425 free_a_printer(&printer, 2);
8430 /****************************************************************
8431 _spoolss_ResetPrinter
8432 ****************************************************************/
8434 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8435 struct spoolss_ResetPrinter *r)
8437 POLICY_HND *handle = r->in.handle;
8438 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8441 DEBUG(5,("_spoolss_ResetPrinter\n"));
8444 * All we do is to check to see if the handle and queue is valid.
8445 * This call really doesn't mean anything to us because we only
8446 * support RAW printing. --jerry
8450 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8451 OUR_HANDLE(handle)));
8455 if (!get_printer_snum(p,handle, &snum, NULL))
8459 /* blindly return success */
8463 /****************************************************************
8464 _spoolss_DeletePrinterData
8465 ****************************************************************/
8467 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8468 struct spoolss_DeletePrinterData *r)
8470 POLICY_HND *handle = r->in.handle;
8471 NT_PRINTER_INFO_LEVEL *printer = NULL;
8473 WERROR status = WERR_OK;
8474 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8476 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8479 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8480 OUR_HANDLE(handle)));
8484 if (!get_printer_snum(p, handle, &snum, NULL))
8487 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8488 DEBUG(3, ("_spoolss_DeletePrinterData: "
8489 "printer properties change denied by handle\n"));
8490 return WERR_ACCESS_DENIED;
8493 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8494 if (!W_ERROR_IS_OK(status))
8497 if (!r->in.value_name) {
8498 free_a_printer(&printer, 2);
8502 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8505 if ( W_ERROR_IS_OK(status) )
8506 mod_a_printer( printer, 2 );
8508 free_a_printer(&printer, 2);
8513 /****************************************************************
8515 ****************************************************************/
8517 WERROR _spoolss_AddForm(pipes_struct *p,
8518 struct spoolss_AddForm *r)
8520 POLICY_HND *handle = r->in.handle;
8521 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8522 nt_forms_struct tmpForm;
8524 WERROR status = WERR_OK;
8525 NT_PRINTER_INFO_LEVEL *printer = NULL;
8528 nt_forms_struct *list=NULL;
8529 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8531 DEBUG(5,("_spoolss_AddForm\n"));
8534 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8535 OUR_HANDLE(handle)));
8540 /* forms can be added on printer of on the print server handle */
8542 if ( Printer->printer_type == SPLHND_PRINTER )
8544 if (!get_printer_snum(p,handle, &snum, NULL))
8547 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8548 if (!W_ERROR_IS_OK(status))
8552 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8553 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8554 status = WERR_ACCESS_DENIED;
8558 /* can't add if builtin */
8560 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8561 status = WERR_FILE_EXISTS;
8565 count = get_ntforms(&list);
8567 if(!add_a_form(&list, form, &count)) {
8568 status = WERR_NOMEM;
8572 write_ntforms(&list, count);
8575 * ChangeID must always be set if this is a printer
8578 if ( Printer->printer_type == SPLHND_PRINTER )
8579 status = mod_a_printer(printer, 2);
8583 free_a_printer(&printer, 2);
8589 /****************************************************************
8591 ****************************************************************/
8593 WERROR _spoolss_DeleteForm(pipes_struct *p,
8594 struct spoolss_DeleteForm *r)
8596 POLICY_HND *handle = r->in.handle;
8597 const char *form_name = r->in.form_name;
8598 nt_forms_struct tmpForm;
8600 nt_forms_struct *list=NULL;
8601 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8603 WERROR status = WERR_OK;
8604 NT_PRINTER_INFO_LEVEL *printer = NULL;
8606 DEBUG(5,("_spoolss_DeleteForm\n"));
8609 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8610 OUR_HANDLE(handle)));
8614 /* forms can be deleted on printer of on the print server handle */
8616 if ( Printer->printer_type == SPLHND_PRINTER )
8618 if (!get_printer_snum(p,handle, &snum, NULL))
8621 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8622 if (!W_ERROR_IS_OK(status))
8626 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8627 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8628 status = WERR_ACCESS_DENIED;
8632 /* can't delete if builtin */
8634 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8635 status = WERR_INVALID_PARAM;
8639 count = get_ntforms(&list);
8641 if ( !delete_a_form(&list, form_name, &count, &status ))
8645 * ChangeID must always be set if this is a printer
8648 if ( Printer->printer_type == SPLHND_PRINTER )
8649 status = mod_a_printer(printer, 2);
8653 free_a_printer(&printer, 2);
8659 /****************************************************************
8661 ****************************************************************/
8663 WERROR _spoolss_SetForm(pipes_struct *p,
8664 struct spoolss_SetForm *r)
8666 POLICY_HND *handle = r->in.handle;
8667 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8668 nt_forms_struct tmpForm;
8670 WERROR status = WERR_OK;
8671 NT_PRINTER_INFO_LEVEL *printer = NULL;
8674 nt_forms_struct *list=NULL;
8675 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8677 DEBUG(5,("_spoolss_SetForm\n"));
8680 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8681 OUR_HANDLE(handle)));
8685 /* forms can be modified on printer of on the print server handle */
8687 if ( Printer->printer_type == SPLHND_PRINTER )
8689 if (!get_printer_snum(p,handle, &snum, NULL))
8692 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8693 if (!W_ERROR_IS_OK(status))
8697 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8698 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8699 status = WERR_ACCESS_DENIED;
8703 /* can't set if builtin */
8704 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8705 status = WERR_INVALID_PARAM;
8709 count = get_ntforms(&list);
8710 update_a_form(&list, form, count);
8711 write_ntforms(&list, count);
8714 * ChangeID must always be set if this is a printer
8717 if ( Printer->printer_type == SPLHND_PRINTER )
8718 status = mod_a_printer(printer, 2);
8723 free_a_printer(&printer, 2);
8729 /****************************************************************************
8730 enumprintprocessors level 1.
8731 ****************************************************************************/
8733 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8735 PRINTPROCESSOR_1 *info_1=NULL;
8736 WERROR result = WERR_OK;
8738 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8743 init_unistr(&info_1->name, "winprint");
8745 *needed += spoolss_size_printprocessor_info_1(info_1);
8747 if (*needed > offered) {
8748 result = WERR_INSUFFICIENT_BUFFER;
8752 if (!rpcbuf_alloc_size(buffer, *needed)) {
8753 result = WERR_NOMEM;
8757 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8762 if ( !W_ERROR_IS_OK(result) )
8768 /****************************************************************************
8769 ****************************************************************************/
8771 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8773 uint32 level = q_u->level;
8774 RPC_BUFFER *buffer = NULL;
8775 uint32 offered = q_u->offered;
8776 uint32 *needed = &r_u->needed;
8777 uint32 *returned = &r_u->returned;
8779 /* that's an [in out] buffer */
8781 if (!q_u->buffer && (offered!=0)) {
8782 return WERR_INVALID_PARAM;
8785 if (offered > MAX_RPC_DATA_SIZE) {
8786 return WERR_INVALID_PARAM;
8789 rpcbuf_move(q_u->buffer, &r_u->buffer);
8790 buffer = r_u->buffer;
8792 DEBUG(5,("spoolss_enumprintprocessors\n"));
8795 * Enumerate the print processors ...
8797 * Just reply with "winprint", to keep NT happy
8798 * and I can use my nice printer checker.
8806 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8808 return WERR_UNKNOWN_LEVEL;
8812 /****************************************************************************
8813 enumprintprocdatatypes level 1.
8814 ****************************************************************************/
8816 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8818 PRINTPROCDATATYPE_1 *info_1=NULL;
8819 WERROR result = WERR_OK;
8821 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8826 init_unistr(&info_1->name, "RAW");
8828 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8830 if (*needed > offered) {
8831 result = WERR_INSUFFICIENT_BUFFER;
8835 if (!rpcbuf_alloc_size(buffer, *needed)) {
8836 result = WERR_NOMEM;
8840 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8845 if ( !W_ERROR_IS_OK(result) )
8851 /****************************************************************************
8852 ****************************************************************************/
8854 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8856 uint32 level = q_u->level;
8857 RPC_BUFFER *buffer = NULL;
8858 uint32 offered = q_u->offered;
8859 uint32 *needed = &r_u->needed;
8860 uint32 *returned = &r_u->returned;
8862 /* that's an [in out] buffer */
8864 if (!q_u->buffer && (offered!=0)) {
8865 return WERR_INVALID_PARAM;
8868 if (offered > MAX_RPC_DATA_SIZE) {
8869 return WERR_INVALID_PARAM;
8872 rpcbuf_move(q_u->buffer, &r_u->buffer);
8873 buffer = r_u->buffer;
8875 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8882 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8884 return WERR_UNKNOWN_LEVEL;
8888 /****************************************************************************
8889 enumprintmonitors level 1.
8890 ****************************************************************************/
8892 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8894 PRINTMONITOR_1 *info_1;
8895 WERROR result = WERR_OK;
8898 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8903 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8904 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8906 for ( i=0; i<*returned; i++ ) {
8907 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8910 if (*needed > offered) {
8911 result = WERR_INSUFFICIENT_BUFFER;
8915 if (!rpcbuf_alloc_size(buffer, *needed)) {
8916 result = WERR_NOMEM;
8920 for ( i=0; i<*returned; i++ ) {
8921 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8927 if ( !W_ERROR_IS_OK(result) )
8933 /****************************************************************************
8934 enumprintmonitors level 2.
8935 ****************************************************************************/
8937 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8939 PRINTMONITOR_2 *info_2;
8940 WERROR result = WERR_OK;
8943 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8948 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8949 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8950 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8952 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8953 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8954 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8956 for ( i=0; i<*returned; i++ ) {
8957 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8960 if (*needed > offered) {
8961 result = WERR_INSUFFICIENT_BUFFER;
8965 if (!rpcbuf_alloc_size(buffer, *needed)) {
8966 result = WERR_NOMEM;
8970 for ( i=0; i<*returned; i++ ) {
8971 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8977 if ( !W_ERROR_IS_OK(result) )
8983 /****************************************************************************
8984 ****************************************************************************/
8986 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8988 uint32 level = q_u->level;
8989 RPC_BUFFER *buffer = NULL;
8990 uint32 offered = q_u->offered;
8991 uint32 *needed = &r_u->needed;
8992 uint32 *returned = &r_u->returned;
8994 /* that's an [in out] buffer */
8996 if (!q_u->buffer && (offered!=0)) {
8997 return WERR_INVALID_PARAM;
9000 if (offered > MAX_RPC_DATA_SIZE) {
9001 return WERR_INVALID_PARAM;
9004 rpcbuf_move(q_u->buffer, &r_u->buffer);
9005 buffer = r_u->buffer;
9007 DEBUG(5,("spoolss_enumprintmonitors\n"));
9010 * Enumerate the print monitors ...
9012 * Just reply with "Local Port", to keep NT happy
9013 * and I can use my nice printer checker.
9021 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9023 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9025 return WERR_UNKNOWN_LEVEL;
9029 /****************************************************************************
9030 ****************************************************************************/
9032 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9033 NT_PRINTER_INFO_LEVEL *ntprinter,
9034 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9039 JOB_INFO_1 *info_1=NULL;
9040 WERROR result = WERR_OK;
9042 info_1=SMB_MALLOC_P(JOB_INFO_1);
9044 if (info_1 == NULL) {
9048 for (i=0; i<count && found==False; i++) {
9049 if ((*queue)[i].job==(int)jobid)
9055 /* NT treats not found as bad param... yet another bad choice */
9056 return WERR_INVALID_PARAM;
9059 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9061 *needed += spoolss_size_job_info_1(info_1);
9063 if (*needed > offered) {
9064 result = WERR_INSUFFICIENT_BUFFER;
9068 if (!rpcbuf_alloc_size(buffer, *needed)) {
9069 result = WERR_NOMEM;
9073 smb_io_job_info_1("", buffer, info_1, 0);
9081 /****************************************************************************
9082 ****************************************************************************/
9084 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9085 NT_PRINTER_INFO_LEVEL *ntprinter,
9086 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9093 DEVICEMODE *devmode = NULL;
9094 NT_DEVICEMODE *nt_devmode = NULL;
9096 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9099 ZERO_STRUCTP(info_2);
9101 for ( i=0; i<count && found==False; i++ )
9103 if ((*queue)[i].job == (int)jobid)
9108 /* NT treats not found as bad param... yet another bad
9110 result = WERR_INVALID_PARAM;
9115 * if the print job does not have a DEVMODE associated with it,
9116 * just use the one for the printer. A NULL devicemode is not
9117 * a failure condition
9120 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9121 devmode = construct_dev_mode(lp_const_servicename(snum));
9123 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9124 ZERO_STRUCTP( devmode );
9125 convert_nt_devicemode( devmode, nt_devmode );
9129 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9131 *needed += spoolss_size_job_info_2(info_2);
9133 if (*needed > offered) {
9134 result = WERR_INSUFFICIENT_BUFFER;
9138 if (!rpcbuf_alloc_size(buffer, *needed)) {
9139 result = WERR_NOMEM;
9143 smb_io_job_info_2("", buffer, info_2, 0);
9148 /* Cleanup allocated memory */
9150 free_job_info_2(info_2); /* Also frees devmode */
9156 /****************************************************************************
9157 ****************************************************************************/
9159 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9161 POLICY_HND *handle = &q_u->handle;
9162 uint32 jobid = q_u->jobid;
9163 uint32 level = q_u->level;
9164 RPC_BUFFER *buffer = NULL;
9165 uint32 offered = q_u->offered;
9166 uint32 *needed = &r_u->needed;
9167 WERROR wstatus = WERR_OK;
9168 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9171 print_queue_struct *queue = NULL;
9172 print_status_struct prt_status;
9174 /* that's an [in out] buffer */
9176 if (!q_u->buffer && (offered!=0)) {
9177 return WERR_INVALID_PARAM;
9180 if (offered > MAX_RPC_DATA_SIZE) {
9181 return WERR_INVALID_PARAM;
9184 rpcbuf_move(q_u->buffer, &r_u->buffer);
9185 buffer = r_u->buffer;
9187 DEBUG(5,("spoolss_getjob\n"));
9191 if (!get_printer_snum(p, handle, &snum, NULL))
9194 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9195 if ( !W_ERROR_IS_OK(wstatus) )
9198 count = print_queue_status(snum, &queue, &prt_status);
9200 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9201 count, prt_status.status, prt_status.message));
9205 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9206 buffer, offered, needed);
9209 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9210 buffer, offered, needed);
9213 wstatus = WERR_UNKNOWN_LEVEL;
9218 free_a_printer( &ntprinter, 2 );
9223 /****************************************************************
9224 _spoolss_GetPrinterDataEx
9226 From MSDN documentation of GetPrinterDataEx: pass request
9227 to GetPrinterData if key is "PrinterDriverData".
9228 ****************************************************************/
9230 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9231 struct spoolss_GetPrinterDataEx *r)
9233 POLICY_HND *handle = r->in.handle;
9235 const char *keyname = r->in.key_name;
9236 const char *valuename = r->in.value_name;
9238 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9240 NT_PRINTER_INFO_LEVEL *printer = NULL;
9242 WERROR status = WERR_OK;
9244 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9246 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9247 keyname, valuename));
9249 /* in case of problem, return some default values */
9255 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9256 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9257 status = WERR_BADFID;
9261 /* Is the handle to a printer or to the server? */
9263 if (Printer->printer_type == SPLHND_SERVER) {
9264 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9265 "Not implemented for server handles yet\n"));
9266 status = WERR_INVALID_PARAM;
9270 if ( !get_printer_snum(p,handle, &snum, NULL) )
9273 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9274 if ( !W_ERROR_IS_OK(status) )
9277 /* check to see if the keyname is valid */
9278 if ( !strlen(keyname) ) {
9279 status = WERR_INVALID_PARAM;
9283 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9284 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9285 "Invalid keyname [%s]\n", keyname ));
9286 free_a_printer( &printer, 2 );
9287 status = WERR_BADFILE;
9291 /* When given a new keyname, we should just create it */
9293 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9294 r->out.type, &data, r->out.needed,
9297 if (*r->out.needed > r->in.offered) {
9298 status = WERR_MORE_DATA;
9301 if (W_ERROR_IS_OK(status)) {
9302 memcpy(r->out.buffer, data, r->in.offered);
9307 free_a_printer( &printer, 2 );
9312 /****************************************************************
9313 _spoolss_SetPrinterDataEx
9314 ****************************************************************/
9316 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9317 struct spoolss_SetPrinterDataEx *r)
9319 POLICY_HND *handle = r->in.handle;
9320 NT_PRINTER_INFO_LEVEL *printer = NULL;
9322 WERROR status = WERR_OK;
9323 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9326 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9328 /* From MSDN documentation of SetPrinterDataEx: pass request to
9329 SetPrinterData if key is "PrinterDriverData" */
9332 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9333 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9337 if ( Printer->printer_type == SPLHND_SERVER ) {
9338 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9339 "Not implemented for server handles yet\n"));
9340 return WERR_INVALID_PARAM;
9343 if ( !get_printer_snum(p,handle, &snum, NULL) )
9347 * Access check : NT returns "access denied" if you make a
9348 * SetPrinterData call without the necessary privildge.
9349 * we were originally returning OK if nothing changed
9350 * which made Win2k issue **a lot** of SetPrinterData
9351 * when connecting to a printer --jerry
9354 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9356 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9357 "change denied by handle access permissions\n"));
9358 return WERR_ACCESS_DENIED;
9361 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9362 if (!W_ERROR_IS_OK(status))
9365 /* check for OID in valuename */
9367 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9373 /* save the registry data */
9375 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9376 r->in.type, r->in.buffer, r->in.offered );
9378 if ( W_ERROR_IS_OK(status) )
9380 /* save the OID if one was specified */
9382 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9383 r->in.key_name, SPOOL_OID_KEY);
9389 * I'm not checking the status here on purpose. Don't know
9390 * if this is right, but I'm returning the status from the
9391 * previous set_printer_dataex() call. I have no idea if
9392 * this is right. --jerry
9395 set_printer_dataex( printer, str, r->in.value_name,
9396 REG_SZ, (uint8 *)oid_string,
9397 strlen(oid_string)+1 );
9400 status = mod_a_printer(printer, 2);
9403 free_a_printer(&printer, 2);
9408 /****************************************************************
9409 _spoolss_DeletePrinterDataEx
9410 ****************************************************************/
9412 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9413 struct spoolss_DeletePrinterDataEx *r)
9415 POLICY_HND *handle = r->in.handle;
9416 NT_PRINTER_INFO_LEVEL *printer = NULL;
9418 WERROR status = WERR_OK;
9419 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9421 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9424 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9425 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9429 if (!get_printer_snum(p, handle, &snum, NULL))
9432 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9433 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9434 "printer properties change denied by handle\n"));
9435 return WERR_ACCESS_DENIED;
9438 if (!r->in.value_name || !r->in.key_name) {
9442 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9443 if (!W_ERROR_IS_OK(status))
9446 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9448 if ( W_ERROR_IS_OK(status) )
9449 mod_a_printer( printer, 2 );
9451 free_a_printer(&printer, 2);
9456 /********************************************************************
9457 * spoolss_enumprinterkey
9458 ********************************************************************/
9461 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9464 fstring *keynames = NULL;
9465 uint16 *enumkeys = NULL;
9468 POLICY_HND *handle = &q_u->handle;
9469 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9470 NT_PRINTER_DATA *data;
9471 NT_PRINTER_INFO_LEVEL *printer = NULL;
9473 WERROR status = WERR_BADFILE;
9476 DEBUG(4,("_spoolss_enumprinterkey\n"));
9479 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9483 if ( !get_printer_snum(p,handle, &snum, NULL) )
9486 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9487 if (!W_ERROR_IS_OK(status))
9490 /* get the list of subkey names */
9492 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9493 data = printer->info_2->data;
9495 num_keys = get_printer_subkeys( data, key, &keynames );
9497 if ( num_keys == -1 ) {
9498 status = WERR_BADFILE;
9502 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9504 r_u->needed = printerkey_len*2;
9506 if ( q_u->size < r_u->needed ) {
9507 status = WERR_MORE_DATA;
9511 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9512 status = WERR_NOMEM;
9518 if ( q_u->size < r_u->needed )
9519 status = WERR_MORE_DATA;
9522 free_a_printer( &printer, 2 );
9523 SAFE_FREE( keynames );
9528 /****************************************************************
9529 _spoolss_DeletePrinterKey
9530 ****************************************************************/
9532 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9533 struct spoolss_DeletePrinterKey *r)
9535 POLICY_HND *handle = r->in.handle;
9536 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9537 NT_PRINTER_INFO_LEVEL *printer = NULL;
9541 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9544 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9545 OUR_HANDLE(handle)));
9549 /* if keyname == NULL, return error */
9551 if ( !r->in.key_name )
9552 return WERR_INVALID_PARAM;
9554 if (!get_printer_snum(p, handle, &snum, NULL))
9557 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9558 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9559 "printer properties change denied by handle\n"));
9560 return WERR_ACCESS_DENIED;
9563 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9564 if (!W_ERROR_IS_OK(status))
9567 /* delete the key and all subneys */
9569 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9571 if ( W_ERROR_IS_OK(status) )
9572 status = mod_a_printer(printer, 2);
9574 free_a_printer( &printer, 2 );
9580 /********************************************************************
9581 * spoolss_enumprinterdataex
9582 ********************************************************************/
9584 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9586 POLICY_HND *handle = &q_u->handle;
9587 uint32 in_size = q_u->size;
9590 NT_PRINTER_INFO_LEVEL *printer = NULL;
9591 PRINTER_ENUM_VALUES *enum_values = NULL;
9592 NT_PRINTER_DATA *p_data;
9594 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9599 REGISTRY_VALUE *val;
9604 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9607 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9612 * first check for a keyname of NULL or "". Win2k seems to send
9613 * this a lot and we should send back WERR_INVALID_PARAM
9614 * no need to spend time looking up the printer in this case.
9618 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9619 if ( !strlen(key) ) {
9620 result = WERR_INVALID_PARAM;
9624 /* get the printer off of disk */
9626 if (!get_printer_snum(p,handle, &snum, NULL))
9629 ZERO_STRUCT(printer);
9630 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9631 if (!W_ERROR_IS_OK(result))
9634 /* now look for a match on the key name */
9636 p_data = printer->info_2->data;
9638 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9639 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9641 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9642 result = WERR_INVALID_PARAM;
9649 /* allocate the memory for the array of pointers -- if necessary */
9651 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9654 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9656 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9657 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9658 result = WERR_NOMEM;
9662 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9666 * loop through all params and build the array to pass
9667 * back to the client
9670 for ( i=0; i<num_entries; i++ )
9672 /* lookup the registry value */
9674 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9675 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9679 value_name = regval_name( val );
9680 init_unistr( &enum_values[i].valuename, value_name );
9681 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9682 enum_values[i].type = regval_type( val );
9684 data_len = regval_size( val );
9686 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9688 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9690 result = WERR_NOMEM;
9694 enum_values[i].data_len = data_len;
9696 /* keep track of the size of the array in bytes */
9698 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9701 /* housekeeping information in the reply */
9703 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9704 * the hand marshalled container size is a multiple
9705 * of 4 bytes for RPC alignment.
9709 needed += 4-(needed % 4);
9712 r_u->needed = needed;
9713 r_u->returned = num_entries;
9715 if (needed > in_size) {
9716 result = WERR_MORE_DATA;
9720 /* copy data into the reply */
9722 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9723 response buffer size is != the offered buffer size
9725 r_u->ctr.size = r_u->needed;
9727 r_u->ctr.size = in_size;
9729 r_u->ctr.size_of_array = r_u->returned;
9730 r_u->ctr.values = enum_values;
9734 free_a_printer(&printer, 2);
9739 /****************************************************************************
9740 ****************************************************************************/
9742 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, const char *name)
9744 init_unistr(&info->name, name);
9747 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
9748 UNISTR2 *environment,
9753 char *long_archi = NULL;
9754 PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
9755 WERROR result = WERR_OK;
9756 TALLOC_CTX *ctx = talloc_tos();
9758 long_archi = unistr2_to_ascii_talloc(ctx, environment);
9763 if (!get_short_archi(long_archi))
9764 return WERR_INVALID_ENVIRONMENT;
9766 if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
9769 fill_printprocessordirectory_1(info, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9771 *needed += spoolss_size_printprocessordirectory_info_1(info);
9773 if (*needed > offered) {
9774 result = WERR_INSUFFICIENT_BUFFER;
9778 if (!rpcbuf_alloc_size(buffer, *needed)) {
9779 result = WERR_INSUFFICIENT_BUFFER;
9783 smb_io_printprocessordirectory_1("", buffer, info, 0);
9791 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
9793 uint32 level = q_u->level;
9794 RPC_BUFFER *buffer = NULL;
9795 uint32 offered = q_u->offered;
9796 uint32 *needed = &r_u->needed;
9799 /* that's an [in out] buffer */
9801 if (!q_u->buffer && (offered!=0)) {
9802 return WERR_INVALID_PARAM;
9805 if (offered > MAX_RPC_DATA_SIZE) {
9806 return WERR_INVALID_PARAM;
9809 rpcbuf_move(q_u->buffer, &r_u->buffer);
9810 buffer = r_u->buffer;
9812 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9818 result = getprintprocessordirectory_level_1
9819 (&q_u->name, &q_u->environment, buffer, offered, needed);
9822 result = WERR_UNKNOWN_LEVEL;
9828 /*******************************************************************
9829 ********************************************************************/
9831 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9832 const char *dllname)
9834 enum ndr_err_code ndr_err;
9835 struct spoolss_MonitorUi ui;
9837 ui.dll_name = dllname;
9839 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9840 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9841 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9842 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9844 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9847 /*******************************************************************
9848 Streams the monitor UI DLL name in UNICODE
9849 *******************************************************************/
9851 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9852 NT_USER_TOKEN *token, DATA_BLOB *in,
9853 DATA_BLOB *out, uint32_t *needed)
9855 const char *dllname = "tcpmonui.dll";
9857 *needed = (strlen(dllname)+1) * 2;
9859 if (out->length < *needed) {
9860 return WERR_INSUFFICIENT_BUFFER;
9863 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9870 /*******************************************************************
9871 ********************************************************************/
9873 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9874 struct spoolss_PortData1 *port1,
9875 const DATA_BLOB *buf)
9877 enum ndr_err_code ndr_err;
9878 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9879 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9880 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9881 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9883 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9886 /*******************************************************************
9887 ********************************************************************/
9889 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9890 struct spoolss_PortData2 *port2,
9891 const DATA_BLOB *buf)
9893 enum ndr_err_code ndr_err;
9894 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9895 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9896 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9897 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9899 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9902 /*******************************************************************
9903 Create a new TCP/IP port
9904 *******************************************************************/
9906 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9907 NT_USER_TOKEN *token, DATA_BLOB *in,
9908 DATA_BLOB *out, uint32_t *needed)
9910 struct spoolss_PortData1 port1;
9911 struct spoolss_PortData2 port2;
9912 char *device_uri = NULL;
9915 const char *portname;
9916 const char *hostaddress;
9918 uint32_t port_number;
9921 /* peek for spoolss_PortData version */
9923 if (!in || (in->length < (128 + 4))) {
9924 return WERR_GENERAL_FAILURE;
9927 version = IVAL(in->data, 128);
9933 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9937 portname = port1.portname;
9938 hostaddress = port1.hostaddress;
9939 queue = port1.queue;
9940 protocol = port1.protocol;
9941 port_number = port1.port_number;
9947 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9951 portname = port2.portname;
9952 hostaddress = port2.hostaddress;
9953 queue = port2.queue;
9954 protocol = port2.protocol;
9955 port_number = port2.port_number;
9959 DEBUG(1,("xcvtcp_addport: "
9960 "unknown version of port_data: %d\n", version));
9961 return WERR_UNKNOWN_PORT;
9964 /* create the device URI and call the add_port_hook() */
9967 case PROTOCOL_RAWTCP_TYPE:
9968 device_uri = talloc_asprintf(mem_ctx,
9969 "socket://%s:%d/", hostaddress,
9973 case PROTOCOL_LPR_TYPE:
9974 device_uri = talloc_asprintf(mem_ctx,
9975 "lpr://%s/%s", hostaddress, queue );
9979 return WERR_UNKNOWN_PORT;
9986 return add_port_hook(mem_ctx, token, portname, device_uri);
9989 /*******************************************************************
9990 *******************************************************************/
9992 struct xcv_api_table xcvtcp_cmds[] = {
9993 { "MonitorUI", xcvtcp_monitorui },
9994 { "AddPort", xcvtcp_addport},
9998 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9999 NT_USER_TOKEN *token, const char *command,
10006 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
10008 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
10009 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
10010 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10013 return WERR_BADFUNC;
10016 /*******************************************************************
10017 *******************************************************************/
10018 #if 0 /* don't support management using the "Local Port" monitor */
10020 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
10021 NT_USER_TOKEN *token, DATA_BLOB *in,
10022 DATA_BLOB *out, uint32_t *needed)
10024 const char *dllname = "localui.dll";
10026 *needed = (strlen(dllname)+1) * 2;
10028 if (out->length < *needed) {
10029 return WERR_INSUFFICIENT_BUFFER;
10032 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10039 /*******************************************************************
10040 *******************************************************************/
10042 struct xcv_api_table xcvlocal_cmds[] = {
10043 { "MonitorUI", xcvlocal_monitorui },
10047 struct xcv_api_table xcvlocal_cmds[] = {
10054 /*******************************************************************
10055 *******************************************************************/
10057 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10058 NT_USER_TOKEN *token, const char *command,
10059 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10064 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10066 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10067 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10068 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10070 return WERR_BADFUNC;
10073 /****************************************************************
10075 ****************************************************************/
10077 WERROR _spoolss_XcvData(pipes_struct *p,
10078 struct spoolss_XcvData *r)
10080 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10081 DATA_BLOB out_data;
10085 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10086 OUR_HANDLE(r->in.handle)));
10087 return WERR_BADFID;
10090 /* Has to be a handle to the TCP/IP port monitor */
10092 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10093 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10094 return WERR_BADFID;
10097 /* requires administrative access to the server */
10099 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10100 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10101 return WERR_ACCESS_DENIED;
10104 /* Allocate the outgoing buffer */
10106 if (r->in.out_data_size) {
10107 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10108 if (out_data.data == NULL) {
10113 switch ( Printer->printer_type ) {
10114 case SPLHND_PORTMON_TCP:
10115 werror = process_xcvtcp_command(p->mem_ctx,
10116 p->server_info->ptok,
10117 r->in.function_name,
10118 &r->in.in_data, &out_data,
10121 case SPLHND_PORTMON_LOCAL:
10122 werror = process_xcvlocal_command(p->mem_ctx,
10123 p->server_info->ptok,
10124 r->in.function_name,
10125 &r->in.in_data, &out_data,
10129 werror = WERR_INVALID_PRINT_MONITOR;
10132 if (!W_ERROR_IS_OK(werror)) {
10136 *r->out.status_code = 0;
10138 memcpy(r->out.out_data, out_data.data, out_data.length);
10143 /****************************************************************
10144 _spoolss_AddPrintProcessor
10145 ****************************************************************/
10147 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10148 struct spoolss_AddPrintProcessor *r)
10150 /* for now, just indicate success and ignore the add. We'll
10151 automatically set the winprint processor for printer
10152 entries later. Used to debug the LexMark Optra S 1855 PCL
10158 /****************************************************************
10159 _spoolss_EnumPrinters
10160 ****************************************************************/
10162 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10163 struct spoolss_EnumPrinters *r)
10165 p->rng_fault_state = true;
10166 return WERR_NOT_SUPPORTED;
10169 /****************************************************************
10171 ****************************************************************/
10173 WERROR _spoolss_GetJob(pipes_struct *p,
10174 struct spoolss_GetJob *r)
10176 p->rng_fault_state = true;
10177 return WERR_NOT_SUPPORTED;
10180 /****************************************************************
10182 ****************************************************************/
10184 WERROR _spoolss_EnumJobs(pipes_struct *p,
10185 struct spoolss_EnumJobs *r)
10187 p->rng_fault_state = true;
10188 return WERR_NOT_SUPPORTED;
10191 /****************************************************************
10192 _spoolss_AddPrinter
10193 ****************************************************************/
10195 WERROR _spoolss_AddPrinter(pipes_struct *p,
10196 struct spoolss_AddPrinter *r)
10198 p->rng_fault_state = true;
10199 return WERR_NOT_SUPPORTED;
10202 /****************************************************************
10203 _spoolss_GetPrinter
10204 ****************************************************************/
10206 WERROR _spoolss_GetPrinter(pipes_struct *p,
10207 struct spoolss_GetPrinter *r)
10209 p->rng_fault_state = true;
10210 return WERR_NOT_SUPPORTED;
10213 /****************************************************************
10214 _spoolss_AddPrinterDriver
10215 ****************************************************************/
10217 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
10218 struct spoolss_AddPrinterDriver *r)
10220 p->rng_fault_state = true;
10221 return WERR_NOT_SUPPORTED;
10224 /****************************************************************
10225 _spoolss_EnumPrinterDrivers
10226 ****************************************************************/
10228 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10229 struct spoolss_EnumPrinterDrivers *r)
10231 p->rng_fault_state = true;
10232 return WERR_NOT_SUPPORTED;
10235 /****************************************************************
10236 _spoolss_GetPrinterDriver
10237 ****************************************************************/
10239 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10240 struct spoolss_GetPrinterDriver *r)
10242 p->rng_fault_state = true;
10243 return WERR_NOT_SUPPORTED;
10246 /****************************************************************
10247 _spoolss_GetPrinterDriverDirectory
10248 ****************************************************************/
10250 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
10251 struct spoolss_GetPrinterDriverDirectory *r)
10253 p->rng_fault_state = true;
10254 return WERR_NOT_SUPPORTED;
10257 /****************************************************************
10258 _spoolss_EnumPrintProcessors
10259 ****************************************************************/
10261 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10262 struct spoolss_EnumPrintProcessors *r)
10264 p->rng_fault_state = true;
10265 return WERR_NOT_SUPPORTED;
10268 /****************************************************************
10269 _spoolss_GetPrintProcessorDirectory
10270 ****************************************************************/
10272 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
10273 struct spoolss_GetPrintProcessorDirectory *r)
10275 p->rng_fault_state = true;
10276 return WERR_NOT_SUPPORTED;
10279 /****************************************************************
10280 _spoolss_ReadPrinter
10281 ****************************************************************/
10283 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10284 struct spoolss_ReadPrinter *r)
10286 p->rng_fault_state = true;
10287 return WERR_NOT_SUPPORTED;
10290 /****************************************************************
10291 _spoolss_GetPrinterData
10292 ****************************************************************/
10294 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10295 struct spoolss_GetPrinterData *r)
10297 p->rng_fault_state = true;
10298 return WERR_NOT_SUPPORTED;
10301 /****************************************************************
10302 _spoolss_SetPrinterData
10303 ****************************************************************/
10305 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10306 struct spoolss_SetPrinterData *r)
10308 p->rng_fault_state = true;
10309 return WERR_NOT_SUPPORTED;
10312 /****************************************************************
10313 _spoolss_WaitForPrinterChange
10314 ****************************************************************/
10316 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10317 struct spoolss_WaitForPrinterChange *r)
10319 p->rng_fault_state = true;
10320 return WERR_NOT_SUPPORTED;
10323 /****************************************************************
10325 ****************************************************************/
10327 WERROR _spoolss_EnumForms(pipes_struct *p,
10328 struct spoolss_EnumForms *r)
10330 p->rng_fault_state = true;
10331 return WERR_NOT_SUPPORTED;
10334 /****************************************************************
10336 ****************************************************************/
10338 WERROR _spoolss_EnumPorts(pipes_struct *p,
10339 struct spoolss_EnumPorts *r)
10341 p->rng_fault_state = true;
10342 return WERR_NOT_SUPPORTED;
10345 /****************************************************************
10346 _spoolss_EnumMonitors
10347 ****************************************************************/
10349 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10350 struct spoolss_EnumMonitors *r)
10352 p->rng_fault_state = true;
10353 return WERR_NOT_SUPPORTED;
10356 /****************************************************************
10358 ****************************************************************/
10360 WERROR _spoolss_AddPort(pipes_struct *p,
10361 struct spoolss_AddPort *r)
10363 p->rng_fault_state = true;
10364 return WERR_NOT_SUPPORTED;
10367 /****************************************************************
10368 _spoolss_ConfigurePort
10369 ****************************************************************/
10371 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10372 struct spoolss_ConfigurePort *r)
10374 p->rng_fault_state = true;
10375 return WERR_NOT_SUPPORTED;
10378 /****************************************************************
10379 _spoolss_DeletePort
10380 ****************************************************************/
10382 WERROR _spoolss_DeletePort(pipes_struct *p,
10383 struct spoolss_DeletePort *r)
10385 p->rng_fault_state = true;
10386 return WERR_NOT_SUPPORTED;
10389 /****************************************************************
10390 _spoolss_CreatePrinterIC
10391 ****************************************************************/
10393 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10394 struct spoolss_CreatePrinterIC *r)
10396 p->rng_fault_state = true;
10397 return WERR_NOT_SUPPORTED;
10400 /****************************************************************
10401 _spoolss_PlayGDIScriptOnPrinterIC
10402 ****************************************************************/
10404 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10405 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10407 p->rng_fault_state = true;
10408 return WERR_NOT_SUPPORTED;
10411 /****************************************************************
10412 _spoolss_DeletePrinterIC
10413 ****************************************************************/
10415 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10416 struct spoolss_DeletePrinterIC *r)
10418 p->rng_fault_state = true;
10419 return WERR_NOT_SUPPORTED;
10422 /****************************************************************
10423 _spoolss_AddPrinterConnection
10424 ****************************************************************/
10426 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10427 struct spoolss_AddPrinterConnection *r)
10429 p->rng_fault_state = true;
10430 return WERR_NOT_SUPPORTED;
10433 /****************************************************************
10434 _spoolss_DeletePrinterConnection
10435 ****************************************************************/
10437 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10438 struct spoolss_DeletePrinterConnection *r)
10440 p->rng_fault_state = true;
10441 return WERR_NOT_SUPPORTED;
10444 /****************************************************************
10445 _spoolss_PrinterMessageBox
10446 ****************************************************************/
10448 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10449 struct spoolss_PrinterMessageBox *r)
10451 p->rng_fault_state = true;
10452 return WERR_NOT_SUPPORTED;
10455 /****************************************************************
10456 _spoolss_AddMonitor
10457 ****************************************************************/
10459 WERROR _spoolss_AddMonitor(pipes_struct *p,
10460 struct spoolss_AddMonitor *r)
10462 p->rng_fault_state = true;
10463 return WERR_NOT_SUPPORTED;
10466 /****************************************************************
10467 _spoolss_DeleteMonitor
10468 ****************************************************************/
10470 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10471 struct spoolss_DeleteMonitor *r)
10473 p->rng_fault_state = true;
10474 return WERR_NOT_SUPPORTED;
10477 /****************************************************************
10478 _spoolss_DeletePrintProcessor
10479 ****************************************************************/
10481 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10482 struct spoolss_DeletePrintProcessor *r)
10484 p->rng_fault_state = true;
10485 return WERR_NOT_SUPPORTED;
10488 /****************************************************************
10489 _spoolss_AddPrintProvidor
10490 ****************************************************************/
10492 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10493 struct spoolss_AddPrintProvidor *r)
10495 p->rng_fault_state = true;
10496 return WERR_NOT_SUPPORTED;
10499 /****************************************************************
10500 _spoolss_DeletePrintProvidor
10501 ****************************************************************/
10503 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10504 struct spoolss_DeletePrintProvidor *r)
10506 p->rng_fault_state = true;
10507 return WERR_NOT_SUPPORTED;
10510 /****************************************************************
10511 _spoolss_EnumPrintProcDataTypes
10512 ****************************************************************/
10514 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10515 struct spoolss_EnumPrintProcDataTypes *r)
10517 p->rng_fault_state = true;
10518 return WERR_NOT_SUPPORTED;
10521 /****************************************************************
10522 _spoolss_GetPrinterDriver2
10523 ****************************************************************/
10525 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10526 struct spoolss_GetPrinterDriver2 *r)
10528 p->rng_fault_state = true;
10529 return WERR_NOT_SUPPORTED;
10532 /****************************************************************
10533 _spoolss_FindFirstPrinterChangeNotification
10534 ****************************************************************/
10536 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10537 struct spoolss_FindFirstPrinterChangeNotification *r)
10539 p->rng_fault_state = true;
10540 return WERR_NOT_SUPPORTED;
10543 /****************************************************************
10544 _spoolss_FindNextPrinterChangeNotification
10545 ****************************************************************/
10547 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10548 struct spoolss_FindNextPrinterChangeNotification *r)
10550 p->rng_fault_state = true;
10551 return WERR_NOT_SUPPORTED;
10554 /****************************************************************
10555 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10556 ****************************************************************/
10558 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10559 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10561 p->rng_fault_state = true;
10562 return WERR_NOT_SUPPORTED;
10565 /****************************************************************
10566 _spoolss_ReplyOpenPrinter
10567 ****************************************************************/
10569 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10570 struct spoolss_ReplyOpenPrinter *r)
10572 p->rng_fault_state = true;
10573 return WERR_NOT_SUPPORTED;
10576 /****************************************************************
10577 _spoolss_RouterReplyPrinter
10578 ****************************************************************/
10580 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10581 struct spoolss_RouterReplyPrinter *r)
10583 p->rng_fault_state = true;
10584 return WERR_NOT_SUPPORTED;
10587 /****************************************************************
10588 _spoolss_ReplyClosePrinter
10589 ****************************************************************/
10591 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10592 struct spoolss_ReplyClosePrinter *r)
10594 p->rng_fault_state = true;
10595 return WERR_NOT_SUPPORTED;
10598 /****************************************************************
10600 ****************************************************************/
10602 WERROR _spoolss_AddPortEx(pipes_struct *p,
10603 struct spoolss_AddPortEx *r)
10605 p->rng_fault_state = true;
10606 return WERR_NOT_SUPPORTED;
10609 /****************************************************************
10610 _spoolss_RouterFindFirstPrinterChangeNotification
10611 ****************************************************************/
10613 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10614 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10616 p->rng_fault_state = true;
10617 return WERR_NOT_SUPPORTED;
10620 /****************************************************************
10621 _spoolss_SpoolerInit
10622 ****************************************************************/
10624 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10625 struct spoolss_SpoolerInit *r)
10627 p->rng_fault_state = true;
10628 return WERR_NOT_SUPPORTED;
10631 /****************************************************************
10632 _spoolss_ResetPrinterEx
10633 ****************************************************************/
10635 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10636 struct spoolss_ResetPrinterEx *r)
10638 p->rng_fault_state = true;
10639 return WERR_NOT_SUPPORTED;
10642 /****************************************************************
10643 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10644 ****************************************************************/
10646 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10647 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10649 p->rng_fault_state = true;
10650 return WERR_NOT_SUPPORTED;
10653 /****************************************************************
10654 _spoolss_RouterReplyPrinterEx
10655 ****************************************************************/
10657 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10658 struct spoolss_RouterReplyPrinterEx *r)
10660 p->rng_fault_state = true;
10661 return WERR_NOT_SUPPORTED;
10664 /****************************************************************
10665 _dcesrv_spoolss_RouterRefreshPrinterChangeNotify
10666 ****************************************************************/
10668 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
10669 struct spoolss_RouterRefreshPrinterChangeNotify *r)
10671 p->rng_fault_state = true;
10672 return WERR_NOT_SUPPORTED;
10675 /****************************************************************
10677 ****************************************************************/
10679 WERROR _spoolss_44(pipes_struct *p,
10680 struct spoolss_44 *r)
10682 p->rng_fault_state = true;
10683 return WERR_NOT_SUPPORTED;
10686 /****************************************************************
10688 ****************************************************************/
10690 WERROR _spoolss_47(pipes_struct *p,
10691 struct spoolss_47 *r)
10693 p->rng_fault_state = true;
10694 return WERR_NOT_SUPPORTED;
10697 /****************************************************************
10698 _spoolss_EnumPrinterData
10699 ****************************************************************/
10701 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10702 struct spoolss_EnumPrinterData *r)
10704 p->rng_fault_state = true;
10705 return WERR_NOT_SUPPORTED;
10708 /****************************************************************
10710 ****************************************************************/
10712 WERROR _spoolss_4a(pipes_struct *p,
10713 struct spoolss_4a *r)
10715 p->rng_fault_state = true;
10716 return WERR_NOT_SUPPORTED;
10719 /****************************************************************
10721 ****************************************************************/
10723 WERROR _spoolss_4b(pipes_struct *p,
10724 struct spoolss_4b *r)
10726 p->rng_fault_state = true;
10727 return WERR_NOT_SUPPORTED;
10730 /****************************************************************
10732 ****************************************************************/
10734 WERROR _spoolss_4c(pipes_struct *p,
10735 struct spoolss_4c *r)
10737 p->rng_fault_state = true;
10738 return WERR_NOT_SUPPORTED;
10741 /****************************************************************
10742 _spoolss_EnumPrinterDataEx
10743 ****************************************************************/
10745 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10746 struct spoolss_EnumPrinterDataEx *r)
10748 p->rng_fault_state = true;
10749 return WERR_NOT_SUPPORTED;
10752 /****************************************************************
10753 _spoolss_EnumPrinterKey
10754 ****************************************************************/
10756 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10757 struct spoolss_EnumPrinterKey *r)
10759 p->rng_fault_state = true;
10760 return WERR_NOT_SUPPORTED;
10763 /****************************************************************
10765 ****************************************************************/
10767 WERROR _spoolss_53(pipes_struct *p,
10768 struct spoolss_53 *r)
10770 p->rng_fault_state = true;
10771 return WERR_NOT_SUPPORTED;
10774 /****************************************************************
10776 ****************************************************************/
10778 WERROR _spoolss_55(pipes_struct *p,
10779 struct spoolss_55 *r)
10781 p->rng_fault_state = true;
10782 return WERR_NOT_SUPPORTED;
10785 /****************************************************************
10787 ****************************************************************/
10789 WERROR _spoolss_56(pipes_struct *p,
10790 struct spoolss_56 *r)
10792 p->rng_fault_state = true;
10793 return WERR_NOT_SUPPORTED;
10796 /****************************************************************
10798 ****************************************************************/
10800 WERROR _spoolss_57(pipes_struct *p,
10801 struct spoolss_57 *r)
10803 p->rng_fault_state = true;
10804 return WERR_NOT_SUPPORTED;
10807 /****************************************************************
10808 _spoolss_AddPrinterDriverEx
10809 ****************************************************************/
10811 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
10812 struct spoolss_AddPrinterDriverEx *r)
10814 p->rng_fault_state = true;
10815 return WERR_NOT_SUPPORTED;
10818 /****************************************************************
10820 ****************************************************************/
10822 WERROR _spoolss_5a(pipes_struct *p,
10823 struct spoolss_5a *r)
10825 p->rng_fault_state = true;
10826 return WERR_NOT_SUPPORTED;
10829 /****************************************************************
10831 ****************************************************************/
10833 WERROR _spoolss_5b(pipes_struct *p,
10834 struct spoolss_5b *r)
10836 p->rng_fault_state = true;
10837 return WERR_NOT_SUPPORTED;
10840 /****************************************************************
10842 ****************************************************************/
10844 WERROR _spoolss_5c(pipes_struct *p,
10845 struct spoolss_5c *r)
10847 p->rng_fault_state = true;
10848 return WERR_NOT_SUPPORTED;
10851 /****************************************************************
10853 ****************************************************************/
10855 WERROR _spoolss_5d(pipes_struct *p,
10856 struct spoolss_5d *r)
10858 p->rng_fault_state = true;
10859 return WERR_NOT_SUPPORTED;
10862 /****************************************************************
10864 ****************************************************************/
10866 WERROR _spoolss_5e(pipes_struct *p,
10867 struct spoolss_5e *r)
10869 p->rng_fault_state = true;
10870 return WERR_NOT_SUPPORTED;
10873 /****************************************************************
10875 ****************************************************************/
10877 WERROR _spoolss_5f(pipes_struct *p,
10878 struct spoolss_5f *r)
10880 p->rng_fault_state = true;
10881 return WERR_NOT_SUPPORTED;