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 ZERO_STRUCTP(r->out.handle);
1533 return WERR_INVALID_PARAM;
1536 Printer=find_printer_index_by_hnd(p, handle);
1538 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1539 "handle we created for printer %s\n", name ));
1540 close_printer_handle(p,handle);
1541 ZERO_STRUCTP(r->out.handle);
1542 return WERR_INVALID_PARAM;
1546 * First case: the user is opening the print server:
1548 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1549 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1551 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1552 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1553 * or if the user is listed in the smb.conf printer admin parameter.
1555 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1556 * client view printer folder, but does not show the MSAPW.
1558 * Note: this test needs code to check access rights here too. Jeremy
1559 * could you look at this?
1561 * Second case: the user is opening a printer:
1562 * NT doesn't let us connect to a printer if the connecting user
1563 * doesn't have print permission.
1565 * Third case: user is opening a Port Monitor
1566 * access checks same as opening a handle to the print server.
1569 switch (Printer->printer_type )
1572 case SPLHND_PORTMON_TCP:
1573 case SPLHND_PORTMON_LOCAL:
1574 /* Printserver handles use global struct... */
1578 /* Map standard access rights to object specific access rights */
1580 se_map_standard(&r->in.access_mask,
1581 &printserver_std_mapping);
1583 /* Deny any object specific bits that don't apply to print
1584 servers (i.e printer and job specific bits) */
1586 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1588 if (r->in.access_mask &
1589 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1590 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1591 close_printer_handle(p, handle);
1592 ZERO_STRUCTP(r->out.handle);
1593 return WERR_ACCESS_DENIED;
1596 /* Allow admin access */
1598 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1600 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1602 if (!lp_ms_add_printer_wizard()) {
1603 close_printer_handle(p, handle);
1604 ZERO_STRUCTP(r->out.handle);
1605 return WERR_ACCESS_DENIED;
1608 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1609 and not a printer admin, then fail */
1611 if ((p->server_info->utok.uid != 0) &&
1612 !user_has_privileges(p->server_info->ptok,
1614 !token_contains_name_in_list(
1615 uidtoname(p->server_info->utok.uid),
1617 p->server_info->ptok,
1618 lp_printer_admin(snum))) {
1619 close_printer_handle(p, handle);
1620 ZERO_STRUCTP(r->out.handle);
1621 return WERR_ACCESS_DENIED;
1624 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1628 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1631 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1632 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1634 /* We fall through to return WERR_OK */
1637 case SPLHND_PRINTER:
1638 /* NT doesn't let us connect to a printer if the connecting user
1639 doesn't have print permission. */
1641 if (!get_printer_snum(p, handle, &snum, NULL)) {
1642 close_printer_handle(p, handle);
1643 ZERO_STRUCTP(r->out.handle);
1647 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1649 /* map an empty access mask to the minimum access mask */
1650 if (r->in.access_mask == 0x0)
1651 r->in.access_mask = PRINTER_ACCESS_USE;
1654 * If we are not serving the printer driver for this printer,
1655 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1656 * will keep NT clients happy --jerry
1659 if (lp_use_client_driver(snum)
1660 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1662 r->in.access_mask = PRINTER_ACCESS_USE;
1665 /* check smb.conf parameters and the the sec_desc */
1667 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1668 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1669 ZERO_STRUCTP(r->out.handle);
1670 return WERR_ACCESS_DENIED;
1673 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1674 p->server_info->ptok, snum) ||
1675 !print_access_check(p->server_info, snum,
1676 r->in.access_mask)) {
1677 DEBUG(3, ("access DENIED for printer open\n"));
1678 close_printer_handle(p, handle);
1679 ZERO_STRUCTP(r->out.handle);
1680 return WERR_ACCESS_DENIED;
1683 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1684 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1685 close_printer_handle(p, handle);
1686 ZERO_STRUCTP(r->out.handle);
1687 return WERR_ACCESS_DENIED;
1690 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1691 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1693 r->in.access_mask = PRINTER_ACCESS_USE;
1695 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1696 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1701 /* sanity check to prevent programmer error */
1702 ZERO_STRUCTP(r->out.handle);
1706 Printer->access_granted = r->in.access_mask;
1709 * If the client sent a devmode in the OpenPrinter() call, then
1710 * save it here in case we get a job submission on this handle
1713 if ( (Printer->printer_type != SPLHND_SERVER)
1714 && r->in.devmode_ctr.devmode )
1716 convert_devicemode_new(Printer->sharename,
1717 r->in.devmode_ctr.devmode,
1718 &Printer->nt_devmode);
1721 #if 0 /* JERRY -- I'm doubtful this is really effective */
1722 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1723 optimization in Windows 2000 clients --jerry */
1725 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1726 && (RA_WIN2K == get_remote_arch()) )
1728 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1729 sys_usleep( 500000 );
1736 /****************************************************************************
1737 ****************************************************************************/
1739 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1740 NT_PRINTER_INFO_LEVEL_2 *d)
1742 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1748 d->attributes = r->attributes;
1749 d->priority = r->priority;
1750 d->default_priority = r->defaultpriority;
1751 d->starttime = r->starttime;
1752 d->untiltime = r->untiltime;
1753 d->status = r->status;
1754 d->cjobs = r->cjobs;
1756 fstrcpy(d->servername, r->servername);
1757 fstrcpy(d->printername, r->printername);
1758 fstrcpy(d->sharename, r->sharename);
1759 fstrcpy(d->portname, r->portname);
1760 fstrcpy(d->drivername, r->drivername);
1761 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1762 fstrcpy(d->location, r->location);
1763 fstrcpy(d->sepfile, r->sepfile);
1764 fstrcpy(d->printprocessor, r->printprocessor);
1765 fstrcpy(d->datatype, r->datatype);
1766 fstrcpy(d->parameters, r->parameters);
1771 /****************************************************************************
1772 ****************************************************************************/
1774 static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
1775 NT_PRINTER_INFO_LEVEL *printer)
1779 switch (info_ctr->level) {
1781 /* allocate memory if needed. Messy because
1782 convert_printer_info is used to update an existing
1783 printer or build a new one */
1785 if (!printer->info_2) {
1786 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1787 if (!printer->info_2) {
1788 DEBUG(0,("convert_printer_info_new: "
1789 "talloc() failed!\n"));
1794 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1796 printer->info_2->setuptime = time(NULL);
1803 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
1804 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
1810 printer->info_3=NULL;
1811 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
1815 printer->info_6=NULL;
1816 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
1826 bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
1827 NT_DEVICEMODE **pp_nt_devmode)
1829 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1832 * Ensure nt_devmode is a valid pointer
1833 * as we will be overwriting it.
1836 if (nt_devmode == NULL) {
1837 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1838 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1842 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
1843 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
1845 nt_devmode->specversion=devmode->specversion;
1846 nt_devmode->driverversion=devmode->driverversion;
1847 nt_devmode->size=devmode->size;
1848 nt_devmode->fields=devmode->fields;
1849 nt_devmode->orientation=devmode->orientation;
1850 nt_devmode->papersize=devmode->papersize;
1851 nt_devmode->paperlength=devmode->paperlength;
1852 nt_devmode->paperwidth=devmode->paperwidth;
1853 nt_devmode->scale=devmode->scale;
1854 nt_devmode->copies=devmode->copies;
1855 nt_devmode->defaultsource=devmode->defaultsource;
1856 nt_devmode->printquality=devmode->printquality;
1857 nt_devmode->color=devmode->color;
1858 nt_devmode->duplex=devmode->duplex;
1859 nt_devmode->yresolution=devmode->yresolution;
1860 nt_devmode->ttoption=devmode->ttoption;
1861 nt_devmode->collate=devmode->collate;
1863 nt_devmode->logpixels=devmode->logpixels;
1864 nt_devmode->bitsperpel=devmode->bitsperpel;
1865 nt_devmode->pelswidth=devmode->pelswidth;
1866 nt_devmode->pelsheight=devmode->pelsheight;
1867 nt_devmode->displayflags=devmode->displayflags;
1868 nt_devmode->displayfrequency=devmode->displayfrequency;
1869 nt_devmode->icmmethod=devmode->icmmethod;
1870 nt_devmode->icmintent=devmode->icmintent;
1871 nt_devmode->mediatype=devmode->mediatype;
1872 nt_devmode->dithertype=devmode->dithertype;
1873 nt_devmode->reserved1=devmode->reserved1;
1874 nt_devmode->reserved2=devmode->reserved2;
1875 nt_devmode->panningwidth=devmode->panningwidth;
1876 nt_devmode->panningheight=devmode->panningheight;
1879 * Only change private and driverextra if the incoming devmode
1880 * has a new one. JRA.
1883 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
1884 SAFE_FREE(nt_devmode->nt_dev_private);
1885 nt_devmode->driverextra=devmode->driverextra;
1886 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1888 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
1891 *pp_nt_devmode = nt_devmode;
1896 /********************************************************************
1897 * _spoolss_enddocprinter_internal.
1898 ********************************************************************/
1900 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
1902 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1906 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
1910 if (!get_printer_snum(p, handle, &snum, NULL))
1913 Printer->document_started=False;
1914 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
1915 /* error codes unhandled so far ... */
1920 /****************************************************************
1921 _spoolss_ClosePrinter
1922 ****************************************************************/
1924 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1925 struct spoolss_ClosePrinter *r)
1927 POLICY_HND *handle = r->in.handle;
1929 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1931 if (Printer && Printer->document_started)
1932 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1934 if (!close_printer_handle(p, handle))
1937 /* clear the returned printer handle. Observed behavior
1938 from Win2k server. Don't think this really matters.
1939 Previous code just copied the value of the closed
1942 ZERO_STRUCTP(r->out.handle);
1947 /****************************************************************
1948 _spoolss_DeletePrinter
1949 ****************************************************************/
1951 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1952 struct spoolss_DeletePrinter *r)
1954 POLICY_HND *handle = r->in.handle;
1955 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1958 if (Printer && Printer->document_started)
1959 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1961 result = delete_printer_handle(p, handle);
1963 update_c_setprinter(False);
1968 /*******************************************************************
1969 * static function to lookup the version id corresponding to an
1970 * long architecture string
1971 ******************************************************************/
1973 static int get_version_id (char * arch)
1976 struct table_node archi_table[]= {
1978 {"Windows 4.0", "WIN40", 0 },
1979 {"Windows NT x86", "W32X86", 2 },
1980 {"Windows NT R4000", "W32MIPS", 2 },
1981 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1982 {"Windows NT PowerPC", "W32PPC", 2 },
1983 {"Windows IA64", "IA64", 3 },
1984 {"Windows x64", "x64", 3 },
1988 for (i=0; archi_table[i].long_archi != NULL; i++)
1990 if (strcmp(arch, archi_table[i].long_archi) == 0)
1991 return (archi_table[i].version);
1997 /****************************************************************
1998 _spoolss_DeletePrinterDriver
1999 ****************************************************************/
2001 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
2002 struct spoolss_DeletePrinterDriver *r)
2006 NT_PRINTER_DRIVER_INFO_LEVEL info;
2007 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2010 WERROR status_win2k = WERR_ACCESS_DENIED;
2011 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2013 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2014 and not a printer admin, then fail */
2016 if ( (p->server_info->utok.uid != 0)
2017 && !user_has_privileges(p->server_info->ptok, &se_printop )
2018 && !token_contains_name_in_list(
2019 uidtoname(p->server_info->utok.uid), NULL,
2020 NULL, p->server_info->ptok,
2021 lp_printer_admin(-1)) )
2023 return WERR_ACCESS_DENIED;
2026 driver = CONST_DISCARD(char *, r->in.driver);
2027 arch = CONST_DISCARD(char *, r->in.architecture);
2029 /* check that we have a valid driver name first */
2031 if ((version=get_version_id(arch)) == -1)
2032 return WERR_INVALID_ENVIRONMENT;
2035 ZERO_STRUCT(info_win2k);
2037 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2039 /* try for Win2k driver if "Windows NT x86" */
2041 if ( version == 2 ) {
2043 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2044 status = WERR_UNKNOWN_PRINTER_DRIVER;
2048 /* otherwise it was a failure */
2050 status = WERR_UNKNOWN_PRINTER_DRIVER;
2056 if (printer_driver_in_use(info.info_3)) {
2057 status = WERR_PRINTER_DRIVER_IN_USE;
2063 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2065 /* if we get to here, we now have 2 driver info structures to remove */
2066 /* remove the Win2k driver first*/
2068 status_win2k = delete_printer_driver(
2069 p, info_win2k.info_3, 3, False );
2070 free_a_printer_driver( info_win2k, 3 );
2072 /* this should not have failed---if it did, report to client */
2073 if ( !W_ERROR_IS_OK(status_win2k) )
2075 status = status_win2k;
2081 status = delete_printer_driver(p, info.info_3, version, False);
2083 /* if at least one of the deletes succeeded return OK */
2085 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2089 free_a_printer_driver( info, 3 );
2094 /****************************************************************
2095 _spoolss_DeletePrinterDriverEx
2096 ****************************************************************/
2098 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2099 struct spoolss_DeletePrinterDriverEx *r)
2103 NT_PRINTER_DRIVER_INFO_LEVEL info;
2104 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2106 uint32_t flags = r->in.delete_flags;
2109 WERROR status_win2k = WERR_ACCESS_DENIED;
2110 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2112 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2113 and not a printer admin, then fail */
2115 if ( (p->server_info->utok.uid != 0)
2116 && !user_has_privileges(p->server_info->ptok, &se_printop )
2117 && !token_contains_name_in_list(
2118 uidtoname(p->server_info->utok.uid), NULL, NULL,
2119 p->server_info->ptok, lp_printer_admin(-1)) )
2121 return WERR_ACCESS_DENIED;
2124 driver = CONST_DISCARD(char *, r->in.driver);
2125 arch = CONST_DISCARD(char *, r->in.architecture);
2127 /* check that we have a valid driver name first */
2128 if ((version=get_version_id(arch)) == -1) {
2129 /* this is what NT returns */
2130 return WERR_INVALID_ENVIRONMENT;
2133 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2134 version = r->in.version;
2137 ZERO_STRUCT(info_win2k);
2139 status = get_a_printer_driver(&info, 3, driver, arch, version);
2141 if ( !W_ERROR_IS_OK(status) )
2144 * if the client asked for a specific version,
2145 * or this is something other than Windows NT x86,
2149 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2152 /* try for Win2k driver if "Windows NT x86" */
2155 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2156 status = WERR_UNKNOWN_PRINTER_DRIVER;
2161 if ( printer_driver_in_use(info.info_3) ) {
2162 status = WERR_PRINTER_DRIVER_IN_USE;
2167 * we have a couple of cases to consider.
2168 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2169 * then the delete should fail if **any** files overlap with
2171 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2172 * non-overlapping files
2173 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2174 * is set, the do not delete any files
2175 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2178 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2180 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2182 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2183 /* no idea of the correct error here */
2184 status = WERR_ACCESS_DENIED;
2189 /* also check for W32X86/3 if necessary; maybe we already have? */
2191 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2192 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2195 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2196 /* no idea of the correct error here */
2197 free_a_printer_driver( info_win2k, 3 );
2198 status = WERR_ACCESS_DENIED;
2202 /* if we get to here, we now have 2 driver info structures to remove */
2203 /* remove the Win2k driver first*/
2205 status_win2k = delete_printer_driver(
2206 p, info_win2k.info_3, 3, delete_files);
2207 free_a_printer_driver( info_win2k, 3 );
2209 /* this should not have failed---if it did, report to client */
2211 if ( !W_ERROR_IS_OK(status_win2k) )
2216 status = delete_printer_driver(p, info.info_3, version, delete_files);
2218 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2221 free_a_printer_driver( info, 3 );
2227 /****************************************************************************
2228 Internal routine for retreiving printerdata
2229 ***************************************************************************/
2231 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2232 const char *key, const char *value, uint32 *type, uint8 **data,
2233 uint32 *needed, uint32 in_size )
2235 REGISTRY_VALUE *val;
2239 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2240 return WERR_BADFILE;
2242 *type = regval_type( val );
2244 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2246 size = regval_size( val );
2248 /* copy the min(in_size, len) */
2251 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2253 /* special case for 0 length values */
2255 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2259 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2268 DEBUG(5,("get_printer_dataex: copy done\n"));
2273 /****************************************************************************
2274 Internal routine for removing printerdata
2275 ***************************************************************************/
2277 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2279 return delete_printer_data( printer->info_2, key, value );
2282 /****************************************************************************
2283 Internal routine for storing printerdata
2284 ***************************************************************************/
2286 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2287 uint32 type, uint8 *data, int real_len )
2289 /* the registry objects enforce uniqueness based on value name */
2291 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2294 /********************************************************************
2295 GetPrinterData on a printer server Handle.
2296 ********************************************************************/
2298 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2302 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2304 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2306 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2308 SIVAL(*data, 0, 0x00);
2313 if (!StrCaseCmp(value, "BeepEnabled")) {
2315 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2317 SIVAL(*data, 0, 0x00);
2322 if (!StrCaseCmp(value, "EventLog")) {
2324 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2326 /* formally was 0x1b */
2327 SIVAL(*data, 0, 0x0);
2332 if (!StrCaseCmp(value, "NetPopup")) {
2334 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2336 SIVAL(*data, 0, 0x00);
2341 if (!StrCaseCmp(value, "MajorVersion")) {
2343 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2346 /* Windows NT 4.0 seems to not allow uploading of drivers
2347 to a server that reports 0x3 as the MajorVersion.
2348 need to investigate more how Win2k gets around this .
2351 if ( RA_WINNT == get_remote_arch() )
2360 if (!StrCaseCmp(value, "MinorVersion")) {
2362 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2370 * uint32 size = 0x114
2372 * uint32 minor = [0|1]
2373 * uint32 build = [2195|2600]
2374 * extra unicode string = e.g. "Service Pack 3"
2376 if (!StrCaseCmp(value, "OSVersion")) {
2380 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2383 SIVAL(*data, 0, *needed); /* size */
2384 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2386 SIVAL(*data, 12, 2195); /* build */
2388 /* leave extra string empty */
2394 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2395 const char *string="C:\\PRINTERS";
2397 *needed = 2*(strlen(string)+1);
2398 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2400 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2402 /* it's done by hand ready to go on the wire */
2403 for (i=0; i<strlen(string); i++) {
2404 (*data)[2*i]=string[i];
2405 (*data)[2*i+1]='\0';
2410 if (!StrCaseCmp(value, "Architecture")) {
2411 const char *string="Windows NT x86";
2413 *needed = 2*(strlen(string)+1);
2414 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2416 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2417 for (i=0; i<strlen(string); i++) {
2418 (*data)[2*i]=string[i];
2419 (*data)[2*i+1]='\0';
2424 if (!StrCaseCmp(value, "DsPresent")) {
2426 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2429 /* only show the publish check box if we are a
2430 memeber of a AD domain */
2432 if ( lp_security() == SEC_ADS )
2433 SIVAL(*data, 0, 0x01);
2435 SIVAL(*data, 0, 0x00);
2441 if (!StrCaseCmp(value, "DNSMachineName")) {
2442 const char *hostname = get_mydnsfullname();
2445 return WERR_BADFILE;
2447 *needed = 2*(strlen(hostname)+1);
2448 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2450 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2451 for (i=0; i<strlen(hostname); i++) {
2452 (*data)[2*i]=hostname[i];
2453 (*data)[2*i+1]='\0';
2459 return WERR_BADFILE;
2462 /********************************************************************
2463 * spoolss_getprinterdata
2464 ********************************************************************/
2466 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2468 POLICY_HND *handle = &q_u->handle;
2469 UNISTR2 *valuename = &q_u->valuename;
2470 uint32 in_size = q_u->size;
2471 uint32 *type = &r_u->type;
2472 uint32 *out_size = &r_u->size;
2473 uint8 **data = &r_u->data;
2474 uint32 *needed = &r_u->needed;
2477 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2478 NT_PRINTER_INFO_LEVEL *printer = NULL;
2482 * Reminder: when it's a string, the length is in BYTES
2483 * even if UNICODE is negociated.
2488 *out_size = in_size;
2490 /* in case of problem, return some default values */
2495 DEBUG(4,("_spoolss_getprinterdata\n"));
2498 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2499 status = WERR_BADFID;
2503 unistr2_to_ascii(value, valuename, sizeof(value));
2505 if ( Printer->printer_type == SPLHND_SERVER )
2506 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2509 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2510 status = WERR_BADFID;
2514 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2515 if ( !W_ERROR_IS_OK(status) )
2518 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2520 if ( strequal(value, "ChangeId") ) {
2522 *needed = sizeof(uint32);
2523 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2524 status = WERR_NOMEM;
2527 SIVAL( *data, 0, printer->info_2->changeid );
2531 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2534 if (*needed > *out_size)
2535 status = WERR_MORE_DATA;
2538 if ( !W_ERROR_IS_OK(status) )
2540 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2542 /* reply this param doesn't exist */
2545 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2547 free_a_printer( &printer, 2 );
2555 /* cleanup & exit */
2558 free_a_printer( &printer, 2 );
2563 /*********************************************************
2564 Connect to the client machine.
2565 **********************************************************/
2567 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2568 struct sockaddr_storage *client_ss, const char *remote_machine)
2571 struct cli_state *the_cli;
2572 struct sockaddr_storage rm_addr;
2574 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2575 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2576 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2580 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2581 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2585 char addr[INET6_ADDRSTRLEN];
2586 rm_addr = *client_ss;
2587 print_sockaddr(addr, sizeof(addr), &rm_addr);
2588 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2592 /* setup the connection */
2594 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2595 &rm_addr, 0, "IPC$", "IPC",
2599 0, lp_client_signing(), NULL );
2601 if ( !NT_STATUS_IS_OK( ret ) ) {
2602 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2607 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2608 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2609 cli_shutdown(the_cli);
2614 * Ok - we have an anonymous connection to the IPC$ share.
2615 * Now start the NT Domain stuff :-).
2618 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2619 if (!NT_STATUS_IS_OK(ret)) {
2620 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2621 remote_machine, nt_errstr(ret)));
2622 cli_shutdown(the_cli);
2629 /***************************************************************************
2630 Connect to the client.
2631 ****************************************************************************/
2633 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2634 uint32 localprinter, uint32 type,
2635 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2641 * If it's the first connection, contact the client
2642 * and connect to the IPC$ share anonymously
2644 if (smb_connections==0) {
2645 fstring unix_printer;
2647 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2649 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2652 messaging_register(smbd_messaging_context(), NULL,
2653 MSG_PRINTER_NOTIFY2,
2654 receive_notify2_message_list);
2655 /* Tell the connections db we're now interested in printer
2656 * notify messages. */
2657 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2661 * Tell the specific printing tdb we want messages for this printer
2662 * by registering our PID.
2665 if (!print_notify_register_pid(snum))
2666 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2670 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2678 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2679 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2680 win_errstr(result)));
2682 return (W_ERROR_IS_OK(result));
2685 /********************************************************************
2687 * ReplyFindFirstPrinterChangeNotifyEx
2689 * before replying OK: status=0 a rpc call is made to the workstation
2690 * asking ReplyOpenPrinter
2692 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2693 * called from api_spoolss_rffpcnex
2694 ********************************************************************/
2696 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2698 POLICY_HND *handle = &q_u->handle;
2699 uint32 flags = q_u->flags;
2700 uint32 options = q_u->options;
2701 UNISTR2 *localmachine = &q_u->localmachine;
2702 uint32 printerlocal = q_u->printerlocal;
2704 SPOOL_NOTIFY_OPTION *option = q_u->option;
2705 struct sockaddr_storage client_ss;
2707 /* store the notify value in the printer struct */
2709 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2712 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2716 Printer->notify.flags=flags;
2717 Printer->notify.options=options;
2718 Printer->notify.printerlocal=printerlocal;
2720 if (Printer->notify.option)
2721 free_spool_notify_option(&Printer->notify.option);
2723 Printer->notify.option=dup_spool_notify_option(option);
2725 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
2726 sizeof(Printer->notify.localmachine));
2728 /* Connect to the client machine and send a ReplyOpenPrinter */
2730 if ( Printer->printer_type == SPLHND_SERVER)
2732 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2733 !get_printer_snum(p, handle, &snum, NULL) )
2736 if (!interpret_string_addr(&client_ss, p->client_address,
2738 return WERR_SERVER_UNAVAILABLE;
2741 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2742 Printer->notify.printerlocal, 1,
2743 &Printer->notify.client_hnd, &client_ss))
2744 return WERR_SERVER_UNAVAILABLE;
2746 Printer->notify.client_connected=True;
2751 /*******************************************************************
2752 * fill a notify_info_data with the servername
2753 ********************************************************************/
2755 void spoolss_notify_server_name(int snum,
2756 SPOOL_NOTIFY_INFO_DATA *data,
2757 print_queue_struct *queue,
2758 NT_PRINTER_INFO_LEVEL *printer,
2759 TALLOC_CTX *mem_ctx)
2761 smb_ucs2_t *temp = NULL;
2764 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername);
2765 if (len == (uint32)-1) {
2769 data->notify_data.data.length = len;
2771 data->notify_data.data.string = (uint16 *)temp;
2773 data->notify_data.data.string = NULL;
2777 /*******************************************************************
2778 * fill a notify_info_data with the printername (not including the servername).
2779 ********************************************************************/
2781 void spoolss_notify_printer_name(int snum,
2782 SPOOL_NOTIFY_INFO_DATA *data,
2783 print_queue_struct *queue,
2784 NT_PRINTER_INFO_LEVEL *printer,
2785 TALLOC_CTX *mem_ctx)
2787 smb_ucs2_t *temp = NULL;
2790 /* the notify name should not contain the \\server\ part */
2791 char *p = strrchr(printer->info_2->printername, '\\');
2794 p = printer->info_2->printername;
2799 len = rpcstr_push_talloc(mem_ctx, &temp, p);
2800 if (len == (uint32)-1) {
2804 data->notify_data.data.length = len;
2806 data->notify_data.data.string = (uint16 *)temp;
2808 data->notify_data.data.string = NULL;
2812 /*******************************************************************
2813 * fill a notify_info_data with the servicename
2814 ********************************************************************/
2816 void spoolss_notify_share_name(int snum,
2817 SPOOL_NOTIFY_INFO_DATA *data,
2818 print_queue_struct *queue,
2819 NT_PRINTER_INFO_LEVEL *printer,
2820 TALLOC_CTX *mem_ctx)
2822 smb_ucs2_t *temp = NULL;
2825 len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum));
2826 if (len == (uint32)-1) {
2830 data->notify_data.data.length = len;
2832 data->notify_data.data.string = (uint16 *)temp;
2834 data->notify_data.data.string = NULL;
2839 /*******************************************************************
2840 * fill a notify_info_data with the port name
2841 ********************************************************************/
2843 void spoolss_notify_port_name(int snum,
2844 SPOOL_NOTIFY_INFO_DATA *data,
2845 print_queue_struct *queue,
2846 NT_PRINTER_INFO_LEVEL *printer,
2847 TALLOC_CTX *mem_ctx)
2849 smb_ucs2_t *temp = NULL;
2852 /* even if it's strange, that's consistant in all the code */
2854 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname);
2855 if (len == (uint32)-1) {
2859 data->notify_data.data.length = len;
2861 data->notify_data.data.string = (uint16 *)temp;
2863 data->notify_data.data.string = NULL;
2867 /*******************************************************************
2868 * fill a notify_info_data with the printername
2869 * but it doesn't exist, have to see what to do
2870 ********************************************************************/
2872 void spoolss_notify_driver_name(int snum,
2873 SPOOL_NOTIFY_INFO_DATA *data,
2874 print_queue_struct *queue,
2875 NT_PRINTER_INFO_LEVEL *printer,
2876 TALLOC_CTX *mem_ctx)
2878 smb_ucs2_t *temp = NULL;
2881 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername);
2882 if (len == (uint32)-1) {
2886 data->notify_data.data.length = len;
2888 data->notify_data.data.string = (uint16 *)temp;
2890 data->notify_data.data.string = NULL;
2894 /*******************************************************************
2895 * fill a notify_info_data with the comment
2896 ********************************************************************/
2898 void spoolss_notify_comment(int snum,
2899 SPOOL_NOTIFY_INFO_DATA *data,
2900 print_queue_struct *queue,
2901 NT_PRINTER_INFO_LEVEL *printer,
2902 TALLOC_CTX *mem_ctx)
2904 smb_ucs2_t *temp = NULL;
2907 if (*printer->info_2->comment == '\0')
2908 len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum));
2910 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment);
2912 if (len == (uint32)-1) {
2915 data->notify_data.data.length = len;
2917 data->notify_data.data.string = (uint16 *)temp;
2919 data->notify_data.data.string = NULL;
2923 /*******************************************************************
2924 * fill a notify_info_data with the comment
2925 * location = "Room 1, floor 2, building 3"
2926 ********************************************************************/
2928 void spoolss_notify_location(int snum,
2929 SPOOL_NOTIFY_INFO_DATA *data,
2930 print_queue_struct *queue,
2931 NT_PRINTER_INFO_LEVEL *printer,
2932 TALLOC_CTX *mem_ctx)
2934 smb_ucs2_t *temp = NULL;
2937 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location);
2938 if (len == (uint32)-1) {
2942 data->notify_data.data.length = len;
2944 data->notify_data.data.string = (uint16 *)temp;
2946 data->notify_data.data.string = NULL;
2950 /*******************************************************************
2951 * fill a notify_info_data with the device mode
2952 * jfm:xxxx don't to it for know but that's a real problem !!!
2953 ********************************************************************/
2955 static void spoolss_notify_devmode(int snum,
2956 SPOOL_NOTIFY_INFO_DATA *data,
2957 print_queue_struct *queue,
2958 NT_PRINTER_INFO_LEVEL *printer,
2959 TALLOC_CTX *mem_ctx)
2961 /* for a dummy implementation we have to zero the fields */
2962 data->notify_data.data.length = 0;
2963 data->notify_data.data.string = NULL;
2966 /*******************************************************************
2967 * fill a notify_info_data with the separator file name
2968 ********************************************************************/
2970 void spoolss_notify_sepfile(int snum,
2971 SPOOL_NOTIFY_INFO_DATA *data,
2972 print_queue_struct *queue,
2973 NT_PRINTER_INFO_LEVEL *printer,
2974 TALLOC_CTX *mem_ctx)
2976 smb_ucs2_t *temp = NULL;
2979 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile);
2980 if (len == (uint32)-1) {
2984 data->notify_data.data.length = len;
2986 data->notify_data.data.string = (uint16 *)temp;
2988 data->notify_data.data.string = NULL;
2992 /*******************************************************************
2993 * fill a notify_info_data with the print processor
2994 * jfm:xxxx return always winprint to indicate we don't do anything to it
2995 ********************************************************************/
2997 void spoolss_notify_print_processor(int snum,
2998 SPOOL_NOTIFY_INFO_DATA *data,
2999 print_queue_struct *queue,
3000 NT_PRINTER_INFO_LEVEL *printer,
3001 TALLOC_CTX *mem_ctx)
3003 smb_ucs2_t *temp = NULL;
3006 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor);
3007 if (len == (uint32)-1) {
3011 data->notify_data.data.length = len;
3013 data->notify_data.data.string = (uint16 *)temp;
3015 data->notify_data.data.string = NULL;
3019 /*******************************************************************
3020 * fill a notify_info_data with the print processor options
3021 * jfm:xxxx send an empty string
3022 ********************************************************************/
3024 void spoolss_notify_parameters(int snum,
3025 SPOOL_NOTIFY_INFO_DATA *data,
3026 print_queue_struct *queue,
3027 NT_PRINTER_INFO_LEVEL *printer,
3028 TALLOC_CTX *mem_ctx)
3030 smb_ucs2_t *temp = NULL;
3033 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters);
3034 if (len == (uint32)-1) {
3038 data->notify_data.data.length = len;
3040 data->notify_data.data.string = (uint16 *)temp;
3042 data->notify_data.data.string = NULL;
3046 /*******************************************************************
3047 * fill a notify_info_data with the data type
3048 * jfm:xxxx always send RAW as data type
3049 ********************************************************************/
3051 void spoolss_notify_datatype(int snum,
3052 SPOOL_NOTIFY_INFO_DATA *data,
3053 print_queue_struct *queue,
3054 NT_PRINTER_INFO_LEVEL *printer,
3055 TALLOC_CTX *mem_ctx)
3057 smb_ucs2_t *temp = NULL;
3060 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype);
3061 if (len == (uint32)-1) {
3065 data->notify_data.data.length = len;
3067 data->notify_data.data.string = (uint16 *)temp;
3069 data->notify_data.data.string = NULL;
3073 /*******************************************************************
3074 * fill a notify_info_data with the security descriptor
3075 * jfm:xxxx send an null pointer to say no security desc
3076 * have to implement security before !
3077 ********************************************************************/
3079 static void spoolss_notify_security_desc(int snum,
3080 SPOOL_NOTIFY_INFO_DATA *data,
3081 print_queue_struct *queue,
3082 NT_PRINTER_INFO_LEVEL *printer,
3083 TALLOC_CTX *mem_ctx)
3085 data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size;
3086 data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ;
3089 /*******************************************************************
3090 * fill a notify_info_data with the attributes
3091 * jfm:xxxx a samba printer is always shared
3092 ********************************************************************/
3094 void spoolss_notify_attributes(int snum,
3095 SPOOL_NOTIFY_INFO_DATA *data,
3096 print_queue_struct *queue,
3097 NT_PRINTER_INFO_LEVEL *printer,
3098 TALLOC_CTX *mem_ctx)
3100 data->notify_data.value[0] = printer->info_2->attributes;
3101 data->notify_data.value[1] = 0;
3104 /*******************************************************************
3105 * fill a notify_info_data with the priority
3106 ********************************************************************/
3108 static void spoolss_notify_priority(int snum,
3109 SPOOL_NOTIFY_INFO_DATA *data,
3110 print_queue_struct *queue,
3111 NT_PRINTER_INFO_LEVEL *printer,
3112 TALLOC_CTX *mem_ctx)
3114 data->notify_data.value[0] = printer->info_2->priority;
3115 data->notify_data.value[1] = 0;
3118 /*******************************************************************
3119 * fill a notify_info_data with the default priority
3120 ********************************************************************/
3122 static void spoolss_notify_default_priority(int snum,
3123 SPOOL_NOTIFY_INFO_DATA *data,
3124 print_queue_struct *queue,
3125 NT_PRINTER_INFO_LEVEL *printer,
3126 TALLOC_CTX *mem_ctx)
3128 data->notify_data.value[0] = printer->info_2->default_priority;
3129 data->notify_data.value[1] = 0;
3132 /*******************************************************************
3133 * fill a notify_info_data with the start time
3134 ********************************************************************/
3136 static void spoolss_notify_start_time(int snum,
3137 SPOOL_NOTIFY_INFO_DATA *data,
3138 print_queue_struct *queue,
3139 NT_PRINTER_INFO_LEVEL *printer,
3140 TALLOC_CTX *mem_ctx)
3142 data->notify_data.value[0] = printer->info_2->starttime;
3143 data->notify_data.value[1] = 0;
3146 /*******************************************************************
3147 * fill a notify_info_data with the until time
3148 ********************************************************************/
3150 static void spoolss_notify_until_time(int snum,
3151 SPOOL_NOTIFY_INFO_DATA *data,
3152 print_queue_struct *queue,
3153 NT_PRINTER_INFO_LEVEL *printer,
3154 TALLOC_CTX *mem_ctx)
3156 data->notify_data.value[0] = printer->info_2->untiltime;
3157 data->notify_data.value[1] = 0;
3160 /*******************************************************************
3161 * fill a notify_info_data with the status
3162 ********************************************************************/
3164 static void spoolss_notify_status(int snum,
3165 SPOOL_NOTIFY_INFO_DATA *data,
3166 print_queue_struct *queue,
3167 NT_PRINTER_INFO_LEVEL *printer,
3168 TALLOC_CTX *mem_ctx)
3170 print_status_struct status;
3172 print_queue_length(snum, &status);
3173 data->notify_data.value[0]=(uint32) status.status;
3174 data->notify_data.value[1] = 0;
3177 /*******************************************************************
3178 * fill a notify_info_data with the number of jobs queued
3179 ********************************************************************/
3181 void spoolss_notify_cjobs(int snum,
3182 SPOOL_NOTIFY_INFO_DATA *data,
3183 print_queue_struct *queue,
3184 NT_PRINTER_INFO_LEVEL *printer,
3185 TALLOC_CTX *mem_ctx)
3187 data->notify_data.value[0] = print_queue_length(snum, NULL);
3188 data->notify_data.value[1] = 0;
3191 /*******************************************************************
3192 * fill a notify_info_data with the average ppm
3193 ********************************************************************/
3195 static void spoolss_notify_average_ppm(int snum,
3196 SPOOL_NOTIFY_INFO_DATA *data,
3197 print_queue_struct *queue,
3198 NT_PRINTER_INFO_LEVEL *printer,
3199 TALLOC_CTX *mem_ctx)
3201 /* always respond 8 pages per minutes */
3202 /* a little hard ! */
3203 data->notify_data.value[0] = printer->info_2->averageppm;
3204 data->notify_data.value[1] = 0;
3207 /*******************************************************************
3208 * fill a notify_info_data with username
3209 ********************************************************************/
3211 static void spoolss_notify_username(int snum,
3212 SPOOL_NOTIFY_INFO_DATA *data,
3213 print_queue_struct *queue,
3214 NT_PRINTER_INFO_LEVEL *printer,
3215 TALLOC_CTX *mem_ctx)
3217 smb_ucs2_t *temp = NULL;
3220 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user);
3221 if (len == (uint32)-1) {
3225 data->notify_data.data.length = len;
3227 data->notify_data.data.string = (uint16 *)temp;
3229 data->notify_data.data.string = NULL;
3233 /*******************************************************************
3234 * fill a notify_info_data with job status
3235 ********************************************************************/
3237 static void spoolss_notify_job_status(int snum,
3238 SPOOL_NOTIFY_INFO_DATA *data,
3239 print_queue_struct *queue,
3240 NT_PRINTER_INFO_LEVEL *printer,
3241 TALLOC_CTX *mem_ctx)
3243 data->notify_data.value[0]=nt_printj_status(queue->status);
3244 data->notify_data.value[1] = 0;
3247 /*******************************************************************
3248 * fill a notify_info_data with job name
3249 ********************************************************************/
3251 static void spoolss_notify_job_name(int snum,
3252 SPOOL_NOTIFY_INFO_DATA *data,
3253 print_queue_struct *queue,
3254 NT_PRINTER_INFO_LEVEL *printer,
3255 TALLOC_CTX *mem_ctx)
3257 smb_ucs2_t *temp = NULL;
3260 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file);
3261 if (len == (uint32)-1) {
3265 data->notify_data.data.length = len;
3267 data->notify_data.data.string = (uint16 *)temp;
3269 data->notify_data.data.string = NULL;
3273 /*******************************************************************
3274 * fill a notify_info_data with job status
3275 ********************************************************************/
3277 static void spoolss_notify_job_status_string(int snum,
3278 SPOOL_NOTIFY_INFO_DATA *data,
3279 print_queue_struct *queue,
3280 NT_PRINTER_INFO_LEVEL *printer,
3281 TALLOC_CTX *mem_ctx)
3284 * Now we're returning job status codes we just return a "" here. JRA.
3288 smb_ucs2_t *temp = NULL;
3291 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3294 switch (queue->status) {
3299 p = ""; /* NT provides the paused string */
3308 #endif /* NO LONGER NEEDED. */
3310 len = rpcstr_push_talloc(mem_ctx, &temp, p);
3311 if (len == (uint32)-1) {
3315 data->notify_data.data.length = len;
3317 data->notify_data.data.string = (uint16 *)temp;
3319 data->notify_data.data.string = NULL;
3323 /*******************************************************************
3324 * fill a notify_info_data with job time
3325 ********************************************************************/
3327 static void spoolss_notify_job_time(int snum,
3328 SPOOL_NOTIFY_INFO_DATA *data,
3329 print_queue_struct *queue,
3330 NT_PRINTER_INFO_LEVEL *printer,
3331 TALLOC_CTX *mem_ctx)
3333 data->notify_data.value[0]=0x0;
3334 data->notify_data.value[1]=0;
3337 /*******************************************************************
3338 * fill a notify_info_data with job size
3339 ********************************************************************/
3341 static void spoolss_notify_job_size(int snum,
3342 SPOOL_NOTIFY_INFO_DATA *data,
3343 print_queue_struct *queue,
3344 NT_PRINTER_INFO_LEVEL *printer,
3345 TALLOC_CTX *mem_ctx)
3347 data->notify_data.value[0]=queue->size;
3348 data->notify_data.value[1]=0;
3351 /*******************************************************************
3352 * fill a notify_info_data with page info
3353 ********************************************************************/
3354 static void spoolss_notify_total_pages(int snum,
3355 SPOOL_NOTIFY_INFO_DATA *data,
3356 print_queue_struct *queue,
3357 NT_PRINTER_INFO_LEVEL *printer,
3358 TALLOC_CTX *mem_ctx)
3360 data->notify_data.value[0]=queue->page_count;
3361 data->notify_data.value[1]=0;
3364 /*******************************************************************
3365 * fill a notify_info_data with pages printed info.
3366 ********************************************************************/
3367 static void spoolss_notify_pages_printed(int snum,
3368 SPOOL_NOTIFY_INFO_DATA *data,
3369 print_queue_struct *queue,
3370 NT_PRINTER_INFO_LEVEL *printer,
3371 TALLOC_CTX *mem_ctx)
3373 data->notify_data.value[0]=0; /* Add code when back-end tracks this */
3374 data->notify_data.value[1]=0;
3377 /*******************************************************************
3378 Fill a notify_info_data with job position.
3379 ********************************************************************/
3381 static void spoolss_notify_job_position(int snum,
3382 SPOOL_NOTIFY_INFO_DATA *data,
3383 print_queue_struct *queue,
3384 NT_PRINTER_INFO_LEVEL *printer,
3385 TALLOC_CTX *mem_ctx)
3387 data->notify_data.value[0]=queue->job;
3388 data->notify_data.value[1]=0;
3391 /*******************************************************************
3392 Fill a notify_info_data with submitted time.
3393 ********************************************************************/
3395 static void spoolss_notify_submitted_time(int snum,
3396 SPOOL_NOTIFY_INFO_DATA *data,
3397 print_queue_struct *queue,
3398 NT_PRINTER_INFO_LEVEL *printer,
3399 TALLOC_CTX *mem_ctx)
3406 t=gmtime(&queue->time);
3408 len = sizeof(SYSTEMTIME);
3410 data->notify_data.data.length = len;
3411 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
3413 if (!data->notify_data.data.string) {
3414 data->notify_data.data.length = 0;
3418 make_systemtime(&st, t);
3421 * Systemtime must be linearized as a set of UINT16's.
3422 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3425 p = (char *)data->notify_data.data.string;
3426 SSVAL(p, 0, st.year);
3427 SSVAL(p, 2, st.month);
3428 SSVAL(p, 4, st.dayofweek);
3429 SSVAL(p, 6, st.day);
3430 SSVAL(p, 8, st.hour);
3431 SSVAL(p, 10, st.minute);
3432 SSVAL(p, 12, st.second);
3433 SSVAL(p, 14, st.milliseconds);
3436 struct s_notify_info_data_table
3442 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
3443 print_queue_struct *queue,
3444 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3447 /* A table describing the various print notification constants and
3448 whether the notification data is a pointer to a variable sized
3449 buffer, a one value uint32 or a two value uint32. */
3451 static const struct s_notify_info_data_table notify_info_data_table[] =
3453 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3454 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3455 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
3456 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3457 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3458 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
3459 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
3460 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3461 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
3462 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3463 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3464 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3465 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
3466 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
3467 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3468 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
3469 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3470 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3471 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
3472 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
3473 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
3474 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
3475 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
3476 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
3477 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
3478 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
3479 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3480 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3481 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3482 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
3483 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
3484 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3485 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3486 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3487 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3488 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3489 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
3490 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
3491 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
3492 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
3493 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3494 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
3495 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
3496 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3497 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3498 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
3499 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
3500 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
3501 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
3502 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3505 /*******************************************************************
3506 Return the size of info_data structure.
3507 ********************************************************************/
3509 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
3513 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3514 if ( (notify_info_data_table[i].type == type)
3515 && (notify_info_data_table[i].field == field) ) {
3516 switch(notify_info_data_table[i].size) {
3517 case NOTIFY_ONE_VALUE:
3518 case NOTIFY_TWO_VALUE:
3523 /* The only pointer notify data I have seen on
3524 the wire is the submitted time and this has
3525 the notify size set to 4. -tpot */
3527 case NOTIFY_POINTER:
3530 case NOTIFY_SECDESC:
3536 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3541 /*******************************************************************
3542 Return the type of notify_info_data.
3543 ********************************************************************/
3545 static uint32 type_of_notify_info_data(uint16 type, uint16 field)
3549 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3550 if (notify_info_data_table[i].type == type &&
3551 notify_info_data_table[i].field == field)
3552 return notify_info_data_table[i].size;
3558 /****************************************************************************
3559 ****************************************************************************/
3561 static bool search_notify(uint16 type, uint16 field, int *value)
3565 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3566 if (notify_info_data_table[i].type == type &&
3567 notify_info_data_table[i].field == field &&
3568 notify_info_data_table[i].fn != NULL) {
3577 /****************************************************************************
3578 ****************************************************************************/
3580 void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
3582 info_data->type = type;
3583 info_data->field = field;
3584 info_data->reserved = 0;
3586 info_data->size = size_of_notify_info_data(type, field);
3587 info_data->enc_type = type_of_notify_info_data(type, field);
3592 /*******************************************************************
3594 * fill a notify_info struct with info asked
3596 ********************************************************************/
3598 static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
3599 snum, SPOOL_NOTIFY_OPTION_TYPE
3600 *option_type, uint32 id,
3601 TALLOC_CTX *mem_ctx)
3607 SPOOL_NOTIFY_INFO_DATA *current_data;
3608 NT_PRINTER_INFO_LEVEL *printer = NULL;
3609 print_queue_struct *queue=NULL;
3611 type=option_type->type;
3613 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3614 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3615 option_type->count, lp_servicename(snum)));
3617 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3620 for(field_num=0; field_num<option_type->count; field_num++) {
3621 field = option_type->fields[field_num];
3623 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3625 if (!search_notify(type, field, &j) )
3628 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3629 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3630 free_a_printer(&printer, 2);
3634 current_data = &info->data[info->count];
3636 construct_info_data(current_data, type, field, id);
3638 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3639 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3641 notify_info_data_table[j].fn(snum, current_data, queue,
3647 free_a_printer(&printer, 2);
3651 /*******************************************************************
3653 * fill a notify_info struct with info asked
3655 ********************************************************************/
3657 static bool construct_notify_jobs_info(print_queue_struct *queue,
3658 SPOOL_NOTIFY_INFO *info,
3659 NT_PRINTER_INFO_LEVEL *printer,
3660 int snum, SPOOL_NOTIFY_OPTION_TYPE
3661 *option_type, uint32 id,
3662 TALLOC_CTX *mem_ctx)
3668 SPOOL_NOTIFY_INFO_DATA *current_data;
3670 DEBUG(4,("construct_notify_jobs_info\n"));
3672 type = option_type->type;
3674 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3675 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3676 option_type->count));
3678 for(field_num=0; field_num<option_type->count; field_num++) {
3679 field = option_type->fields[field_num];
3681 if (!search_notify(type, field, &j) )
3684 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3685 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3689 current_data=&(info->data[info->count]);
3691 construct_info_data(current_data, type, field, id);
3692 notify_info_data_table[j].fn(snum, current_data, queue,
3701 * JFM: The enumeration is not that simple, it's even non obvious.
3703 * let's take an example: I want to monitor the PRINTER SERVER for
3704 * the printer's name and the number of jobs currently queued.
3705 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3706 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3708 * I have 3 printers on the back of my server.
3710 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3713 * 1 printer 1 name 1
3714 * 2 printer 1 cjob 1
3715 * 3 printer 2 name 2
3716 * 4 printer 2 cjob 2
3717 * 5 printer 3 name 3
3718 * 6 printer 3 name 3
3720 * that's the print server case, the printer case is even worse.
3723 /*******************************************************************
3725 * enumerate all printers on the printserver
3726 * fill a notify_info struct with info asked
3728 ********************************************************************/
3730 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3731 SPOOL_NOTIFY_INFO *info,
3732 TALLOC_CTX *mem_ctx)
3735 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3736 int n_services=lp_numservices();
3738 SPOOL_NOTIFY_OPTION *option;
3739 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3741 DEBUG(4,("printserver_notify_info\n"));
3746 option=Printer->notify.option;
3751 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3752 sending a ffpcn() request first */
3757 for (i=0; i<option->count; i++) {
3758 option_type=&(option->ctr.type[i]);
3760 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3763 for (snum=0; snum<n_services; snum++)
3765 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3766 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3772 * Debugging information, don't delete.
3775 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3776 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3777 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3779 for (i=0; i<info->count; i++) {
3780 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3781 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3782 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3789 /*******************************************************************
3791 * fill a notify_info struct with info asked
3793 ********************************************************************/
3795 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
3796 TALLOC_CTX *mem_ctx)
3799 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3802 SPOOL_NOTIFY_OPTION *option;
3803 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3805 print_queue_struct *queue=NULL;
3806 print_status_struct status;
3808 DEBUG(4,("printer_notify_info\n"));
3813 option=Printer->notify.option;
3819 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3820 sending a ffpcn() request first */
3825 get_printer_snum(p, hnd, &snum, NULL);
3827 for (i=0; i<option->count; i++) {
3828 option_type=&option->ctr.type[i];
3830 switch ( option_type->type ) {
3831 case PRINTER_NOTIFY_TYPE:
3832 if(construct_notify_printer_info(Printer, info, snum,
3838 case JOB_NOTIFY_TYPE: {
3839 NT_PRINTER_INFO_LEVEL *printer = NULL;
3841 count = print_queue_status(snum, &queue, &status);
3843 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3846 for (j=0; j<count; j++) {
3847 construct_notify_jobs_info(&queue[j], info,
3854 free_a_printer(&printer, 2);
3864 * Debugging information, don't delete.
3867 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3868 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3869 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3871 for (i=0; i<info->count; i++) {
3872 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3873 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3874 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3880 /********************************************************************
3882 ********************************************************************/
3884 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
3886 POLICY_HND *handle = &q_u->handle;
3887 SPOOL_NOTIFY_INFO *info = &r_u->info;
3889 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3890 WERROR result = WERR_BADFID;
3892 /* we always have a NOTIFY_INFO struct */
3896 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3897 OUR_HANDLE(handle)));
3901 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3904 * We are now using the change value, and
3905 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3906 * I don't have a global notification system, I'm sending back all the
3907 * informations even when _NOTHING_ has changed.
3910 /* We need to keep track of the change value to send back in
3911 RRPCN replies otherwise our updates are ignored. */
3913 Printer->notify.fnpcn = True;
3915 if (Printer->notify.client_connected) {
3916 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
3917 Printer->notify.change = q_u->change;
3920 /* just ignore the SPOOL_NOTIFY_OPTION */
3922 switch (Printer->printer_type) {
3924 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3927 case SPLHND_PRINTER:
3928 result = printer_notify_info(p, handle, info, p->mem_ctx);
3932 Printer->notify.fnpcn = False;
3938 /********************************************************************
3939 * construct_printer_info_0
3940 * fill a printer_info_0 struct
3941 ********************************************************************/
3943 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3945 char *chaine = NULL;
3947 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3948 counter_printer_0 *session_counter;
3949 uint32 global_counter;
3952 print_status_struct status;
3953 TALLOC_CTX *ctx = talloc_tos();
3955 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3958 init_unistr(&printer->printername, ntprinter->info_2->printername);
3960 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3962 free_a_printer(&ntprinter,2);
3966 count = print_queue_length(snum, &status);
3968 /* check if we already have a counter for this printer */
3969 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3970 if (session_counter->snum == snum)
3974 init_unistr(&printer->servername, chaine);
3976 /* it's the first time, add it to the list */
3977 if (session_counter==NULL) {
3978 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3979 free_a_printer(&ntprinter, 2);
3982 ZERO_STRUCTP(session_counter);
3983 session_counter->snum=snum;
3984 session_counter->counter=0;
3985 DLIST_ADD(counter_list, session_counter);
3989 session_counter->counter++;
3992 * the global_counter should be stored in a TDB as it's common to all the clients
3993 * and should be zeroed on samba startup
3995 global_counter=session_counter->counter;
3996 printer->cjobs = count;
3997 printer->total_jobs = 0;
3998 printer->total_bytes = 0;
4000 setuptime = (time_t)ntprinter->info_2->setuptime;
4001 t=gmtime(&setuptime);
4003 printer->year = t->tm_year+1900;
4004 printer->month = t->tm_mon+1;
4005 printer->dayofweek = t->tm_wday;
4006 printer->day = t->tm_mday;
4007 printer->hour = t->tm_hour;
4008 printer->minute = t->tm_min;
4009 printer->second = t->tm_sec;
4010 printer->milliseconds = 0;
4012 printer->global_counter = global_counter;
4013 printer->total_pages = 0;
4015 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
4016 printer->major_version = 0x0005; /* NT 5 */
4017 printer->build_version = 0x0893; /* build 2195 */
4019 printer->unknown7 = 0x1;
4020 printer->unknown8 = 0x0;
4021 printer->unknown9 = 0x0;
4022 printer->session_counter = session_counter->counter;
4023 printer->unknown11 = 0x0;
4024 printer->printer_errors = 0x0; /* number of print failure */
4025 printer->unknown13 = 0x0;
4026 printer->unknown14 = 0x1;
4027 printer->unknown15 = 0x024a; /* 586 Pentium ? */
4028 printer->unknown16 = 0x0;
4029 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
4030 printer->unknown18 = 0x0;
4031 printer->status = nt_printq_status(status.status);
4032 printer->unknown20 = 0x0;
4033 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4034 printer->unknown22 = 0x0;
4035 printer->unknown23 = 0x6; /* 6 ???*/
4036 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
4037 printer->unknown25 = 0;
4038 printer->unknown26 = 0;
4039 printer->unknown27 = 0;
4040 printer->unknown28 = 0;
4041 printer->unknown29 = 0;
4043 free_a_printer(&ntprinter,2);
4047 /********************************************************************
4048 * construct_printer_info_1
4049 * fill a printer_info_1 struct
4050 ********************************************************************/
4051 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4053 char *chaine = NULL;
4054 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4055 TALLOC_CTX *ctx = talloc_tos();
4057 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4060 printer->flags=flags;
4062 if (*ntprinter->info_2->comment == '\0') {
4063 init_unistr(&printer->comment, lp_comment(snum));
4064 chaine = talloc_asprintf(ctx,
4065 "%s,%s,%s", ntprinter->info_2->printername,
4066 ntprinter->info_2->drivername, lp_comment(snum));
4069 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4070 chaine = talloc_asprintf(ctx,
4071 "%s,%s,%s", ntprinter->info_2->printername,
4072 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4076 free_a_printer(&ntprinter,2);
4080 init_unistr(&printer->description, chaine);
4081 init_unistr(&printer->name, ntprinter->info_2->printername);
4083 free_a_printer(&ntprinter,2);
4088 /****************************************************************************
4089 Free a DEVMODE struct.
4090 ****************************************************************************/
4092 static void free_dev_mode(DEVICEMODE *dev)
4097 SAFE_FREE(dev->dev_private);
4102 /****************************************************************************
4103 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4104 should be valid upon entry
4105 ****************************************************************************/
4107 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4109 if ( !devmode || !ntdevmode )
4112 init_unistr(&devmode->devicename, ntdevmode->devicename);
4114 init_unistr(&devmode->formname, ntdevmode->formname);
4116 devmode->specversion = ntdevmode->specversion;
4117 devmode->driverversion = ntdevmode->driverversion;
4118 devmode->size = ntdevmode->size;
4119 devmode->driverextra = ntdevmode->driverextra;
4120 devmode->fields = ntdevmode->fields;
4122 devmode->orientation = ntdevmode->orientation;
4123 devmode->papersize = ntdevmode->papersize;
4124 devmode->paperlength = ntdevmode->paperlength;
4125 devmode->paperwidth = ntdevmode->paperwidth;
4126 devmode->scale = ntdevmode->scale;
4127 devmode->copies = ntdevmode->copies;
4128 devmode->defaultsource = ntdevmode->defaultsource;
4129 devmode->printquality = ntdevmode->printquality;
4130 devmode->color = ntdevmode->color;
4131 devmode->duplex = ntdevmode->duplex;
4132 devmode->yresolution = ntdevmode->yresolution;
4133 devmode->ttoption = ntdevmode->ttoption;
4134 devmode->collate = ntdevmode->collate;
4135 devmode->icmmethod = ntdevmode->icmmethod;
4136 devmode->icmintent = ntdevmode->icmintent;
4137 devmode->mediatype = ntdevmode->mediatype;
4138 devmode->dithertype = ntdevmode->dithertype;
4140 if (ntdevmode->nt_dev_private != NULL) {
4141 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4148 /****************************************************************************
4149 Create a DEVMODE struct. Returns malloced memory.
4150 ****************************************************************************/
4152 DEVICEMODE *construct_dev_mode(const char *servicename)
4154 NT_PRINTER_INFO_LEVEL *printer = NULL;
4155 DEVICEMODE *devmode = NULL;
4157 DEBUG(7,("construct_dev_mode\n"));
4159 DEBUGADD(8,("getting printer characteristics\n"));
4161 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4164 if ( !printer->info_2->devmode ) {
4165 DEBUG(5, ("BONG! There was no device mode!\n"));
4169 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4170 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4174 ZERO_STRUCTP(devmode);
4176 DEBUGADD(8,("loading DEVICEMODE\n"));
4178 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4179 free_dev_mode( devmode );
4184 free_a_printer(&printer,2);
4189 /********************************************************************
4190 * construct_printer_info_2
4191 * fill a printer_info_2 struct
4192 ********************************************************************/
4194 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4197 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4199 print_status_struct status;
4201 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4204 count = print_queue_length(snum, &status);
4206 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4207 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4208 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4209 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4210 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4212 if (*ntprinter->info_2->comment == '\0')
4213 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4215 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4217 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4218 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4219 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4220 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4221 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4223 printer->attributes = ntprinter->info_2->attributes;
4225 printer->priority = ntprinter->info_2->priority; /* priority */
4226 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4227 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4228 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4229 printer->status = nt_printq_status(status.status); /* status */
4230 printer->cjobs = count; /* jobs */
4231 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4233 if ( !(printer->devmode = construct_dev_mode(
4234 lp_const_servicename(snum))) )
4235 DEBUG(8, ("Returning NULL Devicemode!\n"));
4237 printer->secdesc = NULL;
4239 if ( ntprinter->info_2->secdesc_buf
4240 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4242 /* don't use talloc_steal() here unless you do a deep steal of all
4243 the SEC_DESC members */
4245 printer->secdesc = dup_sec_desc( talloc_tos(),
4246 ntprinter->info_2->secdesc_buf->sd );
4249 free_a_printer(&ntprinter, 2);
4254 /********************************************************************
4255 * construct_printer_info_3
4256 * fill a printer_info_3 struct
4257 ********************************************************************/
4259 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4261 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4262 PRINTER_INFO_3 *printer = NULL;
4264 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4268 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4269 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4270 free_a_printer(&ntprinter, 2);
4274 ZERO_STRUCTP(printer);
4276 /* These are the components of the SD we are returning. */
4278 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4279 /* don't use talloc_steal() here unless you do a deep steal of all
4280 the SEC_DESC members */
4282 printer->secdesc = dup_sec_desc( talloc_tos(),
4283 ntprinter->info_2->secdesc_buf->sd );
4286 free_a_printer(&ntprinter, 2);
4288 *pp_printer = printer;
4292 /********************************************************************
4293 * construct_printer_info_4
4294 * fill a printer_info_4 struct
4295 ********************************************************************/
4297 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4299 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4301 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4304 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4305 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4306 printer->attributes = ntprinter->info_2->attributes;
4308 free_a_printer(&ntprinter, 2);
4312 /********************************************************************
4313 * construct_printer_info_5
4314 * fill a printer_info_5 struct
4315 ********************************************************************/
4317 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4319 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4321 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4324 init_unistr(&printer->printername, ntprinter->info_2->printername);
4325 init_unistr(&printer->portname, ntprinter->info_2->portname);
4326 printer->attributes = ntprinter->info_2->attributes;
4328 /* these two are not used by NT+ according to MSDN */
4330 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4331 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4333 free_a_printer(&ntprinter, 2);
4338 /********************************************************************
4339 * construct_printer_info_6
4340 * fill a printer_info_6 struct
4341 ********************************************************************/
4343 static bool construct_printer_info_6(Printer_entry *print_hnd,
4344 PRINTER_INFO_6 *printer,
4347 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4349 print_status_struct status;
4351 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4352 lp_const_servicename(snum))))
4355 count = print_queue_length(snum, &status);
4357 printer->status = nt_printq_status(status.status);
4359 free_a_printer(&ntprinter, 2);
4364 /********************************************************************
4365 * construct_printer_info_7
4366 * fill a printer_info_7 struct
4367 ********************************************************************/
4369 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4371 char *guid_str = NULL;
4374 if (is_printer_published(print_hnd, snum, &guid)) {
4375 if (asprintf(&guid_str, "{%s}",
4376 GUID_string(talloc_tos(), &guid)) == -1) {
4379 strupper_m(guid_str);
4380 init_unistr(&printer->guid, guid_str);
4381 SAFE_FREE(guid_str);
4382 printer->action = SPOOL_DS_PUBLISH;
4384 init_unistr(&printer->guid, "");
4385 printer->action = SPOOL_DS_UNPUBLISH;
4391 /********************************************************************
4392 Spoolss_enumprinters.
4393 ********************************************************************/
4395 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4399 int n_services=lp_numservices();
4400 PRINTER_INFO_1 *printers=NULL;
4401 PRINTER_INFO_1 current_prt;
4402 WERROR result = WERR_OK;
4404 DEBUG(4,("enum_all_printers_info_1\n"));
4406 for (snum=0; snum<n_services; snum++) {
4407 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4408 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4410 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4411 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4412 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4416 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4418 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4424 /* check the required size. */
4425 for (i=0; i<*returned; i++)
4426 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4428 if (*needed > offered) {
4429 result = WERR_INSUFFICIENT_BUFFER;
4433 if (!rpcbuf_alloc_size(buffer, *needed)) {
4434 result = WERR_NOMEM;
4438 /* fill the buffer with the structures */
4439 for (i=0; i<*returned; i++)
4440 smb_io_printer_info_1("", buffer, &printers[i], 0);
4445 SAFE_FREE(printers);
4447 if ( !W_ERROR_IS_OK(result) )
4453 /********************************************************************
4454 enum_all_printers_info_1_local.
4455 *********************************************************************/
4457 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4459 DEBUG(4,("enum_all_printers_info_1_local\n"));
4461 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4464 /********************************************************************
4465 enum_all_printers_info_1_name.
4466 *********************************************************************/
4468 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4472 DEBUG(4,("enum_all_printers_info_1_name\n"));
4474 if ((name[0] == '\\') && (name[1] == '\\'))
4477 if (is_myname_or_ipaddr(s)) {
4478 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4481 return WERR_INVALID_NAME;
4484 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4485 /********************************************************************
4486 enum_all_printers_info_1_remote.
4487 *********************************************************************/
4489 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4491 PRINTER_INFO_1 *printer;
4492 fstring printername;
4495 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4496 WERROR result = WERR_OK;
4498 /* JFM: currently it's more a place holder than anything else.
4499 * In the spooler world there is a notion of server registration.
4500 * the print servers are registered on the PDC (in the same domain)
4502 * We should have a TDB here. The registration is done thru an
4503 * undocumented RPC call.
4506 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4511 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4512 slprintf(desc, sizeof(desc)-1,"%s", name);
4513 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4515 init_unistr(&printer->description, desc);
4516 init_unistr(&printer->name, printername);
4517 init_unistr(&printer->comment, comment);
4518 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4520 /* check the required size. */
4521 *needed += spoolss_size_printer_info_1(printer);
4523 if (*needed > offered) {
4524 result = WERR_INSUFFICIENT_BUFFER;
4528 if (!rpcbuf_alloc_size(buffer, *needed)) {
4529 result = WERR_NOMEM;
4533 /* fill the buffer with the structures */
4534 smb_io_printer_info_1("", buffer, printer, 0);
4540 if ( !W_ERROR_IS_OK(result) )
4548 /********************************************************************
4549 enum_all_printers_info_1_network.
4550 *********************************************************************/
4552 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4556 DEBUG(4,("enum_all_printers_info_1_network\n"));
4558 /* If we respond to a enum_printers level 1 on our name with flags
4559 set to PRINTER_ENUM_REMOTE with a list of printers then these
4560 printers incorrectly appear in the APW browse list.
4561 Specifically the printers for the server appear at the workgroup
4562 level where all the other servers in the domain are
4563 listed. Windows responds to this call with a
4564 WERR_CAN_NOT_COMPLETE so we should do the same. */
4566 if (name[0] == '\\' && name[1] == '\\')
4569 if (is_myname_or_ipaddr(s))
4570 return WERR_CAN_NOT_COMPLETE;
4572 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4575 /********************************************************************
4576 * api_spoolss_enumprinters
4578 * called from api_spoolss_enumprinters (see this to understand)
4579 ********************************************************************/
4581 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4585 int n_services=lp_numservices();
4586 PRINTER_INFO_2 *printers=NULL;
4587 PRINTER_INFO_2 current_prt;
4588 WERROR result = WERR_OK;
4592 for (snum=0; snum<n_services; snum++) {
4593 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4594 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4596 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4597 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4598 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4603 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4605 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4612 /* check the required size. */
4613 for (i=0; i<*returned; i++)
4614 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4616 if (*needed > offered) {
4617 result = WERR_INSUFFICIENT_BUFFER;
4621 if (!rpcbuf_alloc_size(buffer, *needed)) {
4622 result = WERR_NOMEM;
4626 /* fill the buffer with the structures */
4627 for (i=0; i<*returned; i++)
4628 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4633 for (i=0; i<*returned; i++)
4634 free_devmode(printers[i].devmode);
4636 SAFE_FREE(printers);
4638 if ( !W_ERROR_IS_OK(result) )
4644 /********************************************************************
4645 * handle enumeration of printers at level 1
4646 ********************************************************************/
4648 static WERROR enumprinters_level1( uint32 flags, fstring name,
4649 RPC_BUFFER *buffer, uint32 offered,
4650 uint32 *needed, uint32 *returned)
4652 /* Not all the flags are equals */
4654 if (flags & PRINTER_ENUM_LOCAL)
4655 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4657 if (flags & PRINTER_ENUM_NAME)
4658 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4660 #if 0 /* JERRY - disabled for now */
4661 if (flags & PRINTER_ENUM_REMOTE)
4662 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4665 if (flags & PRINTER_ENUM_NETWORK)
4666 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4668 return WERR_OK; /* NT4sp5 does that */
4671 /********************************************************************
4672 * handle enumeration of printers at level 2
4673 ********************************************************************/
4675 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4676 RPC_BUFFER *buffer, uint32 offered,
4677 uint32 *needed, uint32 *returned)
4679 if (flags & PRINTER_ENUM_LOCAL) {
4680 return enum_all_printers_info_2(buffer, offered, needed, returned);
4683 if (flags & PRINTER_ENUM_NAME) {
4684 if (is_myname_or_ipaddr(canon_servername(servername)))
4685 return enum_all_printers_info_2(buffer, offered, needed, returned);
4687 return WERR_INVALID_NAME;
4690 if (flags & PRINTER_ENUM_REMOTE)
4691 return WERR_UNKNOWN_LEVEL;
4696 /********************************************************************
4697 * handle enumeration of printers at level 5
4698 ********************************************************************/
4700 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4701 RPC_BUFFER *buffer, uint32 offered,
4702 uint32 *needed, uint32 *returned)
4704 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4708 /********************************************************************
4709 * api_spoolss_enumprinters
4711 * called from api_spoolss_enumprinters (see this to understand)
4712 ********************************************************************/
4714 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4716 uint32 flags = q_u->flags;
4717 UNISTR2 *servername = &q_u->servername;
4718 uint32 level = q_u->level;
4719 RPC_BUFFER *buffer = NULL;
4720 uint32 offered = q_u->offered;
4721 uint32 *needed = &r_u->needed;
4722 uint32 *returned = &r_u->returned;
4726 /* that's an [in out] buffer */
4728 if (!q_u->buffer && (offered!=0)) {
4729 return WERR_INVALID_PARAM;
4732 if (offered > MAX_RPC_DATA_SIZE) {
4733 return WERR_INVALID_PARAM;
4736 rpcbuf_move(q_u->buffer, &r_u->buffer);
4737 buffer = r_u->buffer;
4739 DEBUG(4,("_spoolss_enumprinters\n"));
4746 * flags==PRINTER_ENUM_NAME
4747 * if name=="" then enumerates all printers
4748 * if name!="" then enumerate the printer
4749 * flags==PRINTER_ENUM_REMOTE
4750 * name is NULL, enumerate printers
4751 * Level 2: name!="" enumerates printers, name can't be NULL
4752 * Level 3: doesn't exist
4753 * Level 4: does a local registry lookup
4754 * Level 5: same as Level 2
4757 unistr2_to_ascii(name, servername, sizeof(name));
4762 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4764 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4766 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4771 return WERR_UNKNOWN_LEVEL;
4774 /****************************************************************************
4775 ****************************************************************************/
4777 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4779 PRINTER_INFO_0 *printer=NULL;
4780 WERROR result = WERR_OK;
4782 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4785 construct_printer_info_0(print_hnd, printer, snum);
4787 /* check the required size. */
4788 *needed += spoolss_size_printer_info_0(printer);
4790 if (*needed > offered) {
4791 result = WERR_INSUFFICIENT_BUFFER;
4795 if (!rpcbuf_alloc_size(buffer, *needed)) {
4796 result = WERR_NOMEM;
4800 /* fill the buffer with the structures */
4801 smb_io_printer_info_0("", buffer, printer, 0);
4811 /****************************************************************************
4812 ****************************************************************************/
4814 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4816 PRINTER_INFO_1 *printer=NULL;
4817 WERROR result = WERR_OK;
4819 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4822 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4824 /* check the required size. */
4825 *needed += spoolss_size_printer_info_1(printer);
4827 if (*needed > offered) {
4828 result = WERR_INSUFFICIENT_BUFFER;
4832 if (!rpcbuf_alloc_size(buffer, *needed)) {
4833 result = WERR_NOMEM;
4837 /* fill the buffer with the structures */
4838 smb_io_printer_info_1("", buffer, printer, 0);
4847 /****************************************************************************
4848 ****************************************************************************/
4850 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4852 PRINTER_INFO_2 *printer=NULL;
4853 WERROR result = WERR_OK;
4855 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4858 construct_printer_info_2(print_hnd, printer, snum);
4860 /* check the required size. */
4861 *needed += spoolss_size_printer_info_2(printer);
4863 if (*needed > offered) {
4864 result = WERR_INSUFFICIENT_BUFFER;
4868 if (!rpcbuf_alloc_size(buffer, *needed)) {
4869 result = WERR_NOMEM;
4873 /* fill the buffer with the structures */
4874 if (!smb_io_printer_info_2("", buffer, printer, 0))
4875 result = WERR_NOMEM;
4879 free_printer_info_2(printer);
4884 /****************************************************************************
4885 ****************************************************************************/
4887 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4889 PRINTER_INFO_3 *printer=NULL;
4890 WERROR result = WERR_OK;
4892 if (!construct_printer_info_3(print_hnd, &printer, snum))
4895 /* check the required size. */
4896 *needed += spoolss_size_printer_info_3(printer);
4898 if (*needed > offered) {
4899 result = WERR_INSUFFICIENT_BUFFER;
4903 if (!rpcbuf_alloc_size(buffer, *needed)) {
4904 result = WERR_NOMEM;
4908 /* fill the buffer with the structures */
4909 smb_io_printer_info_3("", buffer, printer, 0);
4913 free_printer_info_3(printer);
4918 /****************************************************************************
4919 ****************************************************************************/
4921 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4923 PRINTER_INFO_4 *printer=NULL;
4924 WERROR result = WERR_OK;
4926 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4929 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4934 /* check the required size. */
4935 *needed += spoolss_size_printer_info_4(printer);
4937 if (*needed > offered) {
4938 result = WERR_INSUFFICIENT_BUFFER;
4942 if (!rpcbuf_alloc_size(buffer, *needed)) {
4943 result = WERR_NOMEM;
4947 /* fill the buffer with the structures */
4948 smb_io_printer_info_4("", buffer, printer, 0);
4952 free_printer_info_4(printer);
4957 /****************************************************************************
4958 ****************************************************************************/
4960 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4962 PRINTER_INFO_5 *printer=NULL;
4963 WERROR result = WERR_OK;
4965 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4968 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4969 free_printer_info_5(printer);
4973 /* check the required size. */
4974 *needed += spoolss_size_printer_info_5(printer);
4976 if (*needed > offered) {
4977 result = WERR_INSUFFICIENT_BUFFER;
4981 if (!rpcbuf_alloc_size(buffer, *needed)) {
4982 result = WERR_NOMEM;
4986 /* fill the buffer with the structures */
4987 smb_io_printer_info_5("", buffer, printer, 0);
4991 free_printer_info_5(printer);
4996 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4998 RPC_BUFFER *buffer, uint32 offered,
5001 PRINTER_INFO_6 *printer;
5002 WERROR result = WERR_OK;
5004 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
5008 if (!construct_printer_info_6(print_hnd, printer, snum)) {
5009 free_printer_info_6(printer);
5013 /* check the required size. */
5014 *needed += spoolss_size_printer_info_6(printer);
5016 if (*needed > offered) {
5017 result = WERR_INSUFFICIENT_BUFFER;
5021 if (!rpcbuf_alloc_size(buffer, *needed)) {
5022 result = WERR_NOMEM;
5026 /* fill the buffer with the structures */
5027 smb_io_printer_info_6("", buffer, printer, 0);
5031 free_printer_info_6(printer);
5036 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5038 PRINTER_INFO_7 *printer=NULL;
5039 WERROR result = WERR_OK;
5041 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5044 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5045 result = WERR_NOMEM;
5049 /* check the required size. */
5050 *needed += spoolss_size_printer_info_7(printer);
5052 if (*needed > offered) {
5053 result = WERR_INSUFFICIENT_BUFFER;
5057 if (!rpcbuf_alloc_size(buffer, *needed)) {
5058 result = WERR_NOMEM;
5063 /* fill the buffer with the structures */
5064 smb_io_printer_info_7("", buffer, printer, 0);
5068 free_printer_info_7(printer);
5073 /****************************************************************************
5074 ****************************************************************************/
5076 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5078 POLICY_HND *handle = &q_u->handle;
5079 uint32 level = q_u->level;
5080 RPC_BUFFER *buffer = NULL;
5081 uint32 offered = q_u->offered;
5082 uint32 *needed = &r_u->needed;
5083 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5087 /* that's an [in out] buffer */
5089 if (!q_u->buffer && (offered!=0)) {
5090 return WERR_INVALID_PARAM;
5093 if (offered > MAX_RPC_DATA_SIZE) {
5094 return WERR_INVALID_PARAM;
5097 rpcbuf_move(q_u->buffer, &r_u->buffer);
5098 buffer = r_u->buffer;
5102 if (!get_printer_snum(p, handle, &snum, NULL))
5107 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5109 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5111 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5113 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5115 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5117 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5119 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5121 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5123 return WERR_UNKNOWN_LEVEL;
5126 /********************************************************************
5127 * fill a DRIVER_INFO_1 struct
5128 ********************************************************************/
5130 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5132 init_unistr( &info->name, driver.info_3->name);
5135 /********************************************************************
5136 * construct_printer_driver_info_1
5137 ********************************************************************/
5139 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5141 NT_PRINTER_INFO_LEVEL *printer = NULL;
5142 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5144 ZERO_STRUCT(driver);
5146 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5147 return WERR_INVALID_PRINTER_NAME;
5149 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5150 free_a_printer(&printer, 2);
5151 return WERR_UNKNOWN_PRINTER_DRIVER;
5154 fill_printer_driver_info_1(info, driver, servername, architecture);
5156 free_a_printer(&printer,2);
5161 /********************************************************************
5162 * construct_printer_driver_info_2
5163 * fill a printer_info_2 struct
5164 ********************************************************************/
5166 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5168 TALLOC_CTX *ctx = talloc_tos();
5170 const char *cservername = canon_servername(servername);
5172 info->version=driver.info_3->cversion;
5174 init_unistr( &info->name, driver.info_3->name );
5175 init_unistr( &info->architecture, driver.info_3->environment );
5177 if (strlen(driver.info_3->driverpath)) {
5178 temp = talloc_asprintf(ctx,
5181 driver.info_3->driverpath);
5182 init_unistr( &info->driverpath, temp );
5184 init_unistr( &info->driverpath, "" );
5188 if (strlen(driver.info_3->datafile)) {
5189 temp = talloc_asprintf(ctx,
5192 driver.info_3->datafile);
5193 init_unistr( &info->datafile, temp );
5195 init_unistr( &info->datafile, "" );
5198 if (strlen(driver.info_3->configfile)) {
5199 temp = talloc_asprintf(ctx,
5202 driver.info_3->configfile);
5203 init_unistr( &info->configfile, temp );
5205 init_unistr( &info->configfile, "" );
5208 /********************************************************************
5209 * construct_printer_driver_info_2
5210 * fill a printer_info_2 struct
5211 ********************************************************************/
5213 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5215 NT_PRINTER_INFO_LEVEL *printer = NULL;
5216 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5218 ZERO_STRUCT(printer);
5219 ZERO_STRUCT(driver);
5221 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5222 return WERR_INVALID_PRINTER_NAME;
5224 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5225 free_a_printer(&printer, 2);
5226 return WERR_UNKNOWN_PRINTER_DRIVER;
5229 fill_printer_driver_info_2(info, driver, servername);
5231 free_a_printer(&printer,2);
5236 /********************************************************************
5237 * copy a strings array and convert to UNICODE
5239 * convert an array of ascii string to a UNICODE string
5240 ********************************************************************/
5242 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5248 TALLOC_CTX *ctx = talloc_tos();
5250 DEBUG(6,("init_unistr_array\n"));
5254 if ( !char_array ) {
5259 v = ""; /* hack to handle null lists */
5262 /* hack to allow this to be used in places other than when generating
5263 the list of dependent files */
5267 line = talloc_asprintf(ctx,
5269 canon_servername(servername),
5272 line = talloc_strdup(ctx, v);
5276 SAFE_FREE(*uni_array);
5279 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5281 /* add one extra unit16 for the second terminating NULL */
5283 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5284 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5291 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5296 /* special case for ""; we need to add both NULL's here */
5298 (*uni_array)[j++]=0x0000;
5299 (*uni_array)[j]=0x0000;
5302 DEBUGADD(6,("last one:done\n"));
5304 /* return size of array in uint16's */
5309 /********************************************************************
5310 * construct_printer_info_3
5311 * fill a printer_info_3 struct
5312 ********************************************************************/
5314 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5317 TALLOC_CTX *ctx = talloc_tos();
5318 const char *cservername = canon_servername(servername);
5322 info->version=driver.info_3->cversion;
5324 init_unistr( &info->name, driver.info_3->name );
5325 init_unistr( &info->architecture, driver.info_3->environment );
5327 if (strlen(driver.info_3->driverpath)) {
5328 temp = talloc_asprintf(ctx,
5331 driver.info_3->driverpath);
5332 init_unistr( &info->driverpath, temp );
5334 init_unistr( &info->driverpath, "" );
5337 if (strlen(driver.info_3->datafile)) {
5338 temp = talloc_asprintf(ctx,
5341 driver.info_3->datafile);
5342 init_unistr( &info->datafile, temp );
5344 init_unistr( &info->datafile, "" );
5347 if (strlen(driver.info_3->configfile)) {
5348 temp = talloc_asprintf(ctx,
5351 driver.info_3->configfile);
5352 init_unistr( &info->configfile, temp );
5354 init_unistr( &info->configfile, "" );
5357 if (strlen(driver.info_3->helpfile)) {
5358 temp = talloc_asprintf(ctx,
5361 driver.info_3->helpfile);
5362 init_unistr( &info->helpfile, temp );
5364 init_unistr( &info->helpfile, "" );
5367 init_unistr( &info->monitorname, driver.info_3->monitorname );
5368 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5370 info->dependentfiles=NULL;
5371 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5374 /********************************************************************
5375 * construct_printer_info_3
5376 * fill a printer_info_3 struct
5377 ********************************************************************/
5379 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5381 NT_PRINTER_INFO_LEVEL *printer = NULL;
5382 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5384 ZERO_STRUCT(driver);
5386 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5387 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5388 if (!W_ERROR_IS_OK(status))
5389 return WERR_INVALID_PRINTER_NAME;
5391 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5392 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5397 * I put this code in during testing. Helpful when commenting out the
5398 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5399 * as win2k always queries the driver using an infor level of 6.
5400 * I've left it in (but ifdef'd out) because I'll probably
5401 * use it in experimentation again in the future. --jerry 22/01/2002
5404 if (!W_ERROR_IS_OK(status)) {
5406 * Is this a W2k client ?
5409 /* Yes - try again with a WinNT driver. */
5411 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5412 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5416 if (!W_ERROR_IS_OK(status)) {
5417 free_a_printer(&printer,2);
5418 return WERR_UNKNOWN_PRINTER_DRIVER;
5426 fill_printer_driver_info_3(info, driver, servername);
5428 free_a_printer(&printer,2);
5433 /********************************************************************
5434 * construct_printer_info_6
5435 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5436 ********************************************************************/
5438 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5442 TALLOC_CTX *ctx = talloc_tos();
5443 const char *cservername = canon_servername(servername);
5446 memset(&nullstr, '\0', sizeof(fstring));
5448 info->version=driver.info_3->cversion;
5450 init_unistr( &info->name, driver.info_3->name );
5451 init_unistr( &info->architecture, driver.info_3->environment );
5453 if (strlen(driver.info_3->driverpath)) {
5454 temp = talloc_asprintf(ctx,
5457 driver.info_3->driverpath);
5458 init_unistr( &info->driverpath, temp );
5460 init_unistr( &info->driverpath, "" );
5463 if (strlen(driver.info_3->datafile)) {
5464 temp = talloc_asprintf(ctx,
5467 driver.info_3->datafile);
5468 init_unistr( &info->datafile, temp );
5470 init_unistr( &info->datafile, "" );
5473 if (strlen(driver.info_3->configfile)) {
5474 temp = talloc_asprintf(ctx,
5477 driver.info_3->configfile);
5478 init_unistr( &info->configfile, temp );
5480 init_unistr( &info->configfile, "" );
5483 if (strlen(driver.info_3->helpfile)) {
5484 temp = talloc_asprintf(ctx,
5487 driver.info_3->helpfile);
5488 init_unistr( &info->helpfile, temp );
5490 init_unistr( &info->helpfile, "" );
5493 init_unistr( &info->monitorname, driver.info_3->monitorname );
5494 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5496 info->dependentfiles = NULL;
5497 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5499 info->previousdrivernames=NULL;
5500 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5502 info->driver_date=0;
5505 info->driver_version_low=0;
5506 info->driver_version_high=0;
5508 init_unistr( &info->mfgname, "");
5509 init_unistr( &info->oem_url, "");
5510 init_unistr( &info->hardware_id, "");
5511 init_unistr( &info->provider, "");
5514 /********************************************************************
5515 * construct_printer_info_6
5516 * fill a printer_info_6 struct
5517 ********************************************************************/
5519 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5520 const char *servername, fstring architecture, uint32 version)
5522 NT_PRINTER_INFO_LEVEL *printer = NULL;
5523 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5526 ZERO_STRUCT(driver);
5528 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5530 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5532 if (!W_ERROR_IS_OK(status))
5533 return WERR_INVALID_PRINTER_NAME;
5535 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5537 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5539 if (!W_ERROR_IS_OK(status))
5542 * Is this a W2k client ?
5546 free_a_printer(&printer,2);
5547 return WERR_UNKNOWN_PRINTER_DRIVER;
5550 /* Yes - try again with a WinNT driver. */
5552 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5553 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5554 if (!W_ERROR_IS_OK(status)) {
5555 free_a_printer(&printer,2);
5556 return WERR_UNKNOWN_PRINTER_DRIVER;
5560 fill_printer_driver_info_6(info, driver, servername);
5562 free_a_printer(&printer,2);
5563 free_a_printer_driver(driver, 3);
5568 /****************************************************************************
5569 ****************************************************************************/
5571 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5573 SAFE_FREE(info->dependentfiles);
5576 /****************************************************************************
5577 ****************************************************************************/
5579 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5581 SAFE_FREE(info->dependentfiles);
5584 /****************************************************************************
5585 ****************************************************************************/
5587 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5589 DRIVER_INFO_1 *info=NULL;
5592 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5595 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5596 if (!W_ERROR_IS_OK(result))
5599 /* check the required size. */
5600 *needed += spoolss_size_printer_driver_info_1(info);
5602 if (*needed > offered) {
5603 result = WERR_INSUFFICIENT_BUFFER;
5607 if (!rpcbuf_alloc_size(buffer, *needed)) {
5608 result = WERR_NOMEM;
5612 /* fill the buffer with the structures */
5613 smb_io_printer_driver_info_1("", buffer, info, 0);
5622 /****************************************************************************
5623 ****************************************************************************/
5625 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5627 DRIVER_INFO_2 *info=NULL;
5630 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5633 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5634 if (!W_ERROR_IS_OK(result))
5637 /* check the required size. */
5638 *needed += spoolss_size_printer_driver_info_2(info);
5640 if (*needed > offered) {
5641 result = WERR_INSUFFICIENT_BUFFER;
5645 if (!rpcbuf_alloc_size(buffer, *needed)) {
5646 result = WERR_NOMEM;
5650 /* fill the buffer with the structures */
5651 smb_io_printer_driver_info_2("", buffer, info, 0);
5660 /****************************************************************************
5661 ****************************************************************************/
5663 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5670 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5671 if (!W_ERROR_IS_OK(result))
5674 /* check the required size. */
5675 *needed += spoolss_size_printer_driver_info_3(&info);
5677 if (*needed > offered) {
5678 result = WERR_INSUFFICIENT_BUFFER;
5682 if (!rpcbuf_alloc_size(buffer, *needed)) {
5683 result = WERR_NOMEM;
5687 /* fill the buffer with the structures */
5688 smb_io_printer_driver_info_3("", buffer, &info, 0);
5691 free_printer_driver_info_3(&info);
5696 /****************************************************************************
5697 ****************************************************************************/
5699 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5706 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5707 if (!W_ERROR_IS_OK(result))
5710 /* check the required size. */
5711 *needed += spoolss_size_printer_driver_info_6(&info);
5713 if (*needed > offered) {
5714 result = WERR_INSUFFICIENT_BUFFER;
5718 if (!rpcbuf_alloc_size(buffer, *needed)) {
5719 result = WERR_NOMEM;
5723 /* fill the buffer with the structures */
5724 smb_io_printer_driver_info_6("", buffer, &info, 0);
5727 free_printer_driver_info_6(&info);
5732 /****************************************************************************
5733 ****************************************************************************/
5735 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5737 POLICY_HND *handle = &q_u->handle;
5738 UNISTR2 *uni_arch = &q_u->architecture;
5739 uint32 level = q_u->level;
5740 uint32 clientmajorversion = q_u->clientmajorversion;
5741 RPC_BUFFER *buffer = NULL;
5742 uint32 offered = q_u->offered;
5743 uint32 *needed = &r_u->needed;
5744 uint32 *servermajorversion = &r_u->servermajorversion;
5745 uint32 *serverminorversion = &r_u->serverminorversion;
5746 Printer_entry *printer;
5749 fstring architecture;
5752 /* that's an [in out] buffer */
5754 if (!q_u->buffer && (offered!=0)) {
5755 return WERR_INVALID_PARAM;
5758 if (offered > MAX_RPC_DATA_SIZE) {
5759 return WERR_INVALID_PARAM;
5762 rpcbuf_move(q_u->buffer, &r_u->buffer);
5763 buffer = r_u->buffer;
5765 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5767 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5768 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5769 return WERR_INVALID_PRINTER_NAME;
5773 *servermajorversion = 0;
5774 *serverminorversion = 0;
5776 fstrcpy(servername, get_server_name( printer ));
5777 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5779 if (!get_printer_snum(p, handle, &snum, NULL))
5784 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5786 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5788 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5790 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5793 /* apparently this call is the equivalent of
5794 EnumPrinterDataEx() for the DsDriver key */
5799 return WERR_UNKNOWN_LEVEL;
5803 /****************************************************************
5804 _spoolss_StartPagePrinter
5805 ****************************************************************/
5807 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5808 struct spoolss_StartPagePrinter *r)
5810 POLICY_HND *handle = r->in.handle;
5812 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5815 DEBUG(3,("_spoolss_StartPagePrinter: "
5816 "Error in startpageprinter printer handle\n"));
5820 Printer->page_started=True;
5824 /****************************************************************
5825 _spoolss_EndPagePrinter
5826 ****************************************************************/
5828 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5829 struct spoolss_EndPagePrinter *r)
5831 POLICY_HND *handle = r->in.handle;
5834 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5837 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5838 OUR_HANDLE(handle)));
5842 if (!get_printer_snum(p, handle, &snum, NULL))
5845 Printer->page_started=False;
5846 print_job_endpage(snum, Printer->jobid);
5851 /****************************************************************
5852 _spoolss_StartDocPrinter
5853 ****************************************************************/
5855 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5856 struct spoolss_StartDocPrinter *r)
5858 POLICY_HND *handle = r->in.handle;
5859 uint32_t *jobid = r->out.job_id;
5860 struct spoolss_DocumentInfo1 *info_1;
5862 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5865 DEBUG(2,("_spoolss_StartDocPrinter: "
5866 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5870 if (r->in.level != 1) {
5871 return WERR_UNKNOWN_LEVEL;
5874 info_1 = r->in.info.info1;
5877 * a nice thing with NT is it doesn't listen to what you tell it.
5878 * when asked to send _only_ RAW datas, it tries to send datas
5881 * So I add checks like in NT Server ...
5884 if (info_1->datatype) {
5885 if (strcmp(info_1->datatype, "RAW") != 0) {
5887 return WERR_INVALID_DATATYPE;
5891 /* get the share number of the printer */
5892 if (!get_printer_snum(p, handle, &snum, NULL)) {
5896 Printer->jobid = print_job_start(p->server_info, snum,
5897 CONST_DISCARD(char *,info_1->document_name),
5898 Printer->nt_devmode);
5900 /* An error occured in print_job_start() so return an appropriate
5903 if (Printer->jobid == -1) {
5904 return map_werror_from_unix(errno);
5907 Printer->document_started=True;
5908 (*jobid) = Printer->jobid;
5913 /****************************************************************
5914 _spoolss_EndDocPrinter
5915 ****************************************************************/
5917 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5918 struct spoolss_EndDocPrinter *r)
5920 POLICY_HND *handle = r->in.handle;
5922 return _spoolss_enddocprinter_internal(p, handle);
5925 /****************************************************************
5926 _spoolss_WritePrinter
5927 ****************************************************************/
5929 WERROR _spoolss_WritePrinter(pipes_struct *p,
5930 struct spoolss_WritePrinter *r)
5932 POLICY_HND *handle = r->in.handle;
5933 uint32 buffer_size = r->in._data_size;
5934 uint8 *buffer = r->in.data.data;
5935 uint32 *buffer_written = &r->in._data_size;
5937 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5940 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5941 OUR_HANDLE(handle)));
5942 *r->out.num_written = r->in._data_size;
5946 if (!get_printer_snum(p, handle, &snum, NULL))
5949 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5950 (SMB_OFF_T)-1, (size_t)buffer_size);
5951 if (*buffer_written == (uint32)-1) {
5952 *r->out.num_written = 0;
5953 if (errno == ENOSPC)
5954 return WERR_NO_SPOOL_SPACE;
5956 return WERR_ACCESS_DENIED;
5959 *r->out.num_written = r->in._data_size;
5964 /********************************************************************
5965 * api_spoolss_getprinter
5966 * called from the spoolss dispatcher
5968 ********************************************************************/
5970 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5974 WERROR errcode = WERR_BADFUNC;
5975 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5978 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5982 if (!get_printer_snum(p, handle, &snum, NULL))
5986 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5987 if (print_queue_pause(p->server_info, snum, &errcode)) {
5991 case SPOOLSS_PRINTER_CONTROL_RESUME:
5992 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5993 if (print_queue_resume(p->server_info, snum, &errcode)) {
5997 case SPOOLSS_PRINTER_CONTROL_PURGE:
5998 if (print_queue_purge(p->server_info, snum, &errcode)) {
6003 return WERR_UNKNOWN_LEVEL;
6010 /****************************************************************
6011 _spoolss_AbortPrinter
6012 * From MSDN: "Deletes printer's spool file if printer is configured
6014 ****************************************************************/
6016 WERROR _spoolss_AbortPrinter(pipes_struct *p,
6017 struct spoolss_AbortPrinter *r)
6019 POLICY_HND *handle = r->in.handle;
6020 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6022 WERROR errcode = WERR_OK;
6025 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6026 OUR_HANDLE(handle)));
6030 if (!get_printer_snum(p, handle, &snum, NULL))
6033 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6038 /********************************************************************
6039 * called by spoolss_api_setprinter
6040 * when updating a printer description
6041 ********************************************************************/
6043 static WERROR update_printer_sec(POLICY_HND *handle,
6044 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6046 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6050 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6052 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6053 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6054 OUR_HANDLE(handle)));
6056 result = WERR_BADFID;
6061 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6062 result = WERR_INVALID_PARAM;
6066 /* Check the user has permissions to change the security
6067 descriptor. By experimentation with two NT machines, the user
6068 requires Full Access to the printer to change security
6071 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6072 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6073 result = WERR_ACCESS_DENIED;
6077 /* NT seems to like setting the security descriptor even though
6078 nothing may have actually changed. */
6080 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6081 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6082 result = WERR_BADFID;
6086 if (DEBUGLEVEL >= 10) {
6090 the_acl = old_secdesc_ctr->sd->dacl;
6091 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6092 PRINTERNAME(snum), the_acl->num_aces));
6094 for (i = 0; i < the_acl->num_aces; i++) {
6095 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6096 &the_acl->aces[i].trustee),
6097 the_acl->aces[i].access_mask));
6100 the_acl = secdesc_ctr->sd->dacl;
6103 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6104 PRINTERNAME(snum), the_acl->num_aces));
6106 for (i = 0; i < the_acl->num_aces; i++) {
6107 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6108 &the_acl->aces[i].trustee),
6109 the_acl->aces[i].access_mask));
6112 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6116 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6117 if (!new_secdesc_ctr) {
6118 result = WERR_NOMEM;
6122 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6127 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6134 /********************************************************************
6135 Canonicalize printer info from a client
6137 ATTN: It does not matter what we set the servername to hear
6138 since we do the necessary work in get_a_printer() to set it to
6139 the correct value based on what the client sent in the
6140 _spoolss_open_printer_ex().
6141 ********************************************************************/
6143 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6145 fstring printername;
6148 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6149 "portname=%s drivername=%s comment=%s location=%s\n",
6150 info->servername, info->printername, info->sharename,
6151 info->portname, info->drivername, info->comment, info->location));
6153 /* we force some elements to "correct" values */
6154 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6155 fstrcpy(info->sharename, lp_servicename(snum));
6157 /* check to see if we allow printername != sharename */
6159 if ( lp_force_printername(snum) ) {
6160 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6161 global_myname(), info->sharename );
6164 /* make sure printername is in \\server\printername format */
6166 fstrcpy( printername, info->printername );
6168 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6169 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6173 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6174 global_myname(), p );
6177 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6178 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6185 /****************************************************************************
6186 ****************************************************************************/
6188 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6190 char *cmd = lp_addport_cmd();
6191 char *command = NULL;
6193 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6194 bool is_print_op = False;
6197 return WERR_ACCESS_DENIED;
6200 command = talloc_asprintf(ctx,
6201 "%s \"%s\" \"%s\"", cmd, portname, uri );
6207 is_print_op = user_has_privileges( token, &se_printop );
6209 DEBUG(10,("Running [%s]\n", command));
6211 /********* BEGIN SePrintOperatorPrivilege **********/
6216 ret = smbrun(command, NULL);
6221 /********* END SePrintOperatorPrivilege **********/
6223 DEBUGADD(10,("returned [%d]\n", ret));
6225 TALLOC_FREE(command);
6228 return WERR_ACCESS_DENIED;
6234 /****************************************************************************
6235 ****************************************************************************/
6237 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6239 char *cmd = lp_addprinter_cmd();
6241 char *command = NULL;
6245 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6246 bool is_print_op = False;
6247 char *remote_machine = talloc_strdup(ctx, "%m");
6249 if (!remote_machine) {
6252 remote_machine = talloc_sub_basic(ctx,
6253 current_user_info.smb_name,
6254 current_user_info.domain,
6256 if (!remote_machine) {
6260 command = talloc_asprintf(ctx,
6261 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6262 cmd, printer->info_2->printername, printer->info_2->sharename,
6263 printer->info_2->portname, printer->info_2->drivername,
6264 printer->info_2->location, printer->info_2->comment, remote_machine);
6270 is_print_op = user_has_privileges( token, &se_printop );
6272 DEBUG(10,("Running [%s]\n", command));
6274 /********* BEGIN SePrintOperatorPrivilege **********/
6279 if ( (ret = smbrun(command, &fd)) == 0 ) {
6280 /* Tell everyone we updated smb.conf. */
6281 message_send_all(smbd_messaging_context(),
6282 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6288 /********* END SePrintOperatorPrivilege **********/
6290 DEBUGADD(10,("returned [%d]\n", ret));
6292 TALLOC_FREE(command);
6293 TALLOC_FREE(remote_machine);
6301 /* reload our services immediately */
6302 reload_services( False );
6305 /* Get lines and convert them back to dos-codepage */
6306 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6307 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6310 /* Set the portname to what the script says the portname should be. */
6311 /* but don't require anything to be return from the script exit a good error code */
6314 /* Set the portname to what the script says the portname should be. */
6315 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6316 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6319 TALLOC_FREE(qlines);
6324 /********************************************************************
6325 * Called by spoolss_api_setprinter
6326 * when updating a printer description.
6327 ********************************************************************/
6329 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6330 struct spoolss_SetPrinterInfoCtr *info_ctr,
6331 struct spoolss_DeviceMode *devmode)
6334 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6335 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6340 DEBUG(8,("update_printer\n"));
6345 result = WERR_BADFID;
6349 if (!get_printer_snum(p, handle, &snum, NULL)) {
6350 result = WERR_BADFID;
6354 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6355 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6356 result = WERR_BADFID;
6360 DEBUGADD(8,("Converting info_2 struct\n"));
6363 * convert_printer_info converts the incoming
6364 * info from the client and overwrites the info
6365 * just read from the tdb in the pointer 'printer'.
6368 if (!convert_printer_info_new(info_ctr, printer)) {
6369 result = WERR_NOMEM;
6374 /* we have a valid devmode
6375 convert it and link it*/
6377 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6378 if (!convert_devicemode_new(printer->info_2->printername,
6380 &printer->info_2->devmode)) {
6381 result = WERR_NOMEM;
6386 /* Do sanity check on the requested changes for Samba */
6388 if (!check_printer_ok(printer->info_2, snum)) {
6389 result = WERR_INVALID_PARAM;
6393 /* FIXME!!! If the driver has changed we really should verify that
6394 it is installed before doing much else --jerry */
6396 /* Check calling user has permission to update printer description */
6398 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6399 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6400 result = WERR_ACCESS_DENIED;
6404 /* Call addprinter hook */
6405 /* Check changes to see if this is really needed */
6407 if ( *lp_addprinter_cmd()
6408 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6409 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6410 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6411 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6413 /* add_printer_hook() will call reload_services() */
6415 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6417 result = WERR_ACCESS_DENIED;
6423 * When a *new* driver is bound to a printer, the drivername is used to
6424 * lookup previously saved driver initialization info, which is then
6425 * bound to the printer, simulating what happens in the Windows arch.
6427 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6429 if (!set_driver_init(printer, 2))
6431 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6432 printer->info_2->drivername));
6435 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6436 printer->info_2->drivername));
6438 notify_printer_driver(snum, printer->info_2->drivername);
6442 * flag which changes actually occured. This is a small subset of
6443 * all the possible changes. We also have to update things in the
6447 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6448 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6449 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6450 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6452 notify_printer_comment(snum, printer->info_2->comment);
6455 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6456 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6457 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6458 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6460 notify_printer_sharename(snum, printer->info_2->sharename);
6463 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6466 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6469 pname = printer->info_2->printername;
6472 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6473 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6474 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6476 notify_printer_printername( snum, pname );
6479 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6480 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6481 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6482 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6484 notify_printer_port(snum, printer->info_2->portname);
6487 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6488 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6489 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6490 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6492 notify_printer_location(snum, printer->info_2->location);
6495 /* here we need to update some more DsSpooler keys */
6496 /* uNCName, serverName, shortServerName */
6498 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6499 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6500 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6501 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6502 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6504 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6505 global_myname(), printer->info_2->sharename );
6506 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6507 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6508 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6510 /* Update printer info */
6511 result = mod_a_printer(printer, 2);
6514 free_a_printer(&printer, 2);
6515 free_a_printer(&old_printer, 2);
6521 /****************************************************************************
6522 ****************************************************************************/
6523 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6524 struct spoolss_SetPrinterInfo7 *info7)
6528 Printer_entry *Printer;
6530 if ( lp_security() != SEC_ADS ) {
6531 return WERR_UNKNOWN_LEVEL;
6534 Printer = find_printer_index_by_hnd(p, handle);
6536 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6541 if (!get_printer_snum(p, handle, &snum, NULL))
6544 nt_printer_publish(Printer, snum, info7->action);
6548 return WERR_UNKNOWN_LEVEL;
6552 /****************************************************************
6554 ****************************************************************/
6556 WERROR _spoolss_SetPrinter(pipes_struct *p,
6557 struct spoolss_SetPrinter *r)
6559 POLICY_HND *handle = r->in.handle;
6562 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6565 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6566 OUR_HANDLE(handle)));
6570 /* check the level */
6571 switch (r->in.info_ctr->level) {
6573 return control_printer(handle, r->in.command, p);
6575 result = update_printer(p, handle,
6577 r->in.devmode_ctr->devmode);
6578 if (!W_ERROR_IS_OK(result))
6580 if (r->in.secdesc_ctr->sd)
6581 result = update_printer_sec(handle, p,
6585 return update_printer_sec(handle, p,
6588 return publish_or_unpublish_printer(p, handle,
6589 r->in.info_ctr->info.info7);
6591 return WERR_UNKNOWN_LEVEL;
6595 /****************************************************************
6596 _spoolss_FindClosePrinterNotify
6597 ****************************************************************/
6599 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6600 struct spoolss_FindClosePrinterNotify *r)
6602 POLICY_HND *handle = r->in.handle;
6603 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6606 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6607 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6611 if (Printer->notify.client_connected==True) {
6614 if ( Printer->printer_type == SPLHND_SERVER)
6616 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6617 !get_printer_snum(p, handle, &snum, NULL) )
6620 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6623 Printer->notify.flags=0;
6624 Printer->notify.options=0;
6625 Printer->notify.localmachine[0]='\0';
6626 Printer->notify.printerlocal=0;
6627 if (Printer->notify.option)
6628 free_spool_notify_option(&Printer->notify.option);
6629 Printer->notify.client_connected=False;
6634 /****************************************************************
6636 ****************************************************************/
6638 WERROR _spoolss_AddJob(pipes_struct *p,
6639 struct spoolss_AddJob *r)
6641 if (!r->in.buffer && (r->in.offered != 0)) {
6642 return WERR_INVALID_PARAM;
6645 /* this is what a NT server returns for AddJob. AddJob must fail on
6646 * non-local printers */
6648 return WERR_INVALID_PARAM;
6651 /****************************************************************************
6652 ****************************************************************************/
6654 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6655 int position, int snum,
6656 const NT_PRINTER_INFO_LEVEL *ntprinter)
6660 t=gmtime(&queue->time);
6662 job_info->jobid=queue->job;
6663 init_unistr(&job_info->printername, lp_servicename(snum));
6664 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6665 init_unistr(&job_info->username, queue->fs_user);
6666 init_unistr(&job_info->document, queue->fs_file);
6667 init_unistr(&job_info->datatype, "RAW");
6668 init_unistr(&job_info->text_status, "");
6669 job_info->status=nt_printj_status(queue->status);
6670 job_info->priority=queue->priority;
6671 job_info->position=position;
6672 job_info->totalpages=queue->page_count;
6673 job_info->pagesprinted=0;
6675 make_systemtime(&job_info->submitted, t);
6678 /****************************************************************************
6679 ****************************************************************************/
6681 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6682 int position, int snum,
6683 const NT_PRINTER_INFO_LEVEL *ntprinter,
6684 DEVICEMODE *devmode)
6688 t=gmtime(&queue->time);
6690 job_info->jobid=queue->job;
6692 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6694 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6695 init_unistr(&job_info->username, queue->fs_user);
6696 init_unistr(&job_info->document, queue->fs_file);
6697 init_unistr(&job_info->notifyname, queue->fs_user);
6698 init_unistr(&job_info->datatype, "RAW");
6699 init_unistr(&job_info->printprocessor, "winprint");
6700 init_unistr(&job_info->parameters, "");
6701 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6702 init_unistr(&job_info->text_status, "");
6704 /* and here the security descriptor */
6706 job_info->status=nt_printj_status(queue->status);
6707 job_info->priority=queue->priority;
6708 job_info->position=position;
6709 job_info->starttime=0;
6710 job_info->untiltime=0;
6711 job_info->totalpages=queue->page_count;
6712 job_info->size=queue->size;
6713 make_systemtime(&(job_info->submitted), t);
6714 job_info->timeelapsed=0;
6715 job_info->pagesprinted=0;
6717 job_info->devmode = devmode;
6722 /****************************************************************************
6723 Enumjobs at level 1.
6724 ****************************************************************************/
6726 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6727 const NT_PRINTER_INFO_LEVEL *ntprinter,
6728 RPC_BUFFER *buffer, uint32 offered,
6729 uint32 *needed, uint32 *returned)
6733 WERROR result = WERR_OK;
6735 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6741 for (i=0; i<*returned; i++)
6742 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6744 /* check the required size. */
6745 for (i=0; i<*returned; i++)
6746 (*needed) += spoolss_size_job_info_1(&info[i]);
6748 if (*needed > offered) {
6749 result = WERR_INSUFFICIENT_BUFFER;
6753 if (!rpcbuf_alloc_size(buffer, *needed)) {
6754 result = WERR_NOMEM;
6758 /* fill the buffer with the structures */
6759 for (i=0; i<*returned; i++)
6760 smb_io_job_info_1("", buffer, &info[i], 0);
6766 if ( !W_ERROR_IS_OK(result) )
6772 /****************************************************************************
6773 Enumjobs at level 2.
6774 ****************************************************************************/
6776 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6777 const NT_PRINTER_INFO_LEVEL *ntprinter,
6778 RPC_BUFFER *buffer, uint32 offered,
6779 uint32 *needed, uint32 *returned)
6781 JOB_INFO_2 *info = NULL;
6783 WERROR result = WERR_OK;
6784 DEVICEMODE *devmode = NULL;
6786 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6791 /* this should not be a failure condition if the devmode is NULL */
6793 devmode = construct_dev_mode(lp_const_servicename(snum));
6795 for (i=0; i<*returned; i++)
6796 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6798 /* check the required size. */
6799 for (i=0; i<*returned; i++)
6800 (*needed) += spoolss_size_job_info_2(&info[i]);
6802 if (*needed > offered) {
6803 result = WERR_INSUFFICIENT_BUFFER;
6807 if (!rpcbuf_alloc_size(buffer, *needed)) {
6808 result = WERR_NOMEM;
6812 /* fill the buffer with the structures */
6813 for (i=0; i<*returned; i++)
6814 smb_io_job_info_2("", buffer, &info[i], 0);
6817 free_devmode(devmode);
6820 if ( !W_ERROR_IS_OK(result) )
6827 /****************************************************************************
6829 ****************************************************************************/
6831 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6833 POLICY_HND *handle = &q_u->handle;
6834 uint32 level = q_u->level;
6835 RPC_BUFFER *buffer = NULL;
6836 uint32 offered = q_u->offered;
6837 uint32 *needed = &r_u->needed;
6838 uint32 *returned = &r_u->returned;
6840 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6842 print_status_struct prt_status;
6843 print_queue_struct *queue=NULL;
6845 /* that's an [in out] buffer */
6847 if (!q_u->buffer && (offered!=0)) {
6848 return WERR_INVALID_PARAM;
6851 if (offered > MAX_RPC_DATA_SIZE) {
6852 return WERR_INVALID_PARAM;
6855 rpcbuf_move(q_u->buffer, &r_u->buffer);
6856 buffer = r_u->buffer;
6858 DEBUG(4,("_spoolss_enumjobs\n"));
6863 /* lookup the printer snum and tdb entry */
6865 if (!get_printer_snum(p, handle, &snum, NULL))
6868 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6869 if ( !W_ERROR_IS_OK(wret) )
6872 *returned = print_queue_status(snum, &queue, &prt_status);
6873 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6875 if (*returned == 0) {
6877 free_a_printer(&ntprinter, 2);
6883 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6886 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6890 wret = WERR_UNKNOWN_LEVEL;
6895 free_a_printer( &ntprinter, 2 );
6899 /****************************************************************
6900 _spoolss_ScheduleJob
6901 ****************************************************************/
6903 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6904 struct spoolss_ScheduleJob *r)
6909 /****************************************************************
6911 ****************************************************************/
6913 WERROR _spoolss_SetJob(pipes_struct *p,
6914 struct spoolss_SetJob *r)
6916 POLICY_HND *handle = r->in.handle;
6917 uint32 jobid = r->in.job_id;
6918 uint32 command = r->in.command;
6921 WERROR errcode = WERR_BADFUNC;
6923 if (!get_printer_snum(p, handle, &snum, NULL)) {
6927 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6928 return WERR_INVALID_PRINTER_NAME;
6932 case SPOOLSS_JOB_CONTROL_CANCEL:
6933 case SPOOLSS_JOB_CONTROL_DELETE:
6934 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6938 case SPOOLSS_JOB_CONTROL_PAUSE:
6939 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6943 case SPOOLSS_JOB_CONTROL_RESTART:
6944 case SPOOLSS_JOB_CONTROL_RESUME:
6945 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6950 return WERR_UNKNOWN_LEVEL;
6956 /****************************************************************************
6957 Enumerates all printer drivers at level 1.
6958 ****************************************************************************/
6960 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6965 fstring *list = NULL;
6966 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6967 DRIVER_INFO_1 *driver_info_1=NULL;
6968 WERROR result = WERR_OK;
6972 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6974 ndrivers=get_ntdrivers(&list, architecture, version);
6975 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6977 if(ndrivers == -1) {
6978 SAFE_FREE(driver_info_1);
6983 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6984 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6990 for (i=0; i<ndrivers; i++) {
6992 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6993 ZERO_STRUCT(driver);
6994 status = get_a_printer_driver(&driver, 3, list[i],
6995 architecture, version);
6996 if (!W_ERROR_IS_OK(status)) {
6998 SAFE_FREE(driver_info_1);
7001 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
7002 free_a_printer_driver(driver, 3);
7005 *returned+=ndrivers;
7009 /* check the required size. */
7010 for (i=0; i<*returned; i++) {
7011 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7012 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
7015 if (*needed > offered) {
7016 result = WERR_INSUFFICIENT_BUFFER;
7020 if (!rpcbuf_alloc_size(buffer, *needed)) {
7021 result = WERR_NOMEM;
7025 /* fill the buffer with the driver structures */
7026 for (i=0; i<*returned; i++) {
7027 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7028 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
7032 SAFE_FREE(driver_info_1);
7034 if ( !W_ERROR_IS_OK(result) )
7040 /****************************************************************************
7041 Enumerates all printer drivers at level 2.
7042 ****************************************************************************/
7044 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7049 fstring *list = NULL;
7050 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7051 DRIVER_INFO_2 *driver_info_2=NULL;
7052 WERROR result = WERR_OK;
7056 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7058 ndrivers=get_ntdrivers(&list, architecture, version);
7059 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7061 if(ndrivers == -1) {
7062 SAFE_FREE(driver_info_2);
7067 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7068 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7074 for (i=0; i<ndrivers; i++) {
7077 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7078 ZERO_STRUCT(driver);
7079 status = get_a_printer_driver(&driver, 3, list[i],
7080 architecture, version);
7081 if (!W_ERROR_IS_OK(status)) {
7083 SAFE_FREE(driver_info_2);
7086 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7087 free_a_printer_driver(driver, 3);
7090 *returned+=ndrivers;
7094 /* check the required size. */
7095 for (i=0; i<*returned; i++) {
7096 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7097 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7100 if (*needed > offered) {
7101 result = WERR_INSUFFICIENT_BUFFER;
7105 if (!rpcbuf_alloc_size(buffer, *needed)) {
7106 result = WERR_NOMEM;
7110 /* fill the buffer with the form structures */
7111 for (i=0; i<*returned; i++) {
7112 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7113 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7117 SAFE_FREE(driver_info_2);
7119 if ( !W_ERROR_IS_OK(result) )
7125 /****************************************************************************
7126 Enumerates all printer drivers at level 3.
7127 ****************************************************************************/
7129 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7134 fstring *list = NULL;
7135 DRIVER_INFO_3 *driver_info_3=NULL;
7136 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7137 WERROR result = WERR_OK;
7141 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7143 ndrivers=get_ntdrivers(&list, architecture, version);
7144 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7146 if(ndrivers == -1) {
7147 SAFE_FREE(driver_info_3);
7152 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7153 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7159 for (i=0; i<ndrivers; i++) {
7162 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7163 ZERO_STRUCT(driver);
7164 status = get_a_printer_driver(&driver, 3, list[i],
7165 architecture, version);
7166 if (!W_ERROR_IS_OK(status)) {
7168 SAFE_FREE(driver_info_3);
7171 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7172 free_a_printer_driver(driver, 3);
7175 *returned+=ndrivers;
7179 /* check the required size. */
7180 for (i=0; i<*returned; i++) {
7181 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7182 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7185 if (*needed > offered) {
7186 result = WERR_INSUFFICIENT_BUFFER;
7190 if (!rpcbuf_alloc_size(buffer, *needed)) {
7191 result = WERR_NOMEM;
7195 /* fill the buffer with the driver structures */
7196 for (i=0; i<*returned; i++) {
7197 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7198 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7202 for (i=0; i<*returned; i++) {
7203 SAFE_FREE(driver_info_3[i].dependentfiles);
7206 SAFE_FREE(driver_info_3);
7208 if ( !W_ERROR_IS_OK(result) )
7214 /****************************************************************************
7215 Enumerates all printer drivers.
7216 ****************************************************************************/
7218 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7220 uint32 level = q_u->level;
7221 RPC_BUFFER *buffer = NULL;
7222 uint32 offered = q_u->offered;
7223 uint32 *needed = &r_u->needed;
7224 uint32 *returned = &r_u->returned;
7225 const char *cservername;
7227 fstring architecture;
7229 /* that's an [in out] buffer */
7231 if (!q_u->buffer && (offered!=0)) {
7232 return WERR_INVALID_PARAM;
7235 if (offered > MAX_RPC_DATA_SIZE) {
7236 return WERR_INVALID_PARAM;
7239 rpcbuf_move(q_u->buffer, &r_u->buffer);
7240 buffer = r_u->buffer;
7242 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7247 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7248 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7250 cservername = canon_servername(servername);
7252 if (!is_myname_or_ipaddr(cservername))
7253 return WERR_UNKNOWN_PRINTER_DRIVER;
7257 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7259 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7261 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7263 return WERR_UNKNOWN_LEVEL;
7267 /****************************************************************************
7268 ****************************************************************************/
7270 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7272 form->flag=list->flag;
7273 init_unistr(&form->name, list->name);
7274 form->width=list->width;
7275 form->length=list->length;
7276 form->left=list->left;
7277 form->top=list->top;
7278 form->right=list->right;
7279 form->bottom=list->bottom;
7282 /****************************************************************************
7283 ****************************************************************************/
7285 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7286 struct spoolss_FormInfo1 *form,
7287 nt_forms_struct *list)
7289 form->form_name = talloc_strdup(mem_ctx, list->name);
7290 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7292 form->flags = list->flag;
7293 form->size.width = list->width;
7294 form->size.height = list->length;
7295 form->area.left = list->left;
7296 form->area.top = list->top;
7297 form->area.right = list->right;
7298 form->area.bottom = list->bottom;
7303 /****************************************************************************
7304 ****************************************************************************/
7306 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7308 uint32 level = q_u->level;
7309 RPC_BUFFER *buffer = NULL;
7310 uint32 offered = q_u->offered;
7311 uint32 *needed = &r_u->needed;
7312 uint32 *numofforms = &r_u->numofforms;
7313 uint32 numbuiltinforms;
7315 nt_forms_struct *list=NULL;
7316 nt_forms_struct *builtinlist=NULL;
7321 /* that's an [in out] buffer */
7323 if (!q_u->buffer && (offered!=0) ) {
7324 return WERR_INVALID_PARAM;
7327 if (offered > MAX_RPC_DATA_SIZE) {
7328 return WERR_INVALID_PARAM;
7331 rpcbuf_move(q_u->buffer, &r_u->buffer);
7332 buffer = r_u->buffer;
7334 DEBUG(4,("_spoolss_enumforms\n"));
7335 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7336 DEBUGADD(5,("Info level [%d]\n", level));
7338 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7339 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7340 *numofforms = get_ntforms(&list);
7341 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7342 *numofforms += numbuiltinforms;
7344 if (*numofforms == 0) {
7345 SAFE_FREE(builtinlist);
7347 return WERR_NO_MORE_ITEMS;
7352 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7353 SAFE_FREE(builtinlist);
7359 /* construct the list of form structures */
7360 for (i=0; i<numbuiltinforms; i++) {
7361 DEBUGADD(6,("Filling form number [%d]\n",i));
7362 fill_form_1(&forms_1[i], &builtinlist[i]);
7365 SAFE_FREE(builtinlist);
7367 for (; i<*numofforms; i++) {
7368 DEBUGADD(6,("Filling form number [%d]\n",i));
7369 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7374 /* check the required size. */
7375 for (i=0; i<numbuiltinforms; i++) {
7376 DEBUGADD(6,("adding form [%d]'s size\n",i));
7377 buffer_size += spoolss_size_form_1(&forms_1[i]);
7379 for (; i<*numofforms; i++) {
7380 DEBUGADD(6,("adding form [%d]'s size\n",i));
7381 buffer_size += spoolss_size_form_1(&forms_1[i]);
7384 *needed=buffer_size;
7386 if (*needed > offered) {
7389 return WERR_INSUFFICIENT_BUFFER;
7392 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7398 /* fill the buffer with the form structures */
7399 for (i=0; i<numbuiltinforms; i++) {
7400 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7401 smb_io_form_1("", buffer, &forms_1[i], 0);
7403 for (; i<*numofforms; i++) {
7404 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7405 smb_io_form_1("", buffer, &forms_1[i], 0);
7414 SAFE_FREE(builtinlist);
7415 return WERR_UNKNOWN_LEVEL;
7419 /****************************************************************
7421 ****************************************************************/
7423 WERROR _spoolss_GetForm(pipes_struct *p,
7424 struct spoolss_GetForm *r)
7426 uint32 level = r->in.level;
7427 uint32 offered = r->in.offered;
7428 uint32 *needed = r->out.needed;
7430 nt_forms_struct *list=NULL;
7431 nt_forms_struct builtin_form;
7433 union spoolss_FormInfo info;
7434 struct spoolss_FormInfo1 form_1;
7435 int numofforms=0, i=0;
7437 /* that's an [in out] buffer */
7439 if (!r->in.buffer && (offered!=0)) {
7440 return WERR_INVALID_PARAM;
7443 DEBUG(4,("_spoolss_GetForm\n"));
7444 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7445 DEBUGADD(5,("Info level [%d]\n", level));
7447 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7448 if (!foundBuiltin) {
7449 numofforms = get_ntforms(&list);
7450 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7452 if (numofforms == 0)
7456 ZERO_STRUCT(form_1);
7461 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7464 /* Check if the requested name is in the list of form structures */
7465 for (i=0; i<numofforms; i++) {
7467 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7468 list[i].name, r->in.form_name));
7470 if (strequal(r->in.form_name, list[i].name)) {
7471 DEBUGADD(6,("Found form %s number [%d]\n",
7472 r->in.form_name, i));
7473 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7479 if (i == numofforms) {
7483 /* check the required size. */
7485 info.info1 = form_1;
7487 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7489 if (*needed > offered) {
7491 return WERR_INSUFFICIENT_BUFFER;
7494 r->out.info->info1 = form_1;
7496 /* fill the buffer with the form structures */
7497 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7498 r->in.form_name, i));
7504 return WERR_UNKNOWN_LEVEL;
7508 /****************************************************************************
7509 ****************************************************************************/
7511 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7513 init_unistr(&port->port_name, name);
7516 /****************************************************************************
7517 TODO: This probably needs distinguish between TCP/IP and Local ports
7519 ****************************************************************************/
7521 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7523 init_unistr(&port->port_name, name);
7524 init_unistr(&port->monitor_name, "Local Monitor");
7525 init_unistr(&port->description, SPL_LOCAL_PORT );
7526 port->port_type=PORT_TYPE_WRITE;
7531 /****************************************************************************
7532 wrapper around the enumer ports command
7533 ****************************************************************************/
7535 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7537 char *cmd = lp_enumports_cmd();
7538 char **qlines = NULL;
7539 char *command = NULL;
7547 /* if no hook then just fill in the default port */
7550 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7553 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7554 TALLOC_FREE(qlines);
7561 /* we have a valid enumport command */
7563 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7568 DEBUG(10,("Running [%s]\n", command));
7569 ret = smbrun(command, &fd);
7570 DEBUG(10,("Returned [%d]\n", ret));
7571 TALLOC_FREE(command);
7576 return WERR_ACCESS_DENIED;
7580 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7581 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7591 /****************************************************************************
7593 ****************************************************************************/
7595 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7597 PORT_INFO_1 *ports=NULL;
7599 WERROR result = WERR_OK;
7600 char **qlines = NULL;
7603 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7604 if (!W_ERROR_IS_OK(result)) {
7605 TALLOC_FREE(qlines);
7610 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7611 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7612 win_errstr(WERR_NOMEM)));
7613 TALLOC_FREE(qlines);
7617 for (i=0; i<numlines; i++) {
7618 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7619 fill_port_1(&ports[i], qlines[i]);
7622 TALLOC_FREE(qlines);
7624 *returned = numlines;
7626 /* check the required size. */
7627 for (i=0; i<*returned; i++) {
7628 DEBUGADD(6,("adding port [%d]'s size\n", i));
7629 *needed += spoolss_size_port_info_1(&ports[i]);
7632 if (*needed > offered) {
7633 result = WERR_INSUFFICIENT_BUFFER;
7637 if (!rpcbuf_alloc_size(buffer, *needed)) {
7638 result = WERR_NOMEM;
7642 /* fill the buffer with the ports structures */
7643 for (i=0; i<*returned; i++) {
7644 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7645 smb_io_port_1("", buffer, &ports[i], 0);
7651 if ( !W_ERROR_IS_OK(result) )
7657 /****************************************************************************
7659 ****************************************************************************/
7661 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7663 PORT_INFO_2 *ports=NULL;
7665 WERROR result = WERR_OK;
7666 char **qlines = NULL;
7669 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7670 if ( !W_ERROR_IS_OK(result)) {
7671 TALLOC_FREE(qlines);
7676 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7677 TALLOC_FREE(qlines);
7681 for (i=0; i<numlines; i++) {
7682 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7683 fill_port_2(&(ports[i]), qlines[i]);
7687 TALLOC_FREE(qlines);
7689 *returned = numlines;
7691 /* check the required size. */
7692 for (i=0; i<*returned; i++) {
7693 DEBUGADD(6,("adding port [%d]'s size\n", i));
7694 *needed += spoolss_size_port_info_2(&ports[i]);
7697 if (*needed > offered) {
7698 result = WERR_INSUFFICIENT_BUFFER;
7702 if (!rpcbuf_alloc_size(buffer, *needed)) {
7703 result = WERR_NOMEM;
7707 /* fill the buffer with the ports structures */
7708 for (i=0; i<*returned; i++) {
7709 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7710 smb_io_port_2("", buffer, &ports[i], 0);
7716 if ( !W_ERROR_IS_OK(result) )
7722 /****************************************************************************
7724 ****************************************************************************/
7726 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7728 uint32 level = q_u->level;
7729 RPC_BUFFER *buffer = NULL;
7730 uint32 offered = q_u->offered;
7731 uint32 *needed = &r_u->needed;
7732 uint32 *returned = &r_u->returned;
7734 /* that's an [in out] buffer */
7736 if (!q_u->buffer && (offered!=0)) {
7737 return WERR_INVALID_PARAM;
7740 if (offered > MAX_RPC_DATA_SIZE) {
7741 return WERR_INVALID_PARAM;
7744 rpcbuf_move(q_u->buffer, &r_u->buffer);
7745 buffer = r_u->buffer;
7747 DEBUG(4,("_spoolss_enumports\n"));
7754 return enumports_level_1(buffer, offered, needed, returned);
7756 return enumports_level_2(buffer, offered, needed, returned);
7758 return WERR_UNKNOWN_LEVEL;
7762 /****************************************************************************
7763 ****************************************************************************/
7765 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7767 struct spoolss_SetPrinterInfoCtr *info_ctr,
7768 struct spoolss_DeviceMode *devmode,
7769 struct security_descriptor *sec_desc,
7770 struct spoolss_UserLevelCtr *user_ctr,
7773 NT_PRINTER_INFO_LEVEL *printer = NULL;
7776 WERROR err = WERR_OK;
7778 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7779 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7783 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7784 if (!convert_printer_info_new(info_ctr, printer)) {
7785 free_a_printer(&printer, 2);
7789 /* check to see if the printer already exists */
7791 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7792 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7793 printer->info_2->sharename));
7794 free_a_printer(&printer, 2);
7795 return WERR_PRINTER_ALREADY_EXISTS;
7798 /* FIXME!!! smbd should check to see if the driver is installed before
7799 trying to add a printer like this --jerry */
7801 if (*lp_addprinter_cmd() ) {
7802 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7804 free_a_printer(&printer,2);
7805 return WERR_ACCESS_DENIED;
7808 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7809 "smb.conf parameter \"addprinter command\" is defined. This"
7810 "parameter must exist for this call to succeed\n",
7811 printer->info_2->sharename ));
7814 /* use our primary netbios name since get_a_printer() will convert
7815 it to what the client expects on a case by case basis */
7817 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7818 printer->info_2->sharename);
7821 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7822 free_a_printer(&printer,2);
7823 return WERR_ACCESS_DENIED;
7826 /* you must be a printer admin to add a new printer */
7827 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7828 free_a_printer(&printer,2);
7829 return WERR_ACCESS_DENIED;
7833 * Do sanity check on the requested changes for Samba.
7836 if (!check_printer_ok(printer->info_2, snum)) {
7837 free_a_printer(&printer,2);
7838 return WERR_INVALID_PARAM;
7842 * When a printer is created, the drivername bound to the printer is used
7843 * to lookup previously saved driver initialization info, which is then
7844 * bound to the new printer, simulating what happens in the Windows arch.
7849 set_driver_init(printer, 2);
7853 /* A valid devmode was included, convert and link it
7855 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7857 if (!convert_devicemode_new(printer->info_2->printername,
7859 &printer->info_2->devmode))
7863 /* write the ASCII on disk */
7864 err = mod_a_printer(printer, 2);
7865 if (!W_ERROR_IS_OK(err)) {
7866 free_a_printer(&printer,2);
7870 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7871 /* Handle open failed - remove addition. */
7872 del_a_printer(printer->info_2->sharename);
7873 free_a_printer(&printer,2);
7874 ZERO_STRUCTP(handle);
7875 return WERR_ACCESS_DENIED;
7878 update_c_setprinter(False);
7879 free_a_printer(&printer,2);
7884 /****************************************************************
7885 _spoolss_AddPrinterEx
7886 ****************************************************************/
7888 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7889 struct spoolss_AddPrinterEx *r)
7891 switch (r->in.info_ctr->level) {
7893 /* we don't handle yet */
7894 /* but I know what to do ... */
7895 return WERR_UNKNOWN_LEVEL;
7897 return spoolss_addprinterex_level_2(p, r->in.server,
7899 r->in.devmode_ctr->devmode,
7900 r->in.secdesc_ctr->sd,
7901 r->in.userlevel_ctr,
7904 return WERR_UNKNOWN_LEVEL;
7908 /****************************************************************************
7909 ****************************************************************************/
7911 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
7913 uint32 level = q_u->level;
7914 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
7915 WERROR err = WERR_OK;
7916 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7917 fstring driver_name;
7920 ZERO_STRUCT(driver);
7922 if (!convert_printer_driver_info(info, &driver, level)) {
7927 DEBUG(5,("Cleaning driver's information\n"));
7928 err = clean_up_driver_struct(p, driver, level);
7929 if (!W_ERROR_IS_OK(err))
7932 DEBUG(5,("Moving driver to final destination\n"));
7933 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7938 if (add_a_printer_driver(driver, level)!=0) {
7939 err = WERR_ACCESS_DENIED;
7945 fstrcpy(driver_name,
7946 driver.info_3->name ? driver.info_3->name : "");
7949 fstrcpy(driver_name,
7950 driver.info_6->name ? driver.info_6->name : "");
7955 * I think this is where he DrvUpgradePrinter() hook would be
7956 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7957 * server. Right now, we just need to send ourselves a message
7958 * to update each printer bound to this driver. --jerry
7961 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7962 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7967 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7968 * decide if the driver init data should be deleted. The rules are:
7969 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7970 * 2) delete init data only if there is no 2k/Xp driver
7971 * 3) always delete init data
7972 * The generalized rule is always use init data from the highest order driver.
7973 * It is necessary to follow the driver install by an initialization step to
7974 * finish off this process.
7977 version = driver.info_3->cversion;
7978 else if (level == 6)
7979 version = driver.info_6->version;
7984 * 9x printer driver - never delete init data
7987 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7992 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7993 * there is no 2k/Xp driver init data for this driver name.
7997 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7999 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
8001 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
8003 if (!del_driver_init(driver_name))
8004 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
8007 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
8009 free_a_printer_driver(driver1,3);
8010 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
8017 * 2k or Xp printer driver - always delete init data
8020 if (!del_driver_init(driver_name))
8021 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
8025 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
8031 free_a_printer_driver(driver, level);
8035 /********************************************************************
8036 * spoolss_addprinterdriverex
8037 ********************************************************************/
8039 WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
8041 SPOOL_Q_ADDPRINTERDRIVER q_u_local;
8042 SPOOL_R_ADDPRINTERDRIVER r_u_local;
8045 * we only support the semantics of AddPrinterDriver()
8046 * i.e. only copy files that are newer than existing ones
8049 if ( q_u->copy_flags != APD_COPY_NEW_FILES )
8050 return WERR_ACCESS_DENIED;
8052 ZERO_STRUCT(q_u_local);
8053 ZERO_STRUCT(r_u_local);
8055 /* just pass the information off to _spoolss_addprinterdriver() */
8056 q_u_local.server_name_ptr = q_u->server_name_ptr;
8057 copy_unistr2(&q_u_local.server_name, &q_u->server_name);
8058 q_u_local.level = q_u->level;
8059 memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
8061 return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
8064 /****************************************************************************
8065 ****************************************************************************/
8067 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8068 const char *servername,
8069 const char *long_archi,
8070 struct spoolss_DriverDirectoryInfo1 *info1,
8075 const char *pservername = NULL;
8076 const char *short_archi;
8078 pservername = canon_servername(servername);
8080 if ( !is_myname_or_ipaddr(pservername))
8081 return WERR_INVALID_PARAM;
8083 if (!(short_archi = get_short_archi(long_archi)))
8084 return WERR_INVALID_ENVIRONMENT;
8086 path = talloc_asprintf(mem_ctx,
8087 "\\\\%s\\print$\\%s", pservername, short_archi);
8092 DEBUG(4,("printer driver directory: [%s]\n", path));
8094 info1->directory_name = path;
8096 *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0);
8098 if (*needed > offered) {
8100 ZERO_STRUCTP(info1);
8101 return WERR_INSUFFICIENT_BUFFER;
8107 /****************************************************************
8108 _spoolss_GetPrinterDriverDirectory
8109 ****************************************************************/
8111 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8112 struct spoolss_GetPrinterDriverDirectory *r)
8116 /* that's an [in out] buffer */
8118 if (!r->in.buffer && (r->in.offered != 0)) {
8119 return WERR_INVALID_PARAM;
8122 if (r->in.offered > MAX_RPC_DATA_SIZE) {
8123 return WERR_INVALID_PARAM;
8126 DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n"));
8130 switch (r->in.level) {
8132 werror = getprinterdriverdir_level_1(p->mem_ctx,
8135 &r->out.info->info1,
8138 if (W_ERROR_EQUAL(werror, WERR_INSUFFICIENT_BUFFER)) {
8139 TALLOC_FREE(r->out.info);
8143 return WERR_UNKNOWN_LEVEL;
8149 /****************************************************************************
8150 ****************************************************************************/
8152 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8154 POLICY_HND *handle = &q_u->handle;
8155 uint32 idx = q_u->index;
8156 uint32 in_value_len = q_u->valuesize;
8157 uint32 in_data_len = q_u->datasize;
8158 uint32 *out_max_value_len = &r_u->valuesize;
8159 uint16 **out_value = &r_u->value;
8160 uint32 *out_value_len = &r_u->realvaluesize;
8161 uint32 *out_type = &r_u->type;
8162 uint32 *out_max_data_len = &r_u->datasize;
8163 uint8 **data_out = &r_u->data;
8164 uint32 *out_data_len = &r_u->realdatasize;
8166 NT_PRINTER_INFO_LEVEL *printer = NULL;
8168 uint32 biggest_valuesize;
8169 uint32 biggest_datasize;
8171 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8174 REGISTRY_VALUE *val = NULL;
8175 NT_PRINTER_DATA *p_data;
8176 int i, key_index, num_values;
8181 *out_max_data_len = 0;
8185 DEBUG(5,("spoolss_enumprinterdata\n"));
8188 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8192 if (!get_printer_snum(p,handle, &snum, NULL))
8195 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8196 if (!W_ERROR_IS_OK(result))
8199 p_data = printer->info_2->data;
8200 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8205 * The NT machine wants to know the biggest size of value and data
8207 * cf: MSDN EnumPrinterData remark section
8210 if ( !in_value_len && !in_data_len && (key_index != -1) )
8212 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8214 biggest_valuesize = 0;
8215 biggest_datasize = 0;
8217 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8219 for ( i=0; i<num_values; i++ )
8221 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8223 name_length = strlen(val->valuename);
8224 if ( strlen(val->valuename) > biggest_valuesize )
8225 biggest_valuesize = name_length;
8227 if ( val->size > biggest_datasize )
8228 biggest_datasize = val->size;
8230 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8234 /* the value is an UNICODE string but real_value_size is the length
8235 in bytes including the trailing 0 */
8237 *out_value_len = 2 * (1+biggest_valuesize);
8238 *out_data_len = biggest_datasize;
8240 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8246 * the value len is wrong in NT sp3
8247 * that's the number of bytes not the number of unicode chars
8250 if ( key_index != -1 )
8251 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8256 /* out_value should default to "" or else NT4 has
8257 problems unmarshalling the response */
8259 *out_max_value_len=(in_value_len/sizeof(uint16));
8262 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8264 result = WERR_NOMEM;
8267 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8273 /* the data is counted in bytes */
8275 *out_max_data_len = in_data_len;
8276 *out_data_len = in_data_len;
8278 /* only allocate when given a non-zero data_len */
8280 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8282 result = WERR_NOMEM;
8286 result = WERR_NO_MORE_ITEMS;
8292 * - counted in bytes in the request
8293 * - counted in UNICODE chars in the max reply
8294 * - counted in bytes in the real size
8296 * take a pause *before* coding not *during* coding
8300 *out_max_value_len=(in_value_len/sizeof(uint16));
8302 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8304 result = WERR_NOMEM;
8308 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8316 *out_type = regval_type( val );
8318 /* data - counted in bytes */
8320 *out_max_data_len = in_data_len;
8321 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8323 result = WERR_NOMEM;
8326 data_len = regval_size(val);
8327 if ( *data_out && data_len )
8328 memcpy( *data_out, regval_data_p(val), data_len );
8329 *out_data_len = data_len;
8333 free_a_printer(&printer, 2);
8337 /****************************************************************************
8338 ****************************************************************************/
8340 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8342 POLICY_HND *handle = &q_u->handle;
8343 UNISTR2 *value = &q_u->value;
8344 uint32 type = q_u->type;
8345 uint8 *data = q_u->data;
8346 uint32 real_len = q_u->real_len;
8348 NT_PRINTER_INFO_LEVEL *printer = NULL;
8350 WERROR status = WERR_OK;
8351 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8354 DEBUG(5,("spoolss_setprinterdata\n"));
8357 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8361 if ( Printer->printer_type == SPLHND_SERVER ) {
8362 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8363 return WERR_INVALID_PARAM;
8366 if (!get_printer_snum(p,handle, &snum, NULL))
8370 * Access check : NT returns "access denied" if you make a
8371 * SetPrinterData call without the necessary privildge.
8372 * we were originally returning OK if nothing changed
8373 * which made Win2k issue **a lot** of SetPrinterData
8374 * when connecting to a printer --jerry
8377 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8379 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8380 status = WERR_ACCESS_DENIED;
8384 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8385 if (!W_ERROR_IS_OK(status))
8388 unistr2_to_ascii(valuename, value, sizeof(valuename));
8391 * When client side code sets a magic printer data key, detect it and save
8392 * the current printer data and the magic key's data (its the DEVMODE) for
8393 * future printer/driver initializations.
8395 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8397 /* Set devmode and printer initialization info */
8398 status = save_driver_init( printer, 2, data, real_len );
8400 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8404 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8405 type, data, real_len );
8406 if ( W_ERROR_IS_OK(status) )
8407 status = mod_a_printer(printer, 2);
8411 free_a_printer(&printer, 2);
8416 /****************************************************************
8417 _spoolss_ResetPrinter
8418 ****************************************************************/
8420 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8421 struct spoolss_ResetPrinter *r)
8423 POLICY_HND *handle = r->in.handle;
8424 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8427 DEBUG(5,("_spoolss_ResetPrinter\n"));
8430 * All we do is to check to see if the handle and queue is valid.
8431 * This call really doesn't mean anything to us because we only
8432 * support RAW printing. --jerry
8436 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8437 OUR_HANDLE(handle)));
8441 if (!get_printer_snum(p,handle, &snum, NULL))
8445 /* blindly return success */
8449 /****************************************************************
8450 _spoolss_DeletePrinterData
8451 ****************************************************************/
8453 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8454 struct spoolss_DeletePrinterData *r)
8456 POLICY_HND *handle = r->in.handle;
8457 NT_PRINTER_INFO_LEVEL *printer = NULL;
8459 WERROR status = WERR_OK;
8460 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8462 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8465 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8466 OUR_HANDLE(handle)));
8470 if (!get_printer_snum(p, handle, &snum, NULL))
8473 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8474 DEBUG(3, ("_spoolss_DeletePrinterData: "
8475 "printer properties change denied by handle\n"));
8476 return WERR_ACCESS_DENIED;
8479 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8480 if (!W_ERROR_IS_OK(status))
8483 if (!r->in.value_name) {
8484 free_a_printer(&printer, 2);
8488 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8491 if ( W_ERROR_IS_OK(status) )
8492 mod_a_printer( printer, 2 );
8494 free_a_printer(&printer, 2);
8499 /****************************************************************
8501 ****************************************************************/
8503 WERROR _spoolss_AddForm(pipes_struct *p,
8504 struct spoolss_AddForm *r)
8506 POLICY_HND *handle = r->in.handle;
8507 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8508 nt_forms_struct tmpForm;
8510 WERROR status = WERR_OK;
8511 NT_PRINTER_INFO_LEVEL *printer = NULL;
8514 nt_forms_struct *list=NULL;
8515 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8517 DEBUG(5,("_spoolss_AddForm\n"));
8520 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8521 OUR_HANDLE(handle)));
8526 /* forms can be added on printer of on the print server handle */
8528 if ( Printer->printer_type == SPLHND_PRINTER )
8530 if (!get_printer_snum(p,handle, &snum, NULL))
8533 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8534 if (!W_ERROR_IS_OK(status))
8538 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8539 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8540 status = WERR_ACCESS_DENIED;
8544 /* can't add if builtin */
8546 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8547 status = WERR_FILE_EXISTS;
8551 count = get_ntforms(&list);
8553 if(!add_a_form(&list, form, &count)) {
8554 status = WERR_NOMEM;
8558 write_ntforms(&list, count);
8561 * ChangeID must always be set if this is a printer
8564 if ( Printer->printer_type == SPLHND_PRINTER )
8565 status = mod_a_printer(printer, 2);
8569 free_a_printer(&printer, 2);
8575 /****************************************************************
8577 ****************************************************************/
8579 WERROR _spoolss_DeleteForm(pipes_struct *p,
8580 struct spoolss_DeleteForm *r)
8582 POLICY_HND *handle = r->in.handle;
8583 const char *form_name = r->in.form_name;
8584 nt_forms_struct tmpForm;
8586 nt_forms_struct *list=NULL;
8587 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8589 WERROR status = WERR_OK;
8590 NT_PRINTER_INFO_LEVEL *printer = NULL;
8592 DEBUG(5,("_spoolss_DeleteForm\n"));
8595 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8596 OUR_HANDLE(handle)));
8600 /* forms can be deleted on printer of on the print server handle */
8602 if ( Printer->printer_type == SPLHND_PRINTER )
8604 if (!get_printer_snum(p,handle, &snum, NULL))
8607 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8608 if (!W_ERROR_IS_OK(status))
8612 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8613 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8614 status = WERR_ACCESS_DENIED;
8618 /* can't delete if builtin */
8620 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8621 status = WERR_INVALID_PARAM;
8625 count = get_ntforms(&list);
8627 if ( !delete_a_form(&list, form_name, &count, &status ))
8631 * ChangeID must always be set if this is a printer
8634 if ( Printer->printer_type == SPLHND_PRINTER )
8635 status = mod_a_printer(printer, 2);
8639 free_a_printer(&printer, 2);
8645 /****************************************************************
8647 ****************************************************************/
8649 WERROR _spoolss_SetForm(pipes_struct *p,
8650 struct spoolss_SetForm *r)
8652 POLICY_HND *handle = r->in.handle;
8653 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8654 nt_forms_struct tmpForm;
8656 WERROR status = WERR_OK;
8657 NT_PRINTER_INFO_LEVEL *printer = NULL;
8660 nt_forms_struct *list=NULL;
8661 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8663 DEBUG(5,("_spoolss_SetForm\n"));
8666 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8667 OUR_HANDLE(handle)));
8671 /* forms can be modified on printer of on the print server handle */
8673 if ( Printer->printer_type == SPLHND_PRINTER )
8675 if (!get_printer_snum(p,handle, &snum, NULL))
8678 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8679 if (!W_ERROR_IS_OK(status))
8683 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8684 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8685 status = WERR_ACCESS_DENIED;
8689 /* can't set if builtin */
8690 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8691 status = WERR_INVALID_PARAM;
8695 count = get_ntforms(&list);
8696 update_a_form(&list, form, count);
8697 write_ntforms(&list, count);
8700 * ChangeID must always be set if this is a printer
8703 if ( Printer->printer_type == SPLHND_PRINTER )
8704 status = mod_a_printer(printer, 2);
8709 free_a_printer(&printer, 2);
8715 /****************************************************************************
8716 enumprintprocessors level 1.
8717 ****************************************************************************/
8719 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8721 PRINTPROCESSOR_1 *info_1=NULL;
8722 WERROR result = WERR_OK;
8724 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8729 init_unistr(&info_1->name, "winprint");
8731 *needed += spoolss_size_printprocessor_info_1(info_1);
8733 if (*needed > offered) {
8734 result = WERR_INSUFFICIENT_BUFFER;
8738 if (!rpcbuf_alloc_size(buffer, *needed)) {
8739 result = WERR_NOMEM;
8743 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8748 if ( !W_ERROR_IS_OK(result) )
8754 /****************************************************************************
8755 ****************************************************************************/
8757 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8759 uint32 level = q_u->level;
8760 RPC_BUFFER *buffer = NULL;
8761 uint32 offered = q_u->offered;
8762 uint32 *needed = &r_u->needed;
8763 uint32 *returned = &r_u->returned;
8765 /* that's an [in out] buffer */
8767 if (!q_u->buffer && (offered!=0)) {
8768 return WERR_INVALID_PARAM;
8771 if (offered > MAX_RPC_DATA_SIZE) {
8772 return WERR_INVALID_PARAM;
8775 rpcbuf_move(q_u->buffer, &r_u->buffer);
8776 buffer = r_u->buffer;
8778 DEBUG(5,("spoolss_enumprintprocessors\n"));
8781 * Enumerate the print processors ...
8783 * Just reply with "winprint", to keep NT happy
8784 * and I can use my nice printer checker.
8792 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8794 return WERR_UNKNOWN_LEVEL;
8798 /****************************************************************************
8799 enumprintprocdatatypes level 1.
8800 ****************************************************************************/
8802 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8804 PRINTPROCDATATYPE_1 *info_1=NULL;
8805 WERROR result = WERR_OK;
8807 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8812 init_unistr(&info_1->name, "RAW");
8814 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8816 if (*needed > offered) {
8817 result = WERR_INSUFFICIENT_BUFFER;
8821 if (!rpcbuf_alloc_size(buffer, *needed)) {
8822 result = WERR_NOMEM;
8826 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8831 if ( !W_ERROR_IS_OK(result) )
8837 /****************************************************************************
8838 ****************************************************************************/
8840 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8842 uint32 level = q_u->level;
8843 RPC_BUFFER *buffer = NULL;
8844 uint32 offered = q_u->offered;
8845 uint32 *needed = &r_u->needed;
8846 uint32 *returned = &r_u->returned;
8848 /* that's an [in out] buffer */
8850 if (!q_u->buffer && (offered!=0)) {
8851 return WERR_INVALID_PARAM;
8854 if (offered > MAX_RPC_DATA_SIZE) {
8855 return WERR_INVALID_PARAM;
8858 rpcbuf_move(q_u->buffer, &r_u->buffer);
8859 buffer = r_u->buffer;
8861 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8868 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8870 return WERR_UNKNOWN_LEVEL;
8874 /****************************************************************************
8875 enumprintmonitors level 1.
8876 ****************************************************************************/
8878 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8880 PRINTMONITOR_1 *info_1;
8881 WERROR result = WERR_OK;
8884 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8889 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8890 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8892 for ( i=0; i<*returned; i++ ) {
8893 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8896 if (*needed > offered) {
8897 result = WERR_INSUFFICIENT_BUFFER;
8901 if (!rpcbuf_alloc_size(buffer, *needed)) {
8902 result = WERR_NOMEM;
8906 for ( i=0; i<*returned; i++ ) {
8907 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8913 if ( !W_ERROR_IS_OK(result) )
8919 /****************************************************************************
8920 enumprintmonitors level 2.
8921 ****************************************************************************/
8923 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8925 PRINTMONITOR_2 *info_2;
8926 WERROR result = WERR_OK;
8929 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8934 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8935 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8936 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8938 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8939 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8940 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8942 for ( i=0; i<*returned; i++ ) {
8943 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8946 if (*needed > offered) {
8947 result = WERR_INSUFFICIENT_BUFFER;
8951 if (!rpcbuf_alloc_size(buffer, *needed)) {
8952 result = WERR_NOMEM;
8956 for ( i=0; i<*returned; i++ ) {
8957 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8963 if ( !W_ERROR_IS_OK(result) )
8969 /****************************************************************************
8970 ****************************************************************************/
8972 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8974 uint32 level = q_u->level;
8975 RPC_BUFFER *buffer = NULL;
8976 uint32 offered = q_u->offered;
8977 uint32 *needed = &r_u->needed;
8978 uint32 *returned = &r_u->returned;
8980 /* that's an [in out] buffer */
8982 if (!q_u->buffer && (offered!=0)) {
8983 return WERR_INVALID_PARAM;
8986 if (offered > MAX_RPC_DATA_SIZE) {
8987 return WERR_INVALID_PARAM;
8990 rpcbuf_move(q_u->buffer, &r_u->buffer);
8991 buffer = r_u->buffer;
8993 DEBUG(5,("spoolss_enumprintmonitors\n"));
8996 * Enumerate the print monitors ...
8998 * Just reply with "Local Port", to keep NT happy
8999 * and I can use my nice printer checker.
9007 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9009 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9011 return WERR_UNKNOWN_LEVEL;
9015 /****************************************************************************
9016 ****************************************************************************/
9018 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9019 NT_PRINTER_INFO_LEVEL *ntprinter,
9020 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9025 JOB_INFO_1 *info_1=NULL;
9026 WERROR result = WERR_OK;
9028 info_1=SMB_MALLOC_P(JOB_INFO_1);
9030 if (info_1 == NULL) {
9034 for (i=0; i<count && found==False; i++) {
9035 if ((*queue)[i].job==(int)jobid)
9041 /* NT treats not found as bad param... yet another bad choice */
9042 return WERR_INVALID_PARAM;
9045 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9047 *needed += spoolss_size_job_info_1(info_1);
9049 if (*needed > offered) {
9050 result = WERR_INSUFFICIENT_BUFFER;
9054 if (!rpcbuf_alloc_size(buffer, *needed)) {
9055 result = WERR_NOMEM;
9059 smb_io_job_info_1("", buffer, info_1, 0);
9067 /****************************************************************************
9068 ****************************************************************************/
9070 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9071 NT_PRINTER_INFO_LEVEL *ntprinter,
9072 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9079 DEVICEMODE *devmode = NULL;
9080 NT_DEVICEMODE *nt_devmode = NULL;
9082 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9085 ZERO_STRUCTP(info_2);
9087 for ( i=0; i<count && found==False; i++ )
9089 if ((*queue)[i].job == (int)jobid)
9094 /* NT treats not found as bad param... yet another bad
9096 result = WERR_INVALID_PARAM;
9101 * if the print job does not have a DEVMODE associated with it,
9102 * just use the one for the printer. A NULL devicemode is not
9103 * a failure condition
9106 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9107 devmode = construct_dev_mode(lp_const_servicename(snum));
9109 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9110 ZERO_STRUCTP( devmode );
9111 convert_nt_devicemode( devmode, nt_devmode );
9115 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9117 *needed += spoolss_size_job_info_2(info_2);
9119 if (*needed > offered) {
9120 result = WERR_INSUFFICIENT_BUFFER;
9124 if (!rpcbuf_alloc_size(buffer, *needed)) {
9125 result = WERR_NOMEM;
9129 smb_io_job_info_2("", buffer, info_2, 0);
9134 /* Cleanup allocated memory */
9136 free_job_info_2(info_2); /* Also frees devmode */
9142 /****************************************************************************
9143 ****************************************************************************/
9145 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9147 POLICY_HND *handle = &q_u->handle;
9148 uint32 jobid = q_u->jobid;
9149 uint32 level = q_u->level;
9150 RPC_BUFFER *buffer = NULL;
9151 uint32 offered = q_u->offered;
9152 uint32 *needed = &r_u->needed;
9153 WERROR wstatus = WERR_OK;
9154 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9157 print_queue_struct *queue = NULL;
9158 print_status_struct prt_status;
9160 /* that's an [in out] buffer */
9162 if (!q_u->buffer && (offered!=0)) {
9163 return WERR_INVALID_PARAM;
9166 if (offered > MAX_RPC_DATA_SIZE) {
9167 return WERR_INVALID_PARAM;
9170 rpcbuf_move(q_u->buffer, &r_u->buffer);
9171 buffer = r_u->buffer;
9173 DEBUG(5,("spoolss_getjob\n"));
9177 if (!get_printer_snum(p, handle, &snum, NULL))
9180 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9181 if ( !W_ERROR_IS_OK(wstatus) )
9184 count = print_queue_status(snum, &queue, &prt_status);
9186 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9187 count, prt_status.status, prt_status.message));
9191 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9192 buffer, offered, needed);
9195 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9196 buffer, offered, needed);
9199 wstatus = WERR_UNKNOWN_LEVEL;
9204 free_a_printer( &ntprinter, 2 );
9209 /****************************************************************
9210 _spoolss_GetPrinterDataEx
9212 From MSDN documentation of GetPrinterDataEx: pass request
9213 to GetPrinterData if key is "PrinterDriverData".
9214 ****************************************************************/
9216 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9217 struct spoolss_GetPrinterDataEx *r)
9219 POLICY_HND *handle = r->in.handle;
9221 const char *keyname = r->in.key_name;
9222 const char *valuename = r->in.value_name;
9224 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9226 NT_PRINTER_INFO_LEVEL *printer = NULL;
9228 WERROR status = WERR_OK;
9230 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9232 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9233 keyname, valuename));
9235 /* in case of problem, return some default values */
9241 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9242 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9243 status = WERR_BADFID;
9247 /* Is the handle to a printer or to the server? */
9249 if (Printer->printer_type == SPLHND_SERVER) {
9250 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9251 "Not implemented for server handles yet\n"));
9252 status = WERR_INVALID_PARAM;
9256 if ( !get_printer_snum(p,handle, &snum, NULL) )
9259 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9260 if ( !W_ERROR_IS_OK(status) )
9263 /* check to see if the keyname is valid */
9264 if ( !strlen(keyname) ) {
9265 status = WERR_INVALID_PARAM;
9269 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9270 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9271 "Invalid keyname [%s]\n", keyname ));
9272 free_a_printer( &printer, 2 );
9273 status = WERR_BADFILE;
9277 /* When given a new keyname, we should just create it */
9279 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9280 r->out.type, &data, r->out.needed,
9283 if (*r->out.needed > r->in.offered) {
9284 status = WERR_MORE_DATA;
9287 if (W_ERROR_IS_OK(status)) {
9288 memcpy(r->out.buffer, data, r->in.offered);
9293 free_a_printer( &printer, 2 );
9298 /****************************************************************
9299 _spoolss_SetPrinterDataEx
9300 ****************************************************************/
9302 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9303 struct spoolss_SetPrinterDataEx *r)
9305 POLICY_HND *handle = r->in.handle;
9306 NT_PRINTER_INFO_LEVEL *printer = NULL;
9308 WERROR status = WERR_OK;
9309 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9312 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9314 /* From MSDN documentation of SetPrinterDataEx: pass request to
9315 SetPrinterData if key is "PrinterDriverData" */
9318 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9319 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9323 if ( Printer->printer_type == SPLHND_SERVER ) {
9324 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9325 "Not implemented for server handles yet\n"));
9326 return WERR_INVALID_PARAM;
9329 if ( !get_printer_snum(p,handle, &snum, NULL) )
9333 * Access check : NT returns "access denied" if you make a
9334 * SetPrinterData call without the necessary privildge.
9335 * we were originally returning OK if nothing changed
9336 * which made Win2k issue **a lot** of SetPrinterData
9337 * when connecting to a printer --jerry
9340 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9342 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9343 "change denied by handle access permissions\n"));
9344 return WERR_ACCESS_DENIED;
9347 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9348 if (!W_ERROR_IS_OK(status))
9351 /* check for OID in valuename */
9353 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9359 /* save the registry data */
9361 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9362 r->in.type, r->in.buffer, r->in.offered );
9364 if ( W_ERROR_IS_OK(status) )
9366 /* save the OID if one was specified */
9368 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9369 r->in.key_name, SPOOL_OID_KEY);
9375 * I'm not checking the status here on purpose. Don't know
9376 * if this is right, but I'm returning the status from the
9377 * previous set_printer_dataex() call. I have no idea if
9378 * this is right. --jerry
9381 set_printer_dataex( printer, str, r->in.value_name,
9382 REG_SZ, (uint8 *)oid_string,
9383 strlen(oid_string)+1 );
9386 status = mod_a_printer(printer, 2);
9389 free_a_printer(&printer, 2);
9394 /****************************************************************
9395 _spoolss_DeletePrinterDataEx
9396 ****************************************************************/
9398 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9399 struct spoolss_DeletePrinterDataEx *r)
9401 POLICY_HND *handle = r->in.handle;
9402 NT_PRINTER_INFO_LEVEL *printer = NULL;
9404 WERROR status = WERR_OK;
9405 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9407 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9410 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9411 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9415 if (!get_printer_snum(p, handle, &snum, NULL))
9418 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9419 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9420 "printer properties change denied by handle\n"));
9421 return WERR_ACCESS_DENIED;
9424 if (!r->in.value_name || !r->in.key_name) {
9428 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9429 if (!W_ERROR_IS_OK(status))
9432 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9434 if ( W_ERROR_IS_OK(status) )
9435 mod_a_printer( printer, 2 );
9437 free_a_printer(&printer, 2);
9442 /********************************************************************
9443 * spoolss_enumprinterkey
9444 ********************************************************************/
9447 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9450 fstring *keynames = NULL;
9451 uint16 *enumkeys = NULL;
9454 POLICY_HND *handle = &q_u->handle;
9455 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9456 NT_PRINTER_DATA *data;
9457 NT_PRINTER_INFO_LEVEL *printer = NULL;
9459 WERROR status = WERR_BADFILE;
9462 DEBUG(4,("_spoolss_enumprinterkey\n"));
9465 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9469 if ( !get_printer_snum(p,handle, &snum, NULL) )
9472 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9473 if (!W_ERROR_IS_OK(status))
9476 /* get the list of subkey names */
9478 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9479 data = printer->info_2->data;
9481 num_keys = get_printer_subkeys( data, key, &keynames );
9483 if ( num_keys == -1 ) {
9484 status = WERR_BADFILE;
9488 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9490 r_u->needed = printerkey_len*2;
9492 if ( q_u->size < r_u->needed ) {
9493 status = WERR_MORE_DATA;
9497 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9498 status = WERR_NOMEM;
9504 if ( q_u->size < r_u->needed )
9505 status = WERR_MORE_DATA;
9508 free_a_printer( &printer, 2 );
9509 SAFE_FREE( keynames );
9514 /****************************************************************
9515 _spoolss_DeletePrinterKey
9516 ****************************************************************/
9518 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9519 struct spoolss_DeletePrinterKey *r)
9521 POLICY_HND *handle = r->in.handle;
9522 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9523 NT_PRINTER_INFO_LEVEL *printer = NULL;
9527 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9530 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9531 OUR_HANDLE(handle)));
9535 /* if keyname == NULL, return error */
9537 if ( !r->in.key_name )
9538 return WERR_INVALID_PARAM;
9540 if (!get_printer_snum(p, handle, &snum, NULL))
9543 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9544 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9545 "printer properties change denied by handle\n"));
9546 return WERR_ACCESS_DENIED;
9549 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9550 if (!W_ERROR_IS_OK(status))
9553 /* delete the key and all subneys */
9555 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9557 if ( W_ERROR_IS_OK(status) )
9558 status = mod_a_printer(printer, 2);
9560 free_a_printer( &printer, 2 );
9566 /********************************************************************
9567 * spoolss_enumprinterdataex
9568 ********************************************************************/
9570 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9572 POLICY_HND *handle = &q_u->handle;
9573 uint32 in_size = q_u->size;
9576 NT_PRINTER_INFO_LEVEL *printer = NULL;
9577 PRINTER_ENUM_VALUES *enum_values = NULL;
9578 NT_PRINTER_DATA *p_data;
9580 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9585 REGISTRY_VALUE *val;
9590 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9593 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9598 * first check for a keyname of NULL or "". Win2k seems to send
9599 * this a lot and we should send back WERR_INVALID_PARAM
9600 * no need to spend time looking up the printer in this case.
9604 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9605 if ( !strlen(key) ) {
9606 result = WERR_INVALID_PARAM;
9610 /* get the printer off of disk */
9612 if (!get_printer_snum(p,handle, &snum, NULL))
9615 ZERO_STRUCT(printer);
9616 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9617 if (!W_ERROR_IS_OK(result))
9620 /* now look for a match on the key name */
9622 p_data = printer->info_2->data;
9624 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9625 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9627 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9628 result = WERR_INVALID_PARAM;
9635 /* allocate the memory for the array of pointers -- if necessary */
9637 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9640 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9642 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9643 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9644 result = WERR_NOMEM;
9648 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9652 * loop through all params and build the array to pass
9653 * back to the client
9656 for ( i=0; i<num_entries; i++ )
9658 /* lookup the registry value */
9660 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9661 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9665 value_name = regval_name( val );
9666 init_unistr( &enum_values[i].valuename, value_name );
9667 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9668 enum_values[i].type = regval_type( val );
9670 data_len = regval_size( val );
9672 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9674 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9676 result = WERR_NOMEM;
9680 enum_values[i].data_len = data_len;
9682 /* keep track of the size of the array in bytes */
9684 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9687 /* housekeeping information in the reply */
9689 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9690 * the hand marshalled container size is a multiple
9691 * of 4 bytes for RPC alignment.
9695 needed += 4-(needed % 4);
9698 r_u->needed = needed;
9699 r_u->returned = num_entries;
9701 if (needed > in_size) {
9702 result = WERR_MORE_DATA;
9706 /* copy data into the reply */
9708 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9709 response buffer size is != the offered buffer size
9711 r_u->ctr.size = r_u->needed;
9713 r_u->ctr.size = in_size;
9715 r_u->ctr.size_of_array = r_u->returned;
9716 r_u->ctr.values = enum_values;
9720 free_a_printer(&printer, 2);
9725 /****************************************************************************
9726 ****************************************************************************/
9728 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, const char *name)
9730 init_unistr(&info->name, name);
9733 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
9734 UNISTR2 *environment,
9739 char *long_archi = NULL;
9740 PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
9741 WERROR result = WERR_OK;
9742 TALLOC_CTX *ctx = talloc_tos();
9744 long_archi = unistr2_to_ascii_talloc(ctx, environment);
9749 if (!get_short_archi(long_archi))
9750 return WERR_INVALID_ENVIRONMENT;
9752 if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
9755 fill_printprocessordirectory_1(info, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9757 *needed += spoolss_size_printprocessordirectory_info_1(info);
9759 if (*needed > offered) {
9760 result = WERR_INSUFFICIENT_BUFFER;
9764 if (!rpcbuf_alloc_size(buffer, *needed)) {
9765 result = WERR_INSUFFICIENT_BUFFER;
9769 smb_io_printprocessordirectory_1("", buffer, info, 0);
9777 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
9779 uint32 level = q_u->level;
9780 RPC_BUFFER *buffer = NULL;
9781 uint32 offered = q_u->offered;
9782 uint32 *needed = &r_u->needed;
9785 /* that's an [in out] buffer */
9787 if (!q_u->buffer && (offered!=0)) {
9788 return WERR_INVALID_PARAM;
9791 if (offered > MAX_RPC_DATA_SIZE) {
9792 return WERR_INVALID_PARAM;
9795 rpcbuf_move(q_u->buffer, &r_u->buffer);
9796 buffer = r_u->buffer;
9798 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9804 result = getprintprocessordirectory_level_1
9805 (&q_u->name, &q_u->environment, buffer, offered, needed);
9808 result = WERR_UNKNOWN_LEVEL;
9814 /*******************************************************************
9815 ********************************************************************/
9817 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9818 const char *dllname)
9820 enum ndr_err_code ndr_err;
9821 struct spoolss_MonitorUi ui;
9823 ui.dll_name = dllname;
9825 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9826 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9827 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9828 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9830 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9833 /*******************************************************************
9834 Streams the monitor UI DLL name in UNICODE
9835 *******************************************************************/
9837 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9838 NT_USER_TOKEN *token, DATA_BLOB *in,
9839 DATA_BLOB *out, uint32_t *needed)
9841 const char *dllname = "tcpmonui.dll";
9843 *needed = (strlen(dllname)+1) * 2;
9845 if (out->length < *needed) {
9846 return WERR_INSUFFICIENT_BUFFER;
9849 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9856 /*******************************************************************
9857 ********************************************************************/
9859 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9860 struct spoolss_PortData1 *port1,
9861 const DATA_BLOB *buf)
9863 enum ndr_err_code ndr_err;
9864 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9865 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9866 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9867 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9869 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9872 /*******************************************************************
9873 ********************************************************************/
9875 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9876 struct spoolss_PortData2 *port2,
9877 const DATA_BLOB *buf)
9879 enum ndr_err_code ndr_err;
9880 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9881 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9882 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9883 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9885 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9888 /*******************************************************************
9889 Create a new TCP/IP port
9890 *******************************************************************/
9892 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9893 NT_USER_TOKEN *token, DATA_BLOB *in,
9894 DATA_BLOB *out, uint32_t *needed)
9896 struct spoolss_PortData1 port1;
9897 struct spoolss_PortData2 port2;
9898 char *device_uri = NULL;
9901 const char *portname;
9902 const char *hostaddress;
9904 uint32_t port_number;
9907 /* peek for spoolss_PortData version */
9909 if (!in || (in->length < (128 + 4))) {
9910 return WERR_GENERAL_FAILURE;
9913 version = IVAL(in->data, 128);
9919 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9923 portname = port1.portname;
9924 hostaddress = port1.hostaddress;
9925 queue = port1.queue;
9926 protocol = port1.protocol;
9927 port_number = port1.port_number;
9933 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9937 portname = port2.portname;
9938 hostaddress = port2.hostaddress;
9939 queue = port2.queue;
9940 protocol = port2.protocol;
9941 port_number = port2.port_number;
9945 DEBUG(1,("xcvtcp_addport: "
9946 "unknown version of port_data: %d\n", version));
9947 return WERR_UNKNOWN_PORT;
9950 /* create the device URI and call the add_port_hook() */
9953 case PROTOCOL_RAWTCP_TYPE:
9954 device_uri = talloc_asprintf(mem_ctx,
9955 "socket://%s:%d/", hostaddress,
9959 case PROTOCOL_LPR_TYPE:
9960 device_uri = talloc_asprintf(mem_ctx,
9961 "lpr://%s/%s", hostaddress, queue );
9965 return WERR_UNKNOWN_PORT;
9972 return add_port_hook(mem_ctx, token, portname, device_uri);
9975 /*******************************************************************
9976 *******************************************************************/
9978 struct xcv_api_table xcvtcp_cmds[] = {
9979 { "MonitorUI", xcvtcp_monitorui },
9980 { "AddPort", xcvtcp_addport},
9984 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9985 NT_USER_TOKEN *token, const char *command,
9992 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9994 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9995 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9996 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9999 return WERR_BADFUNC;
10002 /*******************************************************************
10003 *******************************************************************/
10004 #if 0 /* don't support management using the "Local Port" monitor */
10006 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
10007 NT_USER_TOKEN *token, DATA_BLOB *in,
10008 DATA_BLOB *out, uint32_t *needed)
10010 const char *dllname = "localui.dll";
10012 *needed = (strlen(dllname)+1) * 2;
10014 if (out->length < *needed) {
10015 return WERR_INSUFFICIENT_BUFFER;
10018 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10025 /*******************************************************************
10026 *******************************************************************/
10028 struct xcv_api_table xcvlocal_cmds[] = {
10029 { "MonitorUI", xcvlocal_monitorui },
10033 struct xcv_api_table xcvlocal_cmds[] = {
10040 /*******************************************************************
10041 *******************************************************************/
10043 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10044 NT_USER_TOKEN *token, const char *command,
10045 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10050 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10052 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10053 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10054 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10056 return WERR_BADFUNC;
10059 /****************************************************************
10061 ****************************************************************/
10063 WERROR _spoolss_XcvData(pipes_struct *p,
10064 struct spoolss_XcvData *r)
10066 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10067 DATA_BLOB out_data;
10071 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10072 OUR_HANDLE(r->in.handle)));
10073 return WERR_BADFID;
10076 /* Has to be a handle to the TCP/IP port monitor */
10078 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10079 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10080 return WERR_BADFID;
10083 /* requires administrative access to the server */
10085 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10086 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10087 return WERR_ACCESS_DENIED;
10090 /* Allocate the outgoing buffer */
10092 if (r->in.out_data_size) {
10093 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10094 if (out_data.data == NULL) {
10099 switch ( Printer->printer_type ) {
10100 case SPLHND_PORTMON_TCP:
10101 werror = process_xcvtcp_command(p->mem_ctx,
10102 p->server_info->ptok,
10103 r->in.function_name,
10104 &r->in.in_data, &out_data,
10107 case SPLHND_PORTMON_LOCAL:
10108 werror = process_xcvlocal_command(p->mem_ctx,
10109 p->server_info->ptok,
10110 r->in.function_name,
10111 &r->in.in_data, &out_data,
10115 werror = WERR_INVALID_PRINT_MONITOR;
10118 if (!W_ERROR_IS_OK(werror)) {
10122 *r->out.status_code = 0;
10124 memcpy(r->out.out_data, out_data.data, out_data.length);
10129 /****************************************************************
10130 _spoolss_AddPrintProcessor
10131 ****************************************************************/
10133 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10134 struct spoolss_AddPrintProcessor *r)
10136 /* for now, just indicate success and ignore the add. We'll
10137 automatically set the winprint processor for printer
10138 entries later. Used to debug the LexMark Optra S 1855 PCL
10144 /****************************************************************
10145 _spoolss_EnumPrinters
10146 ****************************************************************/
10148 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10149 struct spoolss_EnumPrinters *r)
10151 p->rng_fault_state = true;
10152 return WERR_NOT_SUPPORTED;
10155 /****************************************************************
10157 ****************************************************************/
10159 WERROR _spoolss_GetJob(pipes_struct *p,
10160 struct spoolss_GetJob *r)
10162 p->rng_fault_state = true;
10163 return WERR_NOT_SUPPORTED;
10166 /****************************************************************
10168 ****************************************************************/
10170 WERROR _spoolss_EnumJobs(pipes_struct *p,
10171 struct spoolss_EnumJobs *r)
10173 p->rng_fault_state = true;
10174 return WERR_NOT_SUPPORTED;
10177 /****************************************************************
10178 _spoolss_AddPrinter
10179 ****************************************************************/
10181 WERROR _spoolss_AddPrinter(pipes_struct *p,
10182 struct spoolss_AddPrinter *r)
10184 p->rng_fault_state = true;
10185 return WERR_NOT_SUPPORTED;
10188 /****************************************************************
10189 _spoolss_GetPrinter
10190 ****************************************************************/
10192 WERROR _spoolss_GetPrinter(pipes_struct *p,
10193 struct spoolss_GetPrinter *r)
10195 p->rng_fault_state = true;
10196 return WERR_NOT_SUPPORTED;
10199 /****************************************************************
10200 _spoolss_AddPrinterDriver
10201 ****************************************************************/
10203 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
10204 struct spoolss_AddPrinterDriver *r)
10206 p->rng_fault_state = true;
10207 return WERR_NOT_SUPPORTED;
10210 /****************************************************************
10211 _spoolss_EnumPrinterDrivers
10212 ****************************************************************/
10214 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10215 struct spoolss_EnumPrinterDrivers *r)
10217 p->rng_fault_state = true;
10218 return WERR_NOT_SUPPORTED;
10221 /****************************************************************
10222 _spoolss_GetPrinterDriver
10223 ****************************************************************/
10225 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10226 struct spoolss_GetPrinterDriver *r)
10228 p->rng_fault_state = true;
10229 return WERR_NOT_SUPPORTED;
10232 /****************************************************************
10233 _spoolss_EnumPrintProcessors
10234 ****************************************************************/
10236 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10237 struct spoolss_EnumPrintProcessors *r)
10239 p->rng_fault_state = true;
10240 return WERR_NOT_SUPPORTED;
10243 /****************************************************************
10244 _spoolss_GetPrintProcessorDirectory
10245 ****************************************************************/
10247 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
10248 struct spoolss_GetPrintProcessorDirectory *r)
10250 p->rng_fault_state = true;
10251 return WERR_NOT_SUPPORTED;
10254 /****************************************************************
10255 _spoolss_ReadPrinter
10256 ****************************************************************/
10258 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10259 struct spoolss_ReadPrinter *r)
10261 p->rng_fault_state = true;
10262 return WERR_NOT_SUPPORTED;
10265 /****************************************************************
10266 _spoolss_GetPrinterData
10267 ****************************************************************/
10269 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10270 struct spoolss_GetPrinterData *r)
10272 p->rng_fault_state = true;
10273 return WERR_NOT_SUPPORTED;
10276 /****************************************************************
10277 _spoolss_SetPrinterData
10278 ****************************************************************/
10280 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10281 struct spoolss_SetPrinterData *r)
10283 p->rng_fault_state = true;
10284 return WERR_NOT_SUPPORTED;
10287 /****************************************************************
10288 _spoolss_WaitForPrinterChange
10289 ****************************************************************/
10291 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10292 struct spoolss_WaitForPrinterChange *r)
10294 p->rng_fault_state = true;
10295 return WERR_NOT_SUPPORTED;
10298 /****************************************************************
10300 ****************************************************************/
10302 WERROR _spoolss_EnumForms(pipes_struct *p,
10303 struct spoolss_EnumForms *r)
10305 p->rng_fault_state = true;
10306 return WERR_NOT_SUPPORTED;
10309 /****************************************************************
10311 ****************************************************************/
10313 WERROR _spoolss_EnumPorts(pipes_struct *p,
10314 struct spoolss_EnumPorts *r)
10316 p->rng_fault_state = true;
10317 return WERR_NOT_SUPPORTED;
10320 /****************************************************************
10321 _spoolss_EnumMonitors
10322 ****************************************************************/
10324 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10325 struct spoolss_EnumMonitors *r)
10327 p->rng_fault_state = true;
10328 return WERR_NOT_SUPPORTED;
10331 /****************************************************************
10333 ****************************************************************/
10335 WERROR _spoolss_AddPort(pipes_struct *p,
10336 struct spoolss_AddPort *r)
10338 p->rng_fault_state = true;
10339 return WERR_NOT_SUPPORTED;
10342 /****************************************************************
10343 _spoolss_ConfigurePort
10344 ****************************************************************/
10346 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10347 struct spoolss_ConfigurePort *r)
10349 p->rng_fault_state = true;
10350 return WERR_NOT_SUPPORTED;
10353 /****************************************************************
10354 _spoolss_DeletePort
10355 ****************************************************************/
10357 WERROR _spoolss_DeletePort(pipes_struct *p,
10358 struct spoolss_DeletePort *r)
10360 p->rng_fault_state = true;
10361 return WERR_NOT_SUPPORTED;
10364 /****************************************************************
10365 _spoolss_CreatePrinterIC
10366 ****************************************************************/
10368 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10369 struct spoolss_CreatePrinterIC *r)
10371 p->rng_fault_state = true;
10372 return WERR_NOT_SUPPORTED;
10375 /****************************************************************
10376 _spoolss_PlayGDIScriptOnPrinterIC
10377 ****************************************************************/
10379 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10380 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10382 p->rng_fault_state = true;
10383 return WERR_NOT_SUPPORTED;
10386 /****************************************************************
10387 _spoolss_DeletePrinterIC
10388 ****************************************************************/
10390 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10391 struct spoolss_DeletePrinterIC *r)
10393 p->rng_fault_state = true;
10394 return WERR_NOT_SUPPORTED;
10397 /****************************************************************
10398 _spoolss_AddPrinterConnection
10399 ****************************************************************/
10401 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10402 struct spoolss_AddPrinterConnection *r)
10404 p->rng_fault_state = true;
10405 return WERR_NOT_SUPPORTED;
10408 /****************************************************************
10409 _spoolss_DeletePrinterConnection
10410 ****************************************************************/
10412 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10413 struct spoolss_DeletePrinterConnection *r)
10415 p->rng_fault_state = true;
10416 return WERR_NOT_SUPPORTED;
10419 /****************************************************************
10420 _spoolss_PrinterMessageBox
10421 ****************************************************************/
10423 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10424 struct spoolss_PrinterMessageBox *r)
10426 p->rng_fault_state = true;
10427 return WERR_NOT_SUPPORTED;
10430 /****************************************************************
10431 _spoolss_AddMonitor
10432 ****************************************************************/
10434 WERROR _spoolss_AddMonitor(pipes_struct *p,
10435 struct spoolss_AddMonitor *r)
10437 p->rng_fault_state = true;
10438 return WERR_NOT_SUPPORTED;
10441 /****************************************************************
10442 _spoolss_DeleteMonitor
10443 ****************************************************************/
10445 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10446 struct spoolss_DeleteMonitor *r)
10448 p->rng_fault_state = true;
10449 return WERR_NOT_SUPPORTED;
10452 /****************************************************************
10453 _spoolss_DeletePrintProcessor
10454 ****************************************************************/
10456 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10457 struct spoolss_DeletePrintProcessor *r)
10459 p->rng_fault_state = true;
10460 return WERR_NOT_SUPPORTED;
10463 /****************************************************************
10464 _spoolss_AddPrintProvidor
10465 ****************************************************************/
10467 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10468 struct spoolss_AddPrintProvidor *r)
10470 p->rng_fault_state = true;
10471 return WERR_NOT_SUPPORTED;
10474 /****************************************************************
10475 _spoolss_DeletePrintProvidor
10476 ****************************************************************/
10478 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10479 struct spoolss_DeletePrintProvidor *r)
10481 p->rng_fault_state = true;
10482 return WERR_NOT_SUPPORTED;
10485 /****************************************************************
10486 _spoolss_EnumPrintProcDataTypes
10487 ****************************************************************/
10489 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10490 struct spoolss_EnumPrintProcDataTypes *r)
10492 p->rng_fault_state = true;
10493 return WERR_NOT_SUPPORTED;
10496 /****************************************************************
10497 _spoolss_GetPrinterDriver2
10498 ****************************************************************/
10500 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10501 struct spoolss_GetPrinterDriver2 *r)
10503 p->rng_fault_state = true;
10504 return WERR_NOT_SUPPORTED;
10507 /****************************************************************
10508 _spoolss_FindFirstPrinterChangeNotification
10509 ****************************************************************/
10511 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10512 struct spoolss_FindFirstPrinterChangeNotification *r)
10514 p->rng_fault_state = true;
10515 return WERR_NOT_SUPPORTED;
10518 /****************************************************************
10519 _spoolss_FindNextPrinterChangeNotification
10520 ****************************************************************/
10522 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10523 struct spoolss_FindNextPrinterChangeNotification *r)
10525 p->rng_fault_state = true;
10526 return WERR_NOT_SUPPORTED;
10529 /****************************************************************
10530 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10531 ****************************************************************/
10533 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10534 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10536 p->rng_fault_state = true;
10537 return WERR_NOT_SUPPORTED;
10540 /****************************************************************
10541 _spoolss_ReplyOpenPrinter
10542 ****************************************************************/
10544 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10545 struct spoolss_ReplyOpenPrinter *r)
10547 p->rng_fault_state = true;
10548 return WERR_NOT_SUPPORTED;
10551 /****************************************************************
10552 _spoolss_RouterReplyPrinter
10553 ****************************************************************/
10555 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10556 struct spoolss_RouterReplyPrinter *r)
10558 p->rng_fault_state = true;
10559 return WERR_NOT_SUPPORTED;
10562 /****************************************************************
10563 _spoolss_ReplyClosePrinter
10564 ****************************************************************/
10566 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10567 struct spoolss_ReplyClosePrinter *r)
10569 p->rng_fault_state = true;
10570 return WERR_NOT_SUPPORTED;
10573 /****************************************************************
10575 ****************************************************************/
10577 WERROR _spoolss_AddPortEx(pipes_struct *p,
10578 struct spoolss_AddPortEx *r)
10580 p->rng_fault_state = true;
10581 return WERR_NOT_SUPPORTED;
10584 /****************************************************************
10585 _spoolss_RouterFindFirstPrinterChangeNotification
10586 ****************************************************************/
10588 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10589 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10591 p->rng_fault_state = true;
10592 return WERR_NOT_SUPPORTED;
10595 /****************************************************************
10596 _spoolss_SpoolerInit
10597 ****************************************************************/
10599 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10600 struct spoolss_SpoolerInit *r)
10602 p->rng_fault_state = true;
10603 return WERR_NOT_SUPPORTED;
10606 /****************************************************************
10607 _spoolss_ResetPrinterEx
10608 ****************************************************************/
10610 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10611 struct spoolss_ResetPrinterEx *r)
10613 p->rng_fault_state = true;
10614 return WERR_NOT_SUPPORTED;
10617 /****************************************************************
10618 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10619 ****************************************************************/
10621 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10622 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10624 p->rng_fault_state = true;
10625 return WERR_NOT_SUPPORTED;
10628 /****************************************************************
10629 _spoolss_RouterReplyPrinterEx
10630 ****************************************************************/
10632 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10633 struct spoolss_RouterReplyPrinterEx *r)
10635 p->rng_fault_state = true;
10636 return WERR_NOT_SUPPORTED;
10639 /****************************************************************
10640 _dcesrv_spoolss_RouterRefreshPrinterChangeNotify
10641 ****************************************************************/
10643 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
10644 struct spoolss_RouterRefreshPrinterChangeNotify *r)
10646 p->rng_fault_state = true;
10647 return WERR_NOT_SUPPORTED;
10650 /****************************************************************
10652 ****************************************************************/
10654 WERROR _spoolss_44(pipes_struct *p,
10655 struct spoolss_44 *r)
10657 p->rng_fault_state = true;
10658 return WERR_NOT_SUPPORTED;
10661 /****************************************************************
10663 ****************************************************************/
10665 WERROR _spoolss_47(pipes_struct *p,
10666 struct spoolss_47 *r)
10668 p->rng_fault_state = true;
10669 return WERR_NOT_SUPPORTED;
10672 /****************************************************************
10673 _spoolss_EnumPrinterData
10674 ****************************************************************/
10676 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10677 struct spoolss_EnumPrinterData *r)
10679 p->rng_fault_state = true;
10680 return WERR_NOT_SUPPORTED;
10683 /****************************************************************
10685 ****************************************************************/
10687 WERROR _spoolss_4a(pipes_struct *p,
10688 struct spoolss_4a *r)
10690 p->rng_fault_state = true;
10691 return WERR_NOT_SUPPORTED;
10694 /****************************************************************
10696 ****************************************************************/
10698 WERROR _spoolss_4b(pipes_struct *p,
10699 struct spoolss_4b *r)
10701 p->rng_fault_state = true;
10702 return WERR_NOT_SUPPORTED;
10705 /****************************************************************
10707 ****************************************************************/
10709 WERROR _spoolss_4c(pipes_struct *p,
10710 struct spoolss_4c *r)
10712 p->rng_fault_state = true;
10713 return WERR_NOT_SUPPORTED;
10716 /****************************************************************
10717 _spoolss_EnumPrinterDataEx
10718 ****************************************************************/
10720 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10721 struct spoolss_EnumPrinterDataEx *r)
10723 p->rng_fault_state = true;
10724 return WERR_NOT_SUPPORTED;
10727 /****************************************************************
10728 _spoolss_EnumPrinterKey
10729 ****************************************************************/
10731 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10732 struct spoolss_EnumPrinterKey *r)
10734 p->rng_fault_state = true;
10735 return WERR_NOT_SUPPORTED;
10738 /****************************************************************
10740 ****************************************************************/
10742 WERROR _spoolss_53(pipes_struct *p,
10743 struct spoolss_53 *r)
10745 p->rng_fault_state = true;
10746 return WERR_NOT_SUPPORTED;
10749 /****************************************************************
10751 ****************************************************************/
10753 WERROR _spoolss_55(pipes_struct *p,
10754 struct spoolss_55 *r)
10756 p->rng_fault_state = true;
10757 return WERR_NOT_SUPPORTED;
10760 /****************************************************************
10762 ****************************************************************/
10764 WERROR _spoolss_56(pipes_struct *p,
10765 struct spoolss_56 *r)
10767 p->rng_fault_state = true;
10768 return WERR_NOT_SUPPORTED;
10771 /****************************************************************
10773 ****************************************************************/
10775 WERROR _spoolss_57(pipes_struct *p,
10776 struct spoolss_57 *r)
10778 p->rng_fault_state = true;
10779 return WERR_NOT_SUPPORTED;
10782 /****************************************************************
10783 _spoolss_AddPrinterDriverEx
10784 ****************************************************************/
10786 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
10787 struct spoolss_AddPrinterDriverEx *r)
10789 p->rng_fault_state = true;
10790 return WERR_NOT_SUPPORTED;
10793 /****************************************************************
10795 ****************************************************************/
10797 WERROR _spoolss_5a(pipes_struct *p,
10798 struct spoolss_5a *r)
10800 p->rng_fault_state = true;
10801 return WERR_NOT_SUPPORTED;
10804 /****************************************************************
10806 ****************************************************************/
10808 WERROR _spoolss_5b(pipes_struct *p,
10809 struct spoolss_5b *r)
10811 p->rng_fault_state = true;
10812 return WERR_NOT_SUPPORTED;
10815 /****************************************************************
10817 ****************************************************************/
10819 WERROR _spoolss_5c(pipes_struct *p,
10820 struct spoolss_5c *r)
10822 p->rng_fault_state = true;
10823 return WERR_NOT_SUPPORTED;
10826 /****************************************************************
10828 ****************************************************************/
10830 WERROR _spoolss_5d(pipes_struct *p,
10831 struct spoolss_5d *r)
10833 p->rng_fault_state = true;
10834 return WERR_NOT_SUPPORTED;
10837 /****************************************************************
10839 ****************************************************************/
10841 WERROR _spoolss_5e(pipes_struct *p,
10842 struct spoolss_5e *r)
10844 p->rng_fault_state = true;
10845 return WERR_NOT_SUPPORTED;
10848 /****************************************************************
10850 ****************************************************************/
10852 WERROR _spoolss_5f(pipes_struct *p,
10853 struct spoolss_5f *r)
10855 p->rng_fault_state = true;
10856 return WERR_NOT_SUPPORTED;