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) (NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *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)
155 * Tell the specific printing tdb we no longer want messages for this printer
156 * by deregistering our PID.
159 if (!print_notify_deregister_pid(snum))
160 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
162 /* weird if the test succeds !!! */
163 if (smb_connections==0) {
164 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
168 result = rpccli_spoolss_reply_close_printer(notify_cli_pipe,
172 if (!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 Copy routines used by convert_to_openprinterex()
1404 *******************************************************************/
1406 static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode)
1414 DEBUG (8,("dup_devmode\n"));
1416 /* bulk copy first */
1418 d = (DEVICEMODE *)TALLOC_MEMDUP(ctx, devmode, sizeof(DEVICEMODE));
1422 /* dup the pointer members separately */
1424 len = unistrlen(devmode->devicename.buffer);
1426 d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len);
1427 if (!d->devicename.buffer) {
1430 if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len)
1435 len = unistrlen(devmode->formname.buffer);
1437 d->formname.buffer = TALLOC_ARRAY(ctx, uint16, len);
1438 if (!d->formname.buffer) {
1441 if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len)
1445 if (devmode->driverextra) {
1446 d->dev_private = (uint8 *)TALLOC_MEMDUP(ctx, devmode->dev_private,
1447 devmode->driverextra);
1448 if (!d->dev_private) {
1452 d->dev_private = NULL;
1457 static void copy_devmode_ctr(TALLOC_CTX *ctx, DEVMODE_CTR *new_ctr, DEVMODE_CTR *ctr)
1459 if (!new_ctr || !ctr)
1462 DEBUG(8,("copy_devmode_ctr\n"));
1464 new_ctr->size = ctr->size;
1465 new_ctr->devmode_ptr = ctr->devmode_ptr;
1467 if(ctr->devmode_ptr)
1468 new_ctr->devmode = dup_devicemode(ctx, ctr->devmode);
1471 static void copy_printer_default(TALLOC_CTX *ctx, PRINTER_DEFAULT *new_def, PRINTER_DEFAULT *def)
1473 if (!new_def || !def)
1476 DEBUG(8,("copy_printer_defaults\n"));
1478 new_def->datatype_ptr = def->datatype_ptr;
1480 if (def->datatype_ptr)
1481 copy_unistr2(&new_def->datatype, &def->datatype);
1483 copy_devmode_ctr(ctx, &new_def->devmode_cont, &def->devmode_cont);
1485 new_def->access_required = def->access_required;
1488 /********************************************************************
1489 * Convert a SPOOL_Q_OPEN_PRINTER structure to a
1490 * SPOOL_Q_OPEN_PRINTER_EX structure
1491 ********************************************************************/
1493 static WERROR convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u)
1495 if (!q_u_ex || !q_u)
1498 DEBUG(8,("convert_to_openprinterex\n"));
1500 if ( q_u->printername ) {
1501 q_u_ex->printername = TALLOC_ZERO_P( ctx, UNISTR2 );
1502 if (q_u_ex->printername == NULL)
1504 copy_unistr2(q_u_ex->printername, q_u->printername);
1507 copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default);
1512 /********************************************************************
1513 * spoolss_open_printer
1515 * called from the spoolss dispatcher
1516 ********************************************************************/
1518 WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R_OPEN_PRINTER *r_u)
1520 SPOOL_Q_OPEN_PRINTER_EX q_u_ex;
1521 SPOOL_R_OPEN_PRINTER_EX r_u_ex;
1526 ZERO_STRUCT(q_u_ex);
1527 ZERO_STRUCT(r_u_ex);
1529 /* convert the OpenPrinter() call to OpenPrinterEx() */
1531 r_u_ex.status = convert_to_openprinterex(p->mem_ctx, &q_u_ex, q_u);
1532 if (!W_ERROR_IS_OK(r_u_ex.status))
1533 return r_u_ex.status;
1535 r_u_ex.status = _spoolss_open_printer_ex(p, &q_u_ex, &r_u_ex);
1537 /* convert back to OpenPrinter() */
1539 memcpy(r_u, &r_u_ex, sizeof(*r_u));
1541 if (W_ERROR_EQUAL(r_u->status, WERR_INVALID_PARAM)) {
1542 /* OpenPrinterEx returns this for a bad
1543 * printer name. We must return WERR_INVALID_PRINTER_NAME
1546 r_u->status = WERR_INVALID_PRINTER_NAME;
1551 /********************************************************************
1552 ********************************************************************/
1554 WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
1556 PRINTER_DEFAULT *printer_default = &q_u->printer_default;
1557 POLICY_HND *handle = &r_u->handle;
1561 Printer_entry *Printer=NULL;
1563 if (!q_u->printername) {
1564 return WERR_INVALID_PARAM;
1567 /* some sanity check because you can open a printer or a print server */
1568 /* aka: \\server\printer or \\server */
1570 unistr2_to_ascii(name, q_u->printername, sizeof(name));
1572 DEBUGADD(3,("checking name: %s\n",name));
1574 if (!open_printer_hnd(p, handle, name, 0)) {
1575 return WERR_INVALID_PARAM;
1578 Printer=find_printer_index_by_hnd(p, handle);
1580 DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer "
1581 "handle we created for printer %s\n", name ));
1582 close_printer_handle(p,handle);
1583 return WERR_INVALID_PARAM;
1587 * First case: the user is opening the print server:
1589 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1590 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1592 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1593 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1594 * or if the user is listed in the smb.conf printer admin parameter.
1596 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1597 * client view printer folder, but does not show the MSAPW.
1599 * Note: this test needs code to check access rights here too. Jeremy
1600 * could you look at this?
1602 * Second case: the user is opening a printer:
1603 * NT doesn't let us connect to a printer if the connecting user
1604 * doesn't have print permission.
1606 * Third case: user is opening a Port Monitor
1607 * access checks same as opening a handle to the print server.
1610 switch (Printer->printer_type )
1613 case SPLHND_PORTMON_TCP:
1614 case SPLHND_PORTMON_LOCAL:
1615 /* Printserver handles use global struct... */
1619 /* Map standard access rights to object specific access rights */
1621 se_map_standard(&printer_default->access_required,
1622 &printserver_std_mapping);
1624 /* Deny any object specific bits that don't apply to print
1625 servers (i.e printer and job specific bits) */
1627 printer_default->access_required &= SPECIFIC_RIGHTS_MASK;
1629 if (printer_default->access_required &
1630 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1631 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1632 close_printer_handle(p, handle);
1633 return WERR_ACCESS_DENIED;
1636 /* Allow admin access */
1638 if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER )
1640 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1642 if (!lp_ms_add_printer_wizard()) {
1643 close_printer_handle(p, handle);
1644 return WERR_ACCESS_DENIED;
1647 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1648 and not a printer admin, then fail */
1650 if ((p->server_info->utok.uid != 0) &&
1651 !user_has_privileges(p->server_info->ptok,
1653 !token_contains_name_in_list(
1654 uidtoname(p->server_info->utok.uid),
1656 p->server_info->ptok,
1657 lp_printer_admin(snum))) {
1658 close_printer_handle(p, handle);
1659 return WERR_ACCESS_DENIED;
1662 printer_default->access_required = SERVER_ACCESS_ADMINISTER;
1666 printer_default->access_required = SERVER_ACCESS_ENUMERATE;
1669 DEBUG(4,("Setting print server access = %s\n", (printer_default->access_required == SERVER_ACCESS_ADMINISTER)
1670 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1672 /* We fall through to return WERR_OK */
1675 case SPLHND_PRINTER:
1676 /* NT doesn't let us connect to a printer if the connecting user
1677 doesn't have print permission. */
1679 if (!get_printer_snum(p, handle, &snum, NULL)) {
1680 close_printer_handle(p, handle);
1684 se_map_standard(&printer_default->access_required, &printer_std_mapping);
1686 /* map an empty access mask to the minimum access mask */
1687 if (printer_default->access_required == 0x0)
1688 printer_default->access_required = PRINTER_ACCESS_USE;
1691 * If we are not serving the printer driver for this printer,
1692 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1693 * will keep NT clients happy --jerry
1696 if (lp_use_client_driver(snum)
1697 && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
1699 printer_default->access_required = PRINTER_ACCESS_USE;
1702 /* check smb.conf parameters and the the sec_desc */
1704 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1705 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1706 return WERR_ACCESS_DENIED;
1709 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1710 p->server_info->ptok, snum) ||
1711 !print_access_check(p->server_info, snum,
1712 printer_default->access_required)) {
1713 DEBUG(3, ("access DENIED for printer open\n"));
1714 close_printer_handle(p, handle);
1715 return WERR_ACCESS_DENIED;
1718 if ((printer_default->access_required & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1719 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1720 close_printer_handle(p, handle);
1721 return WERR_ACCESS_DENIED;
1724 if (printer_default->access_required & PRINTER_ACCESS_ADMINISTER)
1725 printer_default->access_required = PRINTER_ACCESS_ADMINISTER;
1727 printer_default->access_required = PRINTER_ACCESS_USE;
1729 DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
1730 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1735 /* sanity check to prevent programmer error */
1739 Printer->access_granted = printer_default->access_required;
1742 * If the client sent a devmode in the OpenPrinter() call, then
1743 * save it here in case we get a job submission on this handle
1746 if ( (Printer->printer_type != SPLHND_SERVER)
1747 && q_u->printer_default.devmode_cont.devmode_ptr )
1749 convert_devicemode( Printer->sharename, q_u->printer_default.devmode_cont.devmode,
1750 &Printer->nt_devmode );
1753 #if 0 /* JERRY -- I'm doubtful this is really effective */
1754 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1755 optimization in Windows 2000 clients --jerry */
1757 if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
1758 && (RA_WIN2K == get_remote_arch()) )
1760 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
1761 sys_usleep( 500000 );
1768 /****************************************************************************
1769 ****************************************************************************/
1771 static bool convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
1772 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
1778 /* allocate memory if needed. Messy because
1779 convert_printer_info is used to update an existing
1780 printer or build a new one */
1782 if ( !printer->info_2 ) {
1783 printer->info_2 = TALLOC_ZERO_P( printer, NT_PRINTER_INFO_LEVEL_2 );
1784 if ( !printer->info_2 ) {
1785 DEBUG(0,("convert_printer_info: talloc() failed!\n"));
1790 ret = uni_2_asc_printer_info_2(uni->info_2, printer->info_2);
1791 printer->info_2->setuptime = time(NULL);
1799 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
1800 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
1806 printer->info_3=NULL;
1807 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
1811 printer->info_6=NULL;
1812 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
1822 bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
1823 NT_DEVICEMODE **pp_nt_devmode)
1825 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1828 * Ensure nt_devmode is a valid pointer
1829 * as we will be overwriting it.
1832 if (nt_devmode == NULL) {
1833 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1834 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1838 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
1839 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
1841 nt_devmode->specversion=devmode->specversion;
1842 nt_devmode->driverversion=devmode->driverversion;
1843 nt_devmode->size=devmode->size;
1844 nt_devmode->fields=devmode->fields;
1845 nt_devmode->orientation=devmode->orientation;
1846 nt_devmode->papersize=devmode->papersize;
1847 nt_devmode->paperlength=devmode->paperlength;
1848 nt_devmode->paperwidth=devmode->paperwidth;
1849 nt_devmode->scale=devmode->scale;
1850 nt_devmode->copies=devmode->copies;
1851 nt_devmode->defaultsource=devmode->defaultsource;
1852 nt_devmode->printquality=devmode->printquality;
1853 nt_devmode->color=devmode->color;
1854 nt_devmode->duplex=devmode->duplex;
1855 nt_devmode->yresolution=devmode->yresolution;
1856 nt_devmode->ttoption=devmode->ttoption;
1857 nt_devmode->collate=devmode->collate;
1859 nt_devmode->logpixels=devmode->logpixels;
1860 nt_devmode->bitsperpel=devmode->bitsperpel;
1861 nt_devmode->pelswidth=devmode->pelswidth;
1862 nt_devmode->pelsheight=devmode->pelsheight;
1863 nt_devmode->displayflags=devmode->displayflags;
1864 nt_devmode->displayfrequency=devmode->displayfrequency;
1865 nt_devmode->icmmethod=devmode->icmmethod;
1866 nt_devmode->icmintent=devmode->icmintent;
1867 nt_devmode->mediatype=devmode->mediatype;
1868 nt_devmode->dithertype=devmode->dithertype;
1869 nt_devmode->reserved1=devmode->reserved1;
1870 nt_devmode->reserved2=devmode->reserved2;
1871 nt_devmode->panningwidth=devmode->panningwidth;
1872 nt_devmode->panningheight=devmode->panningheight;
1875 * Only change private and driverextra if the incoming devmode
1876 * has a new one. JRA.
1879 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
1880 SAFE_FREE(nt_devmode->nt_dev_private);
1881 nt_devmode->driverextra=devmode->driverextra;
1882 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1884 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
1887 *pp_nt_devmode = nt_devmode;
1892 /********************************************************************
1893 * _spoolss_enddocprinter_internal.
1894 ********************************************************************/
1896 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
1898 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1902 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
1906 if (!get_printer_snum(p, handle, &snum, NULL))
1909 Printer->document_started=False;
1910 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
1911 /* error codes unhandled so far ... */
1916 /****************************************************************
1917 _spoolss_ClosePrinter
1918 ****************************************************************/
1920 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1921 struct spoolss_ClosePrinter *r)
1923 POLICY_HND *handle = r->in.handle;
1925 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1927 if (Printer && Printer->document_started)
1928 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1930 if (!close_printer_handle(p, handle))
1933 /* clear the returned printer handle. Observed behavior
1934 from Win2k server. Don't think this really matters.
1935 Previous code just copied the value of the closed
1938 ZERO_STRUCTP(r->out.handle);
1943 /****************************************************************
1944 _spoolss_DeletePrinter
1945 ****************************************************************/
1947 WERROR _spoolss_DeletePrinter(pipes_struct *p,
1948 struct spoolss_DeletePrinter *r)
1950 POLICY_HND *handle = r->in.handle;
1951 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1954 if (Printer && Printer->document_started)
1955 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
1957 result = delete_printer_handle(p, handle);
1959 update_c_setprinter(False);
1964 /*******************************************************************
1965 * static function to lookup the version id corresponding to an
1966 * long architecture string
1967 ******************************************************************/
1969 static int get_version_id (char * arch)
1972 struct table_node archi_table[]= {
1974 {"Windows 4.0", "WIN40", 0 },
1975 {"Windows NT x86", "W32X86", 2 },
1976 {"Windows NT R4000", "W32MIPS", 2 },
1977 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
1978 {"Windows NT PowerPC", "W32PPC", 2 },
1979 {"Windows IA64", "IA64", 3 },
1980 {"Windows x64", "x64", 3 },
1984 for (i=0; archi_table[i].long_archi != NULL; i++)
1986 if (strcmp(arch, archi_table[i].long_archi) == 0)
1987 return (archi_table[i].version);
1993 /********************************************************************
1994 * _spoolss_deleteprinterdriver
1995 ********************************************************************/
1997 WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u)
2001 NT_PRINTER_DRIVER_INFO_LEVEL info;
2002 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2005 WERROR status_win2k = WERR_ACCESS_DENIED;
2006 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2008 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2009 and not a printer admin, then fail */
2011 if ( (p->server_info->utok.uid != 0)
2012 && !user_has_privileges(p->server_info->ptok, &se_printop )
2013 && !token_contains_name_in_list(
2014 uidtoname(p->server_info->utok.uid), NULL,
2015 NULL, p->server_info->ptok,
2016 lp_printer_admin(-1)) )
2018 return WERR_ACCESS_DENIED;
2021 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver));
2022 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch));
2024 /* check that we have a valid driver name first */
2026 if ((version=get_version_id(arch)) == -1)
2027 return WERR_INVALID_ENVIRONMENT;
2030 ZERO_STRUCT(info_win2k);
2032 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2034 /* try for Win2k driver if "Windows NT x86" */
2036 if ( version == 2 ) {
2038 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2039 status = WERR_UNKNOWN_PRINTER_DRIVER;
2043 /* otherwise it was a failure */
2045 status = WERR_UNKNOWN_PRINTER_DRIVER;
2051 if (printer_driver_in_use(info.info_3)) {
2052 status = WERR_PRINTER_DRIVER_IN_USE;
2058 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2060 /* if we get to here, we now have 2 driver info structures to remove */
2061 /* remove the Win2k driver first*/
2063 status_win2k = delete_printer_driver(
2064 p, info_win2k.info_3, 3, False );
2065 free_a_printer_driver( info_win2k, 3 );
2067 /* this should not have failed---if it did, report to client */
2068 if ( !W_ERROR_IS_OK(status_win2k) )
2070 status = status_win2k;
2076 status = delete_printer_driver(p, info.info_3, version, False);
2078 /* if at least one of the deletes succeeded return OK */
2080 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2084 free_a_printer_driver( info, 3 );
2089 /********************************************************************
2090 * spoolss_deleteprinterdriverex
2091 ********************************************************************/
2093 WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, SPOOL_R_DELETEPRINTERDRIVEREX *r_u)
2097 NT_PRINTER_DRIVER_INFO_LEVEL info;
2098 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2100 uint32 flags = q_u->delete_flags;
2103 WERROR status_win2k = WERR_ACCESS_DENIED;
2104 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2106 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2107 and not a printer admin, then fail */
2109 if ( (p->server_info->utok.uid != 0)
2110 && !user_has_privileges(p->server_info->ptok, &se_printop )
2111 && !token_contains_name_in_list(
2112 uidtoname(p->server_info->utok.uid), NULL, NULL,
2113 p->server_info->ptok, lp_printer_admin(-1)) )
2115 return WERR_ACCESS_DENIED;
2118 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver));
2119 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch));
2121 /* check that we have a valid driver name first */
2122 if ((version=get_version_id(arch)) == -1) {
2123 /* this is what NT returns */
2124 return WERR_INVALID_ENVIRONMENT;
2127 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2128 version = q_u->version;
2131 ZERO_STRUCT(info_win2k);
2133 status = get_a_printer_driver(&info, 3, driver, arch, version);
2135 if ( !W_ERROR_IS_OK(status) )
2138 * if the client asked for a specific version,
2139 * or this is something other than Windows NT x86,
2143 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2146 /* try for Win2k driver if "Windows NT x86" */
2149 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2150 status = WERR_UNKNOWN_PRINTER_DRIVER;
2155 if ( printer_driver_in_use(info.info_3) ) {
2156 status = WERR_PRINTER_DRIVER_IN_USE;
2161 * we have a couple of cases to consider.
2162 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2163 * then the delete should fail if **any** files overlap with
2165 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2166 * non-overlapping files
2167 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2168 * is set, the do not delete any files
2169 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2172 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2174 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2176 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2177 /* no idea of the correct error here */
2178 status = WERR_ACCESS_DENIED;
2183 /* also check for W32X86/3 if necessary; maybe we already have? */
2185 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2186 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2189 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2190 /* no idea of the correct error here */
2191 free_a_printer_driver( info_win2k, 3 );
2192 status = WERR_ACCESS_DENIED;
2196 /* if we get to here, we now have 2 driver info structures to remove */
2197 /* remove the Win2k driver first*/
2199 status_win2k = delete_printer_driver(
2200 p, info_win2k.info_3, 3, delete_files);
2201 free_a_printer_driver( info_win2k, 3 );
2203 /* this should not have failed---if it did, report to client */
2205 if ( !W_ERROR_IS_OK(status_win2k) )
2210 status = delete_printer_driver(p, info.info_3, version, delete_files);
2212 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2215 free_a_printer_driver( info, 3 );
2221 /****************************************************************************
2222 Internal routine for retreiving printerdata
2223 ***************************************************************************/
2225 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2226 const char *key, const char *value, uint32 *type, uint8 **data,
2227 uint32 *needed, uint32 in_size )
2229 REGISTRY_VALUE *val;
2233 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2234 return WERR_BADFILE;
2236 *type = regval_type( val );
2238 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2240 size = regval_size( val );
2242 /* copy the min(in_size, len) */
2245 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2247 /* special case for 0 length values */
2249 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2253 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2262 DEBUG(5,("get_printer_dataex: copy done\n"));
2267 /****************************************************************************
2268 Internal routine for removing printerdata
2269 ***************************************************************************/
2271 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2273 return delete_printer_data( printer->info_2, key, value );
2276 /****************************************************************************
2277 Internal routine for storing printerdata
2278 ***************************************************************************/
2280 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2281 uint32 type, uint8 *data, int real_len )
2283 /* the registry objects enforce uniqueness based on value name */
2285 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2288 /********************************************************************
2289 GetPrinterData on a printer server Handle.
2290 ********************************************************************/
2292 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2296 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2298 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2300 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2302 SIVAL(*data, 0, 0x00);
2307 if (!StrCaseCmp(value, "BeepEnabled")) {
2309 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2311 SIVAL(*data, 0, 0x00);
2316 if (!StrCaseCmp(value, "EventLog")) {
2318 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2320 /* formally was 0x1b */
2321 SIVAL(*data, 0, 0x0);
2326 if (!StrCaseCmp(value, "NetPopup")) {
2328 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2330 SIVAL(*data, 0, 0x00);
2335 if (!StrCaseCmp(value, "MajorVersion")) {
2337 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2340 /* Windows NT 4.0 seems to not allow uploading of drivers
2341 to a server that reports 0x3 as the MajorVersion.
2342 need to investigate more how Win2k gets around this .
2345 if ( RA_WINNT == get_remote_arch() )
2354 if (!StrCaseCmp(value, "MinorVersion")) {
2356 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2364 * uint32 size = 0x114
2366 * uint32 minor = [0|1]
2367 * uint32 build = [2195|2600]
2368 * extra unicode string = e.g. "Service Pack 3"
2370 if (!StrCaseCmp(value, "OSVersion")) {
2374 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2377 SIVAL(*data, 0, *needed); /* size */
2378 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2380 SIVAL(*data, 12, 2195); /* build */
2382 /* leave extra string empty */
2388 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2389 const char *string="C:\\PRINTERS";
2391 *needed = 2*(strlen(string)+1);
2392 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2394 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2396 /* it's done by hand ready to go on the wire */
2397 for (i=0; i<strlen(string); i++) {
2398 (*data)[2*i]=string[i];
2399 (*data)[2*i+1]='\0';
2404 if (!StrCaseCmp(value, "Architecture")) {
2405 const char *string="Windows NT x86";
2407 *needed = 2*(strlen(string)+1);
2408 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2410 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2411 for (i=0; i<strlen(string); i++) {
2412 (*data)[2*i]=string[i];
2413 (*data)[2*i+1]='\0';
2418 if (!StrCaseCmp(value, "DsPresent")) {
2420 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2423 /* only show the publish check box if we are a
2424 memeber of a AD domain */
2426 if ( lp_security() == SEC_ADS )
2427 SIVAL(*data, 0, 0x01);
2429 SIVAL(*data, 0, 0x00);
2435 if (!StrCaseCmp(value, "DNSMachineName")) {
2436 const char *hostname = get_mydnsfullname();
2439 return WERR_BADFILE;
2441 *needed = 2*(strlen(hostname)+1);
2442 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2444 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2445 for (i=0; i<strlen(hostname); i++) {
2446 (*data)[2*i]=hostname[i];
2447 (*data)[2*i+1]='\0';
2453 return WERR_BADFILE;
2456 /********************************************************************
2457 * spoolss_getprinterdata
2458 ********************************************************************/
2460 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2462 POLICY_HND *handle = &q_u->handle;
2463 UNISTR2 *valuename = &q_u->valuename;
2464 uint32 in_size = q_u->size;
2465 uint32 *type = &r_u->type;
2466 uint32 *out_size = &r_u->size;
2467 uint8 **data = &r_u->data;
2468 uint32 *needed = &r_u->needed;
2471 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2472 NT_PRINTER_INFO_LEVEL *printer = NULL;
2476 * Reminder: when it's a string, the length is in BYTES
2477 * even if UNICODE is negociated.
2482 *out_size = in_size;
2484 /* in case of problem, return some default values */
2489 DEBUG(4,("_spoolss_getprinterdata\n"));
2492 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2493 status = WERR_BADFID;
2497 unistr2_to_ascii(value, valuename, sizeof(value));
2499 if ( Printer->printer_type == SPLHND_SERVER )
2500 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2503 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2504 status = WERR_BADFID;
2508 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2509 if ( !W_ERROR_IS_OK(status) )
2512 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2514 if ( strequal(value, "ChangeId") ) {
2516 *needed = sizeof(uint32);
2517 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2518 status = WERR_NOMEM;
2521 SIVAL( *data, 0, printer->info_2->changeid );
2525 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2528 if (*needed > *out_size)
2529 status = WERR_MORE_DATA;
2532 if ( !W_ERROR_IS_OK(status) )
2534 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2536 /* reply this param doesn't exist */
2539 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2541 free_a_printer( &printer, 2 );
2549 /* cleanup & exit */
2552 free_a_printer( &printer, 2 );
2557 /*********************************************************
2558 Connect to the client machine.
2559 **********************************************************/
2561 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2562 struct sockaddr_storage *client_ss, const char *remote_machine)
2565 struct cli_state *the_cli;
2566 struct sockaddr_storage rm_addr;
2568 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2569 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2570 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2574 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2575 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2579 char addr[INET6_ADDRSTRLEN];
2580 rm_addr = *client_ss;
2581 print_sockaddr(addr, sizeof(addr), &rm_addr);
2582 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2586 /* setup the connection */
2588 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2589 &rm_addr, 0, "IPC$", "IPC",
2593 0, lp_client_signing(), NULL );
2595 if ( !NT_STATUS_IS_OK( ret ) ) {
2596 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2601 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2602 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2603 cli_shutdown(the_cli);
2608 * Ok - we have an anonymous connection to the IPC$ share.
2609 * Now start the NT Domain stuff :-).
2612 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2613 if (!NT_STATUS_IS_OK(ret)) {
2614 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2615 remote_machine, nt_errstr(ret)));
2616 cli_shutdown(the_cli);
2623 /***************************************************************************
2624 Connect to the client.
2625 ****************************************************************************/
2627 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2628 uint32 localprinter, uint32 type,
2629 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2634 * If it's the first connection, contact the client
2635 * and connect to the IPC$ share anonymously
2637 if (smb_connections==0) {
2638 fstring unix_printer;
2640 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2642 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2645 messaging_register(smbd_messaging_context(), NULL,
2646 MSG_PRINTER_NOTIFY2,
2647 receive_notify2_message_list);
2648 /* Tell the connections db we're now interested in printer
2649 * notify messages. */
2650 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2654 * Tell the specific printing tdb we want messages for this printer
2655 * by registering our PID.
2658 if (!print_notify_register_pid(snum))
2659 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2663 result = rpccli_spoolss_reply_open_printer(notify_cli_pipe,
2670 if (!W_ERROR_IS_OK(result))
2671 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2672 win_errstr(result)));
2674 return (W_ERROR_IS_OK(result));
2677 /********************************************************************
2679 * ReplyFindFirstPrinterChangeNotifyEx
2681 * before replying OK: status=0 a rpc call is made to the workstation
2682 * asking ReplyOpenPrinter
2684 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2685 * called from api_spoolss_rffpcnex
2686 ********************************************************************/
2688 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2690 POLICY_HND *handle = &q_u->handle;
2691 uint32 flags = q_u->flags;
2692 uint32 options = q_u->options;
2693 UNISTR2 *localmachine = &q_u->localmachine;
2694 uint32 printerlocal = q_u->printerlocal;
2696 SPOOL_NOTIFY_OPTION *option = q_u->option;
2697 struct sockaddr_storage client_ss;
2699 /* store the notify value in the printer struct */
2701 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2704 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2708 Printer->notify.flags=flags;
2709 Printer->notify.options=options;
2710 Printer->notify.printerlocal=printerlocal;
2712 if (Printer->notify.option)
2713 free_spool_notify_option(&Printer->notify.option);
2715 Printer->notify.option=dup_spool_notify_option(option);
2717 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
2718 sizeof(Printer->notify.localmachine));
2720 /* Connect to the client machine and send a ReplyOpenPrinter */
2722 if ( Printer->printer_type == SPLHND_SERVER)
2724 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2725 !get_printer_snum(p, handle, &snum, NULL) )
2728 if (!interpret_string_addr(&client_ss, p->client_address,
2730 return WERR_SERVER_UNAVAILABLE;
2733 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2734 Printer->notify.printerlocal, 1,
2735 &Printer->notify.client_hnd, &client_ss))
2736 return WERR_SERVER_UNAVAILABLE;
2738 Printer->notify.client_connected=True;
2743 /*******************************************************************
2744 * fill a notify_info_data with the servername
2745 ********************************************************************/
2747 void spoolss_notify_server_name(int snum,
2748 SPOOL_NOTIFY_INFO_DATA *data,
2749 print_queue_struct *queue,
2750 NT_PRINTER_INFO_LEVEL *printer,
2751 TALLOC_CTX *mem_ctx)
2753 smb_ucs2_t *temp = NULL;
2756 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername);
2757 if (len == (uint32)-1) {
2761 data->notify_data.data.length = len;
2763 data->notify_data.data.string = (uint16 *)temp;
2765 data->notify_data.data.string = NULL;
2769 /*******************************************************************
2770 * fill a notify_info_data with the printername (not including the servername).
2771 ********************************************************************/
2773 void spoolss_notify_printer_name(int snum,
2774 SPOOL_NOTIFY_INFO_DATA *data,
2775 print_queue_struct *queue,
2776 NT_PRINTER_INFO_LEVEL *printer,
2777 TALLOC_CTX *mem_ctx)
2779 smb_ucs2_t *temp = NULL;
2782 /* the notify name should not contain the \\server\ part */
2783 char *p = strrchr(printer->info_2->printername, '\\');
2786 p = printer->info_2->printername;
2791 len = rpcstr_push_talloc(mem_ctx, &temp, p);
2792 if (len == (uint32)-1) {
2796 data->notify_data.data.length = len;
2798 data->notify_data.data.string = (uint16 *)temp;
2800 data->notify_data.data.string = NULL;
2804 /*******************************************************************
2805 * fill a notify_info_data with the servicename
2806 ********************************************************************/
2808 void spoolss_notify_share_name(int snum,
2809 SPOOL_NOTIFY_INFO_DATA *data,
2810 print_queue_struct *queue,
2811 NT_PRINTER_INFO_LEVEL *printer,
2812 TALLOC_CTX *mem_ctx)
2814 smb_ucs2_t *temp = NULL;
2817 len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum));
2818 if (len == (uint32)-1) {
2822 data->notify_data.data.length = len;
2824 data->notify_data.data.string = (uint16 *)temp;
2826 data->notify_data.data.string = NULL;
2831 /*******************************************************************
2832 * fill a notify_info_data with the port name
2833 ********************************************************************/
2835 void spoolss_notify_port_name(int snum,
2836 SPOOL_NOTIFY_INFO_DATA *data,
2837 print_queue_struct *queue,
2838 NT_PRINTER_INFO_LEVEL *printer,
2839 TALLOC_CTX *mem_ctx)
2841 smb_ucs2_t *temp = NULL;
2844 /* even if it's strange, that's consistant in all the code */
2846 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname);
2847 if (len == (uint32)-1) {
2851 data->notify_data.data.length = len;
2853 data->notify_data.data.string = (uint16 *)temp;
2855 data->notify_data.data.string = NULL;
2859 /*******************************************************************
2860 * fill a notify_info_data with the printername
2861 * but it doesn't exist, have to see what to do
2862 ********************************************************************/
2864 void spoolss_notify_driver_name(int snum,
2865 SPOOL_NOTIFY_INFO_DATA *data,
2866 print_queue_struct *queue,
2867 NT_PRINTER_INFO_LEVEL *printer,
2868 TALLOC_CTX *mem_ctx)
2870 smb_ucs2_t *temp = NULL;
2873 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername);
2874 if (len == (uint32)-1) {
2878 data->notify_data.data.length = len;
2880 data->notify_data.data.string = (uint16 *)temp;
2882 data->notify_data.data.string = NULL;
2886 /*******************************************************************
2887 * fill a notify_info_data with the comment
2888 ********************************************************************/
2890 void spoolss_notify_comment(int snum,
2891 SPOOL_NOTIFY_INFO_DATA *data,
2892 print_queue_struct *queue,
2893 NT_PRINTER_INFO_LEVEL *printer,
2894 TALLOC_CTX *mem_ctx)
2896 smb_ucs2_t *temp = NULL;
2899 if (*printer->info_2->comment == '\0')
2900 len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum));
2902 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment);
2904 if (len == (uint32)-1) {
2907 data->notify_data.data.length = len;
2909 data->notify_data.data.string = (uint16 *)temp;
2911 data->notify_data.data.string = NULL;
2915 /*******************************************************************
2916 * fill a notify_info_data with the comment
2917 * location = "Room 1, floor 2, building 3"
2918 ********************************************************************/
2920 void spoolss_notify_location(int snum,
2921 SPOOL_NOTIFY_INFO_DATA *data,
2922 print_queue_struct *queue,
2923 NT_PRINTER_INFO_LEVEL *printer,
2924 TALLOC_CTX *mem_ctx)
2926 smb_ucs2_t *temp = NULL;
2929 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location);
2930 if (len == (uint32)-1) {
2934 data->notify_data.data.length = len;
2936 data->notify_data.data.string = (uint16 *)temp;
2938 data->notify_data.data.string = NULL;
2942 /*******************************************************************
2943 * fill a notify_info_data with the device mode
2944 * jfm:xxxx don't to it for know but that's a real problem !!!
2945 ********************************************************************/
2947 static void spoolss_notify_devmode(int snum,
2948 SPOOL_NOTIFY_INFO_DATA *data,
2949 print_queue_struct *queue,
2950 NT_PRINTER_INFO_LEVEL *printer,
2951 TALLOC_CTX *mem_ctx)
2953 /* for a dummy implementation we have to zero the fields */
2954 data->notify_data.data.length = 0;
2955 data->notify_data.data.string = NULL;
2958 /*******************************************************************
2959 * fill a notify_info_data with the separator file name
2960 ********************************************************************/
2962 void spoolss_notify_sepfile(int snum,
2963 SPOOL_NOTIFY_INFO_DATA *data,
2964 print_queue_struct *queue,
2965 NT_PRINTER_INFO_LEVEL *printer,
2966 TALLOC_CTX *mem_ctx)
2968 smb_ucs2_t *temp = NULL;
2971 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile);
2972 if (len == (uint32)-1) {
2976 data->notify_data.data.length = len;
2978 data->notify_data.data.string = (uint16 *)temp;
2980 data->notify_data.data.string = NULL;
2984 /*******************************************************************
2985 * fill a notify_info_data with the print processor
2986 * jfm:xxxx return always winprint to indicate we don't do anything to it
2987 ********************************************************************/
2989 void spoolss_notify_print_processor(int snum,
2990 SPOOL_NOTIFY_INFO_DATA *data,
2991 print_queue_struct *queue,
2992 NT_PRINTER_INFO_LEVEL *printer,
2993 TALLOC_CTX *mem_ctx)
2995 smb_ucs2_t *temp = NULL;
2998 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor);
2999 if (len == (uint32)-1) {
3003 data->notify_data.data.length = len;
3005 data->notify_data.data.string = (uint16 *)temp;
3007 data->notify_data.data.string = NULL;
3011 /*******************************************************************
3012 * fill a notify_info_data with the print processor options
3013 * jfm:xxxx send an empty string
3014 ********************************************************************/
3016 void spoolss_notify_parameters(int snum,
3017 SPOOL_NOTIFY_INFO_DATA *data,
3018 print_queue_struct *queue,
3019 NT_PRINTER_INFO_LEVEL *printer,
3020 TALLOC_CTX *mem_ctx)
3022 smb_ucs2_t *temp = NULL;
3025 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters);
3026 if (len == (uint32)-1) {
3030 data->notify_data.data.length = len;
3032 data->notify_data.data.string = (uint16 *)temp;
3034 data->notify_data.data.string = NULL;
3038 /*******************************************************************
3039 * fill a notify_info_data with the data type
3040 * jfm:xxxx always send RAW as data type
3041 ********************************************************************/
3043 void spoolss_notify_datatype(int snum,
3044 SPOOL_NOTIFY_INFO_DATA *data,
3045 print_queue_struct *queue,
3046 NT_PRINTER_INFO_LEVEL *printer,
3047 TALLOC_CTX *mem_ctx)
3049 smb_ucs2_t *temp = NULL;
3052 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype);
3053 if (len == (uint32)-1) {
3057 data->notify_data.data.length = len;
3059 data->notify_data.data.string = (uint16 *)temp;
3061 data->notify_data.data.string = NULL;
3065 /*******************************************************************
3066 * fill a notify_info_data with the security descriptor
3067 * jfm:xxxx send an null pointer to say no security desc
3068 * have to implement security before !
3069 ********************************************************************/
3071 static void spoolss_notify_security_desc(int snum,
3072 SPOOL_NOTIFY_INFO_DATA *data,
3073 print_queue_struct *queue,
3074 NT_PRINTER_INFO_LEVEL *printer,
3075 TALLOC_CTX *mem_ctx)
3077 data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size;
3078 data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ;
3081 /*******************************************************************
3082 * fill a notify_info_data with the attributes
3083 * jfm:xxxx a samba printer is always shared
3084 ********************************************************************/
3086 void spoolss_notify_attributes(int snum,
3087 SPOOL_NOTIFY_INFO_DATA *data,
3088 print_queue_struct *queue,
3089 NT_PRINTER_INFO_LEVEL *printer,
3090 TALLOC_CTX *mem_ctx)
3092 data->notify_data.value[0] = printer->info_2->attributes;
3093 data->notify_data.value[1] = 0;
3096 /*******************************************************************
3097 * fill a notify_info_data with the priority
3098 ********************************************************************/
3100 static void spoolss_notify_priority(int snum,
3101 SPOOL_NOTIFY_INFO_DATA *data,
3102 print_queue_struct *queue,
3103 NT_PRINTER_INFO_LEVEL *printer,
3104 TALLOC_CTX *mem_ctx)
3106 data->notify_data.value[0] = printer->info_2->priority;
3107 data->notify_data.value[1] = 0;
3110 /*******************************************************************
3111 * fill a notify_info_data with the default priority
3112 ********************************************************************/
3114 static void spoolss_notify_default_priority(int snum,
3115 SPOOL_NOTIFY_INFO_DATA *data,
3116 print_queue_struct *queue,
3117 NT_PRINTER_INFO_LEVEL *printer,
3118 TALLOC_CTX *mem_ctx)
3120 data->notify_data.value[0] = printer->info_2->default_priority;
3121 data->notify_data.value[1] = 0;
3124 /*******************************************************************
3125 * fill a notify_info_data with the start time
3126 ********************************************************************/
3128 static void spoolss_notify_start_time(int snum,
3129 SPOOL_NOTIFY_INFO_DATA *data,
3130 print_queue_struct *queue,
3131 NT_PRINTER_INFO_LEVEL *printer,
3132 TALLOC_CTX *mem_ctx)
3134 data->notify_data.value[0] = printer->info_2->starttime;
3135 data->notify_data.value[1] = 0;
3138 /*******************************************************************
3139 * fill a notify_info_data with the until time
3140 ********************************************************************/
3142 static void spoolss_notify_until_time(int snum,
3143 SPOOL_NOTIFY_INFO_DATA *data,
3144 print_queue_struct *queue,
3145 NT_PRINTER_INFO_LEVEL *printer,
3146 TALLOC_CTX *mem_ctx)
3148 data->notify_data.value[0] = printer->info_2->untiltime;
3149 data->notify_data.value[1] = 0;
3152 /*******************************************************************
3153 * fill a notify_info_data with the status
3154 ********************************************************************/
3156 static void spoolss_notify_status(int snum,
3157 SPOOL_NOTIFY_INFO_DATA *data,
3158 print_queue_struct *queue,
3159 NT_PRINTER_INFO_LEVEL *printer,
3160 TALLOC_CTX *mem_ctx)
3162 print_status_struct status;
3164 print_queue_length(snum, &status);
3165 data->notify_data.value[0]=(uint32) status.status;
3166 data->notify_data.value[1] = 0;
3169 /*******************************************************************
3170 * fill a notify_info_data with the number of jobs queued
3171 ********************************************************************/
3173 void spoolss_notify_cjobs(int snum,
3174 SPOOL_NOTIFY_INFO_DATA *data,
3175 print_queue_struct *queue,
3176 NT_PRINTER_INFO_LEVEL *printer,
3177 TALLOC_CTX *mem_ctx)
3179 data->notify_data.value[0] = print_queue_length(snum, NULL);
3180 data->notify_data.value[1] = 0;
3183 /*******************************************************************
3184 * fill a notify_info_data with the average ppm
3185 ********************************************************************/
3187 static void spoolss_notify_average_ppm(int snum,
3188 SPOOL_NOTIFY_INFO_DATA *data,
3189 print_queue_struct *queue,
3190 NT_PRINTER_INFO_LEVEL *printer,
3191 TALLOC_CTX *mem_ctx)
3193 /* always respond 8 pages per minutes */
3194 /* a little hard ! */
3195 data->notify_data.value[0] = printer->info_2->averageppm;
3196 data->notify_data.value[1] = 0;
3199 /*******************************************************************
3200 * fill a notify_info_data with username
3201 ********************************************************************/
3203 static void spoolss_notify_username(int snum,
3204 SPOOL_NOTIFY_INFO_DATA *data,
3205 print_queue_struct *queue,
3206 NT_PRINTER_INFO_LEVEL *printer,
3207 TALLOC_CTX *mem_ctx)
3209 smb_ucs2_t *temp = NULL;
3212 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user);
3213 if (len == (uint32)-1) {
3217 data->notify_data.data.length = len;
3219 data->notify_data.data.string = (uint16 *)temp;
3221 data->notify_data.data.string = NULL;
3225 /*******************************************************************
3226 * fill a notify_info_data with job status
3227 ********************************************************************/
3229 static void spoolss_notify_job_status(int snum,
3230 SPOOL_NOTIFY_INFO_DATA *data,
3231 print_queue_struct *queue,
3232 NT_PRINTER_INFO_LEVEL *printer,
3233 TALLOC_CTX *mem_ctx)
3235 data->notify_data.value[0]=nt_printj_status(queue->status);
3236 data->notify_data.value[1] = 0;
3239 /*******************************************************************
3240 * fill a notify_info_data with job name
3241 ********************************************************************/
3243 static void spoolss_notify_job_name(int snum,
3244 SPOOL_NOTIFY_INFO_DATA *data,
3245 print_queue_struct *queue,
3246 NT_PRINTER_INFO_LEVEL *printer,
3247 TALLOC_CTX *mem_ctx)
3249 smb_ucs2_t *temp = NULL;
3252 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file);
3253 if (len == (uint32)-1) {
3257 data->notify_data.data.length = len;
3259 data->notify_data.data.string = (uint16 *)temp;
3261 data->notify_data.data.string = NULL;
3265 /*******************************************************************
3266 * fill a notify_info_data with job status
3267 ********************************************************************/
3269 static void spoolss_notify_job_status_string(int snum,
3270 SPOOL_NOTIFY_INFO_DATA *data,
3271 print_queue_struct *queue,
3272 NT_PRINTER_INFO_LEVEL *printer,
3273 TALLOC_CTX *mem_ctx)
3276 * Now we're returning job status codes we just return a "" here. JRA.
3280 smb_ucs2_t *temp = NULL;
3283 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3286 switch (queue->status) {
3291 p = ""; /* NT provides the paused string */
3300 #endif /* NO LONGER NEEDED. */
3302 len = rpcstr_push_talloc(mem_ctx, &temp, p);
3303 if (len == (uint32)-1) {
3307 data->notify_data.data.length = len;
3309 data->notify_data.data.string = (uint16 *)temp;
3311 data->notify_data.data.string = NULL;
3315 /*******************************************************************
3316 * fill a notify_info_data with job time
3317 ********************************************************************/
3319 static void spoolss_notify_job_time(int snum,
3320 SPOOL_NOTIFY_INFO_DATA *data,
3321 print_queue_struct *queue,
3322 NT_PRINTER_INFO_LEVEL *printer,
3323 TALLOC_CTX *mem_ctx)
3325 data->notify_data.value[0]=0x0;
3326 data->notify_data.value[1]=0;
3329 /*******************************************************************
3330 * fill a notify_info_data with job size
3331 ********************************************************************/
3333 static void spoolss_notify_job_size(int snum,
3334 SPOOL_NOTIFY_INFO_DATA *data,
3335 print_queue_struct *queue,
3336 NT_PRINTER_INFO_LEVEL *printer,
3337 TALLOC_CTX *mem_ctx)
3339 data->notify_data.value[0]=queue->size;
3340 data->notify_data.value[1]=0;
3343 /*******************************************************************
3344 * fill a notify_info_data with page info
3345 ********************************************************************/
3346 static void spoolss_notify_total_pages(int snum,
3347 SPOOL_NOTIFY_INFO_DATA *data,
3348 print_queue_struct *queue,
3349 NT_PRINTER_INFO_LEVEL *printer,
3350 TALLOC_CTX *mem_ctx)
3352 data->notify_data.value[0]=queue->page_count;
3353 data->notify_data.value[1]=0;
3356 /*******************************************************************
3357 * fill a notify_info_data with pages printed info.
3358 ********************************************************************/
3359 static void spoolss_notify_pages_printed(int snum,
3360 SPOOL_NOTIFY_INFO_DATA *data,
3361 print_queue_struct *queue,
3362 NT_PRINTER_INFO_LEVEL *printer,
3363 TALLOC_CTX *mem_ctx)
3365 data->notify_data.value[0]=0; /* Add code when back-end tracks this */
3366 data->notify_data.value[1]=0;
3369 /*******************************************************************
3370 Fill a notify_info_data with job position.
3371 ********************************************************************/
3373 static void spoolss_notify_job_position(int snum,
3374 SPOOL_NOTIFY_INFO_DATA *data,
3375 print_queue_struct *queue,
3376 NT_PRINTER_INFO_LEVEL *printer,
3377 TALLOC_CTX *mem_ctx)
3379 data->notify_data.value[0]=queue->job;
3380 data->notify_data.value[1]=0;
3383 /*******************************************************************
3384 Fill a notify_info_data with submitted time.
3385 ********************************************************************/
3387 static void spoolss_notify_submitted_time(int snum,
3388 SPOOL_NOTIFY_INFO_DATA *data,
3389 print_queue_struct *queue,
3390 NT_PRINTER_INFO_LEVEL *printer,
3391 TALLOC_CTX *mem_ctx)
3398 t=gmtime(&queue->time);
3400 len = sizeof(SYSTEMTIME);
3402 data->notify_data.data.length = len;
3403 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
3405 if (!data->notify_data.data.string) {
3406 data->notify_data.data.length = 0;
3410 make_systemtime(&st, t);
3413 * Systemtime must be linearized as a set of UINT16's.
3414 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3417 p = (char *)data->notify_data.data.string;
3418 SSVAL(p, 0, st.year);
3419 SSVAL(p, 2, st.month);
3420 SSVAL(p, 4, st.dayofweek);
3421 SSVAL(p, 6, st.day);
3422 SSVAL(p, 8, st.hour);
3423 SSVAL(p, 10, st.minute);
3424 SSVAL(p, 12, st.second);
3425 SSVAL(p, 14, st.milliseconds);
3428 struct s_notify_info_data_table
3434 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
3435 print_queue_struct *queue,
3436 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3439 /* A table describing the various print notification constants and
3440 whether the notification data is a pointer to a variable sized
3441 buffer, a one value uint32 or a two value uint32. */
3443 static const struct s_notify_info_data_table notify_info_data_table[] =
3445 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3446 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3447 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
3448 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3449 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3450 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
3451 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
3452 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3453 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
3454 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3455 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3456 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3457 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
3458 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
3459 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3460 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
3461 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3462 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3463 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
3464 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
3465 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
3466 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
3467 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
3468 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
3469 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
3470 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
3471 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3472 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3473 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3474 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
3475 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
3476 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3477 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3478 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3479 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3480 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3481 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
3482 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
3483 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
3484 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
3485 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3486 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
3487 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
3488 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3489 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3490 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
3491 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
3492 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
3493 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
3494 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3497 /*******************************************************************
3498 Return the size of info_data structure.
3499 ********************************************************************/
3501 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
3505 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3506 if ( (notify_info_data_table[i].type == type)
3507 && (notify_info_data_table[i].field == field) ) {
3508 switch(notify_info_data_table[i].size) {
3509 case NOTIFY_ONE_VALUE:
3510 case NOTIFY_TWO_VALUE:
3515 /* The only pointer notify data I have seen on
3516 the wire is the submitted time and this has
3517 the notify size set to 4. -tpot */
3519 case NOTIFY_POINTER:
3522 case NOTIFY_SECDESC:
3528 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3533 /*******************************************************************
3534 Return the type of notify_info_data.
3535 ********************************************************************/
3537 static uint32 type_of_notify_info_data(uint16 type, uint16 field)
3541 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3542 if (notify_info_data_table[i].type == type &&
3543 notify_info_data_table[i].field == field)
3544 return notify_info_data_table[i].size;
3550 /****************************************************************************
3551 ****************************************************************************/
3553 static bool search_notify(uint16 type, uint16 field, int *value)
3557 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3558 if (notify_info_data_table[i].type == type &&
3559 notify_info_data_table[i].field == field &&
3560 notify_info_data_table[i].fn != NULL) {
3569 /****************************************************************************
3570 ****************************************************************************/
3572 void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
3574 info_data->type = type;
3575 info_data->field = field;
3576 info_data->reserved = 0;
3578 info_data->size = size_of_notify_info_data(type, field);
3579 info_data->enc_type = type_of_notify_info_data(type, field);
3584 /*******************************************************************
3586 * fill a notify_info struct with info asked
3588 ********************************************************************/
3590 static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
3591 snum, SPOOL_NOTIFY_OPTION_TYPE
3592 *option_type, uint32 id,
3593 TALLOC_CTX *mem_ctx)
3599 SPOOL_NOTIFY_INFO_DATA *current_data;
3600 NT_PRINTER_INFO_LEVEL *printer = NULL;
3601 print_queue_struct *queue=NULL;
3603 type=option_type->type;
3605 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3606 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3607 option_type->count, lp_servicename(snum)));
3609 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3612 for(field_num=0; field_num<option_type->count; field_num++) {
3613 field = option_type->fields[field_num];
3615 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3617 if (!search_notify(type, field, &j) )
3620 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3621 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3622 free_a_printer(&printer, 2);
3626 current_data = &info->data[info->count];
3628 construct_info_data(current_data, type, field, id);
3630 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3631 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3633 notify_info_data_table[j].fn(snum, current_data, queue,
3639 free_a_printer(&printer, 2);
3643 /*******************************************************************
3645 * fill a notify_info struct with info asked
3647 ********************************************************************/
3649 static bool construct_notify_jobs_info(print_queue_struct *queue,
3650 SPOOL_NOTIFY_INFO *info,
3651 NT_PRINTER_INFO_LEVEL *printer,
3652 int snum, SPOOL_NOTIFY_OPTION_TYPE
3653 *option_type, uint32 id,
3654 TALLOC_CTX *mem_ctx)
3660 SPOOL_NOTIFY_INFO_DATA *current_data;
3662 DEBUG(4,("construct_notify_jobs_info\n"));
3664 type = option_type->type;
3666 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3667 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3668 option_type->count));
3670 for(field_num=0; field_num<option_type->count; field_num++) {
3671 field = option_type->fields[field_num];
3673 if (!search_notify(type, field, &j) )
3676 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3677 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3681 current_data=&(info->data[info->count]);
3683 construct_info_data(current_data, type, field, id);
3684 notify_info_data_table[j].fn(snum, current_data, queue,
3693 * JFM: The enumeration is not that simple, it's even non obvious.
3695 * let's take an example: I want to monitor the PRINTER SERVER for
3696 * the printer's name and the number of jobs currently queued.
3697 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3698 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3700 * I have 3 printers on the back of my server.
3702 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3705 * 1 printer 1 name 1
3706 * 2 printer 1 cjob 1
3707 * 3 printer 2 name 2
3708 * 4 printer 2 cjob 2
3709 * 5 printer 3 name 3
3710 * 6 printer 3 name 3
3712 * that's the print server case, the printer case is even worse.
3715 /*******************************************************************
3717 * enumerate all printers on the printserver
3718 * fill a notify_info struct with info asked
3720 ********************************************************************/
3722 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3723 SPOOL_NOTIFY_INFO *info,
3724 TALLOC_CTX *mem_ctx)
3727 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3728 int n_services=lp_numservices();
3730 SPOOL_NOTIFY_OPTION *option;
3731 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3733 DEBUG(4,("printserver_notify_info\n"));
3738 option=Printer->notify.option;
3743 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3744 sending a ffpcn() request first */
3749 for (i=0; i<option->count; i++) {
3750 option_type=&(option->ctr.type[i]);
3752 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3755 for (snum=0; snum<n_services; snum++)
3757 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3758 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3764 * Debugging information, don't delete.
3767 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3768 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3769 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3771 for (i=0; i<info->count; i++) {
3772 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3773 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3774 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3781 /*******************************************************************
3783 * fill a notify_info struct with info asked
3785 ********************************************************************/
3787 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
3788 TALLOC_CTX *mem_ctx)
3791 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3794 SPOOL_NOTIFY_OPTION *option;
3795 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3797 print_queue_struct *queue=NULL;
3798 print_status_struct status;
3800 DEBUG(4,("printer_notify_info\n"));
3805 option=Printer->notify.option;
3811 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3812 sending a ffpcn() request first */
3817 get_printer_snum(p, hnd, &snum, NULL);
3819 for (i=0; i<option->count; i++) {
3820 option_type=&option->ctr.type[i];
3822 switch ( option_type->type ) {
3823 case PRINTER_NOTIFY_TYPE:
3824 if(construct_notify_printer_info(Printer, info, snum,
3830 case JOB_NOTIFY_TYPE: {
3831 NT_PRINTER_INFO_LEVEL *printer = NULL;
3833 count = print_queue_status(snum, &queue, &status);
3835 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3838 for (j=0; j<count; j++) {
3839 construct_notify_jobs_info(&queue[j], info,
3846 free_a_printer(&printer, 2);
3856 * Debugging information, don't delete.
3859 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3860 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3861 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3863 for (i=0; i<info->count; i++) {
3864 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3865 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3866 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3872 /********************************************************************
3874 ********************************************************************/
3876 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
3878 POLICY_HND *handle = &q_u->handle;
3879 SPOOL_NOTIFY_INFO *info = &r_u->info;
3881 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3882 WERROR result = WERR_BADFID;
3884 /* we always have a NOTIFY_INFO struct */
3888 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3889 OUR_HANDLE(handle)));
3893 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3896 * We are now using the change value, and
3897 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3898 * I don't have a global notification system, I'm sending back all the
3899 * informations even when _NOTHING_ has changed.
3902 /* We need to keep track of the change value to send back in
3903 RRPCN replies otherwise our updates are ignored. */
3905 Printer->notify.fnpcn = True;
3907 if (Printer->notify.client_connected) {
3908 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
3909 Printer->notify.change = q_u->change;
3912 /* just ignore the SPOOL_NOTIFY_OPTION */
3914 switch (Printer->printer_type) {
3916 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3919 case SPLHND_PRINTER:
3920 result = printer_notify_info(p, handle, info, p->mem_ctx);
3924 Printer->notify.fnpcn = False;
3930 /********************************************************************
3931 * construct_printer_info_0
3932 * fill a printer_info_0 struct
3933 ********************************************************************/
3935 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3937 char *chaine = NULL;
3939 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3940 counter_printer_0 *session_counter;
3941 uint32 global_counter;
3944 print_status_struct status;
3945 TALLOC_CTX *ctx = talloc_tos();
3947 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3950 init_unistr(&printer->printername, ntprinter->info_2->printername);
3952 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3954 free_a_printer(&ntprinter,2);
3958 count = print_queue_length(snum, &status);
3960 /* check if we already have a counter for this printer */
3961 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3962 if (session_counter->snum == snum)
3966 init_unistr(&printer->servername, chaine);
3968 /* it's the first time, add it to the list */
3969 if (session_counter==NULL) {
3970 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3971 free_a_printer(&ntprinter, 2);
3974 ZERO_STRUCTP(session_counter);
3975 session_counter->snum=snum;
3976 session_counter->counter=0;
3977 DLIST_ADD(counter_list, session_counter);
3981 session_counter->counter++;
3984 * the global_counter should be stored in a TDB as it's common to all the clients
3985 * and should be zeroed on samba startup
3987 global_counter=session_counter->counter;
3988 printer->cjobs = count;
3989 printer->total_jobs = 0;
3990 printer->total_bytes = 0;
3992 setuptime = (time_t)ntprinter->info_2->setuptime;
3993 t=gmtime(&setuptime);
3995 printer->year = t->tm_year+1900;
3996 printer->month = t->tm_mon+1;
3997 printer->dayofweek = t->tm_wday;
3998 printer->day = t->tm_mday;
3999 printer->hour = t->tm_hour;
4000 printer->minute = t->tm_min;
4001 printer->second = t->tm_sec;
4002 printer->milliseconds = 0;
4004 printer->global_counter = global_counter;
4005 printer->total_pages = 0;
4007 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
4008 printer->major_version = 0x0005; /* NT 5 */
4009 printer->build_version = 0x0893; /* build 2195 */
4011 printer->unknown7 = 0x1;
4012 printer->unknown8 = 0x0;
4013 printer->unknown9 = 0x0;
4014 printer->session_counter = session_counter->counter;
4015 printer->unknown11 = 0x0;
4016 printer->printer_errors = 0x0; /* number of print failure */
4017 printer->unknown13 = 0x0;
4018 printer->unknown14 = 0x1;
4019 printer->unknown15 = 0x024a; /* 586 Pentium ? */
4020 printer->unknown16 = 0x0;
4021 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
4022 printer->unknown18 = 0x0;
4023 printer->status = nt_printq_status(status.status);
4024 printer->unknown20 = 0x0;
4025 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4026 printer->unknown22 = 0x0;
4027 printer->unknown23 = 0x6; /* 6 ???*/
4028 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
4029 printer->unknown25 = 0;
4030 printer->unknown26 = 0;
4031 printer->unknown27 = 0;
4032 printer->unknown28 = 0;
4033 printer->unknown29 = 0;
4035 free_a_printer(&ntprinter,2);
4039 /********************************************************************
4040 * construct_printer_info_1
4041 * fill a printer_info_1 struct
4042 ********************************************************************/
4043 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4045 char *chaine = NULL;
4046 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4047 TALLOC_CTX *ctx = talloc_tos();
4049 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4052 printer->flags=flags;
4054 if (*ntprinter->info_2->comment == '\0') {
4055 init_unistr(&printer->comment, lp_comment(snum));
4056 chaine = talloc_asprintf(ctx,
4057 "%s,%s,%s", ntprinter->info_2->printername,
4058 ntprinter->info_2->drivername, lp_comment(snum));
4061 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4062 chaine = talloc_asprintf(ctx,
4063 "%s,%s,%s", ntprinter->info_2->printername,
4064 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4068 free_a_printer(&ntprinter,2);
4072 init_unistr(&printer->description, chaine);
4073 init_unistr(&printer->name, ntprinter->info_2->printername);
4075 free_a_printer(&ntprinter,2);
4080 /****************************************************************************
4081 Free a DEVMODE struct.
4082 ****************************************************************************/
4084 static void free_dev_mode(DEVICEMODE *dev)
4089 SAFE_FREE(dev->dev_private);
4094 /****************************************************************************
4095 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4096 should be valid upon entry
4097 ****************************************************************************/
4099 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4101 if ( !devmode || !ntdevmode )
4104 init_unistr(&devmode->devicename, ntdevmode->devicename);
4106 init_unistr(&devmode->formname, ntdevmode->formname);
4108 devmode->specversion = ntdevmode->specversion;
4109 devmode->driverversion = ntdevmode->driverversion;
4110 devmode->size = ntdevmode->size;
4111 devmode->driverextra = ntdevmode->driverextra;
4112 devmode->fields = ntdevmode->fields;
4114 devmode->orientation = ntdevmode->orientation;
4115 devmode->papersize = ntdevmode->papersize;
4116 devmode->paperlength = ntdevmode->paperlength;
4117 devmode->paperwidth = ntdevmode->paperwidth;
4118 devmode->scale = ntdevmode->scale;
4119 devmode->copies = ntdevmode->copies;
4120 devmode->defaultsource = ntdevmode->defaultsource;
4121 devmode->printquality = ntdevmode->printquality;
4122 devmode->color = ntdevmode->color;
4123 devmode->duplex = ntdevmode->duplex;
4124 devmode->yresolution = ntdevmode->yresolution;
4125 devmode->ttoption = ntdevmode->ttoption;
4126 devmode->collate = ntdevmode->collate;
4127 devmode->icmmethod = ntdevmode->icmmethod;
4128 devmode->icmintent = ntdevmode->icmintent;
4129 devmode->mediatype = ntdevmode->mediatype;
4130 devmode->dithertype = ntdevmode->dithertype;
4132 if (ntdevmode->nt_dev_private != NULL) {
4133 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4140 /****************************************************************************
4141 Create a DEVMODE struct. Returns malloced memory.
4142 ****************************************************************************/
4144 DEVICEMODE *construct_dev_mode(const char *servicename)
4146 NT_PRINTER_INFO_LEVEL *printer = NULL;
4147 DEVICEMODE *devmode = NULL;
4149 DEBUG(7,("construct_dev_mode\n"));
4151 DEBUGADD(8,("getting printer characteristics\n"));
4153 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4156 if ( !printer->info_2->devmode ) {
4157 DEBUG(5, ("BONG! There was no device mode!\n"));
4161 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4162 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4166 ZERO_STRUCTP(devmode);
4168 DEBUGADD(8,("loading DEVICEMODE\n"));
4170 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4171 free_dev_mode( devmode );
4176 free_a_printer(&printer,2);
4181 /********************************************************************
4182 * construct_printer_info_2
4183 * fill a printer_info_2 struct
4184 ********************************************************************/
4186 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4189 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4191 print_status_struct status;
4193 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4196 count = print_queue_length(snum, &status);
4198 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4199 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4200 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4201 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4202 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4204 if (*ntprinter->info_2->comment == '\0')
4205 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4207 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4209 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4210 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4211 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4212 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4213 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4215 printer->attributes = ntprinter->info_2->attributes;
4217 printer->priority = ntprinter->info_2->priority; /* priority */
4218 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4219 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4220 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4221 printer->status = nt_printq_status(status.status); /* status */
4222 printer->cjobs = count; /* jobs */
4223 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4225 if ( !(printer->devmode = construct_dev_mode(
4226 lp_const_servicename(snum))) )
4227 DEBUG(8, ("Returning NULL Devicemode!\n"));
4229 printer->secdesc = NULL;
4231 if ( ntprinter->info_2->secdesc_buf
4232 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4234 /* don't use talloc_steal() here unless you do a deep steal of all
4235 the SEC_DESC members */
4237 printer->secdesc = dup_sec_desc( talloc_tos(),
4238 ntprinter->info_2->secdesc_buf->sd );
4241 free_a_printer(&ntprinter, 2);
4246 /********************************************************************
4247 * construct_printer_info_3
4248 * fill a printer_info_3 struct
4249 ********************************************************************/
4251 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4253 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4254 PRINTER_INFO_3 *printer = NULL;
4256 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4260 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4261 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4262 free_a_printer(&ntprinter, 2);
4266 ZERO_STRUCTP(printer);
4268 /* These are the components of the SD we are returning. */
4270 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4271 /* don't use talloc_steal() here unless you do a deep steal of all
4272 the SEC_DESC members */
4274 printer->secdesc = dup_sec_desc( talloc_tos(),
4275 ntprinter->info_2->secdesc_buf->sd );
4278 free_a_printer(&ntprinter, 2);
4280 *pp_printer = printer;
4284 /********************************************************************
4285 * construct_printer_info_4
4286 * fill a printer_info_4 struct
4287 ********************************************************************/
4289 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4291 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4293 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4296 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4297 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4298 printer->attributes = ntprinter->info_2->attributes;
4300 free_a_printer(&ntprinter, 2);
4304 /********************************************************************
4305 * construct_printer_info_5
4306 * fill a printer_info_5 struct
4307 ********************************************************************/
4309 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4311 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4313 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4316 init_unistr(&printer->printername, ntprinter->info_2->printername);
4317 init_unistr(&printer->portname, ntprinter->info_2->portname);
4318 printer->attributes = ntprinter->info_2->attributes;
4320 /* these two are not used by NT+ according to MSDN */
4322 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4323 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4325 free_a_printer(&ntprinter, 2);
4330 /********************************************************************
4331 * construct_printer_info_6
4332 * fill a printer_info_6 struct
4333 ********************************************************************/
4335 static bool construct_printer_info_6(Printer_entry *print_hnd,
4336 PRINTER_INFO_6 *printer,
4339 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4341 print_status_struct status;
4343 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4344 lp_const_servicename(snum))))
4347 count = print_queue_length(snum, &status);
4349 printer->status = nt_printq_status(status.status);
4351 free_a_printer(&ntprinter, 2);
4356 /********************************************************************
4357 * construct_printer_info_7
4358 * fill a printer_info_7 struct
4359 ********************************************************************/
4361 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4363 char *guid_str = NULL;
4366 if (is_printer_published(print_hnd, snum, &guid)) {
4367 if (asprintf(&guid_str, "{%s}",
4368 GUID_string(talloc_tos(), &guid)) == -1) {
4371 strupper_m(guid_str);
4372 init_unistr(&printer->guid, guid_str);
4373 SAFE_FREE(guid_str);
4374 printer->action = SPOOL_DS_PUBLISH;
4376 init_unistr(&printer->guid, "");
4377 printer->action = SPOOL_DS_UNPUBLISH;
4383 /********************************************************************
4384 Spoolss_enumprinters.
4385 ********************************************************************/
4387 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4391 int n_services=lp_numservices();
4392 PRINTER_INFO_1 *printers=NULL;
4393 PRINTER_INFO_1 current_prt;
4394 WERROR result = WERR_OK;
4396 DEBUG(4,("enum_all_printers_info_1\n"));
4398 for (snum=0; snum<n_services; snum++) {
4399 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4400 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4402 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4403 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4404 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4408 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4410 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4416 /* check the required size. */
4417 for (i=0; i<*returned; i++)
4418 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4420 if (*needed > offered) {
4421 result = WERR_INSUFFICIENT_BUFFER;
4425 if (!rpcbuf_alloc_size(buffer, *needed)) {
4426 result = WERR_NOMEM;
4430 /* fill the buffer with the structures */
4431 for (i=0; i<*returned; i++)
4432 smb_io_printer_info_1("", buffer, &printers[i], 0);
4437 SAFE_FREE(printers);
4439 if ( !W_ERROR_IS_OK(result) )
4445 /********************************************************************
4446 enum_all_printers_info_1_local.
4447 *********************************************************************/
4449 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4451 DEBUG(4,("enum_all_printers_info_1_local\n"));
4453 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4456 /********************************************************************
4457 enum_all_printers_info_1_name.
4458 *********************************************************************/
4460 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4464 DEBUG(4,("enum_all_printers_info_1_name\n"));
4466 if ((name[0] == '\\') && (name[1] == '\\'))
4469 if (is_myname_or_ipaddr(s)) {
4470 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4473 return WERR_INVALID_NAME;
4476 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4477 /********************************************************************
4478 enum_all_printers_info_1_remote.
4479 *********************************************************************/
4481 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4483 PRINTER_INFO_1 *printer;
4484 fstring printername;
4487 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4488 WERROR result = WERR_OK;
4490 /* JFM: currently it's more a place holder than anything else.
4491 * In the spooler world there is a notion of server registration.
4492 * the print servers are registered on the PDC (in the same domain)
4494 * We should have a TDB here. The registration is done thru an
4495 * undocumented RPC call.
4498 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4503 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4504 slprintf(desc, sizeof(desc)-1,"%s", name);
4505 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4507 init_unistr(&printer->description, desc);
4508 init_unistr(&printer->name, printername);
4509 init_unistr(&printer->comment, comment);
4510 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4512 /* check the required size. */
4513 *needed += spoolss_size_printer_info_1(printer);
4515 if (*needed > offered) {
4516 result = WERR_INSUFFICIENT_BUFFER;
4520 if (!rpcbuf_alloc_size(buffer, *needed)) {
4521 result = WERR_NOMEM;
4525 /* fill the buffer with the structures */
4526 smb_io_printer_info_1("", buffer, printer, 0);
4532 if ( !W_ERROR_IS_OK(result) )
4540 /********************************************************************
4541 enum_all_printers_info_1_network.
4542 *********************************************************************/
4544 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4548 DEBUG(4,("enum_all_printers_info_1_network\n"));
4550 /* If we respond to a enum_printers level 1 on our name with flags
4551 set to PRINTER_ENUM_REMOTE with a list of printers then these
4552 printers incorrectly appear in the APW browse list.
4553 Specifically the printers for the server appear at the workgroup
4554 level where all the other servers in the domain are
4555 listed. Windows responds to this call with a
4556 WERR_CAN_NOT_COMPLETE so we should do the same. */
4558 if (name[0] == '\\' && name[1] == '\\')
4561 if (is_myname_or_ipaddr(s))
4562 return WERR_CAN_NOT_COMPLETE;
4564 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned);
4567 /********************************************************************
4568 * api_spoolss_enumprinters
4570 * called from api_spoolss_enumprinters (see this to understand)
4571 ********************************************************************/
4573 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4577 int n_services=lp_numservices();
4578 PRINTER_INFO_2 *printers=NULL;
4579 PRINTER_INFO_2 current_prt;
4580 WERROR result = WERR_OK;
4584 for (snum=0; snum<n_services; snum++) {
4585 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4586 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4588 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4589 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4590 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4595 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4597 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4604 /* check the required size. */
4605 for (i=0; i<*returned; i++)
4606 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4608 if (*needed > offered) {
4609 result = WERR_INSUFFICIENT_BUFFER;
4613 if (!rpcbuf_alloc_size(buffer, *needed)) {
4614 result = WERR_NOMEM;
4618 /* fill the buffer with the structures */
4619 for (i=0; i<*returned; i++)
4620 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4625 for (i=0; i<*returned; i++)
4626 free_devmode(printers[i].devmode);
4628 SAFE_FREE(printers);
4630 if ( !W_ERROR_IS_OK(result) )
4636 /********************************************************************
4637 * handle enumeration of printers at level 1
4638 ********************************************************************/
4640 static WERROR enumprinters_level1( uint32 flags, fstring name,
4641 RPC_BUFFER *buffer, uint32 offered,
4642 uint32 *needed, uint32 *returned)
4644 /* Not all the flags are equals */
4646 if (flags & PRINTER_ENUM_LOCAL)
4647 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4649 if (flags & PRINTER_ENUM_NAME)
4650 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4652 #if 0 /* JERRY - disabled for now */
4653 if (flags & PRINTER_ENUM_REMOTE)
4654 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4657 if (flags & PRINTER_ENUM_NETWORK)
4658 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4660 return WERR_OK; /* NT4sp5 does that */
4663 /********************************************************************
4664 * handle enumeration of printers at level 2
4665 ********************************************************************/
4667 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4668 RPC_BUFFER *buffer, uint32 offered,
4669 uint32 *needed, uint32 *returned)
4671 if (flags & PRINTER_ENUM_LOCAL) {
4672 return enum_all_printers_info_2(buffer, offered, needed, returned);
4675 if (flags & PRINTER_ENUM_NAME) {
4676 if (is_myname_or_ipaddr(canon_servername(servername)))
4677 return enum_all_printers_info_2(buffer, offered, needed, returned);
4679 return WERR_INVALID_NAME;
4682 if (flags & PRINTER_ENUM_REMOTE)
4683 return WERR_UNKNOWN_LEVEL;
4688 /********************************************************************
4689 * handle enumeration of printers at level 5
4690 ********************************************************************/
4692 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4693 RPC_BUFFER *buffer, uint32 offered,
4694 uint32 *needed, uint32 *returned)
4696 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4700 /********************************************************************
4701 * api_spoolss_enumprinters
4703 * called from api_spoolss_enumprinters (see this to understand)
4704 ********************************************************************/
4706 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4708 uint32 flags = q_u->flags;
4709 UNISTR2 *servername = &q_u->servername;
4710 uint32 level = q_u->level;
4711 RPC_BUFFER *buffer = NULL;
4712 uint32 offered = q_u->offered;
4713 uint32 *needed = &r_u->needed;
4714 uint32 *returned = &r_u->returned;
4718 /* that's an [in out] buffer */
4720 if (!q_u->buffer && (offered!=0)) {
4721 return WERR_INVALID_PARAM;
4724 rpcbuf_move(q_u->buffer, &r_u->buffer);
4725 buffer = r_u->buffer;
4727 DEBUG(4,("_spoolss_enumprinters\n"));
4734 * flags==PRINTER_ENUM_NAME
4735 * if name=="" then enumerates all printers
4736 * if name!="" then enumerate the printer
4737 * flags==PRINTER_ENUM_REMOTE
4738 * name is NULL, enumerate printers
4739 * Level 2: name!="" enumerates printers, name can't be NULL
4740 * Level 3: doesn't exist
4741 * Level 4: does a local registry lookup
4742 * Level 5: same as Level 2
4745 unistr2_to_ascii(name, servername, sizeof(name));
4750 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4752 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4754 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4759 return WERR_UNKNOWN_LEVEL;
4762 /****************************************************************************
4763 ****************************************************************************/
4765 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4767 PRINTER_INFO_0 *printer=NULL;
4768 WERROR result = WERR_OK;
4770 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4773 construct_printer_info_0(print_hnd, printer, snum);
4775 /* check the required size. */
4776 *needed += spoolss_size_printer_info_0(printer);
4778 if (*needed > offered) {
4779 result = WERR_INSUFFICIENT_BUFFER;
4783 if (!rpcbuf_alloc_size(buffer, *needed)) {
4784 result = WERR_NOMEM;
4788 /* fill the buffer with the structures */
4789 smb_io_printer_info_0("", buffer, printer, 0);
4799 /****************************************************************************
4800 ****************************************************************************/
4802 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4804 PRINTER_INFO_1 *printer=NULL;
4805 WERROR result = WERR_OK;
4807 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4810 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4812 /* check the required size. */
4813 *needed += spoolss_size_printer_info_1(printer);
4815 if (*needed > offered) {
4816 result = WERR_INSUFFICIENT_BUFFER;
4820 if (!rpcbuf_alloc_size(buffer, *needed)) {
4821 result = WERR_NOMEM;
4825 /* fill the buffer with the structures */
4826 smb_io_printer_info_1("", buffer, printer, 0);
4835 /****************************************************************************
4836 ****************************************************************************/
4838 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4840 PRINTER_INFO_2 *printer=NULL;
4841 WERROR result = WERR_OK;
4843 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4846 construct_printer_info_2(print_hnd, printer, snum);
4848 /* check the required size. */
4849 *needed += spoolss_size_printer_info_2(printer);
4851 if (*needed > offered) {
4852 result = WERR_INSUFFICIENT_BUFFER;
4856 if (!rpcbuf_alloc_size(buffer, *needed)) {
4857 result = WERR_NOMEM;
4861 /* fill the buffer with the structures */
4862 if (!smb_io_printer_info_2("", buffer, printer, 0))
4863 result = WERR_NOMEM;
4867 free_printer_info_2(printer);
4872 /****************************************************************************
4873 ****************************************************************************/
4875 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4877 PRINTER_INFO_3 *printer=NULL;
4878 WERROR result = WERR_OK;
4880 if (!construct_printer_info_3(print_hnd, &printer, snum))
4883 /* check the required size. */
4884 *needed += spoolss_size_printer_info_3(printer);
4886 if (*needed > offered) {
4887 result = WERR_INSUFFICIENT_BUFFER;
4891 if (!rpcbuf_alloc_size(buffer, *needed)) {
4892 result = WERR_NOMEM;
4896 /* fill the buffer with the structures */
4897 smb_io_printer_info_3("", buffer, printer, 0);
4901 free_printer_info_3(printer);
4906 /****************************************************************************
4907 ****************************************************************************/
4909 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4911 PRINTER_INFO_4 *printer=NULL;
4912 WERROR result = WERR_OK;
4914 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4917 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4922 /* check the required size. */
4923 *needed += spoolss_size_printer_info_4(printer);
4925 if (*needed > offered) {
4926 result = WERR_INSUFFICIENT_BUFFER;
4930 if (!rpcbuf_alloc_size(buffer, *needed)) {
4931 result = WERR_NOMEM;
4935 /* fill the buffer with the structures */
4936 smb_io_printer_info_4("", buffer, printer, 0);
4940 free_printer_info_4(printer);
4945 /****************************************************************************
4946 ****************************************************************************/
4948 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4950 PRINTER_INFO_5 *printer=NULL;
4951 WERROR result = WERR_OK;
4953 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4956 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4957 free_printer_info_5(printer);
4961 /* check the required size. */
4962 *needed += spoolss_size_printer_info_5(printer);
4964 if (*needed > offered) {
4965 result = WERR_INSUFFICIENT_BUFFER;
4969 if (!rpcbuf_alloc_size(buffer, *needed)) {
4970 result = WERR_NOMEM;
4974 /* fill the buffer with the structures */
4975 smb_io_printer_info_5("", buffer, printer, 0);
4979 free_printer_info_5(printer);
4984 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4986 RPC_BUFFER *buffer, uint32 offered,
4989 PRINTER_INFO_6 *printer;
4990 WERROR result = WERR_OK;
4992 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4996 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4997 free_printer_info_6(printer);
5001 /* check the required size. */
5002 *needed += spoolss_size_printer_info_6(printer);
5004 if (*needed > offered) {
5005 result = WERR_INSUFFICIENT_BUFFER;
5009 if (!rpcbuf_alloc_size(buffer, *needed)) {
5010 result = WERR_NOMEM;
5014 /* fill the buffer with the structures */
5015 smb_io_printer_info_6("", buffer, printer, 0);
5019 free_printer_info_6(printer);
5024 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5026 PRINTER_INFO_7 *printer=NULL;
5027 WERROR result = WERR_OK;
5029 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5032 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5033 result = WERR_NOMEM;
5037 /* check the required size. */
5038 *needed += spoolss_size_printer_info_7(printer);
5040 if (*needed > offered) {
5041 result = WERR_INSUFFICIENT_BUFFER;
5045 if (!rpcbuf_alloc_size(buffer, *needed)) {
5046 result = WERR_NOMEM;
5051 /* fill the buffer with the structures */
5052 smb_io_printer_info_7("", buffer, printer, 0);
5056 free_printer_info_7(printer);
5061 /****************************************************************************
5062 ****************************************************************************/
5064 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5066 POLICY_HND *handle = &q_u->handle;
5067 uint32 level = q_u->level;
5068 RPC_BUFFER *buffer = NULL;
5069 uint32 offered = q_u->offered;
5070 uint32 *needed = &r_u->needed;
5071 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5075 /* that's an [in out] buffer */
5077 if (!q_u->buffer && (offered!=0)) {
5078 return WERR_INVALID_PARAM;
5081 rpcbuf_move(q_u->buffer, &r_u->buffer);
5082 buffer = r_u->buffer;
5086 if (!get_printer_snum(p, handle, &snum, NULL))
5091 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5093 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5095 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5097 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5099 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5101 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5103 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5105 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5107 return WERR_UNKNOWN_LEVEL;
5110 /********************************************************************
5111 * fill a DRIVER_INFO_1 struct
5112 ********************************************************************/
5114 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5116 init_unistr( &info->name, driver.info_3->name);
5119 /********************************************************************
5120 * construct_printer_driver_info_1
5121 ********************************************************************/
5123 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5125 NT_PRINTER_INFO_LEVEL *printer = NULL;
5126 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5128 ZERO_STRUCT(driver);
5130 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5131 return WERR_INVALID_PRINTER_NAME;
5133 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5134 free_a_printer(&printer, 2);
5135 return WERR_UNKNOWN_PRINTER_DRIVER;
5138 fill_printer_driver_info_1(info, driver, servername, architecture);
5140 free_a_printer(&printer,2);
5145 /********************************************************************
5146 * construct_printer_driver_info_2
5147 * fill a printer_info_2 struct
5148 ********************************************************************/
5150 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5152 TALLOC_CTX *ctx = talloc_tos();
5154 const char *cservername = canon_servername(servername);
5156 info->version=driver.info_3->cversion;
5158 init_unistr( &info->name, driver.info_3->name );
5159 init_unistr( &info->architecture, driver.info_3->environment );
5161 if (strlen(driver.info_3->driverpath)) {
5162 temp = talloc_asprintf(ctx,
5165 driver.info_3->driverpath);
5166 init_unistr( &info->driverpath, temp );
5168 init_unistr( &info->driverpath, "" );
5172 if (strlen(driver.info_3->datafile)) {
5173 temp = talloc_asprintf(ctx,
5176 driver.info_3->datafile);
5177 init_unistr( &info->datafile, temp );
5179 init_unistr( &info->datafile, "" );
5182 if (strlen(driver.info_3->configfile)) {
5183 temp = talloc_asprintf(ctx,
5186 driver.info_3->configfile);
5187 init_unistr( &info->configfile, temp );
5189 init_unistr( &info->configfile, "" );
5192 /********************************************************************
5193 * construct_printer_driver_info_2
5194 * fill a printer_info_2 struct
5195 ********************************************************************/
5197 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5199 NT_PRINTER_INFO_LEVEL *printer = NULL;
5200 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5202 ZERO_STRUCT(printer);
5203 ZERO_STRUCT(driver);
5205 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5206 return WERR_INVALID_PRINTER_NAME;
5208 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5209 free_a_printer(&printer, 2);
5210 return WERR_UNKNOWN_PRINTER_DRIVER;
5213 fill_printer_driver_info_2(info, driver, servername);
5215 free_a_printer(&printer,2);
5220 /********************************************************************
5221 * copy a strings array and convert to UNICODE
5223 * convert an array of ascii string to a UNICODE string
5224 ********************************************************************/
5226 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5232 TALLOC_CTX *ctx = talloc_tos();
5234 DEBUG(6,("init_unistr_array\n"));
5238 if ( !char_array ) {
5243 v = ""; /* hack to handle null lists */
5246 /* hack to allow this to be used in places other than when generating
5247 the list of dependent files */
5251 line = talloc_asprintf(ctx,
5253 canon_servername(servername),
5256 line = talloc_strdup(ctx, v);
5260 SAFE_FREE(*uni_array);
5263 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5265 /* add one extra unit16 for the second terminating NULL */
5267 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5268 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5275 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5280 /* special case for ""; we need to add both NULL's here */
5282 (*uni_array)[j++]=0x0000;
5283 (*uni_array)[j]=0x0000;
5286 DEBUGADD(6,("last one:done\n"));
5288 /* return size of array in uint16's */
5293 /********************************************************************
5294 * construct_printer_info_3
5295 * fill a printer_info_3 struct
5296 ********************************************************************/
5298 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5301 TALLOC_CTX *ctx = talloc_tos();
5302 const char *cservername = canon_servername(servername);
5306 info->version=driver.info_3->cversion;
5308 init_unistr( &info->name, driver.info_3->name );
5309 init_unistr( &info->architecture, driver.info_3->environment );
5311 if (strlen(driver.info_3->driverpath)) {
5312 temp = talloc_asprintf(ctx,
5315 driver.info_3->driverpath);
5316 init_unistr( &info->driverpath, temp );
5318 init_unistr( &info->driverpath, "" );
5321 if (strlen(driver.info_3->datafile)) {
5322 temp = talloc_asprintf(ctx,
5325 driver.info_3->datafile);
5326 init_unistr( &info->datafile, temp );
5328 init_unistr( &info->datafile, "" );
5331 if (strlen(driver.info_3->configfile)) {
5332 temp = talloc_asprintf(ctx,
5335 driver.info_3->configfile);
5336 init_unistr( &info->configfile, temp );
5338 init_unistr( &info->configfile, "" );
5341 if (strlen(driver.info_3->helpfile)) {
5342 temp = talloc_asprintf(ctx,
5345 driver.info_3->helpfile);
5346 init_unistr( &info->helpfile, temp );
5348 init_unistr( &info->helpfile, "" );
5351 init_unistr( &info->monitorname, driver.info_3->monitorname );
5352 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5354 info->dependentfiles=NULL;
5355 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5358 /********************************************************************
5359 * construct_printer_info_3
5360 * fill a printer_info_3 struct
5361 ********************************************************************/
5363 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5365 NT_PRINTER_INFO_LEVEL *printer = NULL;
5366 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5368 ZERO_STRUCT(driver);
5370 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5371 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5372 if (!W_ERROR_IS_OK(status))
5373 return WERR_INVALID_PRINTER_NAME;
5375 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5376 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5381 * I put this code in during testing. Helpful when commenting out the
5382 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5383 * as win2k always queries the driver using an infor level of 6.
5384 * I've left it in (but ifdef'd out) because I'll probably
5385 * use it in experimentation again in the future. --jerry 22/01/2002
5388 if (!W_ERROR_IS_OK(status)) {
5390 * Is this a W2k client ?
5393 /* Yes - try again with a WinNT driver. */
5395 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5396 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5400 if (!W_ERROR_IS_OK(status)) {
5401 free_a_printer(&printer,2);
5402 return WERR_UNKNOWN_PRINTER_DRIVER;
5410 fill_printer_driver_info_3(info, driver, servername);
5412 free_a_printer(&printer,2);
5417 /********************************************************************
5418 * construct_printer_info_6
5419 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5420 ********************************************************************/
5422 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5426 TALLOC_CTX *ctx = talloc_tos();
5427 const char *cservername = canon_servername(servername);
5430 memset(&nullstr, '\0', sizeof(fstring));
5432 info->version=driver.info_3->cversion;
5434 init_unistr( &info->name, driver.info_3->name );
5435 init_unistr( &info->architecture, driver.info_3->environment );
5437 if (strlen(driver.info_3->driverpath)) {
5438 temp = talloc_asprintf(ctx,
5441 driver.info_3->driverpath);
5442 init_unistr( &info->driverpath, temp );
5444 init_unistr( &info->driverpath, "" );
5447 if (strlen(driver.info_3->datafile)) {
5448 temp = talloc_asprintf(ctx,
5451 driver.info_3->datafile);
5452 init_unistr( &info->datafile, temp );
5454 init_unistr( &info->datafile, "" );
5457 if (strlen(driver.info_3->configfile)) {
5458 temp = talloc_asprintf(ctx,
5461 driver.info_3->configfile);
5462 init_unistr( &info->configfile, temp );
5464 init_unistr( &info->configfile, "" );
5467 if (strlen(driver.info_3->helpfile)) {
5468 temp = talloc_asprintf(ctx,
5471 driver.info_3->helpfile);
5472 init_unistr( &info->helpfile, temp );
5474 init_unistr( &info->helpfile, "" );
5477 init_unistr( &info->monitorname, driver.info_3->monitorname );
5478 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5480 info->dependentfiles = NULL;
5481 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5483 info->previousdrivernames=NULL;
5484 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5486 info->driver_date=0;
5489 info->driver_version_low=0;
5490 info->driver_version_high=0;
5492 init_unistr( &info->mfgname, "");
5493 init_unistr( &info->oem_url, "");
5494 init_unistr( &info->hardware_id, "");
5495 init_unistr( &info->provider, "");
5498 /********************************************************************
5499 * construct_printer_info_6
5500 * fill a printer_info_6 struct
5501 ********************************************************************/
5503 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5504 const char *servername, fstring architecture, uint32 version)
5506 NT_PRINTER_INFO_LEVEL *printer = NULL;
5507 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5510 ZERO_STRUCT(driver);
5512 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5514 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5516 if (!W_ERROR_IS_OK(status))
5517 return WERR_INVALID_PRINTER_NAME;
5519 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5521 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5523 if (!W_ERROR_IS_OK(status))
5526 * Is this a W2k client ?
5530 free_a_printer(&printer,2);
5531 return WERR_UNKNOWN_PRINTER_DRIVER;
5534 /* Yes - try again with a WinNT driver. */
5536 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)));
5538 if (!W_ERROR_IS_OK(status)) {
5539 free_a_printer(&printer,2);
5540 return WERR_UNKNOWN_PRINTER_DRIVER;
5544 fill_printer_driver_info_6(info, driver, servername);
5546 free_a_printer(&printer,2);
5547 free_a_printer_driver(driver, 3);
5552 /****************************************************************************
5553 ****************************************************************************/
5555 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5557 SAFE_FREE(info->dependentfiles);
5560 /****************************************************************************
5561 ****************************************************************************/
5563 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5565 SAFE_FREE(info->dependentfiles);
5568 /****************************************************************************
5569 ****************************************************************************/
5571 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5573 DRIVER_INFO_1 *info=NULL;
5576 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5579 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5580 if (!W_ERROR_IS_OK(result))
5583 /* check the required size. */
5584 *needed += spoolss_size_printer_driver_info_1(info);
5586 if (*needed > offered) {
5587 result = WERR_INSUFFICIENT_BUFFER;
5591 if (!rpcbuf_alloc_size(buffer, *needed)) {
5592 result = WERR_NOMEM;
5596 /* fill the buffer with the structures */
5597 smb_io_printer_driver_info_1("", buffer, info, 0);
5606 /****************************************************************************
5607 ****************************************************************************/
5609 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5611 DRIVER_INFO_2 *info=NULL;
5614 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5617 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5618 if (!W_ERROR_IS_OK(result))
5621 /* check the required size. */
5622 *needed += spoolss_size_printer_driver_info_2(info);
5624 if (*needed > offered) {
5625 result = WERR_INSUFFICIENT_BUFFER;
5629 if (!rpcbuf_alloc_size(buffer, *needed)) {
5630 result = WERR_NOMEM;
5634 /* fill the buffer with the structures */
5635 smb_io_printer_driver_info_2("", buffer, info, 0);
5644 /****************************************************************************
5645 ****************************************************************************/
5647 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5654 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5655 if (!W_ERROR_IS_OK(result))
5658 /* check the required size. */
5659 *needed += spoolss_size_printer_driver_info_3(&info);
5661 if (*needed > offered) {
5662 result = WERR_INSUFFICIENT_BUFFER;
5666 if (!rpcbuf_alloc_size(buffer, *needed)) {
5667 result = WERR_NOMEM;
5671 /* fill the buffer with the structures */
5672 smb_io_printer_driver_info_3("", buffer, &info, 0);
5675 free_printer_driver_info_3(&info);
5680 /****************************************************************************
5681 ****************************************************************************/
5683 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5690 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5691 if (!W_ERROR_IS_OK(result))
5694 /* check the required size. */
5695 *needed += spoolss_size_printer_driver_info_6(&info);
5697 if (*needed > offered) {
5698 result = WERR_INSUFFICIENT_BUFFER;
5702 if (!rpcbuf_alloc_size(buffer, *needed)) {
5703 result = WERR_NOMEM;
5707 /* fill the buffer with the structures */
5708 smb_io_printer_driver_info_6("", buffer, &info, 0);
5711 free_printer_driver_info_6(&info);
5716 /****************************************************************************
5717 ****************************************************************************/
5719 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5721 POLICY_HND *handle = &q_u->handle;
5722 UNISTR2 *uni_arch = &q_u->architecture;
5723 uint32 level = q_u->level;
5724 uint32 clientmajorversion = q_u->clientmajorversion;
5725 RPC_BUFFER *buffer = NULL;
5726 uint32 offered = q_u->offered;
5727 uint32 *needed = &r_u->needed;
5728 uint32 *servermajorversion = &r_u->servermajorversion;
5729 uint32 *serverminorversion = &r_u->serverminorversion;
5730 Printer_entry *printer;
5733 fstring architecture;
5736 /* that's an [in out] buffer */
5738 if (!q_u->buffer && (offered!=0)) {
5739 return WERR_INVALID_PARAM;
5742 rpcbuf_move(q_u->buffer, &r_u->buffer);
5743 buffer = r_u->buffer;
5745 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5747 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5748 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5749 return WERR_INVALID_PRINTER_NAME;
5753 *servermajorversion = 0;
5754 *serverminorversion = 0;
5756 fstrcpy(servername, get_server_name( printer ));
5757 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5759 if (!get_printer_snum(p, handle, &snum, NULL))
5764 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5766 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5768 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5770 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5773 /* apparently this call is the equivalent of
5774 EnumPrinterDataEx() for the DsDriver key */
5779 return WERR_UNKNOWN_LEVEL;
5783 /****************************************************************
5784 _spoolss_StartPagePrinter
5785 ****************************************************************/
5787 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5788 struct spoolss_StartPagePrinter *r)
5790 POLICY_HND *handle = r->in.handle;
5792 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5795 DEBUG(3,("_spoolss_StartPagePrinter: "
5796 "Error in startpageprinter printer handle\n"));
5800 Printer->page_started=True;
5804 /****************************************************************
5805 _spoolss_EndPagePrinter
5806 ****************************************************************/
5808 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5809 struct spoolss_EndPagePrinter *r)
5811 POLICY_HND *handle = r->in.handle;
5814 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5817 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5818 OUR_HANDLE(handle)));
5822 if (!get_printer_snum(p, handle, &snum, NULL))
5825 Printer->page_started=False;
5826 print_job_endpage(snum, Printer->jobid);
5831 /********************************************************************
5832 * api_spoolss_getprinter
5833 * called from the spoolss dispatcher
5835 ********************************************************************/
5837 WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
5839 POLICY_HND *handle = &q_u->handle;
5840 DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
5841 uint32 *jobid = &r_u->jobid;
5842 TALLOC_CTX *ctx = p->mem_ctx;
5843 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
5845 char *jobname = NULL;
5847 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5850 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5855 * a nice thing with NT is it doesn't listen to what you tell it.
5856 * when asked to send _only_ RAW datas, it tries to send datas
5859 * So I add checks like in NT Server ...
5862 if (info_1->p_datatype != 0) {
5863 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
5864 if (strcmp(datatype, "RAW") != 0) {
5866 return WERR_INVALID_DATATYPE;
5870 /* get the share number of the printer */
5871 if (!get_printer_snum(p, handle, &snum, NULL)) {
5875 jobname = unistr2_to_ascii_talloc(ctx, &info_1->docname);
5877 Printer->jobid = print_job_start(p->server_info, snum, jobname,
5878 Printer->nt_devmode);
5880 /* An error occured in print_job_start() so return an appropriate
5883 if (Printer->jobid == -1) {
5884 return map_werror_from_unix(errno);
5887 Printer->document_started=True;
5888 (*jobid) = Printer->jobid;
5893 /****************************************************************
5894 _spoolss_EndDocPrinter
5895 ****************************************************************/
5897 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5898 struct spoolss_EndDocPrinter *r)
5900 POLICY_HND *handle = r->in.handle;
5902 return _spoolss_enddocprinter_internal(p, handle);
5905 /****************************************************************
5906 _spoolss_WritePrinter
5907 ****************************************************************/
5909 WERROR _spoolss_WritePrinter(pipes_struct *p,
5910 struct spoolss_WritePrinter *r)
5912 POLICY_HND *handle = r->in.handle;
5913 uint32 buffer_size = r->in._data_size;
5914 uint8 *buffer = r->in.data.data;
5915 uint32 *buffer_written = &r->in._data_size;
5917 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5920 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5921 OUR_HANDLE(handle)));
5922 *r->out.num_written = r->in._data_size;
5926 if (!get_printer_snum(p, handle, &snum, NULL))
5929 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5930 (SMB_OFF_T)-1, (size_t)buffer_size);
5931 if (*buffer_written == (uint32)-1) {
5932 *r->out.num_written = 0;
5933 if (errno == ENOSPC)
5934 return WERR_NO_SPOOL_SPACE;
5936 return WERR_ACCESS_DENIED;
5939 *r->out.num_written = r->in._data_size;
5944 /********************************************************************
5945 * api_spoolss_getprinter
5946 * called from the spoolss dispatcher
5948 ********************************************************************/
5950 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5954 WERROR errcode = WERR_BADFUNC;
5955 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5958 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5962 if (!get_printer_snum(p, handle, &snum, NULL))
5966 case PRINTER_CONTROL_PAUSE:
5967 if (print_queue_pause(p->server_info, snum, &errcode)) {
5971 case PRINTER_CONTROL_RESUME:
5972 case PRINTER_CONTROL_UNPAUSE:
5973 if (print_queue_resume(p->server_info, snum, &errcode)) {
5977 case PRINTER_CONTROL_PURGE:
5978 if (print_queue_purge(p->server_info, snum, &errcode)) {
5983 return WERR_UNKNOWN_LEVEL;
5990 /****************************************************************
5991 _spoolss_AbortPrinter
5992 * From MSDN: "Deletes printer's spool file if printer is configured
5994 ****************************************************************/
5996 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5997 struct spoolss_AbortPrinter *r)
5999 POLICY_HND *handle = r->in.handle;
6000 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6002 WERROR errcode = WERR_OK;
6005 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6006 OUR_HANDLE(handle)));
6010 if (!get_printer_snum(p, handle, &snum, NULL))
6013 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6018 /********************************************************************
6019 * called by spoolss_api_setprinter
6020 * when updating a printer description
6021 ********************************************************************/
6023 static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
6024 const SPOOL_PRINTER_INFO_LEVEL *info,
6025 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6027 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6031 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6033 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6034 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6035 OUR_HANDLE(handle)));
6037 result = WERR_BADFID;
6042 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6043 result = WERR_INVALID_PARAM;
6047 /* Check the user has permissions to change the security
6048 descriptor. By experimentation with two NT machines, the user
6049 requires Full Access to the printer to change security
6052 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6053 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6054 result = WERR_ACCESS_DENIED;
6058 /* NT seems to like setting the security descriptor even though
6059 nothing may have actually changed. */
6061 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6062 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6063 result = WERR_BADFID;
6067 if (DEBUGLEVEL >= 10) {
6071 the_acl = old_secdesc_ctr->sd->dacl;
6072 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6073 PRINTERNAME(snum), the_acl->num_aces));
6075 for (i = 0; i < the_acl->num_aces; i++) {
6076 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6077 &the_acl->aces[i].trustee),
6078 the_acl->aces[i].access_mask));
6081 the_acl = secdesc_ctr->sd->dacl;
6084 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6085 PRINTERNAME(snum), the_acl->num_aces));
6087 for (i = 0; i < the_acl->num_aces; i++) {
6088 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6089 &the_acl->aces[i].trustee),
6090 the_acl->aces[i].access_mask));
6093 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6097 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6098 if (!new_secdesc_ctr) {
6099 result = WERR_NOMEM;
6103 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6108 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6115 /********************************************************************
6116 Canonicalize printer info from a client
6118 ATTN: It does not matter what we set the servername to hear
6119 since we do the necessary work in get_a_printer() to set it to
6120 the correct value based on what the client sent in the
6121 _spoolss_open_printer_ex().
6122 ********************************************************************/
6124 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6126 fstring printername;
6129 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6130 "portname=%s drivername=%s comment=%s location=%s\n",
6131 info->servername, info->printername, info->sharename,
6132 info->portname, info->drivername, info->comment, info->location));
6134 /* we force some elements to "correct" values */
6135 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6136 fstrcpy(info->sharename, lp_servicename(snum));
6138 /* check to see if we allow printername != sharename */
6140 if ( lp_force_printername(snum) ) {
6141 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6142 global_myname(), info->sharename );
6145 /* make sure printername is in \\server\printername format */
6147 fstrcpy( printername, info->printername );
6149 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6150 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6154 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6155 global_myname(), p );
6158 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6159 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6166 /****************************************************************************
6167 ****************************************************************************/
6169 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6171 char *cmd = lp_addport_cmd();
6172 char *command = NULL;
6174 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6175 bool is_print_op = False;
6178 return WERR_ACCESS_DENIED;
6181 command = talloc_asprintf(ctx,
6182 "%s \"%s\" \"%s\"", cmd, portname, uri );
6188 is_print_op = user_has_privileges( token, &se_printop );
6190 DEBUG(10,("Running [%s]\n", command));
6192 /********* BEGIN SePrintOperatorPrivilege **********/
6197 ret = smbrun(command, NULL);
6202 /********* END SePrintOperatorPrivilege **********/
6204 DEBUGADD(10,("returned [%d]\n", ret));
6206 TALLOC_FREE(command);
6209 return WERR_ACCESS_DENIED;
6215 /****************************************************************************
6216 ****************************************************************************/
6218 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6220 char *cmd = lp_addprinter_cmd();
6222 char *command = NULL;
6226 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6227 bool is_print_op = False;
6228 char *remote_machine = talloc_strdup(ctx, "%m");
6230 if (!remote_machine) {
6233 remote_machine = talloc_sub_basic(ctx,
6234 current_user_info.smb_name,
6235 current_user_info.domain,
6237 if (!remote_machine) {
6241 command = talloc_asprintf(ctx,
6242 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6243 cmd, printer->info_2->printername, printer->info_2->sharename,
6244 printer->info_2->portname, printer->info_2->drivername,
6245 printer->info_2->location, printer->info_2->comment, remote_machine);
6251 is_print_op = user_has_privileges( token, &se_printop );
6253 DEBUG(10,("Running [%s]\n", command));
6255 /********* BEGIN SePrintOperatorPrivilege **********/
6260 if ( (ret = smbrun(command, &fd)) == 0 ) {
6261 /* Tell everyone we updated smb.conf. */
6262 message_send_all(smbd_messaging_context(),
6263 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6269 /********* END SePrintOperatorPrivilege **********/
6271 DEBUGADD(10,("returned [%d]\n", ret));
6273 TALLOC_FREE(command);
6274 TALLOC_FREE(remote_machine);
6282 /* reload our services immediately */
6283 reload_services( False );
6286 /* Get lines and convert them back to dos-codepage */
6287 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6288 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6291 /* Set the portname to what the script says the portname should be. */
6292 /* but don't require anything to be return from the script exit a good error code */
6295 /* Set the portname to what the script says the portname should be. */
6296 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6297 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6300 TALLOC_FREE(qlines);
6305 /********************************************************************
6306 * Called by spoolss_api_setprinter
6307 * when updating a printer description.
6308 ********************************************************************/
6310 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
6311 const SPOOL_PRINTER_INFO_LEVEL *info,
6312 DEVICEMODE *devmode)
6315 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6316 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6321 DEBUG(8,("update_printer\n"));
6326 result = WERR_BADFID;
6330 if (!get_printer_snum(p, handle, &snum, NULL)) {
6331 result = WERR_BADFID;
6335 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6336 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6337 result = WERR_BADFID;
6341 DEBUGADD(8,("Converting info_2 struct\n"));
6344 * convert_printer_info converts the incoming
6345 * info from the client and overwrites the info
6346 * just read from the tdb in the pointer 'printer'.
6349 if (!convert_printer_info(info, printer, level)) {
6350 result = WERR_NOMEM;
6355 /* we have a valid devmode
6356 convert it and link it*/
6358 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6359 if (!convert_devicemode(printer->info_2->printername, devmode,
6360 &printer->info_2->devmode)) {
6361 result = WERR_NOMEM;
6366 /* Do sanity check on the requested changes for Samba */
6368 if (!check_printer_ok(printer->info_2, snum)) {
6369 result = WERR_INVALID_PARAM;
6373 /* FIXME!!! If the driver has changed we really should verify that
6374 it is installed before doing much else --jerry */
6376 /* Check calling user has permission to update printer description */
6378 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6379 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6380 result = WERR_ACCESS_DENIED;
6384 /* Call addprinter hook */
6385 /* Check changes to see if this is really needed */
6387 if ( *lp_addprinter_cmd()
6388 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6389 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6390 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6391 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6393 /* add_printer_hook() will call reload_services() */
6395 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6397 result = WERR_ACCESS_DENIED;
6403 * When a *new* driver is bound to a printer, the drivername is used to
6404 * lookup previously saved driver initialization info, which is then
6405 * bound to the printer, simulating what happens in the Windows arch.
6407 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6409 if (!set_driver_init(printer, 2))
6411 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6412 printer->info_2->drivername));
6415 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6416 printer->info_2->drivername));
6418 notify_printer_driver(snum, printer->info_2->drivername);
6422 * flag which changes actually occured. This is a small subset of
6423 * all the possible changes. We also have to update things in the
6427 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6428 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6429 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6430 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6432 notify_printer_comment(snum, printer->info_2->comment);
6435 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6436 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6437 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6438 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6440 notify_printer_sharename(snum, printer->info_2->sharename);
6443 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6446 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6449 pname = printer->info_2->printername;
6452 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6453 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6454 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6456 notify_printer_printername( snum, pname );
6459 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6460 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6461 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6462 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6464 notify_printer_port(snum, printer->info_2->portname);
6467 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6468 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6469 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6470 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6472 notify_printer_location(snum, printer->info_2->location);
6475 /* here we need to update some more DsSpooler keys */
6476 /* uNCName, serverName, shortServerName */
6478 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6479 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6480 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6481 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6482 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6484 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6485 global_myname(), printer->info_2->sharename );
6486 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6487 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6488 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6490 /* Update printer info */
6491 result = mod_a_printer(printer, 2);
6494 free_a_printer(&printer, 2);
6495 free_a_printer(&old_printer, 2);
6501 /****************************************************************************
6502 ****************************************************************************/
6503 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6504 const SPOOL_PRINTER_INFO_LEVEL *info)
6507 SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
6509 Printer_entry *Printer;
6511 if ( lp_security() != SEC_ADS ) {
6512 return WERR_UNKNOWN_LEVEL;
6515 Printer = find_printer_index_by_hnd(p, handle);
6517 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6522 if (!get_printer_snum(p, handle, &snum, NULL))
6525 nt_printer_publish(Printer, snum, info7->action);
6529 return WERR_UNKNOWN_LEVEL;
6532 /****************************************************************************
6533 ****************************************************************************/
6535 WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
6537 POLICY_HND *handle = &q_u->handle;
6538 uint32 level = q_u->level;
6539 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
6540 DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
6541 SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
6542 uint32 command = q_u->command;
6545 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6548 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6552 /* check the level */
6555 return control_printer(handle, command, p);
6557 result = update_printer(p, handle, level, info, devmode_ctr.devmode);
6558 if (!W_ERROR_IS_OK(result))
6561 result = update_printer_sec(handle, level, info, p, secdesc_ctr);
6564 return update_printer_sec(handle, level, info, p,
6567 return publish_or_unpublish_printer(p, handle, info);
6569 return WERR_UNKNOWN_LEVEL;
6573 /****************************************************************************
6574 ****************************************************************************/
6576 WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u)
6578 POLICY_HND *handle = &q_u->handle;
6579 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6582 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6586 if (Printer->notify.client_connected==True) {
6589 if ( Printer->printer_type == SPLHND_SERVER)
6591 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6592 !get_printer_snum(p, handle, &snum, NULL) )
6595 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6598 Printer->notify.flags=0;
6599 Printer->notify.options=0;
6600 Printer->notify.localmachine[0]='\0';
6601 Printer->notify.printerlocal=0;
6602 if (Printer->notify.option)
6603 free_spool_notify_option(&Printer->notify.option);
6604 Printer->notify.client_connected=False;
6609 /****************************************************************************
6610 ****************************************************************************/
6612 WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
6614 /* that's an [in out] buffer */
6616 if (!q_u->buffer && (q_u->offered!=0)) {
6617 return WERR_INVALID_PARAM;
6620 rpcbuf_move(q_u->buffer, &r_u->buffer);
6623 return WERR_INVALID_PARAM; /* this is what a NT server
6624 returns for AddJob. AddJob
6625 must fail on non-local
6629 /****************************************************************************
6630 ****************************************************************************/
6632 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6633 int position, int snum,
6634 const NT_PRINTER_INFO_LEVEL *ntprinter)
6638 t=gmtime(&queue->time);
6640 job_info->jobid=queue->job;
6641 init_unistr(&job_info->printername, lp_servicename(snum));
6642 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6643 init_unistr(&job_info->username, queue->fs_user);
6644 init_unistr(&job_info->document, queue->fs_file);
6645 init_unistr(&job_info->datatype, "RAW");
6646 init_unistr(&job_info->text_status, "");
6647 job_info->status=nt_printj_status(queue->status);
6648 job_info->priority=queue->priority;
6649 job_info->position=position;
6650 job_info->totalpages=queue->page_count;
6651 job_info->pagesprinted=0;
6653 make_systemtime(&job_info->submitted, t);
6656 /****************************************************************************
6657 ****************************************************************************/
6659 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6660 int position, int snum,
6661 const NT_PRINTER_INFO_LEVEL *ntprinter,
6662 DEVICEMODE *devmode)
6666 t=gmtime(&queue->time);
6668 job_info->jobid=queue->job;
6670 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6672 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6673 init_unistr(&job_info->username, queue->fs_user);
6674 init_unistr(&job_info->document, queue->fs_file);
6675 init_unistr(&job_info->notifyname, queue->fs_user);
6676 init_unistr(&job_info->datatype, "RAW");
6677 init_unistr(&job_info->printprocessor, "winprint");
6678 init_unistr(&job_info->parameters, "");
6679 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6680 init_unistr(&job_info->text_status, "");
6682 /* and here the security descriptor */
6684 job_info->status=nt_printj_status(queue->status);
6685 job_info->priority=queue->priority;
6686 job_info->position=position;
6687 job_info->starttime=0;
6688 job_info->untiltime=0;
6689 job_info->totalpages=queue->page_count;
6690 job_info->size=queue->size;
6691 make_systemtime(&(job_info->submitted), t);
6692 job_info->timeelapsed=0;
6693 job_info->pagesprinted=0;
6695 job_info->devmode = devmode;
6700 /****************************************************************************
6701 Enumjobs at level 1.
6702 ****************************************************************************/
6704 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6705 const NT_PRINTER_INFO_LEVEL *ntprinter,
6706 RPC_BUFFER *buffer, uint32 offered,
6707 uint32 *needed, uint32 *returned)
6711 WERROR result = WERR_OK;
6713 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6719 for (i=0; i<*returned; i++)
6720 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6722 /* check the required size. */
6723 for (i=0; i<*returned; i++)
6724 (*needed) += spoolss_size_job_info_1(&info[i]);
6726 if (*needed > offered) {
6727 result = WERR_INSUFFICIENT_BUFFER;
6731 if (!rpcbuf_alloc_size(buffer, *needed)) {
6732 result = WERR_NOMEM;
6736 /* fill the buffer with the structures */
6737 for (i=0; i<*returned; i++)
6738 smb_io_job_info_1("", buffer, &info[i], 0);
6744 if ( !W_ERROR_IS_OK(result) )
6750 /****************************************************************************
6751 Enumjobs at level 2.
6752 ****************************************************************************/
6754 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6755 const NT_PRINTER_INFO_LEVEL *ntprinter,
6756 RPC_BUFFER *buffer, uint32 offered,
6757 uint32 *needed, uint32 *returned)
6759 JOB_INFO_2 *info = NULL;
6761 WERROR result = WERR_OK;
6762 DEVICEMODE *devmode = NULL;
6764 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6769 /* this should not be a failure condition if the devmode is NULL */
6771 devmode = construct_dev_mode(lp_const_servicename(snum));
6773 for (i=0; i<*returned; i++)
6774 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6776 /* check the required size. */
6777 for (i=0; i<*returned; i++)
6778 (*needed) += spoolss_size_job_info_2(&info[i]);
6780 if (*needed > offered) {
6781 result = WERR_INSUFFICIENT_BUFFER;
6785 if (!rpcbuf_alloc_size(buffer, *needed)) {
6786 result = WERR_NOMEM;
6790 /* fill the buffer with the structures */
6791 for (i=0; i<*returned; i++)
6792 smb_io_job_info_2("", buffer, &info[i], 0);
6795 free_devmode(devmode);
6798 if ( !W_ERROR_IS_OK(result) )
6805 /****************************************************************************
6807 ****************************************************************************/
6809 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6811 POLICY_HND *handle = &q_u->handle;
6812 uint32 level = q_u->level;
6813 RPC_BUFFER *buffer = NULL;
6814 uint32 offered = q_u->offered;
6815 uint32 *needed = &r_u->needed;
6816 uint32 *returned = &r_u->returned;
6818 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6820 print_status_struct prt_status;
6821 print_queue_struct *queue=NULL;
6823 /* that's an [in out] buffer */
6825 if (!q_u->buffer && (offered!=0)) {
6826 return WERR_INVALID_PARAM;
6829 rpcbuf_move(q_u->buffer, &r_u->buffer);
6830 buffer = r_u->buffer;
6832 DEBUG(4,("_spoolss_enumjobs\n"));
6837 /* lookup the printer snum and tdb entry */
6839 if (!get_printer_snum(p, handle, &snum, NULL))
6842 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6843 if ( !W_ERROR_IS_OK(wret) )
6846 *returned = print_queue_status(snum, &queue, &prt_status);
6847 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6849 if (*returned == 0) {
6851 free_a_printer(&ntprinter, 2);
6857 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6860 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6864 wret = WERR_UNKNOWN_LEVEL;
6869 free_a_printer( &ntprinter, 2 );
6873 /****************************************************************************
6874 ****************************************************************************/
6876 WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u)
6881 /****************************************************************************
6882 ****************************************************************************/
6884 WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
6886 POLICY_HND *handle = &q_u->handle;
6887 uint32 jobid = q_u->jobid;
6888 uint32 command = q_u->command;
6891 WERROR errcode = WERR_BADFUNC;
6893 if (!get_printer_snum(p, handle, &snum, NULL)) {
6897 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6898 return WERR_INVALID_PRINTER_NAME;
6902 case JOB_CONTROL_CANCEL:
6903 case JOB_CONTROL_DELETE:
6904 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6908 case JOB_CONTROL_PAUSE:
6909 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6913 case JOB_CONTROL_RESTART:
6914 case JOB_CONTROL_RESUME:
6915 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6920 return WERR_UNKNOWN_LEVEL;
6926 /****************************************************************************
6927 Enumerates all printer drivers at level 1.
6928 ****************************************************************************/
6930 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6935 fstring *list = NULL;
6936 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6937 DRIVER_INFO_1 *driver_info_1=NULL;
6938 WERROR result = WERR_OK;
6942 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6944 ndrivers=get_ntdrivers(&list, architecture, version);
6945 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6947 if(ndrivers == -1) {
6948 SAFE_FREE(driver_info_1);
6953 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6954 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6960 for (i=0; i<ndrivers; i++) {
6962 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6963 ZERO_STRUCT(driver);
6964 status = get_a_printer_driver(&driver, 3, list[i],
6965 architecture, version);
6966 if (!W_ERROR_IS_OK(status)) {
6968 SAFE_FREE(driver_info_1);
6971 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6972 free_a_printer_driver(driver, 3);
6975 *returned+=ndrivers;
6979 /* check the required size. */
6980 for (i=0; i<*returned; i++) {
6981 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6982 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6985 if (*needed > offered) {
6986 result = WERR_INSUFFICIENT_BUFFER;
6990 if (!rpcbuf_alloc_size(buffer, *needed)) {
6991 result = WERR_NOMEM;
6995 /* fill the buffer with the driver structures */
6996 for (i=0; i<*returned; i++) {
6997 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
6998 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
7002 SAFE_FREE(driver_info_1);
7004 if ( !W_ERROR_IS_OK(result) )
7010 /****************************************************************************
7011 Enumerates all printer drivers at level 2.
7012 ****************************************************************************/
7014 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7019 fstring *list = NULL;
7020 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7021 DRIVER_INFO_2 *driver_info_2=NULL;
7022 WERROR result = WERR_OK;
7026 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7028 ndrivers=get_ntdrivers(&list, architecture, version);
7029 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7031 if(ndrivers == -1) {
7032 SAFE_FREE(driver_info_2);
7037 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7038 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7044 for (i=0; i<ndrivers; i++) {
7047 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7048 ZERO_STRUCT(driver);
7049 status = get_a_printer_driver(&driver, 3, list[i],
7050 architecture, version);
7051 if (!W_ERROR_IS_OK(status)) {
7053 SAFE_FREE(driver_info_2);
7056 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7057 free_a_printer_driver(driver, 3);
7060 *returned+=ndrivers;
7064 /* check the required size. */
7065 for (i=0; i<*returned; i++) {
7066 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7067 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7070 if (*needed > offered) {
7071 result = WERR_INSUFFICIENT_BUFFER;
7075 if (!rpcbuf_alloc_size(buffer, *needed)) {
7076 result = WERR_NOMEM;
7080 /* fill the buffer with the form structures */
7081 for (i=0; i<*returned; i++) {
7082 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7083 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7087 SAFE_FREE(driver_info_2);
7089 if ( !W_ERROR_IS_OK(result) )
7095 /****************************************************************************
7096 Enumerates all printer drivers at level 3.
7097 ****************************************************************************/
7099 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7104 fstring *list = NULL;
7105 DRIVER_INFO_3 *driver_info_3=NULL;
7106 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7107 WERROR result = WERR_OK;
7111 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7113 ndrivers=get_ntdrivers(&list, architecture, version);
7114 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7116 if(ndrivers == -1) {
7117 SAFE_FREE(driver_info_3);
7122 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7123 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7129 for (i=0; i<ndrivers; i++) {
7132 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7133 ZERO_STRUCT(driver);
7134 status = get_a_printer_driver(&driver, 3, list[i],
7135 architecture, version);
7136 if (!W_ERROR_IS_OK(status)) {
7138 SAFE_FREE(driver_info_3);
7141 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7142 free_a_printer_driver(driver, 3);
7145 *returned+=ndrivers;
7149 /* check the required size. */
7150 for (i=0; i<*returned; i++) {
7151 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7152 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7155 if (*needed > offered) {
7156 result = WERR_INSUFFICIENT_BUFFER;
7160 if (!rpcbuf_alloc_size(buffer, *needed)) {
7161 result = WERR_NOMEM;
7165 /* fill the buffer with the driver structures */
7166 for (i=0; i<*returned; i++) {
7167 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7168 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7172 for (i=0; i<*returned; i++) {
7173 SAFE_FREE(driver_info_3[i].dependentfiles);
7176 SAFE_FREE(driver_info_3);
7178 if ( !W_ERROR_IS_OK(result) )
7184 /****************************************************************************
7185 Enumerates all printer drivers.
7186 ****************************************************************************/
7188 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7190 uint32 level = q_u->level;
7191 RPC_BUFFER *buffer = NULL;
7192 uint32 offered = q_u->offered;
7193 uint32 *needed = &r_u->needed;
7194 uint32 *returned = &r_u->returned;
7195 const char *cservername;
7197 fstring architecture;
7199 /* that's an [in out] buffer */
7201 if (!q_u->buffer && (offered!=0)) {
7202 return WERR_INVALID_PARAM;
7205 rpcbuf_move(q_u->buffer, &r_u->buffer);
7206 buffer = r_u->buffer;
7208 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7213 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7214 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7216 cservername = canon_servername(servername);
7218 if (!is_myname_or_ipaddr(cservername))
7219 return WERR_UNKNOWN_PRINTER_DRIVER;
7223 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7225 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7227 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7229 return WERR_UNKNOWN_LEVEL;
7233 /****************************************************************************
7234 ****************************************************************************/
7236 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7238 form->flag=list->flag;
7239 init_unistr(&form->name, list->name);
7240 form->width=list->width;
7241 form->length=list->length;
7242 form->left=list->left;
7243 form->top=list->top;
7244 form->right=list->right;
7245 form->bottom=list->bottom;
7248 /****************************************************************************
7249 ****************************************************************************/
7251 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7252 struct spoolss_FormInfo1 *form,
7253 nt_forms_struct *list)
7255 form->form_name = talloc_strdup(mem_ctx, list->name);
7256 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7258 form->flags = list->flag;
7259 form->size.width = list->width;
7260 form->size.height = list->length;
7261 form->area.left = list->left;
7262 form->area.top = list->top;
7263 form->area.right = list->right;
7264 form->area.bottom = list->bottom;
7269 /****************************************************************************
7270 ****************************************************************************/
7272 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7274 uint32 level = q_u->level;
7275 RPC_BUFFER *buffer = NULL;
7276 uint32 offered = q_u->offered;
7277 uint32 *needed = &r_u->needed;
7278 uint32 *numofforms = &r_u->numofforms;
7279 uint32 numbuiltinforms;
7281 nt_forms_struct *list=NULL;
7282 nt_forms_struct *builtinlist=NULL;
7287 /* that's an [in out] buffer */
7289 if (!q_u->buffer && (offered!=0) ) {
7290 return WERR_INVALID_PARAM;
7293 rpcbuf_move(q_u->buffer, &r_u->buffer);
7294 buffer = r_u->buffer;
7296 DEBUG(4,("_spoolss_enumforms\n"));
7297 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7298 DEBUGADD(5,("Info level [%d]\n", level));
7300 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7301 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7302 *numofforms = get_ntforms(&list);
7303 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7304 *numofforms += numbuiltinforms;
7306 if (*numofforms == 0) {
7307 SAFE_FREE(builtinlist);
7309 return WERR_NO_MORE_ITEMS;
7314 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7315 SAFE_FREE(builtinlist);
7321 /* construct the list of form structures */
7322 for (i=0; i<numbuiltinforms; i++) {
7323 DEBUGADD(6,("Filling form number [%d]\n",i));
7324 fill_form_1(&forms_1[i], &builtinlist[i]);
7327 SAFE_FREE(builtinlist);
7329 for (; i<*numofforms; i++) {
7330 DEBUGADD(6,("Filling form number [%d]\n",i));
7331 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7336 /* check the required size. */
7337 for (i=0; i<numbuiltinforms; i++) {
7338 DEBUGADD(6,("adding form [%d]'s size\n",i));
7339 buffer_size += spoolss_size_form_1(&forms_1[i]);
7341 for (; i<*numofforms; i++) {
7342 DEBUGADD(6,("adding form [%d]'s size\n",i));
7343 buffer_size += spoolss_size_form_1(&forms_1[i]);
7346 *needed=buffer_size;
7348 if (*needed > offered) {
7351 return WERR_INSUFFICIENT_BUFFER;
7354 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7360 /* fill the buffer with the form structures */
7361 for (i=0; i<numbuiltinforms; i++) {
7362 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7363 smb_io_form_1("", buffer, &forms_1[i], 0);
7365 for (; i<*numofforms; i++) {
7366 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7367 smb_io_form_1("", buffer, &forms_1[i], 0);
7376 SAFE_FREE(builtinlist);
7377 return WERR_UNKNOWN_LEVEL;
7381 /****************************************************************
7383 ****************************************************************/
7385 WERROR _spoolss_GetForm(pipes_struct *p,
7386 struct spoolss_GetForm *r)
7388 uint32 level = r->in.level;
7389 uint32 offered = r->in.offered;
7390 uint32 *needed = r->out.needed;
7392 nt_forms_struct *list=NULL;
7393 nt_forms_struct builtin_form;
7395 union spoolss_FormInfo info;
7396 struct spoolss_FormInfo1 form_1;
7397 int numofforms=0, i=0;
7399 /* that's an [in out] buffer */
7401 if (!r->in.buffer && (offered!=0)) {
7402 return WERR_INVALID_PARAM;
7405 DEBUG(4,("_spoolss_GetForm\n"));
7406 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7407 DEBUGADD(5,("Info level [%d]\n", level));
7409 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7410 if (!foundBuiltin) {
7411 numofforms = get_ntforms(&list);
7412 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7414 if (numofforms == 0)
7421 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7424 /* Check if the requested name is in the list of form structures */
7425 for (i=0; i<numofforms; i++) {
7427 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7428 list[i].name, r->in.form_name));
7430 if (strequal(r->in.form_name, list[i].name)) {
7431 DEBUGADD(6,("Found form %s number [%d]\n",
7432 r->in.form_name, i));
7433 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7439 if (i == numofforms) {
7443 /* check the required size. */
7445 info.info1 = form_1;
7447 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7449 if (*needed > offered) {
7451 return WERR_INSUFFICIENT_BUFFER;
7454 r->out.info->info1 = form_1;
7456 /* fill the buffer with the form structures */
7457 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7458 r->in.form_name, i));
7464 return WERR_UNKNOWN_LEVEL;
7468 /****************************************************************************
7469 ****************************************************************************/
7471 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7473 init_unistr(&port->port_name, name);
7476 /****************************************************************************
7477 TODO: This probably needs distinguish between TCP/IP and Local ports
7479 ****************************************************************************/
7481 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7483 init_unistr(&port->port_name, name);
7484 init_unistr(&port->monitor_name, "Local Monitor");
7485 init_unistr(&port->description, SPL_LOCAL_PORT );
7486 port->port_type=PORT_TYPE_WRITE;
7491 /****************************************************************************
7492 wrapper around the enumer ports command
7493 ****************************************************************************/
7495 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7497 char *cmd = lp_enumports_cmd();
7498 char **qlines = NULL;
7499 char *command = NULL;
7507 /* if no hook then just fill in the default port */
7510 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7513 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7514 TALLOC_FREE(qlines);
7521 /* we have a valid enumport command */
7523 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7528 DEBUG(10,("Running [%s]\n", command));
7529 ret = smbrun(command, &fd);
7530 DEBUG(10,("Returned [%d]\n", ret));
7531 TALLOC_FREE(command);
7536 return WERR_ACCESS_DENIED;
7540 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7541 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7551 /****************************************************************************
7553 ****************************************************************************/
7555 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7557 PORT_INFO_1 *ports=NULL;
7559 WERROR result = WERR_OK;
7560 char **qlines = NULL;
7563 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7564 if (!W_ERROR_IS_OK(result)) {
7565 TALLOC_FREE(qlines);
7570 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7571 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7572 win_errstr(WERR_NOMEM)));
7573 TALLOC_FREE(qlines);
7577 for (i=0; i<numlines; i++) {
7578 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7579 fill_port_1(&ports[i], qlines[i]);
7582 TALLOC_FREE(qlines);
7584 *returned = numlines;
7586 /* check the required size. */
7587 for (i=0; i<*returned; i++) {
7588 DEBUGADD(6,("adding port [%d]'s size\n", i));
7589 *needed += spoolss_size_port_info_1(&ports[i]);
7592 if (*needed > offered) {
7593 result = WERR_INSUFFICIENT_BUFFER;
7597 if (!rpcbuf_alloc_size(buffer, *needed)) {
7598 result = WERR_NOMEM;
7602 /* fill the buffer with the ports structures */
7603 for (i=0; i<*returned; i++) {
7604 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7605 smb_io_port_1("", buffer, &ports[i], 0);
7611 if ( !W_ERROR_IS_OK(result) )
7617 /****************************************************************************
7619 ****************************************************************************/
7621 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7623 PORT_INFO_2 *ports=NULL;
7625 WERROR result = WERR_OK;
7626 char **qlines = NULL;
7629 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7630 if ( !W_ERROR_IS_OK(result)) {
7631 TALLOC_FREE(qlines);
7636 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7637 TALLOC_FREE(qlines);
7641 for (i=0; i<numlines; i++) {
7642 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7643 fill_port_2(&(ports[i]), qlines[i]);
7647 TALLOC_FREE(qlines);
7649 *returned = numlines;
7651 /* check the required size. */
7652 for (i=0; i<*returned; i++) {
7653 DEBUGADD(6,("adding port [%d]'s size\n", i));
7654 *needed += spoolss_size_port_info_2(&ports[i]);
7657 if (*needed > offered) {
7658 result = WERR_INSUFFICIENT_BUFFER;
7662 if (!rpcbuf_alloc_size(buffer, *needed)) {
7663 result = WERR_NOMEM;
7667 /* fill the buffer with the ports structures */
7668 for (i=0; i<*returned; i++) {
7669 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7670 smb_io_port_2("", buffer, &ports[i], 0);
7676 if ( !W_ERROR_IS_OK(result) )
7682 /****************************************************************************
7684 ****************************************************************************/
7686 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7688 uint32 level = q_u->level;
7689 RPC_BUFFER *buffer = NULL;
7690 uint32 offered = q_u->offered;
7691 uint32 *needed = &r_u->needed;
7692 uint32 *returned = &r_u->returned;
7694 /* that's an [in out] buffer */
7696 if (!q_u->buffer && (offered!=0)) {
7697 return WERR_INVALID_PARAM;
7700 rpcbuf_move(q_u->buffer, &r_u->buffer);
7701 buffer = r_u->buffer;
7703 DEBUG(4,("_spoolss_enumports\n"));
7710 return enumports_level_1(buffer, offered, needed, returned);
7712 return enumports_level_2(buffer, offered, needed, returned);
7714 return WERR_UNKNOWN_LEVEL;
7718 /****************************************************************************
7719 ****************************************************************************/
7721 static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
7722 const SPOOL_PRINTER_INFO_LEVEL *info,
7723 DEVICEMODE *devmode, SEC_DESC_BUF *sec_desc_buf,
7724 uint32 user_switch, const SPOOL_USER_CTR *user,
7727 NT_PRINTER_INFO_LEVEL *printer = NULL;
7730 WERROR err = WERR_OK;
7732 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7733 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7737 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7738 if (!convert_printer_info(info, printer, 2)) {
7739 free_a_printer(&printer, 2);
7743 /* check to see if the printer already exists */
7745 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7746 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7747 printer->info_2->sharename));
7748 free_a_printer(&printer, 2);
7749 return WERR_PRINTER_ALREADY_EXISTS;
7752 /* FIXME!!! smbd should check to see if the driver is installed before
7753 trying to add a printer like this --jerry */
7755 if (*lp_addprinter_cmd() ) {
7756 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7758 free_a_printer(&printer,2);
7759 return WERR_ACCESS_DENIED;
7762 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7763 "smb.conf parameter \"addprinter command\" is defined. This"
7764 "parameter must exist for this call to succeed\n",
7765 printer->info_2->sharename ));
7768 /* use our primary netbios name since get_a_printer() will convert
7769 it to what the client expects on a case by case basis */
7771 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7772 printer->info_2->sharename);
7775 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7776 free_a_printer(&printer,2);
7777 return WERR_ACCESS_DENIED;
7780 /* you must be a printer admin to add a new printer */
7781 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7782 free_a_printer(&printer,2);
7783 return WERR_ACCESS_DENIED;
7787 * Do sanity check on the requested changes for Samba.
7790 if (!check_printer_ok(printer->info_2, snum)) {
7791 free_a_printer(&printer,2);
7792 return WERR_INVALID_PARAM;
7796 * When a printer is created, the drivername bound to the printer is used
7797 * to lookup previously saved driver initialization info, which is then
7798 * bound to the new printer, simulating what happens in the Windows arch.
7803 set_driver_init(printer, 2);
7807 /* A valid devmode was included, convert and link it
7809 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7811 if (!convert_devicemode(printer->info_2->printername, devmode,
7812 &printer->info_2->devmode))
7816 /* write the ASCII on disk */
7817 err = mod_a_printer(printer, 2);
7818 if (!W_ERROR_IS_OK(err)) {
7819 free_a_printer(&printer,2);
7823 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7824 /* Handle open failed - remove addition. */
7825 del_a_printer(printer->info_2->sharename);
7826 free_a_printer(&printer,2);
7827 return WERR_ACCESS_DENIED;
7830 update_c_setprinter(False);
7831 free_a_printer(&printer,2);
7836 /****************************************************************************
7837 ****************************************************************************/
7839 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
7841 UNISTR2 *uni_srv_name = q_u->server_name;
7842 uint32 level = q_u->level;
7843 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
7844 DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
7845 SEC_DESC_BUF *sdb = q_u->secdesc_ctr;
7846 uint32 user_switch = q_u->user_switch;
7847 SPOOL_USER_CTR *user = &q_u->user_ctr;
7848 POLICY_HND *handle = &r_u->handle;
7852 /* we don't handle yet */
7853 /* but I know what to do ... */
7854 return WERR_UNKNOWN_LEVEL;
7856 return spoolss_addprinterex_level_2(p, uni_srv_name, info,
7858 user_switch, user, handle);
7860 return WERR_UNKNOWN_LEVEL;
7864 /****************************************************************************
7865 ****************************************************************************/
7867 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
7869 uint32 level = q_u->level;
7870 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
7871 WERROR err = WERR_OK;
7872 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7873 fstring driver_name;
7876 ZERO_STRUCT(driver);
7878 if (!convert_printer_driver_info(info, &driver, level)) {
7883 DEBUG(5,("Cleaning driver's information\n"));
7884 err = clean_up_driver_struct(p, driver, level);
7885 if (!W_ERROR_IS_OK(err))
7888 DEBUG(5,("Moving driver to final destination\n"));
7889 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7894 if (add_a_printer_driver(driver, level)!=0) {
7895 err = WERR_ACCESS_DENIED;
7901 fstrcpy(driver_name,
7902 driver.info_3->name ? driver.info_3->name : "");
7905 fstrcpy(driver_name,
7906 driver.info_6->name ? driver.info_6->name : "");
7911 * I think this is where he DrvUpgradePrinter() hook would be
7912 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7913 * server. Right now, we just need to send ourselves a message
7914 * to update each printer bound to this driver. --jerry
7917 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7918 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7923 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7924 * decide if the driver init data should be deleted. The rules are:
7925 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7926 * 2) delete init data only if there is no 2k/Xp driver
7927 * 3) always delete init data
7928 * The generalized rule is always use init data from the highest order driver.
7929 * It is necessary to follow the driver install by an initialization step to
7930 * finish off this process.
7933 version = driver.info_3->cversion;
7934 else if (level == 6)
7935 version = driver.info_6->version;
7940 * 9x printer driver - never delete init data
7943 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7948 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7949 * there is no 2k/Xp driver init data for this driver name.
7953 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7955 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7957 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7959 if (!del_driver_init(driver_name))
7960 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
7963 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7965 free_a_printer_driver(driver1,3);
7966 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
7973 * 2k or Xp printer driver - always delete init data
7976 if (!del_driver_init(driver_name))
7977 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
7981 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
7987 free_a_printer_driver(driver, level);
7991 /********************************************************************
7992 * spoolss_addprinterdriverex
7993 ********************************************************************/
7995 WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
7997 SPOOL_Q_ADDPRINTERDRIVER q_u_local;
7998 SPOOL_R_ADDPRINTERDRIVER r_u_local;
8001 * we only support the semantics of AddPrinterDriver()
8002 * i.e. only copy files that are newer than existing ones
8005 if ( q_u->copy_flags != APD_COPY_NEW_FILES )
8006 return WERR_ACCESS_DENIED;
8008 ZERO_STRUCT(q_u_local);
8009 ZERO_STRUCT(r_u_local);
8011 /* just pass the information off to _spoolss_addprinterdriver() */
8012 q_u_local.server_name_ptr = q_u->server_name_ptr;
8013 copy_unistr2(&q_u_local.server_name, &q_u->server_name);
8014 q_u_local.level = q_u->level;
8015 memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
8017 return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
8020 /****************************************************************************
8021 ****************************************************************************/
8023 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
8025 init_unistr(&info->name, name);
8028 /****************************************************************************
8029 ****************************************************************************/
8031 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
8034 char *long_archi = NULL;
8035 char *servername = NULL;
8036 const char *pservername = NULL;
8037 const char *short_archi;
8038 DRIVER_DIRECTORY_1 *info=NULL;
8039 WERROR result = WERR_OK;
8040 TALLOC_CTX *ctx = talloc_tos();
8042 servername = unistr2_to_ascii_talloc(ctx, name);
8046 long_archi = unistr2_to_ascii_talloc(ctx, uni_environment);
8051 pservername = canon_servername(servername);
8053 if ( !is_myname_or_ipaddr(pservername))
8054 return WERR_INVALID_PARAM;
8056 if (!(short_archi = get_short_archi(long_archi)))
8057 return WERR_INVALID_ENVIRONMENT;
8059 if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
8062 path = talloc_asprintf(ctx,
8063 "\\\\%s\\print$\\%s", pservername, short_archi);
8065 result = WERR_NOMEM;
8069 DEBUG(4,("printer driver directory: [%s]\n", path));
8071 fill_driverdir_1(info, path);
8073 *needed += spoolss_size_driverdir_info_1(info);
8075 if (*needed > offered) {
8076 result = WERR_INSUFFICIENT_BUFFER;
8080 if (!rpcbuf_alloc_size(buffer, *needed)) {
8081 result = WERR_NOMEM;
8085 smb_io_driverdir_1("", buffer, info, 0);
8093 /****************************************************************************
8094 ****************************************************************************/
8096 WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
8098 UNISTR2 *name = &q_u->name;
8099 UNISTR2 *uni_environment = &q_u->environment;
8100 uint32 level = q_u->level;
8101 RPC_BUFFER *buffer = NULL;
8102 uint32 offered = q_u->offered;
8103 uint32 *needed = &r_u->needed;
8105 /* that's an [in out] buffer */
8107 if (!q_u->buffer && (offered!=0)) {
8108 return WERR_INVALID_PARAM;
8111 rpcbuf_move(q_u->buffer, &r_u->buffer);
8112 buffer = r_u->buffer;
8114 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8120 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
8122 return WERR_UNKNOWN_LEVEL;
8126 /****************************************************************************
8127 ****************************************************************************/
8129 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8131 POLICY_HND *handle = &q_u->handle;
8132 uint32 idx = q_u->index;
8133 uint32 in_value_len = q_u->valuesize;
8134 uint32 in_data_len = q_u->datasize;
8135 uint32 *out_max_value_len = &r_u->valuesize;
8136 uint16 **out_value = &r_u->value;
8137 uint32 *out_value_len = &r_u->realvaluesize;
8138 uint32 *out_type = &r_u->type;
8139 uint32 *out_max_data_len = &r_u->datasize;
8140 uint8 **data_out = &r_u->data;
8141 uint32 *out_data_len = &r_u->realdatasize;
8143 NT_PRINTER_INFO_LEVEL *printer = NULL;
8145 uint32 biggest_valuesize;
8146 uint32 biggest_datasize;
8148 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8151 REGISTRY_VALUE *val = NULL;
8152 NT_PRINTER_DATA *p_data;
8153 int i, key_index, num_values;
8158 *out_max_data_len = 0;
8162 DEBUG(5,("spoolss_enumprinterdata\n"));
8165 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8169 if (!get_printer_snum(p,handle, &snum, NULL))
8172 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8173 if (!W_ERROR_IS_OK(result))
8176 p_data = printer->info_2->data;
8177 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8182 * The NT machine wants to know the biggest size of value and data
8184 * cf: MSDN EnumPrinterData remark section
8187 if ( !in_value_len && !in_data_len && (key_index != -1) )
8189 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8191 biggest_valuesize = 0;
8192 biggest_datasize = 0;
8194 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8196 for ( i=0; i<num_values; i++ )
8198 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8200 name_length = strlen(val->valuename);
8201 if ( strlen(val->valuename) > biggest_valuesize )
8202 biggest_valuesize = name_length;
8204 if ( val->size > biggest_datasize )
8205 biggest_datasize = val->size;
8207 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8211 /* the value is an UNICODE string but real_value_size is the length
8212 in bytes including the trailing 0 */
8214 *out_value_len = 2 * (1+biggest_valuesize);
8215 *out_data_len = biggest_datasize;
8217 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8223 * the value len is wrong in NT sp3
8224 * that's the number of bytes not the number of unicode chars
8227 if ( key_index != -1 )
8228 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8233 /* out_value should default to "" or else NT4 has
8234 problems unmarshalling the response */
8236 *out_max_value_len=(in_value_len/sizeof(uint16));
8239 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8241 result = WERR_NOMEM;
8244 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8250 /* the data is counted in bytes */
8252 *out_max_data_len = in_data_len;
8253 *out_data_len = in_data_len;
8255 /* only allocate when given a non-zero data_len */
8257 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8259 result = WERR_NOMEM;
8263 result = WERR_NO_MORE_ITEMS;
8269 * - counted in bytes in the request
8270 * - counted in UNICODE chars in the max reply
8271 * - counted in bytes in the real size
8273 * take a pause *before* coding not *during* coding
8277 *out_max_value_len=(in_value_len/sizeof(uint16));
8279 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8281 result = WERR_NOMEM;
8285 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8293 *out_type = regval_type( val );
8295 /* data - counted in bytes */
8297 *out_max_data_len = in_data_len;
8298 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8300 result = WERR_NOMEM;
8303 data_len = regval_size(val);
8304 if ( *data_out && data_len )
8305 memcpy( *data_out, regval_data_p(val), data_len );
8306 *out_data_len = data_len;
8310 free_a_printer(&printer, 2);
8314 /****************************************************************************
8315 ****************************************************************************/
8317 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8319 POLICY_HND *handle = &q_u->handle;
8320 UNISTR2 *value = &q_u->value;
8321 uint32 type = q_u->type;
8322 uint8 *data = q_u->data;
8323 uint32 real_len = q_u->real_len;
8325 NT_PRINTER_INFO_LEVEL *printer = NULL;
8327 WERROR status = WERR_OK;
8328 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8331 DEBUG(5,("spoolss_setprinterdata\n"));
8334 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8338 if ( Printer->printer_type == SPLHND_SERVER ) {
8339 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8340 return WERR_INVALID_PARAM;
8343 if (!get_printer_snum(p,handle, &snum, NULL))
8347 * Access check : NT returns "access denied" if you make a
8348 * SetPrinterData call without the necessary privildge.
8349 * we were originally returning OK if nothing changed
8350 * which made Win2k issue **a lot** of SetPrinterData
8351 * when connecting to a printer --jerry
8354 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8356 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8357 status = WERR_ACCESS_DENIED;
8361 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8362 if (!W_ERROR_IS_OK(status))
8365 unistr2_to_ascii(valuename, value, sizeof(valuename));
8368 * When client side code sets a magic printer data key, detect it and save
8369 * the current printer data and the magic key's data (its the DEVMODE) for
8370 * future printer/driver initializations.
8372 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8374 /* Set devmode and printer initialization info */
8375 status = save_driver_init( printer, 2, data, real_len );
8377 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8381 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8382 type, data, real_len );
8383 if ( W_ERROR_IS_OK(status) )
8384 status = mod_a_printer(printer, 2);
8388 free_a_printer(&printer, 2);
8393 /****************************************************************************
8394 ****************************************************************************/
8396 WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
8398 POLICY_HND *handle = &q_u->handle;
8399 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8402 DEBUG(5,("_spoolss_resetprinter\n"));
8405 * All we do is to check to see if the handle and queue is valid.
8406 * This call really doesn't mean anything to us because we only
8407 * support RAW printing. --jerry
8411 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8415 if (!get_printer_snum(p,handle, &snum, NULL))
8419 /* blindly return success */
8423 /****************************************************************
8424 _spoolss_DeletePrinterData
8425 ****************************************************************/
8427 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8428 struct spoolss_DeletePrinterData *r)
8430 POLICY_HND *handle = r->in.handle;
8431 NT_PRINTER_INFO_LEVEL *printer = NULL;
8433 WERROR status = WERR_OK;
8434 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8436 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8439 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8440 OUR_HANDLE(handle)));
8444 if (!get_printer_snum(p, handle, &snum, NULL))
8447 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8448 DEBUG(3, ("_spoolss_DeletePrinterData: "
8449 "printer properties change denied by handle\n"));
8450 return WERR_ACCESS_DENIED;
8453 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8454 if (!W_ERROR_IS_OK(status))
8457 if (!r->in.value_name) {
8458 free_a_printer(&printer, 2);
8462 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8465 if ( W_ERROR_IS_OK(status) )
8466 mod_a_printer( printer, 2 );
8468 free_a_printer(&printer, 2);
8473 /****************************************************************
8475 ****************************************************************/
8477 WERROR _spoolss_AddForm(pipes_struct *p,
8478 struct spoolss_AddForm *r)
8480 POLICY_HND *handle = r->in.handle;
8481 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8482 nt_forms_struct tmpForm;
8484 WERROR status = WERR_OK;
8485 NT_PRINTER_INFO_LEVEL *printer = NULL;
8488 nt_forms_struct *list=NULL;
8489 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8491 DEBUG(5,("_spoolss_AddForm\n"));
8494 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8495 OUR_HANDLE(handle)));
8500 /* forms can be added on printer of on the print server handle */
8502 if ( Printer->printer_type == SPLHND_PRINTER )
8504 if (!get_printer_snum(p,handle, &snum, NULL))
8507 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8508 if (!W_ERROR_IS_OK(status))
8512 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8513 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8514 status = WERR_ACCESS_DENIED;
8518 /* can't add if builtin */
8520 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8521 status = WERR_FILE_EXISTS;
8525 count = get_ntforms(&list);
8527 if(!add_a_form(&list, form, &count)) {
8528 status = WERR_NOMEM;
8532 write_ntforms(&list, count);
8535 * ChangeID must always be set if this is a printer
8538 if ( Printer->printer_type == SPLHND_PRINTER )
8539 status = mod_a_printer(printer, 2);
8543 free_a_printer(&printer, 2);
8549 /****************************************************************
8551 ****************************************************************/
8553 WERROR _spoolss_DeleteForm(pipes_struct *p,
8554 struct spoolss_DeleteForm *r)
8556 POLICY_HND *handle = r->in.handle;
8557 const char *form_name = r->in.form_name;
8558 nt_forms_struct tmpForm;
8560 nt_forms_struct *list=NULL;
8561 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8563 WERROR status = WERR_OK;
8564 NT_PRINTER_INFO_LEVEL *printer = NULL;
8566 DEBUG(5,("_spoolss_DeleteForm\n"));
8569 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8570 OUR_HANDLE(handle)));
8574 /* forms can be deleted on printer of on the print server handle */
8576 if ( Printer->printer_type == SPLHND_PRINTER )
8578 if (!get_printer_snum(p,handle, &snum, NULL))
8581 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8582 if (!W_ERROR_IS_OK(status))
8586 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8587 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8588 status = WERR_ACCESS_DENIED;
8592 /* can't delete if builtin */
8594 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8595 status = WERR_INVALID_PARAM;
8599 count = get_ntforms(&list);
8601 if ( !delete_a_form(&list, form_name, &count, &status ))
8605 * ChangeID must always be set if this is a printer
8608 if ( Printer->printer_type == SPLHND_PRINTER )
8609 status = mod_a_printer(printer, 2);
8613 free_a_printer(&printer, 2);
8619 /****************************************************************
8621 ****************************************************************/
8623 WERROR _spoolss_SetForm(pipes_struct *p,
8624 struct spoolss_SetForm *r)
8626 POLICY_HND *handle = r->in.handle;
8627 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8628 nt_forms_struct tmpForm;
8630 WERROR status = WERR_OK;
8631 NT_PRINTER_INFO_LEVEL *printer = NULL;
8634 nt_forms_struct *list=NULL;
8635 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8637 DEBUG(5,("_spoolss_SetForm\n"));
8640 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8641 OUR_HANDLE(handle)));
8645 /* forms can be modified on printer of on the print server handle */
8647 if ( Printer->printer_type == SPLHND_PRINTER )
8649 if (!get_printer_snum(p,handle, &snum, NULL))
8652 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8653 if (!W_ERROR_IS_OK(status))
8657 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8658 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8659 status = WERR_ACCESS_DENIED;
8663 /* can't set if builtin */
8664 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8665 status = WERR_INVALID_PARAM;
8669 count = get_ntforms(&list);
8670 update_a_form(&list, form, count);
8671 write_ntforms(&list, count);
8674 * ChangeID must always be set if this is a printer
8677 if ( Printer->printer_type == SPLHND_PRINTER )
8678 status = mod_a_printer(printer, 2);
8683 free_a_printer(&printer, 2);
8689 /****************************************************************************
8690 enumprintprocessors level 1.
8691 ****************************************************************************/
8693 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8695 PRINTPROCESSOR_1 *info_1=NULL;
8696 WERROR result = WERR_OK;
8698 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8703 init_unistr(&info_1->name, "winprint");
8705 *needed += spoolss_size_printprocessor_info_1(info_1);
8707 if (*needed > offered) {
8708 result = WERR_INSUFFICIENT_BUFFER;
8712 if (!rpcbuf_alloc_size(buffer, *needed)) {
8713 result = WERR_NOMEM;
8717 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8722 if ( !W_ERROR_IS_OK(result) )
8728 /****************************************************************************
8729 ****************************************************************************/
8731 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8733 uint32 level = q_u->level;
8734 RPC_BUFFER *buffer = NULL;
8735 uint32 offered = q_u->offered;
8736 uint32 *needed = &r_u->needed;
8737 uint32 *returned = &r_u->returned;
8739 /* that's an [in out] buffer */
8741 if (!q_u->buffer && (offered!=0)) {
8742 return WERR_INVALID_PARAM;
8745 rpcbuf_move(q_u->buffer, &r_u->buffer);
8746 buffer = r_u->buffer;
8748 DEBUG(5,("spoolss_enumprintprocessors\n"));
8751 * Enumerate the print processors ...
8753 * Just reply with "winprint", to keep NT happy
8754 * and I can use my nice printer checker.
8762 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8764 return WERR_UNKNOWN_LEVEL;
8768 /****************************************************************************
8769 enumprintprocdatatypes level 1.
8770 ****************************************************************************/
8772 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8774 PRINTPROCDATATYPE_1 *info_1=NULL;
8775 WERROR result = WERR_OK;
8777 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8782 init_unistr(&info_1->name, "RAW");
8784 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8786 if (*needed > offered) {
8787 result = WERR_INSUFFICIENT_BUFFER;
8791 if (!rpcbuf_alloc_size(buffer, *needed)) {
8792 result = WERR_NOMEM;
8796 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8801 if ( !W_ERROR_IS_OK(result) )
8807 /****************************************************************************
8808 ****************************************************************************/
8810 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8812 uint32 level = q_u->level;
8813 RPC_BUFFER *buffer = NULL;
8814 uint32 offered = q_u->offered;
8815 uint32 *needed = &r_u->needed;
8816 uint32 *returned = &r_u->returned;
8818 /* that's an [in out] buffer */
8820 if (!q_u->buffer && (offered!=0)) {
8821 return WERR_INVALID_PARAM;
8824 rpcbuf_move(q_u->buffer, &r_u->buffer);
8825 buffer = r_u->buffer;
8827 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8834 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8836 return WERR_UNKNOWN_LEVEL;
8840 /****************************************************************************
8841 enumprintmonitors level 1.
8842 ****************************************************************************/
8844 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8846 PRINTMONITOR_1 *info_1;
8847 WERROR result = WERR_OK;
8850 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8855 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8856 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8858 for ( i=0; i<*returned; i++ ) {
8859 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8862 if (*needed > offered) {
8863 result = WERR_INSUFFICIENT_BUFFER;
8867 if (!rpcbuf_alloc_size(buffer, *needed)) {
8868 result = WERR_NOMEM;
8872 for ( i=0; i<*returned; i++ ) {
8873 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8879 if ( !W_ERROR_IS_OK(result) )
8885 /****************************************************************************
8886 enumprintmonitors level 2.
8887 ****************************************************************************/
8889 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8891 PRINTMONITOR_2 *info_2;
8892 WERROR result = WERR_OK;
8895 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8900 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8901 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8902 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8904 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8905 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8906 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8908 for ( i=0; i<*returned; i++ ) {
8909 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8912 if (*needed > offered) {
8913 result = WERR_INSUFFICIENT_BUFFER;
8917 if (!rpcbuf_alloc_size(buffer, *needed)) {
8918 result = WERR_NOMEM;
8922 for ( i=0; i<*returned; i++ ) {
8923 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8929 if ( !W_ERROR_IS_OK(result) )
8935 /****************************************************************************
8936 ****************************************************************************/
8938 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8940 uint32 level = q_u->level;
8941 RPC_BUFFER *buffer = NULL;
8942 uint32 offered = q_u->offered;
8943 uint32 *needed = &r_u->needed;
8944 uint32 *returned = &r_u->returned;
8946 /* that's an [in out] buffer */
8948 if (!q_u->buffer && (offered!=0)) {
8949 return WERR_INVALID_PARAM;
8952 rpcbuf_move(q_u->buffer, &r_u->buffer);
8953 buffer = r_u->buffer;
8955 DEBUG(5,("spoolss_enumprintmonitors\n"));
8958 * Enumerate the print monitors ...
8960 * Just reply with "Local Port", to keep NT happy
8961 * and I can use my nice printer checker.
8969 return enumprintmonitors_level_1(buffer, offered, needed, returned);
8971 return enumprintmonitors_level_2(buffer, offered, needed, returned);
8973 return WERR_UNKNOWN_LEVEL;
8977 /****************************************************************************
8978 ****************************************************************************/
8980 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
8981 NT_PRINTER_INFO_LEVEL *ntprinter,
8982 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
8987 JOB_INFO_1 *info_1=NULL;
8988 WERROR result = WERR_OK;
8990 info_1=SMB_MALLOC_P(JOB_INFO_1);
8992 if (info_1 == NULL) {
8996 for (i=0; i<count && found==False; i++) {
8997 if ((*queue)[i].job==(int)jobid)
9003 /* NT treats not found as bad param... yet another bad choice */
9004 return WERR_INVALID_PARAM;
9007 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9009 *needed += spoolss_size_job_info_1(info_1);
9011 if (*needed > offered) {
9012 result = WERR_INSUFFICIENT_BUFFER;
9016 if (!rpcbuf_alloc_size(buffer, *needed)) {
9017 result = WERR_NOMEM;
9021 smb_io_job_info_1("", buffer, info_1, 0);
9029 /****************************************************************************
9030 ****************************************************************************/
9032 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9033 NT_PRINTER_INFO_LEVEL *ntprinter,
9034 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9041 DEVICEMODE *devmode = NULL;
9042 NT_DEVICEMODE *nt_devmode = NULL;
9044 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9047 ZERO_STRUCTP(info_2);
9049 for ( i=0; i<count && found==False; i++ )
9051 if ((*queue)[i].job == (int)jobid)
9056 /* NT treats not found as bad param... yet another bad
9058 result = WERR_INVALID_PARAM;
9063 * if the print job does not have a DEVMODE associated with it,
9064 * just use the one for the printer. A NULL devicemode is not
9065 * a failure condition
9068 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9069 devmode = construct_dev_mode(lp_const_servicename(snum));
9071 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9072 ZERO_STRUCTP( devmode );
9073 convert_nt_devicemode( devmode, nt_devmode );
9077 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9079 *needed += spoolss_size_job_info_2(info_2);
9081 if (*needed > offered) {
9082 result = WERR_INSUFFICIENT_BUFFER;
9086 if (!rpcbuf_alloc_size(buffer, *needed)) {
9087 result = WERR_NOMEM;
9091 smb_io_job_info_2("", buffer, info_2, 0);
9096 /* Cleanup allocated memory */
9098 free_job_info_2(info_2); /* Also frees devmode */
9104 /****************************************************************************
9105 ****************************************************************************/
9107 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9109 POLICY_HND *handle = &q_u->handle;
9110 uint32 jobid = q_u->jobid;
9111 uint32 level = q_u->level;
9112 RPC_BUFFER *buffer = NULL;
9113 uint32 offered = q_u->offered;
9114 uint32 *needed = &r_u->needed;
9115 WERROR wstatus = WERR_OK;
9116 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9119 print_queue_struct *queue = NULL;
9120 print_status_struct prt_status;
9122 /* that's an [in out] buffer */
9124 if (!q_u->buffer && (offered!=0)) {
9125 return WERR_INVALID_PARAM;
9128 rpcbuf_move(q_u->buffer, &r_u->buffer);
9129 buffer = r_u->buffer;
9131 DEBUG(5,("spoolss_getjob\n"));
9135 if (!get_printer_snum(p, handle, &snum, NULL))
9138 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9139 if ( !W_ERROR_IS_OK(wstatus) )
9142 count = print_queue_status(snum, &queue, &prt_status);
9144 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9145 count, prt_status.status, prt_status.message));
9149 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9150 buffer, offered, needed);
9153 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9154 buffer, offered, needed);
9157 wstatus = WERR_UNKNOWN_LEVEL;
9162 free_a_printer( &ntprinter, 2 );
9167 /********************************************************************
9168 spoolss_getprinterdataex
9170 From MSDN documentation of GetPrinterDataEx: pass request
9171 to GetPrinterData if key is "PrinterDriverData".
9172 ********************************************************************/
9174 WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
9176 POLICY_HND *handle = &q_u->handle;
9177 uint32 in_size = q_u->size;
9178 uint32 *type = &r_u->type;
9179 uint32 *out_size = &r_u->size;
9180 uint8 **data = &r_u->data;
9181 uint32 *needed = &r_u->needed;
9182 fstring keyname, valuename;
9184 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9186 NT_PRINTER_INFO_LEVEL *printer = NULL;
9188 WERROR status = WERR_OK;
9190 DEBUG(4,("_spoolss_getprinterdataex\n"));
9192 unistr2_to_ascii(keyname, &q_u->keyname, sizeof(keyname));
9193 unistr2_to_ascii(valuename, &q_u->valuename, sizeof(valuename));
9195 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
9196 keyname, valuename));
9198 /* in case of problem, return some default values */
9202 *out_size = in_size;
9205 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9206 status = WERR_BADFID;
9210 /* Is the handle to a printer or to the server? */
9212 if (Printer->printer_type == SPLHND_SERVER) {
9213 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
9214 status = WERR_INVALID_PARAM;
9218 if ( !get_printer_snum(p,handle, &snum, NULL) )
9221 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9222 if ( !W_ERROR_IS_OK(status) )
9225 /* check to see if the keyname is valid */
9226 if ( !strlen(keyname) ) {
9227 status = WERR_INVALID_PARAM;
9231 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9232 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname ));
9233 free_a_printer( &printer, 2 );
9234 status = WERR_BADFILE;
9238 /* When given a new keyname, we should just create it */
9240 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, type, data, needed, in_size );
9242 if (*needed > *out_size)
9243 status = WERR_MORE_DATA;
9246 if ( !W_ERROR_IS_OK(status) )
9248 DEBUG(5, ("error: allocating %d\n", *out_size));
9250 /* reply this param doesn't exist */
9254 if( (*data=(uint8 *)TALLOC_ZERO(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
9255 status = WERR_NOMEM;
9264 free_a_printer( &printer, 2 );
9269 /********************************************************************
9270 * spoolss_setprinterdataex
9271 ********************************************************************/
9273 WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u)
9275 POLICY_HND *handle = &q_u->handle;
9276 uint32 type = q_u->type;
9277 uint8 *data = q_u->data;
9278 uint32 real_len = q_u->real_len;
9280 NT_PRINTER_INFO_LEVEL *printer = NULL;
9282 WERROR status = WERR_OK;
9283 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9288 DEBUG(4,("_spoolss_setprinterdataex\n"));
9290 /* From MSDN documentation of SetPrinterDataEx: pass request to
9291 SetPrinterData if key is "PrinterDriverData" */
9294 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9298 if ( Printer->printer_type == SPLHND_SERVER ) {
9299 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
9300 return WERR_INVALID_PARAM;
9303 if ( !get_printer_snum(p,handle, &snum, NULL) )
9307 * Access check : NT returns "access denied" if you make a
9308 * SetPrinterData call without the necessary privildge.
9309 * we were originally returning OK if nothing changed
9310 * which made Win2k issue **a lot** of SetPrinterData
9311 * when connecting to a printer --jerry
9314 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9316 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
9317 return WERR_ACCESS_DENIED;
9320 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9321 if (!W_ERROR_IS_OK(status))
9324 unistr2_to_ascii( valuename, &q_u->value, sizeof(valuename));
9325 unistr2_to_ascii( keyname, &q_u->key, sizeof(keyname));
9327 /* check for OID in valuename */
9329 if ( (oid_string = strchr( valuename, ',' )) != NULL )
9335 /* save the registry data */
9337 status = set_printer_dataex( printer, keyname, valuename, type, data, real_len );
9339 if ( W_ERROR_IS_OK(status) )
9341 /* save the OID if one was specified */
9343 fstrcat( keyname, "\\" );
9344 fstrcat( keyname, SPOOL_OID_KEY );
9347 * I'm not checking the status here on purpose. Don't know
9348 * if this is right, but I'm returning the status from the
9349 * previous set_printer_dataex() call. I have no idea if
9350 * this is right. --jerry
9353 set_printer_dataex( printer, keyname, valuename,
9354 REG_SZ, (uint8 *)oid_string,
9355 strlen(oid_string)+1 );
9358 status = mod_a_printer(printer, 2);
9361 free_a_printer(&printer, 2);
9366 /****************************************************************
9367 _spoolss_DeletePrinterDataEx
9368 ****************************************************************/
9370 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9371 struct spoolss_DeletePrinterDataEx *r)
9373 POLICY_HND *handle = r->in.handle;
9374 NT_PRINTER_INFO_LEVEL *printer = NULL;
9376 WERROR status = WERR_OK;
9377 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9379 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9382 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9383 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9387 if (!get_printer_snum(p, handle, &snum, NULL))
9390 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9391 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9392 "printer properties change denied by handle\n"));
9393 return WERR_ACCESS_DENIED;
9396 if (!r->in.value_name || !r->in.key_name) {
9400 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9401 if (!W_ERROR_IS_OK(status))
9404 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9406 if ( W_ERROR_IS_OK(status) )
9407 mod_a_printer( printer, 2 );
9409 free_a_printer(&printer, 2);
9414 /********************************************************************
9415 * spoolss_enumprinterkey
9416 ********************************************************************/
9419 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9422 fstring *keynames = NULL;
9423 uint16 *enumkeys = NULL;
9426 POLICY_HND *handle = &q_u->handle;
9427 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9428 NT_PRINTER_DATA *data;
9429 NT_PRINTER_INFO_LEVEL *printer = NULL;
9431 WERROR status = WERR_BADFILE;
9434 DEBUG(4,("_spoolss_enumprinterkey\n"));
9437 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9441 if ( !get_printer_snum(p,handle, &snum, NULL) )
9444 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9445 if (!W_ERROR_IS_OK(status))
9448 /* get the list of subkey names */
9450 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9451 data = printer->info_2->data;
9453 num_keys = get_printer_subkeys( data, key, &keynames );
9455 if ( num_keys == -1 ) {
9456 status = WERR_BADFILE;
9460 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9462 r_u->needed = printerkey_len*2;
9464 if ( q_u->size < r_u->needed ) {
9465 status = WERR_MORE_DATA;
9469 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9470 status = WERR_NOMEM;
9476 if ( q_u->size < r_u->needed )
9477 status = WERR_MORE_DATA;
9480 free_a_printer( &printer, 2 );
9481 SAFE_FREE( keynames );
9486 /****************************************************************
9487 _spoolss_DeletePrinterKey
9488 ****************************************************************/
9490 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9491 struct spoolss_DeletePrinterKey *r)
9493 POLICY_HND *handle = r->in.handle;
9494 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9495 NT_PRINTER_INFO_LEVEL *printer = NULL;
9499 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9502 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9503 OUR_HANDLE(handle)));
9507 /* if keyname == NULL, return error */
9509 if ( !r->in.key_name )
9510 return WERR_INVALID_PARAM;
9512 if (!get_printer_snum(p, handle, &snum, NULL))
9515 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9516 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9517 "printer properties change denied by handle\n"));
9518 return WERR_ACCESS_DENIED;
9521 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9522 if (!W_ERROR_IS_OK(status))
9525 /* delete the key and all subneys */
9527 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9529 if ( W_ERROR_IS_OK(status) )
9530 status = mod_a_printer(printer, 2);
9532 free_a_printer( &printer, 2 );
9538 /********************************************************************
9539 * spoolss_enumprinterdataex
9540 ********************************************************************/
9542 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9544 POLICY_HND *handle = &q_u->handle;
9545 uint32 in_size = q_u->size;
9548 NT_PRINTER_INFO_LEVEL *printer = NULL;
9549 PRINTER_ENUM_VALUES *enum_values = NULL;
9550 NT_PRINTER_DATA *p_data;
9552 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9557 REGISTRY_VALUE *val;
9562 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9565 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9570 * first check for a keyname of NULL or "". Win2k seems to send
9571 * this a lot and we should send back WERR_INVALID_PARAM
9572 * no need to spend time looking up the printer in this case.
9576 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9577 if ( !strlen(key) ) {
9578 result = WERR_INVALID_PARAM;
9582 /* get the printer off of disk */
9584 if (!get_printer_snum(p,handle, &snum, NULL))
9587 ZERO_STRUCT(printer);
9588 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9589 if (!W_ERROR_IS_OK(result))
9592 /* now look for a match on the key name */
9594 p_data = printer->info_2->data;
9596 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9597 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9599 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9600 result = WERR_INVALID_PARAM;
9607 /* allocate the memory for the array of pointers -- if necessary */
9609 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9612 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9614 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9615 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9616 result = WERR_NOMEM;
9620 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9624 * loop through all params and build the array to pass
9625 * back to the client
9628 for ( i=0; i<num_entries; i++ )
9630 /* lookup the registry value */
9632 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9633 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9637 value_name = regval_name( val );
9638 init_unistr( &enum_values[i].valuename, value_name );
9639 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9640 enum_values[i].type = regval_type( val );
9642 data_len = regval_size( val );
9644 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9646 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9648 result = WERR_NOMEM;
9652 enum_values[i].data_len = data_len;
9654 /* keep track of the size of the array in bytes */
9656 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9659 /* housekeeping information in the reply */
9661 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9662 * the hand marshalled container size is a multiple
9663 * of 4 bytes for RPC alignment.
9667 needed += 4-(needed % 4);
9670 r_u->needed = needed;
9671 r_u->returned = num_entries;
9673 if (needed > in_size) {
9674 result = WERR_MORE_DATA;
9678 /* copy data into the reply */
9680 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9681 response buffer size is != the offered buffer size
9683 r_u->ctr.size = r_u->needed;
9685 r_u->ctr.size = in_size;
9687 r_u->ctr.size_of_array = r_u->returned;
9688 r_u->ctr.values = enum_values;
9692 free_a_printer(&printer, 2);
9697 /****************************************************************************
9698 ****************************************************************************/
9700 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, const char *name)
9702 init_unistr(&info->name, name);
9705 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
9706 UNISTR2 *environment,
9711 char *long_archi = NULL;
9712 PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
9713 WERROR result = WERR_OK;
9714 TALLOC_CTX *ctx = talloc_tos();
9716 long_archi = unistr2_to_ascii_talloc(ctx, environment);
9721 if (!get_short_archi(long_archi))
9722 return WERR_INVALID_ENVIRONMENT;
9724 if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
9727 fill_printprocessordirectory_1(info, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9729 *needed += spoolss_size_printprocessordirectory_info_1(info);
9731 if (*needed > offered) {
9732 result = WERR_INSUFFICIENT_BUFFER;
9736 if (!rpcbuf_alloc_size(buffer, *needed)) {
9737 result = WERR_INSUFFICIENT_BUFFER;
9741 smb_io_printprocessordirectory_1("", buffer, info, 0);
9749 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
9751 uint32 level = q_u->level;
9752 RPC_BUFFER *buffer = NULL;
9753 uint32 offered = q_u->offered;
9754 uint32 *needed = &r_u->needed;
9757 /* that's an [in out] buffer */
9759 if (!q_u->buffer && (offered!=0)) {
9760 return WERR_INVALID_PARAM;
9763 rpcbuf_move(q_u->buffer, &r_u->buffer);
9764 buffer = r_u->buffer;
9766 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9772 result = getprintprocessordirectory_level_1
9773 (&q_u->name, &q_u->environment, buffer, offered, needed);
9776 result = WERR_UNKNOWN_LEVEL;
9782 /*******************************************************************
9783 Streams the monitor UI DLL name in UNICODE
9784 *******************************************************************/
9786 static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
9787 RPC_BUFFER *out, uint32 *needed )
9789 const char *dllname = "tcpmonui.dll";
9791 *needed = (strlen(dllname)+1) * 2;
9793 if ( rpcbuf_get_size(out) < *needed ) {
9794 return WERR_INSUFFICIENT_BUFFER;
9797 if ( !make_monitorui_buf( out, dllname ) ) {
9804 /*******************************************************************
9805 Create a new TCP/IP port
9806 *******************************************************************/
9808 static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in,
9809 RPC_BUFFER *out, uint32 *needed )
9811 NT_PORT_DATA_1 port1;
9812 TALLOC_CTX *ctx = talloc_tos();
9813 char *device_uri = NULL;
9815 ZERO_STRUCT( port1 );
9817 /* convert to our internal port data structure */
9819 if ( !convert_port_data_1( &port1, in ) ) {
9823 /* create the device URI and call the add_port_hook() */
9825 switch ( port1.protocol ) {
9826 case PORT_PROTOCOL_DIRECT:
9827 device_uri = talloc_asprintf(ctx,
9828 "socket://%s:%d/", port1.hostaddr, port1.port );
9831 case PORT_PROTOCOL_LPR:
9832 device_uri = talloc_asprintf(ctx,
9833 "lpr://%s/%s", port1.hostaddr, port1.queue );
9837 return WERR_UNKNOWN_PORT;
9844 return add_port_hook(ctx, token, port1.name, device_uri );
9847 /*******************************************************************
9848 *******************************************************************/
9850 struct xcv_api_table xcvtcp_cmds[] = {
9851 { "MonitorUI", xcvtcp_monitorui },
9852 { "AddPort", xcvtcp_addport},
9856 static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command,
9857 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
9862 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9864 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9865 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9866 return xcvtcp_cmds[i].fn( token, inbuf, outbuf, needed );
9869 return WERR_BADFUNC;
9872 /*******************************************************************
9873 *******************************************************************/
9874 #if 0 /* don't support management using the "Local Port" monitor */
9876 static WERROR xcvlocal_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
9877 RPC_BUFFER *out, uint32 *needed )
9879 const char *dllname = "localui.dll";
9881 *needed = (strlen(dllname)+1) * 2;
9883 if ( rpcbuf_get_size(out) < *needed ) {
9884 return WERR_INSUFFICIENT_BUFFER;
9887 if ( !make_monitorui_buf( out, dllname )) {
9894 /*******************************************************************
9895 *******************************************************************/
9897 struct xcv_api_table xcvlocal_cmds[] = {
9898 { "MonitorUI", xcvlocal_monitorui },
9902 struct xcv_api_table xcvlocal_cmds[] = {
9909 /*******************************************************************
9910 *******************************************************************/
9912 static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command,
9913 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
9918 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9920 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9921 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9922 return xcvlocal_cmds[i].fn( token, inbuf, outbuf , needed );
9924 return WERR_BADFUNC;
9927 /*******************************************************************
9928 *******************************************************************/
9930 WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u)
9932 Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle);
9936 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle)));
9940 /* Has to be a handle to the TCP/IP port monitor */
9942 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9943 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
9947 /* requires administrative access to the server */
9949 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9950 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
9951 return WERR_ACCESS_DENIED;
9954 /* Get the command name. There's numerous commands supported by the
9955 TCPMON interface. */
9957 rpcstr_pull(command, q_u->dataname.buffer, sizeof(command),
9958 q_u->dataname.uni_str_len*2, 0);
9960 /* Allocate the outgoing buffer */
9962 if (!rpcbuf_init( &r_u->outdata, q_u->offered, p->mem_ctx ))
9965 switch ( Printer->printer_type ) {
9966 case SPLHND_PORTMON_TCP:
9967 return process_xcvtcp_command( p->server_info->ptok, command,
9968 &q_u->indata, &r_u->outdata, &r_u->needed );
9969 case SPLHND_PORTMON_LOCAL:
9970 return process_xcvlocal_command( p->server_info->ptok, command,
9971 &q_u->indata, &r_u->outdata, &r_u->needed );
9974 return WERR_INVALID_PRINT_MONITOR;
9976 /****************************************************************
9977 _spoolss_EnumPrinters
9978 ****************************************************************/
9980 WERROR _spoolss_EnumPrinters(pipes_struct *p,
9981 struct spoolss_EnumPrinters *r)
9983 p->rng_fault_state = true;
9984 return WERR_NOT_SUPPORTED;
9987 /****************************************************************
9988 _spoolss_OpenPrinter
9989 ****************************************************************/
9991 WERROR _spoolss_OpenPrinter(pipes_struct *p,
9992 struct spoolss_OpenPrinter *r)
9994 p->rng_fault_state = true;
9995 return WERR_NOT_SUPPORTED;
9998 /****************************************************************
10000 ****************************************************************/
10002 WERROR _spoolss_SetJob(pipes_struct *p,
10003 struct spoolss_SetJob *r)
10005 p->rng_fault_state = true;
10006 return WERR_NOT_SUPPORTED;
10009 /****************************************************************
10011 ****************************************************************/
10013 WERROR _spoolss_GetJob(pipes_struct *p,
10014 struct spoolss_GetJob *r)
10016 p->rng_fault_state = true;
10017 return WERR_NOT_SUPPORTED;
10020 /****************************************************************
10022 ****************************************************************/
10024 WERROR _spoolss_EnumJobs(pipes_struct *p,
10025 struct spoolss_EnumJobs *r)
10027 p->rng_fault_state = true;
10028 return WERR_NOT_SUPPORTED;
10031 /****************************************************************
10032 _spoolss_AddPrinter
10033 ****************************************************************/
10035 WERROR _spoolss_AddPrinter(pipes_struct *p,
10036 struct spoolss_AddPrinter *r)
10038 p->rng_fault_state = true;
10039 return WERR_NOT_SUPPORTED;
10042 /****************************************************************
10043 _spoolss_SetPrinter
10044 ****************************************************************/
10046 WERROR _spoolss_SetPrinter(pipes_struct *p,
10047 struct spoolss_SetPrinter *r)
10049 p->rng_fault_state = true;
10050 return WERR_NOT_SUPPORTED;
10053 /****************************************************************
10054 _spoolss_GetPrinter
10055 ****************************************************************/
10057 WERROR _spoolss_GetPrinter(pipes_struct *p,
10058 struct spoolss_GetPrinter *r)
10060 p->rng_fault_state = true;
10061 return WERR_NOT_SUPPORTED;
10064 /****************************************************************
10065 _spoolss_AddPrinterDriver
10066 ****************************************************************/
10068 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
10069 struct spoolss_AddPrinterDriver *r)
10071 p->rng_fault_state = true;
10072 return WERR_NOT_SUPPORTED;
10075 /****************************************************************
10076 _spoolss_EnumPrinterDrivers
10077 ****************************************************************/
10079 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10080 struct spoolss_EnumPrinterDrivers *r)
10082 p->rng_fault_state = true;
10083 return WERR_NOT_SUPPORTED;
10086 /****************************************************************
10087 _spoolss_GetPrinterDriver
10088 ****************************************************************/
10090 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10091 struct spoolss_GetPrinterDriver *r)
10093 p->rng_fault_state = true;
10094 return WERR_NOT_SUPPORTED;
10097 /****************************************************************
10098 _spoolss_GetPrinterDriverDirectory
10099 ****************************************************************/
10101 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
10102 struct spoolss_GetPrinterDriverDirectory *r)
10104 p->rng_fault_state = true;
10105 return WERR_NOT_SUPPORTED;
10108 /****************************************************************
10109 _spoolss_DeletePrinterDriver
10110 ****************************************************************/
10112 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
10113 struct spoolss_DeletePrinterDriver *r)
10115 p->rng_fault_state = true;
10116 return WERR_NOT_SUPPORTED;
10119 /****************************************************************
10120 _spoolss_AddPrintProcessor
10121 ****************************************************************/
10123 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10124 struct spoolss_AddPrintProcessor *r)
10126 p->rng_fault_state = true;
10127 return WERR_NOT_SUPPORTED;
10130 /****************************************************************
10131 _spoolss_EnumPrintProcessors
10132 ****************************************************************/
10134 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10135 struct spoolss_EnumPrintProcessors *r)
10137 p->rng_fault_state = true;
10138 return WERR_NOT_SUPPORTED;
10141 /****************************************************************
10142 _spoolss_GetPrintProcessorDirectory
10143 ****************************************************************/
10145 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
10146 struct spoolss_GetPrintProcessorDirectory *r)
10148 p->rng_fault_state = true;
10149 return WERR_NOT_SUPPORTED;
10152 /****************************************************************
10153 _spoolss_StartDocPrinter
10154 ****************************************************************/
10156 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
10157 struct spoolss_StartDocPrinter *r)
10159 p->rng_fault_state = true;
10160 return WERR_NOT_SUPPORTED;
10163 /****************************************************************
10164 _spoolss_ReadPrinter
10165 ****************************************************************/
10167 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10168 struct spoolss_ReadPrinter *r)
10170 p->rng_fault_state = true;
10171 return WERR_NOT_SUPPORTED;
10174 /****************************************************************
10176 ****************************************************************/
10178 WERROR _spoolss_AddJob(pipes_struct *p,
10179 struct spoolss_AddJob *r)
10181 p->rng_fault_state = true;
10182 return WERR_NOT_SUPPORTED;
10185 /****************************************************************
10186 _spoolss_ScheduleJob
10187 ****************************************************************/
10189 WERROR _spoolss_ScheduleJob(pipes_struct *p,
10190 struct spoolss_ScheduleJob *r)
10192 p->rng_fault_state = true;
10193 return WERR_NOT_SUPPORTED;
10196 /****************************************************************
10197 _spoolss_GetPrinterData
10198 ****************************************************************/
10200 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10201 struct spoolss_GetPrinterData *r)
10203 p->rng_fault_state = true;
10204 return WERR_NOT_SUPPORTED;
10207 /****************************************************************
10208 _spoolss_SetPrinterData
10209 ****************************************************************/
10211 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10212 struct spoolss_SetPrinterData *r)
10214 p->rng_fault_state = true;
10215 return WERR_NOT_SUPPORTED;
10218 /****************************************************************
10219 _spoolss_WaitForPrinterChange
10220 ****************************************************************/
10222 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10223 struct spoolss_WaitForPrinterChange *r)
10225 p->rng_fault_state = true;
10226 return WERR_NOT_SUPPORTED;
10229 /****************************************************************
10231 ****************************************************************/
10233 WERROR _spoolss_EnumForms(pipes_struct *p,
10234 struct spoolss_EnumForms *r)
10236 p->rng_fault_state = true;
10237 return WERR_NOT_SUPPORTED;
10240 /****************************************************************
10242 ****************************************************************/
10244 WERROR _spoolss_EnumPorts(pipes_struct *p,
10245 struct spoolss_EnumPorts *r)
10247 p->rng_fault_state = true;
10248 return WERR_NOT_SUPPORTED;
10251 /****************************************************************
10252 _spoolss_EnumMonitors
10253 ****************************************************************/
10255 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10256 struct spoolss_EnumMonitors *r)
10258 p->rng_fault_state = true;
10259 return WERR_NOT_SUPPORTED;
10262 /****************************************************************
10264 ****************************************************************/
10266 WERROR _spoolss_AddPort(pipes_struct *p,
10267 struct spoolss_AddPort *r)
10269 p->rng_fault_state = true;
10270 return WERR_NOT_SUPPORTED;
10273 /****************************************************************
10274 _spoolss_ConfigurePort
10275 ****************************************************************/
10277 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10278 struct spoolss_ConfigurePort *r)
10280 p->rng_fault_state = true;
10281 return WERR_NOT_SUPPORTED;
10284 /****************************************************************
10285 _spoolss_DeletePort
10286 ****************************************************************/
10288 WERROR _spoolss_DeletePort(pipes_struct *p,
10289 struct spoolss_DeletePort *r)
10291 p->rng_fault_state = true;
10292 return WERR_NOT_SUPPORTED;
10295 /****************************************************************
10296 _spoolss_CreatePrinterIC
10297 ****************************************************************/
10299 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10300 struct spoolss_CreatePrinterIC *r)
10302 p->rng_fault_state = true;
10303 return WERR_NOT_SUPPORTED;
10306 /****************************************************************
10307 _spoolss_PlayGDIScriptOnPrinterIC
10308 ****************************************************************/
10310 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10311 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10313 p->rng_fault_state = true;
10314 return WERR_NOT_SUPPORTED;
10317 /****************************************************************
10318 _spoolss_DeletePrinterIC
10319 ****************************************************************/
10321 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10322 struct spoolss_DeletePrinterIC *r)
10324 p->rng_fault_state = true;
10325 return WERR_NOT_SUPPORTED;
10328 /****************************************************************
10329 _spoolss_AddPrinterConnection
10330 ****************************************************************/
10332 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10333 struct spoolss_AddPrinterConnection *r)
10335 p->rng_fault_state = true;
10336 return WERR_NOT_SUPPORTED;
10339 /****************************************************************
10340 _spoolss_DeletePrinterConnection
10341 ****************************************************************/
10343 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10344 struct spoolss_DeletePrinterConnection *r)
10346 p->rng_fault_state = true;
10347 return WERR_NOT_SUPPORTED;
10350 /****************************************************************
10351 _spoolss_PrinterMessageBox
10352 ****************************************************************/
10354 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10355 struct spoolss_PrinterMessageBox *r)
10357 p->rng_fault_state = true;
10358 return WERR_NOT_SUPPORTED;
10361 /****************************************************************
10362 _spoolss_AddMonitor
10363 ****************************************************************/
10365 WERROR _spoolss_AddMonitor(pipes_struct *p,
10366 struct spoolss_AddMonitor *r)
10368 p->rng_fault_state = true;
10369 return WERR_NOT_SUPPORTED;
10372 /****************************************************************
10373 _spoolss_DeleteMonitor
10374 ****************************************************************/
10376 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10377 struct spoolss_DeleteMonitor *r)
10379 p->rng_fault_state = true;
10380 return WERR_NOT_SUPPORTED;
10383 /****************************************************************
10384 _spoolss_DeletePrintProcessor
10385 ****************************************************************/
10387 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10388 struct spoolss_DeletePrintProcessor *r)
10390 p->rng_fault_state = true;
10391 return WERR_NOT_SUPPORTED;
10394 /****************************************************************
10395 _spoolss_AddPrintProvidor
10396 ****************************************************************/
10398 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10399 struct spoolss_AddPrintProvidor *r)
10401 p->rng_fault_state = true;
10402 return WERR_NOT_SUPPORTED;
10405 /****************************************************************
10406 _spoolss_DeletePrintProvidor
10407 ****************************************************************/
10409 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10410 struct spoolss_DeletePrintProvidor *r)
10412 p->rng_fault_state = true;
10413 return WERR_NOT_SUPPORTED;
10416 /****************************************************************
10417 _spoolss_EnumPrintProcDataTypes
10418 ****************************************************************/
10420 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10421 struct spoolss_EnumPrintProcDataTypes *r)
10423 p->rng_fault_state = true;
10424 return WERR_NOT_SUPPORTED;
10427 /****************************************************************
10428 _spoolss_ResetPrinter
10429 ****************************************************************/
10431 WERROR _spoolss_ResetPrinter(pipes_struct *p,
10432 struct spoolss_ResetPrinter *r)
10434 p->rng_fault_state = true;
10435 return WERR_NOT_SUPPORTED;
10438 /****************************************************************
10439 _spoolss_GetPrinterDriver2
10440 ****************************************************************/
10442 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10443 struct spoolss_GetPrinterDriver2 *r)
10445 p->rng_fault_state = true;
10446 return WERR_NOT_SUPPORTED;
10449 /****************************************************************
10450 _spoolss_FindFirstPrinterChangeNotification
10451 ****************************************************************/
10453 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10454 struct spoolss_FindFirstPrinterChangeNotification *r)
10456 p->rng_fault_state = true;
10457 return WERR_NOT_SUPPORTED;
10460 /****************************************************************
10461 _spoolss_FindNextPrinterChangeNotification
10462 ****************************************************************/
10464 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10465 struct spoolss_FindNextPrinterChangeNotification *r)
10467 p->rng_fault_state = true;
10468 return WERR_NOT_SUPPORTED;
10471 /****************************************************************
10472 _spoolss_FindClosePrinterNotify
10473 ****************************************************************/
10475 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
10476 struct spoolss_FindClosePrinterNotify *r)
10478 p->rng_fault_state = true;
10479 return WERR_NOT_SUPPORTED;
10482 /****************************************************************
10483 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10484 ****************************************************************/
10486 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10487 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10489 p->rng_fault_state = true;
10490 return WERR_NOT_SUPPORTED;
10493 /****************************************************************
10494 _spoolss_ReplyOpenPrinter
10495 ****************************************************************/
10497 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10498 struct spoolss_ReplyOpenPrinter *r)
10500 p->rng_fault_state = true;
10501 return WERR_NOT_SUPPORTED;
10504 /****************************************************************
10505 _spoolss_RouterReplyPrinter
10506 ****************************************************************/
10508 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10509 struct spoolss_RouterReplyPrinter *r)
10511 p->rng_fault_state = true;
10512 return WERR_NOT_SUPPORTED;
10515 /****************************************************************
10516 _spoolss_ReplyClosePrinter
10517 ****************************************************************/
10519 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10520 struct spoolss_ReplyClosePrinter *r)
10522 p->rng_fault_state = true;
10523 return WERR_NOT_SUPPORTED;
10526 /****************************************************************
10528 ****************************************************************/
10530 WERROR _spoolss_AddPortEx(pipes_struct *p,
10531 struct spoolss_AddPortEx *r)
10533 p->rng_fault_state = true;
10534 return WERR_NOT_SUPPORTED;
10537 /****************************************************************
10538 _spoolss_RouterFindFirstPrinterChangeNotification
10539 ****************************************************************/
10541 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10542 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10544 p->rng_fault_state = true;
10545 return WERR_NOT_SUPPORTED;
10548 /****************************************************************
10549 _spoolss_SpoolerInit
10550 ****************************************************************/
10552 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10553 struct spoolss_SpoolerInit *r)
10555 p->rng_fault_state = true;
10556 return WERR_NOT_SUPPORTED;
10559 /****************************************************************
10560 _spoolss_ResetPrinterEx
10561 ****************************************************************/
10563 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10564 struct spoolss_ResetPrinterEx *r)
10566 p->rng_fault_state = true;
10567 return WERR_NOT_SUPPORTED;
10570 /****************************************************************
10571 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10572 ****************************************************************/
10574 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10575 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10577 p->rng_fault_state = true;
10578 return WERR_NOT_SUPPORTED;
10581 /****************************************************************
10582 _spoolss_RouterRefreshPrinterChangeNotification
10583 ****************************************************************/
10585 WERROR _spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p,
10586 struct spoolss_RouterRefreshPrinterChangeNotification *r)
10588 p->rng_fault_state = true;
10589 return WERR_NOT_SUPPORTED;
10592 /****************************************************************
10593 _spoolss_RemoteFindNextPrinterChangeNotifyEx
10594 ****************************************************************/
10596 WERROR _spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p,
10597 struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r)
10599 p->rng_fault_state = true;
10600 return WERR_NOT_SUPPORTED;
10603 /****************************************************************
10605 ****************************************************************/
10607 WERROR _spoolss_44(pipes_struct *p,
10608 struct spoolss_44 *r)
10610 p->rng_fault_state = true;
10611 return WERR_NOT_SUPPORTED;
10614 /****************************************************************
10615 _spoolss_OpenPrinterEx
10616 ****************************************************************/
10618 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
10619 struct spoolss_OpenPrinterEx *r)
10621 p->rng_fault_state = true;
10622 return WERR_NOT_SUPPORTED;
10625 /****************************************************************
10626 _spoolss_AddPrinterEx
10627 ****************************************************************/
10629 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
10630 struct spoolss_AddPrinterEx *r)
10632 p->rng_fault_state = true;
10633 return WERR_NOT_SUPPORTED;
10636 /****************************************************************
10638 ****************************************************************/
10640 WERROR _spoolss_47(pipes_struct *p,
10641 struct spoolss_47 *r)
10643 p->rng_fault_state = true;
10644 return WERR_NOT_SUPPORTED;
10647 /****************************************************************
10648 _spoolss_EnumPrinterData
10649 ****************************************************************/
10651 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10652 struct spoolss_EnumPrinterData *r)
10654 p->rng_fault_state = true;
10655 return WERR_NOT_SUPPORTED;
10658 /****************************************************************
10660 ****************************************************************/
10662 WERROR _spoolss_4a(pipes_struct *p,
10663 struct spoolss_4a *r)
10665 p->rng_fault_state = true;
10666 return WERR_NOT_SUPPORTED;
10669 /****************************************************************
10671 ****************************************************************/
10673 WERROR _spoolss_4b(pipes_struct *p,
10674 struct spoolss_4b *r)
10676 p->rng_fault_state = true;
10677 return WERR_NOT_SUPPORTED;
10680 /****************************************************************
10682 ****************************************************************/
10684 WERROR _spoolss_4c(pipes_struct *p,
10685 struct spoolss_4c *r)
10687 p->rng_fault_state = true;
10688 return WERR_NOT_SUPPORTED;
10691 /****************************************************************
10692 _spoolss_SetPrinterDataEx
10693 ****************************************************************/
10695 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
10696 struct spoolss_SetPrinterDataEx *r)
10698 p->rng_fault_state = true;
10699 return WERR_NOT_SUPPORTED;
10702 /****************************************************************
10703 _spoolss_GetPrinterDataEx
10704 ****************************************************************/
10706 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
10707 struct spoolss_GetPrinterDataEx *r)
10709 p->rng_fault_state = true;
10710 return WERR_NOT_SUPPORTED;
10713 /****************************************************************
10714 _spoolss_EnumPrinterDataEx
10715 ****************************************************************/
10717 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10718 struct spoolss_EnumPrinterDataEx *r)
10720 p->rng_fault_state = true;
10721 return WERR_NOT_SUPPORTED;
10724 /****************************************************************
10725 _spoolss_EnumPrinterKey
10726 ****************************************************************/
10728 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10729 struct spoolss_EnumPrinterKey *r)
10731 p->rng_fault_state = true;
10732 return WERR_NOT_SUPPORTED;
10735 /****************************************************************
10737 ****************************************************************/
10739 WERROR _spoolss_53(pipes_struct *p,
10740 struct spoolss_53 *r)
10742 p->rng_fault_state = true;
10743 return WERR_NOT_SUPPORTED;
10746 /****************************************************************
10747 _spoolss_DeletePrinterDriverEx
10748 ****************************************************************/
10750 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
10751 struct spoolss_DeletePrinterDriverEx *r)
10753 p->rng_fault_state = true;
10754 return WERR_NOT_SUPPORTED;
10757 /****************************************************************
10759 ****************************************************************/
10761 WERROR _spoolss_55(pipes_struct *p,
10762 struct spoolss_55 *r)
10764 p->rng_fault_state = true;
10765 return WERR_NOT_SUPPORTED;
10768 /****************************************************************
10770 ****************************************************************/
10772 WERROR _spoolss_56(pipes_struct *p,
10773 struct spoolss_56 *r)
10775 p->rng_fault_state = true;
10776 return WERR_NOT_SUPPORTED;
10779 /****************************************************************
10781 ****************************************************************/
10783 WERROR _spoolss_57(pipes_struct *p,
10784 struct spoolss_57 *r)
10786 p->rng_fault_state = true;
10787 return WERR_NOT_SUPPORTED;
10790 /****************************************************************
10792 ****************************************************************/
10794 WERROR _spoolss_XcvData(pipes_struct *p,
10795 struct spoolss_XcvData *r)
10797 p->rng_fault_state = true;
10798 return WERR_NOT_SUPPORTED;
10801 /****************************************************************
10802 _spoolss_AddPrinterDriverEx
10803 ****************************************************************/
10805 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
10806 struct spoolss_AddPrinterDriverEx *r)
10808 p->rng_fault_state = true;
10809 return WERR_NOT_SUPPORTED;
10812 /****************************************************************
10814 ****************************************************************/
10816 WERROR _spoolss_5a(pipes_struct *p,
10817 struct spoolss_5a *r)
10819 p->rng_fault_state = true;
10820 return WERR_NOT_SUPPORTED;
10823 /****************************************************************
10825 ****************************************************************/
10827 WERROR _spoolss_5b(pipes_struct *p,
10828 struct spoolss_5b *r)
10830 p->rng_fault_state = true;
10831 return WERR_NOT_SUPPORTED;
10834 /****************************************************************
10836 ****************************************************************/
10838 WERROR _spoolss_5c(pipes_struct *p,
10839 struct spoolss_5c *r)
10841 p->rng_fault_state = true;
10842 return WERR_NOT_SUPPORTED;
10845 /****************************************************************
10847 ****************************************************************/
10849 WERROR _spoolss_5d(pipes_struct *p,
10850 struct spoolss_5d *r)
10852 p->rng_fault_state = true;
10853 return WERR_NOT_SUPPORTED;
10856 /****************************************************************
10858 ****************************************************************/
10860 WERROR _spoolss_5e(pipes_struct *p,
10861 struct spoolss_5e *r)
10863 p->rng_fault_state = true;
10864 return WERR_NOT_SUPPORTED;
10867 /****************************************************************
10869 ****************************************************************/
10871 WERROR _spoolss_5f(pipes_struct *p,
10872 struct spoolss_5f *r)
10874 p->rng_fault_state = true;
10875 return WERR_NOT_SUPPORTED;