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,
1998 struct spoolss_DeletePrinterDriver *r)
2002 NT_PRINTER_DRIVER_INFO_LEVEL info;
2003 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2006 WERROR status_win2k = WERR_ACCESS_DENIED;
2007 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2009 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2010 and not a printer admin, then fail */
2012 if ( (p->server_info->utok.uid != 0)
2013 && !user_has_privileges(p->server_info->ptok, &se_printop )
2014 && !token_contains_name_in_list(
2015 uidtoname(p->server_info->utok.uid), NULL,
2016 NULL, p->server_info->ptok,
2017 lp_printer_admin(-1)) )
2019 return WERR_ACCESS_DENIED;
2022 /* check that we have a valid driver name first */
2024 if ((version=get_version_id(arch)) == -1)
2025 return WERR_INVALID_ENVIRONMENT;
2028 ZERO_STRUCT(info_win2k);
2030 driver = CONST_DISCARD(char *, r->in.driver);
2031 arch = CONST_DISCARD(char *, r->in.architecture);
2033 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2035 /* try for Win2k driver if "Windows NT x86" */
2037 if ( version == 2 ) {
2039 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2040 status = WERR_UNKNOWN_PRINTER_DRIVER;
2044 /* otherwise it was a failure */
2046 status = WERR_UNKNOWN_PRINTER_DRIVER;
2052 if (printer_driver_in_use(info.info_3)) {
2053 status = WERR_PRINTER_DRIVER_IN_USE;
2059 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2061 /* if we get to here, we now have 2 driver info structures to remove */
2062 /* remove the Win2k driver first*/
2064 status_win2k = delete_printer_driver(
2065 p, info_win2k.info_3, 3, False );
2066 free_a_printer_driver( info_win2k, 3 );
2068 /* this should not have failed---if it did, report to client */
2069 if ( !W_ERROR_IS_OK(status_win2k) )
2071 status = status_win2k;
2077 status = delete_printer_driver(p, info.info_3, version, False);
2079 /* if at least one of the deletes succeeded return OK */
2081 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2085 free_a_printer_driver( info, 3 );
2090 /****************************************************************
2091 _spoolss_DeletePrinterDriverEx
2092 ****************************************************************/
2094 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2095 struct spoolss_DeletePrinterDriverEx *r)
2099 NT_PRINTER_DRIVER_INFO_LEVEL info;
2100 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2102 uint32_t flags = r->in.delete_flags;
2105 WERROR status_win2k = WERR_ACCESS_DENIED;
2106 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2108 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2109 and not a printer admin, then fail */
2111 if ( (p->server_info->utok.uid != 0)
2112 && !user_has_privileges(p->server_info->ptok, &se_printop )
2113 && !token_contains_name_in_list(
2114 uidtoname(p->server_info->utok.uid), NULL, NULL,
2115 p->server_info->ptok, lp_printer_admin(-1)) )
2117 return WERR_ACCESS_DENIED;
2120 driver = CONST_DISCARD(char *, r->in.driver);
2121 arch = CONST_DISCARD(char *, r->in.architecture);
2123 /* check that we have a valid driver name first */
2124 if ((version=get_version_id(arch)) == -1) {
2125 /* this is what NT returns */
2126 return WERR_INVALID_ENVIRONMENT;
2129 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2130 version = r->in.version;
2133 ZERO_STRUCT(info_win2k);
2135 status = get_a_printer_driver(&info, 3, driver, arch, version);
2137 if ( !W_ERROR_IS_OK(status) )
2140 * if the client asked for a specific version,
2141 * or this is something other than Windows NT x86,
2145 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2148 /* try for Win2k driver if "Windows NT x86" */
2151 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2152 status = WERR_UNKNOWN_PRINTER_DRIVER;
2157 if ( printer_driver_in_use(info.info_3) ) {
2158 status = WERR_PRINTER_DRIVER_IN_USE;
2163 * we have a couple of cases to consider.
2164 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2165 * then the delete should fail if **any** files overlap with
2167 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2168 * non-overlapping files
2169 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2170 * is set, the do not delete any files
2171 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2174 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2176 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2178 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2179 /* no idea of the correct error here */
2180 status = WERR_ACCESS_DENIED;
2185 /* also check for W32X86/3 if necessary; maybe we already have? */
2187 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2188 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2191 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2192 /* no idea of the correct error here */
2193 free_a_printer_driver( info_win2k, 3 );
2194 status = WERR_ACCESS_DENIED;
2198 /* if we get to here, we now have 2 driver info structures to remove */
2199 /* remove the Win2k driver first*/
2201 status_win2k = delete_printer_driver(
2202 p, info_win2k.info_3, 3, delete_files);
2203 free_a_printer_driver( info_win2k, 3 );
2205 /* this should not have failed---if it did, report to client */
2207 if ( !W_ERROR_IS_OK(status_win2k) )
2212 status = delete_printer_driver(p, info.info_3, version, delete_files);
2214 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2217 free_a_printer_driver( info, 3 );
2223 /****************************************************************************
2224 Internal routine for retreiving printerdata
2225 ***************************************************************************/
2227 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2228 const char *key, const char *value, uint32 *type, uint8 **data,
2229 uint32 *needed, uint32 in_size )
2231 REGISTRY_VALUE *val;
2235 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2236 return WERR_BADFILE;
2238 *type = regval_type( val );
2240 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2242 size = regval_size( val );
2244 /* copy the min(in_size, len) */
2247 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2249 /* special case for 0 length values */
2251 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2255 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2264 DEBUG(5,("get_printer_dataex: copy done\n"));
2269 /****************************************************************************
2270 Internal routine for removing printerdata
2271 ***************************************************************************/
2273 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2275 return delete_printer_data( printer->info_2, key, value );
2278 /****************************************************************************
2279 Internal routine for storing printerdata
2280 ***************************************************************************/
2282 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2283 uint32 type, uint8 *data, int real_len )
2285 /* the registry objects enforce uniqueness based on value name */
2287 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2290 /********************************************************************
2291 GetPrinterData on a printer server Handle.
2292 ********************************************************************/
2294 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2298 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2300 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2302 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2304 SIVAL(*data, 0, 0x00);
2309 if (!StrCaseCmp(value, "BeepEnabled")) {
2311 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2313 SIVAL(*data, 0, 0x00);
2318 if (!StrCaseCmp(value, "EventLog")) {
2320 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2322 /* formally was 0x1b */
2323 SIVAL(*data, 0, 0x0);
2328 if (!StrCaseCmp(value, "NetPopup")) {
2330 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2332 SIVAL(*data, 0, 0x00);
2337 if (!StrCaseCmp(value, "MajorVersion")) {
2339 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2342 /* Windows NT 4.0 seems to not allow uploading of drivers
2343 to a server that reports 0x3 as the MajorVersion.
2344 need to investigate more how Win2k gets around this .
2347 if ( RA_WINNT == get_remote_arch() )
2356 if (!StrCaseCmp(value, "MinorVersion")) {
2358 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2366 * uint32 size = 0x114
2368 * uint32 minor = [0|1]
2369 * uint32 build = [2195|2600]
2370 * extra unicode string = e.g. "Service Pack 3"
2372 if (!StrCaseCmp(value, "OSVersion")) {
2376 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2379 SIVAL(*data, 0, *needed); /* size */
2380 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2382 SIVAL(*data, 12, 2195); /* build */
2384 /* leave extra string empty */
2390 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2391 const char *string="C:\\PRINTERS";
2393 *needed = 2*(strlen(string)+1);
2394 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2396 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2398 /* it's done by hand ready to go on the wire */
2399 for (i=0; i<strlen(string); i++) {
2400 (*data)[2*i]=string[i];
2401 (*data)[2*i+1]='\0';
2406 if (!StrCaseCmp(value, "Architecture")) {
2407 const char *string="Windows NT x86";
2409 *needed = 2*(strlen(string)+1);
2410 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2412 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2413 for (i=0; i<strlen(string); i++) {
2414 (*data)[2*i]=string[i];
2415 (*data)[2*i+1]='\0';
2420 if (!StrCaseCmp(value, "DsPresent")) {
2422 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2425 /* only show the publish check box if we are a
2426 memeber of a AD domain */
2428 if ( lp_security() == SEC_ADS )
2429 SIVAL(*data, 0, 0x01);
2431 SIVAL(*data, 0, 0x00);
2437 if (!StrCaseCmp(value, "DNSMachineName")) {
2438 const char *hostname = get_mydnsfullname();
2441 return WERR_BADFILE;
2443 *needed = 2*(strlen(hostname)+1);
2444 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2446 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2447 for (i=0; i<strlen(hostname); i++) {
2448 (*data)[2*i]=hostname[i];
2449 (*data)[2*i+1]='\0';
2455 return WERR_BADFILE;
2458 /********************************************************************
2459 * spoolss_getprinterdata
2460 ********************************************************************/
2462 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2464 POLICY_HND *handle = &q_u->handle;
2465 UNISTR2 *valuename = &q_u->valuename;
2466 uint32 in_size = q_u->size;
2467 uint32 *type = &r_u->type;
2468 uint32 *out_size = &r_u->size;
2469 uint8 **data = &r_u->data;
2470 uint32 *needed = &r_u->needed;
2473 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2474 NT_PRINTER_INFO_LEVEL *printer = NULL;
2478 * Reminder: when it's a string, the length is in BYTES
2479 * even if UNICODE is negociated.
2484 *out_size = in_size;
2486 /* in case of problem, return some default values */
2491 DEBUG(4,("_spoolss_getprinterdata\n"));
2494 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2495 status = WERR_BADFID;
2499 unistr2_to_ascii(value, valuename, sizeof(value));
2501 if ( Printer->printer_type == SPLHND_SERVER )
2502 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2505 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2506 status = WERR_BADFID;
2510 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2511 if ( !W_ERROR_IS_OK(status) )
2514 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2516 if ( strequal(value, "ChangeId") ) {
2518 *needed = sizeof(uint32);
2519 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2520 status = WERR_NOMEM;
2523 SIVAL( *data, 0, printer->info_2->changeid );
2527 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2530 if (*needed > *out_size)
2531 status = WERR_MORE_DATA;
2534 if ( !W_ERROR_IS_OK(status) )
2536 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2538 /* reply this param doesn't exist */
2541 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2543 free_a_printer( &printer, 2 );
2551 /* cleanup & exit */
2554 free_a_printer( &printer, 2 );
2559 /*********************************************************
2560 Connect to the client machine.
2561 **********************************************************/
2563 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2564 struct sockaddr_storage *client_ss, const char *remote_machine)
2567 struct cli_state *the_cli;
2568 struct sockaddr_storage rm_addr;
2570 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2571 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2572 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2576 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2577 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2581 char addr[INET6_ADDRSTRLEN];
2582 rm_addr = *client_ss;
2583 print_sockaddr(addr, sizeof(addr), &rm_addr);
2584 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2588 /* setup the connection */
2590 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2591 &rm_addr, 0, "IPC$", "IPC",
2595 0, lp_client_signing(), NULL );
2597 if ( !NT_STATUS_IS_OK( ret ) ) {
2598 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2603 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2604 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2605 cli_shutdown(the_cli);
2610 * Ok - we have an anonymous connection to the IPC$ share.
2611 * Now start the NT Domain stuff :-).
2614 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2615 if (!NT_STATUS_IS_OK(ret)) {
2616 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2617 remote_machine, nt_errstr(ret)));
2618 cli_shutdown(the_cli);
2625 /***************************************************************************
2626 Connect to the client.
2627 ****************************************************************************/
2629 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2630 uint32 localprinter, uint32 type,
2631 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2636 * If it's the first connection, contact the client
2637 * and connect to the IPC$ share anonymously
2639 if (smb_connections==0) {
2640 fstring unix_printer;
2642 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2644 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2647 messaging_register(smbd_messaging_context(), NULL,
2648 MSG_PRINTER_NOTIFY2,
2649 receive_notify2_message_list);
2650 /* Tell the connections db we're now interested in printer
2651 * notify messages. */
2652 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2656 * Tell the specific printing tdb we want messages for this printer
2657 * by registering our PID.
2660 if (!print_notify_register_pid(snum))
2661 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2665 result = rpccli_spoolss_reply_open_printer(notify_cli_pipe,
2672 if (!W_ERROR_IS_OK(result))
2673 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2674 win_errstr(result)));
2676 return (W_ERROR_IS_OK(result));
2679 /********************************************************************
2681 * ReplyFindFirstPrinterChangeNotifyEx
2683 * before replying OK: status=0 a rpc call is made to the workstation
2684 * asking ReplyOpenPrinter
2686 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2687 * called from api_spoolss_rffpcnex
2688 ********************************************************************/
2690 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2692 POLICY_HND *handle = &q_u->handle;
2693 uint32 flags = q_u->flags;
2694 uint32 options = q_u->options;
2695 UNISTR2 *localmachine = &q_u->localmachine;
2696 uint32 printerlocal = q_u->printerlocal;
2698 SPOOL_NOTIFY_OPTION *option = q_u->option;
2699 struct sockaddr_storage client_ss;
2701 /* store the notify value in the printer struct */
2703 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2706 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2710 Printer->notify.flags=flags;
2711 Printer->notify.options=options;
2712 Printer->notify.printerlocal=printerlocal;
2714 if (Printer->notify.option)
2715 free_spool_notify_option(&Printer->notify.option);
2717 Printer->notify.option=dup_spool_notify_option(option);
2719 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
2720 sizeof(Printer->notify.localmachine));
2722 /* Connect to the client machine and send a ReplyOpenPrinter */
2724 if ( Printer->printer_type == SPLHND_SERVER)
2726 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2727 !get_printer_snum(p, handle, &snum, NULL) )
2730 if (!interpret_string_addr(&client_ss, p->client_address,
2732 return WERR_SERVER_UNAVAILABLE;
2735 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2736 Printer->notify.printerlocal, 1,
2737 &Printer->notify.client_hnd, &client_ss))
2738 return WERR_SERVER_UNAVAILABLE;
2740 Printer->notify.client_connected=True;
2745 /*******************************************************************
2746 * fill a notify_info_data with the servername
2747 ********************************************************************/
2749 void spoolss_notify_server_name(int snum,
2750 SPOOL_NOTIFY_INFO_DATA *data,
2751 print_queue_struct *queue,
2752 NT_PRINTER_INFO_LEVEL *printer,
2753 TALLOC_CTX *mem_ctx)
2755 smb_ucs2_t *temp = NULL;
2758 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername);
2759 if (len == (uint32)-1) {
2763 data->notify_data.data.length = len;
2765 data->notify_data.data.string = (uint16 *)temp;
2767 data->notify_data.data.string = NULL;
2771 /*******************************************************************
2772 * fill a notify_info_data with the printername (not including the servername).
2773 ********************************************************************/
2775 void spoolss_notify_printer_name(int snum,
2776 SPOOL_NOTIFY_INFO_DATA *data,
2777 print_queue_struct *queue,
2778 NT_PRINTER_INFO_LEVEL *printer,
2779 TALLOC_CTX *mem_ctx)
2781 smb_ucs2_t *temp = NULL;
2784 /* the notify name should not contain the \\server\ part */
2785 char *p = strrchr(printer->info_2->printername, '\\');
2788 p = printer->info_2->printername;
2793 len = rpcstr_push_talloc(mem_ctx, &temp, p);
2794 if (len == (uint32)-1) {
2798 data->notify_data.data.length = len;
2800 data->notify_data.data.string = (uint16 *)temp;
2802 data->notify_data.data.string = NULL;
2806 /*******************************************************************
2807 * fill a notify_info_data with the servicename
2808 ********************************************************************/
2810 void spoolss_notify_share_name(int snum,
2811 SPOOL_NOTIFY_INFO_DATA *data,
2812 print_queue_struct *queue,
2813 NT_PRINTER_INFO_LEVEL *printer,
2814 TALLOC_CTX *mem_ctx)
2816 smb_ucs2_t *temp = NULL;
2819 len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum));
2820 if (len == (uint32)-1) {
2824 data->notify_data.data.length = len;
2826 data->notify_data.data.string = (uint16 *)temp;
2828 data->notify_data.data.string = NULL;
2833 /*******************************************************************
2834 * fill a notify_info_data with the port name
2835 ********************************************************************/
2837 void spoolss_notify_port_name(int snum,
2838 SPOOL_NOTIFY_INFO_DATA *data,
2839 print_queue_struct *queue,
2840 NT_PRINTER_INFO_LEVEL *printer,
2841 TALLOC_CTX *mem_ctx)
2843 smb_ucs2_t *temp = NULL;
2846 /* even if it's strange, that's consistant in all the code */
2848 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname);
2849 if (len == (uint32)-1) {
2853 data->notify_data.data.length = len;
2855 data->notify_data.data.string = (uint16 *)temp;
2857 data->notify_data.data.string = NULL;
2861 /*******************************************************************
2862 * fill a notify_info_data with the printername
2863 * but it doesn't exist, have to see what to do
2864 ********************************************************************/
2866 void spoolss_notify_driver_name(int snum,
2867 SPOOL_NOTIFY_INFO_DATA *data,
2868 print_queue_struct *queue,
2869 NT_PRINTER_INFO_LEVEL *printer,
2870 TALLOC_CTX *mem_ctx)
2872 smb_ucs2_t *temp = NULL;
2875 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername);
2876 if (len == (uint32)-1) {
2880 data->notify_data.data.length = len;
2882 data->notify_data.data.string = (uint16 *)temp;
2884 data->notify_data.data.string = NULL;
2888 /*******************************************************************
2889 * fill a notify_info_data with the comment
2890 ********************************************************************/
2892 void spoolss_notify_comment(int snum,
2893 SPOOL_NOTIFY_INFO_DATA *data,
2894 print_queue_struct *queue,
2895 NT_PRINTER_INFO_LEVEL *printer,
2896 TALLOC_CTX *mem_ctx)
2898 smb_ucs2_t *temp = NULL;
2901 if (*printer->info_2->comment == '\0')
2902 len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum));
2904 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment);
2906 if (len == (uint32)-1) {
2909 data->notify_data.data.length = len;
2911 data->notify_data.data.string = (uint16 *)temp;
2913 data->notify_data.data.string = NULL;
2917 /*******************************************************************
2918 * fill a notify_info_data with the comment
2919 * location = "Room 1, floor 2, building 3"
2920 ********************************************************************/
2922 void spoolss_notify_location(int snum,
2923 SPOOL_NOTIFY_INFO_DATA *data,
2924 print_queue_struct *queue,
2925 NT_PRINTER_INFO_LEVEL *printer,
2926 TALLOC_CTX *mem_ctx)
2928 smb_ucs2_t *temp = NULL;
2931 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location);
2932 if (len == (uint32)-1) {
2936 data->notify_data.data.length = len;
2938 data->notify_data.data.string = (uint16 *)temp;
2940 data->notify_data.data.string = NULL;
2944 /*******************************************************************
2945 * fill a notify_info_data with the device mode
2946 * jfm:xxxx don't to it for know but that's a real problem !!!
2947 ********************************************************************/
2949 static void spoolss_notify_devmode(int snum,
2950 SPOOL_NOTIFY_INFO_DATA *data,
2951 print_queue_struct *queue,
2952 NT_PRINTER_INFO_LEVEL *printer,
2953 TALLOC_CTX *mem_ctx)
2955 /* for a dummy implementation we have to zero the fields */
2956 data->notify_data.data.length = 0;
2957 data->notify_data.data.string = NULL;
2960 /*******************************************************************
2961 * fill a notify_info_data with the separator file name
2962 ********************************************************************/
2964 void spoolss_notify_sepfile(int snum,
2965 SPOOL_NOTIFY_INFO_DATA *data,
2966 print_queue_struct *queue,
2967 NT_PRINTER_INFO_LEVEL *printer,
2968 TALLOC_CTX *mem_ctx)
2970 smb_ucs2_t *temp = NULL;
2973 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile);
2974 if (len == (uint32)-1) {
2978 data->notify_data.data.length = len;
2980 data->notify_data.data.string = (uint16 *)temp;
2982 data->notify_data.data.string = NULL;
2986 /*******************************************************************
2987 * fill a notify_info_data with the print processor
2988 * jfm:xxxx return always winprint to indicate we don't do anything to it
2989 ********************************************************************/
2991 void spoolss_notify_print_processor(int snum,
2992 SPOOL_NOTIFY_INFO_DATA *data,
2993 print_queue_struct *queue,
2994 NT_PRINTER_INFO_LEVEL *printer,
2995 TALLOC_CTX *mem_ctx)
2997 smb_ucs2_t *temp = NULL;
3000 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor);
3001 if (len == (uint32)-1) {
3005 data->notify_data.data.length = len;
3007 data->notify_data.data.string = (uint16 *)temp;
3009 data->notify_data.data.string = NULL;
3013 /*******************************************************************
3014 * fill a notify_info_data with the print processor options
3015 * jfm:xxxx send an empty string
3016 ********************************************************************/
3018 void spoolss_notify_parameters(int snum,
3019 SPOOL_NOTIFY_INFO_DATA *data,
3020 print_queue_struct *queue,
3021 NT_PRINTER_INFO_LEVEL *printer,
3022 TALLOC_CTX *mem_ctx)
3024 smb_ucs2_t *temp = NULL;
3027 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters);
3028 if (len == (uint32)-1) {
3032 data->notify_data.data.length = len;
3034 data->notify_data.data.string = (uint16 *)temp;
3036 data->notify_data.data.string = NULL;
3040 /*******************************************************************
3041 * fill a notify_info_data with the data type
3042 * jfm:xxxx always send RAW as data type
3043 ********************************************************************/
3045 void spoolss_notify_datatype(int snum,
3046 SPOOL_NOTIFY_INFO_DATA *data,
3047 print_queue_struct *queue,
3048 NT_PRINTER_INFO_LEVEL *printer,
3049 TALLOC_CTX *mem_ctx)
3051 smb_ucs2_t *temp = NULL;
3054 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype);
3055 if (len == (uint32)-1) {
3059 data->notify_data.data.length = len;
3061 data->notify_data.data.string = (uint16 *)temp;
3063 data->notify_data.data.string = NULL;
3067 /*******************************************************************
3068 * fill a notify_info_data with the security descriptor
3069 * jfm:xxxx send an null pointer to say no security desc
3070 * have to implement security before !
3071 ********************************************************************/
3073 static void spoolss_notify_security_desc(int snum,
3074 SPOOL_NOTIFY_INFO_DATA *data,
3075 print_queue_struct *queue,
3076 NT_PRINTER_INFO_LEVEL *printer,
3077 TALLOC_CTX *mem_ctx)
3079 data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size;
3080 data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ;
3083 /*******************************************************************
3084 * fill a notify_info_data with the attributes
3085 * jfm:xxxx a samba printer is always shared
3086 ********************************************************************/
3088 void spoolss_notify_attributes(int snum,
3089 SPOOL_NOTIFY_INFO_DATA *data,
3090 print_queue_struct *queue,
3091 NT_PRINTER_INFO_LEVEL *printer,
3092 TALLOC_CTX *mem_ctx)
3094 data->notify_data.value[0] = printer->info_2->attributes;
3095 data->notify_data.value[1] = 0;
3098 /*******************************************************************
3099 * fill a notify_info_data with the priority
3100 ********************************************************************/
3102 static void spoolss_notify_priority(int snum,
3103 SPOOL_NOTIFY_INFO_DATA *data,
3104 print_queue_struct *queue,
3105 NT_PRINTER_INFO_LEVEL *printer,
3106 TALLOC_CTX *mem_ctx)
3108 data->notify_data.value[0] = printer->info_2->priority;
3109 data->notify_data.value[1] = 0;
3112 /*******************************************************************
3113 * fill a notify_info_data with the default priority
3114 ********************************************************************/
3116 static void spoolss_notify_default_priority(int snum,
3117 SPOOL_NOTIFY_INFO_DATA *data,
3118 print_queue_struct *queue,
3119 NT_PRINTER_INFO_LEVEL *printer,
3120 TALLOC_CTX *mem_ctx)
3122 data->notify_data.value[0] = printer->info_2->default_priority;
3123 data->notify_data.value[1] = 0;
3126 /*******************************************************************
3127 * fill a notify_info_data with the start time
3128 ********************************************************************/
3130 static void spoolss_notify_start_time(int snum,
3131 SPOOL_NOTIFY_INFO_DATA *data,
3132 print_queue_struct *queue,
3133 NT_PRINTER_INFO_LEVEL *printer,
3134 TALLOC_CTX *mem_ctx)
3136 data->notify_data.value[0] = printer->info_2->starttime;
3137 data->notify_data.value[1] = 0;
3140 /*******************************************************************
3141 * fill a notify_info_data with the until time
3142 ********************************************************************/
3144 static void spoolss_notify_until_time(int snum,
3145 SPOOL_NOTIFY_INFO_DATA *data,
3146 print_queue_struct *queue,
3147 NT_PRINTER_INFO_LEVEL *printer,
3148 TALLOC_CTX *mem_ctx)
3150 data->notify_data.value[0] = printer->info_2->untiltime;
3151 data->notify_data.value[1] = 0;
3154 /*******************************************************************
3155 * fill a notify_info_data with the status
3156 ********************************************************************/
3158 static void spoolss_notify_status(int snum,
3159 SPOOL_NOTIFY_INFO_DATA *data,
3160 print_queue_struct *queue,
3161 NT_PRINTER_INFO_LEVEL *printer,
3162 TALLOC_CTX *mem_ctx)
3164 print_status_struct status;
3166 print_queue_length(snum, &status);
3167 data->notify_data.value[0]=(uint32) status.status;
3168 data->notify_data.value[1] = 0;
3171 /*******************************************************************
3172 * fill a notify_info_data with the number of jobs queued
3173 ********************************************************************/
3175 void spoolss_notify_cjobs(int snum,
3176 SPOOL_NOTIFY_INFO_DATA *data,
3177 print_queue_struct *queue,
3178 NT_PRINTER_INFO_LEVEL *printer,
3179 TALLOC_CTX *mem_ctx)
3181 data->notify_data.value[0] = print_queue_length(snum, NULL);
3182 data->notify_data.value[1] = 0;
3185 /*******************************************************************
3186 * fill a notify_info_data with the average ppm
3187 ********************************************************************/
3189 static void spoolss_notify_average_ppm(int snum,
3190 SPOOL_NOTIFY_INFO_DATA *data,
3191 print_queue_struct *queue,
3192 NT_PRINTER_INFO_LEVEL *printer,
3193 TALLOC_CTX *mem_ctx)
3195 /* always respond 8 pages per minutes */
3196 /* a little hard ! */
3197 data->notify_data.value[0] = printer->info_2->averageppm;
3198 data->notify_data.value[1] = 0;
3201 /*******************************************************************
3202 * fill a notify_info_data with username
3203 ********************************************************************/
3205 static void spoolss_notify_username(int snum,
3206 SPOOL_NOTIFY_INFO_DATA *data,
3207 print_queue_struct *queue,
3208 NT_PRINTER_INFO_LEVEL *printer,
3209 TALLOC_CTX *mem_ctx)
3211 smb_ucs2_t *temp = NULL;
3214 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user);
3215 if (len == (uint32)-1) {
3219 data->notify_data.data.length = len;
3221 data->notify_data.data.string = (uint16 *)temp;
3223 data->notify_data.data.string = NULL;
3227 /*******************************************************************
3228 * fill a notify_info_data with job status
3229 ********************************************************************/
3231 static void spoolss_notify_job_status(int snum,
3232 SPOOL_NOTIFY_INFO_DATA *data,
3233 print_queue_struct *queue,
3234 NT_PRINTER_INFO_LEVEL *printer,
3235 TALLOC_CTX *mem_ctx)
3237 data->notify_data.value[0]=nt_printj_status(queue->status);
3238 data->notify_data.value[1] = 0;
3241 /*******************************************************************
3242 * fill a notify_info_data with job name
3243 ********************************************************************/
3245 static void spoolss_notify_job_name(int snum,
3246 SPOOL_NOTIFY_INFO_DATA *data,
3247 print_queue_struct *queue,
3248 NT_PRINTER_INFO_LEVEL *printer,
3249 TALLOC_CTX *mem_ctx)
3251 smb_ucs2_t *temp = NULL;
3254 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file);
3255 if (len == (uint32)-1) {
3259 data->notify_data.data.length = len;
3261 data->notify_data.data.string = (uint16 *)temp;
3263 data->notify_data.data.string = NULL;
3267 /*******************************************************************
3268 * fill a notify_info_data with job status
3269 ********************************************************************/
3271 static void spoolss_notify_job_status_string(int snum,
3272 SPOOL_NOTIFY_INFO_DATA *data,
3273 print_queue_struct *queue,
3274 NT_PRINTER_INFO_LEVEL *printer,
3275 TALLOC_CTX *mem_ctx)
3278 * Now we're returning job status codes we just return a "" here. JRA.
3282 smb_ucs2_t *temp = NULL;
3285 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3288 switch (queue->status) {
3293 p = ""; /* NT provides the paused string */
3302 #endif /* NO LONGER NEEDED. */
3304 len = rpcstr_push_talloc(mem_ctx, &temp, p);
3305 if (len == (uint32)-1) {
3309 data->notify_data.data.length = len;
3311 data->notify_data.data.string = (uint16 *)temp;
3313 data->notify_data.data.string = NULL;
3317 /*******************************************************************
3318 * fill a notify_info_data with job time
3319 ********************************************************************/
3321 static void spoolss_notify_job_time(int snum,
3322 SPOOL_NOTIFY_INFO_DATA *data,
3323 print_queue_struct *queue,
3324 NT_PRINTER_INFO_LEVEL *printer,
3325 TALLOC_CTX *mem_ctx)
3327 data->notify_data.value[0]=0x0;
3328 data->notify_data.value[1]=0;
3331 /*******************************************************************
3332 * fill a notify_info_data with job size
3333 ********************************************************************/
3335 static void spoolss_notify_job_size(int snum,
3336 SPOOL_NOTIFY_INFO_DATA *data,
3337 print_queue_struct *queue,
3338 NT_PRINTER_INFO_LEVEL *printer,
3339 TALLOC_CTX *mem_ctx)
3341 data->notify_data.value[0]=queue->size;
3342 data->notify_data.value[1]=0;
3345 /*******************************************************************
3346 * fill a notify_info_data with page info
3347 ********************************************************************/
3348 static void spoolss_notify_total_pages(int snum,
3349 SPOOL_NOTIFY_INFO_DATA *data,
3350 print_queue_struct *queue,
3351 NT_PRINTER_INFO_LEVEL *printer,
3352 TALLOC_CTX *mem_ctx)
3354 data->notify_data.value[0]=queue->page_count;
3355 data->notify_data.value[1]=0;
3358 /*******************************************************************
3359 * fill a notify_info_data with pages printed info.
3360 ********************************************************************/
3361 static void spoolss_notify_pages_printed(int snum,
3362 SPOOL_NOTIFY_INFO_DATA *data,
3363 print_queue_struct *queue,
3364 NT_PRINTER_INFO_LEVEL *printer,
3365 TALLOC_CTX *mem_ctx)
3367 data->notify_data.value[0]=0; /* Add code when back-end tracks this */
3368 data->notify_data.value[1]=0;
3371 /*******************************************************************
3372 Fill a notify_info_data with job position.
3373 ********************************************************************/
3375 static void spoolss_notify_job_position(int snum,
3376 SPOOL_NOTIFY_INFO_DATA *data,
3377 print_queue_struct *queue,
3378 NT_PRINTER_INFO_LEVEL *printer,
3379 TALLOC_CTX *mem_ctx)
3381 data->notify_data.value[0]=queue->job;
3382 data->notify_data.value[1]=0;
3385 /*******************************************************************
3386 Fill a notify_info_data with submitted time.
3387 ********************************************************************/
3389 static void spoolss_notify_submitted_time(int snum,
3390 SPOOL_NOTIFY_INFO_DATA *data,
3391 print_queue_struct *queue,
3392 NT_PRINTER_INFO_LEVEL *printer,
3393 TALLOC_CTX *mem_ctx)
3400 t=gmtime(&queue->time);
3402 len = sizeof(SYSTEMTIME);
3404 data->notify_data.data.length = len;
3405 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
3407 if (!data->notify_data.data.string) {
3408 data->notify_data.data.length = 0;
3412 make_systemtime(&st, t);
3415 * Systemtime must be linearized as a set of UINT16's.
3416 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3419 p = (char *)data->notify_data.data.string;
3420 SSVAL(p, 0, st.year);
3421 SSVAL(p, 2, st.month);
3422 SSVAL(p, 4, st.dayofweek);
3423 SSVAL(p, 6, st.day);
3424 SSVAL(p, 8, st.hour);
3425 SSVAL(p, 10, st.minute);
3426 SSVAL(p, 12, st.second);
3427 SSVAL(p, 14, st.milliseconds);
3430 struct s_notify_info_data_table
3436 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
3437 print_queue_struct *queue,
3438 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3441 /* A table describing the various print notification constants and
3442 whether the notification data is a pointer to a variable sized
3443 buffer, a one value uint32 or a two value uint32. */
3445 static const struct s_notify_info_data_table notify_info_data_table[] =
3447 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3448 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3449 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
3450 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3451 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3452 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
3453 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
3454 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3455 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
3456 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3457 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3458 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3459 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
3460 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
3461 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3462 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
3463 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3464 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3465 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
3466 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
3467 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
3468 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
3469 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
3470 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
3471 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
3472 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
3473 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3474 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3475 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3476 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
3477 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
3478 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3479 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3480 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3481 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3482 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3483 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
3484 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
3485 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
3486 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
3487 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3488 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
3489 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
3490 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3491 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3492 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
3493 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
3494 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
3495 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
3496 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3499 /*******************************************************************
3500 Return the size of info_data structure.
3501 ********************************************************************/
3503 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
3507 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3508 if ( (notify_info_data_table[i].type == type)
3509 && (notify_info_data_table[i].field == field) ) {
3510 switch(notify_info_data_table[i].size) {
3511 case NOTIFY_ONE_VALUE:
3512 case NOTIFY_TWO_VALUE:
3517 /* The only pointer notify data I have seen on
3518 the wire is the submitted time and this has
3519 the notify size set to 4. -tpot */
3521 case NOTIFY_POINTER:
3524 case NOTIFY_SECDESC:
3530 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3535 /*******************************************************************
3536 Return the type of notify_info_data.
3537 ********************************************************************/
3539 static uint32 type_of_notify_info_data(uint16 type, uint16 field)
3543 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3544 if (notify_info_data_table[i].type == type &&
3545 notify_info_data_table[i].field == field)
3546 return notify_info_data_table[i].size;
3552 /****************************************************************************
3553 ****************************************************************************/
3555 static bool search_notify(uint16 type, uint16 field, int *value)
3559 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3560 if (notify_info_data_table[i].type == type &&
3561 notify_info_data_table[i].field == field &&
3562 notify_info_data_table[i].fn != NULL) {
3571 /****************************************************************************
3572 ****************************************************************************/
3574 void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
3576 info_data->type = type;
3577 info_data->field = field;
3578 info_data->reserved = 0;
3580 info_data->size = size_of_notify_info_data(type, field);
3581 info_data->enc_type = type_of_notify_info_data(type, field);
3586 /*******************************************************************
3588 * fill a notify_info struct with info asked
3590 ********************************************************************/
3592 static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
3593 snum, SPOOL_NOTIFY_OPTION_TYPE
3594 *option_type, uint32 id,
3595 TALLOC_CTX *mem_ctx)
3601 SPOOL_NOTIFY_INFO_DATA *current_data;
3602 NT_PRINTER_INFO_LEVEL *printer = NULL;
3603 print_queue_struct *queue=NULL;
3605 type=option_type->type;
3607 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3608 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3609 option_type->count, lp_servicename(snum)));
3611 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3614 for(field_num=0; field_num<option_type->count; field_num++) {
3615 field = option_type->fields[field_num];
3617 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3619 if (!search_notify(type, field, &j) )
3622 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3623 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3624 free_a_printer(&printer, 2);
3628 current_data = &info->data[info->count];
3630 construct_info_data(current_data, type, field, id);
3632 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3633 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3635 notify_info_data_table[j].fn(snum, current_data, queue,
3641 free_a_printer(&printer, 2);
3645 /*******************************************************************
3647 * fill a notify_info struct with info asked
3649 ********************************************************************/
3651 static bool construct_notify_jobs_info(print_queue_struct *queue,
3652 SPOOL_NOTIFY_INFO *info,
3653 NT_PRINTER_INFO_LEVEL *printer,
3654 int snum, SPOOL_NOTIFY_OPTION_TYPE
3655 *option_type, uint32 id,
3656 TALLOC_CTX *mem_ctx)
3662 SPOOL_NOTIFY_INFO_DATA *current_data;
3664 DEBUG(4,("construct_notify_jobs_info\n"));
3666 type = option_type->type;
3668 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3669 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3670 option_type->count));
3672 for(field_num=0; field_num<option_type->count; field_num++) {
3673 field = option_type->fields[field_num];
3675 if (!search_notify(type, field, &j) )
3678 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3679 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3683 current_data=&(info->data[info->count]);
3685 construct_info_data(current_data, type, field, id);
3686 notify_info_data_table[j].fn(snum, current_data, queue,
3695 * JFM: The enumeration is not that simple, it's even non obvious.
3697 * let's take an example: I want to monitor the PRINTER SERVER for
3698 * the printer's name and the number of jobs currently queued.
3699 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3700 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3702 * I have 3 printers on the back of my server.
3704 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3707 * 1 printer 1 name 1
3708 * 2 printer 1 cjob 1
3709 * 3 printer 2 name 2
3710 * 4 printer 2 cjob 2
3711 * 5 printer 3 name 3
3712 * 6 printer 3 name 3
3714 * that's the print server case, the printer case is even worse.
3717 /*******************************************************************
3719 * enumerate all printers on the printserver
3720 * fill a notify_info struct with info asked
3722 ********************************************************************/
3724 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3725 SPOOL_NOTIFY_INFO *info,
3726 TALLOC_CTX *mem_ctx)
3729 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3730 int n_services=lp_numservices();
3732 SPOOL_NOTIFY_OPTION *option;
3733 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3735 DEBUG(4,("printserver_notify_info\n"));
3740 option=Printer->notify.option;
3745 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3746 sending a ffpcn() request first */
3751 for (i=0; i<option->count; i++) {
3752 option_type=&(option->ctr.type[i]);
3754 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3757 for (snum=0; snum<n_services; snum++)
3759 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3760 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3766 * Debugging information, don't delete.
3769 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3770 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3771 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3773 for (i=0; i<info->count; i++) {
3774 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3775 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3776 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3783 /*******************************************************************
3785 * fill a notify_info struct with info asked
3787 ********************************************************************/
3789 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
3790 TALLOC_CTX *mem_ctx)
3793 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3796 SPOOL_NOTIFY_OPTION *option;
3797 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3799 print_queue_struct *queue=NULL;
3800 print_status_struct status;
3802 DEBUG(4,("printer_notify_info\n"));
3807 option=Printer->notify.option;
3813 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3814 sending a ffpcn() request first */
3819 get_printer_snum(p, hnd, &snum, NULL);
3821 for (i=0; i<option->count; i++) {
3822 option_type=&option->ctr.type[i];
3824 switch ( option_type->type ) {
3825 case PRINTER_NOTIFY_TYPE:
3826 if(construct_notify_printer_info(Printer, info, snum,
3832 case JOB_NOTIFY_TYPE: {
3833 NT_PRINTER_INFO_LEVEL *printer = NULL;
3835 count = print_queue_status(snum, &queue, &status);
3837 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3840 for (j=0; j<count; j++) {
3841 construct_notify_jobs_info(&queue[j], info,
3848 free_a_printer(&printer, 2);
3858 * Debugging information, don't delete.
3861 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3862 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3863 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3865 for (i=0; i<info->count; i++) {
3866 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3867 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3868 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3874 /********************************************************************
3876 ********************************************************************/
3878 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
3880 POLICY_HND *handle = &q_u->handle;
3881 SPOOL_NOTIFY_INFO *info = &r_u->info;
3883 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3884 WERROR result = WERR_BADFID;
3886 /* we always have a NOTIFY_INFO struct */
3890 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3891 OUR_HANDLE(handle)));
3895 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3898 * We are now using the change value, and
3899 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3900 * I don't have a global notification system, I'm sending back all the
3901 * informations even when _NOTHING_ has changed.
3904 /* We need to keep track of the change value to send back in
3905 RRPCN replies otherwise our updates are ignored. */
3907 Printer->notify.fnpcn = True;
3909 if (Printer->notify.client_connected) {
3910 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
3911 Printer->notify.change = q_u->change;
3914 /* just ignore the SPOOL_NOTIFY_OPTION */
3916 switch (Printer->printer_type) {
3918 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3921 case SPLHND_PRINTER:
3922 result = printer_notify_info(p, handle, info, p->mem_ctx);
3926 Printer->notify.fnpcn = False;
3932 /********************************************************************
3933 * construct_printer_info_0
3934 * fill a printer_info_0 struct
3935 ********************************************************************/
3937 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3939 char *chaine = NULL;
3941 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3942 counter_printer_0 *session_counter;
3943 uint32 global_counter;
3946 print_status_struct status;
3947 TALLOC_CTX *ctx = talloc_tos();
3949 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3952 init_unistr(&printer->printername, ntprinter->info_2->printername);
3954 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3956 free_a_printer(&ntprinter,2);
3960 count = print_queue_length(snum, &status);
3962 /* check if we already have a counter for this printer */
3963 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3964 if (session_counter->snum == snum)
3968 init_unistr(&printer->servername, chaine);
3970 /* it's the first time, add it to the list */
3971 if (session_counter==NULL) {
3972 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3973 free_a_printer(&ntprinter, 2);
3976 ZERO_STRUCTP(session_counter);
3977 session_counter->snum=snum;
3978 session_counter->counter=0;
3979 DLIST_ADD(counter_list, session_counter);
3983 session_counter->counter++;
3986 * the global_counter should be stored in a TDB as it's common to all the clients
3987 * and should be zeroed on samba startup
3989 global_counter=session_counter->counter;
3990 printer->cjobs = count;
3991 printer->total_jobs = 0;
3992 printer->total_bytes = 0;
3994 setuptime = (time_t)ntprinter->info_2->setuptime;
3995 t=gmtime(&setuptime);
3997 printer->year = t->tm_year+1900;
3998 printer->month = t->tm_mon+1;
3999 printer->dayofweek = t->tm_wday;
4000 printer->day = t->tm_mday;
4001 printer->hour = t->tm_hour;
4002 printer->minute = t->tm_min;
4003 printer->second = t->tm_sec;
4004 printer->milliseconds = 0;
4006 printer->global_counter = global_counter;
4007 printer->total_pages = 0;
4009 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
4010 printer->major_version = 0x0005; /* NT 5 */
4011 printer->build_version = 0x0893; /* build 2195 */
4013 printer->unknown7 = 0x1;
4014 printer->unknown8 = 0x0;
4015 printer->unknown9 = 0x0;
4016 printer->session_counter = session_counter->counter;
4017 printer->unknown11 = 0x0;
4018 printer->printer_errors = 0x0; /* number of print failure */
4019 printer->unknown13 = 0x0;
4020 printer->unknown14 = 0x1;
4021 printer->unknown15 = 0x024a; /* 586 Pentium ? */
4022 printer->unknown16 = 0x0;
4023 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
4024 printer->unknown18 = 0x0;
4025 printer->status = nt_printq_status(status.status);
4026 printer->unknown20 = 0x0;
4027 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4028 printer->unknown22 = 0x0;
4029 printer->unknown23 = 0x6; /* 6 ???*/
4030 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
4031 printer->unknown25 = 0;
4032 printer->unknown26 = 0;
4033 printer->unknown27 = 0;
4034 printer->unknown28 = 0;
4035 printer->unknown29 = 0;
4037 free_a_printer(&ntprinter,2);
4041 /********************************************************************
4042 * construct_printer_info_1
4043 * fill a printer_info_1 struct
4044 ********************************************************************/
4045 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4047 char *chaine = NULL;
4048 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4049 TALLOC_CTX *ctx = talloc_tos();
4051 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4054 printer->flags=flags;
4056 if (*ntprinter->info_2->comment == '\0') {
4057 init_unistr(&printer->comment, lp_comment(snum));
4058 chaine = talloc_asprintf(ctx,
4059 "%s,%s,%s", ntprinter->info_2->printername,
4060 ntprinter->info_2->drivername, lp_comment(snum));
4063 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4064 chaine = talloc_asprintf(ctx,
4065 "%s,%s,%s", ntprinter->info_2->printername,
4066 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4070 free_a_printer(&ntprinter,2);
4074 init_unistr(&printer->description, chaine);
4075 init_unistr(&printer->name, ntprinter->info_2->printername);
4077 free_a_printer(&ntprinter,2);
4082 /****************************************************************************
4083 Free a DEVMODE struct.
4084 ****************************************************************************/
4086 static void free_dev_mode(DEVICEMODE *dev)
4091 SAFE_FREE(dev->dev_private);
4096 /****************************************************************************
4097 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4098 should be valid upon entry
4099 ****************************************************************************/
4101 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4103 if ( !devmode || !ntdevmode )
4106 init_unistr(&devmode->devicename, ntdevmode->devicename);
4108 init_unistr(&devmode->formname, ntdevmode->formname);
4110 devmode->specversion = ntdevmode->specversion;
4111 devmode->driverversion = ntdevmode->driverversion;
4112 devmode->size = ntdevmode->size;
4113 devmode->driverextra = ntdevmode->driverextra;
4114 devmode->fields = ntdevmode->fields;
4116 devmode->orientation = ntdevmode->orientation;
4117 devmode->papersize = ntdevmode->papersize;
4118 devmode->paperlength = ntdevmode->paperlength;
4119 devmode->paperwidth = ntdevmode->paperwidth;
4120 devmode->scale = ntdevmode->scale;
4121 devmode->copies = ntdevmode->copies;
4122 devmode->defaultsource = ntdevmode->defaultsource;
4123 devmode->printquality = ntdevmode->printquality;
4124 devmode->color = ntdevmode->color;
4125 devmode->duplex = ntdevmode->duplex;
4126 devmode->yresolution = ntdevmode->yresolution;
4127 devmode->ttoption = ntdevmode->ttoption;
4128 devmode->collate = ntdevmode->collate;
4129 devmode->icmmethod = ntdevmode->icmmethod;
4130 devmode->icmintent = ntdevmode->icmintent;
4131 devmode->mediatype = ntdevmode->mediatype;
4132 devmode->dithertype = ntdevmode->dithertype;
4134 if (ntdevmode->nt_dev_private != NULL) {
4135 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4142 /****************************************************************************
4143 Create a DEVMODE struct. Returns malloced memory.
4144 ****************************************************************************/
4146 DEVICEMODE *construct_dev_mode(const char *servicename)
4148 NT_PRINTER_INFO_LEVEL *printer = NULL;
4149 DEVICEMODE *devmode = NULL;
4151 DEBUG(7,("construct_dev_mode\n"));
4153 DEBUGADD(8,("getting printer characteristics\n"));
4155 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4158 if ( !printer->info_2->devmode ) {
4159 DEBUG(5, ("BONG! There was no device mode!\n"));
4163 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4164 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4168 ZERO_STRUCTP(devmode);
4170 DEBUGADD(8,("loading DEVICEMODE\n"));
4172 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4173 free_dev_mode( devmode );
4178 free_a_printer(&printer,2);
4183 /********************************************************************
4184 * construct_printer_info_2
4185 * fill a printer_info_2 struct
4186 ********************************************************************/
4188 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4191 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4193 print_status_struct status;
4195 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4198 count = print_queue_length(snum, &status);
4200 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4201 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4202 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4203 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4204 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4206 if (*ntprinter->info_2->comment == '\0')
4207 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4209 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4211 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4212 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4213 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4214 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4215 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4217 printer->attributes = ntprinter->info_2->attributes;
4219 printer->priority = ntprinter->info_2->priority; /* priority */
4220 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4221 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4222 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4223 printer->status = nt_printq_status(status.status); /* status */
4224 printer->cjobs = count; /* jobs */
4225 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4227 if ( !(printer->devmode = construct_dev_mode(
4228 lp_const_servicename(snum))) )
4229 DEBUG(8, ("Returning NULL Devicemode!\n"));
4231 printer->secdesc = NULL;
4233 if ( ntprinter->info_2->secdesc_buf
4234 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4236 /* don't use talloc_steal() here unless you do a deep steal of all
4237 the SEC_DESC members */
4239 printer->secdesc = dup_sec_desc( talloc_tos(),
4240 ntprinter->info_2->secdesc_buf->sd );
4243 free_a_printer(&ntprinter, 2);
4248 /********************************************************************
4249 * construct_printer_info_3
4250 * fill a printer_info_3 struct
4251 ********************************************************************/
4253 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4255 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4256 PRINTER_INFO_3 *printer = NULL;
4258 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4262 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4263 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4264 free_a_printer(&ntprinter, 2);
4268 ZERO_STRUCTP(printer);
4270 /* These are the components of the SD we are returning. */
4272 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4273 /* don't use talloc_steal() here unless you do a deep steal of all
4274 the SEC_DESC members */
4276 printer->secdesc = dup_sec_desc( talloc_tos(),
4277 ntprinter->info_2->secdesc_buf->sd );
4280 free_a_printer(&ntprinter, 2);
4282 *pp_printer = printer;
4286 /********************************************************************
4287 * construct_printer_info_4
4288 * fill a printer_info_4 struct
4289 ********************************************************************/
4291 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4293 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4295 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4298 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4299 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4300 printer->attributes = ntprinter->info_2->attributes;
4302 free_a_printer(&ntprinter, 2);
4306 /********************************************************************
4307 * construct_printer_info_5
4308 * fill a printer_info_5 struct
4309 ********************************************************************/
4311 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4313 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4315 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4318 init_unistr(&printer->printername, ntprinter->info_2->printername);
4319 init_unistr(&printer->portname, ntprinter->info_2->portname);
4320 printer->attributes = ntprinter->info_2->attributes;
4322 /* these two are not used by NT+ according to MSDN */
4324 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4325 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4327 free_a_printer(&ntprinter, 2);
4332 /********************************************************************
4333 * construct_printer_info_6
4334 * fill a printer_info_6 struct
4335 ********************************************************************/
4337 static bool construct_printer_info_6(Printer_entry *print_hnd,
4338 PRINTER_INFO_6 *printer,
4341 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4343 print_status_struct status;
4345 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4346 lp_const_servicename(snum))))
4349 count = print_queue_length(snum, &status);
4351 printer->status = nt_printq_status(status.status);
4353 free_a_printer(&ntprinter, 2);
4358 /********************************************************************
4359 * construct_printer_info_7
4360 * fill a printer_info_7 struct
4361 ********************************************************************/
4363 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4365 char *guid_str = NULL;
4368 if (is_printer_published(print_hnd, snum, &guid)) {
4369 if (asprintf(&guid_str, "{%s}",
4370 GUID_string(talloc_tos(), &guid)) == -1) {
4373 strupper_m(guid_str);
4374 init_unistr(&printer->guid, guid_str);
4375 SAFE_FREE(guid_str);
4376 printer->action = SPOOL_DS_PUBLISH;
4378 init_unistr(&printer->guid, "");
4379 printer->action = SPOOL_DS_UNPUBLISH;
4385 /********************************************************************
4386 Spoolss_enumprinters.
4387 ********************************************************************/
4389 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4393 int n_services=lp_numservices();
4394 PRINTER_INFO_1 *printers=NULL;
4395 PRINTER_INFO_1 current_prt;
4396 WERROR result = WERR_OK;
4398 DEBUG(4,("enum_all_printers_info_1\n"));
4400 for (snum=0; snum<n_services; snum++) {
4401 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4402 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4404 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4405 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4406 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4410 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4412 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4418 /* check the required size. */
4419 for (i=0; i<*returned; i++)
4420 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4422 if (*needed > offered) {
4423 result = WERR_INSUFFICIENT_BUFFER;
4427 if (!rpcbuf_alloc_size(buffer, *needed)) {
4428 result = WERR_NOMEM;
4432 /* fill the buffer with the structures */
4433 for (i=0; i<*returned; i++)
4434 smb_io_printer_info_1("", buffer, &printers[i], 0);
4439 SAFE_FREE(printers);
4441 if ( !W_ERROR_IS_OK(result) )
4447 /********************************************************************
4448 enum_all_printers_info_1_local.
4449 *********************************************************************/
4451 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4453 DEBUG(4,("enum_all_printers_info_1_local\n"));
4455 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4458 /********************************************************************
4459 enum_all_printers_info_1_name.
4460 *********************************************************************/
4462 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4466 DEBUG(4,("enum_all_printers_info_1_name\n"));
4468 if ((name[0] == '\\') && (name[1] == '\\'))
4471 if (is_myname_or_ipaddr(s)) {
4472 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4475 return WERR_INVALID_NAME;
4478 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4479 /********************************************************************
4480 enum_all_printers_info_1_remote.
4481 *********************************************************************/
4483 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4485 PRINTER_INFO_1 *printer;
4486 fstring printername;
4489 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4490 WERROR result = WERR_OK;
4492 /* JFM: currently it's more a place holder than anything else.
4493 * In the spooler world there is a notion of server registration.
4494 * the print servers are registered on the PDC (in the same domain)
4496 * We should have a TDB here. The registration is done thru an
4497 * undocumented RPC call.
4500 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4505 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4506 slprintf(desc, sizeof(desc)-1,"%s", name);
4507 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4509 init_unistr(&printer->description, desc);
4510 init_unistr(&printer->name, printername);
4511 init_unistr(&printer->comment, comment);
4512 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4514 /* check the required size. */
4515 *needed += spoolss_size_printer_info_1(printer);
4517 if (*needed > offered) {
4518 result = WERR_INSUFFICIENT_BUFFER;
4522 if (!rpcbuf_alloc_size(buffer, *needed)) {
4523 result = WERR_NOMEM;
4527 /* fill the buffer with the structures */
4528 smb_io_printer_info_1("", buffer, printer, 0);
4534 if ( !W_ERROR_IS_OK(result) )
4542 /********************************************************************
4543 enum_all_printers_info_1_network.
4544 *********************************************************************/
4546 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4550 DEBUG(4,("enum_all_printers_info_1_network\n"));
4552 /* If we respond to a enum_printers level 1 on our name with flags
4553 set to PRINTER_ENUM_REMOTE with a list of printers then these
4554 printers incorrectly appear in the APW browse list.
4555 Specifically the printers for the server appear at the workgroup
4556 level where all the other servers in the domain are
4557 listed. Windows responds to this call with a
4558 WERR_CAN_NOT_COMPLETE so we should do the same. */
4560 if (name[0] == '\\' && name[1] == '\\')
4563 if (is_myname_or_ipaddr(s))
4564 return WERR_CAN_NOT_COMPLETE;
4566 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4569 /********************************************************************
4570 * api_spoolss_enumprinters
4572 * called from api_spoolss_enumprinters (see this to understand)
4573 ********************************************************************/
4575 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4579 int n_services=lp_numservices();
4580 PRINTER_INFO_2 *printers=NULL;
4581 PRINTER_INFO_2 current_prt;
4582 WERROR result = WERR_OK;
4586 for (snum=0; snum<n_services; snum++) {
4587 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4588 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4590 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4591 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4592 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4597 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4599 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4606 /* check the required size. */
4607 for (i=0; i<*returned; i++)
4608 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4610 if (*needed > offered) {
4611 result = WERR_INSUFFICIENT_BUFFER;
4615 if (!rpcbuf_alloc_size(buffer, *needed)) {
4616 result = WERR_NOMEM;
4620 /* fill the buffer with the structures */
4621 for (i=0; i<*returned; i++)
4622 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4627 for (i=0; i<*returned; i++)
4628 free_devmode(printers[i].devmode);
4630 SAFE_FREE(printers);
4632 if ( !W_ERROR_IS_OK(result) )
4638 /********************************************************************
4639 * handle enumeration of printers at level 1
4640 ********************************************************************/
4642 static WERROR enumprinters_level1( uint32 flags, fstring name,
4643 RPC_BUFFER *buffer, uint32 offered,
4644 uint32 *needed, uint32 *returned)
4646 /* Not all the flags are equals */
4648 if (flags & PRINTER_ENUM_LOCAL)
4649 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4651 if (flags & PRINTER_ENUM_NAME)
4652 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4654 #if 0 /* JERRY - disabled for now */
4655 if (flags & PRINTER_ENUM_REMOTE)
4656 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4659 if (flags & PRINTER_ENUM_NETWORK)
4660 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4662 return WERR_OK; /* NT4sp5 does that */
4665 /********************************************************************
4666 * handle enumeration of printers at level 2
4667 ********************************************************************/
4669 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4670 RPC_BUFFER *buffer, uint32 offered,
4671 uint32 *needed, uint32 *returned)
4673 if (flags & PRINTER_ENUM_LOCAL) {
4674 return enum_all_printers_info_2(buffer, offered, needed, returned);
4677 if (flags & PRINTER_ENUM_NAME) {
4678 if (is_myname_or_ipaddr(canon_servername(servername)))
4679 return enum_all_printers_info_2(buffer, offered, needed, returned);
4681 return WERR_INVALID_NAME;
4684 if (flags & PRINTER_ENUM_REMOTE)
4685 return WERR_UNKNOWN_LEVEL;
4690 /********************************************************************
4691 * handle enumeration of printers at level 5
4692 ********************************************************************/
4694 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4695 RPC_BUFFER *buffer, uint32 offered,
4696 uint32 *needed, uint32 *returned)
4698 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4702 /********************************************************************
4703 * api_spoolss_enumprinters
4705 * called from api_spoolss_enumprinters (see this to understand)
4706 ********************************************************************/
4708 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4710 uint32 flags = q_u->flags;
4711 UNISTR2 *servername = &q_u->servername;
4712 uint32 level = q_u->level;
4713 RPC_BUFFER *buffer = NULL;
4714 uint32 offered = q_u->offered;
4715 uint32 *needed = &r_u->needed;
4716 uint32 *returned = &r_u->returned;
4720 /* that's an [in out] buffer */
4722 if (!q_u->buffer && (offered!=0)) {
4723 return WERR_INVALID_PARAM;
4726 rpcbuf_move(q_u->buffer, &r_u->buffer);
4727 buffer = r_u->buffer;
4729 DEBUG(4,("_spoolss_enumprinters\n"));
4736 * flags==PRINTER_ENUM_NAME
4737 * if name=="" then enumerates all printers
4738 * if name!="" then enumerate the printer
4739 * flags==PRINTER_ENUM_REMOTE
4740 * name is NULL, enumerate printers
4741 * Level 2: name!="" enumerates printers, name can't be NULL
4742 * Level 3: doesn't exist
4743 * Level 4: does a local registry lookup
4744 * Level 5: same as Level 2
4747 unistr2_to_ascii(name, servername, sizeof(name));
4752 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4754 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4756 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4761 return WERR_UNKNOWN_LEVEL;
4764 /****************************************************************************
4765 ****************************************************************************/
4767 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4769 PRINTER_INFO_0 *printer=NULL;
4770 WERROR result = WERR_OK;
4772 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4775 construct_printer_info_0(print_hnd, printer, snum);
4777 /* check the required size. */
4778 *needed += spoolss_size_printer_info_0(printer);
4780 if (*needed > offered) {
4781 result = WERR_INSUFFICIENT_BUFFER;
4785 if (!rpcbuf_alloc_size(buffer, *needed)) {
4786 result = WERR_NOMEM;
4790 /* fill the buffer with the structures */
4791 smb_io_printer_info_0("", buffer, printer, 0);
4801 /****************************************************************************
4802 ****************************************************************************/
4804 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4806 PRINTER_INFO_1 *printer=NULL;
4807 WERROR result = WERR_OK;
4809 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4812 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4814 /* check the required size. */
4815 *needed += spoolss_size_printer_info_1(printer);
4817 if (*needed > offered) {
4818 result = WERR_INSUFFICIENT_BUFFER;
4822 if (!rpcbuf_alloc_size(buffer, *needed)) {
4823 result = WERR_NOMEM;
4827 /* fill the buffer with the structures */
4828 smb_io_printer_info_1("", buffer, printer, 0);
4837 /****************************************************************************
4838 ****************************************************************************/
4840 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4842 PRINTER_INFO_2 *printer=NULL;
4843 WERROR result = WERR_OK;
4845 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4848 construct_printer_info_2(print_hnd, printer, snum);
4850 /* check the required size. */
4851 *needed += spoolss_size_printer_info_2(printer);
4853 if (*needed > offered) {
4854 result = WERR_INSUFFICIENT_BUFFER;
4858 if (!rpcbuf_alloc_size(buffer, *needed)) {
4859 result = WERR_NOMEM;
4863 /* fill the buffer with the structures */
4864 if (!smb_io_printer_info_2("", buffer, printer, 0))
4865 result = WERR_NOMEM;
4869 free_printer_info_2(printer);
4874 /****************************************************************************
4875 ****************************************************************************/
4877 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4879 PRINTER_INFO_3 *printer=NULL;
4880 WERROR result = WERR_OK;
4882 if (!construct_printer_info_3(print_hnd, &printer, snum))
4885 /* check the required size. */
4886 *needed += spoolss_size_printer_info_3(printer);
4888 if (*needed > offered) {
4889 result = WERR_INSUFFICIENT_BUFFER;
4893 if (!rpcbuf_alloc_size(buffer, *needed)) {
4894 result = WERR_NOMEM;
4898 /* fill the buffer with the structures */
4899 smb_io_printer_info_3("", buffer, printer, 0);
4903 free_printer_info_3(printer);
4908 /****************************************************************************
4909 ****************************************************************************/
4911 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4913 PRINTER_INFO_4 *printer=NULL;
4914 WERROR result = WERR_OK;
4916 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4919 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4924 /* check the required size. */
4925 *needed += spoolss_size_printer_info_4(printer);
4927 if (*needed > offered) {
4928 result = WERR_INSUFFICIENT_BUFFER;
4932 if (!rpcbuf_alloc_size(buffer, *needed)) {
4933 result = WERR_NOMEM;
4937 /* fill the buffer with the structures */
4938 smb_io_printer_info_4("", buffer, printer, 0);
4942 free_printer_info_4(printer);
4947 /****************************************************************************
4948 ****************************************************************************/
4950 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4952 PRINTER_INFO_5 *printer=NULL;
4953 WERROR result = WERR_OK;
4955 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4958 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4959 free_printer_info_5(printer);
4963 /* check the required size. */
4964 *needed += spoolss_size_printer_info_5(printer);
4966 if (*needed > offered) {
4967 result = WERR_INSUFFICIENT_BUFFER;
4971 if (!rpcbuf_alloc_size(buffer, *needed)) {
4972 result = WERR_NOMEM;
4976 /* fill the buffer with the structures */
4977 smb_io_printer_info_5("", buffer, printer, 0);
4981 free_printer_info_5(printer);
4986 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4988 RPC_BUFFER *buffer, uint32 offered,
4991 PRINTER_INFO_6 *printer;
4992 WERROR result = WERR_OK;
4994 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4998 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4999 free_printer_info_6(printer);
5003 /* check the required size. */
5004 *needed += spoolss_size_printer_info_6(printer);
5006 if (*needed > offered) {
5007 result = WERR_INSUFFICIENT_BUFFER;
5011 if (!rpcbuf_alloc_size(buffer, *needed)) {
5012 result = WERR_NOMEM;
5016 /* fill the buffer with the structures */
5017 smb_io_printer_info_6("", buffer, printer, 0);
5021 free_printer_info_6(printer);
5026 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5028 PRINTER_INFO_7 *printer=NULL;
5029 WERROR result = WERR_OK;
5031 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5034 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5035 result = WERR_NOMEM;
5039 /* check the required size. */
5040 *needed += spoolss_size_printer_info_7(printer);
5042 if (*needed > offered) {
5043 result = WERR_INSUFFICIENT_BUFFER;
5047 if (!rpcbuf_alloc_size(buffer, *needed)) {
5048 result = WERR_NOMEM;
5053 /* fill the buffer with the structures */
5054 smb_io_printer_info_7("", buffer, printer, 0);
5058 free_printer_info_7(printer);
5063 /****************************************************************************
5064 ****************************************************************************/
5066 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5068 POLICY_HND *handle = &q_u->handle;
5069 uint32 level = q_u->level;
5070 RPC_BUFFER *buffer = NULL;
5071 uint32 offered = q_u->offered;
5072 uint32 *needed = &r_u->needed;
5073 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5077 /* that's an [in out] buffer */
5079 if (!q_u->buffer && (offered!=0)) {
5080 return WERR_INVALID_PARAM;
5083 rpcbuf_move(q_u->buffer, &r_u->buffer);
5084 buffer = r_u->buffer;
5088 if (!get_printer_snum(p, handle, &snum, NULL))
5093 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5095 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5097 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5099 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5101 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5103 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5105 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5107 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5109 return WERR_UNKNOWN_LEVEL;
5112 /********************************************************************
5113 * fill a DRIVER_INFO_1 struct
5114 ********************************************************************/
5116 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5118 init_unistr( &info->name, driver.info_3->name);
5121 /********************************************************************
5122 * construct_printer_driver_info_1
5123 ********************************************************************/
5125 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5127 NT_PRINTER_INFO_LEVEL *printer = NULL;
5128 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5130 ZERO_STRUCT(driver);
5132 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5133 return WERR_INVALID_PRINTER_NAME;
5135 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5136 free_a_printer(&printer, 2);
5137 return WERR_UNKNOWN_PRINTER_DRIVER;
5140 fill_printer_driver_info_1(info, driver, servername, architecture);
5142 free_a_printer(&printer,2);
5147 /********************************************************************
5148 * construct_printer_driver_info_2
5149 * fill a printer_info_2 struct
5150 ********************************************************************/
5152 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5154 TALLOC_CTX *ctx = talloc_tos();
5156 const char *cservername = canon_servername(servername);
5158 info->version=driver.info_3->cversion;
5160 init_unistr( &info->name, driver.info_3->name );
5161 init_unistr( &info->architecture, driver.info_3->environment );
5163 if (strlen(driver.info_3->driverpath)) {
5164 temp = talloc_asprintf(ctx,
5167 driver.info_3->driverpath);
5168 init_unistr( &info->driverpath, temp );
5170 init_unistr( &info->driverpath, "" );
5174 if (strlen(driver.info_3->datafile)) {
5175 temp = talloc_asprintf(ctx,
5178 driver.info_3->datafile);
5179 init_unistr( &info->datafile, temp );
5181 init_unistr( &info->datafile, "" );
5184 if (strlen(driver.info_3->configfile)) {
5185 temp = talloc_asprintf(ctx,
5188 driver.info_3->configfile);
5189 init_unistr( &info->configfile, temp );
5191 init_unistr( &info->configfile, "" );
5194 /********************************************************************
5195 * construct_printer_driver_info_2
5196 * fill a printer_info_2 struct
5197 ********************************************************************/
5199 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5201 NT_PRINTER_INFO_LEVEL *printer = NULL;
5202 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5204 ZERO_STRUCT(printer);
5205 ZERO_STRUCT(driver);
5207 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5208 return WERR_INVALID_PRINTER_NAME;
5210 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5211 free_a_printer(&printer, 2);
5212 return WERR_UNKNOWN_PRINTER_DRIVER;
5215 fill_printer_driver_info_2(info, driver, servername);
5217 free_a_printer(&printer,2);
5222 /********************************************************************
5223 * copy a strings array and convert to UNICODE
5225 * convert an array of ascii string to a UNICODE string
5226 ********************************************************************/
5228 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5234 TALLOC_CTX *ctx = talloc_tos();
5236 DEBUG(6,("init_unistr_array\n"));
5240 if ( !char_array ) {
5245 v = ""; /* hack to handle null lists */
5248 /* hack to allow this to be used in places other than when generating
5249 the list of dependent files */
5253 line = talloc_asprintf(ctx,
5255 canon_servername(servername),
5258 line = talloc_strdup(ctx, v);
5262 SAFE_FREE(*uni_array);
5265 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5267 /* add one extra unit16 for the second terminating NULL */
5269 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5270 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5277 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5282 /* special case for ""; we need to add both NULL's here */
5284 (*uni_array)[j++]=0x0000;
5285 (*uni_array)[j]=0x0000;
5288 DEBUGADD(6,("last one:done\n"));
5290 /* return size of array in uint16's */
5295 /********************************************************************
5296 * construct_printer_info_3
5297 * fill a printer_info_3 struct
5298 ********************************************************************/
5300 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5303 TALLOC_CTX *ctx = talloc_tos();
5304 const char *cservername = canon_servername(servername);
5308 info->version=driver.info_3->cversion;
5310 init_unistr( &info->name, driver.info_3->name );
5311 init_unistr( &info->architecture, driver.info_3->environment );
5313 if (strlen(driver.info_3->driverpath)) {
5314 temp = talloc_asprintf(ctx,
5317 driver.info_3->driverpath);
5318 init_unistr( &info->driverpath, temp );
5320 init_unistr( &info->driverpath, "" );
5323 if (strlen(driver.info_3->datafile)) {
5324 temp = talloc_asprintf(ctx,
5327 driver.info_3->datafile);
5328 init_unistr( &info->datafile, temp );
5330 init_unistr( &info->datafile, "" );
5333 if (strlen(driver.info_3->configfile)) {
5334 temp = talloc_asprintf(ctx,
5337 driver.info_3->configfile);
5338 init_unistr( &info->configfile, temp );
5340 init_unistr( &info->configfile, "" );
5343 if (strlen(driver.info_3->helpfile)) {
5344 temp = talloc_asprintf(ctx,
5347 driver.info_3->helpfile);
5348 init_unistr( &info->helpfile, temp );
5350 init_unistr( &info->helpfile, "" );
5353 init_unistr( &info->monitorname, driver.info_3->monitorname );
5354 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5356 info->dependentfiles=NULL;
5357 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5360 /********************************************************************
5361 * construct_printer_info_3
5362 * fill a printer_info_3 struct
5363 ********************************************************************/
5365 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5367 NT_PRINTER_INFO_LEVEL *printer = NULL;
5368 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5370 ZERO_STRUCT(driver);
5372 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5373 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5374 if (!W_ERROR_IS_OK(status))
5375 return WERR_INVALID_PRINTER_NAME;
5377 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5378 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5383 * I put this code in during testing. Helpful when commenting out the
5384 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5385 * as win2k always queries the driver using an infor level of 6.
5386 * I've left it in (but ifdef'd out) because I'll probably
5387 * use it in experimentation again in the future. --jerry 22/01/2002
5390 if (!W_ERROR_IS_OK(status)) {
5392 * Is this a W2k client ?
5395 /* Yes - try again with a WinNT driver. */
5397 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5398 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5402 if (!W_ERROR_IS_OK(status)) {
5403 free_a_printer(&printer,2);
5404 return WERR_UNKNOWN_PRINTER_DRIVER;
5412 fill_printer_driver_info_3(info, driver, servername);
5414 free_a_printer(&printer,2);
5419 /********************************************************************
5420 * construct_printer_info_6
5421 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5422 ********************************************************************/
5424 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5428 TALLOC_CTX *ctx = talloc_tos();
5429 const char *cservername = canon_servername(servername);
5432 memset(&nullstr, '\0', sizeof(fstring));
5434 info->version=driver.info_3->cversion;
5436 init_unistr( &info->name, driver.info_3->name );
5437 init_unistr( &info->architecture, driver.info_3->environment );
5439 if (strlen(driver.info_3->driverpath)) {
5440 temp = talloc_asprintf(ctx,
5443 driver.info_3->driverpath);
5444 init_unistr( &info->driverpath, temp );
5446 init_unistr( &info->driverpath, "" );
5449 if (strlen(driver.info_3->datafile)) {
5450 temp = talloc_asprintf(ctx,
5453 driver.info_3->datafile);
5454 init_unistr( &info->datafile, temp );
5456 init_unistr( &info->datafile, "" );
5459 if (strlen(driver.info_3->configfile)) {
5460 temp = talloc_asprintf(ctx,
5463 driver.info_3->configfile);
5464 init_unistr( &info->configfile, temp );
5466 init_unistr( &info->configfile, "" );
5469 if (strlen(driver.info_3->helpfile)) {
5470 temp = talloc_asprintf(ctx,
5473 driver.info_3->helpfile);
5474 init_unistr( &info->helpfile, temp );
5476 init_unistr( &info->helpfile, "" );
5479 init_unistr( &info->monitorname, driver.info_3->monitorname );
5480 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5482 info->dependentfiles = NULL;
5483 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5485 info->previousdrivernames=NULL;
5486 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5488 info->driver_date=0;
5491 info->driver_version_low=0;
5492 info->driver_version_high=0;
5494 init_unistr( &info->mfgname, "");
5495 init_unistr( &info->oem_url, "");
5496 init_unistr( &info->hardware_id, "");
5497 init_unistr( &info->provider, "");
5500 /********************************************************************
5501 * construct_printer_info_6
5502 * fill a printer_info_6 struct
5503 ********************************************************************/
5505 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5506 const char *servername, fstring architecture, uint32 version)
5508 NT_PRINTER_INFO_LEVEL *printer = NULL;
5509 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5512 ZERO_STRUCT(driver);
5514 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5516 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5518 if (!W_ERROR_IS_OK(status))
5519 return WERR_INVALID_PRINTER_NAME;
5521 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5523 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5525 if (!W_ERROR_IS_OK(status))
5528 * Is this a W2k client ?
5532 free_a_printer(&printer,2);
5533 return WERR_UNKNOWN_PRINTER_DRIVER;
5536 /* Yes - try again with a WinNT driver. */
5538 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5539 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5540 if (!W_ERROR_IS_OK(status)) {
5541 free_a_printer(&printer,2);
5542 return WERR_UNKNOWN_PRINTER_DRIVER;
5546 fill_printer_driver_info_6(info, driver, servername);
5548 free_a_printer(&printer,2);
5549 free_a_printer_driver(driver, 3);
5554 /****************************************************************************
5555 ****************************************************************************/
5557 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5559 SAFE_FREE(info->dependentfiles);
5562 /****************************************************************************
5563 ****************************************************************************/
5565 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5567 SAFE_FREE(info->dependentfiles);
5570 /****************************************************************************
5571 ****************************************************************************/
5573 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5575 DRIVER_INFO_1 *info=NULL;
5578 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5581 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5582 if (!W_ERROR_IS_OK(result))
5585 /* check the required size. */
5586 *needed += spoolss_size_printer_driver_info_1(info);
5588 if (*needed > offered) {
5589 result = WERR_INSUFFICIENT_BUFFER;
5593 if (!rpcbuf_alloc_size(buffer, *needed)) {
5594 result = WERR_NOMEM;
5598 /* fill the buffer with the structures */
5599 smb_io_printer_driver_info_1("", buffer, info, 0);
5608 /****************************************************************************
5609 ****************************************************************************/
5611 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5613 DRIVER_INFO_2 *info=NULL;
5616 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5619 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5620 if (!W_ERROR_IS_OK(result))
5623 /* check the required size. */
5624 *needed += spoolss_size_printer_driver_info_2(info);
5626 if (*needed > offered) {
5627 result = WERR_INSUFFICIENT_BUFFER;
5631 if (!rpcbuf_alloc_size(buffer, *needed)) {
5632 result = WERR_NOMEM;
5636 /* fill the buffer with the structures */
5637 smb_io_printer_driver_info_2("", buffer, info, 0);
5646 /****************************************************************************
5647 ****************************************************************************/
5649 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5656 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5657 if (!W_ERROR_IS_OK(result))
5660 /* check the required size. */
5661 *needed += spoolss_size_printer_driver_info_3(&info);
5663 if (*needed > offered) {
5664 result = WERR_INSUFFICIENT_BUFFER;
5668 if (!rpcbuf_alloc_size(buffer, *needed)) {
5669 result = WERR_NOMEM;
5673 /* fill the buffer with the structures */
5674 smb_io_printer_driver_info_3("", buffer, &info, 0);
5677 free_printer_driver_info_3(&info);
5682 /****************************************************************************
5683 ****************************************************************************/
5685 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5692 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5693 if (!W_ERROR_IS_OK(result))
5696 /* check the required size. */
5697 *needed += spoolss_size_printer_driver_info_6(&info);
5699 if (*needed > offered) {
5700 result = WERR_INSUFFICIENT_BUFFER;
5704 if (!rpcbuf_alloc_size(buffer, *needed)) {
5705 result = WERR_NOMEM;
5709 /* fill the buffer with the structures */
5710 smb_io_printer_driver_info_6("", buffer, &info, 0);
5713 free_printer_driver_info_6(&info);
5718 /****************************************************************************
5719 ****************************************************************************/
5721 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5723 POLICY_HND *handle = &q_u->handle;
5724 UNISTR2 *uni_arch = &q_u->architecture;
5725 uint32 level = q_u->level;
5726 uint32 clientmajorversion = q_u->clientmajorversion;
5727 RPC_BUFFER *buffer = NULL;
5728 uint32 offered = q_u->offered;
5729 uint32 *needed = &r_u->needed;
5730 uint32 *servermajorversion = &r_u->servermajorversion;
5731 uint32 *serverminorversion = &r_u->serverminorversion;
5732 Printer_entry *printer;
5735 fstring architecture;
5738 /* that's an [in out] buffer */
5740 if (!q_u->buffer && (offered!=0)) {
5741 return WERR_INVALID_PARAM;
5744 rpcbuf_move(q_u->buffer, &r_u->buffer);
5745 buffer = r_u->buffer;
5747 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5749 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5750 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5751 return WERR_INVALID_PRINTER_NAME;
5755 *servermajorversion = 0;
5756 *serverminorversion = 0;
5758 fstrcpy(servername, get_server_name( printer ));
5759 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5761 if (!get_printer_snum(p, handle, &snum, NULL))
5766 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5768 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5770 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5772 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5775 /* apparently this call is the equivalent of
5776 EnumPrinterDataEx() for the DsDriver key */
5781 return WERR_UNKNOWN_LEVEL;
5785 /****************************************************************
5786 _spoolss_StartPagePrinter
5787 ****************************************************************/
5789 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5790 struct spoolss_StartPagePrinter *r)
5792 POLICY_HND *handle = r->in.handle;
5794 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5797 DEBUG(3,("_spoolss_StartPagePrinter: "
5798 "Error in startpageprinter printer handle\n"));
5802 Printer->page_started=True;
5806 /****************************************************************
5807 _spoolss_EndPagePrinter
5808 ****************************************************************/
5810 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5811 struct spoolss_EndPagePrinter *r)
5813 POLICY_HND *handle = r->in.handle;
5816 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5819 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5820 OUR_HANDLE(handle)));
5824 if (!get_printer_snum(p, handle, &snum, NULL))
5827 Printer->page_started=False;
5828 print_job_endpage(snum, Printer->jobid);
5833 /********************************************************************
5834 * api_spoolss_getprinter
5835 * called from the spoolss dispatcher
5837 ********************************************************************/
5839 WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u)
5841 POLICY_HND *handle = &q_u->handle;
5842 DOC_INFO *docinfo = &q_u->doc_info_container.docinfo;
5843 uint32 *jobid = &r_u->jobid;
5844 TALLOC_CTX *ctx = p->mem_ctx;
5845 DOC_INFO_1 *info_1 = &docinfo->doc_info_1;
5847 char *jobname = NULL;
5849 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5852 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5857 * a nice thing with NT is it doesn't listen to what you tell it.
5858 * when asked to send _only_ RAW datas, it tries to send datas
5861 * So I add checks like in NT Server ...
5864 if (info_1->p_datatype != 0) {
5865 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype));
5866 if (strcmp(datatype, "RAW") != 0) {
5868 return WERR_INVALID_DATATYPE;
5872 /* get the share number of the printer */
5873 if (!get_printer_snum(p, handle, &snum, NULL)) {
5877 jobname = unistr2_to_ascii_talloc(ctx, &info_1->docname);
5879 Printer->jobid = print_job_start(p->server_info, snum, jobname,
5880 Printer->nt_devmode);
5882 /* An error occured in print_job_start() so return an appropriate
5885 if (Printer->jobid == -1) {
5886 return map_werror_from_unix(errno);
5889 Printer->document_started=True;
5890 (*jobid) = Printer->jobid;
5895 /****************************************************************
5896 _spoolss_EndDocPrinter
5897 ****************************************************************/
5899 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5900 struct spoolss_EndDocPrinter *r)
5902 POLICY_HND *handle = r->in.handle;
5904 return _spoolss_enddocprinter_internal(p, handle);
5907 /****************************************************************
5908 _spoolss_WritePrinter
5909 ****************************************************************/
5911 WERROR _spoolss_WritePrinter(pipes_struct *p,
5912 struct spoolss_WritePrinter *r)
5914 POLICY_HND *handle = r->in.handle;
5915 uint32 buffer_size = r->in._data_size;
5916 uint8 *buffer = r->in.data.data;
5917 uint32 *buffer_written = &r->in._data_size;
5919 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5922 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5923 OUR_HANDLE(handle)));
5924 *r->out.num_written = r->in._data_size;
5928 if (!get_printer_snum(p, handle, &snum, NULL))
5931 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5932 (SMB_OFF_T)-1, (size_t)buffer_size);
5933 if (*buffer_written == (uint32)-1) {
5934 *r->out.num_written = 0;
5935 if (errno == ENOSPC)
5936 return WERR_NO_SPOOL_SPACE;
5938 return WERR_ACCESS_DENIED;
5941 *r->out.num_written = r->in._data_size;
5946 /********************************************************************
5947 * api_spoolss_getprinter
5948 * called from the spoolss dispatcher
5950 ********************************************************************/
5952 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5956 WERROR errcode = WERR_BADFUNC;
5957 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5960 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5964 if (!get_printer_snum(p, handle, &snum, NULL))
5968 case PRINTER_CONTROL_PAUSE:
5969 if (print_queue_pause(p->server_info, snum, &errcode)) {
5973 case PRINTER_CONTROL_RESUME:
5974 case PRINTER_CONTROL_UNPAUSE:
5975 if (print_queue_resume(p->server_info, snum, &errcode)) {
5979 case PRINTER_CONTROL_PURGE:
5980 if (print_queue_purge(p->server_info, snum, &errcode)) {
5985 return WERR_UNKNOWN_LEVEL;
5992 /****************************************************************
5993 _spoolss_AbortPrinter
5994 * From MSDN: "Deletes printer's spool file if printer is configured
5996 ****************************************************************/
5998 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5999 struct spoolss_AbortPrinter *r)
6001 POLICY_HND *handle = r->in.handle;
6002 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6004 WERROR errcode = WERR_OK;
6007 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6008 OUR_HANDLE(handle)));
6012 if (!get_printer_snum(p, handle, &snum, NULL))
6015 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6020 /********************************************************************
6021 * called by spoolss_api_setprinter
6022 * when updating a printer description
6023 ********************************************************************/
6025 static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
6026 const SPOOL_PRINTER_INFO_LEVEL *info,
6027 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6029 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6033 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6035 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6036 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6037 OUR_HANDLE(handle)));
6039 result = WERR_BADFID;
6044 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6045 result = WERR_INVALID_PARAM;
6049 /* Check the user has permissions to change the security
6050 descriptor. By experimentation with two NT machines, the user
6051 requires Full Access to the printer to change security
6054 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6055 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6056 result = WERR_ACCESS_DENIED;
6060 /* NT seems to like setting the security descriptor even though
6061 nothing may have actually changed. */
6063 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6064 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6065 result = WERR_BADFID;
6069 if (DEBUGLEVEL >= 10) {
6073 the_acl = old_secdesc_ctr->sd->dacl;
6074 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6075 PRINTERNAME(snum), the_acl->num_aces));
6077 for (i = 0; i < the_acl->num_aces; i++) {
6078 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6079 &the_acl->aces[i].trustee),
6080 the_acl->aces[i].access_mask));
6083 the_acl = secdesc_ctr->sd->dacl;
6086 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6087 PRINTERNAME(snum), the_acl->num_aces));
6089 for (i = 0; i < the_acl->num_aces; i++) {
6090 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6091 &the_acl->aces[i].trustee),
6092 the_acl->aces[i].access_mask));
6095 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6099 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6100 if (!new_secdesc_ctr) {
6101 result = WERR_NOMEM;
6105 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6110 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6117 /********************************************************************
6118 Canonicalize printer info from a client
6120 ATTN: It does not matter what we set the servername to hear
6121 since we do the necessary work in get_a_printer() to set it to
6122 the correct value based on what the client sent in the
6123 _spoolss_open_printer_ex().
6124 ********************************************************************/
6126 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6128 fstring printername;
6131 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6132 "portname=%s drivername=%s comment=%s location=%s\n",
6133 info->servername, info->printername, info->sharename,
6134 info->portname, info->drivername, info->comment, info->location));
6136 /* we force some elements to "correct" values */
6137 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6138 fstrcpy(info->sharename, lp_servicename(snum));
6140 /* check to see if we allow printername != sharename */
6142 if ( lp_force_printername(snum) ) {
6143 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6144 global_myname(), info->sharename );
6147 /* make sure printername is in \\server\printername format */
6149 fstrcpy( printername, info->printername );
6151 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6152 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6156 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6157 global_myname(), p );
6160 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6161 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6168 /****************************************************************************
6169 ****************************************************************************/
6171 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6173 char *cmd = lp_addport_cmd();
6174 char *command = NULL;
6176 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6177 bool is_print_op = False;
6180 return WERR_ACCESS_DENIED;
6183 command = talloc_asprintf(ctx,
6184 "%s \"%s\" \"%s\"", cmd, portname, uri );
6190 is_print_op = user_has_privileges( token, &se_printop );
6192 DEBUG(10,("Running [%s]\n", command));
6194 /********* BEGIN SePrintOperatorPrivilege **********/
6199 ret = smbrun(command, NULL);
6204 /********* END SePrintOperatorPrivilege **********/
6206 DEBUGADD(10,("returned [%d]\n", ret));
6208 TALLOC_FREE(command);
6211 return WERR_ACCESS_DENIED;
6217 /****************************************************************************
6218 ****************************************************************************/
6220 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6222 char *cmd = lp_addprinter_cmd();
6224 char *command = NULL;
6228 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6229 bool is_print_op = False;
6230 char *remote_machine = talloc_strdup(ctx, "%m");
6232 if (!remote_machine) {
6235 remote_machine = talloc_sub_basic(ctx,
6236 current_user_info.smb_name,
6237 current_user_info.domain,
6239 if (!remote_machine) {
6243 command = talloc_asprintf(ctx,
6244 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6245 cmd, printer->info_2->printername, printer->info_2->sharename,
6246 printer->info_2->portname, printer->info_2->drivername,
6247 printer->info_2->location, printer->info_2->comment, remote_machine);
6253 is_print_op = user_has_privileges( token, &se_printop );
6255 DEBUG(10,("Running [%s]\n", command));
6257 /********* BEGIN SePrintOperatorPrivilege **********/
6262 if ( (ret = smbrun(command, &fd)) == 0 ) {
6263 /* Tell everyone we updated smb.conf. */
6264 message_send_all(smbd_messaging_context(),
6265 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6271 /********* END SePrintOperatorPrivilege **********/
6273 DEBUGADD(10,("returned [%d]\n", ret));
6275 TALLOC_FREE(command);
6276 TALLOC_FREE(remote_machine);
6284 /* reload our services immediately */
6285 reload_services( False );
6288 /* Get lines and convert them back to dos-codepage */
6289 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6290 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6293 /* Set the portname to what the script says the portname should be. */
6294 /* but don't require anything to be return from the script exit a good error code */
6297 /* Set the portname to what the script says the portname should be. */
6298 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6299 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6302 TALLOC_FREE(qlines);
6307 /********************************************************************
6308 * Called by spoolss_api_setprinter
6309 * when updating a printer description.
6310 ********************************************************************/
6312 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
6313 const SPOOL_PRINTER_INFO_LEVEL *info,
6314 DEVICEMODE *devmode)
6317 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6318 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6323 DEBUG(8,("update_printer\n"));
6328 result = WERR_BADFID;
6332 if (!get_printer_snum(p, handle, &snum, NULL)) {
6333 result = WERR_BADFID;
6337 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6338 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6339 result = WERR_BADFID;
6343 DEBUGADD(8,("Converting info_2 struct\n"));
6346 * convert_printer_info converts the incoming
6347 * info from the client and overwrites the info
6348 * just read from the tdb in the pointer 'printer'.
6351 if (!convert_printer_info(info, printer, level)) {
6352 result = WERR_NOMEM;
6357 /* we have a valid devmode
6358 convert it and link it*/
6360 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6361 if (!convert_devicemode(printer->info_2->printername, devmode,
6362 &printer->info_2->devmode)) {
6363 result = WERR_NOMEM;
6368 /* Do sanity check on the requested changes for Samba */
6370 if (!check_printer_ok(printer->info_2, snum)) {
6371 result = WERR_INVALID_PARAM;
6375 /* FIXME!!! If the driver has changed we really should verify that
6376 it is installed before doing much else --jerry */
6378 /* Check calling user has permission to update printer description */
6380 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6381 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6382 result = WERR_ACCESS_DENIED;
6386 /* Call addprinter hook */
6387 /* Check changes to see if this is really needed */
6389 if ( *lp_addprinter_cmd()
6390 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6391 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6392 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6393 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6395 /* add_printer_hook() will call reload_services() */
6397 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6399 result = WERR_ACCESS_DENIED;
6405 * When a *new* driver is bound to a printer, the drivername is used to
6406 * lookup previously saved driver initialization info, which is then
6407 * bound to the printer, simulating what happens in the Windows arch.
6409 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6411 if (!set_driver_init(printer, 2))
6413 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6414 printer->info_2->drivername));
6417 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6418 printer->info_2->drivername));
6420 notify_printer_driver(snum, printer->info_2->drivername);
6424 * flag which changes actually occured. This is a small subset of
6425 * all the possible changes. We also have to update things in the
6429 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6430 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6431 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6432 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6434 notify_printer_comment(snum, printer->info_2->comment);
6437 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6438 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6439 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6440 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6442 notify_printer_sharename(snum, printer->info_2->sharename);
6445 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6448 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6451 pname = printer->info_2->printername;
6454 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6455 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6456 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6458 notify_printer_printername( snum, pname );
6461 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6462 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6463 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6464 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6466 notify_printer_port(snum, printer->info_2->portname);
6469 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6470 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6471 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6472 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6474 notify_printer_location(snum, printer->info_2->location);
6477 /* here we need to update some more DsSpooler keys */
6478 /* uNCName, serverName, shortServerName */
6480 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6481 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6482 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6483 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6484 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6486 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6487 global_myname(), printer->info_2->sharename );
6488 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6489 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6490 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6492 /* Update printer info */
6493 result = mod_a_printer(printer, 2);
6496 free_a_printer(&printer, 2);
6497 free_a_printer(&old_printer, 2);
6503 /****************************************************************************
6504 ****************************************************************************/
6505 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6506 const SPOOL_PRINTER_INFO_LEVEL *info)
6509 SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
6511 Printer_entry *Printer;
6513 if ( lp_security() != SEC_ADS ) {
6514 return WERR_UNKNOWN_LEVEL;
6517 Printer = find_printer_index_by_hnd(p, handle);
6519 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6524 if (!get_printer_snum(p, handle, &snum, NULL))
6527 nt_printer_publish(Printer, snum, info7->action);
6531 return WERR_UNKNOWN_LEVEL;
6534 /****************************************************************************
6535 ****************************************************************************/
6537 WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
6539 POLICY_HND *handle = &q_u->handle;
6540 uint32 level = q_u->level;
6541 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
6542 DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
6543 SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
6544 uint32 command = q_u->command;
6547 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6550 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6554 /* check the level */
6557 return control_printer(handle, command, p);
6559 result = update_printer(p, handle, level, info, devmode_ctr.devmode);
6560 if (!W_ERROR_IS_OK(result))
6563 result = update_printer_sec(handle, level, info, p, secdesc_ctr);
6566 return update_printer_sec(handle, level, info, p,
6569 return publish_or_unpublish_printer(p, handle, info);
6571 return WERR_UNKNOWN_LEVEL;
6575 /****************************************************************
6576 _spoolss_FindClosePrinterNotify
6577 ****************************************************************/
6579 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6580 struct spoolss_FindClosePrinterNotify *r)
6582 POLICY_HND *handle = r->in.handle;
6583 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6586 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6587 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6591 if (Printer->notify.client_connected==True) {
6594 if ( Printer->printer_type == SPLHND_SERVER)
6596 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6597 !get_printer_snum(p, handle, &snum, NULL) )
6600 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6603 Printer->notify.flags=0;
6604 Printer->notify.options=0;
6605 Printer->notify.localmachine[0]='\0';
6606 Printer->notify.printerlocal=0;
6607 if (Printer->notify.option)
6608 free_spool_notify_option(&Printer->notify.option);
6609 Printer->notify.client_connected=False;
6614 /****************************************************************************
6615 ****************************************************************************/
6617 WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u)
6619 /* that's an [in out] buffer */
6621 if (!q_u->buffer && (q_u->offered!=0)) {
6622 return WERR_INVALID_PARAM;
6625 rpcbuf_move(q_u->buffer, &r_u->buffer);
6628 return WERR_INVALID_PARAM; /* this is what a NT server
6629 returns for AddJob. AddJob
6630 must fail on non-local
6634 /****************************************************************************
6635 ****************************************************************************/
6637 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6638 int position, int snum,
6639 const NT_PRINTER_INFO_LEVEL *ntprinter)
6643 t=gmtime(&queue->time);
6645 job_info->jobid=queue->job;
6646 init_unistr(&job_info->printername, lp_servicename(snum));
6647 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6648 init_unistr(&job_info->username, queue->fs_user);
6649 init_unistr(&job_info->document, queue->fs_file);
6650 init_unistr(&job_info->datatype, "RAW");
6651 init_unistr(&job_info->text_status, "");
6652 job_info->status=nt_printj_status(queue->status);
6653 job_info->priority=queue->priority;
6654 job_info->position=position;
6655 job_info->totalpages=queue->page_count;
6656 job_info->pagesprinted=0;
6658 make_systemtime(&job_info->submitted, t);
6661 /****************************************************************************
6662 ****************************************************************************/
6664 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6665 int position, int snum,
6666 const NT_PRINTER_INFO_LEVEL *ntprinter,
6667 DEVICEMODE *devmode)
6671 t=gmtime(&queue->time);
6673 job_info->jobid=queue->job;
6675 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6677 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6678 init_unistr(&job_info->username, queue->fs_user);
6679 init_unistr(&job_info->document, queue->fs_file);
6680 init_unistr(&job_info->notifyname, queue->fs_user);
6681 init_unistr(&job_info->datatype, "RAW");
6682 init_unistr(&job_info->printprocessor, "winprint");
6683 init_unistr(&job_info->parameters, "");
6684 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6685 init_unistr(&job_info->text_status, "");
6687 /* and here the security descriptor */
6689 job_info->status=nt_printj_status(queue->status);
6690 job_info->priority=queue->priority;
6691 job_info->position=position;
6692 job_info->starttime=0;
6693 job_info->untiltime=0;
6694 job_info->totalpages=queue->page_count;
6695 job_info->size=queue->size;
6696 make_systemtime(&(job_info->submitted), t);
6697 job_info->timeelapsed=0;
6698 job_info->pagesprinted=0;
6700 job_info->devmode = devmode;
6705 /****************************************************************************
6706 Enumjobs at level 1.
6707 ****************************************************************************/
6709 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6710 const NT_PRINTER_INFO_LEVEL *ntprinter,
6711 RPC_BUFFER *buffer, uint32 offered,
6712 uint32 *needed, uint32 *returned)
6716 WERROR result = WERR_OK;
6718 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6724 for (i=0; i<*returned; i++)
6725 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6727 /* check the required size. */
6728 for (i=0; i<*returned; i++)
6729 (*needed) += spoolss_size_job_info_1(&info[i]);
6731 if (*needed > offered) {
6732 result = WERR_INSUFFICIENT_BUFFER;
6736 if (!rpcbuf_alloc_size(buffer, *needed)) {
6737 result = WERR_NOMEM;
6741 /* fill the buffer with the structures */
6742 for (i=0; i<*returned; i++)
6743 smb_io_job_info_1("", buffer, &info[i], 0);
6749 if ( !W_ERROR_IS_OK(result) )
6755 /****************************************************************************
6756 Enumjobs at level 2.
6757 ****************************************************************************/
6759 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6760 const NT_PRINTER_INFO_LEVEL *ntprinter,
6761 RPC_BUFFER *buffer, uint32 offered,
6762 uint32 *needed, uint32 *returned)
6764 JOB_INFO_2 *info = NULL;
6766 WERROR result = WERR_OK;
6767 DEVICEMODE *devmode = NULL;
6769 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6774 /* this should not be a failure condition if the devmode is NULL */
6776 devmode = construct_dev_mode(lp_const_servicename(snum));
6778 for (i=0; i<*returned; i++)
6779 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6781 /* check the required size. */
6782 for (i=0; i<*returned; i++)
6783 (*needed) += spoolss_size_job_info_2(&info[i]);
6785 if (*needed > offered) {
6786 result = WERR_INSUFFICIENT_BUFFER;
6790 if (!rpcbuf_alloc_size(buffer, *needed)) {
6791 result = WERR_NOMEM;
6795 /* fill the buffer with the structures */
6796 for (i=0; i<*returned; i++)
6797 smb_io_job_info_2("", buffer, &info[i], 0);
6800 free_devmode(devmode);
6803 if ( !W_ERROR_IS_OK(result) )
6810 /****************************************************************************
6812 ****************************************************************************/
6814 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6816 POLICY_HND *handle = &q_u->handle;
6817 uint32 level = q_u->level;
6818 RPC_BUFFER *buffer = NULL;
6819 uint32 offered = q_u->offered;
6820 uint32 *needed = &r_u->needed;
6821 uint32 *returned = &r_u->returned;
6823 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6825 print_status_struct prt_status;
6826 print_queue_struct *queue=NULL;
6828 /* that's an [in out] buffer */
6830 if (!q_u->buffer && (offered!=0)) {
6831 return WERR_INVALID_PARAM;
6834 rpcbuf_move(q_u->buffer, &r_u->buffer);
6835 buffer = r_u->buffer;
6837 DEBUG(4,("_spoolss_enumjobs\n"));
6842 /* lookup the printer snum and tdb entry */
6844 if (!get_printer_snum(p, handle, &snum, NULL))
6847 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6848 if ( !W_ERROR_IS_OK(wret) )
6851 *returned = print_queue_status(snum, &queue, &prt_status);
6852 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6854 if (*returned == 0) {
6856 free_a_printer(&ntprinter, 2);
6862 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6865 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6869 wret = WERR_UNKNOWN_LEVEL;
6874 free_a_printer( &ntprinter, 2 );
6878 /****************************************************************************
6879 ****************************************************************************/
6881 WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u)
6886 /****************************************************************************
6887 ****************************************************************************/
6889 WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u)
6891 POLICY_HND *handle = &q_u->handle;
6892 uint32 jobid = q_u->jobid;
6893 uint32 command = q_u->command;
6896 WERROR errcode = WERR_BADFUNC;
6898 if (!get_printer_snum(p, handle, &snum, NULL)) {
6902 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6903 return WERR_INVALID_PRINTER_NAME;
6907 case JOB_CONTROL_CANCEL:
6908 case JOB_CONTROL_DELETE:
6909 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6913 case JOB_CONTROL_PAUSE:
6914 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6918 case JOB_CONTROL_RESTART:
6919 case JOB_CONTROL_RESUME:
6920 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6925 return WERR_UNKNOWN_LEVEL;
6931 /****************************************************************************
6932 Enumerates all printer drivers at level 1.
6933 ****************************************************************************/
6935 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6940 fstring *list = NULL;
6941 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6942 DRIVER_INFO_1 *driver_info_1=NULL;
6943 WERROR result = WERR_OK;
6947 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6949 ndrivers=get_ntdrivers(&list, architecture, version);
6950 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6952 if(ndrivers == -1) {
6953 SAFE_FREE(driver_info_1);
6958 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6959 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6965 for (i=0; i<ndrivers; i++) {
6967 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6968 ZERO_STRUCT(driver);
6969 status = get_a_printer_driver(&driver, 3, list[i],
6970 architecture, version);
6971 if (!W_ERROR_IS_OK(status)) {
6973 SAFE_FREE(driver_info_1);
6976 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6977 free_a_printer_driver(driver, 3);
6980 *returned+=ndrivers;
6984 /* check the required size. */
6985 for (i=0; i<*returned; i++) {
6986 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6987 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6990 if (*needed > offered) {
6991 result = WERR_INSUFFICIENT_BUFFER;
6995 if (!rpcbuf_alloc_size(buffer, *needed)) {
6996 result = WERR_NOMEM;
7000 /* fill the buffer with the driver structures */
7001 for (i=0; i<*returned; i++) {
7002 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7003 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
7007 SAFE_FREE(driver_info_1);
7009 if ( !W_ERROR_IS_OK(result) )
7015 /****************************************************************************
7016 Enumerates all printer drivers at level 2.
7017 ****************************************************************************/
7019 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7024 fstring *list = NULL;
7025 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7026 DRIVER_INFO_2 *driver_info_2=NULL;
7027 WERROR result = WERR_OK;
7031 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7033 ndrivers=get_ntdrivers(&list, architecture, version);
7034 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7036 if(ndrivers == -1) {
7037 SAFE_FREE(driver_info_2);
7042 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7043 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7049 for (i=0; i<ndrivers; i++) {
7052 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7053 ZERO_STRUCT(driver);
7054 status = get_a_printer_driver(&driver, 3, list[i],
7055 architecture, version);
7056 if (!W_ERROR_IS_OK(status)) {
7058 SAFE_FREE(driver_info_2);
7061 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7062 free_a_printer_driver(driver, 3);
7065 *returned+=ndrivers;
7069 /* check the required size. */
7070 for (i=0; i<*returned; i++) {
7071 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7072 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7075 if (*needed > offered) {
7076 result = WERR_INSUFFICIENT_BUFFER;
7080 if (!rpcbuf_alloc_size(buffer, *needed)) {
7081 result = WERR_NOMEM;
7085 /* fill the buffer with the form structures */
7086 for (i=0; i<*returned; i++) {
7087 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7088 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7092 SAFE_FREE(driver_info_2);
7094 if ( !W_ERROR_IS_OK(result) )
7100 /****************************************************************************
7101 Enumerates all printer drivers at level 3.
7102 ****************************************************************************/
7104 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7109 fstring *list = NULL;
7110 DRIVER_INFO_3 *driver_info_3=NULL;
7111 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7112 WERROR result = WERR_OK;
7116 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7118 ndrivers=get_ntdrivers(&list, architecture, version);
7119 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7121 if(ndrivers == -1) {
7122 SAFE_FREE(driver_info_3);
7127 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7128 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7134 for (i=0; i<ndrivers; i++) {
7137 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7138 ZERO_STRUCT(driver);
7139 status = get_a_printer_driver(&driver, 3, list[i],
7140 architecture, version);
7141 if (!W_ERROR_IS_OK(status)) {
7143 SAFE_FREE(driver_info_3);
7146 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7147 free_a_printer_driver(driver, 3);
7150 *returned+=ndrivers;
7154 /* check the required size. */
7155 for (i=0; i<*returned; i++) {
7156 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7157 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7160 if (*needed > offered) {
7161 result = WERR_INSUFFICIENT_BUFFER;
7165 if (!rpcbuf_alloc_size(buffer, *needed)) {
7166 result = WERR_NOMEM;
7170 /* fill the buffer with the driver structures */
7171 for (i=0; i<*returned; i++) {
7172 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7173 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7177 for (i=0; i<*returned; i++) {
7178 SAFE_FREE(driver_info_3[i].dependentfiles);
7181 SAFE_FREE(driver_info_3);
7183 if ( !W_ERROR_IS_OK(result) )
7189 /****************************************************************************
7190 Enumerates all printer drivers.
7191 ****************************************************************************/
7193 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7195 uint32 level = q_u->level;
7196 RPC_BUFFER *buffer = NULL;
7197 uint32 offered = q_u->offered;
7198 uint32 *needed = &r_u->needed;
7199 uint32 *returned = &r_u->returned;
7200 const char *cservername;
7202 fstring architecture;
7204 /* that's an [in out] buffer */
7206 if (!q_u->buffer && (offered!=0)) {
7207 return WERR_INVALID_PARAM;
7210 rpcbuf_move(q_u->buffer, &r_u->buffer);
7211 buffer = r_u->buffer;
7213 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7218 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7219 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7221 cservername = canon_servername(servername);
7223 if (!is_myname_or_ipaddr(cservername))
7224 return WERR_UNKNOWN_PRINTER_DRIVER;
7228 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7230 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7232 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7234 return WERR_UNKNOWN_LEVEL;
7238 /****************************************************************************
7239 ****************************************************************************/
7241 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7243 form->flag=list->flag;
7244 init_unistr(&form->name, list->name);
7245 form->width=list->width;
7246 form->length=list->length;
7247 form->left=list->left;
7248 form->top=list->top;
7249 form->right=list->right;
7250 form->bottom=list->bottom;
7253 /****************************************************************************
7254 ****************************************************************************/
7256 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7257 struct spoolss_FormInfo1 *form,
7258 nt_forms_struct *list)
7260 form->form_name = talloc_strdup(mem_ctx, list->name);
7261 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7263 form->flags = list->flag;
7264 form->size.width = list->width;
7265 form->size.height = list->length;
7266 form->area.left = list->left;
7267 form->area.top = list->top;
7268 form->area.right = list->right;
7269 form->area.bottom = list->bottom;
7274 /****************************************************************************
7275 ****************************************************************************/
7277 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7279 uint32 level = q_u->level;
7280 RPC_BUFFER *buffer = NULL;
7281 uint32 offered = q_u->offered;
7282 uint32 *needed = &r_u->needed;
7283 uint32 *numofforms = &r_u->numofforms;
7284 uint32 numbuiltinforms;
7286 nt_forms_struct *list=NULL;
7287 nt_forms_struct *builtinlist=NULL;
7292 /* that's an [in out] buffer */
7294 if (!q_u->buffer && (offered!=0) ) {
7295 return WERR_INVALID_PARAM;
7298 rpcbuf_move(q_u->buffer, &r_u->buffer);
7299 buffer = r_u->buffer;
7301 DEBUG(4,("_spoolss_enumforms\n"));
7302 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7303 DEBUGADD(5,("Info level [%d]\n", level));
7305 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7306 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7307 *numofforms = get_ntforms(&list);
7308 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7309 *numofforms += numbuiltinforms;
7311 if (*numofforms == 0) {
7312 SAFE_FREE(builtinlist);
7314 return WERR_NO_MORE_ITEMS;
7319 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7320 SAFE_FREE(builtinlist);
7326 /* construct the list of form structures */
7327 for (i=0; i<numbuiltinforms; i++) {
7328 DEBUGADD(6,("Filling form number [%d]\n",i));
7329 fill_form_1(&forms_1[i], &builtinlist[i]);
7332 SAFE_FREE(builtinlist);
7334 for (; i<*numofforms; i++) {
7335 DEBUGADD(6,("Filling form number [%d]\n",i));
7336 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7341 /* check the required size. */
7342 for (i=0; i<numbuiltinforms; i++) {
7343 DEBUGADD(6,("adding form [%d]'s size\n",i));
7344 buffer_size += spoolss_size_form_1(&forms_1[i]);
7346 for (; i<*numofforms; i++) {
7347 DEBUGADD(6,("adding form [%d]'s size\n",i));
7348 buffer_size += spoolss_size_form_1(&forms_1[i]);
7351 *needed=buffer_size;
7353 if (*needed > offered) {
7356 return WERR_INSUFFICIENT_BUFFER;
7359 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7365 /* fill the buffer with the form structures */
7366 for (i=0; i<numbuiltinforms; i++) {
7367 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7368 smb_io_form_1("", buffer, &forms_1[i], 0);
7370 for (; i<*numofforms; i++) {
7371 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7372 smb_io_form_1("", buffer, &forms_1[i], 0);
7381 SAFE_FREE(builtinlist);
7382 return WERR_UNKNOWN_LEVEL;
7386 /****************************************************************
7388 ****************************************************************/
7390 WERROR _spoolss_GetForm(pipes_struct *p,
7391 struct spoolss_GetForm *r)
7393 uint32 level = r->in.level;
7394 uint32 offered = r->in.offered;
7395 uint32 *needed = r->out.needed;
7397 nt_forms_struct *list=NULL;
7398 nt_forms_struct builtin_form;
7400 union spoolss_FormInfo info;
7401 struct spoolss_FormInfo1 form_1;
7402 int numofforms=0, i=0;
7404 /* that's an [in out] buffer */
7406 if (!r->in.buffer && (offered!=0)) {
7407 return WERR_INVALID_PARAM;
7410 DEBUG(4,("_spoolss_GetForm\n"));
7411 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7412 DEBUGADD(5,("Info level [%d]\n", level));
7414 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7415 if (!foundBuiltin) {
7416 numofforms = get_ntforms(&list);
7417 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7419 if (numofforms == 0)
7426 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7429 /* Check if the requested name is in the list of form structures */
7430 for (i=0; i<numofforms; i++) {
7432 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7433 list[i].name, r->in.form_name));
7435 if (strequal(r->in.form_name, list[i].name)) {
7436 DEBUGADD(6,("Found form %s number [%d]\n",
7437 r->in.form_name, i));
7438 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7444 if (i == numofforms) {
7448 /* check the required size. */
7450 info.info1 = form_1;
7452 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7454 if (*needed > offered) {
7456 return WERR_INSUFFICIENT_BUFFER;
7459 r->out.info->info1 = form_1;
7461 /* fill the buffer with the form structures */
7462 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7463 r->in.form_name, i));
7469 return WERR_UNKNOWN_LEVEL;
7473 /****************************************************************************
7474 ****************************************************************************/
7476 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7478 init_unistr(&port->port_name, name);
7481 /****************************************************************************
7482 TODO: This probably needs distinguish between TCP/IP and Local ports
7484 ****************************************************************************/
7486 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7488 init_unistr(&port->port_name, name);
7489 init_unistr(&port->monitor_name, "Local Monitor");
7490 init_unistr(&port->description, SPL_LOCAL_PORT );
7491 port->port_type=PORT_TYPE_WRITE;
7496 /****************************************************************************
7497 wrapper around the enumer ports command
7498 ****************************************************************************/
7500 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7502 char *cmd = lp_enumports_cmd();
7503 char **qlines = NULL;
7504 char *command = NULL;
7512 /* if no hook then just fill in the default port */
7515 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7518 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7519 TALLOC_FREE(qlines);
7526 /* we have a valid enumport command */
7528 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7533 DEBUG(10,("Running [%s]\n", command));
7534 ret = smbrun(command, &fd);
7535 DEBUG(10,("Returned [%d]\n", ret));
7536 TALLOC_FREE(command);
7541 return WERR_ACCESS_DENIED;
7545 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7546 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7556 /****************************************************************************
7558 ****************************************************************************/
7560 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7562 PORT_INFO_1 *ports=NULL;
7564 WERROR result = WERR_OK;
7565 char **qlines = NULL;
7568 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7569 if (!W_ERROR_IS_OK(result)) {
7570 TALLOC_FREE(qlines);
7575 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7576 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7577 win_errstr(WERR_NOMEM)));
7578 TALLOC_FREE(qlines);
7582 for (i=0; i<numlines; i++) {
7583 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7584 fill_port_1(&ports[i], qlines[i]);
7587 TALLOC_FREE(qlines);
7589 *returned = numlines;
7591 /* check the required size. */
7592 for (i=0; i<*returned; i++) {
7593 DEBUGADD(6,("adding port [%d]'s size\n", i));
7594 *needed += spoolss_size_port_info_1(&ports[i]);
7597 if (*needed > offered) {
7598 result = WERR_INSUFFICIENT_BUFFER;
7602 if (!rpcbuf_alloc_size(buffer, *needed)) {
7603 result = WERR_NOMEM;
7607 /* fill the buffer with the ports structures */
7608 for (i=0; i<*returned; i++) {
7609 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7610 smb_io_port_1("", buffer, &ports[i], 0);
7616 if ( !W_ERROR_IS_OK(result) )
7622 /****************************************************************************
7624 ****************************************************************************/
7626 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7628 PORT_INFO_2 *ports=NULL;
7630 WERROR result = WERR_OK;
7631 char **qlines = NULL;
7634 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7635 if ( !W_ERROR_IS_OK(result)) {
7636 TALLOC_FREE(qlines);
7641 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7642 TALLOC_FREE(qlines);
7646 for (i=0; i<numlines; i++) {
7647 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7648 fill_port_2(&(ports[i]), qlines[i]);
7652 TALLOC_FREE(qlines);
7654 *returned = numlines;
7656 /* check the required size. */
7657 for (i=0; i<*returned; i++) {
7658 DEBUGADD(6,("adding port [%d]'s size\n", i));
7659 *needed += spoolss_size_port_info_2(&ports[i]);
7662 if (*needed > offered) {
7663 result = WERR_INSUFFICIENT_BUFFER;
7667 if (!rpcbuf_alloc_size(buffer, *needed)) {
7668 result = WERR_NOMEM;
7672 /* fill the buffer with the ports structures */
7673 for (i=0; i<*returned; i++) {
7674 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7675 smb_io_port_2("", buffer, &ports[i], 0);
7681 if ( !W_ERROR_IS_OK(result) )
7687 /****************************************************************************
7689 ****************************************************************************/
7691 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7693 uint32 level = q_u->level;
7694 RPC_BUFFER *buffer = NULL;
7695 uint32 offered = q_u->offered;
7696 uint32 *needed = &r_u->needed;
7697 uint32 *returned = &r_u->returned;
7699 /* that's an [in out] buffer */
7701 if (!q_u->buffer && (offered!=0)) {
7702 return WERR_INVALID_PARAM;
7705 rpcbuf_move(q_u->buffer, &r_u->buffer);
7706 buffer = r_u->buffer;
7708 DEBUG(4,("_spoolss_enumports\n"));
7715 return enumports_level_1(buffer, offered, needed, returned);
7717 return enumports_level_2(buffer, offered, needed, returned);
7719 return WERR_UNKNOWN_LEVEL;
7723 /****************************************************************************
7724 ****************************************************************************/
7726 static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
7727 const SPOOL_PRINTER_INFO_LEVEL *info,
7728 DEVICEMODE *devmode, SEC_DESC_BUF *sec_desc_buf,
7729 uint32 user_switch, const SPOOL_USER_CTR *user,
7732 NT_PRINTER_INFO_LEVEL *printer = NULL;
7735 WERROR err = WERR_OK;
7737 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7738 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7742 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7743 if (!convert_printer_info(info, printer, 2)) {
7744 free_a_printer(&printer, 2);
7748 /* check to see if the printer already exists */
7750 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7751 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7752 printer->info_2->sharename));
7753 free_a_printer(&printer, 2);
7754 return WERR_PRINTER_ALREADY_EXISTS;
7757 /* FIXME!!! smbd should check to see if the driver is installed before
7758 trying to add a printer like this --jerry */
7760 if (*lp_addprinter_cmd() ) {
7761 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7763 free_a_printer(&printer,2);
7764 return WERR_ACCESS_DENIED;
7767 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7768 "smb.conf parameter \"addprinter command\" is defined. This"
7769 "parameter must exist for this call to succeed\n",
7770 printer->info_2->sharename ));
7773 /* use our primary netbios name since get_a_printer() will convert
7774 it to what the client expects on a case by case basis */
7776 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7777 printer->info_2->sharename);
7780 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7781 free_a_printer(&printer,2);
7782 return WERR_ACCESS_DENIED;
7785 /* you must be a printer admin to add a new printer */
7786 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7787 free_a_printer(&printer,2);
7788 return WERR_ACCESS_DENIED;
7792 * Do sanity check on the requested changes for Samba.
7795 if (!check_printer_ok(printer->info_2, snum)) {
7796 free_a_printer(&printer,2);
7797 return WERR_INVALID_PARAM;
7801 * When a printer is created, the drivername bound to the printer is used
7802 * to lookup previously saved driver initialization info, which is then
7803 * bound to the new printer, simulating what happens in the Windows arch.
7808 set_driver_init(printer, 2);
7812 /* A valid devmode was included, convert and link it
7814 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7816 if (!convert_devicemode(printer->info_2->printername, devmode,
7817 &printer->info_2->devmode))
7821 /* write the ASCII on disk */
7822 err = mod_a_printer(printer, 2);
7823 if (!W_ERROR_IS_OK(err)) {
7824 free_a_printer(&printer,2);
7828 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7829 /* Handle open failed - remove addition. */
7830 del_a_printer(printer->info_2->sharename);
7831 free_a_printer(&printer,2);
7832 return WERR_ACCESS_DENIED;
7835 update_c_setprinter(False);
7836 free_a_printer(&printer,2);
7841 /****************************************************************************
7842 ****************************************************************************/
7844 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
7846 UNISTR2 *uni_srv_name = q_u->server_name;
7847 uint32 level = q_u->level;
7848 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
7849 DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
7850 SEC_DESC_BUF *sdb = q_u->secdesc_ctr;
7851 uint32 user_switch = q_u->user_switch;
7852 SPOOL_USER_CTR *user = &q_u->user_ctr;
7853 POLICY_HND *handle = &r_u->handle;
7857 /* we don't handle yet */
7858 /* but I know what to do ... */
7859 return WERR_UNKNOWN_LEVEL;
7861 return spoolss_addprinterex_level_2(p, uni_srv_name, info,
7863 user_switch, user, handle);
7865 return WERR_UNKNOWN_LEVEL;
7869 /****************************************************************************
7870 ****************************************************************************/
7872 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
7874 uint32 level = q_u->level;
7875 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
7876 WERROR err = WERR_OK;
7877 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7878 fstring driver_name;
7881 ZERO_STRUCT(driver);
7883 if (!convert_printer_driver_info(info, &driver, level)) {
7888 DEBUG(5,("Cleaning driver's information\n"));
7889 err = clean_up_driver_struct(p, driver, level);
7890 if (!W_ERROR_IS_OK(err))
7893 DEBUG(5,("Moving driver to final destination\n"));
7894 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7899 if (add_a_printer_driver(driver, level)!=0) {
7900 err = WERR_ACCESS_DENIED;
7906 fstrcpy(driver_name,
7907 driver.info_3->name ? driver.info_3->name : "");
7910 fstrcpy(driver_name,
7911 driver.info_6->name ? driver.info_6->name : "");
7916 * I think this is where he DrvUpgradePrinter() hook would be
7917 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7918 * server. Right now, we just need to send ourselves a message
7919 * to update each printer bound to this driver. --jerry
7922 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7923 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
7928 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7929 * decide if the driver init data should be deleted. The rules are:
7930 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7931 * 2) delete init data only if there is no 2k/Xp driver
7932 * 3) always delete init data
7933 * The generalized rule is always use init data from the highest order driver.
7934 * It is necessary to follow the driver install by an initialization step to
7935 * finish off this process.
7938 version = driver.info_3->cversion;
7939 else if (level == 6)
7940 version = driver.info_6->version;
7945 * 9x printer driver - never delete init data
7948 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
7953 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7954 * there is no 2k/Xp driver init data for this driver name.
7958 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7960 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7962 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7964 if (!del_driver_init(driver_name))
7965 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
7968 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7970 free_a_printer_driver(driver1,3);
7971 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
7978 * 2k or Xp printer driver - always delete init data
7981 if (!del_driver_init(driver_name))
7982 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
7986 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
7992 free_a_printer_driver(driver, level);
7996 /********************************************************************
7997 * spoolss_addprinterdriverex
7998 ********************************************************************/
8000 WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
8002 SPOOL_Q_ADDPRINTERDRIVER q_u_local;
8003 SPOOL_R_ADDPRINTERDRIVER r_u_local;
8006 * we only support the semantics of AddPrinterDriver()
8007 * i.e. only copy files that are newer than existing ones
8010 if ( q_u->copy_flags != APD_COPY_NEW_FILES )
8011 return WERR_ACCESS_DENIED;
8013 ZERO_STRUCT(q_u_local);
8014 ZERO_STRUCT(r_u_local);
8016 /* just pass the information off to _spoolss_addprinterdriver() */
8017 q_u_local.server_name_ptr = q_u->server_name_ptr;
8018 copy_unistr2(&q_u_local.server_name, &q_u->server_name);
8019 q_u_local.level = q_u->level;
8020 memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
8022 return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
8025 /****************************************************************************
8026 ****************************************************************************/
8028 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
8030 init_unistr(&info->name, name);
8033 /****************************************************************************
8034 ****************************************************************************/
8036 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
8039 char *long_archi = NULL;
8040 char *servername = NULL;
8041 const char *pservername = NULL;
8042 const char *short_archi;
8043 DRIVER_DIRECTORY_1 *info=NULL;
8044 WERROR result = WERR_OK;
8045 TALLOC_CTX *ctx = talloc_tos();
8047 servername = unistr2_to_ascii_talloc(ctx, name);
8051 long_archi = unistr2_to_ascii_talloc(ctx, uni_environment);
8056 pservername = canon_servername(servername);
8058 if ( !is_myname_or_ipaddr(pservername))
8059 return WERR_INVALID_PARAM;
8061 if (!(short_archi = get_short_archi(long_archi)))
8062 return WERR_INVALID_ENVIRONMENT;
8064 if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
8067 path = talloc_asprintf(ctx,
8068 "\\\\%s\\print$\\%s", pservername, short_archi);
8070 result = WERR_NOMEM;
8074 DEBUG(4,("printer driver directory: [%s]\n", path));
8076 fill_driverdir_1(info, path);
8078 *needed += spoolss_size_driverdir_info_1(info);
8080 if (*needed > offered) {
8081 result = WERR_INSUFFICIENT_BUFFER;
8085 if (!rpcbuf_alloc_size(buffer, *needed)) {
8086 result = WERR_NOMEM;
8090 smb_io_driverdir_1("", buffer, info, 0);
8098 /****************************************************************************
8099 ****************************************************************************/
8101 WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
8103 UNISTR2 *name = &q_u->name;
8104 UNISTR2 *uni_environment = &q_u->environment;
8105 uint32 level = q_u->level;
8106 RPC_BUFFER *buffer = NULL;
8107 uint32 offered = q_u->offered;
8108 uint32 *needed = &r_u->needed;
8110 /* that's an [in out] buffer */
8112 if (!q_u->buffer && (offered!=0)) {
8113 return WERR_INVALID_PARAM;
8116 rpcbuf_move(q_u->buffer, &r_u->buffer);
8117 buffer = r_u->buffer;
8119 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8125 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
8127 return WERR_UNKNOWN_LEVEL;
8131 /****************************************************************************
8132 ****************************************************************************/
8134 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8136 POLICY_HND *handle = &q_u->handle;
8137 uint32 idx = q_u->index;
8138 uint32 in_value_len = q_u->valuesize;
8139 uint32 in_data_len = q_u->datasize;
8140 uint32 *out_max_value_len = &r_u->valuesize;
8141 uint16 **out_value = &r_u->value;
8142 uint32 *out_value_len = &r_u->realvaluesize;
8143 uint32 *out_type = &r_u->type;
8144 uint32 *out_max_data_len = &r_u->datasize;
8145 uint8 **data_out = &r_u->data;
8146 uint32 *out_data_len = &r_u->realdatasize;
8148 NT_PRINTER_INFO_LEVEL *printer = NULL;
8150 uint32 biggest_valuesize;
8151 uint32 biggest_datasize;
8153 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8156 REGISTRY_VALUE *val = NULL;
8157 NT_PRINTER_DATA *p_data;
8158 int i, key_index, num_values;
8163 *out_max_data_len = 0;
8167 DEBUG(5,("spoolss_enumprinterdata\n"));
8170 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8174 if (!get_printer_snum(p,handle, &snum, NULL))
8177 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8178 if (!W_ERROR_IS_OK(result))
8181 p_data = printer->info_2->data;
8182 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8187 * The NT machine wants to know the biggest size of value and data
8189 * cf: MSDN EnumPrinterData remark section
8192 if ( !in_value_len && !in_data_len && (key_index != -1) )
8194 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8196 biggest_valuesize = 0;
8197 biggest_datasize = 0;
8199 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8201 for ( i=0; i<num_values; i++ )
8203 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8205 name_length = strlen(val->valuename);
8206 if ( strlen(val->valuename) > biggest_valuesize )
8207 biggest_valuesize = name_length;
8209 if ( val->size > biggest_datasize )
8210 biggest_datasize = val->size;
8212 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8216 /* the value is an UNICODE string but real_value_size is the length
8217 in bytes including the trailing 0 */
8219 *out_value_len = 2 * (1+biggest_valuesize);
8220 *out_data_len = biggest_datasize;
8222 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8228 * the value len is wrong in NT sp3
8229 * that's the number of bytes not the number of unicode chars
8232 if ( key_index != -1 )
8233 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8238 /* out_value should default to "" or else NT4 has
8239 problems unmarshalling the response */
8241 *out_max_value_len=(in_value_len/sizeof(uint16));
8244 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8246 result = WERR_NOMEM;
8249 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8255 /* the data is counted in bytes */
8257 *out_max_data_len = in_data_len;
8258 *out_data_len = in_data_len;
8260 /* only allocate when given a non-zero data_len */
8262 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8264 result = WERR_NOMEM;
8268 result = WERR_NO_MORE_ITEMS;
8274 * - counted in bytes in the request
8275 * - counted in UNICODE chars in the max reply
8276 * - counted in bytes in the real size
8278 * take a pause *before* coding not *during* coding
8282 *out_max_value_len=(in_value_len/sizeof(uint16));
8284 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8286 result = WERR_NOMEM;
8290 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8298 *out_type = regval_type( val );
8300 /* data - counted in bytes */
8302 *out_max_data_len = in_data_len;
8303 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8305 result = WERR_NOMEM;
8308 data_len = regval_size(val);
8309 if ( *data_out && data_len )
8310 memcpy( *data_out, regval_data_p(val), data_len );
8311 *out_data_len = data_len;
8315 free_a_printer(&printer, 2);
8319 /****************************************************************************
8320 ****************************************************************************/
8322 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8324 POLICY_HND *handle = &q_u->handle;
8325 UNISTR2 *value = &q_u->value;
8326 uint32 type = q_u->type;
8327 uint8 *data = q_u->data;
8328 uint32 real_len = q_u->real_len;
8330 NT_PRINTER_INFO_LEVEL *printer = NULL;
8332 WERROR status = WERR_OK;
8333 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8336 DEBUG(5,("spoolss_setprinterdata\n"));
8339 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8343 if ( Printer->printer_type == SPLHND_SERVER ) {
8344 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8345 return WERR_INVALID_PARAM;
8348 if (!get_printer_snum(p,handle, &snum, NULL))
8352 * Access check : NT returns "access denied" if you make a
8353 * SetPrinterData call without the necessary privildge.
8354 * we were originally returning OK if nothing changed
8355 * which made Win2k issue **a lot** of SetPrinterData
8356 * when connecting to a printer --jerry
8359 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8361 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8362 status = WERR_ACCESS_DENIED;
8366 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8367 if (!W_ERROR_IS_OK(status))
8370 unistr2_to_ascii(valuename, value, sizeof(valuename));
8373 * When client side code sets a magic printer data key, detect it and save
8374 * the current printer data and the magic key's data (its the DEVMODE) for
8375 * future printer/driver initializations.
8377 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8379 /* Set devmode and printer initialization info */
8380 status = save_driver_init( printer, 2, data, real_len );
8382 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8386 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8387 type, data, real_len );
8388 if ( W_ERROR_IS_OK(status) )
8389 status = mod_a_printer(printer, 2);
8393 free_a_printer(&printer, 2);
8398 /****************************************************************************
8399 ****************************************************************************/
8401 WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
8403 POLICY_HND *handle = &q_u->handle;
8404 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8407 DEBUG(5,("_spoolss_resetprinter\n"));
8410 * All we do is to check to see if the handle and queue is valid.
8411 * This call really doesn't mean anything to us because we only
8412 * support RAW printing. --jerry
8416 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8420 if (!get_printer_snum(p,handle, &snum, NULL))
8424 /* blindly return success */
8428 /****************************************************************
8429 _spoolss_DeletePrinterData
8430 ****************************************************************/
8432 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8433 struct spoolss_DeletePrinterData *r)
8435 POLICY_HND *handle = r->in.handle;
8436 NT_PRINTER_INFO_LEVEL *printer = NULL;
8438 WERROR status = WERR_OK;
8439 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8441 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8444 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8445 OUR_HANDLE(handle)));
8449 if (!get_printer_snum(p, handle, &snum, NULL))
8452 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8453 DEBUG(3, ("_spoolss_DeletePrinterData: "
8454 "printer properties change denied by handle\n"));
8455 return WERR_ACCESS_DENIED;
8458 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8459 if (!W_ERROR_IS_OK(status))
8462 if (!r->in.value_name) {
8463 free_a_printer(&printer, 2);
8467 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8470 if ( W_ERROR_IS_OK(status) )
8471 mod_a_printer( printer, 2 );
8473 free_a_printer(&printer, 2);
8478 /****************************************************************
8480 ****************************************************************/
8482 WERROR _spoolss_AddForm(pipes_struct *p,
8483 struct spoolss_AddForm *r)
8485 POLICY_HND *handle = r->in.handle;
8486 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8487 nt_forms_struct tmpForm;
8489 WERROR status = WERR_OK;
8490 NT_PRINTER_INFO_LEVEL *printer = NULL;
8493 nt_forms_struct *list=NULL;
8494 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8496 DEBUG(5,("_spoolss_AddForm\n"));
8499 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8500 OUR_HANDLE(handle)));
8505 /* forms can be added on printer of on the print server handle */
8507 if ( Printer->printer_type == SPLHND_PRINTER )
8509 if (!get_printer_snum(p,handle, &snum, NULL))
8512 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8513 if (!W_ERROR_IS_OK(status))
8517 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8518 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8519 status = WERR_ACCESS_DENIED;
8523 /* can't add if builtin */
8525 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8526 status = WERR_FILE_EXISTS;
8530 count = get_ntforms(&list);
8532 if(!add_a_form(&list, form, &count)) {
8533 status = WERR_NOMEM;
8537 write_ntforms(&list, count);
8540 * ChangeID must always be set if this is a printer
8543 if ( Printer->printer_type == SPLHND_PRINTER )
8544 status = mod_a_printer(printer, 2);
8548 free_a_printer(&printer, 2);
8554 /****************************************************************
8556 ****************************************************************/
8558 WERROR _spoolss_DeleteForm(pipes_struct *p,
8559 struct spoolss_DeleteForm *r)
8561 POLICY_HND *handle = r->in.handle;
8562 const char *form_name = r->in.form_name;
8563 nt_forms_struct tmpForm;
8565 nt_forms_struct *list=NULL;
8566 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8568 WERROR status = WERR_OK;
8569 NT_PRINTER_INFO_LEVEL *printer = NULL;
8571 DEBUG(5,("_spoolss_DeleteForm\n"));
8574 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8575 OUR_HANDLE(handle)));
8579 /* forms can be deleted on printer of on the print server handle */
8581 if ( Printer->printer_type == SPLHND_PRINTER )
8583 if (!get_printer_snum(p,handle, &snum, NULL))
8586 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8587 if (!W_ERROR_IS_OK(status))
8591 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8592 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8593 status = WERR_ACCESS_DENIED;
8597 /* can't delete if builtin */
8599 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8600 status = WERR_INVALID_PARAM;
8604 count = get_ntforms(&list);
8606 if ( !delete_a_form(&list, form_name, &count, &status ))
8610 * ChangeID must always be set if this is a printer
8613 if ( Printer->printer_type == SPLHND_PRINTER )
8614 status = mod_a_printer(printer, 2);
8618 free_a_printer(&printer, 2);
8624 /****************************************************************
8626 ****************************************************************/
8628 WERROR _spoolss_SetForm(pipes_struct *p,
8629 struct spoolss_SetForm *r)
8631 POLICY_HND *handle = r->in.handle;
8632 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8633 nt_forms_struct tmpForm;
8635 WERROR status = WERR_OK;
8636 NT_PRINTER_INFO_LEVEL *printer = NULL;
8639 nt_forms_struct *list=NULL;
8640 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8642 DEBUG(5,("_spoolss_SetForm\n"));
8645 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8646 OUR_HANDLE(handle)));
8650 /* forms can be modified on printer of on the print server handle */
8652 if ( Printer->printer_type == SPLHND_PRINTER )
8654 if (!get_printer_snum(p,handle, &snum, NULL))
8657 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8658 if (!W_ERROR_IS_OK(status))
8662 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8663 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8664 status = WERR_ACCESS_DENIED;
8668 /* can't set if builtin */
8669 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8670 status = WERR_INVALID_PARAM;
8674 count = get_ntforms(&list);
8675 update_a_form(&list, form, count);
8676 write_ntforms(&list, count);
8679 * ChangeID must always be set if this is a printer
8682 if ( Printer->printer_type == SPLHND_PRINTER )
8683 status = mod_a_printer(printer, 2);
8688 free_a_printer(&printer, 2);
8694 /****************************************************************************
8695 enumprintprocessors level 1.
8696 ****************************************************************************/
8698 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8700 PRINTPROCESSOR_1 *info_1=NULL;
8701 WERROR result = WERR_OK;
8703 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8708 init_unistr(&info_1->name, "winprint");
8710 *needed += spoolss_size_printprocessor_info_1(info_1);
8712 if (*needed > offered) {
8713 result = WERR_INSUFFICIENT_BUFFER;
8717 if (!rpcbuf_alloc_size(buffer, *needed)) {
8718 result = WERR_NOMEM;
8722 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8727 if ( !W_ERROR_IS_OK(result) )
8733 /****************************************************************************
8734 ****************************************************************************/
8736 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8738 uint32 level = q_u->level;
8739 RPC_BUFFER *buffer = NULL;
8740 uint32 offered = q_u->offered;
8741 uint32 *needed = &r_u->needed;
8742 uint32 *returned = &r_u->returned;
8744 /* that's an [in out] buffer */
8746 if (!q_u->buffer && (offered!=0)) {
8747 return WERR_INVALID_PARAM;
8750 rpcbuf_move(q_u->buffer, &r_u->buffer);
8751 buffer = r_u->buffer;
8753 DEBUG(5,("spoolss_enumprintprocessors\n"));
8756 * Enumerate the print processors ...
8758 * Just reply with "winprint", to keep NT happy
8759 * and I can use my nice printer checker.
8767 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8769 return WERR_UNKNOWN_LEVEL;
8773 /****************************************************************************
8774 enumprintprocdatatypes level 1.
8775 ****************************************************************************/
8777 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8779 PRINTPROCDATATYPE_1 *info_1=NULL;
8780 WERROR result = WERR_OK;
8782 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8787 init_unistr(&info_1->name, "RAW");
8789 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8791 if (*needed > offered) {
8792 result = WERR_INSUFFICIENT_BUFFER;
8796 if (!rpcbuf_alloc_size(buffer, *needed)) {
8797 result = WERR_NOMEM;
8801 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8806 if ( !W_ERROR_IS_OK(result) )
8812 /****************************************************************************
8813 ****************************************************************************/
8815 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8817 uint32 level = q_u->level;
8818 RPC_BUFFER *buffer = NULL;
8819 uint32 offered = q_u->offered;
8820 uint32 *needed = &r_u->needed;
8821 uint32 *returned = &r_u->returned;
8823 /* that's an [in out] buffer */
8825 if (!q_u->buffer && (offered!=0)) {
8826 return WERR_INVALID_PARAM;
8829 rpcbuf_move(q_u->buffer, &r_u->buffer);
8830 buffer = r_u->buffer;
8832 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8839 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8841 return WERR_UNKNOWN_LEVEL;
8845 /****************************************************************************
8846 enumprintmonitors level 1.
8847 ****************************************************************************/
8849 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8851 PRINTMONITOR_1 *info_1;
8852 WERROR result = WERR_OK;
8855 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8860 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8861 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8863 for ( i=0; i<*returned; i++ ) {
8864 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8867 if (*needed > offered) {
8868 result = WERR_INSUFFICIENT_BUFFER;
8872 if (!rpcbuf_alloc_size(buffer, *needed)) {
8873 result = WERR_NOMEM;
8877 for ( i=0; i<*returned; i++ ) {
8878 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8884 if ( !W_ERROR_IS_OK(result) )
8890 /****************************************************************************
8891 enumprintmonitors level 2.
8892 ****************************************************************************/
8894 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8896 PRINTMONITOR_2 *info_2;
8897 WERROR result = WERR_OK;
8900 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8905 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8906 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8907 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8909 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8910 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8911 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8913 for ( i=0; i<*returned; i++ ) {
8914 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8917 if (*needed > offered) {
8918 result = WERR_INSUFFICIENT_BUFFER;
8922 if (!rpcbuf_alloc_size(buffer, *needed)) {
8923 result = WERR_NOMEM;
8927 for ( i=0; i<*returned; i++ ) {
8928 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8934 if ( !W_ERROR_IS_OK(result) )
8940 /****************************************************************************
8941 ****************************************************************************/
8943 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8945 uint32 level = q_u->level;
8946 RPC_BUFFER *buffer = NULL;
8947 uint32 offered = q_u->offered;
8948 uint32 *needed = &r_u->needed;
8949 uint32 *returned = &r_u->returned;
8951 /* that's an [in out] buffer */
8953 if (!q_u->buffer && (offered!=0)) {
8954 return WERR_INVALID_PARAM;
8957 rpcbuf_move(q_u->buffer, &r_u->buffer);
8958 buffer = r_u->buffer;
8960 DEBUG(5,("spoolss_enumprintmonitors\n"));
8963 * Enumerate the print monitors ...
8965 * Just reply with "Local Port", to keep NT happy
8966 * and I can use my nice printer checker.
8974 return enumprintmonitors_level_1(buffer, offered, needed, returned);
8976 return enumprintmonitors_level_2(buffer, offered, needed, returned);
8978 return WERR_UNKNOWN_LEVEL;
8982 /****************************************************************************
8983 ****************************************************************************/
8985 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
8986 NT_PRINTER_INFO_LEVEL *ntprinter,
8987 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
8992 JOB_INFO_1 *info_1=NULL;
8993 WERROR result = WERR_OK;
8995 info_1=SMB_MALLOC_P(JOB_INFO_1);
8997 if (info_1 == NULL) {
9001 for (i=0; i<count && found==False; i++) {
9002 if ((*queue)[i].job==(int)jobid)
9008 /* NT treats not found as bad param... yet another bad choice */
9009 return WERR_INVALID_PARAM;
9012 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9014 *needed += spoolss_size_job_info_1(info_1);
9016 if (*needed > offered) {
9017 result = WERR_INSUFFICIENT_BUFFER;
9021 if (!rpcbuf_alloc_size(buffer, *needed)) {
9022 result = WERR_NOMEM;
9026 smb_io_job_info_1("", buffer, info_1, 0);
9034 /****************************************************************************
9035 ****************************************************************************/
9037 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9038 NT_PRINTER_INFO_LEVEL *ntprinter,
9039 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9046 DEVICEMODE *devmode = NULL;
9047 NT_DEVICEMODE *nt_devmode = NULL;
9049 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9052 ZERO_STRUCTP(info_2);
9054 for ( i=0; i<count && found==False; i++ )
9056 if ((*queue)[i].job == (int)jobid)
9061 /* NT treats not found as bad param... yet another bad
9063 result = WERR_INVALID_PARAM;
9068 * if the print job does not have a DEVMODE associated with it,
9069 * just use the one for the printer. A NULL devicemode is not
9070 * a failure condition
9073 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9074 devmode = construct_dev_mode(lp_const_servicename(snum));
9076 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9077 ZERO_STRUCTP( devmode );
9078 convert_nt_devicemode( devmode, nt_devmode );
9082 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9084 *needed += spoolss_size_job_info_2(info_2);
9086 if (*needed > offered) {
9087 result = WERR_INSUFFICIENT_BUFFER;
9091 if (!rpcbuf_alloc_size(buffer, *needed)) {
9092 result = WERR_NOMEM;
9096 smb_io_job_info_2("", buffer, info_2, 0);
9101 /* Cleanup allocated memory */
9103 free_job_info_2(info_2); /* Also frees devmode */
9109 /****************************************************************************
9110 ****************************************************************************/
9112 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9114 POLICY_HND *handle = &q_u->handle;
9115 uint32 jobid = q_u->jobid;
9116 uint32 level = q_u->level;
9117 RPC_BUFFER *buffer = NULL;
9118 uint32 offered = q_u->offered;
9119 uint32 *needed = &r_u->needed;
9120 WERROR wstatus = WERR_OK;
9121 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9124 print_queue_struct *queue = NULL;
9125 print_status_struct prt_status;
9127 /* that's an [in out] buffer */
9129 if (!q_u->buffer && (offered!=0)) {
9130 return WERR_INVALID_PARAM;
9133 rpcbuf_move(q_u->buffer, &r_u->buffer);
9134 buffer = r_u->buffer;
9136 DEBUG(5,("spoolss_getjob\n"));
9140 if (!get_printer_snum(p, handle, &snum, NULL))
9143 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9144 if ( !W_ERROR_IS_OK(wstatus) )
9147 count = print_queue_status(snum, &queue, &prt_status);
9149 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9150 count, prt_status.status, prt_status.message));
9154 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9155 buffer, offered, needed);
9158 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9159 buffer, offered, needed);
9162 wstatus = WERR_UNKNOWN_LEVEL;
9167 free_a_printer( &ntprinter, 2 );
9172 /********************************************************************
9173 spoolss_getprinterdataex
9175 From MSDN documentation of GetPrinterDataEx: pass request
9176 to GetPrinterData if key is "PrinterDriverData".
9177 ********************************************************************/
9179 WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
9181 POLICY_HND *handle = &q_u->handle;
9182 uint32 in_size = q_u->size;
9183 uint32 *type = &r_u->type;
9184 uint32 *out_size = &r_u->size;
9185 uint8 **data = &r_u->data;
9186 uint32 *needed = &r_u->needed;
9187 fstring keyname, valuename;
9189 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9191 NT_PRINTER_INFO_LEVEL *printer = NULL;
9193 WERROR status = WERR_OK;
9195 DEBUG(4,("_spoolss_getprinterdataex\n"));
9197 unistr2_to_ascii(keyname, &q_u->keyname, sizeof(keyname));
9198 unistr2_to_ascii(valuename, &q_u->valuename, sizeof(valuename));
9200 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
9201 keyname, valuename));
9203 /* in case of problem, return some default values */
9207 *out_size = in_size;
9210 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9211 status = WERR_BADFID;
9215 /* Is the handle to a printer or to the server? */
9217 if (Printer->printer_type == SPLHND_SERVER) {
9218 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
9219 status = WERR_INVALID_PARAM;
9223 if ( !get_printer_snum(p,handle, &snum, NULL) )
9226 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9227 if ( !W_ERROR_IS_OK(status) )
9230 /* check to see if the keyname is valid */
9231 if ( !strlen(keyname) ) {
9232 status = WERR_INVALID_PARAM;
9236 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9237 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname ));
9238 free_a_printer( &printer, 2 );
9239 status = WERR_BADFILE;
9243 /* When given a new keyname, we should just create it */
9245 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, type, data, needed, in_size );
9247 if (*needed > *out_size)
9248 status = WERR_MORE_DATA;
9251 if ( !W_ERROR_IS_OK(status) )
9253 DEBUG(5, ("error: allocating %d\n", *out_size));
9255 /* reply this param doesn't exist */
9259 if( (*data=(uint8 *)TALLOC_ZERO(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
9260 status = WERR_NOMEM;
9269 free_a_printer( &printer, 2 );
9274 /********************************************************************
9275 * spoolss_setprinterdataex
9276 ********************************************************************/
9278 WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u)
9280 POLICY_HND *handle = &q_u->handle;
9281 uint32 type = q_u->type;
9282 uint8 *data = q_u->data;
9283 uint32 real_len = q_u->real_len;
9285 NT_PRINTER_INFO_LEVEL *printer = NULL;
9287 WERROR status = WERR_OK;
9288 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9293 DEBUG(4,("_spoolss_setprinterdataex\n"));
9295 /* From MSDN documentation of SetPrinterDataEx: pass request to
9296 SetPrinterData if key is "PrinterDriverData" */
9299 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9303 if ( Printer->printer_type == SPLHND_SERVER ) {
9304 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
9305 return WERR_INVALID_PARAM;
9308 if ( !get_printer_snum(p,handle, &snum, NULL) )
9312 * Access check : NT returns "access denied" if you make a
9313 * SetPrinterData call without the necessary privildge.
9314 * we were originally returning OK if nothing changed
9315 * which made Win2k issue **a lot** of SetPrinterData
9316 * when connecting to a printer --jerry
9319 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9321 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
9322 return WERR_ACCESS_DENIED;
9325 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9326 if (!W_ERROR_IS_OK(status))
9329 unistr2_to_ascii( valuename, &q_u->value, sizeof(valuename));
9330 unistr2_to_ascii( keyname, &q_u->key, sizeof(keyname));
9332 /* check for OID in valuename */
9334 if ( (oid_string = strchr( valuename, ',' )) != NULL )
9340 /* save the registry data */
9342 status = set_printer_dataex( printer, keyname, valuename, type, data, real_len );
9344 if ( W_ERROR_IS_OK(status) )
9346 /* save the OID if one was specified */
9348 fstrcat( keyname, "\\" );
9349 fstrcat( keyname, SPOOL_OID_KEY );
9352 * I'm not checking the status here on purpose. Don't know
9353 * if this is right, but I'm returning the status from the
9354 * previous set_printer_dataex() call. I have no idea if
9355 * this is right. --jerry
9358 set_printer_dataex( printer, keyname, valuename,
9359 REG_SZ, (uint8 *)oid_string,
9360 strlen(oid_string)+1 );
9363 status = mod_a_printer(printer, 2);
9366 free_a_printer(&printer, 2);
9371 /****************************************************************
9372 _spoolss_DeletePrinterDataEx
9373 ****************************************************************/
9375 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9376 struct spoolss_DeletePrinterDataEx *r)
9378 POLICY_HND *handle = r->in.handle;
9379 NT_PRINTER_INFO_LEVEL *printer = NULL;
9381 WERROR status = WERR_OK;
9382 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9384 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9387 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9388 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9392 if (!get_printer_snum(p, handle, &snum, NULL))
9395 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9396 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9397 "printer properties change denied by handle\n"));
9398 return WERR_ACCESS_DENIED;
9401 if (!r->in.value_name || !r->in.key_name) {
9405 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9406 if (!W_ERROR_IS_OK(status))
9409 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9411 if ( W_ERROR_IS_OK(status) )
9412 mod_a_printer( printer, 2 );
9414 free_a_printer(&printer, 2);
9419 /********************************************************************
9420 * spoolss_enumprinterkey
9421 ********************************************************************/
9424 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9427 fstring *keynames = NULL;
9428 uint16 *enumkeys = NULL;
9431 POLICY_HND *handle = &q_u->handle;
9432 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9433 NT_PRINTER_DATA *data;
9434 NT_PRINTER_INFO_LEVEL *printer = NULL;
9436 WERROR status = WERR_BADFILE;
9439 DEBUG(4,("_spoolss_enumprinterkey\n"));
9442 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9446 if ( !get_printer_snum(p,handle, &snum, NULL) )
9449 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9450 if (!W_ERROR_IS_OK(status))
9453 /* get the list of subkey names */
9455 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9456 data = printer->info_2->data;
9458 num_keys = get_printer_subkeys( data, key, &keynames );
9460 if ( num_keys == -1 ) {
9461 status = WERR_BADFILE;
9465 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9467 r_u->needed = printerkey_len*2;
9469 if ( q_u->size < r_u->needed ) {
9470 status = WERR_MORE_DATA;
9474 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9475 status = WERR_NOMEM;
9481 if ( q_u->size < r_u->needed )
9482 status = WERR_MORE_DATA;
9485 free_a_printer( &printer, 2 );
9486 SAFE_FREE( keynames );
9491 /****************************************************************
9492 _spoolss_DeletePrinterKey
9493 ****************************************************************/
9495 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9496 struct spoolss_DeletePrinterKey *r)
9498 POLICY_HND *handle = r->in.handle;
9499 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9500 NT_PRINTER_INFO_LEVEL *printer = NULL;
9504 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9507 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9508 OUR_HANDLE(handle)));
9512 /* if keyname == NULL, return error */
9514 if ( !r->in.key_name )
9515 return WERR_INVALID_PARAM;
9517 if (!get_printer_snum(p, handle, &snum, NULL))
9520 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9521 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9522 "printer properties change denied by handle\n"));
9523 return WERR_ACCESS_DENIED;
9526 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9527 if (!W_ERROR_IS_OK(status))
9530 /* delete the key and all subneys */
9532 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9534 if ( W_ERROR_IS_OK(status) )
9535 status = mod_a_printer(printer, 2);
9537 free_a_printer( &printer, 2 );
9543 /********************************************************************
9544 * spoolss_enumprinterdataex
9545 ********************************************************************/
9547 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9549 POLICY_HND *handle = &q_u->handle;
9550 uint32 in_size = q_u->size;
9553 NT_PRINTER_INFO_LEVEL *printer = NULL;
9554 PRINTER_ENUM_VALUES *enum_values = NULL;
9555 NT_PRINTER_DATA *p_data;
9557 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9562 REGISTRY_VALUE *val;
9567 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9570 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9575 * first check for a keyname of NULL or "". Win2k seems to send
9576 * this a lot and we should send back WERR_INVALID_PARAM
9577 * no need to spend time looking up the printer in this case.
9581 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9582 if ( !strlen(key) ) {
9583 result = WERR_INVALID_PARAM;
9587 /* get the printer off of disk */
9589 if (!get_printer_snum(p,handle, &snum, NULL))
9592 ZERO_STRUCT(printer);
9593 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9594 if (!W_ERROR_IS_OK(result))
9597 /* now look for a match on the key name */
9599 p_data = printer->info_2->data;
9601 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9602 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9604 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9605 result = WERR_INVALID_PARAM;
9612 /* allocate the memory for the array of pointers -- if necessary */
9614 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9617 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9619 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9620 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9621 result = WERR_NOMEM;
9625 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9629 * loop through all params and build the array to pass
9630 * back to the client
9633 for ( i=0; i<num_entries; i++ )
9635 /* lookup the registry value */
9637 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9638 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9642 value_name = regval_name( val );
9643 init_unistr( &enum_values[i].valuename, value_name );
9644 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9645 enum_values[i].type = regval_type( val );
9647 data_len = regval_size( val );
9649 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9651 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9653 result = WERR_NOMEM;
9657 enum_values[i].data_len = data_len;
9659 /* keep track of the size of the array in bytes */
9661 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9664 /* housekeeping information in the reply */
9666 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9667 * the hand marshalled container size is a multiple
9668 * of 4 bytes for RPC alignment.
9672 needed += 4-(needed % 4);
9675 r_u->needed = needed;
9676 r_u->returned = num_entries;
9678 if (needed > in_size) {
9679 result = WERR_MORE_DATA;
9683 /* copy data into the reply */
9685 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9686 response buffer size is != the offered buffer size
9688 r_u->ctr.size = r_u->needed;
9690 r_u->ctr.size = in_size;
9692 r_u->ctr.size_of_array = r_u->returned;
9693 r_u->ctr.values = enum_values;
9697 free_a_printer(&printer, 2);
9702 /****************************************************************************
9703 ****************************************************************************/
9705 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, const char *name)
9707 init_unistr(&info->name, name);
9710 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
9711 UNISTR2 *environment,
9716 char *long_archi = NULL;
9717 PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
9718 WERROR result = WERR_OK;
9719 TALLOC_CTX *ctx = talloc_tos();
9721 long_archi = unistr2_to_ascii_talloc(ctx, environment);
9726 if (!get_short_archi(long_archi))
9727 return WERR_INVALID_ENVIRONMENT;
9729 if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
9732 fill_printprocessordirectory_1(info, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9734 *needed += spoolss_size_printprocessordirectory_info_1(info);
9736 if (*needed > offered) {
9737 result = WERR_INSUFFICIENT_BUFFER;
9741 if (!rpcbuf_alloc_size(buffer, *needed)) {
9742 result = WERR_INSUFFICIENT_BUFFER;
9746 smb_io_printprocessordirectory_1("", buffer, info, 0);
9754 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
9756 uint32 level = q_u->level;
9757 RPC_BUFFER *buffer = NULL;
9758 uint32 offered = q_u->offered;
9759 uint32 *needed = &r_u->needed;
9762 /* that's an [in out] buffer */
9764 if (!q_u->buffer && (offered!=0)) {
9765 return WERR_INVALID_PARAM;
9768 rpcbuf_move(q_u->buffer, &r_u->buffer);
9769 buffer = r_u->buffer;
9771 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9777 result = getprintprocessordirectory_level_1
9778 (&q_u->name, &q_u->environment, buffer, offered, needed);
9781 result = WERR_UNKNOWN_LEVEL;
9787 /*******************************************************************
9788 Streams the monitor UI DLL name in UNICODE
9789 *******************************************************************/
9791 static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
9792 RPC_BUFFER *out, uint32 *needed )
9794 const char *dllname = "tcpmonui.dll";
9796 *needed = (strlen(dllname)+1) * 2;
9798 if ( rpcbuf_get_size(out) < *needed ) {
9799 return WERR_INSUFFICIENT_BUFFER;
9802 if ( !make_monitorui_buf( out, dllname ) ) {
9809 /*******************************************************************
9810 Create a new TCP/IP port
9811 *******************************************************************/
9813 static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in,
9814 RPC_BUFFER *out, uint32 *needed )
9816 NT_PORT_DATA_1 port1;
9817 TALLOC_CTX *ctx = talloc_tos();
9818 char *device_uri = NULL;
9820 ZERO_STRUCT( port1 );
9822 /* convert to our internal port data structure */
9824 if ( !convert_port_data_1( &port1, in ) ) {
9828 /* create the device URI and call the add_port_hook() */
9830 switch ( port1.protocol ) {
9831 case PORT_PROTOCOL_DIRECT:
9832 device_uri = talloc_asprintf(ctx,
9833 "socket://%s:%d/", port1.hostaddr, port1.port );
9836 case PORT_PROTOCOL_LPR:
9837 device_uri = talloc_asprintf(ctx,
9838 "lpr://%s/%s", port1.hostaddr, port1.queue );
9842 return WERR_UNKNOWN_PORT;
9849 return add_port_hook(ctx, token, port1.name, device_uri );
9852 /*******************************************************************
9853 *******************************************************************/
9855 struct xcv_api_table xcvtcp_cmds[] = {
9856 { "MonitorUI", xcvtcp_monitorui },
9857 { "AddPort", xcvtcp_addport},
9861 static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command,
9862 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
9867 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9869 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9870 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9871 return xcvtcp_cmds[i].fn( token, inbuf, outbuf, needed );
9874 return WERR_BADFUNC;
9877 /*******************************************************************
9878 *******************************************************************/
9879 #if 0 /* don't support management using the "Local Port" monitor */
9881 static WERROR xcvlocal_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
9882 RPC_BUFFER *out, uint32 *needed )
9884 const char *dllname = "localui.dll";
9886 *needed = (strlen(dllname)+1) * 2;
9888 if ( rpcbuf_get_size(out) < *needed ) {
9889 return WERR_INSUFFICIENT_BUFFER;
9892 if ( !make_monitorui_buf( out, dllname )) {
9899 /*******************************************************************
9900 *******************************************************************/
9902 struct xcv_api_table xcvlocal_cmds[] = {
9903 { "MonitorUI", xcvlocal_monitorui },
9907 struct xcv_api_table xcvlocal_cmds[] = {
9914 /*******************************************************************
9915 *******************************************************************/
9917 static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command,
9918 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
9923 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9925 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9926 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9927 return xcvlocal_cmds[i].fn( token, inbuf, outbuf , needed );
9929 return WERR_BADFUNC;
9932 /*******************************************************************
9933 *******************************************************************/
9935 WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u)
9937 Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle);
9941 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle)));
9945 /* Has to be a handle to the TCP/IP port monitor */
9947 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
9948 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
9952 /* requires administrative access to the server */
9954 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
9955 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
9956 return WERR_ACCESS_DENIED;
9959 /* Get the command name. There's numerous commands supported by the
9960 TCPMON interface. */
9962 rpcstr_pull(command, q_u->dataname.buffer, sizeof(command),
9963 q_u->dataname.uni_str_len*2, 0);
9965 /* Allocate the outgoing buffer */
9967 if (!rpcbuf_init( &r_u->outdata, q_u->offered, p->mem_ctx ))
9970 switch ( Printer->printer_type ) {
9971 case SPLHND_PORTMON_TCP:
9972 return process_xcvtcp_command( p->server_info->ptok, command,
9973 &q_u->indata, &r_u->outdata, &r_u->needed );
9974 case SPLHND_PORTMON_LOCAL:
9975 return process_xcvlocal_command( p->server_info->ptok, command,
9976 &q_u->indata, &r_u->outdata, &r_u->needed );
9979 return WERR_INVALID_PRINT_MONITOR;
9981 /****************************************************************
9982 _spoolss_EnumPrinters
9983 ****************************************************************/
9985 WERROR _spoolss_EnumPrinters(pipes_struct *p,
9986 struct spoolss_EnumPrinters *r)
9988 p->rng_fault_state = true;
9989 return WERR_NOT_SUPPORTED;
9992 /****************************************************************
9993 _spoolss_OpenPrinter
9994 ****************************************************************/
9996 WERROR _spoolss_OpenPrinter(pipes_struct *p,
9997 struct spoolss_OpenPrinter *r)
9999 p->rng_fault_state = true;
10000 return WERR_NOT_SUPPORTED;
10003 /****************************************************************
10005 ****************************************************************/
10007 WERROR _spoolss_SetJob(pipes_struct *p,
10008 struct spoolss_SetJob *r)
10010 p->rng_fault_state = true;
10011 return WERR_NOT_SUPPORTED;
10014 /****************************************************************
10016 ****************************************************************/
10018 WERROR _spoolss_GetJob(pipes_struct *p,
10019 struct spoolss_GetJob *r)
10021 p->rng_fault_state = true;
10022 return WERR_NOT_SUPPORTED;
10025 /****************************************************************
10027 ****************************************************************/
10029 WERROR _spoolss_EnumJobs(pipes_struct *p,
10030 struct spoolss_EnumJobs *r)
10032 p->rng_fault_state = true;
10033 return WERR_NOT_SUPPORTED;
10036 /****************************************************************
10037 _spoolss_AddPrinter
10038 ****************************************************************/
10040 WERROR _spoolss_AddPrinter(pipes_struct *p,
10041 struct spoolss_AddPrinter *r)
10043 p->rng_fault_state = true;
10044 return WERR_NOT_SUPPORTED;
10047 /****************************************************************
10048 _spoolss_SetPrinter
10049 ****************************************************************/
10051 WERROR _spoolss_SetPrinter(pipes_struct *p,
10052 struct spoolss_SetPrinter *r)
10054 p->rng_fault_state = true;
10055 return WERR_NOT_SUPPORTED;
10058 /****************************************************************
10059 _spoolss_GetPrinter
10060 ****************************************************************/
10062 WERROR _spoolss_GetPrinter(pipes_struct *p,
10063 struct spoolss_GetPrinter *r)
10065 p->rng_fault_state = true;
10066 return WERR_NOT_SUPPORTED;
10069 /****************************************************************
10070 _spoolss_AddPrinterDriver
10071 ****************************************************************/
10073 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
10074 struct spoolss_AddPrinterDriver *r)
10076 p->rng_fault_state = true;
10077 return WERR_NOT_SUPPORTED;
10080 /****************************************************************
10081 _spoolss_EnumPrinterDrivers
10082 ****************************************************************/
10084 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10085 struct spoolss_EnumPrinterDrivers *r)
10087 p->rng_fault_state = true;
10088 return WERR_NOT_SUPPORTED;
10091 /****************************************************************
10092 _spoolss_GetPrinterDriver
10093 ****************************************************************/
10095 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10096 struct spoolss_GetPrinterDriver *r)
10098 p->rng_fault_state = true;
10099 return WERR_NOT_SUPPORTED;
10102 /****************************************************************
10103 _spoolss_GetPrinterDriverDirectory
10104 ****************************************************************/
10106 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
10107 struct spoolss_GetPrinterDriverDirectory *r)
10109 p->rng_fault_state = true;
10110 return WERR_NOT_SUPPORTED;
10113 /****************************************************************
10114 _spoolss_AddPrintProcessor
10115 ****************************************************************/
10117 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10118 struct spoolss_AddPrintProcessor *r)
10120 p->rng_fault_state = true;
10121 return WERR_NOT_SUPPORTED;
10124 /****************************************************************
10125 _spoolss_EnumPrintProcessors
10126 ****************************************************************/
10128 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10129 struct spoolss_EnumPrintProcessors *r)
10131 p->rng_fault_state = true;
10132 return WERR_NOT_SUPPORTED;
10135 /****************************************************************
10136 _spoolss_GetPrintProcessorDirectory
10137 ****************************************************************/
10139 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
10140 struct spoolss_GetPrintProcessorDirectory *r)
10142 p->rng_fault_state = true;
10143 return WERR_NOT_SUPPORTED;
10146 /****************************************************************
10147 _spoolss_StartDocPrinter
10148 ****************************************************************/
10150 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
10151 struct spoolss_StartDocPrinter *r)
10153 p->rng_fault_state = true;
10154 return WERR_NOT_SUPPORTED;
10157 /****************************************************************
10158 _spoolss_ReadPrinter
10159 ****************************************************************/
10161 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10162 struct spoolss_ReadPrinter *r)
10164 p->rng_fault_state = true;
10165 return WERR_NOT_SUPPORTED;
10168 /****************************************************************
10170 ****************************************************************/
10172 WERROR _spoolss_AddJob(pipes_struct *p,
10173 struct spoolss_AddJob *r)
10175 p->rng_fault_state = true;
10176 return WERR_NOT_SUPPORTED;
10179 /****************************************************************
10180 _spoolss_ScheduleJob
10181 ****************************************************************/
10183 WERROR _spoolss_ScheduleJob(pipes_struct *p,
10184 struct spoolss_ScheduleJob *r)
10186 p->rng_fault_state = true;
10187 return WERR_NOT_SUPPORTED;
10190 /****************************************************************
10191 _spoolss_GetPrinterData
10192 ****************************************************************/
10194 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10195 struct spoolss_GetPrinterData *r)
10197 p->rng_fault_state = true;
10198 return WERR_NOT_SUPPORTED;
10201 /****************************************************************
10202 _spoolss_SetPrinterData
10203 ****************************************************************/
10205 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10206 struct spoolss_SetPrinterData *r)
10208 p->rng_fault_state = true;
10209 return WERR_NOT_SUPPORTED;
10212 /****************************************************************
10213 _spoolss_WaitForPrinterChange
10214 ****************************************************************/
10216 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10217 struct spoolss_WaitForPrinterChange *r)
10219 p->rng_fault_state = true;
10220 return WERR_NOT_SUPPORTED;
10223 /****************************************************************
10225 ****************************************************************/
10227 WERROR _spoolss_EnumForms(pipes_struct *p,
10228 struct spoolss_EnumForms *r)
10230 p->rng_fault_state = true;
10231 return WERR_NOT_SUPPORTED;
10234 /****************************************************************
10236 ****************************************************************/
10238 WERROR _spoolss_EnumPorts(pipes_struct *p,
10239 struct spoolss_EnumPorts *r)
10241 p->rng_fault_state = true;
10242 return WERR_NOT_SUPPORTED;
10245 /****************************************************************
10246 _spoolss_EnumMonitors
10247 ****************************************************************/
10249 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10250 struct spoolss_EnumMonitors *r)
10252 p->rng_fault_state = true;
10253 return WERR_NOT_SUPPORTED;
10256 /****************************************************************
10258 ****************************************************************/
10260 WERROR _spoolss_AddPort(pipes_struct *p,
10261 struct spoolss_AddPort *r)
10263 p->rng_fault_state = true;
10264 return WERR_NOT_SUPPORTED;
10267 /****************************************************************
10268 _spoolss_ConfigurePort
10269 ****************************************************************/
10271 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10272 struct spoolss_ConfigurePort *r)
10274 p->rng_fault_state = true;
10275 return WERR_NOT_SUPPORTED;
10278 /****************************************************************
10279 _spoolss_DeletePort
10280 ****************************************************************/
10282 WERROR _spoolss_DeletePort(pipes_struct *p,
10283 struct spoolss_DeletePort *r)
10285 p->rng_fault_state = true;
10286 return WERR_NOT_SUPPORTED;
10289 /****************************************************************
10290 _spoolss_CreatePrinterIC
10291 ****************************************************************/
10293 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10294 struct spoolss_CreatePrinterIC *r)
10296 p->rng_fault_state = true;
10297 return WERR_NOT_SUPPORTED;
10300 /****************************************************************
10301 _spoolss_PlayGDIScriptOnPrinterIC
10302 ****************************************************************/
10304 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10305 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10307 p->rng_fault_state = true;
10308 return WERR_NOT_SUPPORTED;
10311 /****************************************************************
10312 _spoolss_DeletePrinterIC
10313 ****************************************************************/
10315 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10316 struct spoolss_DeletePrinterIC *r)
10318 p->rng_fault_state = true;
10319 return WERR_NOT_SUPPORTED;
10322 /****************************************************************
10323 _spoolss_AddPrinterConnection
10324 ****************************************************************/
10326 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10327 struct spoolss_AddPrinterConnection *r)
10329 p->rng_fault_state = true;
10330 return WERR_NOT_SUPPORTED;
10333 /****************************************************************
10334 _spoolss_DeletePrinterConnection
10335 ****************************************************************/
10337 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10338 struct spoolss_DeletePrinterConnection *r)
10340 p->rng_fault_state = true;
10341 return WERR_NOT_SUPPORTED;
10344 /****************************************************************
10345 _spoolss_PrinterMessageBox
10346 ****************************************************************/
10348 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10349 struct spoolss_PrinterMessageBox *r)
10351 p->rng_fault_state = true;
10352 return WERR_NOT_SUPPORTED;
10355 /****************************************************************
10356 _spoolss_AddMonitor
10357 ****************************************************************/
10359 WERROR _spoolss_AddMonitor(pipes_struct *p,
10360 struct spoolss_AddMonitor *r)
10362 p->rng_fault_state = true;
10363 return WERR_NOT_SUPPORTED;
10366 /****************************************************************
10367 _spoolss_DeleteMonitor
10368 ****************************************************************/
10370 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10371 struct spoolss_DeleteMonitor *r)
10373 p->rng_fault_state = true;
10374 return WERR_NOT_SUPPORTED;
10377 /****************************************************************
10378 _spoolss_DeletePrintProcessor
10379 ****************************************************************/
10381 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10382 struct spoolss_DeletePrintProcessor *r)
10384 p->rng_fault_state = true;
10385 return WERR_NOT_SUPPORTED;
10388 /****************************************************************
10389 _spoolss_AddPrintProvidor
10390 ****************************************************************/
10392 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10393 struct spoolss_AddPrintProvidor *r)
10395 p->rng_fault_state = true;
10396 return WERR_NOT_SUPPORTED;
10399 /****************************************************************
10400 _spoolss_DeletePrintProvidor
10401 ****************************************************************/
10403 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10404 struct spoolss_DeletePrintProvidor *r)
10406 p->rng_fault_state = true;
10407 return WERR_NOT_SUPPORTED;
10410 /****************************************************************
10411 _spoolss_EnumPrintProcDataTypes
10412 ****************************************************************/
10414 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10415 struct spoolss_EnumPrintProcDataTypes *r)
10417 p->rng_fault_state = true;
10418 return WERR_NOT_SUPPORTED;
10421 /****************************************************************
10422 _spoolss_ResetPrinter
10423 ****************************************************************/
10425 WERROR _spoolss_ResetPrinter(pipes_struct *p,
10426 struct spoolss_ResetPrinter *r)
10428 p->rng_fault_state = true;
10429 return WERR_NOT_SUPPORTED;
10432 /****************************************************************
10433 _spoolss_GetPrinterDriver2
10434 ****************************************************************/
10436 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10437 struct spoolss_GetPrinterDriver2 *r)
10439 p->rng_fault_state = true;
10440 return WERR_NOT_SUPPORTED;
10443 /****************************************************************
10444 _spoolss_FindFirstPrinterChangeNotification
10445 ****************************************************************/
10447 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10448 struct spoolss_FindFirstPrinterChangeNotification *r)
10450 p->rng_fault_state = true;
10451 return WERR_NOT_SUPPORTED;
10454 /****************************************************************
10455 _spoolss_FindNextPrinterChangeNotification
10456 ****************************************************************/
10458 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10459 struct spoolss_FindNextPrinterChangeNotification *r)
10461 p->rng_fault_state = true;
10462 return WERR_NOT_SUPPORTED;
10465 /****************************************************************
10466 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10467 ****************************************************************/
10469 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10470 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10472 p->rng_fault_state = true;
10473 return WERR_NOT_SUPPORTED;
10476 /****************************************************************
10477 _spoolss_ReplyOpenPrinter
10478 ****************************************************************/
10480 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10481 struct spoolss_ReplyOpenPrinter *r)
10483 p->rng_fault_state = true;
10484 return WERR_NOT_SUPPORTED;
10487 /****************************************************************
10488 _spoolss_RouterReplyPrinter
10489 ****************************************************************/
10491 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10492 struct spoolss_RouterReplyPrinter *r)
10494 p->rng_fault_state = true;
10495 return WERR_NOT_SUPPORTED;
10498 /****************************************************************
10499 _spoolss_ReplyClosePrinter
10500 ****************************************************************/
10502 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10503 struct spoolss_ReplyClosePrinter *r)
10505 p->rng_fault_state = true;
10506 return WERR_NOT_SUPPORTED;
10509 /****************************************************************
10511 ****************************************************************/
10513 WERROR _spoolss_AddPortEx(pipes_struct *p,
10514 struct spoolss_AddPortEx *r)
10516 p->rng_fault_state = true;
10517 return WERR_NOT_SUPPORTED;
10520 /****************************************************************
10521 _spoolss_RouterFindFirstPrinterChangeNotification
10522 ****************************************************************/
10524 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10525 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10527 p->rng_fault_state = true;
10528 return WERR_NOT_SUPPORTED;
10531 /****************************************************************
10532 _spoolss_SpoolerInit
10533 ****************************************************************/
10535 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10536 struct spoolss_SpoolerInit *r)
10538 p->rng_fault_state = true;
10539 return WERR_NOT_SUPPORTED;
10542 /****************************************************************
10543 _spoolss_ResetPrinterEx
10544 ****************************************************************/
10546 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10547 struct spoolss_ResetPrinterEx *r)
10549 p->rng_fault_state = true;
10550 return WERR_NOT_SUPPORTED;
10553 /****************************************************************
10554 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10555 ****************************************************************/
10557 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10558 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10560 p->rng_fault_state = true;
10561 return WERR_NOT_SUPPORTED;
10564 /****************************************************************
10565 _spoolss_RouterRefreshPrinterChangeNotification
10566 ****************************************************************/
10568 WERROR _spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p,
10569 struct spoolss_RouterRefreshPrinterChangeNotification *r)
10571 p->rng_fault_state = true;
10572 return WERR_NOT_SUPPORTED;
10575 /****************************************************************
10576 _spoolss_RemoteFindNextPrinterChangeNotifyEx
10577 ****************************************************************/
10579 WERROR _spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p,
10580 struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r)
10582 p->rng_fault_state = true;
10583 return WERR_NOT_SUPPORTED;
10586 /****************************************************************
10588 ****************************************************************/
10590 WERROR _spoolss_44(pipes_struct *p,
10591 struct spoolss_44 *r)
10593 p->rng_fault_state = true;
10594 return WERR_NOT_SUPPORTED;
10597 /****************************************************************
10598 _spoolss_OpenPrinterEx
10599 ****************************************************************/
10601 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
10602 struct spoolss_OpenPrinterEx *r)
10604 p->rng_fault_state = true;
10605 return WERR_NOT_SUPPORTED;
10608 /****************************************************************
10609 _spoolss_AddPrinterEx
10610 ****************************************************************/
10612 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
10613 struct spoolss_AddPrinterEx *r)
10615 p->rng_fault_state = true;
10616 return WERR_NOT_SUPPORTED;
10619 /****************************************************************
10621 ****************************************************************/
10623 WERROR _spoolss_47(pipes_struct *p,
10624 struct spoolss_47 *r)
10626 p->rng_fault_state = true;
10627 return WERR_NOT_SUPPORTED;
10630 /****************************************************************
10631 _spoolss_EnumPrinterData
10632 ****************************************************************/
10634 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10635 struct spoolss_EnumPrinterData *r)
10637 p->rng_fault_state = true;
10638 return WERR_NOT_SUPPORTED;
10641 /****************************************************************
10643 ****************************************************************/
10645 WERROR _spoolss_4a(pipes_struct *p,
10646 struct spoolss_4a *r)
10648 p->rng_fault_state = true;
10649 return WERR_NOT_SUPPORTED;
10652 /****************************************************************
10654 ****************************************************************/
10656 WERROR _spoolss_4b(pipes_struct *p,
10657 struct spoolss_4b *r)
10659 p->rng_fault_state = true;
10660 return WERR_NOT_SUPPORTED;
10663 /****************************************************************
10665 ****************************************************************/
10667 WERROR _spoolss_4c(pipes_struct *p,
10668 struct spoolss_4c *r)
10670 p->rng_fault_state = true;
10671 return WERR_NOT_SUPPORTED;
10674 /****************************************************************
10675 _spoolss_SetPrinterDataEx
10676 ****************************************************************/
10678 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
10679 struct spoolss_SetPrinterDataEx *r)
10681 p->rng_fault_state = true;
10682 return WERR_NOT_SUPPORTED;
10685 /****************************************************************
10686 _spoolss_GetPrinterDataEx
10687 ****************************************************************/
10689 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
10690 struct spoolss_GetPrinterDataEx *r)
10692 p->rng_fault_state = true;
10693 return WERR_NOT_SUPPORTED;
10696 /****************************************************************
10697 _spoolss_EnumPrinterDataEx
10698 ****************************************************************/
10700 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10701 struct spoolss_EnumPrinterDataEx *r)
10703 p->rng_fault_state = true;
10704 return WERR_NOT_SUPPORTED;
10707 /****************************************************************
10708 _spoolss_EnumPrinterKey
10709 ****************************************************************/
10711 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10712 struct spoolss_EnumPrinterKey *r)
10714 p->rng_fault_state = true;
10715 return WERR_NOT_SUPPORTED;
10718 /****************************************************************
10720 ****************************************************************/
10722 WERROR _spoolss_53(pipes_struct *p,
10723 struct spoolss_53 *r)
10725 p->rng_fault_state = true;
10726 return WERR_NOT_SUPPORTED;
10729 /****************************************************************
10731 ****************************************************************/
10733 WERROR _spoolss_55(pipes_struct *p,
10734 struct spoolss_55 *r)
10736 p->rng_fault_state = true;
10737 return WERR_NOT_SUPPORTED;
10740 /****************************************************************
10742 ****************************************************************/
10744 WERROR _spoolss_56(pipes_struct *p,
10745 struct spoolss_56 *r)
10747 p->rng_fault_state = true;
10748 return WERR_NOT_SUPPORTED;
10751 /****************************************************************
10753 ****************************************************************/
10755 WERROR _spoolss_57(pipes_struct *p,
10756 struct spoolss_57 *r)
10758 p->rng_fault_state = true;
10759 return WERR_NOT_SUPPORTED;
10762 /****************************************************************
10764 ****************************************************************/
10766 WERROR _spoolss_XcvData(pipes_struct *p,
10767 struct spoolss_XcvData *r)
10769 p->rng_fault_state = true;
10770 return WERR_NOT_SUPPORTED;
10773 /****************************************************************
10774 _spoolss_AddPrinterDriverEx
10775 ****************************************************************/
10777 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
10778 struct spoolss_AddPrinterDriverEx *r)
10780 p->rng_fault_state = true;
10781 return WERR_NOT_SUPPORTED;
10784 /****************************************************************
10786 ****************************************************************/
10788 WERROR _spoolss_5a(pipes_struct *p,
10789 struct spoolss_5a *r)
10791 p->rng_fault_state = true;
10792 return WERR_NOT_SUPPORTED;
10795 /****************************************************************
10797 ****************************************************************/
10799 WERROR _spoolss_5b(pipes_struct *p,
10800 struct spoolss_5b *r)
10802 p->rng_fault_state = true;
10803 return WERR_NOT_SUPPORTED;
10806 /****************************************************************
10808 ****************************************************************/
10810 WERROR _spoolss_5c(pipes_struct *p,
10811 struct spoolss_5c *r)
10813 p->rng_fault_state = true;
10814 return WERR_NOT_SUPPORTED;
10817 /****************************************************************
10819 ****************************************************************/
10821 WERROR _spoolss_5d(pipes_struct *p,
10822 struct spoolss_5d *r)
10824 p->rng_fault_state = true;
10825 return WERR_NOT_SUPPORTED;
10828 /****************************************************************
10830 ****************************************************************/
10832 WERROR _spoolss_5e(pipes_struct *p,
10833 struct spoolss_5e *r)
10835 p->rng_fault_state = true;
10836 return WERR_NOT_SUPPORTED;
10839 /****************************************************************
10841 ****************************************************************/
10843 WERROR _spoolss_5f(pipes_struct *p,
10844 struct spoolss_5f *r)
10846 p->rng_fault_state = true;
10847 return WERR_NOT_SUPPORTED;