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)
156 * Tell the specific printing tdb we no longer want messages for this printer
157 * by deregistering our PID.
160 if (!print_notify_deregister_pid(snum))
161 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
163 /* weird if the test succeds !!! */
164 if (smb_connections==0) {
165 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
169 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
172 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
173 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
174 win_errstr(result)));
176 /* if it's the last connection, deconnect the IPC$ share */
177 if (smb_connections==1) {
179 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
180 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
182 messaging_deregister(smbd_messaging_context(),
183 MSG_PRINTER_NOTIFY2, NULL);
185 /* Tell the connections db we're no longer interested in
186 * printer notify messages. */
188 register_message_flags( False, FLAG_MSG_PRINT_NOTIFY );
194 /****************************************************************************
195 Functions to free a printer entry datastruct.
196 ****************************************************************************/
198 static int printer_entry_destructor(Printer_entry *Printer)
200 if (Printer->notify.client_connected==True) {
203 if ( Printer->printer_type == SPLHND_SERVER) {
205 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
206 } else if (Printer->printer_type == SPLHND_PRINTER) {
207 snum = print_queue_snum(Printer->sharename);
209 srv_spoolss_replycloseprinter(snum,
210 &Printer->notify.client_hnd);
214 Printer->notify.flags=0;
215 Printer->notify.options=0;
216 Printer->notify.localmachine[0]='\0';
217 Printer->notify.printerlocal=0;
218 free_spool_notify_option(&Printer->notify.option);
219 Printer->notify.option=NULL;
220 Printer->notify.client_connected=False;
222 free_nt_devicemode( &Printer->nt_devmode );
223 free_a_printer( &Printer->printer_info, 2 );
225 /* Remove from the internal list. */
226 DLIST_REMOVE(printers_list, Printer);
230 /****************************************************************************
231 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
232 ****************************************************************************/
234 static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
236 SPOOL_NOTIFY_OPTION *new_sp = NULL;
241 new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION);
248 new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
250 if (!new_sp->ctr.type) {
259 /****************************************************************************
260 find printer index by handle
261 ****************************************************************************/
263 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
265 Printer_entry *find_printer = NULL;
267 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
268 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
275 /****************************************************************************
276 Close printer index by handle.
277 ****************************************************************************/
279 static bool close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
281 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
284 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
288 close_policy_hnd(p, hnd);
293 /****************************************************************************
294 Delete a printer given a handle.
295 ****************************************************************************/
297 WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename )
299 char *cmd = lp_deleteprinter_cmd();
300 char *command = NULL;
302 SE_PRIV se_printop = SE_PRINT_OPERATOR;
303 bool is_print_op = False;
305 /* can't fail if we don't try */
310 command = talloc_asprintf(ctx,
317 is_print_op = user_has_privileges( token, &se_printop );
319 DEBUG(10,("Running [%s]\n", command));
321 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
326 if ( (ret = smbrun(command, NULL)) == 0 ) {
327 /* Tell everyone we updated smb.conf. */
328 message_send_all(smbd_messaging_context(),
329 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
335 /********** END SePrintOperatorPrivlege BLOCK **********/
337 DEBUGADD(10,("returned [%d]\n", ret));
339 TALLOC_FREE(command);
342 return WERR_BADFID; /* What to return here? */
344 /* go ahead and re-read the services immediately */
345 reload_services( False );
347 if ( lp_servicenumber( sharename ) < 0 )
348 return WERR_ACCESS_DENIED;
353 /****************************************************************************
354 Delete a printer given a handle.
355 ****************************************************************************/
357 static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
359 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
362 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
367 * It turns out that Windows allows delete printer on a handle
368 * opened by an admin user, then used on a pipe handle created
369 * by an anonymous user..... but they're working on security.... riiight !
373 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
374 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
375 return WERR_ACCESS_DENIED;
378 /* this does not need a become root since the access check has been
379 done on the handle already */
381 if (del_a_printer( Printer->sharename ) != 0) {
382 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
386 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
387 Printer->sharename );
390 /****************************************************************************
391 Return the snum of a printer corresponding to an handle.
392 ****************************************************************************/
394 static bool get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number,
395 struct share_params **params)
397 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
400 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
404 switch (Printer->printer_type) {
406 DEBUG(4,("short name:%s\n", Printer->sharename));
407 *number = print_queue_snum(Printer->sharename);
408 return (*number != -1);
416 /****************************************************************************
417 Set printer handle type.
418 Check if it's \\server or \\server\printer
419 ****************************************************************************/
421 static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
423 DEBUG(3,("Setting printer type=%s\n", handlename));
425 if ( strlen(handlename) < 3 ) {
426 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
430 /* it's a print server */
431 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
432 DEBUGADD(4,("Printer is a print server\n"));
433 Printer->printer_type = SPLHND_SERVER;
435 /* it's a printer (set_printer_hnd_name() will handle port monitors */
437 DEBUGADD(4,("Printer is a printer\n"));
438 Printer->printer_type = SPLHND_PRINTER;
444 /****************************************************************************
445 Set printer handle name.. Accept names like \\server, \\server\printer,
446 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
447 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
448 XcvDataPort() interface.
449 ****************************************************************************/
451 static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
454 int n_services=lp_numservices();
455 char *aprinter, *printername;
456 const char *servername;
459 NT_PRINTER_INFO_LEVEL *printer = NULL;
462 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
464 aprinter = handlename;
465 if ( *handlename == '\\' ) {
466 servername = canon_servername(handlename);
467 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
475 /* save the servername to fill in replies on this handle */
477 if ( !is_myname_or_ipaddr( servername ) )
480 fstrcpy( Printer->servername, servername );
482 if ( Printer->printer_type == SPLHND_SERVER )
485 if ( Printer->printer_type != SPLHND_PRINTER )
488 DEBUGADD(5, ("searching for [%s]\n", aprinter ));
490 /* check for the Port Monitor Interface */
492 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
493 Printer->printer_type = SPLHND_PORTMON_TCP;
494 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
497 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
498 Printer->printer_type = SPLHND_PORTMON_LOCAL;
499 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
503 /* Search all sharenames first as this is easier than pulling
504 the printer_info_2 off of disk. Don't use find_service() since
505 that calls out to map_username() */
507 /* do another loop to look for printernames */
509 for (snum=0; !found && snum<n_services; snum++) {
511 /* no point going on if this is not a printer */
513 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
516 fstrcpy(sname, lp_servicename(snum));
517 if ( strequal( aprinter, sname ) ) {
522 /* no point looking up the printer object if
523 we aren't allowing printername != sharename */
525 if ( lp_force_printername(snum) )
528 fstrcpy(sname, lp_servicename(snum));
532 /* This call doesn't fill in the location or comment from
533 * a CUPS server for efficiency with large numbers of printers.
537 result = get_a_printer_search( NULL, &printer, 2, sname );
538 if ( !W_ERROR_IS_OK(result) ) {
539 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
540 sname, win_errstr(result)));
544 /* printername is always returned as \\server\printername */
545 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
546 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
547 printer->info_2->printername));
548 free_a_printer( &printer, 2);
554 if ( strequal(printername, aprinter) ) {
555 free_a_printer( &printer, 2);
560 DEBUGADD(10, ("printername: %s\n", printername));
562 free_a_printer( &printer, 2);
565 free_a_printer( &printer, 2);
568 DEBUGADD(4,("Printer not found\n"));
572 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
574 fstrcpy(Printer->sharename, sname);
579 /****************************************************************************
580 Find first available printer slot. creates a printer handle for you.
581 ****************************************************************************/
583 static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted)
585 Printer_entry *new_printer;
587 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
589 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
590 if (new_printer == NULL) {
593 talloc_set_destructor(new_printer, printer_entry_destructor);
595 if (!create_policy_hnd(p, hnd, new_printer)) {
596 TALLOC_FREE(new_printer);
600 /* Add to the internal list. */
601 DLIST_ADD(printers_list, new_printer);
603 new_printer->notify.option=NULL;
605 if (!set_printer_hnd_printertype(new_printer, name)) {
606 close_printer_handle(p, hnd);
610 if (!set_printer_hnd_name(new_printer, name)) {
611 close_printer_handle(p, hnd);
615 new_printer->access_granted = access_granted;
617 DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
622 /***************************************************************************
623 check to see if the client motify handle is monitoring the notification
624 given by (notify_type, notify_field).
625 **************************************************************************/
627 static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type,
633 static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
636 SPOOL_NOTIFY_OPTION *option = p->notify.option;
640 * Flags should always be zero when the change notify
641 * is registered by the client's spooler. A user Win32 app
642 * might use the flags though instead of the NOTIFY_OPTION_INFO
651 return is_monitoring_event_flags(
652 p->notify.flags, notify_type, notify_field);
654 for (i = 0; i < option->count; i++) {
656 /* Check match for notify_type */
658 if (option->ctr.type[i].type != notify_type)
661 /* Check match for field */
663 for (j = 0; j < option->ctr.type[i].count; j++) {
664 if (option->ctr.type[i].fields[j] == notify_field) {
670 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
671 p->servername, p->sharename, notify_type, notify_field));
676 /* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */
678 static void notify_one_value(struct spoolss_notify_msg *msg,
679 SPOOL_NOTIFY_INFO_DATA *data,
682 data->notify_data.value[0] = msg->notify.value[0];
683 data->notify_data.value[1] = 0;
686 static void notify_string(struct spoolss_notify_msg *msg,
687 SPOOL_NOTIFY_INFO_DATA *data,
692 /* The length of the message includes the trailing \0 */
694 init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE);
696 data->notify_data.data.length = msg->len * 2;
697 data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len);
699 if (!data->notify_data.data.string) {
700 data->notify_data.data.length = 0;
704 memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2);
707 static void notify_system_time(struct spoolss_notify_msg *msg,
708 SPOOL_NOTIFY_INFO_DATA *data,
714 if (msg->len != sizeof(time_t)) {
715 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
720 if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) {
721 DEBUG(5, ("notify_system_time: prs_init() failed\n"));
725 if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) {
726 DEBUG(5, ("notify_system_time: unable to make systemtime\n"));
731 if (!spoolss_io_system_time("", &ps, 0, &systime)) {
736 data->notify_data.data.length = prs_offset(&ps);
737 if (prs_offset(&ps)) {
738 data->notify_data.data.string = (uint16 *)
739 TALLOC(mem_ctx, prs_offset(&ps));
740 if (!data->notify_data.data.string) {
744 prs_copy_all_data_out((char *)data->notify_data.data.string, &ps);
746 data->notify_data.data.string = NULL;
752 struct notify2_message_table {
754 void (*fn)(struct spoolss_notify_msg *msg,
755 SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx);
758 static struct notify2_message_table printer_notify_table[] = {
759 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
760 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
761 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
762 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string },
763 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
764 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string },
765 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string },
766 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
767 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
768 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
769 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
770 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
771 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
772 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
773 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
774 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
775 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
776 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
777 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
780 static struct notify2_message_table job_notify_table[] = {
781 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
782 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
783 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
784 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
785 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
786 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
787 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
788 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
789 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
790 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
791 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
792 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
793 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
794 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
795 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
796 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
797 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
798 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
799 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
800 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
801 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
802 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
803 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
804 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
808 /***********************************************************************
809 Allocate talloc context for container object
810 **********************************************************************/
812 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
817 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
822 /***********************************************************************
823 release all allocated memory and zero out structure
824 **********************************************************************/
826 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
832 talloc_destroy(ctr->ctx);
839 /***********************************************************************
840 **********************************************************************/
842 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
850 /***********************************************************************
851 **********************************************************************/
853 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
855 if ( !ctr || !ctr->msg_groups )
858 if ( idx >= ctr->num_groups )
861 return &ctr->msg_groups[idx];
865 /***********************************************************************
866 How many groups of change messages do we have ?
867 **********************************************************************/
869 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
874 return ctr->num_groups;
877 /***********************************************************************
878 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
879 **********************************************************************/
881 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
883 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
884 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
885 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
891 /* loop over all groups looking for a matching printer name */
893 for ( i=0; i<ctr->num_groups; i++ ) {
894 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
898 /* add a new group? */
900 if ( i == ctr->num_groups ) {
903 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
904 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
907 ctr->msg_groups = groups;
909 /* clear the new entry and set the printer name */
911 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
912 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
915 /* add the change messages; 'i' is the correct index now regardless */
917 msg_grp = &ctr->msg_groups[i];
921 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
922 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
925 msg_grp->msgs = msg_list;
927 new_slot = msg_grp->num_msgs-1;
928 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
930 /* need to allocate own copy of data */
933 msg_grp->msgs[new_slot].notify.data = (char *)
934 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
936 return ctr->num_groups;
939 /***********************************************************************
940 Send a change notication message on all handles which have a call
942 **********************************************************************/
944 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
947 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
948 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
949 SPOOLSS_NOTIFY_MSG *messages;
950 int sending_msg_count;
953 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
957 messages = msg_group->msgs;
960 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
964 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
966 /* loop over all printers */
968 for (p = printers_list; p; p = p->next) {
969 SPOOL_NOTIFY_INFO_DATA *data;
974 /* Is there notification on this handle? */
976 if ( !p->notify.client_connected )
979 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
981 /* For this printer? Print servers always receive
984 if ( ( p->printer_type == SPLHND_PRINTER ) &&
985 ( !strequal(msg_group->printername, p->sharename) ) )
988 DEBUG(10,("Our printer\n"));
990 /* allocate the max entries possible */
992 data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs);
999 /* build the array of change notifications */
1001 sending_msg_count = 0;
1003 for ( i=0; i<msg_group->num_msgs; i++ ) {
1004 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1006 /* Are we monitoring this event? */
1008 if (!is_monitoring_event(p, msg->type, msg->field))
1011 sending_msg_count++;
1014 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1015 msg->type, msg->field, p->sharename));
1018 * if the is a printer notification handle and not a job notification
1019 * type, then set the id to 0. Other wise just use what was specified
1022 * When registering change notification on a print server handle
1023 * we always need to send back the id (snum) matching the printer
1024 * for which the change took place. For change notify registered
1025 * on a printer handle, this does not matter and the id should be 0.
1030 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1036 /* Convert unix jobid to smb jobid */
1038 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1039 id = sysjob_to_jobid(msg->id);
1042 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1047 construct_info_data( &data[data_len], msg->type, msg->field, id );
1050 case PRINTER_NOTIFY_TYPE:
1051 if ( printer_notify_table[msg->field].fn )
1052 printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
1055 case JOB_NOTIFY_TYPE:
1056 if ( job_notify_table[msg->field].fn )
1057 job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
1061 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1068 if ( sending_msg_count ) {
1069 rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd,
1070 data_len, data, p->notify.change, 0 );
1075 DEBUG(8,("send_notify2_changes: Exit...\n"));
1079 /***********************************************************************
1080 **********************************************************************/
1082 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1085 uint32 tv_sec, tv_usec;
1088 /* Unpack message */
1090 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f",
1093 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd",
1095 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1098 tdb_unpack((uint8 *)buf + offset, len - offset, "dd",
1099 &msg->notify.value[0], &msg->notify.value[1]);
1101 tdb_unpack((uint8 *)buf + offset, len - offset, "B",
1102 &msg->len, &msg->notify.data);
1104 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1105 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1107 tv->tv_sec = tv_sec;
1108 tv->tv_usec = tv_usec;
1111 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1112 msg->notify.value[1]));
1114 dump_data(3, (uint8 *)msg->notify.data, msg->len);
1119 /********************************************************************
1120 Receive a notify2 message list
1121 ********************************************************************/
1123 static void receive_notify2_message_list(struct messaging_context *msg,
1126 struct server_id server_id,
1129 size_t msg_count, i;
1130 char *buf = (char *)data->data;
1133 SPOOLSS_NOTIFY_MSG notify;
1134 SPOOLSS_NOTIFY_MSG_CTR messages;
1137 if (data->length < 4) {
1138 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1142 msg_count = IVAL(buf, 0);
1145 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1147 if (msg_count == 0) {
1148 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1152 /* initialize the container */
1154 ZERO_STRUCT( messages );
1155 notify_msg_ctr_init( &messages );
1158 * build message groups for each printer identified
1159 * in a change_notify msg. Remember that a PCN message
1160 * includes the handle returned for the srv_spoolss_replyopenprinter()
1161 * call. Therefore messages are grouped according to printer handle.
1164 for ( i=0; i<msg_count; i++ ) {
1165 struct timeval msg_tv;
1167 if (msg_ptr + 4 - buf > data->length) {
1168 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1172 msg_len = IVAL(msg_ptr,0);
1175 if (msg_ptr + msg_len - buf > data->length) {
1176 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1180 /* unpack messages */
1182 ZERO_STRUCT( notify );
1183 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1186 /* add to correct list in container */
1188 notify_msg_ctr_addmsg( &messages, ¬ify );
1190 /* free memory that might have been allocated by notify2_unpack_msg() */
1192 if ( notify.len != 0 )
1193 SAFE_FREE( notify.notify.data );
1196 /* process each group of messages */
1198 num_groups = notify_msg_ctr_numgroups( &messages );
1199 for ( i=0; i<num_groups; i++ )
1200 send_notify2_changes( &messages, i );
1205 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
1207 notify_msg_ctr_destroy( &messages );
1212 /********************************************************************
1213 Send a message to ourself about new driver being installed
1214 so we can upgrade the information for each printer bound to this
1216 ********************************************************************/
1218 static bool srv_spoolss_drv_upgrade_printer(char* drivername)
1220 int len = strlen(drivername);
1225 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1228 messaging_send_buf(smbd_messaging_context(), procid_self(),
1229 MSG_PRINTER_DRVUPGRADE,
1230 (uint8 *)drivername, len+1);
1235 /**********************************************************************
1236 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1237 over all printers, upgrading ones as necessary
1238 **********************************************************************/
1240 void do_drv_upgrade_printer(struct messaging_context *msg,
1243 struct server_id server_id,
1248 int n_services = lp_numservices();
1251 len = MIN(data->length,sizeof(drivername)-1);
1252 strncpy(drivername, (const char *)data->data, len);
1254 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1256 /* Iterate the printer list */
1258 for (snum=0; snum<n_services; snum++)
1260 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1263 NT_PRINTER_INFO_LEVEL *printer = NULL;
1265 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1266 if (!W_ERROR_IS_OK(result))
1269 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1271 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1273 /* all we care about currently is the change_id */
1275 result = mod_a_printer(printer, 2);
1276 if (!W_ERROR_IS_OK(result)) {
1277 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1278 win_errstr(result)));
1282 free_a_printer(&printer, 2);
1289 /********************************************************************
1290 Update the cache for all printq's with a registered client
1292 ********************************************************************/
1294 void update_monitored_printq_cache( void )
1296 Printer_entry *printer = printers_list;
1299 /* loop through all printers and update the cache where
1300 client_connected == True */
1303 if ( (printer->printer_type == SPLHND_PRINTER)
1304 && printer->notify.client_connected )
1306 snum = print_queue_snum(printer->sharename);
1307 print_queue_status( snum, NULL, NULL );
1310 printer = printer->next;
1315 /********************************************************************
1316 Send a message to ourself about new driver being installed
1317 so we can upgrade the information for each printer bound to this
1319 ********************************************************************/
1321 static bool srv_spoolss_reset_printerdata(char* drivername)
1323 int len = strlen(drivername);
1328 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1331 messaging_send_buf(smbd_messaging_context(), procid_self(),
1332 MSG_PRINTERDATA_INIT_RESET,
1333 (uint8 *)drivername, len+1);
1338 /**********************************************************************
1339 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1340 over all printers, resetting printer data as neessary
1341 **********************************************************************/
1343 void reset_all_printerdata(struct messaging_context *msg,
1346 struct server_id server_id,
1351 int n_services = lp_numservices();
1354 len = MIN( data->length, sizeof(drivername)-1 );
1355 strncpy( drivername, (const char *)data->data, len );
1357 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1359 /* Iterate the printer list */
1361 for ( snum=0; snum<n_services; snum++ )
1363 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1366 NT_PRINTER_INFO_LEVEL *printer = NULL;
1368 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1369 if ( !W_ERROR_IS_OK(result) )
1373 * if the printer is bound to the driver,
1374 * then reset to the new driver initdata
1377 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1379 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1381 if ( !set_driver_init(printer, 2) ) {
1382 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1383 printer->info_2->printername, printer->info_2->drivername));
1386 result = mod_a_printer( printer, 2 );
1387 if ( !W_ERROR_IS_OK(result) ) {
1388 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1389 get_dos_error_msg(result)));
1393 free_a_printer( &printer, 2 );
1402 /********************************************************************
1403 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 FIXME: temporary convert_devicemode_new function
1553 ********************************************************************/
1555 static bool convert_devicemode_new(const char *printername,
1556 struct spoolss_DeviceMode *devmode,
1557 NT_DEVICEMODE **pp_nt_devmode)
1559 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1562 * Ensure nt_devmode is a valid pointer
1563 * as we will be overwriting it.
1566 if (nt_devmode == NULL) {
1567 DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
1568 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1572 rpcstr_push(nt_devmode->devicename, devmode->devicename, 31, 0);
1573 rpcstr_push(nt_devmode->formname, devmode->formname, 31, 0);
1575 nt_devmode->specversion = devmode->specversion;
1576 nt_devmode->driverversion = devmode->driverversion;
1577 nt_devmode->size = devmode->size;
1578 nt_devmode->fields = devmode->fields;
1579 nt_devmode->orientation = devmode->orientation;
1580 nt_devmode->papersize = devmode->papersize;
1581 nt_devmode->paperlength = devmode->paperlength;
1582 nt_devmode->paperwidth = devmode->paperwidth;
1583 nt_devmode->scale = devmode->scale;
1584 nt_devmode->copies = devmode->copies;
1585 nt_devmode->defaultsource = devmode->defaultsource;
1586 nt_devmode->printquality = devmode->printquality;
1587 nt_devmode->color = devmode->color;
1588 nt_devmode->duplex = devmode->duplex;
1589 nt_devmode->yresolution = devmode->yresolution;
1590 nt_devmode->ttoption = devmode->ttoption;
1591 nt_devmode->collate = devmode->collate;
1593 nt_devmode->logpixels = devmode->logpixels;
1594 nt_devmode->bitsperpel = devmode->bitsperpel;
1595 nt_devmode->pelswidth = devmode->pelswidth;
1596 nt_devmode->pelsheight = devmode->pelsheight;
1597 nt_devmode->displayflags = devmode->displayflags;
1598 nt_devmode->displayfrequency = devmode->displayfrequency;
1599 nt_devmode->icmmethod = devmode->icmmethod;
1600 nt_devmode->icmintent = devmode->icmintent;
1601 nt_devmode->mediatype = devmode->mediatype;
1602 nt_devmode->dithertype = devmode->dithertype;
1603 nt_devmode->reserved1 = devmode->reserved1;
1604 nt_devmode->reserved2 = devmode->reserved2;
1605 nt_devmode->panningwidth = devmode->panningwidth;
1606 nt_devmode->panningheight = devmode->panningheight;
1609 * Only change private and driverextra if the incoming devmode
1610 * has a new one. JRA.
1613 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1614 SAFE_FREE(nt_devmode->nt_dev_private);
1615 nt_devmode->driverextra = devmode->__driverextra_length;
1616 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1618 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1621 *pp_nt_devmode = nt_devmode;
1626 /********************************************************************
1627 ********************************************************************/
1629 WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u)
1631 PRINTER_DEFAULT *printer_default = &q_u->printer_default;
1632 POLICY_HND *handle = &r_u->handle;
1636 Printer_entry *Printer=NULL;
1638 if (!q_u->printername) {
1639 return WERR_INVALID_PARAM;
1642 /* some sanity check because you can open a printer or a print server */
1643 /* aka: \\server\printer or \\server */
1645 unistr2_to_ascii(name, q_u->printername, sizeof(name));
1647 DEBUGADD(3,("checking name: %s\n",name));
1649 if (!open_printer_hnd(p, handle, name, 0)) {
1650 return WERR_INVALID_PARAM;
1653 Printer=find_printer_index_by_hnd(p, handle);
1655 DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer "
1656 "handle we created for printer %s\n", name ));
1657 close_printer_handle(p,handle);
1658 return WERR_INVALID_PARAM;
1662 * First case: the user is opening the print server:
1664 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1665 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1667 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1668 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1669 * or if the user is listed in the smb.conf printer admin parameter.
1671 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1672 * client view printer folder, but does not show the MSAPW.
1674 * Note: this test needs code to check access rights here too. Jeremy
1675 * could you look at this?
1677 * Second case: the user is opening a printer:
1678 * NT doesn't let us connect to a printer if the connecting user
1679 * doesn't have print permission.
1681 * Third case: user is opening a Port Monitor
1682 * access checks same as opening a handle to the print server.
1685 switch (Printer->printer_type )
1688 case SPLHND_PORTMON_TCP:
1689 case SPLHND_PORTMON_LOCAL:
1690 /* Printserver handles use global struct... */
1694 /* Map standard access rights to object specific access rights */
1696 se_map_standard(&printer_default->access_required,
1697 &printserver_std_mapping);
1699 /* Deny any object specific bits that don't apply to print
1700 servers (i.e printer and job specific bits) */
1702 printer_default->access_required &= SPECIFIC_RIGHTS_MASK;
1704 if (printer_default->access_required &
1705 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1706 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1707 close_printer_handle(p, handle);
1708 return WERR_ACCESS_DENIED;
1711 /* Allow admin access */
1713 if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER )
1715 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1717 if (!lp_ms_add_printer_wizard()) {
1718 close_printer_handle(p, handle);
1719 return WERR_ACCESS_DENIED;
1722 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1723 and not a printer admin, then fail */
1725 if ((p->server_info->utok.uid != 0) &&
1726 !user_has_privileges(p->server_info->ptok,
1728 !token_contains_name_in_list(
1729 uidtoname(p->server_info->utok.uid),
1731 p->server_info->ptok,
1732 lp_printer_admin(snum))) {
1733 close_printer_handle(p, handle);
1734 return WERR_ACCESS_DENIED;
1737 printer_default->access_required = SERVER_ACCESS_ADMINISTER;
1741 printer_default->access_required = SERVER_ACCESS_ENUMERATE;
1744 DEBUG(4,("Setting print server access = %s\n", (printer_default->access_required == SERVER_ACCESS_ADMINISTER)
1745 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1747 /* We fall through to return WERR_OK */
1750 case SPLHND_PRINTER:
1751 /* NT doesn't let us connect to a printer if the connecting user
1752 doesn't have print permission. */
1754 if (!get_printer_snum(p, handle, &snum, NULL)) {
1755 close_printer_handle(p, handle);
1759 se_map_standard(&printer_default->access_required, &printer_std_mapping);
1761 /* map an empty access mask to the minimum access mask */
1762 if (printer_default->access_required == 0x0)
1763 printer_default->access_required = PRINTER_ACCESS_USE;
1766 * If we are not serving the printer driver for this printer,
1767 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1768 * will keep NT clients happy --jerry
1771 if (lp_use_client_driver(snum)
1772 && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER))
1774 printer_default->access_required = PRINTER_ACCESS_USE;
1777 /* check smb.conf parameters and the the sec_desc */
1779 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1780 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1781 return WERR_ACCESS_DENIED;
1784 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1785 p->server_info->ptok, snum) ||
1786 !print_access_check(p->server_info, snum,
1787 printer_default->access_required)) {
1788 DEBUG(3, ("access DENIED for printer open\n"));
1789 close_printer_handle(p, handle);
1790 return WERR_ACCESS_DENIED;
1793 if ((printer_default->access_required & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1794 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1795 close_printer_handle(p, handle);
1796 return WERR_ACCESS_DENIED;
1799 if (printer_default->access_required & PRINTER_ACCESS_ADMINISTER)
1800 printer_default->access_required = PRINTER_ACCESS_ADMINISTER;
1802 printer_default->access_required = PRINTER_ACCESS_USE;
1804 DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
1805 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1810 /* sanity check to prevent programmer error */
1814 Printer->access_granted = printer_default->access_required;
1817 * If the client sent a devmode in the OpenPrinter() call, then
1818 * save it here in case we get a job submission on this handle
1821 if ( (Printer->printer_type != SPLHND_SERVER)
1822 && q_u->printer_default.devmode_cont.devmode_ptr )
1824 convert_devicemode( Printer->sharename, q_u->printer_default.devmode_cont.devmode,
1825 &Printer->nt_devmode );
1828 #if 0 /* JERRY -- I'm doubtful this is really effective */
1829 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1830 optimization in Windows 2000 clients --jerry */
1832 if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER)
1833 && (RA_WIN2K == get_remote_arch()) )
1835 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n"));
1836 sys_usleep( 500000 );
1843 /****************************************************************************
1844 ****************************************************************************/
1846 static bool convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni,
1847 NT_PRINTER_INFO_LEVEL *printer, uint32 level)
1853 /* allocate memory if needed. Messy because
1854 convert_printer_info is used to update an existing
1855 printer or build a new one */
1857 if ( !printer->info_2 ) {
1858 printer->info_2 = TALLOC_ZERO_P( printer, NT_PRINTER_INFO_LEVEL_2 );
1859 if ( !printer->info_2 ) {
1860 DEBUG(0,("convert_printer_info: talloc() failed!\n"));
1865 ret = uni_2_asc_printer_info_2(uni->info_2, printer->info_2);
1866 printer->info_2->setuptime = time(NULL);
1874 static bool convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni,
1875 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level)
1881 printer->info_3=NULL;
1882 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3))
1886 printer->info_6=NULL;
1887 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6))
1897 bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
1898 NT_DEVICEMODE **pp_nt_devmode)
1900 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1903 * Ensure nt_devmode is a valid pointer
1904 * as we will be overwriting it.
1907 if (nt_devmode == NULL) {
1908 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
1909 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1913 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
1914 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
1916 nt_devmode->specversion=devmode->specversion;
1917 nt_devmode->driverversion=devmode->driverversion;
1918 nt_devmode->size=devmode->size;
1919 nt_devmode->fields=devmode->fields;
1920 nt_devmode->orientation=devmode->orientation;
1921 nt_devmode->papersize=devmode->papersize;
1922 nt_devmode->paperlength=devmode->paperlength;
1923 nt_devmode->paperwidth=devmode->paperwidth;
1924 nt_devmode->scale=devmode->scale;
1925 nt_devmode->copies=devmode->copies;
1926 nt_devmode->defaultsource=devmode->defaultsource;
1927 nt_devmode->printquality=devmode->printquality;
1928 nt_devmode->color=devmode->color;
1929 nt_devmode->duplex=devmode->duplex;
1930 nt_devmode->yresolution=devmode->yresolution;
1931 nt_devmode->ttoption=devmode->ttoption;
1932 nt_devmode->collate=devmode->collate;
1934 nt_devmode->logpixels=devmode->logpixels;
1935 nt_devmode->bitsperpel=devmode->bitsperpel;
1936 nt_devmode->pelswidth=devmode->pelswidth;
1937 nt_devmode->pelsheight=devmode->pelsheight;
1938 nt_devmode->displayflags=devmode->displayflags;
1939 nt_devmode->displayfrequency=devmode->displayfrequency;
1940 nt_devmode->icmmethod=devmode->icmmethod;
1941 nt_devmode->icmintent=devmode->icmintent;
1942 nt_devmode->mediatype=devmode->mediatype;
1943 nt_devmode->dithertype=devmode->dithertype;
1944 nt_devmode->reserved1=devmode->reserved1;
1945 nt_devmode->reserved2=devmode->reserved2;
1946 nt_devmode->panningwidth=devmode->panningwidth;
1947 nt_devmode->panningheight=devmode->panningheight;
1950 * Only change private and driverextra if the incoming devmode
1951 * has a new one. JRA.
1954 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
1955 SAFE_FREE(nt_devmode->nt_dev_private);
1956 nt_devmode->driverextra=devmode->driverextra;
1957 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1959 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
1962 *pp_nt_devmode = nt_devmode;
1967 /********************************************************************
1968 * _spoolss_enddocprinter_internal.
1969 ********************************************************************/
1971 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
1973 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
1977 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
1981 if (!get_printer_snum(p, handle, &snum, NULL))
1984 Printer->document_started=False;
1985 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
1986 /* error codes unhandled so far ... */
1991 /****************************************************************
1992 _spoolss_ClosePrinter
1993 ****************************************************************/
1995 WERROR _spoolss_ClosePrinter(pipes_struct *p,
1996 struct spoolss_ClosePrinter *r)
1998 POLICY_HND *handle = r->in.handle;
2000 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2002 if (Printer && Printer->document_started)
2003 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2005 if (!close_printer_handle(p, handle))
2008 /* clear the returned printer handle. Observed behavior
2009 from Win2k server. Don't think this really matters.
2010 Previous code just copied the value of the closed
2013 ZERO_STRUCTP(r->out.handle);
2018 /****************************************************************
2019 _spoolss_DeletePrinter
2020 ****************************************************************/
2022 WERROR _spoolss_DeletePrinter(pipes_struct *p,
2023 struct spoolss_DeletePrinter *r)
2025 POLICY_HND *handle = r->in.handle;
2026 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2029 if (Printer && Printer->document_started)
2030 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2032 result = delete_printer_handle(p, handle);
2034 update_c_setprinter(False);
2039 /*******************************************************************
2040 * static function to lookup the version id corresponding to an
2041 * long architecture string
2042 ******************************************************************/
2044 static int get_version_id (char * arch)
2047 struct table_node archi_table[]= {
2049 {"Windows 4.0", "WIN40", 0 },
2050 {"Windows NT x86", "W32X86", 2 },
2051 {"Windows NT R4000", "W32MIPS", 2 },
2052 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
2053 {"Windows NT PowerPC", "W32PPC", 2 },
2054 {"Windows IA64", "IA64", 3 },
2055 {"Windows x64", "x64", 3 },
2059 for (i=0; archi_table[i].long_archi != NULL; i++)
2061 if (strcmp(arch, archi_table[i].long_archi) == 0)
2062 return (archi_table[i].version);
2068 /****************************************************************
2069 _spoolss_DeletePrinterDriver
2070 ****************************************************************/
2072 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
2073 struct spoolss_DeletePrinterDriver *r)
2077 NT_PRINTER_DRIVER_INFO_LEVEL info;
2078 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2081 WERROR status_win2k = WERR_ACCESS_DENIED;
2082 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2084 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2085 and not a printer admin, then fail */
2087 if ( (p->server_info->utok.uid != 0)
2088 && !user_has_privileges(p->server_info->ptok, &se_printop )
2089 && !token_contains_name_in_list(
2090 uidtoname(p->server_info->utok.uid), NULL,
2091 NULL, p->server_info->ptok,
2092 lp_printer_admin(-1)) )
2094 return WERR_ACCESS_DENIED;
2097 driver = CONST_DISCARD(char *, r->in.driver);
2098 arch = CONST_DISCARD(char *, r->in.architecture);
2100 /* check that we have a valid driver name first */
2102 if ((version=get_version_id(arch)) == -1)
2103 return WERR_INVALID_ENVIRONMENT;
2106 ZERO_STRUCT(info_win2k);
2108 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2110 /* try for Win2k driver if "Windows NT x86" */
2112 if ( version == 2 ) {
2114 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2115 status = WERR_UNKNOWN_PRINTER_DRIVER;
2119 /* otherwise it was a failure */
2121 status = WERR_UNKNOWN_PRINTER_DRIVER;
2127 if (printer_driver_in_use(info.info_3)) {
2128 status = WERR_PRINTER_DRIVER_IN_USE;
2134 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2136 /* if we get to here, we now have 2 driver info structures to remove */
2137 /* remove the Win2k driver first*/
2139 status_win2k = delete_printer_driver(
2140 p, info_win2k.info_3, 3, False );
2141 free_a_printer_driver( info_win2k, 3 );
2143 /* this should not have failed---if it did, report to client */
2144 if ( !W_ERROR_IS_OK(status_win2k) )
2146 status = status_win2k;
2152 status = delete_printer_driver(p, info.info_3, version, False);
2154 /* if at least one of the deletes succeeded return OK */
2156 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2160 free_a_printer_driver( info, 3 );
2165 /****************************************************************
2166 _spoolss_DeletePrinterDriverEx
2167 ****************************************************************/
2169 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2170 struct spoolss_DeletePrinterDriverEx *r)
2174 NT_PRINTER_DRIVER_INFO_LEVEL info;
2175 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2177 uint32_t flags = r->in.delete_flags;
2180 WERROR status_win2k = WERR_ACCESS_DENIED;
2181 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2183 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2184 and not a printer admin, then fail */
2186 if ( (p->server_info->utok.uid != 0)
2187 && !user_has_privileges(p->server_info->ptok, &se_printop )
2188 && !token_contains_name_in_list(
2189 uidtoname(p->server_info->utok.uid), NULL, NULL,
2190 p->server_info->ptok, lp_printer_admin(-1)) )
2192 return WERR_ACCESS_DENIED;
2195 driver = CONST_DISCARD(char *, r->in.driver);
2196 arch = CONST_DISCARD(char *, r->in.architecture);
2198 /* check that we have a valid driver name first */
2199 if ((version=get_version_id(arch)) == -1) {
2200 /* this is what NT returns */
2201 return WERR_INVALID_ENVIRONMENT;
2204 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2205 version = r->in.version;
2208 ZERO_STRUCT(info_win2k);
2210 status = get_a_printer_driver(&info, 3, driver, arch, version);
2212 if ( !W_ERROR_IS_OK(status) )
2215 * if the client asked for a specific version,
2216 * or this is something other than Windows NT x86,
2220 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2223 /* try for Win2k driver if "Windows NT x86" */
2226 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2227 status = WERR_UNKNOWN_PRINTER_DRIVER;
2232 if ( printer_driver_in_use(info.info_3) ) {
2233 status = WERR_PRINTER_DRIVER_IN_USE;
2238 * we have a couple of cases to consider.
2239 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2240 * then the delete should fail if **any** files overlap with
2242 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2243 * non-overlapping files
2244 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2245 * is set, the do not delete any files
2246 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2249 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2251 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2253 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2254 /* no idea of the correct error here */
2255 status = WERR_ACCESS_DENIED;
2260 /* also check for W32X86/3 if necessary; maybe we already have? */
2262 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2263 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2266 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2267 /* no idea of the correct error here */
2268 free_a_printer_driver( info_win2k, 3 );
2269 status = WERR_ACCESS_DENIED;
2273 /* if we get to here, we now have 2 driver info structures to remove */
2274 /* remove the Win2k driver first*/
2276 status_win2k = delete_printer_driver(
2277 p, info_win2k.info_3, 3, delete_files);
2278 free_a_printer_driver( info_win2k, 3 );
2280 /* this should not have failed---if it did, report to client */
2282 if ( !W_ERROR_IS_OK(status_win2k) )
2287 status = delete_printer_driver(p, info.info_3, version, delete_files);
2289 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2292 free_a_printer_driver( info, 3 );
2298 /****************************************************************************
2299 Internal routine for retreiving printerdata
2300 ***************************************************************************/
2302 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2303 const char *key, const char *value, uint32 *type, uint8 **data,
2304 uint32 *needed, uint32 in_size )
2306 REGISTRY_VALUE *val;
2310 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2311 return WERR_BADFILE;
2313 *type = regval_type( val );
2315 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2317 size = regval_size( val );
2319 /* copy the min(in_size, len) */
2322 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2324 /* special case for 0 length values */
2326 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2330 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2339 DEBUG(5,("get_printer_dataex: copy done\n"));
2344 /****************************************************************************
2345 Internal routine for removing printerdata
2346 ***************************************************************************/
2348 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2350 return delete_printer_data( printer->info_2, key, value );
2353 /****************************************************************************
2354 Internal routine for storing printerdata
2355 ***************************************************************************/
2357 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2358 uint32 type, uint8 *data, int real_len )
2360 /* the registry objects enforce uniqueness based on value name */
2362 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2365 /********************************************************************
2366 GetPrinterData on a printer server Handle.
2367 ********************************************************************/
2369 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2373 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2375 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2377 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2379 SIVAL(*data, 0, 0x00);
2384 if (!StrCaseCmp(value, "BeepEnabled")) {
2386 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2388 SIVAL(*data, 0, 0x00);
2393 if (!StrCaseCmp(value, "EventLog")) {
2395 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2397 /* formally was 0x1b */
2398 SIVAL(*data, 0, 0x0);
2403 if (!StrCaseCmp(value, "NetPopup")) {
2405 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2407 SIVAL(*data, 0, 0x00);
2412 if (!StrCaseCmp(value, "MajorVersion")) {
2414 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2417 /* Windows NT 4.0 seems to not allow uploading of drivers
2418 to a server that reports 0x3 as the MajorVersion.
2419 need to investigate more how Win2k gets around this .
2422 if ( RA_WINNT == get_remote_arch() )
2431 if (!StrCaseCmp(value, "MinorVersion")) {
2433 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2441 * uint32 size = 0x114
2443 * uint32 minor = [0|1]
2444 * uint32 build = [2195|2600]
2445 * extra unicode string = e.g. "Service Pack 3"
2447 if (!StrCaseCmp(value, "OSVersion")) {
2451 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2454 SIVAL(*data, 0, *needed); /* size */
2455 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2457 SIVAL(*data, 12, 2195); /* build */
2459 /* leave extra string empty */
2465 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2466 const char *string="C:\\PRINTERS";
2468 *needed = 2*(strlen(string)+1);
2469 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2471 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2473 /* it's done by hand ready to go on the wire */
2474 for (i=0; i<strlen(string); i++) {
2475 (*data)[2*i]=string[i];
2476 (*data)[2*i+1]='\0';
2481 if (!StrCaseCmp(value, "Architecture")) {
2482 const char *string="Windows NT x86";
2484 *needed = 2*(strlen(string)+1);
2485 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2487 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2488 for (i=0; i<strlen(string); i++) {
2489 (*data)[2*i]=string[i];
2490 (*data)[2*i+1]='\0';
2495 if (!StrCaseCmp(value, "DsPresent")) {
2497 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2500 /* only show the publish check box if we are a
2501 memeber of a AD domain */
2503 if ( lp_security() == SEC_ADS )
2504 SIVAL(*data, 0, 0x01);
2506 SIVAL(*data, 0, 0x00);
2512 if (!StrCaseCmp(value, "DNSMachineName")) {
2513 const char *hostname = get_mydnsfullname();
2516 return WERR_BADFILE;
2518 *needed = 2*(strlen(hostname)+1);
2519 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2521 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2522 for (i=0; i<strlen(hostname); i++) {
2523 (*data)[2*i]=hostname[i];
2524 (*data)[2*i+1]='\0';
2530 return WERR_BADFILE;
2533 /********************************************************************
2534 * spoolss_getprinterdata
2535 ********************************************************************/
2537 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2539 POLICY_HND *handle = &q_u->handle;
2540 UNISTR2 *valuename = &q_u->valuename;
2541 uint32 in_size = q_u->size;
2542 uint32 *type = &r_u->type;
2543 uint32 *out_size = &r_u->size;
2544 uint8 **data = &r_u->data;
2545 uint32 *needed = &r_u->needed;
2548 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2549 NT_PRINTER_INFO_LEVEL *printer = NULL;
2553 * Reminder: when it's a string, the length is in BYTES
2554 * even if UNICODE is negociated.
2559 *out_size = in_size;
2561 /* in case of problem, return some default values */
2566 DEBUG(4,("_spoolss_getprinterdata\n"));
2569 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2570 status = WERR_BADFID;
2574 unistr2_to_ascii(value, valuename, sizeof(value));
2576 if ( Printer->printer_type == SPLHND_SERVER )
2577 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2580 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2581 status = WERR_BADFID;
2585 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2586 if ( !W_ERROR_IS_OK(status) )
2589 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2591 if ( strequal(value, "ChangeId") ) {
2593 *needed = sizeof(uint32);
2594 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2595 status = WERR_NOMEM;
2598 SIVAL( *data, 0, printer->info_2->changeid );
2602 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2605 if (*needed > *out_size)
2606 status = WERR_MORE_DATA;
2609 if ( !W_ERROR_IS_OK(status) )
2611 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2613 /* reply this param doesn't exist */
2616 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2618 free_a_printer( &printer, 2 );
2626 /* cleanup & exit */
2629 free_a_printer( &printer, 2 );
2634 /*********************************************************
2635 Connect to the client machine.
2636 **********************************************************/
2638 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2639 struct sockaddr_storage *client_ss, const char *remote_machine)
2642 struct cli_state *the_cli;
2643 struct sockaddr_storage rm_addr;
2645 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2646 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2647 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2651 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2652 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2656 char addr[INET6_ADDRSTRLEN];
2657 rm_addr = *client_ss;
2658 print_sockaddr(addr, sizeof(addr), &rm_addr);
2659 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2663 /* setup the connection */
2665 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2666 &rm_addr, 0, "IPC$", "IPC",
2670 0, lp_client_signing(), NULL );
2672 if ( !NT_STATUS_IS_OK( ret ) ) {
2673 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2678 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2679 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2680 cli_shutdown(the_cli);
2685 * Ok - we have an anonymous connection to the IPC$ share.
2686 * Now start the NT Domain stuff :-).
2689 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2690 if (!NT_STATUS_IS_OK(ret)) {
2691 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2692 remote_machine, nt_errstr(ret)));
2693 cli_shutdown(the_cli);
2700 /***************************************************************************
2701 Connect to the client.
2702 ****************************************************************************/
2704 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2705 uint32 localprinter, uint32 type,
2706 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2711 * If it's the first connection, contact the client
2712 * and connect to the IPC$ share anonymously
2714 if (smb_connections==0) {
2715 fstring unix_printer;
2717 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2719 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2722 messaging_register(smbd_messaging_context(), NULL,
2723 MSG_PRINTER_NOTIFY2,
2724 receive_notify2_message_list);
2725 /* Tell the connections db we're now interested in printer
2726 * notify messages. */
2727 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2731 * Tell the specific printing tdb we want messages for this printer
2732 * by registering our PID.
2735 if (!print_notify_register_pid(snum))
2736 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2740 result = rpccli_spoolss_reply_open_printer(notify_cli_pipe,
2747 if (!W_ERROR_IS_OK(result))
2748 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2749 win_errstr(result)));
2751 return (W_ERROR_IS_OK(result));
2754 /********************************************************************
2756 * ReplyFindFirstPrinterChangeNotifyEx
2758 * before replying OK: status=0 a rpc call is made to the workstation
2759 * asking ReplyOpenPrinter
2761 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2762 * called from api_spoolss_rffpcnex
2763 ********************************************************************/
2765 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2767 POLICY_HND *handle = &q_u->handle;
2768 uint32 flags = q_u->flags;
2769 uint32 options = q_u->options;
2770 UNISTR2 *localmachine = &q_u->localmachine;
2771 uint32 printerlocal = q_u->printerlocal;
2773 SPOOL_NOTIFY_OPTION *option = q_u->option;
2774 struct sockaddr_storage client_ss;
2776 /* store the notify value in the printer struct */
2778 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2781 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2785 Printer->notify.flags=flags;
2786 Printer->notify.options=options;
2787 Printer->notify.printerlocal=printerlocal;
2789 if (Printer->notify.option)
2790 free_spool_notify_option(&Printer->notify.option);
2792 Printer->notify.option=dup_spool_notify_option(option);
2794 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
2795 sizeof(Printer->notify.localmachine));
2797 /* Connect to the client machine and send a ReplyOpenPrinter */
2799 if ( Printer->printer_type == SPLHND_SERVER)
2801 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2802 !get_printer_snum(p, handle, &snum, NULL) )
2805 if (!interpret_string_addr(&client_ss, p->client_address,
2807 return WERR_SERVER_UNAVAILABLE;
2810 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2811 Printer->notify.printerlocal, 1,
2812 &Printer->notify.client_hnd, &client_ss))
2813 return WERR_SERVER_UNAVAILABLE;
2815 Printer->notify.client_connected=True;
2820 /*******************************************************************
2821 * fill a notify_info_data with the servername
2822 ********************************************************************/
2824 void spoolss_notify_server_name(int snum,
2825 SPOOL_NOTIFY_INFO_DATA *data,
2826 print_queue_struct *queue,
2827 NT_PRINTER_INFO_LEVEL *printer,
2828 TALLOC_CTX *mem_ctx)
2830 smb_ucs2_t *temp = NULL;
2833 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->servername);
2834 if (len == (uint32)-1) {
2838 data->notify_data.data.length = len;
2840 data->notify_data.data.string = (uint16 *)temp;
2842 data->notify_data.data.string = NULL;
2846 /*******************************************************************
2847 * fill a notify_info_data with the printername (not including the servername).
2848 ********************************************************************/
2850 void spoolss_notify_printer_name(int snum,
2851 SPOOL_NOTIFY_INFO_DATA *data,
2852 print_queue_struct *queue,
2853 NT_PRINTER_INFO_LEVEL *printer,
2854 TALLOC_CTX *mem_ctx)
2856 smb_ucs2_t *temp = NULL;
2859 /* the notify name should not contain the \\server\ part */
2860 char *p = strrchr(printer->info_2->printername, '\\');
2863 p = printer->info_2->printername;
2868 len = rpcstr_push_talloc(mem_ctx, &temp, p);
2869 if (len == (uint32)-1) {
2873 data->notify_data.data.length = len;
2875 data->notify_data.data.string = (uint16 *)temp;
2877 data->notify_data.data.string = NULL;
2881 /*******************************************************************
2882 * fill a notify_info_data with the servicename
2883 ********************************************************************/
2885 void spoolss_notify_share_name(int snum,
2886 SPOOL_NOTIFY_INFO_DATA *data,
2887 print_queue_struct *queue,
2888 NT_PRINTER_INFO_LEVEL *printer,
2889 TALLOC_CTX *mem_ctx)
2891 smb_ucs2_t *temp = NULL;
2894 len = rpcstr_push_talloc(mem_ctx, &temp, lp_servicename(snum));
2895 if (len == (uint32)-1) {
2899 data->notify_data.data.length = len;
2901 data->notify_data.data.string = (uint16 *)temp;
2903 data->notify_data.data.string = NULL;
2908 /*******************************************************************
2909 * fill a notify_info_data with the port name
2910 ********************************************************************/
2912 void spoolss_notify_port_name(int snum,
2913 SPOOL_NOTIFY_INFO_DATA *data,
2914 print_queue_struct *queue,
2915 NT_PRINTER_INFO_LEVEL *printer,
2916 TALLOC_CTX *mem_ctx)
2918 smb_ucs2_t *temp = NULL;
2921 /* even if it's strange, that's consistant in all the code */
2923 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->portname);
2924 if (len == (uint32)-1) {
2928 data->notify_data.data.length = len;
2930 data->notify_data.data.string = (uint16 *)temp;
2932 data->notify_data.data.string = NULL;
2936 /*******************************************************************
2937 * fill a notify_info_data with the printername
2938 * but it doesn't exist, have to see what to do
2939 ********************************************************************/
2941 void spoolss_notify_driver_name(int snum,
2942 SPOOL_NOTIFY_INFO_DATA *data,
2943 print_queue_struct *queue,
2944 NT_PRINTER_INFO_LEVEL *printer,
2945 TALLOC_CTX *mem_ctx)
2947 smb_ucs2_t *temp = NULL;
2950 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->drivername);
2951 if (len == (uint32)-1) {
2955 data->notify_data.data.length = len;
2957 data->notify_data.data.string = (uint16 *)temp;
2959 data->notify_data.data.string = NULL;
2963 /*******************************************************************
2964 * fill a notify_info_data with the comment
2965 ********************************************************************/
2967 void spoolss_notify_comment(int snum,
2968 SPOOL_NOTIFY_INFO_DATA *data,
2969 print_queue_struct *queue,
2970 NT_PRINTER_INFO_LEVEL *printer,
2971 TALLOC_CTX *mem_ctx)
2973 smb_ucs2_t *temp = NULL;
2976 if (*printer->info_2->comment == '\0')
2977 len = rpcstr_push_talloc(mem_ctx, &temp, lp_comment(snum));
2979 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->comment);
2981 if (len == (uint32)-1) {
2984 data->notify_data.data.length = len;
2986 data->notify_data.data.string = (uint16 *)temp;
2988 data->notify_data.data.string = NULL;
2992 /*******************************************************************
2993 * fill a notify_info_data with the comment
2994 * location = "Room 1, floor 2, building 3"
2995 ********************************************************************/
2997 void spoolss_notify_location(int snum,
2998 SPOOL_NOTIFY_INFO_DATA *data,
2999 print_queue_struct *queue,
3000 NT_PRINTER_INFO_LEVEL *printer,
3001 TALLOC_CTX *mem_ctx)
3003 smb_ucs2_t *temp = NULL;
3006 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->location);
3007 if (len == (uint32)-1) {
3011 data->notify_data.data.length = len;
3013 data->notify_data.data.string = (uint16 *)temp;
3015 data->notify_data.data.string = NULL;
3019 /*******************************************************************
3020 * fill a notify_info_data with the device mode
3021 * jfm:xxxx don't to it for know but that's a real problem !!!
3022 ********************************************************************/
3024 static void spoolss_notify_devmode(int snum,
3025 SPOOL_NOTIFY_INFO_DATA *data,
3026 print_queue_struct *queue,
3027 NT_PRINTER_INFO_LEVEL *printer,
3028 TALLOC_CTX *mem_ctx)
3030 /* for a dummy implementation we have to zero the fields */
3031 data->notify_data.data.length = 0;
3032 data->notify_data.data.string = NULL;
3035 /*******************************************************************
3036 * fill a notify_info_data with the separator file name
3037 ********************************************************************/
3039 void spoolss_notify_sepfile(int snum,
3040 SPOOL_NOTIFY_INFO_DATA *data,
3041 print_queue_struct *queue,
3042 NT_PRINTER_INFO_LEVEL *printer,
3043 TALLOC_CTX *mem_ctx)
3045 smb_ucs2_t *temp = NULL;
3048 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->sepfile);
3049 if (len == (uint32)-1) {
3053 data->notify_data.data.length = len;
3055 data->notify_data.data.string = (uint16 *)temp;
3057 data->notify_data.data.string = NULL;
3061 /*******************************************************************
3062 * fill a notify_info_data with the print processor
3063 * jfm:xxxx return always winprint to indicate we don't do anything to it
3064 ********************************************************************/
3066 void spoolss_notify_print_processor(int snum,
3067 SPOOL_NOTIFY_INFO_DATA *data,
3068 print_queue_struct *queue,
3069 NT_PRINTER_INFO_LEVEL *printer,
3070 TALLOC_CTX *mem_ctx)
3072 smb_ucs2_t *temp = NULL;
3075 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->printprocessor);
3076 if (len == (uint32)-1) {
3080 data->notify_data.data.length = len;
3082 data->notify_data.data.string = (uint16 *)temp;
3084 data->notify_data.data.string = NULL;
3088 /*******************************************************************
3089 * fill a notify_info_data with the print processor options
3090 * jfm:xxxx send an empty string
3091 ********************************************************************/
3093 void spoolss_notify_parameters(int snum,
3094 SPOOL_NOTIFY_INFO_DATA *data,
3095 print_queue_struct *queue,
3096 NT_PRINTER_INFO_LEVEL *printer,
3097 TALLOC_CTX *mem_ctx)
3099 smb_ucs2_t *temp = NULL;
3102 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->parameters);
3103 if (len == (uint32)-1) {
3107 data->notify_data.data.length = len;
3109 data->notify_data.data.string = (uint16 *)temp;
3111 data->notify_data.data.string = NULL;
3115 /*******************************************************************
3116 * fill a notify_info_data with the data type
3117 * jfm:xxxx always send RAW as data type
3118 ********************************************************************/
3120 void spoolss_notify_datatype(int snum,
3121 SPOOL_NOTIFY_INFO_DATA *data,
3122 print_queue_struct *queue,
3123 NT_PRINTER_INFO_LEVEL *printer,
3124 TALLOC_CTX *mem_ctx)
3126 smb_ucs2_t *temp = NULL;
3129 len = rpcstr_push_talloc(mem_ctx, &temp, printer->info_2->datatype);
3130 if (len == (uint32)-1) {
3134 data->notify_data.data.length = len;
3136 data->notify_data.data.string = (uint16 *)temp;
3138 data->notify_data.data.string = NULL;
3142 /*******************************************************************
3143 * fill a notify_info_data with the security descriptor
3144 * jfm:xxxx send an null pointer to say no security desc
3145 * have to implement security before !
3146 ********************************************************************/
3148 static void spoolss_notify_security_desc(int snum,
3149 SPOOL_NOTIFY_INFO_DATA *data,
3150 print_queue_struct *queue,
3151 NT_PRINTER_INFO_LEVEL *printer,
3152 TALLOC_CTX *mem_ctx)
3154 data->notify_data.sd.size = printer->info_2->secdesc_buf->sd_size;
3155 data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sd ) ;
3158 /*******************************************************************
3159 * fill a notify_info_data with the attributes
3160 * jfm:xxxx a samba printer is always shared
3161 ********************************************************************/
3163 void spoolss_notify_attributes(int snum,
3164 SPOOL_NOTIFY_INFO_DATA *data,
3165 print_queue_struct *queue,
3166 NT_PRINTER_INFO_LEVEL *printer,
3167 TALLOC_CTX *mem_ctx)
3169 data->notify_data.value[0] = printer->info_2->attributes;
3170 data->notify_data.value[1] = 0;
3173 /*******************************************************************
3174 * fill a notify_info_data with the priority
3175 ********************************************************************/
3177 static void spoolss_notify_priority(int snum,
3178 SPOOL_NOTIFY_INFO_DATA *data,
3179 print_queue_struct *queue,
3180 NT_PRINTER_INFO_LEVEL *printer,
3181 TALLOC_CTX *mem_ctx)
3183 data->notify_data.value[0] = printer->info_2->priority;
3184 data->notify_data.value[1] = 0;
3187 /*******************************************************************
3188 * fill a notify_info_data with the default priority
3189 ********************************************************************/
3191 static void spoolss_notify_default_priority(int snum,
3192 SPOOL_NOTIFY_INFO_DATA *data,
3193 print_queue_struct *queue,
3194 NT_PRINTER_INFO_LEVEL *printer,
3195 TALLOC_CTX *mem_ctx)
3197 data->notify_data.value[0] = printer->info_2->default_priority;
3198 data->notify_data.value[1] = 0;
3201 /*******************************************************************
3202 * fill a notify_info_data with the start time
3203 ********************************************************************/
3205 static void spoolss_notify_start_time(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 data->notify_data.value[0] = printer->info_2->starttime;
3212 data->notify_data.value[1] = 0;
3215 /*******************************************************************
3216 * fill a notify_info_data with the until time
3217 ********************************************************************/
3219 static void spoolss_notify_until_time(int snum,
3220 SPOOL_NOTIFY_INFO_DATA *data,
3221 print_queue_struct *queue,
3222 NT_PRINTER_INFO_LEVEL *printer,
3223 TALLOC_CTX *mem_ctx)
3225 data->notify_data.value[0] = printer->info_2->untiltime;
3226 data->notify_data.value[1] = 0;
3229 /*******************************************************************
3230 * fill a notify_info_data with the status
3231 ********************************************************************/
3233 static void spoolss_notify_status(int snum,
3234 SPOOL_NOTIFY_INFO_DATA *data,
3235 print_queue_struct *queue,
3236 NT_PRINTER_INFO_LEVEL *printer,
3237 TALLOC_CTX *mem_ctx)
3239 print_status_struct status;
3241 print_queue_length(snum, &status);
3242 data->notify_data.value[0]=(uint32) status.status;
3243 data->notify_data.value[1] = 0;
3246 /*******************************************************************
3247 * fill a notify_info_data with the number of jobs queued
3248 ********************************************************************/
3250 void spoolss_notify_cjobs(int snum,
3251 SPOOL_NOTIFY_INFO_DATA *data,
3252 print_queue_struct *queue,
3253 NT_PRINTER_INFO_LEVEL *printer,
3254 TALLOC_CTX *mem_ctx)
3256 data->notify_data.value[0] = print_queue_length(snum, NULL);
3257 data->notify_data.value[1] = 0;
3260 /*******************************************************************
3261 * fill a notify_info_data with the average ppm
3262 ********************************************************************/
3264 static void spoolss_notify_average_ppm(int snum,
3265 SPOOL_NOTIFY_INFO_DATA *data,
3266 print_queue_struct *queue,
3267 NT_PRINTER_INFO_LEVEL *printer,
3268 TALLOC_CTX *mem_ctx)
3270 /* always respond 8 pages per minutes */
3271 /* a little hard ! */
3272 data->notify_data.value[0] = printer->info_2->averageppm;
3273 data->notify_data.value[1] = 0;
3276 /*******************************************************************
3277 * fill a notify_info_data with username
3278 ********************************************************************/
3280 static void spoolss_notify_username(int snum,
3281 SPOOL_NOTIFY_INFO_DATA *data,
3282 print_queue_struct *queue,
3283 NT_PRINTER_INFO_LEVEL *printer,
3284 TALLOC_CTX *mem_ctx)
3286 smb_ucs2_t *temp = NULL;
3289 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_user);
3290 if (len == (uint32)-1) {
3294 data->notify_data.data.length = len;
3296 data->notify_data.data.string = (uint16 *)temp;
3298 data->notify_data.data.string = NULL;
3302 /*******************************************************************
3303 * fill a notify_info_data with job status
3304 ********************************************************************/
3306 static void spoolss_notify_job_status(int snum,
3307 SPOOL_NOTIFY_INFO_DATA *data,
3308 print_queue_struct *queue,
3309 NT_PRINTER_INFO_LEVEL *printer,
3310 TALLOC_CTX *mem_ctx)
3312 data->notify_data.value[0]=nt_printj_status(queue->status);
3313 data->notify_data.value[1] = 0;
3316 /*******************************************************************
3317 * fill a notify_info_data with job name
3318 ********************************************************************/
3320 static void spoolss_notify_job_name(int snum,
3321 SPOOL_NOTIFY_INFO_DATA *data,
3322 print_queue_struct *queue,
3323 NT_PRINTER_INFO_LEVEL *printer,
3324 TALLOC_CTX *mem_ctx)
3326 smb_ucs2_t *temp = NULL;
3329 len = rpcstr_push_talloc(mem_ctx, &temp, queue->fs_file);
3330 if (len == (uint32)-1) {
3334 data->notify_data.data.length = len;
3336 data->notify_data.data.string = (uint16 *)temp;
3338 data->notify_data.data.string = NULL;
3342 /*******************************************************************
3343 * fill a notify_info_data with job status
3344 ********************************************************************/
3346 static void spoolss_notify_job_status_string(int snum,
3347 SPOOL_NOTIFY_INFO_DATA *data,
3348 print_queue_struct *queue,
3349 NT_PRINTER_INFO_LEVEL *printer,
3350 TALLOC_CTX *mem_ctx)
3353 * Now we're returning job status codes we just return a "" here. JRA.
3357 smb_ucs2_t *temp = NULL;
3360 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3363 switch (queue->status) {
3368 p = ""; /* NT provides the paused string */
3377 #endif /* NO LONGER NEEDED. */
3379 len = rpcstr_push_talloc(mem_ctx, &temp, p);
3380 if (len == (uint32)-1) {
3384 data->notify_data.data.length = len;
3386 data->notify_data.data.string = (uint16 *)temp;
3388 data->notify_data.data.string = NULL;
3392 /*******************************************************************
3393 * fill a notify_info_data with job time
3394 ********************************************************************/
3396 static void spoolss_notify_job_time(int snum,
3397 SPOOL_NOTIFY_INFO_DATA *data,
3398 print_queue_struct *queue,
3399 NT_PRINTER_INFO_LEVEL *printer,
3400 TALLOC_CTX *mem_ctx)
3402 data->notify_data.value[0]=0x0;
3403 data->notify_data.value[1]=0;
3406 /*******************************************************************
3407 * fill a notify_info_data with job size
3408 ********************************************************************/
3410 static void spoolss_notify_job_size(int snum,
3411 SPOOL_NOTIFY_INFO_DATA *data,
3412 print_queue_struct *queue,
3413 NT_PRINTER_INFO_LEVEL *printer,
3414 TALLOC_CTX *mem_ctx)
3416 data->notify_data.value[0]=queue->size;
3417 data->notify_data.value[1]=0;
3420 /*******************************************************************
3421 * fill a notify_info_data with page info
3422 ********************************************************************/
3423 static void spoolss_notify_total_pages(int snum,
3424 SPOOL_NOTIFY_INFO_DATA *data,
3425 print_queue_struct *queue,
3426 NT_PRINTER_INFO_LEVEL *printer,
3427 TALLOC_CTX *mem_ctx)
3429 data->notify_data.value[0]=queue->page_count;
3430 data->notify_data.value[1]=0;
3433 /*******************************************************************
3434 * fill a notify_info_data with pages printed info.
3435 ********************************************************************/
3436 static void spoolss_notify_pages_printed(int snum,
3437 SPOOL_NOTIFY_INFO_DATA *data,
3438 print_queue_struct *queue,
3439 NT_PRINTER_INFO_LEVEL *printer,
3440 TALLOC_CTX *mem_ctx)
3442 data->notify_data.value[0]=0; /* Add code when back-end tracks this */
3443 data->notify_data.value[1]=0;
3446 /*******************************************************************
3447 Fill a notify_info_data with job position.
3448 ********************************************************************/
3450 static void spoolss_notify_job_position(int snum,
3451 SPOOL_NOTIFY_INFO_DATA *data,
3452 print_queue_struct *queue,
3453 NT_PRINTER_INFO_LEVEL *printer,
3454 TALLOC_CTX *mem_ctx)
3456 data->notify_data.value[0]=queue->job;
3457 data->notify_data.value[1]=0;
3460 /*******************************************************************
3461 Fill a notify_info_data with submitted time.
3462 ********************************************************************/
3464 static void spoolss_notify_submitted_time(int snum,
3465 SPOOL_NOTIFY_INFO_DATA *data,
3466 print_queue_struct *queue,
3467 NT_PRINTER_INFO_LEVEL *printer,
3468 TALLOC_CTX *mem_ctx)
3475 t=gmtime(&queue->time);
3477 len = sizeof(SYSTEMTIME);
3479 data->notify_data.data.length = len;
3480 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len);
3482 if (!data->notify_data.data.string) {
3483 data->notify_data.data.length = 0;
3487 make_systemtime(&st, t);
3490 * Systemtime must be linearized as a set of UINT16's.
3491 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
3494 p = (char *)data->notify_data.data.string;
3495 SSVAL(p, 0, st.year);
3496 SSVAL(p, 2, st.month);
3497 SSVAL(p, 4, st.dayofweek);
3498 SSVAL(p, 6, st.day);
3499 SSVAL(p, 8, st.hour);
3500 SSVAL(p, 10, st.minute);
3501 SSVAL(p, 12, st.second);
3502 SSVAL(p, 14, st.milliseconds);
3505 struct s_notify_info_data_table
3511 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data,
3512 print_queue_struct *queue,
3513 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3516 /* A table describing the various print notification constants and
3517 whether the notification data is a pointer to a variable sized
3518 buffer, a one value uint32 or a two value uint32. */
3520 static const struct s_notify_info_data_table notify_info_data_table[] =
3522 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3523 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3524 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
3525 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3526 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3527 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
3528 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
3529 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3530 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
3531 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3532 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3533 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3534 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
3535 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
3536 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3537 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
3538 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3539 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3540 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
3541 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
3542 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
3543 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
3544 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
3545 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
3546 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
3547 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
3548 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3549 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3550 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3551 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
3552 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
3553 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3554 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3555 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3556 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3557 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3558 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
3559 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
3560 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
3561 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
3562 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3563 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
3564 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
3565 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3566 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3567 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
3568 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
3569 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
3570 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
3571 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3574 /*******************************************************************
3575 Return the size of info_data structure.
3576 ********************************************************************/
3578 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
3582 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3583 if ( (notify_info_data_table[i].type == type)
3584 && (notify_info_data_table[i].field == field) ) {
3585 switch(notify_info_data_table[i].size) {
3586 case NOTIFY_ONE_VALUE:
3587 case NOTIFY_TWO_VALUE:
3592 /* The only pointer notify data I have seen on
3593 the wire is the submitted time and this has
3594 the notify size set to 4. -tpot */
3596 case NOTIFY_POINTER:
3599 case NOTIFY_SECDESC:
3605 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3610 /*******************************************************************
3611 Return the type of notify_info_data.
3612 ********************************************************************/
3614 static uint32 type_of_notify_info_data(uint16 type, uint16 field)
3618 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3619 if (notify_info_data_table[i].type == type &&
3620 notify_info_data_table[i].field == field)
3621 return notify_info_data_table[i].size;
3627 /****************************************************************************
3628 ****************************************************************************/
3630 static bool search_notify(uint16 type, uint16 field, int *value)
3634 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3635 if (notify_info_data_table[i].type == type &&
3636 notify_info_data_table[i].field == field &&
3637 notify_info_data_table[i].fn != NULL) {
3646 /****************************************************************************
3647 ****************************************************************************/
3649 void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id)
3651 info_data->type = type;
3652 info_data->field = field;
3653 info_data->reserved = 0;
3655 info_data->size = size_of_notify_info_data(type, field);
3656 info_data->enc_type = type_of_notify_info_data(type, field);
3661 /*******************************************************************
3663 * fill a notify_info struct with info asked
3665 ********************************************************************/
3667 static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
3668 snum, SPOOL_NOTIFY_OPTION_TYPE
3669 *option_type, uint32 id,
3670 TALLOC_CTX *mem_ctx)
3676 SPOOL_NOTIFY_INFO_DATA *current_data;
3677 NT_PRINTER_INFO_LEVEL *printer = NULL;
3678 print_queue_struct *queue=NULL;
3680 type=option_type->type;
3682 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3683 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3684 option_type->count, lp_servicename(snum)));
3686 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3689 for(field_num=0; field_num<option_type->count; field_num++) {
3690 field = option_type->fields[field_num];
3692 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3694 if (!search_notify(type, field, &j) )
3697 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3698 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3699 free_a_printer(&printer, 2);
3703 current_data = &info->data[info->count];
3705 construct_info_data(current_data, type, field, id);
3707 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3708 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3710 notify_info_data_table[j].fn(snum, current_data, queue,
3716 free_a_printer(&printer, 2);
3720 /*******************************************************************
3722 * fill a notify_info struct with info asked
3724 ********************************************************************/
3726 static bool construct_notify_jobs_info(print_queue_struct *queue,
3727 SPOOL_NOTIFY_INFO *info,
3728 NT_PRINTER_INFO_LEVEL *printer,
3729 int snum, SPOOL_NOTIFY_OPTION_TYPE
3730 *option_type, uint32 id,
3731 TALLOC_CTX *mem_ctx)
3737 SPOOL_NOTIFY_INFO_DATA *current_data;
3739 DEBUG(4,("construct_notify_jobs_info\n"));
3741 type = option_type->type;
3743 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3744 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3745 option_type->count));
3747 for(field_num=0; field_num<option_type->count; field_num++) {
3748 field = option_type->fields[field_num];
3750 if (!search_notify(type, field, &j) )
3753 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) {
3754 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3758 current_data=&(info->data[info->count]);
3760 construct_info_data(current_data, type, field, id);
3761 notify_info_data_table[j].fn(snum, current_data, queue,
3770 * JFM: The enumeration is not that simple, it's even non obvious.
3772 * let's take an example: I want to monitor the PRINTER SERVER for
3773 * the printer's name and the number of jobs currently queued.
3774 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3775 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3777 * I have 3 printers on the back of my server.
3779 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3782 * 1 printer 1 name 1
3783 * 2 printer 1 cjob 1
3784 * 3 printer 2 name 2
3785 * 4 printer 2 cjob 2
3786 * 5 printer 3 name 3
3787 * 6 printer 3 name 3
3789 * that's the print server case, the printer case is even worse.
3792 /*******************************************************************
3794 * enumerate all printers on the printserver
3795 * fill a notify_info struct with info asked
3797 ********************************************************************/
3799 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3800 SPOOL_NOTIFY_INFO *info,
3801 TALLOC_CTX *mem_ctx)
3804 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3805 int n_services=lp_numservices();
3807 SPOOL_NOTIFY_OPTION *option;
3808 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3810 DEBUG(4,("printserver_notify_info\n"));
3815 option=Printer->notify.option;
3820 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3821 sending a ffpcn() request first */
3826 for (i=0; i<option->count; i++) {
3827 option_type=&(option->ctr.type[i]);
3829 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3832 for (snum=0; snum<n_services; snum++)
3834 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3835 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3841 * Debugging information, don't delete.
3844 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3845 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3846 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3848 for (i=0; i<info->count; i++) {
3849 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3850 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3851 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3858 /*******************************************************************
3860 * fill a notify_info struct with info asked
3862 ********************************************************************/
3864 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
3865 TALLOC_CTX *mem_ctx)
3868 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3871 SPOOL_NOTIFY_OPTION *option;
3872 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3874 print_queue_struct *queue=NULL;
3875 print_status_struct status;
3877 DEBUG(4,("printer_notify_info\n"));
3882 option=Printer->notify.option;
3888 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3889 sending a ffpcn() request first */
3894 get_printer_snum(p, hnd, &snum, NULL);
3896 for (i=0; i<option->count; i++) {
3897 option_type=&option->ctr.type[i];
3899 switch ( option_type->type ) {
3900 case PRINTER_NOTIFY_TYPE:
3901 if(construct_notify_printer_info(Printer, info, snum,
3907 case JOB_NOTIFY_TYPE: {
3908 NT_PRINTER_INFO_LEVEL *printer = NULL;
3910 count = print_queue_status(snum, &queue, &status);
3912 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3915 for (j=0; j<count; j++) {
3916 construct_notify_jobs_info(&queue[j], info,
3923 free_a_printer(&printer, 2);
3933 * Debugging information, don't delete.
3936 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3937 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3938 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3940 for (i=0; i<info->count; i++) {
3941 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3942 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3943 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3949 /********************************************************************
3951 ********************************************************************/
3953 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
3955 POLICY_HND *handle = &q_u->handle;
3956 SPOOL_NOTIFY_INFO *info = &r_u->info;
3958 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3959 WERROR result = WERR_BADFID;
3961 /* we always have a NOTIFY_INFO struct */
3965 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3966 OUR_HANDLE(handle)));
3970 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3973 * We are now using the change value, and
3974 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3975 * I don't have a global notification system, I'm sending back all the
3976 * informations even when _NOTHING_ has changed.
3979 /* We need to keep track of the change value to send back in
3980 RRPCN replies otherwise our updates are ignored. */
3982 Printer->notify.fnpcn = True;
3984 if (Printer->notify.client_connected) {
3985 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
3986 Printer->notify.change = q_u->change;
3989 /* just ignore the SPOOL_NOTIFY_OPTION */
3991 switch (Printer->printer_type) {
3993 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3996 case SPLHND_PRINTER:
3997 result = printer_notify_info(p, handle, info, p->mem_ctx);
4001 Printer->notify.fnpcn = False;
4007 /********************************************************************
4008 * construct_printer_info_0
4009 * fill a printer_info_0 struct
4010 ********************************************************************/
4012 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
4014 char *chaine = NULL;
4016 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4017 counter_printer_0 *session_counter;
4018 uint32 global_counter;
4021 print_status_struct status;
4022 TALLOC_CTX *ctx = talloc_tos();
4024 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4027 init_unistr(&printer->printername, ntprinter->info_2->printername);
4029 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
4031 free_a_printer(&ntprinter,2);
4035 count = print_queue_length(snum, &status);
4037 /* check if we already have a counter for this printer */
4038 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
4039 if (session_counter->snum == snum)
4043 init_unistr(&printer->servername, chaine);
4045 /* it's the first time, add it to the list */
4046 if (session_counter==NULL) {
4047 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
4048 free_a_printer(&ntprinter, 2);
4051 ZERO_STRUCTP(session_counter);
4052 session_counter->snum=snum;
4053 session_counter->counter=0;
4054 DLIST_ADD(counter_list, session_counter);
4058 session_counter->counter++;
4061 * the global_counter should be stored in a TDB as it's common to all the clients
4062 * and should be zeroed on samba startup
4064 global_counter=session_counter->counter;
4065 printer->cjobs = count;
4066 printer->total_jobs = 0;
4067 printer->total_bytes = 0;
4069 setuptime = (time_t)ntprinter->info_2->setuptime;
4070 t=gmtime(&setuptime);
4072 printer->year = t->tm_year+1900;
4073 printer->month = t->tm_mon+1;
4074 printer->dayofweek = t->tm_wday;
4075 printer->day = t->tm_mday;
4076 printer->hour = t->tm_hour;
4077 printer->minute = t->tm_min;
4078 printer->second = t->tm_sec;
4079 printer->milliseconds = 0;
4081 printer->global_counter = global_counter;
4082 printer->total_pages = 0;
4084 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
4085 printer->major_version = 0x0005; /* NT 5 */
4086 printer->build_version = 0x0893; /* build 2195 */
4088 printer->unknown7 = 0x1;
4089 printer->unknown8 = 0x0;
4090 printer->unknown9 = 0x0;
4091 printer->session_counter = session_counter->counter;
4092 printer->unknown11 = 0x0;
4093 printer->printer_errors = 0x0; /* number of print failure */
4094 printer->unknown13 = 0x0;
4095 printer->unknown14 = 0x1;
4096 printer->unknown15 = 0x024a; /* 586 Pentium ? */
4097 printer->unknown16 = 0x0;
4098 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
4099 printer->unknown18 = 0x0;
4100 printer->status = nt_printq_status(status.status);
4101 printer->unknown20 = 0x0;
4102 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4103 printer->unknown22 = 0x0;
4104 printer->unknown23 = 0x6; /* 6 ???*/
4105 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
4106 printer->unknown25 = 0;
4107 printer->unknown26 = 0;
4108 printer->unknown27 = 0;
4109 printer->unknown28 = 0;
4110 printer->unknown29 = 0;
4112 free_a_printer(&ntprinter,2);
4116 /********************************************************************
4117 * construct_printer_info_1
4118 * fill a printer_info_1 struct
4119 ********************************************************************/
4120 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4122 char *chaine = NULL;
4123 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4124 TALLOC_CTX *ctx = talloc_tos();
4126 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4129 printer->flags=flags;
4131 if (*ntprinter->info_2->comment == '\0') {
4132 init_unistr(&printer->comment, lp_comment(snum));
4133 chaine = talloc_asprintf(ctx,
4134 "%s,%s,%s", ntprinter->info_2->printername,
4135 ntprinter->info_2->drivername, lp_comment(snum));
4138 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4139 chaine = talloc_asprintf(ctx,
4140 "%s,%s,%s", ntprinter->info_2->printername,
4141 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4145 free_a_printer(&ntprinter,2);
4149 init_unistr(&printer->description, chaine);
4150 init_unistr(&printer->name, ntprinter->info_2->printername);
4152 free_a_printer(&ntprinter,2);
4157 /****************************************************************************
4158 Free a DEVMODE struct.
4159 ****************************************************************************/
4161 static void free_dev_mode(DEVICEMODE *dev)
4166 SAFE_FREE(dev->dev_private);
4171 /****************************************************************************
4172 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4173 should be valid upon entry
4174 ****************************************************************************/
4176 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4178 if ( !devmode || !ntdevmode )
4181 init_unistr(&devmode->devicename, ntdevmode->devicename);
4183 init_unistr(&devmode->formname, ntdevmode->formname);
4185 devmode->specversion = ntdevmode->specversion;
4186 devmode->driverversion = ntdevmode->driverversion;
4187 devmode->size = ntdevmode->size;
4188 devmode->driverextra = ntdevmode->driverextra;
4189 devmode->fields = ntdevmode->fields;
4191 devmode->orientation = ntdevmode->orientation;
4192 devmode->papersize = ntdevmode->papersize;
4193 devmode->paperlength = ntdevmode->paperlength;
4194 devmode->paperwidth = ntdevmode->paperwidth;
4195 devmode->scale = ntdevmode->scale;
4196 devmode->copies = ntdevmode->copies;
4197 devmode->defaultsource = ntdevmode->defaultsource;
4198 devmode->printquality = ntdevmode->printquality;
4199 devmode->color = ntdevmode->color;
4200 devmode->duplex = ntdevmode->duplex;
4201 devmode->yresolution = ntdevmode->yresolution;
4202 devmode->ttoption = ntdevmode->ttoption;
4203 devmode->collate = ntdevmode->collate;
4204 devmode->icmmethod = ntdevmode->icmmethod;
4205 devmode->icmintent = ntdevmode->icmintent;
4206 devmode->mediatype = ntdevmode->mediatype;
4207 devmode->dithertype = ntdevmode->dithertype;
4209 if (ntdevmode->nt_dev_private != NULL) {
4210 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4217 /****************************************************************************
4218 Create a DEVMODE struct. Returns malloced memory.
4219 ****************************************************************************/
4221 DEVICEMODE *construct_dev_mode(const char *servicename)
4223 NT_PRINTER_INFO_LEVEL *printer = NULL;
4224 DEVICEMODE *devmode = NULL;
4226 DEBUG(7,("construct_dev_mode\n"));
4228 DEBUGADD(8,("getting printer characteristics\n"));
4230 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4233 if ( !printer->info_2->devmode ) {
4234 DEBUG(5, ("BONG! There was no device mode!\n"));
4238 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4239 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4243 ZERO_STRUCTP(devmode);
4245 DEBUGADD(8,("loading DEVICEMODE\n"));
4247 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4248 free_dev_mode( devmode );
4253 free_a_printer(&printer,2);
4258 /********************************************************************
4259 * construct_printer_info_2
4260 * fill a printer_info_2 struct
4261 ********************************************************************/
4263 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4266 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4268 print_status_struct status;
4270 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4273 count = print_queue_length(snum, &status);
4275 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4276 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4277 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4278 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4279 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4281 if (*ntprinter->info_2->comment == '\0')
4282 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4284 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4286 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4287 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4288 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4289 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4290 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4292 printer->attributes = ntprinter->info_2->attributes;
4294 printer->priority = ntprinter->info_2->priority; /* priority */
4295 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4296 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4297 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4298 printer->status = nt_printq_status(status.status); /* status */
4299 printer->cjobs = count; /* jobs */
4300 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4302 if ( !(printer->devmode = construct_dev_mode(
4303 lp_const_servicename(snum))) )
4304 DEBUG(8, ("Returning NULL Devicemode!\n"));
4306 printer->secdesc = NULL;
4308 if ( ntprinter->info_2->secdesc_buf
4309 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4311 /* don't use talloc_steal() here unless you do a deep steal of all
4312 the SEC_DESC members */
4314 printer->secdesc = dup_sec_desc( talloc_tos(),
4315 ntprinter->info_2->secdesc_buf->sd );
4318 free_a_printer(&ntprinter, 2);
4323 /********************************************************************
4324 * construct_printer_info_3
4325 * fill a printer_info_3 struct
4326 ********************************************************************/
4328 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4330 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4331 PRINTER_INFO_3 *printer = NULL;
4333 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4337 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4338 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4339 free_a_printer(&ntprinter, 2);
4343 ZERO_STRUCTP(printer);
4345 /* These are the components of the SD we are returning. */
4347 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4348 /* don't use talloc_steal() here unless you do a deep steal of all
4349 the SEC_DESC members */
4351 printer->secdesc = dup_sec_desc( talloc_tos(),
4352 ntprinter->info_2->secdesc_buf->sd );
4355 free_a_printer(&ntprinter, 2);
4357 *pp_printer = printer;
4361 /********************************************************************
4362 * construct_printer_info_4
4363 * fill a printer_info_4 struct
4364 ********************************************************************/
4366 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4368 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4370 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4373 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4374 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4375 printer->attributes = ntprinter->info_2->attributes;
4377 free_a_printer(&ntprinter, 2);
4381 /********************************************************************
4382 * construct_printer_info_5
4383 * fill a printer_info_5 struct
4384 ********************************************************************/
4386 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4388 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4390 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4393 init_unistr(&printer->printername, ntprinter->info_2->printername);
4394 init_unistr(&printer->portname, ntprinter->info_2->portname);
4395 printer->attributes = ntprinter->info_2->attributes;
4397 /* these two are not used by NT+ according to MSDN */
4399 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4400 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4402 free_a_printer(&ntprinter, 2);
4407 /********************************************************************
4408 * construct_printer_info_6
4409 * fill a printer_info_6 struct
4410 ********************************************************************/
4412 static bool construct_printer_info_6(Printer_entry *print_hnd,
4413 PRINTER_INFO_6 *printer,
4416 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4418 print_status_struct status;
4420 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4421 lp_const_servicename(snum))))
4424 count = print_queue_length(snum, &status);
4426 printer->status = nt_printq_status(status.status);
4428 free_a_printer(&ntprinter, 2);
4433 /********************************************************************
4434 * construct_printer_info_7
4435 * fill a printer_info_7 struct
4436 ********************************************************************/
4438 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4440 char *guid_str = NULL;
4443 if (is_printer_published(print_hnd, snum, &guid)) {
4444 if (asprintf(&guid_str, "{%s}",
4445 GUID_string(talloc_tos(), &guid)) == -1) {
4448 strupper_m(guid_str);
4449 init_unistr(&printer->guid, guid_str);
4450 SAFE_FREE(guid_str);
4451 printer->action = SPOOL_DS_PUBLISH;
4453 init_unistr(&printer->guid, "");
4454 printer->action = SPOOL_DS_UNPUBLISH;
4460 /********************************************************************
4461 Spoolss_enumprinters.
4462 ********************************************************************/
4464 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4468 int n_services=lp_numservices();
4469 PRINTER_INFO_1 *printers=NULL;
4470 PRINTER_INFO_1 current_prt;
4471 WERROR result = WERR_OK;
4473 DEBUG(4,("enum_all_printers_info_1\n"));
4475 for (snum=0; snum<n_services; snum++) {
4476 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4477 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4479 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4480 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4481 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4485 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4487 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4493 /* check the required size. */
4494 for (i=0; i<*returned; i++)
4495 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4497 if (*needed > offered) {
4498 result = WERR_INSUFFICIENT_BUFFER;
4502 if (!rpcbuf_alloc_size(buffer, *needed)) {
4503 result = WERR_NOMEM;
4507 /* fill the buffer with the structures */
4508 for (i=0; i<*returned; i++)
4509 smb_io_printer_info_1("", buffer, &printers[i], 0);
4514 SAFE_FREE(printers);
4516 if ( !W_ERROR_IS_OK(result) )
4522 /********************************************************************
4523 enum_all_printers_info_1_local.
4524 *********************************************************************/
4526 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4528 DEBUG(4,("enum_all_printers_info_1_local\n"));
4530 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4533 /********************************************************************
4534 enum_all_printers_info_1_name.
4535 *********************************************************************/
4537 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4541 DEBUG(4,("enum_all_printers_info_1_name\n"));
4543 if ((name[0] == '\\') && (name[1] == '\\'))
4546 if (is_myname_or_ipaddr(s)) {
4547 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4550 return WERR_INVALID_NAME;
4553 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4554 /********************************************************************
4555 enum_all_printers_info_1_remote.
4556 *********************************************************************/
4558 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4560 PRINTER_INFO_1 *printer;
4561 fstring printername;
4564 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4565 WERROR result = WERR_OK;
4567 /* JFM: currently it's more a place holder than anything else.
4568 * In the spooler world there is a notion of server registration.
4569 * the print servers are registered on the PDC (in the same domain)
4571 * We should have a TDB here. The registration is done thru an
4572 * undocumented RPC call.
4575 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4580 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4581 slprintf(desc, sizeof(desc)-1,"%s", name);
4582 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4584 init_unistr(&printer->description, desc);
4585 init_unistr(&printer->name, printername);
4586 init_unistr(&printer->comment, comment);
4587 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4589 /* check the required size. */
4590 *needed += spoolss_size_printer_info_1(printer);
4592 if (*needed > offered) {
4593 result = WERR_INSUFFICIENT_BUFFER;
4597 if (!rpcbuf_alloc_size(buffer, *needed)) {
4598 result = WERR_NOMEM;
4602 /* fill the buffer with the structures */
4603 smb_io_printer_info_1("", buffer, printer, 0);
4609 if ( !W_ERROR_IS_OK(result) )
4617 /********************************************************************
4618 enum_all_printers_info_1_network.
4619 *********************************************************************/
4621 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4625 DEBUG(4,("enum_all_printers_info_1_network\n"));
4627 /* If we respond to a enum_printers level 1 on our name with flags
4628 set to PRINTER_ENUM_REMOTE with a list of printers then these
4629 printers incorrectly appear in the APW browse list.
4630 Specifically the printers for the server appear at the workgroup
4631 level where all the other servers in the domain are
4632 listed. Windows responds to this call with a
4633 WERR_CAN_NOT_COMPLETE so we should do the same. */
4635 if (name[0] == '\\' && name[1] == '\\')
4638 if (is_myname_or_ipaddr(s))
4639 return WERR_CAN_NOT_COMPLETE;
4641 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4644 /********************************************************************
4645 * api_spoolss_enumprinters
4647 * called from api_spoolss_enumprinters (see this to understand)
4648 ********************************************************************/
4650 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4654 int n_services=lp_numservices();
4655 PRINTER_INFO_2 *printers=NULL;
4656 PRINTER_INFO_2 current_prt;
4657 WERROR result = WERR_OK;
4661 for (snum=0; snum<n_services; snum++) {
4662 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4663 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4665 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4666 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4667 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4672 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4674 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4681 /* check the required size. */
4682 for (i=0; i<*returned; i++)
4683 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4685 if (*needed > offered) {
4686 result = WERR_INSUFFICIENT_BUFFER;
4690 if (!rpcbuf_alloc_size(buffer, *needed)) {
4691 result = WERR_NOMEM;
4695 /* fill the buffer with the structures */
4696 for (i=0; i<*returned; i++)
4697 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4702 for (i=0; i<*returned; i++)
4703 free_devmode(printers[i].devmode);
4705 SAFE_FREE(printers);
4707 if ( !W_ERROR_IS_OK(result) )
4713 /********************************************************************
4714 * handle enumeration of printers at level 1
4715 ********************************************************************/
4717 static WERROR enumprinters_level1( uint32 flags, fstring name,
4718 RPC_BUFFER *buffer, uint32 offered,
4719 uint32 *needed, uint32 *returned)
4721 /* Not all the flags are equals */
4723 if (flags & PRINTER_ENUM_LOCAL)
4724 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4726 if (flags & PRINTER_ENUM_NAME)
4727 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4729 #if 0 /* JERRY - disabled for now */
4730 if (flags & PRINTER_ENUM_REMOTE)
4731 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4734 if (flags & PRINTER_ENUM_NETWORK)
4735 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4737 return WERR_OK; /* NT4sp5 does that */
4740 /********************************************************************
4741 * handle enumeration of printers at level 2
4742 ********************************************************************/
4744 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4745 RPC_BUFFER *buffer, uint32 offered,
4746 uint32 *needed, uint32 *returned)
4748 if (flags & PRINTER_ENUM_LOCAL) {
4749 return enum_all_printers_info_2(buffer, offered, needed, returned);
4752 if (flags & PRINTER_ENUM_NAME) {
4753 if (is_myname_or_ipaddr(canon_servername(servername)))
4754 return enum_all_printers_info_2(buffer, offered, needed, returned);
4756 return WERR_INVALID_NAME;
4759 if (flags & PRINTER_ENUM_REMOTE)
4760 return WERR_UNKNOWN_LEVEL;
4765 /********************************************************************
4766 * handle enumeration of printers at level 5
4767 ********************************************************************/
4769 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4770 RPC_BUFFER *buffer, uint32 offered,
4771 uint32 *needed, uint32 *returned)
4773 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4777 /********************************************************************
4778 * api_spoolss_enumprinters
4780 * called from api_spoolss_enumprinters (see this to understand)
4781 ********************************************************************/
4783 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4785 uint32 flags = q_u->flags;
4786 UNISTR2 *servername = &q_u->servername;
4787 uint32 level = q_u->level;
4788 RPC_BUFFER *buffer = NULL;
4789 uint32 offered = q_u->offered;
4790 uint32 *needed = &r_u->needed;
4791 uint32 *returned = &r_u->returned;
4795 /* that's an [in out] buffer */
4797 if (!q_u->buffer && (offered!=0)) {
4798 return WERR_INVALID_PARAM;
4801 rpcbuf_move(q_u->buffer, &r_u->buffer);
4802 buffer = r_u->buffer;
4804 DEBUG(4,("_spoolss_enumprinters\n"));
4811 * flags==PRINTER_ENUM_NAME
4812 * if name=="" then enumerates all printers
4813 * if name!="" then enumerate the printer
4814 * flags==PRINTER_ENUM_REMOTE
4815 * name is NULL, enumerate printers
4816 * Level 2: name!="" enumerates printers, name can't be NULL
4817 * Level 3: doesn't exist
4818 * Level 4: does a local registry lookup
4819 * Level 5: same as Level 2
4822 unistr2_to_ascii(name, servername, sizeof(name));
4827 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4829 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4831 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4836 return WERR_UNKNOWN_LEVEL;
4839 /****************************************************************************
4840 ****************************************************************************/
4842 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4844 PRINTER_INFO_0 *printer=NULL;
4845 WERROR result = WERR_OK;
4847 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4850 construct_printer_info_0(print_hnd, printer, snum);
4852 /* check the required size. */
4853 *needed += spoolss_size_printer_info_0(printer);
4855 if (*needed > offered) {
4856 result = WERR_INSUFFICIENT_BUFFER;
4860 if (!rpcbuf_alloc_size(buffer, *needed)) {
4861 result = WERR_NOMEM;
4865 /* fill the buffer with the structures */
4866 smb_io_printer_info_0("", buffer, printer, 0);
4876 /****************************************************************************
4877 ****************************************************************************/
4879 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4881 PRINTER_INFO_1 *printer=NULL;
4882 WERROR result = WERR_OK;
4884 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4887 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4889 /* check the required size. */
4890 *needed += spoolss_size_printer_info_1(printer);
4892 if (*needed > offered) {
4893 result = WERR_INSUFFICIENT_BUFFER;
4897 if (!rpcbuf_alloc_size(buffer, *needed)) {
4898 result = WERR_NOMEM;
4902 /* fill the buffer with the structures */
4903 smb_io_printer_info_1("", buffer, printer, 0);
4912 /****************************************************************************
4913 ****************************************************************************/
4915 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4917 PRINTER_INFO_2 *printer=NULL;
4918 WERROR result = WERR_OK;
4920 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4923 construct_printer_info_2(print_hnd, printer, snum);
4925 /* check the required size. */
4926 *needed += spoolss_size_printer_info_2(printer);
4928 if (*needed > offered) {
4929 result = WERR_INSUFFICIENT_BUFFER;
4933 if (!rpcbuf_alloc_size(buffer, *needed)) {
4934 result = WERR_NOMEM;
4938 /* fill the buffer with the structures */
4939 if (!smb_io_printer_info_2("", buffer, printer, 0))
4940 result = WERR_NOMEM;
4944 free_printer_info_2(printer);
4949 /****************************************************************************
4950 ****************************************************************************/
4952 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4954 PRINTER_INFO_3 *printer=NULL;
4955 WERROR result = WERR_OK;
4957 if (!construct_printer_info_3(print_hnd, &printer, snum))
4960 /* check the required size. */
4961 *needed += spoolss_size_printer_info_3(printer);
4963 if (*needed > offered) {
4964 result = WERR_INSUFFICIENT_BUFFER;
4968 if (!rpcbuf_alloc_size(buffer, *needed)) {
4969 result = WERR_NOMEM;
4973 /* fill the buffer with the structures */
4974 smb_io_printer_info_3("", buffer, printer, 0);
4978 free_printer_info_3(printer);
4983 /****************************************************************************
4984 ****************************************************************************/
4986 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4988 PRINTER_INFO_4 *printer=NULL;
4989 WERROR result = WERR_OK;
4991 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4994 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4999 /* check the required size. */
5000 *needed += spoolss_size_printer_info_4(printer);
5002 if (*needed > offered) {
5003 result = WERR_INSUFFICIENT_BUFFER;
5007 if (!rpcbuf_alloc_size(buffer, *needed)) {
5008 result = WERR_NOMEM;
5012 /* fill the buffer with the structures */
5013 smb_io_printer_info_4("", buffer, printer, 0);
5017 free_printer_info_4(printer);
5022 /****************************************************************************
5023 ****************************************************************************/
5025 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5027 PRINTER_INFO_5 *printer=NULL;
5028 WERROR result = WERR_OK;
5030 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
5033 if (!construct_printer_info_5(print_hnd, printer, snum)) {
5034 free_printer_info_5(printer);
5038 /* check the required size. */
5039 *needed += spoolss_size_printer_info_5(printer);
5041 if (*needed > offered) {
5042 result = WERR_INSUFFICIENT_BUFFER;
5046 if (!rpcbuf_alloc_size(buffer, *needed)) {
5047 result = WERR_NOMEM;
5051 /* fill the buffer with the structures */
5052 smb_io_printer_info_5("", buffer, printer, 0);
5056 free_printer_info_5(printer);
5061 static WERROR getprinter_level_6(Printer_entry *print_hnd,
5063 RPC_BUFFER *buffer, uint32 offered,
5066 PRINTER_INFO_6 *printer;
5067 WERROR result = WERR_OK;
5069 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
5073 if (!construct_printer_info_6(print_hnd, printer, snum)) {
5074 free_printer_info_6(printer);
5078 /* check the required size. */
5079 *needed += spoolss_size_printer_info_6(printer);
5081 if (*needed > offered) {
5082 result = WERR_INSUFFICIENT_BUFFER;
5086 if (!rpcbuf_alloc_size(buffer, *needed)) {
5087 result = WERR_NOMEM;
5091 /* fill the buffer with the structures */
5092 smb_io_printer_info_6("", buffer, printer, 0);
5096 free_printer_info_6(printer);
5101 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5103 PRINTER_INFO_7 *printer=NULL;
5104 WERROR result = WERR_OK;
5106 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5109 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5110 result = WERR_NOMEM;
5114 /* check the required size. */
5115 *needed += spoolss_size_printer_info_7(printer);
5117 if (*needed > offered) {
5118 result = WERR_INSUFFICIENT_BUFFER;
5122 if (!rpcbuf_alloc_size(buffer, *needed)) {
5123 result = WERR_NOMEM;
5128 /* fill the buffer with the structures */
5129 smb_io_printer_info_7("", buffer, printer, 0);
5133 free_printer_info_7(printer);
5138 /****************************************************************************
5139 ****************************************************************************/
5141 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5143 POLICY_HND *handle = &q_u->handle;
5144 uint32 level = q_u->level;
5145 RPC_BUFFER *buffer = NULL;
5146 uint32 offered = q_u->offered;
5147 uint32 *needed = &r_u->needed;
5148 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5152 /* that's an [in out] buffer */
5154 if (!q_u->buffer && (offered!=0)) {
5155 return WERR_INVALID_PARAM;
5158 rpcbuf_move(q_u->buffer, &r_u->buffer);
5159 buffer = r_u->buffer;
5163 if (!get_printer_snum(p, handle, &snum, NULL))
5168 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5170 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5172 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5174 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5176 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5178 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5180 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5182 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5184 return WERR_UNKNOWN_LEVEL;
5187 /********************************************************************
5188 * fill a DRIVER_INFO_1 struct
5189 ********************************************************************/
5191 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5193 init_unistr( &info->name, driver.info_3->name);
5196 /********************************************************************
5197 * construct_printer_driver_info_1
5198 ********************************************************************/
5200 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5202 NT_PRINTER_INFO_LEVEL *printer = NULL;
5203 NT_PRINTER_DRIVER_INFO_LEVEL driver;
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_1(info, driver, servername, architecture);
5217 free_a_printer(&printer,2);
5222 /********************************************************************
5223 * construct_printer_driver_info_2
5224 * fill a printer_info_2 struct
5225 ********************************************************************/
5227 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5229 TALLOC_CTX *ctx = talloc_tos();
5231 const char *cservername = canon_servername(servername);
5233 info->version=driver.info_3->cversion;
5235 init_unistr( &info->name, driver.info_3->name );
5236 init_unistr( &info->architecture, driver.info_3->environment );
5238 if (strlen(driver.info_3->driverpath)) {
5239 temp = talloc_asprintf(ctx,
5242 driver.info_3->driverpath);
5243 init_unistr( &info->driverpath, temp );
5245 init_unistr( &info->driverpath, "" );
5249 if (strlen(driver.info_3->datafile)) {
5250 temp = talloc_asprintf(ctx,
5253 driver.info_3->datafile);
5254 init_unistr( &info->datafile, temp );
5256 init_unistr( &info->datafile, "" );
5259 if (strlen(driver.info_3->configfile)) {
5260 temp = talloc_asprintf(ctx,
5263 driver.info_3->configfile);
5264 init_unistr( &info->configfile, temp );
5266 init_unistr( &info->configfile, "" );
5269 /********************************************************************
5270 * construct_printer_driver_info_2
5271 * fill a printer_info_2 struct
5272 ********************************************************************/
5274 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5276 NT_PRINTER_INFO_LEVEL *printer = NULL;
5277 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5279 ZERO_STRUCT(printer);
5280 ZERO_STRUCT(driver);
5282 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5283 return WERR_INVALID_PRINTER_NAME;
5285 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5286 free_a_printer(&printer, 2);
5287 return WERR_UNKNOWN_PRINTER_DRIVER;
5290 fill_printer_driver_info_2(info, driver, servername);
5292 free_a_printer(&printer,2);
5297 /********************************************************************
5298 * copy a strings array and convert to UNICODE
5300 * convert an array of ascii string to a UNICODE string
5301 ********************************************************************/
5303 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5309 TALLOC_CTX *ctx = talloc_tos();
5311 DEBUG(6,("init_unistr_array\n"));
5315 if ( !char_array ) {
5320 v = ""; /* hack to handle null lists */
5323 /* hack to allow this to be used in places other than when generating
5324 the list of dependent files */
5328 line = talloc_asprintf(ctx,
5330 canon_servername(servername),
5333 line = talloc_strdup(ctx, v);
5337 SAFE_FREE(*uni_array);
5340 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5342 /* add one extra unit16 for the second terminating NULL */
5344 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5345 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5352 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5357 /* special case for ""; we need to add both NULL's here */
5359 (*uni_array)[j++]=0x0000;
5360 (*uni_array)[j]=0x0000;
5363 DEBUGADD(6,("last one:done\n"));
5365 /* return size of array in uint16's */
5370 /********************************************************************
5371 * construct_printer_info_3
5372 * fill a printer_info_3 struct
5373 ********************************************************************/
5375 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5378 TALLOC_CTX *ctx = talloc_tos();
5379 const char *cservername = canon_servername(servername);
5383 info->version=driver.info_3->cversion;
5385 init_unistr( &info->name, driver.info_3->name );
5386 init_unistr( &info->architecture, driver.info_3->environment );
5388 if (strlen(driver.info_3->driverpath)) {
5389 temp = talloc_asprintf(ctx,
5392 driver.info_3->driverpath);
5393 init_unistr( &info->driverpath, temp );
5395 init_unistr( &info->driverpath, "" );
5398 if (strlen(driver.info_3->datafile)) {
5399 temp = talloc_asprintf(ctx,
5402 driver.info_3->datafile);
5403 init_unistr( &info->datafile, temp );
5405 init_unistr( &info->datafile, "" );
5408 if (strlen(driver.info_3->configfile)) {
5409 temp = talloc_asprintf(ctx,
5412 driver.info_3->configfile);
5413 init_unistr( &info->configfile, temp );
5415 init_unistr( &info->configfile, "" );
5418 if (strlen(driver.info_3->helpfile)) {
5419 temp = talloc_asprintf(ctx,
5422 driver.info_3->helpfile);
5423 init_unistr( &info->helpfile, temp );
5425 init_unistr( &info->helpfile, "" );
5428 init_unistr( &info->monitorname, driver.info_3->monitorname );
5429 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5431 info->dependentfiles=NULL;
5432 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5435 /********************************************************************
5436 * construct_printer_info_3
5437 * fill a printer_info_3 struct
5438 ********************************************************************/
5440 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5442 NT_PRINTER_INFO_LEVEL *printer = NULL;
5443 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5445 ZERO_STRUCT(driver);
5447 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5448 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5449 if (!W_ERROR_IS_OK(status))
5450 return WERR_INVALID_PRINTER_NAME;
5452 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5453 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5458 * I put this code in during testing. Helpful when commenting out the
5459 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5460 * as win2k always queries the driver using an infor level of 6.
5461 * I've left it in (but ifdef'd out) because I'll probably
5462 * use it in experimentation again in the future. --jerry 22/01/2002
5465 if (!W_ERROR_IS_OK(status)) {
5467 * Is this a W2k client ?
5470 /* Yes - try again with a WinNT driver. */
5472 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5473 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5477 if (!W_ERROR_IS_OK(status)) {
5478 free_a_printer(&printer,2);
5479 return WERR_UNKNOWN_PRINTER_DRIVER;
5487 fill_printer_driver_info_3(info, driver, servername);
5489 free_a_printer(&printer,2);
5494 /********************************************************************
5495 * construct_printer_info_6
5496 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5497 ********************************************************************/
5499 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5503 TALLOC_CTX *ctx = talloc_tos();
5504 const char *cservername = canon_servername(servername);
5507 memset(&nullstr, '\0', sizeof(fstring));
5509 info->version=driver.info_3->cversion;
5511 init_unistr( &info->name, driver.info_3->name );
5512 init_unistr( &info->architecture, driver.info_3->environment );
5514 if (strlen(driver.info_3->driverpath)) {
5515 temp = talloc_asprintf(ctx,
5518 driver.info_3->driverpath);
5519 init_unistr( &info->driverpath, temp );
5521 init_unistr( &info->driverpath, "" );
5524 if (strlen(driver.info_3->datafile)) {
5525 temp = talloc_asprintf(ctx,
5528 driver.info_3->datafile);
5529 init_unistr( &info->datafile, temp );
5531 init_unistr( &info->datafile, "" );
5534 if (strlen(driver.info_3->configfile)) {
5535 temp = talloc_asprintf(ctx,
5538 driver.info_3->configfile);
5539 init_unistr( &info->configfile, temp );
5541 init_unistr( &info->configfile, "" );
5544 if (strlen(driver.info_3->helpfile)) {
5545 temp = talloc_asprintf(ctx,
5548 driver.info_3->helpfile);
5549 init_unistr( &info->helpfile, temp );
5551 init_unistr( &info->helpfile, "" );
5554 init_unistr( &info->monitorname, driver.info_3->monitorname );
5555 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5557 info->dependentfiles = NULL;
5558 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5560 info->previousdrivernames=NULL;
5561 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5563 info->driver_date=0;
5566 info->driver_version_low=0;
5567 info->driver_version_high=0;
5569 init_unistr( &info->mfgname, "");
5570 init_unistr( &info->oem_url, "");
5571 init_unistr( &info->hardware_id, "");
5572 init_unistr( &info->provider, "");
5575 /********************************************************************
5576 * construct_printer_info_6
5577 * fill a printer_info_6 struct
5578 ********************************************************************/
5580 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5581 const char *servername, fstring architecture, uint32 version)
5583 NT_PRINTER_INFO_LEVEL *printer = NULL;
5584 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5587 ZERO_STRUCT(driver);
5589 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5591 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5593 if (!W_ERROR_IS_OK(status))
5594 return WERR_INVALID_PRINTER_NAME;
5596 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5598 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5600 if (!W_ERROR_IS_OK(status))
5603 * Is this a W2k client ?
5607 free_a_printer(&printer,2);
5608 return WERR_UNKNOWN_PRINTER_DRIVER;
5611 /* Yes - try again with a WinNT driver. */
5613 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5614 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5615 if (!W_ERROR_IS_OK(status)) {
5616 free_a_printer(&printer,2);
5617 return WERR_UNKNOWN_PRINTER_DRIVER;
5621 fill_printer_driver_info_6(info, driver, servername);
5623 free_a_printer(&printer,2);
5624 free_a_printer_driver(driver, 3);
5629 /****************************************************************************
5630 ****************************************************************************/
5632 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5634 SAFE_FREE(info->dependentfiles);
5637 /****************************************************************************
5638 ****************************************************************************/
5640 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5642 SAFE_FREE(info->dependentfiles);
5645 /****************************************************************************
5646 ****************************************************************************/
5648 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5650 DRIVER_INFO_1 *info=NULL;
5653 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5656 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5657 if (!W_ERROR_IS_OK(result))
5660 /* check the required size. */
5661 *needed += spoolss_size_printer_driver_info_1(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_1("", buffer, info, 0);
5683 /****************************************************************************
5684 ****************************************************************************/
5686 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5688 DRIVER_INFO_2 *info=NULL;
5691 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5694 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5695 if (!W_ERROR_IS_OK(result))
5698 /* check the required size. */
5699 *needed += spoolss_size_printer_driver_info_2(info);
5701 if (*needed > offered) {
5702 result = WERR_INSUFFICIENT_BUFFER;
5706 if (!rpcbuf_alloc_size(buffer, *needed)) {
5707 result = WERR_NOMEM;
5711 /* fill the buffer with the structures */
5712 smb_io_printer_driver_info_2("", buffer, info, 0);
5721 /****************************************************************************
5722 ****************************************************************************/
5724 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5731 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5732 if (!W_ERROR_IS_OK(result))
5735 /* check the required size. */
5736 *needed += spoolss_size_printer_driver_info_3(&info);
5738 if (*needed > offered) {
5739 result = WERR_INSUFFICIENT_BUFFER;
5743 if (!rpcbuf_alloc_size(buffer, *needed)) {
5744 result = WERR_NOMEM;
5748 /* fill the buffer with the structures */
5749 smb_io_printer_driver_info_3("", buffer, &info, 0);
5752 free_printer_driver_info_3(&info);
5757 /****************************************************************************
5758 ****************************************************************************/
5760 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5767 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5768 if (!W_ERROR_IS_OK(result))
5771 /* check the required size. */
5772 *needed += spoolss_size_printer_driver_info_6(&info);
5774 if (*needed > offered) {
5775 result = WERR_INSUFFICIENT_BUFFER;
5779 if (!rpcbuf_alloc_size(buffer, *needed)) {
5780 result = WERR_NOMEM;
5784 /* fill the buffer with the structures */
5785 smb_io_printer_driver_info_6("", buffer, &info, 0);
5788 free_printer_driver_info_6(&info);
5793 /****************************************************************************
5794 ****************************************************************************/
5796 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5798 POLICY_HND *handle = &q_u->handle;
5799 UNISTR2 *uni_arch = &q_u->architecture;
5800 uint32 level = q_u->level;
5801 uint32 clientmajorversion = q_u->clientmajorversion;
5802 RPC_BUFFER *buffer = NULL;
5803 uint32 offered = q_u->offered;
5804 uint32 *needed = &r_u->needed;
5805 uint32 *servermajorversion = &r_u->servermajorversion;
5806 uint32 *serverminorversion = &r_u->serverminorversion;
5807 Printer_entry *printer;
5810 fstring architecture;
5813 /* that's an [in out] buffer */
5815 if (!q_u->buffer && (offered!=0)) {
5816 return WERR_INVALID_PARAM;
5819 rpcbuf_move(q_u->buffer, &r_u->buffer);
5820 buffer = r_u->buffer;
5822 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5824 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5825 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5826 return WERR_INVALID_PRINTER_NAME;
5830 *servermajorversion = 0;
5831 *serverminorversion = 0;
5833 fstrcpy(servername, get_server_name( printer ));
5834 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5836 if (!get_printer_snum(p, handle, &snum, NULL))
5841 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5843 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5845 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5847 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5850 /* apparently this call is the equivalent of
5851 EnumPrinterDataEx() for the DsDriver key */
5856 return WERR_UNKNOWN_LEVEL;
5860 /****************************************************************
5861 _spoolss_StartPagePrinter
5862 ****************************************************************/
5864 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5865 struct spoolss_StartPagePrinter *r)
5867 POLICY_HND *handle = r->in.handle;
5869 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5872 DEBUG(3,("_spoolss_StartPagePrinter: "
5873 "Error in startpageprinter printer handle\n"));
5877 Printer->page_started=True;
5881 /****************************************************************
5882 _spoolss_EndPagePrinter
5883 ****************************************************************/
5885 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5886 struct spoolss_EndPagePrinter *r)
5888 POLICY_HND *handle = r->in.handle;
5891 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5894 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5895 OUR_HANDLE(handle)));
5899 if (!get_printer_snum(p, handle, &snum, NULL))
5902 Printer->page_started=False;
5903 print_job_endpage(snum, Printer->jobid);
5908 /****************************************************************
5909 _spoolss_StartDocPrinter
5910 ****************************************************************/
5912 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5913 struct spoolss_StartDocPrinter *r)
5915 POLICY_HND *handle = r->in.handle;
5916 uint32_t *jobid = r->out.job_id;
5917 struct spoolss_DocumentInfo1 *info_1;
5919 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5922 DEBUG(2,("_spoolss_StartDocPrinter: "
5923 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5927 if (r->in.level != 1) {
5928 return WERR_UNKNOWN_LEVEL;
5931 info_1 = r->in.info.info1;
5934 * a nice thing with NT is it doesn't listen to what you tell it.
5935 * when asked to send _only_ RAW datas, it tries to send datas
5938 * So I add checks like in NT Server ...
5941 if (info_1->datatype) {
5942 if (strcmp(info_1->datatype, "RAW") != 0) {
5944 return WERR_INVALID_DATATYPE;
5948 /* get the share number of the printer */
5949 if (!get_printer_snum(p, handle, &snum, NULL)) {
5953 Printer->jobid = print_job_start(p->server_info, snum,
5954 CONST_DISCARD(char *,info_1->document_name),
5955 Printer->nt_devmode);
5957 /* An error occured in print_job_start() so return an appropriate
5960 if (Printer->jobid == -1) {
5961 return map_werror_from_unix(errno);
5964 Printer->document_started=True;
5965 (*jobid) = Printer->jobid;
5970 /****************************************************************
5971 _spoolss_EndDocPrinter
5972 ****************************************************************/
5974 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5975 struct spoolss_EndDocPrinter *r)
5977 POLICY_HND *handle = r->in.handle;
5979 return _spoolss_enddocprinter_internal(p, handle);
5982 /****************************************************************
5983 _spoolss_WritePrinter
5984 ****************************************************************/
5986 WERROR _spoolss_WritePrinter(pipes_struct *p,
5987 struct spoolss_WritePrinter *r)
5989 POLICY_HND *handle = r->in.handle;
5990 uint32 buffer_size = r->in._data_size;
5991 uint8 *buffer = r->in.data.data;
5992 uint32 *buffer_written = &r->in._data_size;
5994 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5997 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5998 OUR_HANDLE(handle)));
5999 *r->out.num_written = r->in._data_size;
6003 if (!get_printer_snum(p, handle, &snum, NULL))
6006 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
6007 (SMB_OFF_T)-1, (size_t)buffer_size);
6008 if (*buffer_written == (uint32)-1) {
6009 *r->out.num_written = 0;
6010 if (errno == ENOSPC)
6011 return WERR_NO_SPOOL_SPACE;
6013 return WERR_ACCESS_DENIED;
6016 *r->out.num_written = r->in._data_size;
6021 /********************************************************************
6022 * api_spoolss_getprinter
6023 * called from the spoolss dispatcher
6025 ********************************************************************/
6027 static WERROR control_printer(POLICY_HND *handle, uint32 command,
6031 WERROR errcode = WERR_BADFUNC;
6032 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6035 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6039 if (!get_printer_snum(p, handle, &snum, NULL))
6043 case PRINTER_CONTROL_PAUSE:
6044 if (print_queue_pause(p->server_info, snum, &errcode)) {
6048 case PRINTER_CONTROL_RESUME:
6049 case PRINTER_CONTROL_UNPAUSE:
6050 if (print_queue_resume(p->server_info, snum, &errcode)) {
6054 case PRINTER_CONTROL_PURGE:
6055 if (print_queue_purge(p->server_info, snum, &errcode)) {
6060 return WERR_UNKNOWN_LEVEL;
6067 /****************************************************************
6068 _spoolss_AbortPrinter
6069 * From MSDN: "Deletes printer's spool file if printer is configured
6071 ****************************************************************/
6073 WERROR _spoolss_AbortPrinter(pipes_struct *p,
6074 struct spoolss_AbortPrinter *r)
6076 POLICY_HND *handle = r->in.handle;
6077 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6079 WERROR errcode = WERR_OK;
6082 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
6083 OUR_HANDLE(handle)));
6087 if (!get_printer_snum(p, handle, &snum, NULL))
6090 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6095 /********************************************************************
6096 * called by spoolss_api_setprinter
6097 * when updating a printer description
6098 ********************************************************************/
6100 static WERROR update_printer_sec(POLICY_HND *handle, uint32 level,
6101 const SPOOL_PRINTER_INFO_LEVEL *info,
6102 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6104 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6108 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6110 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6111 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6112 OUR_HANDLE(handle)));
6114 result = WERR_BADFID;
6119 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6120 result = WERR_INVALID_PARAM;
6124 /* Check the user has permissions to change the security
6125 descriptor. By experimentation with two NT machines, the user
6126 requires Full Access to the printer to change security
6129 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6130 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6131 result = WERR_ACCESS_DENIED;
6135 /* NT seems to like setting the security descriptor even though
6136 nothing may have actually changed. */
6138 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6139 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6140 result = WERR_BADFID;
6144 if (DEBUGLEVEL >= 10) {
6148 the_acl = old_secdesc_ctr->sd->dacl;
6149 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6150 PRINTERNAME(snum), the_acl->num_aces));
6152 for (i = 0; i < the_acl->num_aces; i++) {
6153 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6154 &the_acl->aces[i].trustee),
6155 the_acl->aces[i].access_mask));
6158 the_acl = secdesc_ctr->sd->dacl;
6161 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6162 PRINTERNAME(snum), the_acl->num_aces));
6164 for (i = 0; i < the_acl->num_aces; i++) {
6165 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6166 &the_acl->aces[i].trustee),
6167 the_acl->aces[i].access_mask));
6170 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6174 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6175 if (!new_secdesc_ctr) {
6176 result = WERR_NOMEM;
6180 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6185 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6192 /********************************************************************
6193 Canonicalize printer info from a client
6195 ATTN: It does not matter what we set the servername to hear
6196 since we do the necessary work in get_a_printer() to set it to
6197 the correct value based on what the client sent in the
6198 _spoolss_open_printer_ex().
6199 ********************************************************************/
6201 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6203 fstring printername;
6206 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6207 "portname=%s drivername=%s comment=%s location=%s\n",
6208 info->servername, info->printername, info->sharename,
6209 info->portname, info->drivername, info->comment, info->location));
6211 /* we force some elements to "correct" values */
6212 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6213 fstrcpy(info->sharename, lp_servicename(snum));
6215 /* check to see if we allow printername != sharename */
6217 if ( lp_force_printername(snum) ) {
6218 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6219 global_myname(), info->sharename );
6222 /* make sure printername is in \\server\printername format */
6224 fstrcpy( printername, info->printername );
6226 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6227 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6231 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6232 global_myname(), p );
6235 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6236 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6243 /****************************************************************************
6244 ****************************************************************************/
6246 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6248 char *cmd = lp_addport_cmd();
6249 char *command = NULL;
6251 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6252 bool is_print_op = False;
6255 return WERR_ACCESS_DENIED;
6258 command = talloc_asprintf(ctx,
6259 "%s \"%s\" \"%s\"", cmd, portname, uri );
6265 is_print_op = user_has_privileges( token, &se_printop );
6267 DEBUG(10,("Running [%s]\n", command));
6269 /********* BEGIN SePrintOperatorPrivilege **********/
6274 ret = smbrun(command, NULL);
6279 /********* END SePrintOperatorPrivilege **********/
6281 DEBUGADD(10,("returned [%d]\n", ret));
6283 TALLOC_FREE(command);
6286 return WERR_ACCESS_DENIED;
6292 /****************************************************************************
6293 ****************************************************************************/
6295 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6297 char *cmd = lp_addprinter_cmd();
6299 char *command = NULL;
6303 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6304 bool is_print_op = False;
6305 char *remote_machine = talloc_strdup(ctx, "%m");
6307 if (!remote_machine) {
6310 remote_machine = talloc_sub_basic(ctx,
6311 current_user_info.smb_name,
6312 current_user_info.domain,
6314 if (!remote_machine) {
6318 command = talloc_asprintf(ctx,
6319 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6320 cmd, printer->info_2->printername, printer->info_2->sharename,
6321 printer->info_2->portname, printer->info_2->drivername,
6322 printer->info_2->location, printer->info_2->comment, remote_machine);
6328 is_print_op = user_has_privileges( token, &se_printop );
6330 DEBUG(10,("Running [%s]\n", command));
6332 /********* BEGIN SePrintOperatorPrivilege **********/
6337 if ( (ret = smbrun(command, &fd)) == 0 ) {
6338 /* Tell everyone we updated smb.conf. */
6339 message_send_all(smbd_messaging_context(),
6340 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6346 /********* END SePrintOperatorPrivilege **********/
6348 DEBUGADD(10,("returned [%d]\n", ret));
6350 TALLOC_FREE(command);
6351 TALLOC_FREE(remote_machine);
6359 /* reload our services immediately */
6360 reload_services( False );
6363 /* Get lines and convert them back to dos-codepage */
6364 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6365 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6368 /* Set the portname to what the script says the portname should be. */
6369 /* but don't require anything to be return from the script exit a good error code */
6372 /* Set the portname to what the script says the portname should be. */
6373 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6374 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6377 TALLOC_FREE(qlines);
6382 /********************************************************************
6383 * Called by spoolss_api_setprinter
6384 * when updating a printer description.
6385 ********************************************************************/
6387 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level,
6388 const SPOOL_PRINTER_INFO_LEVEL *info,
6389 DEVICEMODE *devmode)
6392 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6393 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6398 DEBUG(8,("update_printer\n"));
6403 result = WERR_BADFID;
6407 if (!get_printer_snum(p, handle, &snum, NULL)) {
6408 result = WERR_BADFID;
6412 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6413 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6414 result = WERR_BADFID;
6418 DEBUGADD(8,("Converting info_2 struct\n"));
6421 * convert_printer_info converts the incoming
6422 * info from the client and overwrites the info
6423 * just read from the tdb in the pointer 'printer'.
6426 if (!convert_printer_info(info, printer, level)) {
6427 result = WERR_NOMEM;
6432 /* we have a valid devmode
6433 convert it and link it*/
6435 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6436 if (!convert_devicemode(printer->info_2->printername, devmode,
6437 &printer->info_2->devmode)) {
6438 result = WERR_NOMEM;
6443 /* Do sanity check on the requested changes for Samba */
6445 if (!check_printer_ok(printer->info_2, snum)) {
6446 result = WERR_INVALID_PARAM;
6450 /* FIXME!!! If the driver has changed we really should verify that
6451 it is installed before doing much else --jerry */
6453 /* Check calling user has permission to update printer description */
6455 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6456 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6457 result = WERR_ACCESS_DENIED;
6461 /* Call addprinter hook */
6462 /* Check changes to see if this is really needed */
6464 if ( *lp_addprinter_cmd()
6465 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6466 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6467 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6468 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6470 /* add_printer_hook() will call reload_services() */
6472 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6474 result = WERR_ACCESS_DENIED;
6480 * When a *new* driver is bound to a printer, the drivername is used to
6481 * lookup previously saved driver initialization info, which is then
6482 * bound to the printer, simulating what happens in the Windows arch.
6484 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6486 if (!set_driver_init(printer, 2))
6488 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6489 printer->info_2->drivername));
6492 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6493 printer->info_2->drivername));
6495 notify_printer_driver(snum, printer->info_2->drivername);
6499 * flag which changes actually occured. This is a small subset of
6500 * all the possible changes. We also have to update things in the
6504 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6505 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6506 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6507 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6509 notify_printer_comment(snum, printer->info_2->comment);
6512 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6513 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6514 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6515 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6517 notify_printer_sharename(snum, printer->info_2->sharename);
6520 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6523 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6526 pname = printer->info_2->printername;
6529 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6530 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6531 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6533 notify_printer_printername( snum, pname );
6536 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6537 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6538 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6539 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6541 notify_printer_port(snum, printer->info_2->portname);
6544 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6545 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6546 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6547 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6549 notify_printer_location(snum, printer->info_2->location);
6552 /* here we need to update some more DsSpooler keys */
6553 /* uNCName, serverName, shortServerName */
6555 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6556 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6557 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6558 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6559 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6561 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6562 global_myname(), printer->info_2->sharename );
6563 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6564 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6565 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6567 /* Update printer info */
6568 result = mod_a_printer(printer, 2);
6571 free_a_printer(&printer, 2);
6572 free_a_printer(&old_printer, 2);
6578 /****************************************************************************
6579 ****************************************************************************/
6580 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6581 const SPOOL_PRINTER_INFO_LEVEL *info)
6584 SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7;
6586 Printer_entry *Printer;
6588 if ( lp_security() != SEC_ADS ) {
6589 return WERR_UNKNOWN_LEVEL;
6592 Printer = find_printer_index_by_hnd(p, handle);
6594 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6599 if (!get_printer_snum(p, handle, &snum, NULL))
6602 nt_printer_publish(Printer, snum, info7->action);
6606 return WERR_UNKNOWN_LEVEL;
6609 /****************************************************************************
6610 ****************************************************************************/
6612 WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u)
6614 POLICY_HND *handle = &q_u->handle;
6615 uint32 level = q_u->level;
6616 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
6617 DEVMODE_CTR devmode_ctr = q_u->devmode_ctr;
6618 SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr;
6619 uint32 command = q_u->command;
6622 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6625 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6629 /* check the level */
6632 return control_printer(handle, command, p);
6634 result = update_printer(p, handle, level, info, devmode_ctr.devmode);
6635 if (!W_ERROR_IS_OK(result))
6638 result = update_printer_sec(handle, level, info, p, secdesc_ctr);
6641 return update_printer_sec(handle, level, info, p,
6644 return publish_or_unpublish_printer(p, handle, info);
6646 return WERR_UNKNOWN_LEVEL;
6650 /****************************************************************
6651 _spoolss_FindClosePrinterNotify
6652 ****************************************************************/
6654 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6655 struct spoolss_FindClosePrinterNotify *r)
6657 POLICY_HND *handle = r->in.handle;
6658 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6661 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6662 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6666 if (Printer->notify.client_connected==True) {
6669 if ( Printer->printer_type == SPLHND_SERVER)
6671 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6672 !get_printer_snum(p, handle, &snum, NULL) )
6675 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6678 Printer->notify.flags=0;
6679 Printer->notify.options=0;
6680 Printer->notify.localmachine[0]='\0';
6681 Printer->notify.printerlocal=0;
6682 if (Printer->notify.option)
6683 free_spool_notify_option(&Printer->notify.option);
6684 Printer->notify.client_connected=False;
6689 /****************************************************************
6691 ****************************************************************/
6693 WERROR _spoolss_AddJob(pipes_struct *p,
6694 struct spoolss_AddJob *r)
6696 if (!r->in.buffer && (r->in.offered != 0)) {
6697 return WERR_INVALID_PARAM;
6700 /* this is what a NT server returns for AddJob. AddJob must fail on
6701 * non-local printers */
6703 return WERR_INVALID_PARAM;
6706 /****************************************************************************
6707 ****************************************************************************/
6709 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6710 int position, int snum,
6711 const NT_PRINTER_INFO_LEVEL *ntprinter)
6715 t=gmtime(&queue->time);
6717 job_info->jobid=queue->job;
6718 init_unistr(&job_info->printername, lp_servicename(snum));
6719 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6720 init_unistr(&job_info->username, queue->fs_user);
6721 init_unistr(&job_info->document, queue->fs_file);
6722 init_unistr(&job_info->datatype, "RAW");
6723 init_unistr(&job_info->text_status, "");
6724 job_info->status=nt_printj_status(queue->status);
6725 job_info->priority=queue->priority;
6726 job_info->position=position;
6727 job_info->totalpages=queue->page_count;
6728 job_info->pagesprinted=0;
6730 make_systemtime(&job_info->submitted, t);
6733 /****************************************************************************
6734 ****************************************************************************/
6736 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6737 int position, int snum,
6738 const NT_PRINTER_INFO_LEVEL *ntprinter,
6739 DEVICEMODE *devmode)
6743 t=gmtime(&queue->time);
6745 job_info->jobid=queue->job;
6747 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6749 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6750 init_unistr(&job_info->username, queue->fs_user);
6751 init_unistr(&job_info->document, queue->fs_file);
6752 init_unistr(&job_info->notifyname, queue->fs_user);
6753 init_unistr(&job_info->datatype, "RAW");
6754 init_unistr(&job_info->printprocessor, "winprint");
6755 init_unistr(&job_info->parameters, "");
6756 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6757 init_unistr(&job_info->text_status, "");
6759 /* and here the security descriptor */
6761 job_info->status=nt_printj_status(queue->status);
6762 job_info->priority=queue->priority;
6763 job_info->position=position;
6764 job_info->starttime=0;
6765 job_info->untiltime=0;
6766 job_info->totalpages=queue->page_count;
6767 job_info->size=queue->size;
6768 make_systemtime(&(job_info->submitted), t);
6769 job_info->timeelapsed=0;
6770 job_info->pagesprinted=0;
6772 job_info->devmode = devmode;
6777 /****************************************************************************
6778 Enumjobs at level 1.
6779 ****************************************************************************/
6781 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6782 const NT_PRINTER_INFO_LEVEL *ntprinter,
6783 RPC_BUFFER *buffer, uint32 offered,
6784 uint32 *needed, uint32 *returned)
6788 WERROR result = WERR_OK;
6790 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6796 for (i=0; i<*returned; i++)
6797 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6799 /* check the required size. */
6800 for (i=0; i<*returned; i++)
6801 (*needed) += spoolss_size_job_info_1(&info[i]);
6803 if (*needed > offered) {
6804 result = WERR_INSUFFICIENT_BUFFER;
6808 if (!rpcbuf_alloc_size(buffer, *needed)) {
6809 result = WERR_NOMEM;
6813 /* fill the buffer with the structures */
6814 for (i=0; i<*returned; i++)
6815 smb_io_job_info_1("", buffer, &info[i], 0);
6821 if ( !W_ERROR_IS_OK(result) )
6827 /****************************************************************************
6828 Enumjobs at level 2.
6829 ****************************************************************************/
6831 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6832 const NT_PRINTER_INFO_LEVEL *ntprinter,
6833 RPC_BUFFER *buffer, uint32 offered,
6834 uint32 *needed, uint32 *returned)
6836 JOB_INFO_2 *info = NULL;
6838 WERROR result = WERR_OK;
6839 DEVICEMODE *devmode = NULL;
6841 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6846 /* this should not be a failure condition if the devmode is NULL */
6848 devmode = construct_dev_mode(lp_const_servicename(snum));
6850 for (i=0; i<*returned; i++)
6851 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6853 /* check the required size. */
6854 for (i=0; i<*returned; i++)
6855 (*needed) += spoolss_size_job_info_2(&info[i]);
6857 if (*needed > offered) {
6858 result = WERR_INSUFFICIENT_BUFFER;
6862 if (!rpcbuf_alloc_size(buffer, *needed)) {
6863 result = WERR_NOMEM;
6867 /* fill the buffer with the structures */
6868 for (i=0; i<*returned; i++)
6869 smb_io_job_info_2("", buffer, &info[i], 0);
6872 free_devmode(devmode);
6875 if ( !W_ERROR_IS_OK(result) )
6882 /****************************************************************************
6884 ****************************************************************************/
6886 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6888 POLICY_HND *handle = &q_u->handle;
6889 uint32 level = q_u->level;
6890 RPC_BUFFER *buffer = NULL;
6891 uint32 offered = q_u->offered;
6892 uint32 *needed = &r_u->needed;
6893 uint32 *returned = &r_u->returned;
6895 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6897 print_status_struct prt_status;
6898 print_queue_struct *queue=NULL;
6900 /* that's an [in out] buffer */
6902 if (!q_u->buffer && (offered!=0)) {
6903 return WERR_INVALID_PARAM;
6906 rpcbuf_move(q_u->buffer, &r_u->buffer);
6907 buffer = r_u->buffer;
6909 DEBUG(4,("_spoolss_enumjobs\n"));
6914 /* lookup the printer snum and tdb entry */
6916 if (!get_printer_snum(p, handle, &snum, NULL))
6919 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6920 if ( !W_ERROR_IS_OK(wret) )
6923 *returned = print_queue_status(snum, &queue, &prt_status);
6924 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6926 if (*returned == 0) {
6928 free_a_printer(&ntprinter, 2);
6934 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6937 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6941 wret = WERR_UNKNOWN_LEVEL;
6946 free_a_printer( &ntprinter, 2 );
6950 /****************************************************************
6951 _spoolss_ScheduleJob
6952 ****************************************************************/
6954 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6955 struct spoolss_ScheduleJob *r)
6960 /****************************************************************
6962 ****************************************************************/
6964 WERROR _spoolss_SetJob(pipes_struct *p,
6965 struct spoolss_SetJob *r)
6967 POLICY_HND *handle = r->in.handle;
6968 uint32 jobid = r->in.job_id;
6969 uint32 command = r->in.command;
6972 WERROR errcode = WERR_BADFUNC;
6974 if (!get_printer_snum(p, handle, &snum, NULL)) {
6978 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6979 return WERR_INVALID_PRINTER_NAME;
6983 case SPOOLSS_JOB_CONTROL_CANCEL:
6984 case SPOOLSS_JOB_CONTROL_DELETE:
6985 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6989 case SPOOLSS_JOB_CONTROL_PAUSE:
6990 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6994 case SPOOLSS_JOB_CONTROL_RESTART:
6995 case SPOOLSS_JOB_CONTROL_RESUME:
6996 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
7001 return WERR_UNKNOWN_LEVEL;
7007 /****************************************************************************
7008 Enumerates all printer drivers at level 1.
7009 ****************************************************************************/
7011 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7016 fstring *list = NULL;
7017 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7018 DRIVER_INFO_1 *driver_info_1=NULL;
7019 WERROR result = WERR_OK;
7023 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7025 ndrivers=get_ntdrivers(&list, architecture, version);
7026 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7028 if(ndrivers == -1) {
7029 SAFE_FREE(driver_info_1);
7034 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
7035 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
7041 for (i=0; i<ndrivers; i++) {
7043 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7044 ZERO_STRUCT(driver);
7045 status = get_a_printer_driver(&driver, 3, list[i],
7046 architecture, version);
7047 if (!W_ERROR_IS_OK(status)) {
7049 SAFE_FREE(driver_info_1);
7052 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
7053 free_a_printer_driver(driver, 3);
7056 *returned+=ndrivers;
7060 /* check the required size. */
7061 for (i=0; i<*returned; i++) {
7062 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7063 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
7066 if (*needed > offered) {
7067 result = WERR_INSUFFICIENT_BUFFER;
7071 if (!rpcbuf_alloc_size(buffer, *needed)) {
7072 result = WERR_NOMEM;
7076 /* fill the buffer with the driver structures */
7077 for (i=0; i<*returned; i++) {
7078 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7079 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
7083 SAFE_FREE(driver_info_1);
7085 if ( !W_ERROR_IS_OK(result) )
7091 /****************************************************************************
7092 Enumerates all printer drivers at level 2.
7093 ****************************************************************************/
7095 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7100 fstring *list = NULL;
7101 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7102 DRIVER_INFO_2 *driver_info_2=NULL;
7103 WERROR result = WERR_OK;
7107 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7109 ndrivers=get_ntdrivers(&list, architecture, version);
7110 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7112 if(ndrivers == -1) {
7113 SAFE_FREE(driver_info_2);
7118 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7119 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7125 for (i=0; i<ndrivers; i++) {
7128 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7129 ZERO_STRUCT(driver);
7130 status = get_a_printer_driver(&driver, 3, list[i],
7131 architecture, version);
7132 if (!W_ERROR_IS_OK(status)) {
7134 SAFE_FREE(driver_info_2);
7137 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7138 free_a_printer_driver(driver, 3);
7141 *returned+=ndrivers;
7145 /* check the required size. */
7146 for (i=0; i<*returned; i++) {
7147 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7148 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7151 if (*needed > offered) {
7152 result = WERR_INSUFFICIENT_BUFFER;
7156 if (!rpcbuf_alloc_size(buffer, *needed)) {
7157 result = WERR_NOMEM;
7161 /* fill the buffer with the form structures */
7162 for (i=0; i<*returned; i++) {
7163 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7164 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7168 SAFE_FREE(driver_info_2);
7170 if ( !W_ERROR_IS_OK(result) )
7176 /****************************************************************************
7177 Enumerates all printer drivers at level 3.
7178 ****************************************************************************/
7180 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7185 fstring *list = NULL;
7186 DRIVER_INFO_3 *driver_info_3=NULL;
7187 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7188 WERROR result = WERR_OK;
7192 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7194 ndrivers=get_ntdrivers(&list, architecture, version);
7195 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7197 if(ndrivers == -1) {
7198 SAFE_FREE(driver_info_3);
7203 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7204 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7210 for (i=0; i<ndrivers; i++) {
7213 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7214 ZERO_STRUCT(driver);
7215 status = get_a_printer_driver(&driver, 3, list[i],
7216 architecture, version);
7217 if (!W_ERROR_IS_OK(status)) {
7219 SAFE_FREE(driver_info_3);
7222 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7223 free_a_printer_driver(driver, 3);
7226 *returned+=ndrivers;
7230 /* check the required size. */
7231 for (i=0; i<*returned; i++) {
7232 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7233 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7236 if (*needed > offered) {
7237 result = WERR_INSUFFICIENT_BUFFER;
7241 if (!rpcbuf_alloc_size(buffer, *needed)) {
7242 result = WERR_NOMEM;
7246 /* fill the buffer with the driver structures */
7247 for (i=0; i<*returned; i++) {
7248 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7249 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7253 for (i=0; i<*returned; i++) {
7254 SAFE_FREE(driver_info_3[i].dependentfiles);
7257 SAFE_FREE(driver_info_3);
7259 if ( !W_ERROR_IS_OK(result) )
7265 /****************************************************************************
7266 Enumerates all printer drivers.
7267 ****************************************************************************/
7269 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7271 uint32 level = q_u->level;
7272 RPC_BUFFER *buffer = NULL;
7273 uint32 offered = q_u->offered;
7274 uint32 *needed = &r_u->needed;
7275 uint32 *returned = &r_u->returned;
7276 const char *cservername;
7278 fstring architecture;
7280 /* that's an [in out] buffer */
7282 if (!q_u->buffer && (offered!=0)) {
7283 return WERR_INVALID_PARAM;
7286 rpcbuf_move(q_u->buffer, &r_u->buffer);
7287 buffer = r_u->buffer;
7289 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7294 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7295 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7297 cservername = canon_servername(servername);
7299 if (!is_myname_or_ipaddr(cservername))
7300 return WERR_UNKNOWN_PRINTER_DRIVER;
7304 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7306 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7308 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7310 return WERR_UNKNOWN_LEVEL;
7314 /****************************************************************************
7315 ****************************************************************************/
7317 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7319 form->flag=list->flag;
7320 init_unistr(&form->name, list->name);
7321 form->width=list->width;
7322 form->length=list->length;
7323 form->left=list->left;
7324 form->top=list->top;
7325 form->right=list->right;
7326 form->bottom=list->bottom;
7329 /****************************************************************************
7330 ****************************************************************************/
7332 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7333 struct spoolss_FormInfo1 *form,
7334 nt_forms_struct *list)
7336 form->form_name = talloc_strdup(mem_ctx, list->name);
7337 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7339 form->flags = list->flag;
7340 form->size.width = list->width;
7341 form->size.height = list->length;
7342 form->area.left = list->left;
7343 form->area.top = list->top;
7344 form->area.right = list->right;
7345 form->area.bottom = list->bottom;
7350 /****************************************************************************
7351 ****************************************************************************/
7353 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7355 uint32 level = q_u->level;
7356 RPC_BUFFER *buffer = NULL;
7357 uint32 offered = q_u->offered;
7358 uint32 *needed = &r_u->needed;
7359 uint32 *numofforms = &r_u->numofforms;
7360 uint32 numbuiltinforms;
7362 nt_forms_struct *list=NULL;
7363 nt_forms_struct *builtinlist=NULL;
7368 /* that's an [in out] buffer */
7370 if (!q_u->buffer && (offered!=0) ) {
7371 return WERR_INVALID_PARAM;
7374 rpcbuf_move(q_u->buffer, &r_u->buffer);
7375 buffer = r_u->buffer;
7377 DEBUG(4,("_spoolss_enumforms\n"));
7378 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7379 DEBUGADD(5,("Info level [%d]\n", level));
7381 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7382 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7383 *numofforms = get_ntforms(&list);
7384 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7385 *numofforms += numbuiltinforms;
7387 if (*numofforms == 0) {
7388 SAFE_FREE(builtinlist);
7390 return WERR_NO_MORE_ITEMS;
7395 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7396 SAFE_FREE(builtinlist);
7402 /* construct the list of form structures */
7403 for (i=0; i<numbuiltinforms; i++) {
7404 DEBUGADD(6,("Filling form number [%d]\n",i));
7405 fill_form_1(&forms_1[i], &builtinlist[i]);
7408 SAFE_FREE(builtinlist);
7410 for (; i<*numofforms; i++) {
7411 DEBUGADD(6,("Filling form number [%d]\n",i));
7412 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7417 /* check the required size. */
7418 for (i=0; i<numbuiltinforms; i++) {
7419 DEBUGADD(6,("adding form [%d]'s size\n",i));
7420 buffer_size += spoolss_size_form_1(&forms_1[i]);
7422 for (; i<*numofforms; i++) {
7423 DEBUGADD(6,("adding form [%d]'s size\n",i));
7424 buffer_size += spoolss_size_form_1(&forms_1[i]);
7427 *needed=buffer_size;
7429 if (*needed > offered) {
7432 return WERR_INSUFFICIENT_BUFFER;
7435 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7441 /* fill the buffer with the form structures */
7442 for (i=0; i<numbuiltinforms; i++) {
7443 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7444 smb_io_form_1("", buffer, &forms_1[i], 0);
7446 for (; i<*numofforms; i++) {
7447 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7448 smb_io_form_1("", buffer, &forms_1[i], 0);
7457 SAFE_FREE(builtinlist);
7458 return WERR_UNKNOWN_LEVEL;
7462 /****************************************************************
7464 ****************************************************************/
7466 WERROR _spoolss_GetForm(pipes_struct *p,
7467 struct spoolss_GetForm *r)
7469 uint32 level = r->in.level;
7470 uint32 offered = r->in.offered;
7471 uint32 *needed = r->out.needed;
7473 nt_forms_struct *list=NULL;
7474 nt_forms_struct builtin_form;
7476 union spoolss_FormInfo info;
7477 struct spoolss_FormInfo1 form_1;
7478 int numofforms=0, i=0;
7480 /* that's an [in out] buffer */
7482 if (!r->in.buffer && (offered!=0)) {
7483 return WERR_INVALID_PARAM;
7486 DEBUG(4,("_spoolss_GetForm\n"));
7487 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7488 DEBUGADD(5,("Info level [%d]\n", level));
7490 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7491 if (!foundBuiltin) {
7492 numofforms = get_ntforms(&list);
7493 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7495 if (numofforms == 0)
7502 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7505 /* Check if the requested name is in the list of form structures */
7506 for (i=0; i<numofforms; i++) {
7508 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7509 list[i].name, r->in.form_name));
7511 if (strequal(r->in.form_name, list[i].name)) {
7512 DEBUGADD(6,("Found form %s number [%d]\n",
7513 r->in.form_name, i));
7514 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7520 if (i == numofforms) {
7524 /* check the required size. */
7526 info.info1 = form_1;
7528 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7530 if (*needed > offered) {
7532 return WERR_INSUFFICIENT_BUFFER;
7535 r->out.info->info1 = form_1;
7537 /* fill the buffer with the form structures */
7538 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7539 r->in.form_name, i));
7545 return WERR_UNKNOWN_LEVEL;
7549 /****************************************************************************
7550 ****************************************************************************/
7552 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7554 init_unistr(&port->port_name, name);
7557 /****************************************************************************
7558 TODO: This probably needs distinguish between TCP/IP and Local ports
7560 ****************************************************************************/
7562 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7564 init_unistr(&port->port_name, name);
7565 init_unistr(&port->monitor_name, "Local Monitor");
7566 init_unistr(&port->description, SPL_LOCAL_PORT );
7567 port->port_type=PORT_TYPE_WRITE;
7572 /****************************************************************************
7573 wrapper around the enumer ports command
7574 ****************************************************************************/
7576 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7578 char *cmd = lp_enumports_cmd();
7579 char **qlines = NULL;
7580 char *command = NULL;
7588 /* if no hook then just fill in the default port */
7591 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7594 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7595 TALLOC_FREE(qlines);
7602 /* we have a valid enumport command */
7604 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7609 DEBUG(10,("Running [%s]\n", command));
7610 ret = smbrun(command, &fd);
7611 DEBUG(10,("Returned [%d]\n", ret));
7612 TALLOC_FREE(command);
7617 return WERR_ACCESS_DENIED;
7621 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7622 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7632 /****************************************************************************
7634 ****************************************************************************/
7636 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7638 PORT_INFO_1 *ports=NULL;
7640 WERROR result = WERR_OK;
7641 char **qlines = NULL;
7644 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7645 if (!W_ERROR_IS_OK(result)) {
7646 TALLOC_FREE(qlines);
7651 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7652 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7653 win_errstr(WERR_NOMEM)));
7654 TALLOC_FREE(qlines);
7658 for (i=0; i<numlines; i++) {
7659 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7660 fill_port_1(&ports[i], qlines[i]);
7663 TALLOC_FREE(qlines);
7665 *returned = numlines;
7667 /* check the required size. */
7668 for (i=0; i<*returned; i++) {
7669 DEBUGADD(6,("adding port [%d]'s size\n", i));
7670 *needed += spoolss_size_port_info_1(&ports[i]);
7673 if (*needed > offered) {
7674 result = WERR_INSUFFICIENT_BUFFER;
7678 if (!rpcbuf_alloc_size(buffer, *needed)) {
7679 result = WERR_NOMEM;
7683 /* fill the buffer with the ports structures */
7684 for (i=0; i<*returned; i++) {
7685 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7686 smb_io_port_1("", buffer, &ports[i], 0);
7692 if ( !W_ERROR_IS_OK(result) )
7698 /****************************************************************************
7700 ****************************************************************************/
7702 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7704 PORT_INFO_2 *ports=NULL;
7706 WERROR result = WERR_OK;
7707 char **qlines = NULL;
7710 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7711 if ( !W_ERROR_IS_OK(result)) {
7712 TALLOC_FREE(qlines);
7717 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7718 TALLOC_FREE(qlines);
7722 for (i=0; i<numlines; i++) {
7723 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7724 fill_port_2(&(ports[i]), qlines[i]);
7728 TALLOC_FREE(qlines);
7730 *returned = numlines;
7732 /* check the required size. */
7733 for (i=0; i<*returned; i++) {
7734 DEBUGADD(6,("adding port [%d]'s size\n", i));
7735 *needed += spoolss_size_port_info_2(&ports[i]);
7738 if (*needed > offered) {
7739 result = WERR_INSUFFICIENT_BUFFER;
7743 if (!rpcbuf_alloc_size(buffer, *needed)) {
7744 result = WERR_NOMEM;
7748 /* fill the buffer with the ports structures */
7749 for (i=0; i<*returned; i++) {
7750 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7751 smb_io_port_2("", buffer, &ports[i], 0);
7757 if ( !W_ERROR_IS_OK(result) )
7763 /****************************************************************************
7765 ****************************************************************************/
7767 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7769 uint32 level = q_u->level;
7770 RPC_BUFFER *buffer = NULL;
7771 uint32 offered = q_u->offered;
7772 uint32 *needed = &r_u->needed;
7773 uint32 *returned = &r_u->returned;
7775 /* that's an [in out] buffer */
7777 if (!q_u->buffer && (offered!=0)) {
7778 return WERR_INVALID_PARAM;
7781 rpcbuf_move(q_u->buffer, &r_u->buffer);
7782 buffer = r_u->buffer;
7784 DEBUG(4,("_spoolss_enumports\n"));
7791 return enumports_level_1(buffer, offered, needed, returned);
7793 return enumports_level_2(buffer, offered, needed, returned);
7795 return WERR_UNKNOWN_LEVEL;
7799 /****************************************************************************
7800 ****************************************************************************/
7802 static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name,
7803 const SPOOL_PRINTER_INFO_LEVEL *info,
7804 DEVICEMODE *devmode, SEC_DESC_BUF *sec_desc_buf,
7805 uint32 user_switch, const SPOOL_USER_CTR *user,
7808 NT_PRINTER_INFO_LEVEL *printer = NULL;
7811 WERROR err = WERR_OK;
7813 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7814 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7818 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7819 if (!convert_printer_info(info, printer, 2)) {
7820 free_a_printer(&printer, 2);
7824 /* check to see if the printer already exists */
7826 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7827 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7828 printer->info_2->sharename));
7829 free_a_printer(&printer, 2);
7830 return WERR_PRINTER_ALREADY_EXISTS;
7833 /* FIXME!!! smbd should check to see if the driver is installed before
7834 trying to add a printer like this --jerry */
7836 if (*lp_addprinter_cmd() ) {
7837 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7839 free_a_printer(&printer,2);
7840 return WERR_ACCESS_DENIED;
7843 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7844 "smb.conf parameter \"addprinter command\" is defined. This"
7845 "parameter must exist for this call to succeed\n",
7846 printer->info_2->sharename ));
7849 /* use our primary netbios name since get_a_printer() will convert
7850 it to what the client expects on a case by case basis */
7852 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7853 printer->info_2->sharename);
7856 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7857 free_a_printer(&printer,2);
7858 return WERR_ACCESS_DENIED;
7861 /* you must be a printer admin to add a new printer */
7862 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7863 free_a_printer(&printer,2);
7864 return WERR_ACCESS_DENIED;
7868 * Do sanity check on the requested changes for Samba.
7871 if (!check_printer_ok(printer->info_2, snum)) {
7872 free_a_printer(&printer,2);
7873 return WERR_INVALID_PARAM;
7877 * When a printer is created, the drivername bound to the printer is used
7878 * to lookup previously saved driver initialization info, which is then
7879 * bound to the new printer, simulating what happens in the Windows arch.
7884 set_driver_init(printer, 2);
7888 /* A valid devmode was included, convert and link it
7890 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7892 if (!convert_devicemode(printer->info_2->printername, devmode,
7893 &printer->info_2->devmode))
7897 /* write the ASCII on disk */
7898 err = mod_a_printer(printer, 2);
7899 if (!W_ERROR_IS_OK(err)) {
7900 free_a_printer(&printer,2);
7904 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7905 /* Handle open failed - remove addition. */
7906 del_a_printer(printer->info_2->sharename);
7907 free_a_printer(&printer,2);
7908 return WERR_ACCESS_DENIED;
7911 update_c_setprinter(False);
7912 free_a_printer(&printer,2);
7917 /****************************************************************************
7918 ****************************************************************************/
7920 WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u)
7922 UNISTR2 *uni_srv_name = q_u->server_name;
7923 uint32 level = q_u->level;
7924 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info;
7925 DEVICEMODE *devmode = q_u->devmode_ctr.devmode;
7926 SEC_DESC_BUF *sdb = q_u->secdesc_ctr;
7927 uint32 user_switch = q_u->user_switch;
7928 SPOOL_USER_CTR *user = &q_u->user_ctr;
7929 POLICY_HND *handle = &r_u->handle;
7933 /* we don't handle yet */
7934 /* but I know what to do ... */
7935 return WERR_UNKNOWN_LEVEL;
7937 return spoolss_addprinterex_level_2(p, uni_srv_name, info,
7939 user_switch, user, handle);
7941 return WERR_UNKNOWN_LEVEL;
7945 /****************************************************************************
7946 ****************************************************************************/
7948 WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u)
7950 uint32 level = q_u->level;
7951 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info;
7952 WERROR err = WERR_OK;
7953 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7954 fstring driver_name;
7957 ZERO_STRUCT(driver);
7959 if (!convert_printer_driver_info(info, &driver, level)) {
7964 DEBUG(5,("Cleaning driver's information\n"));
7965 err = clean_up_driver_struct(p, driver, level);
7966 if (!W_ERROR_IS_OK(err))
7969 DEBUG(5,("Moving driver to final destination\n"));
7970 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7975 if (add_a_printer_driver(driver, level)!=0) {
7976 err = WERR_ACCESS_DENIED;
7982 fstrcpy(driver_name,
7983 driver.info_3->name ? driver.info_3->name : "");
7986 fstrcpy(driver_name,
7987 driver.info_6->name ? driver.info_6->name : "");
7992 * I think this is where he DrvUpgradePrinter() hook would be
7993 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7994 * server. Right now, we just need to send ourselves a message
7995 * to update each printer bound to this driver. --jerry
7998 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7999 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n",
8004 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
8005 * decide if the driver init data should be deleted. The rules are:
8006 * 1) never delete init data if it is a 9x driver, they don't use it anyway
8007 * 2) delete init data only if there is no 2k/Xp driver
8008 * 3) always delete init data
8009 * The generalized rule is always use init data from the highest order driver.
8010 * It is necessary to follow the driver install by an initialization step to
8011 * finish off this process.
8014 version = driver.info_3->cversion;
8015 else if (level == 6)
8016 version = driver.info_6->version;
8021 * 9x printer driver - never delete init data
8024 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n",
8029 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
8030 * there is no 2k/Xp driver init data for this driver name.
8034 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
8036 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
8038 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
8040 if (!del_driver_init(driver_name))
8041 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name));
8044 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
8046 free_a_printer_driver(driver1,3);
8047 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n",
8054 * 2k or Xp printer driver - always delete init data
8057 if (!del_driver_init(driver_name))
8058 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name));
8062 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level));
8068 free_a_printer_driver(driver, level);
8072 /********************************************************************
8073 * spoolss_addprinterdriverex
8074 ********************************************************************/
8076 WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u)
8078 SPOOL_Q_ADDPRINTERDRIVER q_u_local;
8079 SPOOL_R_ADDPRINTERDRIVER r_u_local;
8082 * we only support the semantics of AddPrinterDriver()
8083 * i.e. only copy files that are newer than existing ones
8086 if ( q_u->copy_flags != APD_COPY_NEW_FILES )
8087 return WERR_ACCESS_DENIED;
8089 ZERO_STRUCT(q_u_local);
8090 ZERO_STRUCT(r_u_local);
8092 /* just pass the information off to _spoolss_addprinterdriver() */
8093 q_u_local.server_name_ptr = q_u->server_name_ptr;
8094 copy_unistr2(&q_u_local.server_name, &q_u->server_name);
8095 q_u_local.level = q_u->level;
8096 memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) );
8098 return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local );
8101 /****************************************************************************
8102 ****************************************************************************/
8104 static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name)
8106 init_unistr(&info->name, name);
8109 /****************************************************************************
8110 ****************************************************************************/
8112 static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
8115 char *long_archi = NULL;
8116 char *servername = NULL;
8117 const char *pservername = NULL;
8118 const char *short_archi;
8119 DRIVER_DIRECTORY_1 *info=NULL;
8120 WERROR result = WERR_OK;
8121 TALLOC_CTX *ctx = talloc_tos();
8123 servername = unistr2_to_ascii_talloc(ctx, name);
8127 long_archi = unistr2_to_ascii_talloc(ctx, uni_environment);
8132 pservername = canon_servername(servername);
8134 if ( !is_myname_or_ipaddr(pservername))
8135 return WERR_INVALID_PARAM;
8137 if (!(short_archi = get_short_archi(long_archi)))
8138 return WERR_INVALID_ENVIRONMENT;
8140 if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL)
8143 path = talloc_asprintf(ctx,
8144 "\\\\%s\\print$\\%s", pservername, short_archi);
8146 result = WERR_NOMEM;
8150 DEBUG(4,("printer driver directory: [%s]\n", path));
8152 fill_driverdir_1(info, path);
8154 *needed += spoolss_size_driverdir_info_1(info);
8156 if (*needed > offered) {
8157 result = WERR_INSUFFICIENT_BUFFER;
8161 if (!rpcbuf_alloc_size(buffer, *needed)) {
8162 result = WERR_NOMEM;
8166 smb_io_driverdir_1("", buffer, info, 0);
8174 /****************************************************************************
8175 ****************************************************************************/
8177 WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u)
8179 UNISTR2 *name = &q_u->name;
8180 UNISTR2 *uni_environment = &q_u->environment;
8181 uint32 level = q_u->level;
8182 RPC_BUFFER *buffer = NULL;
8183 uint32 offered = q_u->offered;
8184 uint32 *needed = &r_u->needed;
8186 /* that's an [in out] buffer */
8188 if (!q_u->buffer && (offered!=0)) {
8189 return WERR_INVALID_PARAM;
8192 rpcbuf_move(q_u->buffer, &r_u->buffer);
8193 buffer = r_u->buffer;
8195 DEBUG(4,("_spoolss_getprinterdriverdirectory\n"));
8201 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed);
8203 return WERR_UNKNOWN_LEVEL;
8207 /****************************************************************************
8208 ****************************************************************************/
8210 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8212 POLICY_HND *handle = &q_u->handle;
8213 uint32 idx = q_u->index;
8214 uint32 in_value_len = q_u->valuesize;
8215 uint32 in_data_len = q_u->datasize;
8216 uint32 *out_max_value_len = &r_u->valuesize;
8217 uint16 **out_value = &r_u->value;
8218 uint32 *out_value_len = &r_u->realvaluesize;
8219 uint32 *out_type = &r_u->type;
8220 uint32 *out_max_data_len = &r_u->datasize;
8221 uint8 **data_out = &r_u->data;
8222 uint32 *out_data_len = &r_u->realdatasize;
8224 NT_PRINTER_INFO_LEVEL *printer = NULL;
8226 uint32 biggest_valuesize;
8227 uint32 biggest_datasize;
8229 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8232 REGISTRY_VALUE *val = NULL;
8233 NT_PRINTER_DATA *p_data;
8234 int i, key_index, num_values;
8239 *out_max_data_len = 0;
8243 DEBUG(5,("spoolss_enumprinterdata\n"));
8246 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8250 if (!get_printer_snum(p,handle, &snum, NULL))
8253 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8254 if (!W_ERROR_IS_OK(result))
8257 p_data = printer->info_2->data;
8258 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8263 * The NT machine wants to know the biggest size of value and data
8265 * cf: MSDN EnumPrinterData remark section
8268 if ( !in_value_len && !in_data_len && (key_index != -1) )
8270 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8272 biggest_valuesize = 0;
8273 biggest_datasize = 0;
8275 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8277 for ( i=0; i<num_values; i++ )
8279 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8281 name_length = strlen(val->valuename);
8282 if ( strlen(val->valuename) > biggest_valuesize )
8283 biggest_valuesize = name_length;
8285 if ( val->size > biggest_datasize )
8286 biggest_datasize = val->size;
8288 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8292 /* the value is an UNICODE string but real_value_size is the length
8293 in bytes including the trailing 0 */
8295 *out_value_len = 2 * (1+biggest_valuesize);
8296 *out_data_len = biggest_datasize;
8298 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8304 * the value len is wrong in NT sp3
8305 * that's the number of bytes not the number of unicode chars
8308 if ( key_index != -1 )
8309 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8314 /* out_value should default to "" or else NT4 has
8315 problems unmarshalling the response */
8317 *out_max_value_len=(in_value_len/sizeof(uint16));
8320 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8322 result = WERR_NOMEM;
8325 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8331 /* the data is counted in bytes */
8333 *out_max_data_len = in_data_len;
8334 *out_data_len = in_data_len;
8336 /* only allocate when given a non-zero data_len */
8338 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8340 result = WERR_NOMEM;
8344 result = WERR_NO_MORE_ITEMS;
8350 * - counted in bytes in the request
8351 * - counted in UNICODE chars in the max reply
8352 * - counted in bytes in the real size
8354 * take a pause *before* coding not *during* coding
8358 *out_max_value_len=(in_value_len/sizeof(uint16));
8360 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8362 result = WERR_NOMEM;
8366 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8374 *out_type = regval_type( val );
8376 /* data - counted in bytes */
8378 *out_max_data_len = in_data_len;
8379 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8381 result = WERR_NOMEM;
8384 data_len = regval_size(val);
8385 if ( *data_out && data_len )
8386 memcpy( *data_out, regval_data_p(val), data_len );
8387 *out_data_len = data_len;
8391 free_a_printer(&printer, 2);
8395 /****************************************************************************
8396 ****************************************************************************/
8398 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8400 POLICY_HND *handle = &q_u->handle;
8401 UNISTR2 *value = &q_u->value;
8402 uint32 type = q_u->type;
8403 uint8 *data = q_u->data;
8404 uint32 real_len = q_u->real_len;
8406 NT_PRINTER_INFO_LEVEL *printer = NULL;
8408 WERROR status = WERR_OK;
8409 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8412 DEBUG(5,("spoolss_setprinterdata\n"));
8415 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8419 if ( Printer->printer_type == SPLHND_SERVER ) {
8420 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8421 return WERR_INVALID_PARAM;
8424 if (!get_printer_snum(p,handle, &snum, NULL))
8428 * Access check : NT returns "access denied" if you make a
8429 * SetPrinterData call without the necessary privildge.
8430 * we were originally returning OK if nothing changed
8431 * which made Win2k issue **a lot** of SetPrinterData
8432 * when connecting to a printer --jerry
8435 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8437 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8438 status = WERR_ACCESS_DENIED;
8442 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8443 if (!W_ERROR_IS_OK(status))
8446 unistr2_to_ascii(valuename, value, sizeof(valuename));
8449 * When client side code sets a magic printer data key, detect it and save
8450 * the current printer data and the magic key's data (its the DEVMODE) for
8451 * future printer/driver initializations.
8453 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8455 /* Set devmode and printer initialization info */
8456 status = save_driver_init( printer, 2, data, real_len );
8458 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8462 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8463 type, data, real_len );
8464 if ( W_ERROR_IS_OK(status) )
8465 status = mod_a_printer(printer, 2);
8469 free_a_printer(&printer, 2);
8474 /****************************************************************************
8475 ****************************************************************************/
8477 WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u)
8479 POLICY_HND *handle = &q_u->handle;
8480 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8483 DEBUG(5,("_spoolss_resetprinter\n"));
8486 * All we do is to check to see if the handle and queue is valid.
8487 * This call really doesn't mean anything to us because we only
8488 * support RAW printing. --jerry
8492 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8496 if (!get_printer_snum(p,handle, &snum, NULL))
8500 /* blindly return success */
8504 /****************************************************************
8505 _spoolss_DeletePrinterData
8506 ****************************************************************/
8508 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8509 struct spoolss_DeletePrinterData *r)
8511 POLICY_HND *handle = r->in.handle;
8512 NT_PRINTER_INFO_LEVEL *printer = NULL;
8514 WERROR status = WERR_OK;
8515 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8517 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8520 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8521 OUR_HANDLE(handle)));
8525 if (!get_printer_snum(p, handle, &snum, NULL))
8528 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8529 DEBUG(3, ("_spoolss_DeletePrinterData: "
8530 "printer properties change denied by handle\n"));
8531 return WERR_ACCESS_DENIED;
8534 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8535 if (!W_ERROR_IS_OK(status))
8538 if (!r->in.value_name) {
8539 free_a_printer(&printer, 2);
8543 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8546 if ( W_ERROR_IS_OK(status) )
8547 mod_a_printer( printer, 2 );
8549 free_a_printer(&printer, 2);
8554 /****************************************************************
8556 ****************************************************************/
8558 WERROR _spoolss_AddForm(pipes_struct *p,
8559 struct spoolss_AddForm *r)
8561 POLICY_HND *handle = r->in.handle;
8562 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8563 nt_forms_struct tmpForm;
8565 WERROR status = WERR_OK;
8566 NT_PRINTER_INFO_LEVEL *printer = NULL;
8569 nt_forms_struct *list=NULL;
8570 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8572 DEBUG(5,("_spoolss_AddForm\n"));
8575 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8576 OUR_HANDLE(handle)));
8581 /* forms can be added on printer of on the print server handle */
8583 if ( Printer->printer_type == SPLHND_PRINTER )
8585 if (!get_printer_snum(p,handle, &snum, NULL))
8588 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8589 if (!W_ERROR_IS_OK(status))
8593 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8594 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8595 status = WERR_ACCESS_DENIED;
8599 /* can't add if builtin */
8601 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8602 status = WERR_FILE_EXISTS;
8606 count = get_ntforms(&list);
8608 if(!add_a_form(&list, form, &count)) {
8609 status = WERR_NOMEM;
8613 write_ntforms(&list, count);
8616 * ChangeID must always be set if this is a printer
8619 if ( Printer->printer_type == SPLHND_PRINTER )
8620 status = mod_a_printer(printer, 2);
8624 free_a_printer(&printer, 2);
8630 /****************************************************************
8632 ****************************************************************/
8634 WERROR _spoolss_DeleteForm(pipes_struct *p,
8635 struct spoolss_DeleteForm *r)
8637 POLICY_HND *handle = r->in.handle;
8638 const char *form_name = r->in.form_name;
8639 nt_forms_struct tmpForm;
8641 nt_forms_struct *list=NULL;
8642 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8644 WERROR status = WERR_OK;
8645 NT_PRINTER_INFO_LEVEL *printer = NULL;
8647 DEBUG(5,("_spoolss_DeleteForm\n"));
8650 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8651 OUR_HANDLE(handle)));
8655 /* forms can be deleted on printer of on the print server handle */
8657 if ( Printer->printer_type == SPLHND_PRINTER )
8659 if (!get_printer_snum(p,handle, &snum, NULL))
8662 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8663 if (!W_ERROR_IS_OK(status))
8667 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8668 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8669 status = WERR_ACCESS_DENIED;
8673 /* can't delete if builtin */
8675 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8676 status = WERR_INVALID_PARAM;
8680 count = get_ntforms(&list);
8682 if ( !delete_a_form(&list, form_name, &count, &status ))
8686 * ChangeID must always be set if this is a printer
8689 if ( Printer->printer_type == SPLHND_PRINTER )
8690 status = mod_a_printer(printer, 2);
8694 free_a_printer(&printer, 2);
8700 /****************************************************************
8702 ****************************************************************/
8704 WERROR _spoolss_SetForm(pipes_struct *p,
8705 struct spoolss_SetForm *r)
8707 POLICY_HND *handle = r->in.handle;
8708 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8709 nt_forms_struct tmpForm;
8711 WERROR status = WERR_OK;
8712 NT_PRINTER_INFO_LEVEL *printer = NULL;
8715 nt_forms_struct *list=NULL;
8716 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8718 DEBUG(5,("_spoolss_SetForm\n"));
8721 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8722 OUR_HANDLE(handle)));
8726 /* forms can be modified on printer of on the print server handle */
8728 if ( Printer->printer_type == SPLHND_PRINTER )
8730 if (!get_printer_snum(p,handle, &snum, NULL))
8733 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8734 if (!W_ERROR_IS_OK(status))
8738 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8739 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8740 status = WERR_ACCESS_DENIED;
8744 /* can't set if builtin */
8745 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8746 status = WERR_INVALID_PARAM;
8750 count = get_ntforms(&list);
8751 update_a_form(&list, form, count);
8752 write_ntforms(&list, count);
8755 * ChangeID must always be set if this is a printer
8758 if ( Printer->printer_type == SPLHND_PRINTER )
8759 status = mod_a_printer(printer, 2);
8764 free_a_printer(&printer, 2);
8770 /****************************************************************************
8771 enumprintprocessors level 1.
8772 ****************************************************************************/
8774 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8776 PRINTPROCESSOR_1 *info_1=NULL;
8777 WERROR result = WERR_OK;
8779 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8784 init_unistr(&info_1->name, "winprint");
8786 *needed += spoolss_size_printprocessor_info_1(info_1);
8788 if (*needed > offered) {
8789 result = WERR_INSUFFICIENT_BUFFER;
8793 if (!rpcbuf_alloc_size(buffer, *needed)) {
8794 result = WERR_NOMEM;
8798 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8803 if ( !W_ERROR_IS_OK(result) )
8809 /****************************************************************************
8810 ****************************************************************************/
8812 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8814 uint32 level = q_u->level;
8815 RPC_BUFFER *buffer = NULL;
8816 uint32 offered = q_u->offered;
8817 uint32 *needed = &r_u->needed;
8818 uint32 *returned = &r_u->returned;
8820 /* that's an [in out] buffer */
8822 if (!q_u->buffer && (offered!=0)) {
8823 return WERR_INVALID_PARAM;
8826 rpcbuf_move(q_u->buffer, &r_u->buffer);
8827 buffer = r_u->buffer;
8829 DEBUG(5,("spoolss_enumprintprocessors\n"));
8832 * Enumerate the print processors ...
8834 * Just reply with "winprint", to keep NT happy
8835 * and I can use my nice printer checker.
8843 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8845 return WERR_UNKNOWN_LEVEL;
8849 /****************************************************************************
8850 enumprintprocdatatypes level 1.
8851 ****************************************************************************/
8853 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8855 PRINTPROCDATATYPE_1 *info_1=NULL;
8856 WERROR result = WERR_OK;
8858 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8863 init_unistr(&info_1->name, "RAW");
8865 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8867 if (*needed > offered) {
8868 result = WERR_INSUFFICIENT_BUFFER;
8872 if (!rpcbuf_alloc_size(buffer, *needed)) {
8873 result = WERR_NOMEM;
8877 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8882 if ( !W_ERROR_IS_OK(result) )
8888 /****************************************************************************
8889 ****************************************************************************/
8891 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8893 uint32 level = q_u->level;
8894 RPC_BUFFER *buffer = NULL;
8895 uint32 offered = q_u->offered;
8896 uint32 *needed = &r_u->needed;
8897 uint32 *returned = &r_u->returned;
8899 /* that's an [in out] buffer */
8901 if (!q_u->buffer && (offered!=0)) {
8902 return WERR_INVALID_PARAM;
8905 rpcbuf_move(q_u->buffer, &r_u->buffer);
8906 buffer = r_u->buffer;
8908 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8915 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8917 return WERR_UNKNOWN_LEVEL;
8921 /****************************************************************************
8922 enumprintmonitors level 1.
8923 ****************************************************************************/
8925 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8927 PRINTMONITOR_1 *info_1;
8928 WERROR result = WERR_OK;
8931 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8936 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8937 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8939 for ( i=0; i<*returned; i++ ) {
8940 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8943 if (*needed > offered) {
8944 result = WERR_INSUFFICIENT_BUFFER;
8948 if (!rpcbuf_alloc_size(buffer, *needed)) {
8949 result = WERR_NOMEM;
8953 for ( i=0; i<*returned; i++ ) {
8954 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8960 if ( !W_ERROR_IS_OK(result) )
8966 /****************************************************************************
8967 enumprintmonitors level 2.
8968 ****************************************************************************/
8970 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8972 PRINTMONITOR_2 *info_2;
8973 WERROR result = WERR_OK;
8976 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8981 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8982 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8983 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8985 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8986 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8987 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8989 for ( i=0; i<*returned; i++ ) {
8990 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8993 if (*needed > offered) {
8994 result = WERR_INSUFFICIENT_BUFFER;
8998 if (!rpcbuf_alloc_size(buffer, *needed)) {
8999 result = WERR_NOMEM;
9003 for ( i=0; i<*returned; i++ ) {
9004 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
9010 if ( !W_ERROR_IS_OK(result) )
9016 /****************************************************************************
9017 ****************************************************************************/
9019 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
9021 uint32 level = q_u->level;
9022 RPC_BUFFER *buffer = NULL;
9023 uint32 offered = q_u->offered;
9024 uint32 *needed = &r_u->needed;
9025 uint32 *returned = &r_u->returned;
9027 /* that's an [in out] buffer */
9029 if (!q_u->buffer && (offered!=0)) {
9030 return WERR_INVALID_PARAM;
9033 rpcbuf_move(q_u->buffer, &r_u->buffer);
9034 buffer = r_u->buffer;
9036 DEBUG(5,("spoolss_enumprintmonitors\n"));
9039 * Enumerate the print monitors ...
9041 * Just reply with "Local Port", to keep NT happy
9042 * and I can use my nice printer checker.
9050 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9052 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9054 return WERR_UNKNOWN_LEVEL;
9058 /****************************************************************************
9059 ****************************************************************************/
9061 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9062 NT_PRINTER_INFO_LEVEL *ntprinter,
9063 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9068 JOB_INFO_1 *info_1=NULL;
9069 WERROR result = WERR_OK;
9071 info_1=SMB_MALLOC_P(JOB_INFO_1);
9073 if (info_1 == NULL) {
9077 for (i=0; i<count && found==False; i++) {
9078 if ((*queue)[i].job==(int)jobid)
9084 /* NT treats not found as bad param... yet another bad choice */
9085 return WERR_INVALID_PARAM;
9088 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9090 *needed += spoolss_size_job_info_1(info_1);
9092 if (*needed > offered) {
9093 result = WERR_INSUFFICIENT_BUFFER;
9097 if (!rpcbuf_alloc_size(buffer, *needed)) {
9098 result = WERR_NOMEM;
9102 smb_io_job_info_1("", buffer, info_1, 0);
9110 /****************************************************************************
9111 ****************************************************************************/
9113 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9114 NT_PRINTER_INFO_LEVEL *ntprinter,
9115 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9122 DEVICEMODE *devmode = NULL;
9123 NT_DEVICEMODE *nt_devmode = NULL;
9125 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9128 ZERO_STRUCTP(info_2);
9130 for ( i=0; i<count && found==False; i++ )
9132 if ((*queue)[i].job == (int)jobid)
9137 /* NT treats not found as bad param... yet another bad
9139 result = WERR_INVALID_PARAM;
9144 * if the print job does not have a DEVMODE associated with it,
9145 * just use the one for the printer. A NULL devicemode is not
9146 * a failure condition
9149 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9150 devmode = construct_dev_mode(lp_const_servicename(snum));
9152 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9153 ZERO_STRUCTP( devmode );
9154 convert_nt_devicemode( devmode, nt_devmode );
9158 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9160 *needed += spoolss_size_job_info_2(info_2);
9162 if (*needed > offered) {
9163 result = WERR_INSUFFICIENT_BUFFER;
9167 if (!rpcbuf_alloc_size(buffer, *needed)) {
9168 result = WERR_NOMEM;
9172 smb_io_job_info_2("", buffer, info_2, 0);
9177 /* Cleanup allocated memory */
9179 free_job_info_2(info_2); /* Also frees devmode */
9185 /****************************************************************************
9186 ****************************************************************************/
9188 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9190 POLICY_HND *handle = &q_u->handle;
9191 uint32 jobid = q_u->jobid;
9192 uint32 level = q_u->level;
9193 RPC_BUFFER *buffer = NULL;
9194 uint32 offered = q_u->offered;
9195 uint32 *needed = &r_u->needed;
9196 WERROR wstatus = WERR_OK;
9197 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9200 print_queue_struct *queue = NULL;
9201 print_status_struct prt_status;
9203 /* that's an [in out] buffer */
9205 if (!q_u->buffer && (offered!=0)) {
9206 return WERR_INVALID_PARAM;
9209 rpcbuf_move(q_u->buffer, &r_u->buffer);
9210 buffer = r_u->buffer;
9212 DEBUG(5,("spoolss_getjob\n"));
9216 if (!get_printer_snum(p, handle, &snum, NULL))
9219 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9220 if ( !W_ERROR_IS_OK(wstatus) )
9223 count = print_queue_status(snum, &queue, &prt_status);
9225 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9226 count, prt_status.status, prt_status.message));
9230 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9231 buffer, offered, needed);
9234 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9235 buffer, offered, needed);
9238 wstatus = WERR_UNKNOWN_LEVEL;
9243 free_a_printer( &ntprinter, 2 );
9248 /********************************************************************
9249 spoolss_getprinterdataex
9251 From MSDN documentation of GetPrinterDataEx: pass request
9252 to GetPrinterData if key is "PrinterDriverData".
9253 ********************************************************************/
9255 WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u)
9257 POLICY_HND *handle = &q_u->handle;
9258 uint32 in_size = q_u->size;
9259 uint32 *type = &r_u->type;
9260 uint32 *out_size = &r_u->size;
9261 uint8 **data = &r_u->data;
9262 uint32 *needed = &r_u->needed;
9263 fstring keyname, valuename;
9265 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9267 NT_PRINTER_INFO_LEVEL *printer = NULL;
9269 WERROR status = WERR_OK;
9271 DEBUG(4,("_spoolss_getprinterdataex\n"));
9273 unistr2_to_ascii(keyname, &q_u->keyname, sizeof(keyname));
9274 unistr2_to_ascii(valuename, &q_u->valuename, sizeof(valuename));
9276 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n",
9277 keyname, valuename));
9279 /* in case of problem, return some default values */
9283 *out_size = in_size;
9286 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9287 status = WERR_BADFID;
9291 /* Is the handle to a printer or to the server? */
9293 if (Printer->printer_type == SPLHND_SERVER) {
9294 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n"));
9295 status = WERR_INVALID_PARAM;
9299 if ( !get_printer_snum(p,handle, &snum, NULL) )
9302 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9303 if ( !W_ERROR_IS_OK(status) )
9306 /* check to see if the keyname is valid */
9307 if ( !strlen(keyname) ) {
9308 status = WERR_INVALID_PARAM;
9312 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9313 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname ));
9314 free_a_printer( &printer, 2 );
9315 status = WERR_BADFILE;
9319 /* When given a new keyname, we should just create it */
9321 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, type, data, needed, in_size );
9323 if (*needed > *out_size)
9324 status = WERR_MORE_DATA;
9327 if ( !W_ERROR_IS_OK(status) )
9329 DEBUG(5, ("error: allocating %d\n", *out_size));
9331 /* reply this param doesn't exist */
9335 if( (*data=(uint8 *)TALLOC_ZERO(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) {
9336 status = WERR_NOMEM;
9345 free_a_printer( &printer, 2 );
9350 /********************************************************************
9351 * spoolss_setprinterdataex
9352 ********************************************************************/
9354 WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u)
9356 POLICY_HND *handle = &q_u->handle;
9357 uint32 type = q_u->type;
9358 uint8 *data = q_u->data;
9359 uint32 real_len = q_u->real_len;
9361 NT_PRINTER_INFO_LEVEL *printer = NULL;
9363 WERROR status = WERR_OK;
9364 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9369 DEBUG(4,("_spoolss_setprinterdataex\n"));
9371 /* From MSDN documentation of SetPrinterDataEx: pass request to
9372 SetPrinterData if key is "PrinterDriverData" */
9375 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9379 if ( Printer->printer_type == SPLHND_SERVER ) {
9380 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n"));
9381 return WERR_INVALID_PARAM;
9384 if ( !get_printer_snum(p,handle, &snum, NULL) )
9388 * Access check : NT returns "access denied" if you make a
9389 * SetPrinterData call without the necessary privildge.
9390 * we were originally returning OK if nothing changed
9391 * which made Win2k issue **a lot** of SetPrinterData
9392 * when connecting to a printer --jerry
9395 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9397 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n"));
9398 return WERR_ACCESS_DENIED;
9401 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9402 if (!W_ERROR_IS_OK(status))
9405 unistr2_to_ascii( valuename, &q_u->value, sizeof(valuename));
9406 unistr2_to_ascii( keyname, &q_u->key, sizeof(keyname));
9408 /* check for OID in valuename */
9410 if ( (oid_string = strchr( valuename, ',' )) != NULL )
9416 /* save the registry data */
9418 status = set_printer_dataex( printer, keyname, valuename, type, data, real_len );
9420 if ( W_ERROR_IS_OK(status) )
9422 /* save the OID if one was specified */
9424 fstrcat( keyname, "\\" );
9425 fstrcat( keyname, SPOOL_OID_KEY );
9428 * I'm not checking the status here on purpose. Don't know
9429 * if this is right, but I'm returning the status from the
9430 * previous set_printer_dataex() call. I have no idea if
9431 * this is right. --jerry
9434 set_printer_dataex( printer, keyname, valuename,
9435 REG_SZ, (uint8 *)oid_string,
9436 strlen(oid_string)+1 );
9439 status = mod_a_printer(printer, 2);
9442 free_a_printer(&printer, 2);
9447 /****************************************************************
9448 _spoolss_DeletePrinterDataEx
9449 ****************************************************************/
9451 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9452 struct spoolss_DeletePrinterDataEx *r)
9454 POLICY_HND *handle = r->in.handle;
9455 NT_PRINTER_INFO_LEVEL *printer = NULL;
9457 WERROR status = WERR_OK;
9458 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9460 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9463 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9464 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9468 if (!get_printer_snum(p, handle, &snum, NULL))
9471 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9472 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9473 "printer properties change denied by handle\n"));
9474 return WERR_ACCESS_DENIED;
9477 if (!r->in.value_name || !r->in.key_name) {
9481 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9482 if (!W_ERROR_IS_OK(status))
9485 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9487 if ( W_ERROR_IS_OK(status) )
9488 mod_a_printer( printer, 2 );
9490 free_a_printer(&printer, 2);
9495 /********************************************************************
9496 * spoolss_enumprinterkey
9497 ********************************************************************/
9500 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9503 fstring *keynames = NULL;
9504 uint16 *enumkeys = NULL;
9507 POLICY_HND *handle = &q_u->handle;
9508 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9509 NT_PRINTER_DATA *data;
9510 NT_PRINTER_INFO_LEVEL *printer = NULL;
9512 WERROR status = WERR_BADFILE;
9515 DEBUG(4,("_spoolss_enumprinterkey\n"));
9518 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9522 if ( !get_printer_snum(p,handle, &snum, NULL) )
9525 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9526 if (!W_ERROR_IS_OK(status))
9529 /* get the list of subkey names */
9531 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9532 data = printer->info_2->data;
9534 num_keys = get_printer_subkeys( data, key, &keynames );
9536 if ( num_keys == -1 ) {
9537 status = WERR_BADFILE;
9541 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9543 r_u->needed = printerkey_len*2;
9545 if ( q_u->size < r_u->needed ) {
9546 status = WERR_MORE_DATA;
9550 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9551 status = WERR_NOMEM;
9557 if ( q_u->size < r_u->needed )
9558 status = WERR_MORE_DATA;
9561 free_a_printer( &printer, 2 );
9562 SAFE_FREE( keynames );
9567 /****************************************************************
9568 _spoolss_DeletePrinterKey
9569 ****************************************************************/
9571 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9572 struct spoolss_DeletePrinterKey *r)
9574 POLICY_HND *handle = r->in.handle;
9575 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9576 NT_PRINTER_INFO_LEVEL *printer = NULL;
9580 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9583 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9584 OUR_HANDLE(handle)));
9588 /* if keyname == NULL, return error */
9590 if ( !r->in.key_name )
9591 return WERR_INVALID_PARAM;
9593 if (!get_printer_snum(p, handle, &snum, NULL))
9596 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9597 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9598 "printer properties change denied by handle\n"));
9599 return WERR_ACCESS_DENIED;
9602 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9603 if (!W_ERROR_IS_OK(status))
9606 /* delete the key and all subneys */
9608 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9610 if ( W_ERROR_IS_OK(status) )
9611 status = mod_a_printer(printer, 2);
9613 free_a_printer( &printer, 2 );
9619 /********************************************************************
9620 * spoolss_enumprinterdataex
9621 ********************************************************************/
9623 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9625 POLICY_HND *handle = &q_u->handle;
9626 uint32 in_size = q_u->size;
9629 NT_PRINTER_INFO_LEVEL *printer = NULL;
9630 PRINTER_ENUM_VALUES *enum_values = NULL;
9631 NT_PRINTER_DATA *p_data;
9633 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9638 REGISTRY_VALUE *val;
9643 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9646 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9651 * first check for a keyname of NULL or "". Win2k seems to send
9652 * this a lot and we should send back WERR_INVALID_PARAM
9653 * no need to spend time looking up the printer in this case.
9657 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9658 if ( !strlen(key) ) {
9659 result = WERR_INVALID_PARAM;
9663 /* get the printer off of disk */
9665 if (!get_printer_snum(p,handle, &snum, NULL))
9668 ZERO_STRUCT(printer);
9669 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9670 if (!W_ERROR_IS_OK(result))
9673 /* now look for a match on the key name */
9675 p_data = printer->info_2->data;
9677 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9678 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9680 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9681 result = WERR_INVALID_PARAM;
9688 /* allocate the memory for the array of pointers -- if necessary */
9690 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9693 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9695 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9696 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9697 result = WERR_NOMEM;
9701 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9705 * loop through all params and build the array to pass
9706 * back to the client
9709 for ( i=0; i<num_entries; i++ )
9711 /* lookup the registry value */
9713 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9714 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9718 value_name = regval_name( val );
9719 init_unistr( &enum_values[i].valuename, value_name );
9720 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9721 enum_values[i].type = regval_type( val );
9723 data_len = regval_size( val );
9725 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9727 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9729 result = WERR_NOMEM;
9733 enum_values[i].data_len = data_len;
9735 /* keep track of the size of the array in bytes */
9737 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9740 /* housekeeping information in the reply */
9742 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9743 * the hand marshalled container size is a multiple
9744 * of 4 bytes for RPC alignment.
9748 needed += 4-(needed % 4);
9751 r_u->needed = needed;
9752 r_u->returned = num_entries;
9754 if (needed > in_size) {
9755 result = WERR_MORE_DATA;
9759 /* copy data into the reply */
9761 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9762 response buffer size is != the offered buffer size
9764 r_u->ctr.size = r_u->needed;
9766 r_u->ctr.size = in_size;
9768 r_u->ctr.size_of_array = r_u->returned;
9769 r_u->ctr.values = enum_values;
9773 free_a_printer(&printer, 2);
9778 /****************************************************************************
9779 ****************************************************************************/
9781 static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, const char *name)
9783 init_unistr(&info->name, name);
9786 static WERROR getprintprocessordirectory_level_1(UNISTR2 *name,
9787 UNISTR2 *environment,
9792 char *long_archi = NULL;
9793 PRINTPROCESSOR_DIRECTORY_1 *info=NULL;
9794 WERROR result = WERR_OK;
9795 TALLOC_CTX *ctx = talloc_tos();
9797 long_archi = unistr2_to_ascii_talloc(ctx, environment);
9802 if (!get_short_archi(long_archi))
9803 return WERR_INVALID_ENVIRONMENT;
9805 if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL)
9808 fill_printprocessordirectory_1(info, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9810 *needed += spoolss_size_printprocessordirectory_info_1(info);
9812 if (*needed > offered) {
9813 result = WERR_INSUFFICIENT_BUFFER;
9817 if (!rpcbuf_alloc_size(buffer, *needed)) {
9818 result = WERR_INSUFFICIENT_BUFFER;
9822 smb_io_printprocessordirectory_1("", buffer, info, 0);
9830 WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u)
9832 uint32 level = q_u->level;
9833 RPC_BUFFER *buffer = NULL;
9834 uint32 offered = q_u->offered;
9835 uint32 *needed = &r_u->needed;
9838 /* that's an [in out] buffer */
9840 if (!q_u->buffer && (offered!=0)) {
9841 return WERR_INVALID_PARAM;
9844 rpcbuf_move(q_u->buffer, &r_u->buffer);
9845 buffer = r_u->buffer;
9847 DEBUG(5,("_spoolss_getprintprocessordirectory\n"));
9853 result = getprintprocessordirectory_level_1
9854 (&q_u->name, &q_u->environment, buffer, offered, needed);
9857 result = WERR_UNKNOWN_LEVEL;
9863 /*******************************************************************
9864 Streams the monitor UI DLL name in UNICODE
9865 *******************************************************************/
9867 static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
9868 RPC_BUFFER *out, uint32 *needed )
9870 const char *dllname = "tcpmonui.dll";
9872 *needed = (strlen(dllname)+1) * 2;
9874 if ( rpcbuf_get_size(out) < *needed ) {
9875 return WERR_INSUFFICIENT_BUFFER;
9878 if ( !make_monitorui_buf( out, dllname ) ) {
9885 /*******************************************************************
9886 Create a new TCP/IP port
9887 *******************************************************************/
9889 static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in,
9890 RPC_BUFFER *out, uint32 *needed )
9892 NT_PORT_DATA_1 port1;
9893 TALLOC_CTX *ctx = talloc_tos();
9894 char *device_uri = NULL;
9896 ZERO_STRUCT( port1 );
9898 /* convert to our internal port data structure */
9900 if ( !convert_port_data_1( &port1, in ) ) {
9904 /* create the device URI and call the add_port_hook() */
9906 switch ( port1.protocol ) {
9907 case PORT_PROTOCOL_DIRECT:
9908 device_uri = talloc_asprintf(ctx,
9909 "socket://%s:%d/", port1.hostaddr, port1.port );
9912 case PORT_PROTOCOL_LPR:
9913 device_uri = talloc_asprintf(ctx,
9914 "lpr://%s/%s", port1.hostaddr, port1.queue );
9918 return WERR_UNKNOWN_PORT;
9925 return add_port_hook(ctx, token, port1.name, device_uri );
9928 /*******************************************************************
9929 *******************************************************************/
9931 struct xcv_api_table xcvtcp_cmds[] = {
9932 { "MonitorUI", xcvtcp_monitorui },
9933 { "AddPort", xcvtcp_addport},
9937 static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command,
9938 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
9943 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9945 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9946 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9947 return xcvtcp_cmds[i].fn( token, inbuf, outbuf, needed );
9950 return WERR_BADFUNC;
9953 /*******************************************************************
9954 *******************************************************************/
9955 #if 0 /* don't support management using the "Local Port" monitor */
9957 static WERROR xcvlocal_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in,
9958 RPC_BUFFER *out, uint32 *needed )
9960 const char *dllname = "localui.dll";
9962 *needed = (strlen(dllname)+1) * 2;
9964 if ( rpcbuf_get_size(out) < *needed ) {
9965 return WERR_INSUFFICIENT_BUFFER;
9968 if ( !make_monitorui_buf( out, dllname )) {
9975 /*******************************************************************
9976 *******************************************************************/
9978 struct xcv_api_table xcvlocal_cmds[] = {
9979 { "MonitorUI", xcvlocal_monitorui },
9983 struct xcv_api_table xcvlocal_cmds[] = {
9990 /*******************************************************************
9991 *******************************************************************/
9993 static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command,
9994 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf,
9999 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10001 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10002 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10003 return xcvlocal_cmds[i].fn( token, inbuf, outbuf , needed );
10005 return WERR_BADFUNC;
10008 /*******************************************************************
10009 *******************************************************************/
10011 WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u)
10013 Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle);
10017 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle)));
10018 return WERR_BADFID;
10021 /* Has to be a handle to the TCP/IP port monitor */
10023 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10024 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n"));
10025 return WERR_BADFID;
10028 /* requires administrative access to the server */
10030 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10031 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n"));
10032 return WERR_ACCESS_DENIED;
10035 /* Get the command name. There's numerous commands supported by the
10036 TCPMON interface. */
10038 rpcstr_pull(command, q_u->dataname.buffer, sizeof(command),
10039 q_u->dataname.uni_str_len*2, 0);
10041 /* Allocate the outgoing buffer */
10043 if (!rpcbuf_init( &r_u->outdata, q_u->offered, p->mem_ctx ))
10046 switch ( Printer->printer_type ) {
10047 case SPLHND_PORTMON_TCP:
10048 return process_xcvtcp_command( p->server_info->ptok, command,
10049 &q_u->indata, &r_u->outdata, &r_u->needed );
10050 case SPLHND_PORTMON_LOCAL:
10051 return process_xcvlocal_command( p->server_info->ptok, command,
10052 &q_u->indata, &r_u->outdata, &r_u->needed );
10055 return WERR_INVALID_PRINT_MONITOR;
10058 /****************************************************************
10059 _spoolss_AddPrintProcessor
10060 ****************************************************************/
10062 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10063 struct spoolss_AddPrintProcessor *r)
10065 /* for now, just indicate success and ignore the add. We'll
10066 automatically set the winprint processor for printer
10067 entries later. Used to debug the LexMark Optra S 1855 PCL
10073 /****************************************************************
10074 _spoolss_EnumPrinters
10075 ****************************************************************/
10077 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10078 struct spoolss_EnumPrinters *r)
10080 p->rng_fault_state = true;
10081 return WERR_NOT_SUPPORTED;
10084 /****************************************************************
10085 _spoolss_OpenPrinter
10086 ****************************************************************/
10088 WERROR _spoolss_OpenPrinter(pipes_struct *p,
10089 struct spoolss_OpenPrinter *r)
10091 p->rng_fault_state = true;
10092 return WERR_NOT_SUPPORTED;
10095 /****************************************************************
10097 ****************************************************************/
10099 WERROR _spoolss_GetJob(pipes_struct *p,
10100 struct spoolss_GetJob *r)
10102 p->rng_fault_state = true;
10103 return WERR_NOT_SUPPORTED;
10106 /****************************************************************
10108 ****************************************************************/
10110 WERROR _spoolss_EnumJobs(pipes_struct *p,
10111 struct spoolss_EnumJobs *r)
10113 p->rng_fault_state = true;
10114 return WERR_NOT_SUPPORTED;
10117 /****************************************************************
10118 _spoolss_AddPrinter
10119 ****************************************************************/
10121 WERROR _spoolss_AddPrinter(pipes_struct *p,
10122 struct spoolss_AddPrinter *r)
10124 p->rng_fault_state = true;
10125 return WERR_NOT_SUPPORTED;
10128 /****************************************************************
10129 _spoolss_SetPrinter
10130 ****************************************************************/
10132 WERROR _spoolss_SetPrinter(pipes_struct *p,
10133 struct spoolss_SetPrinter *r)
10135 p->rng_fault_state = true;
10136 return WERR_NOT_SUPPORTED;
10139 /****************************************************************
10140 _spoolss_GetPrinter
10141 ****************************************************************/
10143 WERROR _spoolss_GetPrinter(pipes_struct *p,
10144 struct spoolss_GetPrinter *r)
10146 p->rng_fault_state = true;
10147 return WERR_NOT_SUPPORTED;
10150 /****************************************************************
10151 _spoolss_AddPrinterDriver
10152 ****************************************************************/
10154 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
10155 struct spoolss_AddPrinterDriver *r)
10157 p->rng_fault_state = true;
10158 return WERR_NOT_SUPPORTED;
10161 /****************************************************************
10162 _spoolss_EnumPrinterDrivers
10163 ****************************************************************/
10165 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10166 struct spoolss_EnumPrinterDrivers *r)
10168 p->rng_fault_state = true;
10169 return WERR_NOT_SUPPORTED;
10172 /****************************************************************
10173 _spoolss_GetPrinterDriver
10174 ****************************************************************/
10176 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10177 struct spoolss_GetPrinterDriver *r)
10179 p->rng_fault_state = true;
10180 return WERR_NOT_SUPPORTED;
10183 /****************************************************************
10184 _spoolss_GetPrinterDriverDirectory
10185 ****************************************************************/
10187 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
10188 struct spoolss_GetPrinterDriverDirectory *r)
10190 p->rng_fault_state = true;
10191 return WERR_NOT_SUPPORTED;
10194 /****************************************************************
10195 _spoolss_EnumPrintProcessors
10196 ****************************************************************/
10198 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10199 struct spoolss_EnumPrintProcessors *r)
10201 p->rng_fault_state = true;
10202 return WERR_NOT_SUPPORTED;
10205 /****************************************************************
10206 _spoolss_GetPrintProcessorDirectory
10207 ****************************************************************/
10209 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
10210 struct spoolss_GetPrintProcessorDirectory *r)
10212 p->rng_fault_state = true;
10213 return WERR_NOT_SUPPORTED;
10216 /****************************************************************
10217 _spoolss_ReadPrinter
10218 ****************************************************************/
10220 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10221 struct spoolss_ReadPrinter *r)
10223 p->rng_fault_state = true;
10224 return WERR_NOT_SUPPORTED;
10227 /****************************************************************
10228 _spoolss_GetPrinterData
10229 ****************************************************************/
10231 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10232 struct spoolss_GetPrinterData *r)
10234 p->rng_fault_state = true;
10235 return WERR_NOT_SUPPORTED;
10238 /****************************************************************
10239 _spoolss_SetPrinterData
10240 ****************************************************************/
10242 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10243 struct spoolss_SetPrinterData *r)
10245 p->rng_fault_state = true;
10246 return WERR_NOT_SUPPORTED;
10249 /****************************************************************
10250 _spoolss_WaitForPrinterChange
10251 ****************************************************************/
10253 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10254 struct spoolss_WaitForPrinterChange *r)
10256 p->rng_fault_state = true;
10257 return WERR_NOT_SUPPORTED;
10260 /****************************************************************
10262 ****************************************************************/
10264 WERROR _spoolss_EnumForms(pipes_struct *p,
10265 struct spoolss_EnumForms *r)
10267 p->rng_fault_state = true;
10268 return WERR_NOT_SUPPORTED;
10271 /****************************************************************
10273 ****************************************************************/
10275 WERROR _spoolss_EnumPorts(pipes_struct *p,
10276 struct spoolss_EnumPorts *r)
10278 p->rng_fault_state = true;
10279 return WERR_NOT_SUPPORTED;
10282 /****************************************************************
10283 _spoolss_EnumMonitors
10284 ****************************************************************/
10286 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10287 struct spoolss_EnumMonitors *r)
10289 p->rng_fault_state = true;
10290 return WERR_NOT_SUPPORTED;
10293 /****************************************************************
10295 ****************************************************************/
10297 WERROR _spoolss_AddPort(pipes_struct *p,
10298 struct spoolss_AddPort *r)
10300 p->rng_fault_state = true;
10301 return WERR_NOT_SUPPORTED;
10304 /****************************************************************
10305 _spoolss_ConfigurePort
10306 ****************************************************************/
10308 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10309 struct spoolss_ConfigurePort *r)
10311 p->rng_fault_state = true;
10312 return WERR_NOT_SUPPORTED;
10315 /****************************************************************
10316 _spoolss_DeletePort
10317 ****************************************************************/
10319 WERROR _spoolss_DeletePort(pipes_struct *p,
10320 struct spoolss_DeletePort *r)
10322 p->rng_fault_state = true;
10323 return WERR_NOT_SUPPORTED;
10326 /****************************************************************
10327 _spoolss_CreatePrinterIC
10328 ****************************************************************/
10330 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10331 struct spoolss_CreatePrinterIC *r)
10333 p->rng_fault_state = true;
10334 return WERR_NOT_SUPPORTED;
10337 /****************************************************************
10338 _spoolss_PlayGDIScriptOnPrinterIC
10339 ****************************************************************/
10341 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10342 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10344 p->rng_fault_state = true;
10345 return WERR_NOT_SUPPORTED;
10348 /****************************************************************
10349 _spoolss_DeletePrinterIC
10350 ****************************************************************/
10352 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10353 struct spoolss_DeletePrinterIC *r)
10355 p->rng_fault_state = true;
10356 return WERR_NOT_SUPPORTED;
10359 /****************************************************************
10360 _spoolss_AddPrinterConnection
10361 ****************************************************************/
10363 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10364 struct spoolss_AddPrinterConnection *r)
10366 p->rng_fault_state = true;
10367 return WERR_NOT_SUPPORTED;
10370 /****************************************************************
10371 _spoolss_DeletePrinterConnection
10372 ****************************************************************/
10374 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10375 struct spoolss_DeletePrinterConnection *r)
10377 p->rng_fault_state = true;
10378 return WERR_NOT_SUPPORTED;
10381 /****************************************************************
10382 _spoolss_PrinterMessageBox
10383 ****************************************************************/
10385 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10386 struct spoolss_PrinterMessageBox *r)
10388 p->rng_fault_state = true;
10389 return WERR_NOT_SUPPORTED;
10392 /****************************************************************
10393 _spoolss_AddMonitor
10394 ****************************************************************/
10396 WERROR _spoolss_AddMonitor(pipes_struct *p,
10397 struct spoolss_AddMonitor *r)
10399 p->rng_fault_state = true;
10400 return WERR_NOT_SUPPORTED;
10403 /****************************************************************
10404 _spoolss_DeleteMonitor
10405 ****************************************************************/
10407 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10408 struct spoolss_DeleteMonitor *r)
10410 p->rng_fault_state = true;
10411 return WERR_NOT_SUPPORTED;
10414 /****************************************************************
10415 _spoolss_DeletePrintProcessor
10416 ****************************************************************/
10418 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10419 struct spoolss_DeletePrintProcessor *r)
10421 p->rng_fault_state = true;
10422 return WERR_NOT_SUPPORTED;
10425 /****************************************************************
10426 _spoolss_AddPrintProvidor
10427 ****************************************************************/
10429 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10430 struct spoolss_AddPrintProvidor *r)
10432 p->rng_fault_state = true;
10433 return WERR_NOT_SUPPORTED;
10436 /****************************************************************
10437 _spoolss_DeletePrintProvidor
10438 ****************************************************************/
10440 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10441 struct spoolss_DeletePrintProvidor *r)
10443 p->rng_fault_state = true;
10444 return WERR_NOT_SUPPORTED;
10447 /****************************************************************
10448 _spoolss_EnumPrintProcDataTypes
10449 ****************************************************************/
10451 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10452 struct spoolss_EnumPrintProcDataTypes *r)
10454 p->rng_fault_state = true;
10455 return WERR_NOT_SUPPORTED;
10458 /****************************************************************
10459 _spoolss_ResetPrinter
10460 ****************************************************************/
10462 WERROR _spoolss_ResetPrinter(pipes_struct *p,
10463 struct spoolss_ResetPrinter *r)
10465 p->rng_fault_state = true;
10466 return WERR_NOT_SUPPORTED;
10469 /****************************************************************
10470 _spoolss_GetPrinterDriver2
10471 ****************************************************************/
10473 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10474 struct spoolss_GetPrinterDriver2 *r)
10476 p->rng_fault_state = true;
10477 return WERR_NOT_SUPPORTED;
10480 /****************************************************************
10481 _spoolss_FindFirstPrinterChangeNotification
10482 ****************************************************************/
10484 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10485 struct spoolss_FindFirstPrinterChangeNotification *r)
10487 p->rng_fault_state = true;
10488 return WERR_NOT_SUPPORTED;
10491 /****************************************************************
10492 _spoolss_FindNextPrinterChangeNotification
10493 ****************************************************************/
10495 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10496 struct spoolss_FindNextPrinterChangeNotification *r)
10498 p->rng_fault_state = true;
10499 return WERR_NOT_SUPPORTED;
10502 /****************************************************************
10503 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10504 ****************************************************************/
10506 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10507 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10509 p->rng_fault_state = true;
10510 return WERR_NOT_SUPPORTED;
10513 /****************************************************************
10514 _spoolss_ReplyOpenPrinter
10515 ****************************************************************/
10517 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10518 struct spoolss_ReplyOpenPrinter *r)
10520 p->rng_fault_state = true;
10521 return WERR_NOT_SUPPORTED;
10524 /****************************************************************
10525 _spoolss_RouterReplyPrinter
10526 ****************************************************************/
10528 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10529 struct spoolss_RouterReplyPrinter *r)
10531 p->rng_fault_state = true;
10532 return WERR_NOT_SUPPORTED;
10535 /****************************************************************
10536 _spoolss_ReplyClosePrinter
10537 ****************************************************************/
10539 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10540 struct spoolss_ReplyClosePrinter *r)
10542 p->rng_fault_state = true;
10543 return WERR_NOT_SUPPORTED;
10546 /****************************************************************
10548 ****************************************************************/
10550 WERROR _spoolss_AddPortEx(pipes_struct *p,
10551 struct spoolss_AddPortEx *r)
10553 p->rng_fault_state = true;
10554 return WERR_NOT_SUPPORTED;
10557 /****************************************************************
10558 _spoolss_RouterFindFirstPrinterChangeNotification
10559 ****************************************************************/
10561 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10562 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10564 p->rng_fault_state = true;
10565 return WERR_NOT_SUPPORTED;
10568 /****************************************************************
10569 _spoolss_SpoolerInit
10570 ****************************************************************/
10572 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10573 struct spoolss_SpoolerInit *r)
10575 p->rng_fault_state = true;
10576 return WERR_NOT_SUPPORTED;
10579 /****************************************************************
10580 _spoolss_ResetPrinterEx
10581 ****************************************************************/
10583 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10584 struct spoolss_ResetPrinterEx *r)
10586 p->rng_fault_state = true;
10587 return WERR_NOT_SUPPORTED;
10590 /****************************************************************
10591 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10592 ****************************************************************/
10594 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10595 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10597 p->rng_fault_state = true;
10598 return WERR_NOT_SUPPORTED;
10601 /****************************************************************
10602 _spoolss_RouterRefreshPrinterChangeNotification
10603 ****************************************************************/
10605 WERROR _spoolss_RouterRefreshPrinterChangeNotification(pipes_struct *p,
10606 struct spoolss_RouterRefreshPrinterChangeNotification *r)
10608 p->rng_fault_state = true;
10609 return WERR_NOT_SUPPORTED;
10612 /****************************************************************
10613 _spoolss_RemoteFindNextPrinterChangeNotifyEx
10614 ****************************************************************/
10616 WERROR _spoolss_RemoteFindNextPrinterChangeNotifyEx(pipes_struct *p,
10617 struct spoolss_RemoteFindNextPrinterChangeNotifyEx *r)
10619 p->rng_fault_state = true;
10620 return WERR_NOT_SUPPORTED;
10623 /****************************************************************
10625 ****************************************************************/
10627 WERROR _spoolss_44(pipes_struct *p,
10628 struct spoolss_44 *r)
10630 p->rng_fault_state = true;
10631 return WERR_NOT_SUPPORTED;
10634 /****************************************************************
10635 _spoolss_OpenPrinterEx
10636 ****************************************************************/
10638 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
10639 struct spoolss_OpenPrinterEx *r)
10641 p->rng_fault_state = true;
10642 return WERR_NOT_SUPPORTED;
10645 /****************************************************************
10646 _spoolss_AddPrinterEx
10647 ****************************************************************/
10649 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
10650 struct spoolss_AddPrinterEx *r)
10652 p->rng_fault_state = true;
10653 return WERR_NOT_SUPPORTED;
10656 /****************************************************************
10658 ****************************************************************/
10660 WERROR _spoolss_47(pipes_struct *p,
10661 struct spoolss_47 *r)
10663 p->rng_fault_state = true;
10664 return WERR_NOT_SUPPORTED;
10667 /****************************************************************
10668 _spoolss_EnumPrinterData
10669 ****************************************************************/
10671 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10672 struct spoolss_EnumPrinterData *r)
10674 p->rng_fault_state = true;
10675 return WERR_NOT_SUPPORTED;
10678 /****************************************************************
10680 ****************************************************************/
10682 WERROR _spoolss_4a(pipes_struct *p,
10683 struct spoolss_4a *r)
10685 p->rng_fault_state = true;
10686 return WERR_NOT_SUPPORTED;
10689 /****************************************************************
10691 ****************************************************************/
10693 WERROR _spoolss_4b(pipes_struct *p,
10694 struct spoolss_4b *r)
10696 p->rng_fault_state = true;
10697 return WERR_NOT_SUPPORTED;
10700 /****************************************************************
10702 ****************************************************************/
10704 WERROR _spoolss_4c(pipes_struct *p,
10705 struct spoolss_4c *r)
10707 p->rng_fault_state = true;
10708 return WERR_NOT_SUPPORTED;
10711 /****************************************************************
10712 _spoolss_SetPrinterDataEx
10713 ****************************************************************/
10715 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
10716 struct spoolss_SetPrinterDataEx *r)
10718 p->rng_fault_state = true;
10719 return WERR_NOT_SUPPORTED;
10722 /****************************************************************
10723 _spoolss_GetPrinterDataEx
10724 ****************************************************************/
10726 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
10727 struct spoolss_GetPrinterDataEx *r)
10729 p->rng_fault_state = true;
10730 return WERR_NOT_SUPPORTED;
10733 /****************************************************************
10734 _spoolss_EnumPrinterDataEx
10735 ****************************************************************/
10737 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10738 struct spoolss_EnumPrinterDataEx *r)
10740 p->rng_fault_state = true;
10741 return WERR_NOT_SUPPORTED;
10744 /****************************************************************
10745 _spoolss_EnumPrinterKey
10746 ****************************************************************/
10748 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10749 struct spoolss_EnumPrinterKey *r)
10751 p->rng_fault_state = true;
10752 return WERR_NOT_SUPPORTED;
10755 /****************************************************************
10757 ****************************************************************/
10759 WERROR _spoolss_53(pipes_struct *p,
10760 struct spoolss_53 *r)
10762 p->rng_fault_state = true;
10763 return WERR_NOT_SUPPORTED;
10766 /****************************************************************
10768 ****************************************************************/
10770 WERROR _spoolss_55(pipes_struct *p,
10771 struct spoolss_55 *r)
10773 p->rng_fault_state = true;
10774 return WERR_NOT_SUPPORTED;
10777 /****************************************************************
10779 ****************************************************************/
10781 WERROR _spoolss_56(pipes_struct *p,
10782 struct spoolss_56 *r)
10784 p->rng_fault_state = true;
10785 return WERR_NOT_SUPPORTED;
10788 /****************************************************************
10790 ****************************************************************/
10792 WERROR _spoolss_57(pipes_struct *p,
10793 struct spoolss_57 *r)
10795 p->rng_fault_state = true;
10796 return WERR_NOT_SUPPORTED;
10799 /****************************************************************
10801 ****************************************************************/
10803 WERROR _spoolss_XcvData(pipes_struct *p,
10804 struct spoolss_XcvData *r)
10806 p->rng_fault_state = true;
10807 return WERR_NOT_SUPPORTED;
10810 /****************************************************************
10811 _spoolss_AddPrinterDriverEx
10812 ****************************************************************/
10814 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
10815 struct spoolss_AddPrinterDriverEx *r)
10817 p->rng_fault_state = true;
10818 return WERR_NOT_SUPPORTED;
10821 /****************************************************************
10823 ****************************************************************/
10825 WERROR _spoolss_5a(pipes_struct *p,
10826 struct spoolss_5a *r)
10828 p->rng_fault_state = true;
10829 return WERR_NOT_SUPPORTED;
10832 /****************************************************************
10834 ****************************************************************/
10836 WERROR _spoolss_5b(pipes_struct *p,
10837 struct spoolss_5b *r)
10839 p->rng_fault_state = true;
10840 return WERR_NOT_SUPPORTED;
10843 /****************************************************************
10845 ****************************************************************/
10847 WERROR _spoolss_5c(pipes_struct *p,
10848 struct spoolss_5c *r)
10850 p->rng_fault_state = true;
10851 return WERR_NOT_SUPPORTED;
10854 /****************************************************************
10856 ****************************************************************/
10858 WERROR _spoolss_5d(pipes_struct *p,
10859 struct spoolss_5d *r)
10861 p->rng_fault_state = true;
10862 return WERR_NOT_SUPPORTED;
10865 /****************************************************************
10867 ****************************************************************/
10869 WERROR _spoolss_5e(pipes_struct *p,
10870 struct spoolss_5e *r)
10872 p->rng_fault_state = true;
10873 return WERR_NOT_SUPPORTED;
10876 /****************************************************************
10878 ****************************************************************/
10880 WERROR _spoolss_5f(pipes_struct *p,
10881 struct spoolss_5f *r)
10883 p->rng_fault_state = true;
10884 return WERR_NOT_SUPPORTED;