2 * Unix SMB/CIFS implementation.
3 * RPC Pipe client / server routines
4 * Copyright (C) Andrew Tridgell 1992-2000,
5 * Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
6 * Copyright (C) Jean François Micouleau 1998-2000,
7 * Copyright (C) Jeremy Allison 2001-2002,
8 * Copyright (C) Gerald Carter 2000-2004,
9 * Copyright (C) Tim Potter 2001-2002.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 3 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, see <http://www.gnu.org/licenses/>.
25 /* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped
26 up, all the errors returned are DOS errors, not NT status codes. */
30 extern userdom_struct current_user_info;
33 #define DBGC_CLASS DBGC_RPC_SRV
35 #ifndef MAX_OPEN_PRINTER_EXS
36 #define MAX_OPEN_PRINTER_EXS 50
39 #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad
40 #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_"
43 const char *long_archi;
44 const char *short_archi;
48 static Printer_entry *printers_list;
50 typedef struct _counter_printer_0 {
51 struct _counter_printer_0 *next;
52 struct _counter_printer_0 *prev;
58 static counter_printer_0 *counter_list;
60 static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/
61 static uint32 smb_connections=0;
64 /* in printing/nt_printing.c */
66 extern struct standard_mapping printer_std_mapping, printserver_std_mapping;
68 /* API table for Xcv Monitor functions */
70 struct xcv_api_table {
72 WERROR(*fn) (TALLOC_CTX *mem_ctx, NT_USER_TOKEN *token, DATA_BLOB *in, DATA_BLOB *out, uint32_t *needed);
75 /********************************************************************
76 * Canonicalize servername.
77 ********************************************************************/
79 static const char *canon_servername(const char *servername)
81 const char *pservername = servername;
82 while (*pservername == '\\') {
88 /* translate between internal status numbers and NT status numbers */
89 static int nt_printj_status(int v)
95 return JOB_STATUS_PAUSED;
97 return JOB_STATUS_SPOOLING;
99 return JOB_STATUS_PRINTING;
101 return JOB_STATUS_ERROR;
103 return JOB_STATUS_DELETING;
105 return JOB_STATUS_OFFLINE;
107 return JOB_STATUS_PAPEROUT;
109 return JOB_STATUS_PRINTED;
111 return JOB_STATUS_DELETED;
113 return JOB_STATUS_BLOCKED;
114 case LPQ_USER_INTERVENTION:
115 return JOB_STATUS_USER_INTERVENTION;
120 static int nt_printq_status(int v)
124 return PRINTER_STATUS_PAUSED;
133 /****************************************************************************
134 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
135 ****************************************************************************/
137 static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp)
142 SAFE_FREE((*pp)->ctr.type);
146 /***************************************************************************
147 Disconnect from the client
148 ****************************************************************************/
150 static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle)
156 * Tell the specific printing tdb we no longer want messages for this printer
157 * by deregistering our PID.
160 if (!print_notify_deregister_pid(snum))
161 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) ));
163 /* weird if the test succeds !!! */
164 if (smb_connections==0) {
165 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
169 status = rpccli_spoolss_ReplyClosePrinter(notify_cli_pipe, talloc_tos(),
172 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
173 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n",
174 win_errstr(result)));
176 /* if it's the last connection, deconnect the IPC$ share */
177 if (smb_connections==1) {
179 cli_shutdown( rpc_pipe_np_smb_conn(notify_cli_pipe) );
180 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */
182 messaging_deregister(smbd_messaging_context(),
183 MSG_PRINTER_NOTIFY2, NULL);
185 /* Tell the connections db we're no longer interested in
186 * printer notify messages. */
188 register_message_flags( False, FLAG_MSG_PRINT_NOTIFY );
194 /****************************************************************************
195 Functions to free a printer entry datastruct.
196 ****************************************************************************/
198 static int printer_entry_destructor(Printer_entry *Printer)
200 if (Printer->notify.client_connected==True) {
203 if ( Printer->printer_type == SPLHND_SERVER) {
205 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
206 } else if (Printer->printer_type == SPLHND_PRINTER) {
207 snum = print_queue_snum(Printer->sharename);
209 srv_spoolss_replycloseprinter(snum,
210 &Printer->notify.client_hnd);
214 Printer->notify.flags=0;
215 Printer->notify.options=0;
216 Printer->notify.localmachine[0]='\0';
217 Printer->notify.printerlocal=0;
218 free_spool_notify_option(&Printer->notify.option);
219 Printer->notify.option=NULL;
220 Printer->notify.client_connected=False;
222 free_nt_devicemode( &Printer->nt_devmode );
223 free_a_printer( &Printer->printer_info, 2 );
225 /* Remove from the internal list. */
226 DLIST_REMOVE(printers_list, Printer);
230 /****************************************************************************
231 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry.
232 ****************************************************************************/
234 static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp)
236 SPOOL_NOTIFY_OPTION *new_sp = NULL;
241 new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION);
248 new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count);
250 if (!new_sp->ctr.type) {
259 /****************************************************************************
260 find printer index by handle
261 ****************************************************************************/
263 static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd)
265 Printer_entry *find_printer = NULL;
267 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) {
268 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: "));
275 /****************************************************************************
276 Close printer index by handle.
277 ****************************************************************************/
279 static bool close_printer_handle(pipes_struct *p, POLICY_HND *hnd)
281 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
284 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
288 close_policy_hnd(p, hnd);
293 /****************************************************************************
294 Delete a printer given a handle.
295 ****************************************************************************/
297 WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sharename )
299 char *cmd = lp_deleteprinter_cmd();
300 char *command = NULL;
302 SE_PRIV se_printop = SE_PRINT_OPERATOR;
303 bool is_print_op = False;
305 /* can't fail if we don't try */
310 command = talloc_asprintf(ctx,
317 is_print_op = user_has_privileges( token, &se_printop );
319 DEBUG(10,("Running [%s]\n", command));
321 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/
326 if ( (ret = smbrun(command, NULL)) == 0 ) {
327 /* Tell everyone we updated smb.conf. */
328 message_send_all(smbd_messaging_context(),
329 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
335 /********** END SePrintOperatorPrivlege BLOCK **********/
337 DEBUGADD(10,("returned [%d]\n", ret));
339 TALLOC_FREE(command);
342 return WERR_BADFID; /* What to return here? */
344 /* go ahead and re-read the services immediately */
345 reload_services( False );
347 if ( lp_servicenumber( sharename ) < 0 )
348 return WERR_ACCESS_DENIED;
353 /****************************************************************************
354 Delete a printer given a handle.
355 ****************************************************************************/
357 static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd)
359 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
362 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
367 * It turns out that Windows allows delete printer on a handle
368 * opened by an admin user, then used on a pipe handle created
369 * by an anonymous user..... but they're working on security.... riiight !
373 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
374 DEBUG(3, ("delete_printer_handle: denied by handle\n"));
375 return WERR_ACCESS_DENIED;
378 /* this does not need a become root since the access check has been
379 done on the handle already */
381 if (del_a_printer( Printer->sharename ) != 0) {
382 DEBUG(3,("Error deleting printer %s\n", Printer->sharename));
386 return delete_printer_hook(p->mem_ctx, p->server_info->ptok,
387 Printer->sharename );
390 /****************************************************************************
391 Return the snum of a printer corresponding to an handle.
392 ****************************************************************************/
394 static bool get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number,
395 struct share_params **params)
397 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd);
400 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd)));
404 switch (Printer->printer_type) {
406 DEBUG(4,("short name:%s\n", Printer->sharename));
407 *number = print_queue_snum(Printer->sharename);
408 return (*number != -1);
416 /****************************************************************************
417 Set printer handle type.
418 Check if it's \\server or \\server\printer
419 ****************************************************************************/
421 static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename)
423 DEBUG(3,("Setting printer type=%s\n", handlename));
425 if ( strlen(handlename) < 3 ) {
426 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename));
430 /* it's a print server */
431 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) {
432 DEBUGADD(4,("Printer is a print server\n"));
433 Printer->printer_type = SPLHND_SERVER;
435 /* it's a printer (set_printer_hnd_name() will handle port monitors */
437 DEBUGADD(4,("Printer is a printer\n"));
438 Printer->printer_type = SPLHND_PRINTER;
444 /****************************************************************************
445 Set printer handle name.. Accept names like \\server, \\server\printer,
446 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See
447 the MSDN docs regarding OpenPrinter() for details on the XcvData() and
448 XcvDataPort() interface.
449 ****************************************************************************/
451 static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename)
454 int n_services=lp_numservices();
455 char *aprinter, *printername;
456 const char *servername;
459 NT_PRINTER_INFO_LEVEL *printer = NULL;
462 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename)));
464 aprinter = handlename;
465 if ( *handlename == '\\' ) {
466 servername = canon_servername(handlename);
467 if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) {
475 /* save the servername to fill in replies on this handle */
477 if ( !is_myname_or_ipaddr( servername ) )
480 fstrcpy( Printer->servername, servername );
482 if ( Printer->printer_type == SPLHND_SERVER )
485 if ( Printer->printer_type != SPLHND_PRINTER )
488 DEBUGADD(5, ("searching for [%s]\n", aprinter ));
490 /* check for the Port Monitor Interface */
492 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) {
493 Printer->printer_type = SPLHND_PORTMON_TCP;
494 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON);
497 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) {
498 Printer->printer_type = SPLHND_PORTMON_LOCAL;
499 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON);
503 /* Search all sharenames first as this is easier than pulling
504 the printer_info_2 off of disk. Don't use find_service() since
505 that calls out to map_username() */
507 /* do another loop to look for printernames */
509 for (snum=0; !found && snum<n_services; snum++) {
511 /* no point going on if this is not a printer */
513 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) )
516 fstrcpy(sname, lp_servicename(snum));
517 if ( strequal( aprinter, sname ) ) {
522 /* no point looking up the printer object if
523 we aren't allowing printername != sharename */
525 if ( lp_force_printername(snum) )
528 fstrcpy(sname, lp_servicename(snum));
532 /* This call doesn't fill in the location or comment from
533 * a CUPS server for efficiency with large numbers of printers.
537 result = get_a_printer_search( NULL, &printer, 2, sname );
538 if ( !W_ERROR_IS_OK(result) ) {
539 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n",
540 sname, win_errstr(result)));
544 /* printername is always returned as \\server\printername */
545 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) {
546 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n",
547 printer->info_2->printername));
548 free_a_printer( &printer, 2);
554 if ( strequal(printername, aprinter) ) {
555 free_a_printer( &printer, 2);
560 DEBUGADD(10, ("printername: %s\n", printername));
562 free_a_printer( &printer, 2);
565 free_a_printer( &printer, 2);
568 DEBUGADD(4,("Printer not found\n"));
572 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname));
574 fstrcpy(Printer->sharename, sname);
579 /****************************************************************************
580 Find first available printer slot. creates a printer handle for you.
581 ****************************************************************************/
583 static bool open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted)
585 Printer_entry *new_printer;
587 DEBUG(10,("open_printer_hnd: name [%s]\n", name));
589 new_printer = TALLOC_ZERO_P(NULL, Printer_entry);
590 if (new_printer == NULL) {
593 talloc_set_destructor(new_printer, printer_entry_destructor);
595 if (!create_policy_hnd(p, hnd, new_printer)) {
596 TALLOC_FREE(new_printer);
600 /* Add to the internal list. */
601 DLIST_ADD(printers_list, new_printer);
603 new_printer->notify.option=NULL;
605 if (!set_printer_hnd_printertype(new_printer, name)) {
606 close_printer_handle(p, hnd);
610 if (!set_printer_hnd_name(new_printer, name)) {
611 close_printer_handle(p, hnd);
615 new_printer->access_granted = access_granted;
617 DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count ));
622 /***************************************************************************
623 check to see if the client motify handle is monitoring the notification
624 given by (notify_type, notify_field).
625 **************************************************************************/
627 static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type,
633 static bool is_monitoring_event(Printer_entry *p, uint16 notify_type,
636 SPOOL_NOTIFY_OPTION *option = p->notify.option;
640 * Flags should always be zero when the change notify
641 * is registered by the client's spooler. A user Win32 app
642 * might use the flags though instead of the NOTIFY_OPTION_INFO
651 return is_monitoring_event_flags(
652 p->notify.flags, notify_type, notify_field);
654 for (i = 0; i < option->count; i++) {
656 /* Check match for notify_type */
658 if (option->ctr.type[i].type != notify_type)
661 /* Check match for field */
663 for (j = 0; j < option->ctr.type[i].count; j++) {
664 if (option->ctr.type[i].fields[j] == notify_field) {
670 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n",
671 p->servername, p->sharename, notify_type, notify_field));
676 #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \
677 _data->data.integer[0] = _integer; \
678 _data->data.integer[1] = 0;
681 #define SETUP_SPOOLSS_NOTIFY_DATA_STRING(_data, _p) \
682 _data->data.string.string = talloc_strdup(mem_ctx, _p); \
683 if (!_data->data.string.string) {\
684 _data->data.string.size = 0; \
686 _data->data.string.size = strlen_m_term(_p) * 2;
688 #define SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(_data, _devmode) \
689 _data->data.devmode.devmode = _devmode;
691 #define SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(_data, _size, _sd) \
692 _data->data.sd.sd = dup_sec_desc(mem_ctx, _sd); \
693 if (!_data->data.sd.sd) { \
694 _data->data.sd.sd_size = 0; \
696 _data->data.sd.sd_size = _size;
698 static void init_systemtime_buffer(TALLOC_CTX *mem_ctx,
703 struct spoolss_Time st;
707 if (!init_systemtime(&st, t)) {
711 p = talloc_array(mem_ctx, char, len);
717 * Systemtime must be linearized as a set of UINT16's.
718 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au
721 SSVAL(p, 0, st.year);
722 SSVAL(p, 2, st.month);
723 SSVAL(p, 4, st.day_of_week);
725 SSVAL(p, 8, st.hour);
726 SSVAL(p, 10, st.minute);
727 SSVAL(p, 12, st.second);
728 SSVAL(p, 14, st.millisecond);
734 /* Convert a notification message to a struct spoolss_Notify */
736 static void notify_one_value(struct spoolss_notify_msg *msg,
737 struct spoolss_Notify *data,
740 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, msg->notify.value[0]);
743 static void notify_string(struct spoolss_notify_msg *msg,
744 struct spoolss_Notify *data,
747 /* The length of the message includes the trailing \0 */
749 data->data.string.size = msg->len * 2;
750 data->data.string.string = talloc_strdup(mem_ctx, msg->notify.data);
751 if (!data->data.string.string) {
752 data->data.string.size = 0;
757 static void notify_system_time(struct spoolss_notify_msg *msg,
758 struct spoolss_Notify *data,
761 data->data.string.string = NULL;
762 data->data.string.size = 0;
764 if (msg->len != sizeof(time_t)) {
765 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n",
770 init_systemtime_buffer(mem_ctx, gmtime((time_t *)msg->notify.data),
771 &data->data.string.string,
772 &data->data.string.size);
775 struct notify2_message_table {
777 void (*fn)(struct spoolss_notify_msg *msg,
778 struct spoolss_Notify *data, TALLOC_CTX *mem_ctx);
781 static struct notify2_message_table printer_notify_table[] = {
782 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string },
783 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string },
784 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string },
785 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string },
786 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string },
787 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string },
788 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string },
789 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL },
790 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string },
791 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string },
792 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL },
793 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string },
794 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL },
795 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value },
796 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value },
797 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL },
798 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL },
799 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL },
800 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value },
803 static struct notify2_message_table job_notify_table[] = {
804 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL },
805 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL },
806 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL },
807 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string },
808 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL },
809 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL },
810 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL },
811 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL },
812 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL },
813 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL },
814 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value },
815 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL },
816 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL },
817 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string },
818 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL },
819 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL },
820 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time },
821 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL },
822 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL },
823 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL },
824 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value },
825 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL },
826 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value },
827 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL },
831 /***********************************************************************
832 Allocate talloc context for container object
833 **********************************************************************/
835 static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr )
840 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr);
845 /***********************************************************************
846 release all allocated memory and zero out structure
847 **********************************************************************/
849 static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr )
855 talloc_destroy(ctr->ctx);
862 /***********************************************************************
863 **********************************************************************/
865 static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr )
873 /***********************************************************************
874 **********************************************************************/
876 static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
878 if ( !ctr || !ctr->msg_groups )
881 if ( idx >= ctr->num_groups )
884 return &ctr->msg_groups[idx];
888 /***********************************************************************
889 How many groups of change messages do we have ?
890 **********************************************************************/
892 static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr )
897 return ctr->num_groups;
900 /***********************************************************************
901 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group
902 **********************************************************************/
904 static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg )
906 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL;
907 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL;
908 SPOOLSS_NOTIFY_MSG *msg_list = NULL;
914 /* loop over all groups looking for a matching printer name */
916 for ( i=0; i<ctr->num_groups; i++ ) {
917 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 )
921 /* add a new group? */
923 if ( i == ctr->num_groups ) {
926 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) {
927 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n"));
930 ctr->msg_groups = groups;
932 /* clear the new entry and set the printer name */
934 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] );
935 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer );
938 /* add the change messages; 'i' is the correct index now regardless */
940 msg_grp = &ctr->msg_groups[i];
944 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) {
945 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs));
948 msg_grp->msgs = msg_list;
950 new_slot = msg_grp->num_msgs-1;
951 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) );
953 /* need to allocate own copy of data */
956 msg_grp->msgs[new_slot].notify.data = (char *)
957 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len );
959 return ctr->num_groups;
962 /***********************************************************************
963 Send a change notication message on all handles which have a call
965 **********************************************************************/
967 static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
970 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr );
971 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx );
972 SPOOLSS_NOTIFY_MSG *messages;
973 int sending_msg_count;
976 DEBUG(5,("send_notify2_changes() called with no msg group!\n"));
980 messages = msg_group->msgs;
983 DEBUG(5,("send_notify2_changes() called with no messages!\n"));
987 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername));
989 /* loop over all printers */
991 for (p = printers_list; p; p = p->next) {
992 struct spoolss_Notify *notifies;
997 /* Is there notification on this handle? */
999 if ( !p->notify.client_connected )
1002 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename));
1004 /* For this printer? Print servers always receive
1007 if ( ( p->printer_type == SPLHND_PRINTER ) &&
1008 ( !strequal(msg_group->printername, p->sharename) ) )
1011 DEBUG(10,("Our printer\n"));
1013 /* allocate the max entries possible */
1015 notifies = TALLOC_ZERO_ARRAY(mem_ctx, struct spoolss_Notify, msg_group->num_msgs);
1020 /* build the array of change notifications */
1022 sending_msg_count = 0;
1024 for ( i=0; i<msg_group->num_msgs; i++ ) {
1025 SPOOLSS_NOTIFY_MSG *msg = &messages[i];
1027 /* Are we monitoring this event? */
1029 if (!is_monitoring_event(p, msg->type, msg->field))
1032 sending_msg_count++;
1035 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n",
1036 msg->type, msg->field, p->sharename));
1039 * if the is a printer notification handle and not a job notification
1040 * type, then set the id to 0. Other wise just use what was specified
1043 * When registering change notification on a print server handle
1044 * we always need to send back the id (snum) matching the printer
1045 * for which the change took place. For change notify registered
1046 * on a printer handle, this does not matter and the id should be 0.
1051 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) )
1057 /* Convert unix jobid to smb jobid */
1059 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) {
1060 id = sysjob_to_jobid(msg->id);
1063 DEBUG(3, ("no such unix jobid %d\n", msg->id));
1068 construct_info_data( ¬ifies[count], msg->type, msg->field, id );
1071 case PRINTER_NOTIFY_TYPE:
1072 if ( printer_notify_table[msg->field].fn )
1073 printer_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1076 case JOB_NOTIFY_TYPE:
1077 if ( job_notify_table[msg->field].fn )
1078 job_notify_table[msg->field].fn(msg, ¬ifies[count], mem_ctx);
1082 DEBUG(5, ("Unknown notification type %d\n", msg->type));
1089 if ( sending_msg_count ) {
1092 union spoolss_ReplyPrinterInfo info;
1093 struct spoolss_NotifyInfo info0;
1094 uint32_t reply_result;
1096 info0.version = 0x2;
1097 info0.flags = count ? 0x00020000 /* ??? */ : PRINTER_NOTIFY_INFO_DISCARDED;
1098 info0.count = count;
1099 info0.notifies = notifies;
1101 info.info0 = &info0;
1103 status = rpccli_spoolss_RouterReplyPrinterEx(notify_cli_pipe, mem_ctx,
1104 &p->notify.client_hnd,
1105 p->notify.change, /* color */
1108 0, /* reply_type, must be 0 */
1111 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(werr)) {
1112 DEBUG(1,("RouterReplyPrinterEx to client: %s failed: %s\n",
1113 notify_cli_pipe->srv_name_slash,
1116 switch (reply_result) {
1119 case PRINTER_NOTIFY_INFO_DISCARDED:
1120 case PRINTER_NOTIFY_INFO_DISCARDNOTED:
1121 case PRINTER_NOTIFY_INFO_COLOR_MISMATCH:
1130 DEBUG(8,("send_notify2_changes: Exit...\n"));
1134 /***********************************************************************
1135 **********************************************************************/
1137 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1140 uint32 tv_sec, tv_usec;
1143 /* Unpack message */
1145 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f",
1148 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd",
1150 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1153 tdb_unpack((uint8 *)buf + offset, len - offset, "dd",
1154 &msg->notify.value[0], &msg->notify.value[1]);
1156 tdb_unpack((uint8 *)buf + offset, len - offset, "B",
1157 &msg->len, &msg->notify.data);
1159 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1160 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1162 tv->tv_sec = tv_sec;
1163 tv->tv_usec = tv_usec;
1166 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1167 msg->notify.value[1]));
1169 dump_data(3, (uint8 *)msg->notify.data, msg->len);
1174 /********************************************************************
1175 Receive a notify2 message list
1176 ********************************************************************/
1178 static void receive_notify2_message_list(struct messaging_context *msg,
1181 struct server_id server_id,
1184 size_t msg_count, i;
1185 char *buf = (char *)data->data;
1188 SPOOLSS_NOTIFY_MSG notify;
1189 SPOOLSS_NOTIFY_MSG_CTR messages;
1192 if (data->length < 4) {
1193 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1197 msg_count = IVAL(buf, 0);
1200 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1202 if (msg_count == 0) {
1203 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1207 /* initialize the container */
1209 ZERO_STRUCT( messages );
1210 notify_msg_ctr_init( &messages );
1213 * build message groups for each printer identified
1214 * in a change_notify msg. Remember that a PCN message
1215 * includes the handle returned for the srv_spoolss_replyopenprinter()
1216 * call. Therefore messages are grouped according to printer handle.
1219 for ( i=0; i<msg_count; i++ ) {
1220 struct timeval msg_tv;
1222 if (msg_ptr + 4 - buf > data->length) {
1223 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1227 msg_len = IVAL(msg_ptr,0);
1230 if (msg_ptr + msg_len - buf > data->length) {
1231 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1235 /* unpack messages */
1237 ZERO_STRUCT( notify );
1238 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1241 /* add to correct list in container */
1243 notify_msg_ctr_addmsg( &messages, ¬ify );
1245 /* free memory that might have been allocated by notify2_unpack_msg() */
1247 if ( notify.len != 0 )
1248 SAFE_FREE( notify.notify.data );
1251 /* process each group of messages */
1253 num_groups = notify_msg_ctr_numgroups( &messages );
1254 for ( i=0; i<num_groups; i++ )
1255 send_notify2_changes( &messages, i );
1260 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
1262 notify_msg_ctr_destroy( &messages );
1267 /********************************************************************
1268 Send a message to ourself about new driver being installed
1269 so we can upgrade the information for each printer bound to this
1271 ********************************************************************/
1273 static bool srv_spoolss_drv_upgrade_printer(char* drivername)
1275 int len = strlen(drivername);
1280 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1283 messaging_send_buf(smbd_messaging_context(), procid_self(),
1284 MSG_PRINTER_DRVUPGRADE,
1285 (uint8 *)drivername, len+1);
1290 /**********************************************************************
1291 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1292 over all printers, upgrading ones as necessary
1293 **********************************************************************/
1295 void do_drv_upgrade_printer(struct messaging_context *msg,
1298 struct server_id server_id,
1303 int n_services = lp_numservices();
1306 len = MIN(data->length,sizeof(drivername)-1);
1307 strncpy(drivername, (const char *)data->data, len);
1309 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1311 /* Iterate the printer list */
1313 for (snum=0; snum<n_services; snum++)
1315 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1318 NT_PRINTER_INFO_LEVEL *printer = NULL;
1320 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1321 if (!W_ERROR_IS_OK(result))
1324 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1326 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1328 /* all we care about currently is the change_id */
1330 result = mod_a_printer(printer, 2);
1331 if (!W_ERROR_IS_OK(result)) {
1332 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1333 win_errstr(result)));
1337 free_a_printer(&printer, 2);
1344 /********************************************************************
1345 Update the cache for all printq's with a registered client
1347 ********************************************************************/
1349 void update_monitored_printq_cache( void )
1351 Printer_entry *printer = printers_list;
1354 /* loop through all printers and update the cache where
1355 client_connected == True */
1358 if ( (printer->printer_type == SPLHND_PRINTER)
1359 && printer->notify.client_connected )
1361 snum = print_queue_snum(printer->sharename);
1362 print_queue_status( snum, NULL, NULL );
1365 printer = printer->next;
1370 /********************************************************************
1371 Send a message to ourself about new driver being installed
1372 so we can upgrade the information for each printer bound to this
1374 ********************************************************************/
1376 static bool srv_spoolss_reset_printerdata(char* drivername)
1378 int len = strlen(drivername);
1383 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1386 messaging_send_buf(smbd_messaging_context(), procid_self(),
1387 MSG_PRINTERDATA_INIT_RESET,
1388 (uint8 *)drivername, len+1);
1393 /**********************************************************************
1394 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1395 over all printers, resetting printer data as neessary
1396 **********************************************************************/
1398 void reset_all_printerdata(struct messaging_context *msg,
1401 struct server_id server_id,
1406 int n_services = lp_numservices();
1409 len = MIN( data->length, sizeof(drivername)-1 );
1410 strncpy( drivername, (const char *)data->data, len );
1412 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1414 /* Iterate the printer list */
1416 for ( snum=0; snum<n_services; snum++ )
1418 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1421 NT_PRINTER_INFO_LEVEL *printer = NULL;
1423 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1424 if ( !W_ERROR_IS_OK(result) )
1428 * if the printer is bound to the driver,
1429 * then reset to the new driver initdata
1432 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1434 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1436 if ( !set_driver_init(printer, 2) ) {
1437 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1438 printer->info_2->printername, printer->info_2->drivername));
1441 result = mod_a_printer( printer, 2 );
1442 if ( !W_ERROR_IS_OK(result) ) {
1443 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1444 get_dos_error_msg(result)));
1448 free_a_printer( &printer, 2 );
1457 /****************************************************************
1458 _spoolss_OpenPrinter
1459 ****************************************************************/
1461 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1462 struct spoolss_OpenPrinter *r)
1464 struct spoolss_OpenPrinterEx e;
1467 ZERO_STRUCT(e.in.userlevel);
1469 e.in.printername = r->in.printername;
1470 e.in.datatype = r->in.datatype;
1471 e.in.devmode_ctr = r->in.devmode_ctr;
1472 e.in.access_mask = r->in.access_mask;
1475 e.out.handle = r->out.handle;
1477 werr = _spoolss_OpenPrinterEx(p, &e);
1479 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1480 /* OpenPrinterEx returns this for a bad
1481 * printer name. We must return WERR_INVALID_PRINTER_NAME
1484 werr = WERR_INVALID_PRINTER_NAME;
1490 /********************************************************************
1491 FIXME: temporary convert_devicemode_new function
1492 ********************************************************************/
1494 static bool convert_devicemode_new(const char *printername,
1495 struct spoolss_DeviceMode *devmode,
1496 NT_DEVICEMODE **pp_nt_devmode)
1498 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1501 * Ensure nt_devmode is a valid pointer
1502 * as we will be overwriting it.
1505 if (nt_devmode == NULL) {
1506 DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
1507 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1511 rpcstr_push(nt_devmode->devicename, devmode->devicename, 31, 0);
1512 rpcstr_push(nt_devmode->formname, devmode->formname, 31, 0);
1514 nt_devmode->specversion = devmode->specversion;
1515 nt_devmode->driverversion = devmode->driverversion;
1516 nt_devmode->size = devmode->size;
1517 nt_devmode->fields = devmode->fields;
1518 nt_devmode->orientation = devmode->orientation;
1519 nt_devmode->papersize = devmode->papersize;
1520 nt_devmode->paperlength = devmode->paperlength;
1521 nt_devmode->paperwidth = devmode->paperwidth;
1522 nt_devmode->scale = devmode->scale;
1523 nt_devmode->copies = devmode->copies;
1524 nt_devmode->defaultsource = devmode->defaultsource;
1525 nt_devmode->printquality = devmode->printquality;
1526 nt_devmode->color = devmode->color;
1527 nt_devmode->duplex = devmode->duplex;
1528 nt_devmode->yresolution = devmode->yresolution;
1529 nt_devmode->ttoption = devmode->ttoption;
1530 nt_devmode->collate = devmode->collate;
1532 nt_devmode->logpixels = devmode->logpixels;
1533 nt_devmode->bitsperpel = devmode->bitsperpel;
1534 nt_devmode->pelswidth = devmode->pelswidth;
1535 nt_devmode->pelsheight = devmode->pelsheight;
1536 nt_devmode->displayflags = devmode->displayflags;
1537 nt_devmode->displayfrequency = devmode->displayfrequency;
1538 nt_devmode->icmmethod = devmode->icmmethod;
1539 nt_devmode->icmintent = devmode->icmintent;
1540 nt_devmode->mediatype = devmode->mediatype;
1541 nt_devmode->dithertype = devmode->dithertype;
1542 nt_devmode->reserved1 = devmode->reserved1;
1543 nt_devmode->reserved2 = devmode->reserved2;
1544 nt_devmode->panningwidth = devmode->panningwidth;
1545 nt_devmode->panningheight = devmode->panningheight;
1548 * Only change private and driverextra if the incoming devmode
1549 * has a new one. JRA.
1552 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1553 SAFE_FREE(nt_devmode->nt_dev_private);
1554 nt_devmode->driverextra = devmode->__driverextra_length;
1555 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1557 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1560 *pp_nt_devmode = nt_devmode;
1565 /****************************************************************
1566 _spoolss_OpenPrinterEx
1567 ****************************************************************/
1569 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1570 struct spoolss_OpenPrinterEx *r)
1572 POLICY_HND *handle = r->out.handle;
1573 char *name = CONST_DISCARD(char *, r->in.printername);
1575 Printer_entry *Printer=NULL;
1578 return WERR_INVALID_PARAM;
1581 /* some sanity check because you can open a printer or a print server */
1582 /* aka: \\server\printer or \\server */
1584 DEBUGADD(3,("checking name: %s\n",name));
1586 if (!open_printer_hnd(p, handle, name, 0)) {
1587 ZERO_STRUCTP(r->out.handle);
1588 return WERR_INVALID_PARAM;
1591 Printer=find_printer_index_by_hnd(p, handle);
1593 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1594 "handle we created for printer %s\n", name ));
1595 close_printer_handle(p,handle);
1596 ZERO_STRUCTP(r->out.handle);
1597 return WERR_INVALID_PARAM;
1601 * First case: the user is opening the print server:
1603 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1604 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1606 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1607 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1608 * or if the user is listed in the smb.conf printer admin parameter.
1610 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1611 * client view printer folder, but does not show the MSAPW.
1613 * Note: this test needs code to check access rights here too. Jeremy
1614 * could you look at this?
1616 * Second case: the user is opening a printer:
1617 * NT doesn't let us connect to a printer if the connecting user
1618 * doesn't have print permission.
1620 * Third case: user is opening a Port Monitor
1621 * access checks same as opening a handle to the print server.
1624 switch (Printer->printer_type )
1627 case SPLHND_PORTMON_TCP:
1628 case SPLHND_PORTMON_LOCAL:
1629 /* Printserver handles use global struct... */
1633 /* Map standard access rights to object specific access rights */
1635 se_map_standard(&r->in.access_mask,
1636 &printserver_std_mapping);
1638 /* Deny any object specific bits that don't apply to print
1639 servers (i.e printer and job specific bits) */
1641 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1643 if (r->in.access_mask &
1644 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1645 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1646 close_printer_handle(p, handle);
1647 ZERO_STRUCTP(r->out.handle);
1648 return WERR_ACCESS_DENIED;
1651 /* Allow admin access */
1653 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1655 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1657 if (!lp_ms_add_printer_wizard()) {
1658 close_printer_handle(p, handle);
1659 ZERO_STRUCTP(r->out.handle);
1660 return WERR_ACCESS_DENIED;
1663 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1664 and not a printer admin, then fail */
1666 if ((p->server_info->utok.uid != 0) &&
1667 !user_has_privileges(p->server_info->ptok,
1669 !token_contains_name_in_list(
1670 uidtoname(p->server_info->utok.uid),
1672 p->server_info->ptok,
1673 lp_printer_admin(snum))) {
1674 close_printer_handle(p, handle);
1675 ZERO_STRUCTP(r->out.handle);
1676 return WERR_ACCESS_DENIED;
1679 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1683 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1686 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1687 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1689 /* We fall through to return WERR_OK */
1692 case SPLHND_PRINTER:
1693 /* NT doesn't let us connect to a printer if the connecting user
1694 doesn't have print permission. */
1696 if (!get_printer_snum(p, handle, &snum, NULL)) {
1697 close_printer_handle(p, handle);
1698 ZERO_STRUCTP(r->out.handle);
1702 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1704 /* map an empty access mask to the minimum access mask */
1705 if (r->in.access_mask == 0x0)
1706 r->in.access_mask = PRINTER_ACCESS_USE;
1709 * If we are not serving the printer driver for this printer,
1710 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1711 * will keep NT clients happy --jerry
1714 if (lp_use_client_driver(snum)
1715 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1717 r->in.access_mask = PRINTER_ACCESS_USE;
1720 /* check smb.conf parameters and the the sec_desc */
1722 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1723 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1724 ZERO_STRUCTP(r->out.handle);
1725 return WERR_ACCESS_DENIED;
1728 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1729 p->server_info->ptok, snum) ||
1730 !print_access_check(p->server_info, snum,
1731 r->in.access_mask)) {
1732 DEBUG(3, ("access DENIED for printer open\n"));
1733 close_printer_handle(p, handle);
1734 ZERO_STRUCTP(r->out.handle);
1735 return WERR_ACCESS_DENIED;
1738 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1739 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1740 close_printer_handle(p, handle);
1741 ZERO_STRUCTP(r->out.handle);
1742 return WERR_ACCESS_DENIED;
1745 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1746 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1748 r->in.access_mask = PRINTER_ACCESS_USE;
1750 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1751 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1756 /* sanity check to prevent programmer error */
1757 ZERO_STRUCTP(r->out.handle);
1761 Printer->access_granted = r->in.access_mask;
1764 * If the client sent a devmode in the OpenPrinter() call, then
1765 * save it here in case we get a job submission on this handle
1768 if ( (Printer->printer_type != SPLHND_SERVER)
1769 && r->in.devmode_ctr.devmode )
1771 convert_devicemode_new(Printer->sharename,
1772 r->in.devmode_ctr.devmode,
1773 &Printer->nt_devmode);
1776 #if 0 /* JERRY -- I'm doubtful this is really effective */
1777 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1778 optimization in Windows 2000 clients --jerry */
1780 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1781 && (RA_WIN2K == get_remote_arch()) )
1783 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1784 sys_usleep( 500000 );
1791 /****************************************************************************
1792 ****************************************************************************/
1794 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1795 NT_PRINTER_INFO_LEVEL_2 *d)
1797 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1803 d->attributes = r->attributes;
1804 d->priority = r->priority;
1805 d->default_priority = r->defaultpriority;
1806 d->starttime = r->starttime;
1807 d->untiltime = r->untiltime;
1808 d->status = r->status;
1809 d->cjobs = r->cjobs;
1811 fstrcpy(d->servername, r->servername);
1812 fstrcpy(d->printername, r->printername);
1813 fstrcpy(d->sharename, r->sharename);
1814 fstrcpy(d->portname, r->portname);
1815 fstrcpy(d->drivername, r->drivername);
1816 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1817 fstrcpy(d->location, r->location);
1818 fstrcpy(d->sepfile, r->sepfile);
1819 fstrcpy(d->printprocessor, r->printprocessor);
1820 fstrcpy(d->datatype, r->datatype);
1821 fstrcpy(d->parameters, r->parameters);
1826 /****************************************************************************
1827 ****************************************************************************/
1829 static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
1830 NT_PRINTER_INFO_LEVEL *printer)
1834 switch (info_ctr->level) {
1836 /* allocate memory if needed. Messy because
1837 convert_printer_info is used to update an existing
1838 printer or build a new one */
1840 if (!printer->info_2) {
1841 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1842 if (!printer->info_2) {
1843 DEBUG(0,("convert_printer_info_new: "
1844 "talloc() failed!\n"));
1849 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1851 printer->info_2->setuptime = time(NULL);
1858 /*******************************************************************
1859 ********************************************************************/
1861 static bool string_array_to_fstring_array(const char **sarray, fstring **farray)
1870 *farray = SMB_MALLOC_ARRAY(fstring, 1);
1875 for (i=0; sarray[i] != NULL; i++) {
1876 *farray = SMB_REALLOC_ARRAY(*farray, fstring, i+2);
1880 fstrcpy((*farray)[i], sarray[i]);
1883 fstrcpy((*farray)[i], "");
1888 /*******************************************************************
1889 ********************************************************************/
1891 static bool driver_info3_to_nt_driver_info3(struct spoolss_AddDriverInfo3 *r,
1892 NT_PRINTER_DRIVER_INFO_LEVEL_3 **p)
1894 NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
1896 DEBUG(7,("driver_info3_to_nt_driver_info3: Converting from UNICODE to ASCII\n"));
1899 *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
1908 d->cversion = r->version;
1910 fstrcpy(d->name, r->driver_name);
1911 fstrcpy(d->environment, r->architecture);
1912 fstrcpy(d->driverpath, r->driver_path);
1913 fstrcpy(d->datafile, r->data_file);
1914 fstrcpy(d->configfile, r->config_file);
1915 fstrcpy(d->helpfile, r->help_file);
1916 fstrcpy(d->monitorname, r->monitor_name);
1917 fstrcpy(d->defaultdatatype, r->default_datatype);
1919 DEBUGADD(8,( "version: %d\n", d->cversion));
1920 DEBUGADD(8,( "name: %s\n", d->name));
1921 DEBUGADD(8,( "environment: %s\n", d->environment));
1922 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
1923 DEBUGADD(8,( "datafile: %s\n", d->datafile));
1924 DEBUGADD(8,( "configfile: %s\n", d->configfile));
1925 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
1926 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
1927 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
1929 if (r->dependent_files) {
1930 if (!string_array_to_fstring_array(r->dependent_files->string,
1931 &d->dependentfiles)) {
1940 /*******************************************************************
1941 ********************************************************************/
1943 static bool driver_info6_to_nt_driver_info6(struct spoolss_AddDriverInfo6 *r,
1944 NT_PRINTER_DRIVER_INFO_LEVEL_6 **p)
1946 NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
1948 DEBUG(7,("driver_info6_to_nt_driver_info6: Converting from UNICODE to ASCII\n"));
1951 *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
1960 d->version = r->version;
1962 fstrcpy(d->name, r->driver_name);
1963 fstrcpy(d->environment, r->architecture);
1964 fstrcpy(d->driverpath, r->driver_path);
1965 fstrcpy(d->datafile, r->data_file);
1966 fstrcpy(d->configfile, r->config_file);
1967 fstrcpy(d->helpfile, r->help_file);
1968 fstrcpy(d->monitorname, r->monitor_name);
1969 fstrcpy(d->defaultdatatype, r->default_datatype);
1971 DEBUGADD(8,( "version: %d\n", d->version));
1972 DEBUGADD(8,( "name: %s\n", d->name));
1973 DEBUGADD(8,( "environment: %s\n", d->environment));
1974 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
1975 DEBUGADD(8,( "datafile: %s\n", d->datafile));
1976 DEBUGADD(8,( "configfile: %s\n", d->configfile));
1977 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
1978 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
1979 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
1981 if (r->dependent_files) {
1982 if (!string_array_to_fstring_array(r->dependent_files->string,
1983 &d->dependentfiles)) {
1988 if (r->previous_names) {
1989 if (!string_array_to_fstring_array(r->previous_names->string,
1990 &d->previousnames)) {
2002 /********************************************************************
2003 ********************************************************************/
2005 static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr *r,
2006 NT_PRINTER_DRIVER_INFO_LEVEL *printer,
2011 printer->info_3 = NULL;
2012 if (!driver_info3_to_nt_driver_info3(r->info.info3, &printer->info_3)) {
2017 printer->info_6 = NULL;
2018 if (!driver_info6_to_nt_driver_info6(r->info.info6, &printer->info_6)) {
2029 bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
2030 NT_DEVICEMODE **pp_nt_devmode)
2032 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
2035 * Ensure nt_devmode is a valid pointer
2036 * as we will be overwriting it.
2039 if (nt_devmode == NULL) {
2040 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
2041 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
2045 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
2046 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
2048 nt_devmode->specversion=devmode->specversion;
2049 nt_devmode->driverversion=devmode->driverversion;
2050 nt_devmode->size=devmode->size;
2051 nt_devmode->fields=devmode->fields;
2052 nt_devmode->orientation=devmode->orientation;
2053 nt_devmode->papersize=devmode->papersize;
2054 nt_devmode->paperlength=devmode->paperlength;
2055 nt_devmode->paperwidth=devmode->paperwidth;
2056 nt_devmode->scale=devmode->scale;
2057 nt_devmode->copies=devmode->copies;
2058 nt_devmode->defaultsource=devmode->defaultsource;
2059 nt_devmode->printquality=devmode->printquality;
2060 nt_devmode->color=devmode->color;
2061 nt_devmode->duplex=devmode->duplex;
2062 nt_devmode->yresolution=devmode->yresolution;
2063 nt_devmode->ttoption=devmode->ttoption;
2064 nt_devmode->collate=devmode->collate;
2066 nt_devmode->logpixels=devmode->logpixels;
2067 nt_devmode->bitsperpel=devmode->bitsperpel;
2068 nt_devmode->pelswidth=devmode->pelswidth;
2069 nt_devmode->pelsheight=devmode->pelsheight;
2070 nt_devmode->displayflags=devmode->displayflags;
2071 nt_devmode->displayfrequency=devmode->displayfrequency;
2072 nt_devmode->icmmethod=devmode->icmmethod;
2073 nt_devmode->icmintent=devmode->icmintent;
2074 nt_devmode->mediatype=devmode->mediatype;
2075 nt_devmode->dithertype=devmode->dithertype;
2076 nt_devmode->reserved1=devmode->reserved1;
2077 nt_devmode->reserved2=devmode->reserved2;
2078 nt_devmode->panningwidth=devmode->panningwidth;
2079 nt_devmode->panningheight=devmode->panningheight;
2082 * Only change private and driverextra if the incoming devmode
2083 * has a new one. JRA.
2086 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
2087 SAFE_FREE(nt_devmode->nt_dev_private);
2088 nt_devmode->driverextra=devmode->driverextra;
2089 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
2091 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
2094 *pp_nt_devmode = nt_devmode;
2099 /********************************************************************
2100 * _spoolss_enddocprinter_internal.
2101 ********************************************************************/
2103 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
2105 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2109 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
2113 if (!get_printer_snum(p, handle, &snum, NULL))
2116 Printer->document_started=False;
2117 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
2118 /* error codes unhandled so far ... */
2123 /****************************************************************
2124 _spoolss_ClosePrinter
2125 ****************************************************************/
2127 WERROR _spoolss_ClosePrinter(pipes_struct *p,
2128 struct spoolss_ClosePrinter *r)
2130 POLICY_HND *handle = r->in.handle;
2132 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2134 if (Printer && Printer->document_started)
2135 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2137 if (!close_printer_handle(p, handle))
2140 /* clear the returned printer handle. Observed behavior
2141 from Win2k server. Don't think this really matters.
2142 Previous code just copied the value of the closed
2145 ZERO_STRUCTP(r->out.handle);
2150 /****************************************************************
2151 _spoolss_DeletePrinter
2152 ****************************************************************/
2154 WERROR _spoolss_DeletePrinter(pipes_struct *p,
2155 struct spoolss_DeletePrinter *r)
2157 POLICY_HND *handle = r->in.handle;
2158 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2161 if (Printer && Printer->document_started)
2162 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2164 result = delete_printer_handle(p, handle);
2166 update_c_setprinter(False);
2171 /*******************************************************************
2172 * static function to lookup the version id corresponding to an
2173 * long architecture string
2174 ******************************************************************/
2176 static int get_version_id (char * arch)
2179 struct table_node archi_table[]= {
2181 {"Windows 4.0", "WIN40", 0 },
2182 {"Windows NT x86", "W32X86", 2 },
2183 {"Windows NT R4000", "W32MIPS", 2 },
2184 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
2185 {"Windows NT PowerPC", "W32PPC", 2 },
2186 {"Windows IA64", "IA64", 3 },
2187 {"Windows x64", "x64", 3 },
2191 for (i=0; archi_table[i].long_archi != NULL; i++)
2193 if (strcmp(arch, archi_table[i].long_archi) == 0)
2194 return (archi_table[i].version);
2200 /****************************************************************
2201 _spoolss_DeletePrinterDriver
2202 ****************************************************************/
2204 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
2205 struct spoolss_DeletePrinterDriver *r)
2209 NT_PRINTER_DRIVER_INFO_LEVEL info;
2210 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2213 WERROR status_win2k = WERR_ACCESS_DENIED;
2214 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2216 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2217 and not a printer admin, then fail */
2219 if ( (p->server_info->utok.uid != 0)
2220 && !user_has_privileges(p->server_info->ptok, &se_printop )
2221 && !token_contains_name_in_list(
2222 uidtoname(p->server_info->utok.uid), NULL,
2223 NULL, p->server_info->ptok,
2224 lp_printer_admin(-1)) )
2226 return WERR_ACCESS_DENIED;
2229 driver = CONST_DISCARD(char *, r->in.driver);
2230 arch = CONST_DISCARD(char *, r->in.architecture);
2232 /* check that we have a valid driver name first */
2234 if ((version=get_version_id(arch)) == -1)
2235 return WERR_INVALID_ENVIRONMENT;
2238 ZERO_STRUCT(info_win2k);
2240 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2242 /* try for Win2k driver if "Windows NT x86" */
2244 if ( version == 2 ) {
2246 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2247 status = WERR_UNKNOWN_PRINTER_DRIVER;
2251 /* otherwise it was a failure */
2253 status = WERR_UNKNOWN_PRINTER_DRIVER;
2259 if (printer_driver_in_use(info.info_3)) {
2260 status = WERR_PRINTER_DRIVER_IN_USE;
2266 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2268 /* if we get to here, we now have 2 driver info structures to remove */
2269 /* remove the Win2k driver first*/
2271 status_win2k = delete_printer_driver(
2272 p, info_win2k.info_3, 3, False );
2273 free_a_printer_driver( info_win2k, 3 );
2275 /* this should not have failed---if it did, report to client */
2276 if ( !W_ERROR_IS_OK(status_win2k) )
2278 status = status_win2k;
2284 status = delete_printer_driver(p, info.info_3, version, False);
2286 /* if at least one of the deletes succeeded return OK */
2288 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2292 free_a_printer_driver( info, 3 );
2297 /****************************************************************
2298 _spoolss_DeletePrinterDriverEx
2299 ****************************************************************/
2301 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2302 struct spoolss_DeletePrinterDriverEx *r)
2306 NT_PRINTER_DRIVER_INFO_LEVEL info;
2307 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2309 uint32_t flags = r->in.delete_flags;
2312 WERROR status_win2k = WERR_ACCESS_DENIED;
2313 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2315 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2316 and not a printer admin, then fail */
2318 if ( (p->server_info->utok.uid != 0)
2319 && !user_has_privileges(p->server_info->ptok, &se_printop )
2320 && !token_contains_name_in_list(
2321 uidtoname(p->server_info->utok.uid), NULL, NULL,
2322 p->server_info->ptok, lp_printer_admin(-1)) )
2324 return WERR_ACCESS_DENIED;
2327 driver = CONST_DISCARD(char *, r->in.driver);
2328 arch = CONST_DISCARD(char *, r->in.architecture);
2330 /* check that we have a valid driver name first */
2331 if ((version=get_version_id(arch)) == -1) {
2332 /* this is what NT returns */
2333 return WERR_INVALID_ENVIRONMENT;
2336 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2337 version = r->in.version;
2340 ZERO_STRUCT(info_win2k);
2342 status = get_a_printer_driver(&info, 3, driver, arch, version);
2344 if ( !W_ERROR_IS_OK(status) )
2347 * if the client asked for a specific version,
2348 * or this is something other than Windows NT x86,
2352 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2355 /* try for Win2k driver if "Windows NT x86" */
2358 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2359 status = WERR_UNKNOWN_PRINTER_DRIVER;
2364 if ( printer_driver_in_use(info.info_3) ) {
2365 status = WERR_PRINTER_DRIVER_IN_USE;
2370 * we have a couple of cases to consider.
2371 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2372 * then the delete should fail if **any** files overlap with
2374 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2375 * non-overlapping files
2376 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2377 * is set, the do not delete any files
2378 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2381 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2383 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2385 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2386 /* no idea of the correct error here */
2387 status = WERR_ACCESS_DENIED;
2392 /* also check for W32X86/3 if necessary; maybe we already have? */
2394 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2395 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2398 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2399 /* no idea of the correct error here */
2400 free_a_printer_driver( info_win2k, 3 );
2401 status = WERR_ACCESS_DENIED;
2405 /* if we get to here, we now have 2 driver info structures to remove */
2406 /* remove the Win2k driver first*/
2408 status_win2k = delete_printer_driver(
2409 p, info_win2k.info_3, 3, delete_files);
2410 free_a_printer_driver( info_win2k, 3 );
2412 /* this should not have failed---if it did, report to client */
2414 if ( !W_ERROR_IS_OK(status_win2k) )
2419 status = delete_printer_driver(p, info.info_3, version, delete_files);
2421 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2424 free_a_printer_driver( info, 3 );
2430 /****************************************************************************
2431 Internal routine for retreiving printerdata
2432 ***************************************************************************/
2434 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2435 const char *key, const char *value, uint32 *type, uint8 **data,
2436 uint32 *needed, uint32 in_size )
2438 REGISTRY_VALUE *val;
2442 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2443 return WERR_BADFILE;
2445 *type = regval_type( val );
2447 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2449 size = regval_size( val );
2451 /* copy the min(in_size, len) */
2454 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2456 /* special case for 0 length values */
2458 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2462 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2471 DEBUG(5,("get_printer_dataex: copy done\n"));
2476 /****************************************************************************
2477 Internal routine for removing printerdata
2478 ***************************************************************************/
2480 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2482 return delete_printer_data( printer->info_2, key, value );
2485 /****************************************************************************
2486 Internal routine for storing printerdata
2487 ***************************************************************************/
2489 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2490 uint32 type, uint8 *data, int real_len )
2492 /* the registry objects enforce uniqueness based on value name */
2494 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2497 /********************************************************************
2498 GetPrinterData on a printer server Handle.
2499 ********************************************************************/
2501 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2505 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2507 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2509 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2511 SIVAL(*data, 0, 0x00);
2516 if (!StrCaseCmp(value, "BeepEnabled")) {
2518 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2520 SIVAL(*data, 0, 0x00);
2525 if (!StrCaseCmp(value, "EventLog")) {
2527 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2529 /* formally was 0x1b */
2530 SIVAL(*data, 0, 0x0);
2535 if (!StrCaseCmp(value, "NetPopup")) {
2537 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2539 SIVAL(*data, 0, 0x00);
2544 if (!StrCaseCmp(value, "MajorVersion")) {
2546 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2549 /* Windows NT 4.0 seems to not allow uploading of drivers
2550 to a server that reports 0x3 as the MajorVersion.
2551 need to investigate more how Win2k gets around this .
2554 if ( RA_WINNT == get_remote_arch() )
2563 if (!StrCaseCmp(value, "MinorVersion")) {
2565 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2573 * uint32 size = 0x114
2575 * uint32 minor = [0|1]
2576 * uint32 build = [2195|2600]
2577 * extra unicode string = e.g. "Service Pack 3"
2579 if (!StrCaseCmp(value, "OSVersion")) {
2583 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2586 SIVAL(*data, 0, *needed); /* size */
2587 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2589 SIVAL(*data, 12, 2195); /* build */
2591 /* leave extra string empty */
2597 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2598 const char *string="C:\\PRINTERS";
2600 *needed = 2*(strlen(string)+1);
2601 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2603 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2605 /* it's done by hand ready to go on the wire */
2606 for (i=0; i<strlen(string); i++) {
2607 (*data)[2*i]=string[i];
2608 (*data)[2*i+1]='\0';
2613 if (!StrCaseCmp(value, "Architecture")) {
2614 const char *string="Windows NT x86";
2616 *needed = 2*(strlen(string)+1);
2617 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2619 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2620 for (i=0; i<strlen(string); i++) {
2621 (*data)[2*i]=string[i];
2622 (*data)[2*i+1]='\0';
2627 if (!StrCaseCmp(value, "DsPresent")) {
2629 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2632 /* only show the publish check box if we are a
2633 memeber of a AD domain */
2635 if ( lp_security() == SEC_ADS )
2636 SIVAL(*data, 0, 0x01);
2638 SIVAL(*data, 0, 0x00);
2644 if (!StrCaseCmp(value, "DNSMachineName")) {
2645 const char *hostname = get_mydnsfullname();
2648 return WERR_BADFILE;
2650 *needed = 2*(strlen(hostname)+1);
2651 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2653 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2654 for (i=0; i<strlen(hostname); i++) {
2655 (*data)[2*i]=hostname[i];
2656 (*data)[2*i+1]='\0';
2662 return WERR_BADFILE;
2665 /********************************************************************
2666 * spoolss_getprinterdata
2667 ********************************************************************/
2669 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2671 POLICY_HND *handle = &q_u->handle;
2672 UNISTR2 *valuename = &q_u->valuename;
2673 uint32 in_size = q_u->size;
2674 uint32 *type = &r_u->type;
2675 uint32 *out_size = &r_u->size;
2676 uint8 **data = &r_u->data;
2677 uint32 *needed = &r_u->needed;
2680 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2681 NT_PRINTER_INFO_LEVEL *printer = NULL;
2685 * Reminder: when it's a string, the length is in BYTES
2686 * even if UNICODE is negociated.
2691 *out_size = in_size;
2693 /* in case of problem, return some default values */
2698 DEBUG(4,("_spoolss_getprinterdata\n"));
2701 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2702 status = WERR_BADFID;
2706 unistr2_to_ascii(value, valuename, sizeof(value));
2708 if ( Printer->printer_type == SPLHND_SERVER )
2709 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2712 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2713 status = WERR_BADFID;
2717 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2718 if ( !W_ERROR_IS_OK(status) )
2721 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2723 if ( strequal(value, "ChangeId") ) {
2725 *needed = sizeof(uint32);
2726 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2727 status = WERR_NOMEM;
2730 SIVAL( *data, 0, printer->info_2->changeid );
2734 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2737 if (*needed > *out_size)
2738 status = WERR_MORE_DATA;
2741 if ( !W_ERROR_IS_OK(status) )
2743 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2745 /* reply this param doesn't exist */
2748 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2750 free_a_printer( &printer, 2 );
2758 /* cleanup & exit */
2761 free_a_printer( &printer, 2 );
2766 /*********************************************************
2767 Connect to the client machine.
2768 **********************************************************/
2770 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2771 struct sockaddr_storage *client_ss, const char *remote_machine)
2774 struct cli_state *the_cli;
2775 struct sockaddr_storage rm_addr;
2777 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2778 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2779 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2783 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2784 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2788 char addr[INET6_ADDRSTRLEN];
2789 rm_addr = *client_ss;
2790 print_sockaddr(addr, sizeof(addr), &rm_addr);
2791 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2795 /* setup the connection */
2797 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2798 &rm_addr, 0, "IPC$", "IPC",
2802 0, lp_client_signing(), NULL );
2804 if ( !NT_STATUS_IS_OK( ret ) ) {
2805 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2810 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2811 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2812 cli_shutdown(the_cli);
2817 * Ok - we have an anonymous connection to the IPC$ share.
2818 * Now start the NT Domain stuff :-).
2821 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2822 if (!NT_STATUS_IS_OK(ret)) {
2823 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2824 remote_machine, nt_errstr(ret)));
2825 cli_shutdown(the_cli);
2832 /***************************************************************************
2833 Connect to the client.
2834 ****************************************************************************/
2836 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2837 uint32 localprinter, uint32 type,
2838 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2844 * If it's the first connection, contact the client
2845 * and connect to the IPC$ share anonymously
2847 if (smb_connections==0) {
2848 fstring unix_printer;
2850 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2852 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2855 messaging_register(smbd_messaging_context(), NULL,
2856 MSG_PRINTER_NOTIFY2,
2857 receive_notify2_message_list);
2858 /* Tell the connections db we're now interested in printer
2859 * notify messages. */
2860 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2864 * Tell the specific printing tdb we want messages for this printer
2865 * by registering our PID.
2868 if (!print_notify_register_pid(snum))
2869 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2873 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2881 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2882 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2883 win_errstr(result)));
2885 return (W_ERROR_IS_OK(result));
2888 /********************************************************************
2890 * ReplyFindFirstPrinterChangeNotifyEx
2892 * before replying OK: status=0 a rpc call is made to the workstation
2893 * asking ReplyOpenPrinter
2895 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2896 * called from api_spoolss_rffpcnex
2897 ********************************************************************/
2899 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2901 POLICY_HND *handle = &q_u->handle;
2902 uint32 flags = q_u->flags;
2903 uint32 options = q_u->options;
2904 UNISTR2 *localmachine = &q_u->localmachine;
2905 uint32 printerlocal = q_u->printerlocal;
2907 SPOOL_NOTIFY_OPTION *option = q_u->option;
2908 struct sockaddr_storage client_ss;
2910 /* store the notify value in the printer struct */
2912 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2915 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2919 Printer->notify.flags=flags;
2920 Printer->notify.options=options;
2921 Printer->notify.printerlocal=printerlocal;
2923 if (Printer->notify.option)
2924 free_spool_notify_option(&Printer->notify.option);
2926 Printer->notify.option=dup_spool_notify_option(option);
2928 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
2929 sizeof(Printer->notify.localmachine));
2931 /* Connect to the client machine and send a ReplyOpenPrinter */
2933 if ( Printer->printer_type == SPLHND_SERVER)
2935 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2936 !get_printer_snum(p, handle, &snum, NULL) )
2939 if (!interpret_string_addr(&client_ss, p->client_address,
2941 return WERR_SERVER_UNAVAILABLE;
2944 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2945 Printer->notify.printerlocal, 1,
2946 &Printer->notify.client_hnd, &client_ss))
2947 return WERR_SERVER_UNAVAILABLE;
2949 Printer->notify.client_connected=True;
2954 /*******************************************************************
2955 * fill a notify_info_data with the servername
2956 ********************************************************************/
2958 void spoolss_notify_server_name(int snum,
2959 struct spoolss_Notify *data,
2960 print_queue_struct *queue,
2961 NT_PRINTER_INFO_LEVEL *printer,
2962 TALLOC_CTX *mem_ctx)
2964 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2967 /*******************************************************************
2968 * fill a notify_info_data with the printername (not including the servername).
2969 ********************************************************************/
2971 void spoolss_notify_printer_name(int snum,
2972 struct spoolss_Notify *data,
2973 print_queue_struct *queue,
2974 NT_PRINTER_INFO_LEVEL *printer,
2975 TALLOC_CTX *mem_ctx)
2977 /* the notify name should not contain the \\server\ part */
2978 char *p = strrchr(printer->info_2->printername, '\\');
2981 p = printer->info_2->printername;
2986 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2989 /*******************************************************************
2990 * fill a notify_info_data with the servicename
2991 ********************************************************************/
2993 void spoolss_notify_share_name(int snum,
2994 struct spoolss_Notify *data,
2995 print_queue_struct *queue,
2996 NT_PRINTER_INFO_LEVEL *printer,
2997 TALLOC_CTX *mem_ctx)
2999 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
3002 /*******************************************************************
3003 * fill a notify_info_data with the port name
3004 ********************************************************************/
3006 void spoolss_notify_port_name(int snum,
3007 struct spoolss_Notify *data,
3008 print_queue_struct *queue,
3009 NT_PRINTER_INFO_LEVEL *printer,
3010 TALLOC_CTX *mem_ctx)
3012 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
3015 /*******************************************************************
3016 * fill a notify_info_data with the printername
3017 * but it doesn't exist, have to see what to do
3018 ********************************************************************/
3020 void spoolss_notify_driver_name(int snum,
3021 struct spoolss_Notify *data,
3022 print_queue_struct *queue,
3023 NT_PRINTER_INFO_LEVEL *printer,
3024 TALLOC_CTX *mem_ctx)
3026 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
3029 /*******************************************************************
3030 * fill a notify_info_data with the comment
3031 ********************************************************************/
3033 void spoolss_notify_comment(int snum,
3034 struct spoolss_Notify *data,
3035 print_queue_struct *queue,
3036 NT_PRINTER_INFO_LEVEL *printer,
3037 TALLOC_CTX *mem_ctx)
3041 if (*printer->info_2->comment == '\0') {
3042 p = lp_comment(snum);
3044 p = printer->info_2->comment;
3047 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
3050 /*******************************************************************
3051 * fill a notify_info_data with the comment
3052 * location = "Room 1, floor 2, building 3"
3053 ********************************************************************/
3055 void spoolss_notify_location(int snum,
3056 struct spoolss_Notify *data,
3057 print_queue_struct *queue,
3058 NT_PRINTER_INFO_LEVEL *printer,
3059 TALLOC_CTX *mem_ctx)
3061 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
3064 /*******************************************************************
3065 * fill a notify_info_data with the device mode
3066 * jfm:xxxx don't to it for know but that's a real problem !!!
3067 ********************************************************************/
3069 static void spoolss_notify_devmode(int snum,
3070 struct spoolss_Notify *data,
3071 print_queue_struct *queue,
3072 NT_PRINTER_INFO_LEVEL *printer,
3073 TALLOC_CTX *mem_ctx)
3075 /* for a dummy implementation we have to zero the fields */
3076 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
3079 /*******************************************************************
3080 * fill a notify_info_data with the separator file name
3081 ********************************************************************/
3083 void spoolss_notify_sepfile(int snum,
3084 struct spoolss_Notify *data,
3085 print_queue_struct *queue,
3086 NT_PRINTER_INFO_LEVEL *printer,
3087 TALLOC_CTX *mem_ctx)
3089 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
3092 /*******************************************************************
3093 * fill a notify_info_data with the print processor
3094 * jfm:xxxx return always winprint to indicate we don't do anything to it
3095 ********************************************************************/
3097 void spoolss_notify_print_processor(int snum,
3098 struct spoolss_Notify *data,
3099 print_queue_struct *queue,
3100 NT_PRINTER_INFO_LEVEL *printer,
3101 TALLOC_CTX *mem_ctx)
3103 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
3106 /*******************************************************************
3107 * fill a notify_info_data with the print processor options
3108 * jfm:xxxx send an empty string
3109 ********************************************************************/
3111 void spoolss_notify_parameters(int snum,
3112 struct spoolss_Notify *data,
3113 print_queue_struct *queue,
3114 NT_PRINTER_INFO_LEVEL *printer,
3115 TALLOC_CTX *mem_ctx)
3117 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
3120 /*******************************************************************
3121 * fill a notify_info_data with the data type
3122 * jfm:xxxx always send RAW as data type
3123 ********************************************************************/
3125 void spoolss_notify_datatype(int snum,
3126 struct spoolss_Notify *data,
3127 print_queue_struct *queue,
3128 NT_PRINTER_INFO_LEVEL *printer,
3129 TALLOC_CTX *mem_ctx)
3131 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
3134 /*******************************************************************
3135 * fill a notify_info_data with the security descriptor
3136 * jfm:xxxx send an null pointer to say no security desc
3137 * have to implement security before !
3138 ********************************************************************/
3140 static void spoolss_notify_security_desc(int snum,
3141 struct spoolss_Notify *data,
3142 print_queue_struct *queue,
3143 NT_PRINTER_INFO_LEVEL *printer,
3144 TALLOC_CTX *mem_ctx)
3146 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
3147 printer->info_2->secdesc_buf->sd_size,
3148 printer->info_2->secdesc_buf->sd);
3151 /*******************************************************************
3152 * fill a notify_info_data with the attributes
3153 * jfm:xxxx a samba printer is always shared
3154 ********************************************************************/
3156 void spoolss_notify_attributes(int snum,
3157 struct spoolss_Notify *data,
3158 print_queue_struct *queue,
3159 NT_PRINTER_INFO_LEVEL *printer,
3160 TALLOC_CTX *mem_ctx)
3162 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
3165 /*******************************************************************
3166 * fill a notify_info_data with the priority
3167 ********************************************************************/
3169 static void spoolss_notify_priority(int snum,
3170 struct spoolss_Notify *data,
3171 print_queue_struct *queue,
3172 NT_PRINTER_INFO_LEVEL *printer,
3173 TALLOC_CTX *mem_ctx)
3175 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
3178 /*******************************************************************
3179 * fill a notify_info_data with the default priority
3180 ********************************************************************/
3182 static void spoolss_notify_default_priority(int snum,
3183 struct spoolss_Notify *data,
3184 print_queue_struct *queue,
3185 NT_PRINTER_INFO_LEVEL *printer,
3186 TALLOC_CTX *mem_ctx)
3188 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
3191 /*******************************************************************
3192 * fill a notify_info_data with the start time
3193 ********************************************************************/
3195 static void spoolss_notify_start_time(int snum,
3196 struct spoolss_Notify *data,
3197 print_queue_struct *queue,
3198 NT_PRINTER_INFO_LEVEL *printer,
3199 TALLOC_CTX *mem_ctx)
3201 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
3204 /*******************************************************************
3205 * fill a notify_info_data with the until time
3206 ********************************************************************/
3208 static void spoolss_notify_until_time(int snum,
3209 struct spoolss_Notify *data,
3210 print_queue_struct *queue,
3211 NT_PRINTER_INFO_LEVEL *printer,
3212 TALLOC_CTX *mem_ctx)
3214 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
3217 /*******************************************************************
3218 * fill a notify_info_data with the status
3219 ********************************************************************/
3221 static void spoolss_notify_status(int snum,
3222 struct spoolss_Notify *data,
3223 print_queue_struct *queue,
3224 NT_PRINTER_INFO_LEVEL *printer,
3225 TALLOC_CTX *mem_ctx)
3227 print_status_struct status;
3229 print_queue_length(snum, &status);
3230 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
3233 /*******************************************************************
3234 * fill a notify_info_data with the number of jobs queued
3235 ********************************************************************/
3237 void spoolss_notify_cjobs(int snum,
3238 struct spoolss_Notify *data,
3239 print_queue_struct *queue,
3240 NT_PRINTER_INFO_LEVEL *printer,
3241 TALLOC_CTX *mem_ctx)
3243 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
3246 /*******************************************************************
3247 * fill a notify_info_data with the average ppm
3248 ********************************************************************/
3250 static void spoolss_notify_average_ppm(int snum,
3251 struct spoolss_Notify *data,
3252 print_queue_struct *queue,
3253 NT_PRINTER_INFO_LEVEL *printer,
3254 TALLOC_CTX *mem_ctx)
3256 /* always respond 8 pages per minutes */
3257 /* a little hard ! */
3258 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
3261 /*******************************************************************
3262 * fill a notify_info_data with username
3263 ********************************************************************/
3265 static void spoolss_notify_username(int snum,
3266 struct spoolss_Notify *data,
3267 print_queue_struct *queue,
3268 NT_PRINTER_INFO_LEVEL *printer,
3269 TALLOC_CTX *mem_ctx)
3271 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
3274 /*******************************************************************
3275 * fill a notify_info_data with job status
3276 ********************************************************************/
3278 static void spoolss_notify_job_status(int snum,
3279 struct spoolss_Notify *data,
3280 print_queue_struct *queue,
3281 NT_PRINTER_INFO_LEVEL *printer,
3282 TALLOC_CTX *mem_ctx)
3284 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
3287 /*******************************************************************
3288 * fill a notify_info_data with job name
3289 ********************************************************************/
3291 static void spoolss_notify_job_name(int snum,
3292 struct spoolss_Notify *data,
3293 print_queue_struct *queue,
3294 NT_PRINTER_INFO_LEVEL *printer,
3295 TALLOC_CTX *mem_ctx)
3297 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
3300 /*******************************************************************
3301 * fill a notify_info_data with job status
3302 ********************************************************************/
3304 static void spoolss_notify_job_status_string(int snum,
3305 struct spoolss_Notify *data,
3306 print_queue_struct *queue,
3307 NT_PRINTER_INFO_LEVEL *printer,
3308 TALLOC_CTX *mem_ctx)
3311 * Now we're returning job status codes we just return a "" here. JRA.
3316 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3319 switch (queue->status) {
3324 p = ""; /* NT provides the paused string */
3333 #endif /* NO LONGER NEEDED. */
3335 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3338 /*******************************************************************
3339 * fill a notify_info_data with job time
3340 ********************************************************************/
3342 static void spoolss_notify_job_time(int snum,
3343 struct spoolss_Notify *data,
3344 print_queue_struct *queue,
3345 NT_PRINTER_INFO_LEVEL *printer,
3346 TALLOC_CTX *mem_ctx)
3348 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3351 /*******************************************************************
3352 * fill a notify_info_data with job size
3353 ********************************************************************/
3355 static void spoolss_notify_job_size(int snum,
3356 struct spoolss_Notify *data,
3357 print_queue_struct *queue,
3358 NT_PRINTER_INFO_LEVEL *printer,
3359 TALLOC_CTX *mem_ctx)
3361 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3364 /*******************************************************************
3365 * fill a notify_info_data with page info
3366 ********************************************************************/
3367 static void spoolss_notify_total_pages(int snum,
3368 struct spoolss_Notify *data,
3369 print_queue_struct *queue,
3370 NT_PRINTER_INFO_LEVEL *printer,
3371 TALLOC_CTX *mem_ctx)
3373 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3376 /*******************************************************************
3377 * fill a notify_info_data with pages printed info.
3378 ********************************************************************/
3379 static void spoolss_notify_pages_printed(int snum,
3380 struct spoolss_Notify *data,
3381 print_queue_struct *queue,
3382 NT_PRINTER_INFO_LEVEL *printer,
3383 TALLOC_CTX *mem_ctx)
3385 /* Add code when back-end tracks this */
3386 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3389 /*******************************************************************
3390 Fill a notify_info_data with job position.
3391 ********************************************************************/
3393 static void spoolss_notify_job_position(int snum,
3394 struct spoolss_Notify *data,
3395 print_queue_struct *queue,
3396 NT_PRINTER_INFO_LEVEL *printer,
3397 TALLOC_CTX *mem_ctx)
3399 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3402 /*******************************************************************
3403 Fill a notify_info_data with submitted time.
3404 ********************************************************************/
3406 static void spoolss_notify_submitted_time(int snum,
3407 struct spoolss_Notify *data,
3408 print_queue_struct *queue,
3409 NT_PRINTER_INFO_LEVEL *printer,
3410 TALLOC_CTX *mem_ctx)
3412 data->data.string.string = NULL;
3413 data->data.string.size = 0;
3415 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3416 &data->data.string.string,
3417 &data->data.string.size);
3421 struct s_notify_info_data_table
3423 enum spoolss_NotifyType type;
3424 enum spoolss_Field field;
3426 enum spoolss_NotifyTable variable_type;
3427 void (*fn) (int snum, struct spoolss_Notify *data,
3428 print_queue_struct *queue,
3429 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3432 /* A table describing the various print notification constants and
3433 whether the notification data is a pointer to a variable sized
3434 buffer, a one value uint32 or a two value uint32. */
3436 static const struct s_notify_info_data_table notify_info_data_table[] =
3438 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3439 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3440 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3441 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3442 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3443 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3444 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3445 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3446 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3447 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3448 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3449 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3450 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3451 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3452 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3453 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3454 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3455 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3456 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3457 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3458 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3459 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3460 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3461 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3462 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3463 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3464 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3465 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3466 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3467 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3468 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3469 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3470 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3471 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3472 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3473 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3474 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3475 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3476 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3477 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3478 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3479 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3480 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3481 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3482 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3483 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3484 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3485 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3486 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3487 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3490 /*******************************************************************
3491 Return the variable_type of info_data structure.
3492 ********************************************************************/
3494 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3495 enum spoolss_Field field)
3499 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3500 if ( (notify_info_data_table[i].type == type) &&
3501 (notify_info_data_table[i].field == field) ) {
3502 return notify_info_data_table[i].variable_type;
3506 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3511 /****************************************************************************
3512 ****************************************************************************/
3514 static bool search_notify(uint16 type, uint16 field, int *value)
3518 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3519 if (notify_info_data_table[i].type == type &&
3520 notify_info_data_table[i].field == field &&
3521 notify_info_data_table[i].fn != NULL) {
3530 /****************************************************************************
3531 ****************************************************************************/
3533 void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id)
3535 info_data->type = type;
3536 info_data->field = field;
3537 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3538 info_data->job_id = id;
3541 /*******************************************************************
3543 * fill a notify_info struct with info asked
3545 ********************************************************************/
3547 static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spoolss_NotifyInfo *info, int
3548 snum, SPOOL_NOTIFY_OPTION_TYPE
3549 *option_type, uint32 id,
3550 TALLOC_CTX *mem_ctx)
3556 struct spoolss_Notify *current_data;
3557 NT_PRINTER_INFO_LEVEL *printer = NULL;
3558 print_queue_struct *queue=NULL;
3560 type=option_type->type;
3562 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3563 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3564 option_type->count, lp_servicename(snum)));
3566 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3569 for(field_num=0; field_num<option_type->count; field_num++) {
3570 field = option_type->fields[field_num];
3572 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3574 if (!search_notify(type, field, &j) )
3577 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3578 struct spoolss_Notify,
3580 if (info->notifies == NULL) {
3581 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3582 free_a_printer(&printer, 2);
3586 current_data = &info->notifies[info->count];
3588 construct_info_data(current_data, type, field, id);
3590 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3591 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3593 notify_info_data_table[j].fn(snum, current_data, queue,
3599 free_a_printer(&printer, 2);
3603 /*******************************************************************
3605 * fill a notify_info struct with info asked
3607 ********************************************************************/
3609 static bool construct_notify_jobs_info(print_queue_struct *queue,
3610 struct spoolss_NotifyInfo *info,
3611 NT_PRINTER_INFO_LEVEL *printer,
3612 int snum, SPOOL_NOTIFY_OPTION_TYPE
3613 *option_type, uint32 id,
3614 TALLOC_CTX *mem_ctx)
3620 struct spoolss_Notify *current_data;
3622 DEBUG(4,("construct_notify_jobs_info\n"));
3624 type = option_type->type;
3626 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3627 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3628 option_type->count));
3630 for(field_num=0; field_num<option_type->count; field_num++) {
3631 field = option_type->fields[field_num];
3633 if (!search_notify(type, field, &j) )
3636 info->notifies = TALLOC_REALLOC_ARRAY(info, info->notifies,
3637 struct spoolss_Notify,
3639 if (info->notifies == NULL) {
3640 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3644 current_data=&(info->notifies[info->count]);
3646 construct_info_data(current_data, type, field, id);
3647 notify_info_data_table[j].fn(snum, current_data, queue,
3656 * JFM: The enumeration is not that simple, it's even non obvious.
3658 * let's take an example: I want to monitor the PRINTER SERVER for
3659 * the printer's name and the number of jobs currently queued.
3660 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3661 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3663 * I have 3 printers on the back of my server.
3665 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3668 * 1 printer 1 name 1
3669 * 2 printer 1 cjob 1
3670 * 3 printer 2 name 2
3671 * 4 printer 2 cjob 2
3672 * 5 printer 3 name 3
3673 * 6 printer 3 name 3
3675 * that's the print server case, the printer case is even worse.
3678 /*******************************************************************
3680 * enumerate all printers on the printserver
3681 * fill a notify_info struct with info asked
3683 ********************************************************************/
3685 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3686 struct spoolss_NotifyInfo *info,
3687 TALLOC_CTX *mem_ctx)
3690 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3691 int n_services=lp_numservices();
3693 SPOOL_NOTIFY_OPTION *option;
3694 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3696 DEBUG(4,("printserver_notify_info\n"));
3701 option=Printer->notify.option;
3704 info->notifies = NULL;
3707 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3708 sending a ffpcn() request first */
3713 for (i=0; i<option->count; i++) {
3714 option_type=&(option->ctr.type[i]);
3716 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3719 for (snum=0; snum<n_services; snum++)
3721 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3722 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3728 * Debugging information, don't delete.
3731 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3732 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3733 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3735 for (i=0; i<info->count; i++) {
3736 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3737 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3738 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3745 /*******************************************************************
3747 * fill a notify_info struct with info asked
3749 ********************************************************************/
3751 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info,
3752 TALLOC_CTX *mem_ctx)
3755 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3758 SPOOL_NOTIFY_OPTION *option;
3759 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3761 print_queue_struct *queue=NULL;
3762 print_status_struct status;
3764 DEBUG(4,("printer_notify_info\n"));
3769 option=Printer->notify.option;
3773 info->notifies = NULL;
3776 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3777 sending a ffpcn() request first */
3782 get_printer_snum(p, hnd, &snum, NULL);
3784 for (i=0; i<option->count; i++) {
3785 option_type=&option->ctr.type[i];
3787 switch ( option_type->type ) {
3788 case PRINTER_NOTIFY_TYPE:
3789 if(construct_notify_printer_info(Printer, info, snum,
3795 case JOB_NOTIFY_TYPE: {
3796 NT_PRINTER_INFO_LEVEL *printer = NULL;
3798 count = print_queue_status(snum, &queue, &status);
3800 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3803 for (j=0; j<count; j++) {
3804 construct_notify_jobs_info(&queue[j], info,
3811 free_a_printer(&printer, 2);
3821 * Debugging information, don't delete.
3824 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3825 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3826 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3828 for (i=0; i<info->count; i++) {
3829 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3830 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3831 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3837 /****************************************************************
3838 _spoolss_RouterRefreshPrinterChangeNotify
3839 ****************************************************************/
3841 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
3842 struct spoolss_RouterRefreshPrinterChangeNotify *r)
3844 POLICY_HND *handle = r->in.handle;
3845 struct spoolss_NotifyInfo *info;
3847 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3848 WERROR result = WERR_BADFID;
3850 /* we always have a spoolss_NotifyInfo struct */
3851 info = talloc_zero(p->mem_ctx, struct spoolss_NotifyInfo);
3853 result = WERR_NOMEM;
3857 *r->out.info = info;
3860 DEBUG(2,("_spoolss_RouterRefreshPrinterChangeNotify: "
3861 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
3865 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3868 * We are now using the change value, and
3869 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3870 * I don't have a global notification system, I'm sending back all the
3871 * informations even when _NOTHING_ has changed.
3874 /* We need to keep track of the change value to send back in
3875 RRPCN replies otherwise our updates are ignored. */
3877 Printer->notify.fnpcn = True;
3879 if (Printer->notify.client_connected) {
3880 DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: "
3881 "Saving change value in request [%x]\n",
3883 Printer->notify.change = r->in.change_low;
3886 /* just ignore the SPOOL_NOTIFY_OPTION */
3888 switch (Printer->printer_type) {
3890 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3893 case SPLHND_PRINTER:
3894 result = printer_notify_info(p, handle, info, p->mem_ctx);
3898 Printer->notify.fnpcn = False;
3904 /********************************************************************
3905 * construct_printer_info_0
3906 * fill a printer_info_0 struct
3907 ********************************************************************/
3909 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3911 char *chaine = NULL;
3913 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3914 counter_printer_0 *session_counter;
3915 uint32 global_counter;
3918 print_status_struct status;
3919 TALLOC_CTX *ctx = talloc_tos();
3921 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3924 init_unistr(&printer->printername, ntprinter->info_2->printername);
3926 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3928 free_a_printer(&ntprinter,2);
3932 count = print_queue_length(snum, &status);
3934 /* check if we already have a counter for this printer */
3935 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3936 if (session_counter->snum == snum)
3940 init_unistr(&printer->servername, chaine);
3942 /* it's the first time, add it to the list */
3943 if (session_counter==NULL) {
3944 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3945 free_a_printer(&ntprinter, 2);
3948 ZERO_STRUCTP(session_counter);
3949 session_counter->snum=snum;
3950 session_counter->counter=0;
3951 DLIST_ADD(counter_list, session_counter);
3955 session_counter->counter++;
3958 * the global_counter should be stored in a TDB as it's common to all the clients
3959 * and should be zeroed on samba startup
3961 global_counter=session_counter->counter;
3962 printer->cjobs = count;
3963 printer->total_jobs = 0;
3964 printer->total_bytes = 0;
3966 setuptime = (time_t)ntprinter->info_2->setuptime;
3967 t=gmtime(&setuptime);
3969 printer->year = t->tm_year+1900;
3970 printer->month = t->tm_mon+1;
3971 printer->dayofweek = t->tm_wday;
3972 printer->day = t->tm_mday;
3973 printer->hour = t->tm_hour;
3974 printer->minute = t->tm_min;
3975 printer->second = t->tm_sec;
3976 printer->milliseconds = 0;
3978 printer->global_counter = global_counter;
3979 printer->total_pages = 0;
3981 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3982 printer->major_version = 0x0005; /* NT 5 */
3983 printer->build_version = 0x0893; /* build 2195 */
3985 printer->unknown7 = 0x1;
3986 printer->unknown8 = 0x0;
3987 printer->unknown9 = 0x0;
3988 printer->session_counter = session_counter->counter;
3989 printer->unknown11 = 0x0;
3990 printer->printer_errors = 0x0; /* number of print failure */
3991 printer->unknown13 = 0x0;
3992 printer->unknown14 = 0x1;
3993 printer->unknown15 = 0x024a; /* 586 Pentium ? */
3994 printer->unknown16 = 0x0;
3995 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3996 printer->unknown18 = 0x0;
3997 printer->status = nt_printq_status(status.status);
3998 printer->unknown20 = 0x0;
3999 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
4000 printer->unknown22 = 0x0;
4001 printer->unknown23 = 0x6; /* 6 ???*/
4002 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
4003 printer->unknown25 = 0;
4004 printer->unknown26 = 0;
4005 printer->unknown27 = 0;
4006 printer->unknown28 = 0;
4007 printer->unknown29 = 0;
4009 free_a_printer(&ntprinter,2);
4013 /********************************************************************
4014 * construct_printer_info_1
4015 * fill a printer_info_1 struct
4016 ********************************************************************/
4017 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4019 char *chaine = NULL;
4020 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4021 TALLOC_CTX *ctx = talloc_tos();
4023 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4026 printer->flags=flags;
4028 if (*ntprinter->info_2->comment == '\0') {
4029 init_unistr(&printer->comment, lp_comment(snum));
4030 chaine = talloc_asprintf(ctx,
4031 "%s,%s,%s", ntprinter->info_2->printername,
4032 ntprinter->info_2->drivername, lp_comment(snum));
4035 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4036 chaine = talloc_asprintf(ctx,
4037 "%s,%s,%s", ntprinter->info_2->printername,
4038 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4042 free_a_printer(&ntprinter,2);
4046 init_unistr(&printer->description, chaine);
4047 init_unistr(&printer->name, ntprinter->info_2->printername);
4049 free_a_printer(&ntprinter,2);
4054 /****************************************************************************
4055 Free a DEVMODE struct.
4056 ****************************************************************************/
4058 static void free_dev_mode(DEVICEMODE *dev)
4063 SAFE_FREE(dev->dev_private);
4068 /****************************************************************************
4069 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4070 should be valid upon entry
4071 ****************************************************************************/
4073 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4075 if ( !devmode || !ntdevmode )
4078 init_unistr(&devmode->devicename, ntdevmode->devicename);
4080 init_unistr(&devmode->formname, ntdevmode->formname);
4082 devmode->specversion = ntdevmode->specversion;
4083 devmode->driverversion = ntdevmode->driverversion;
4084 devmode->size = ntdevmode->size;
4085 devmode->driverextra = ntdevmode->driverextra;
4086 devmode->fields = ntdevmode->fields;
4088 devmode->orientation = ntdevmode->orientation;
4089 devmode->papersize = ntdevmode->papersize;
4090 devmode->paperlength = ntdevmode->paperlength;
4091 devmode->paperwidth = ntdevmode->paperwidth;
4092 devmode->scale = ntdevmode->scale;
4093 devmode->copies = ntdevmode->copies;
4094 devmode->defaultsource = ntdevmode->defaultsource;
4095 devmode->printquality = ntdevmode->printquality;
4096 devmode->color = ntdevmode->color;
4097 devmode->duplex = ntdevmode->duplex;
4098 devmode->yresolution = ntdevmode->yresolution;
4099 devmode->ttoption = ntdevmode->ttoption;
4100 devmode->collate = ntdevmode->collate;
4101 devmode->icmmethod = ntdevmode->icmmethod;
4102 devmode->icmintent = ntdevmode->icmintent;
4103 devmode->mediatype = ntdevmode->mediatype;
4104 devmode->dithertype = ntdevmode->dithertype;
4106 if (ntdevmode->nt_dev_private != NULL) {
4107 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4114 /****************************************************************************
4115 Create a DEVMODE struct. Returns malloced memory.
4116 ****************************************************************************/
4118 DEVICEMODE *construct_dev_mode(const char *servicename)
4120 NT_PRINTER_INFO_LEVEL *printer = NULL;
4121 DEVICEMODE *devmode = NULL;
4123 DEBUG(7,("construct_dev_mode\n"));
4125 DEBUGADD(8,("getting printer characteristics\n"));
4127 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4130 if ( !printer->info_2->devmode ) {
4131 DEBUG(5, ("BONG! There was no device mode!\n"));
4135 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4136 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4140 ZERO_STRUCTP(devmode);
4142 DEBUGADD(8,("loading DEVICEMODE\n"));
4144 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4145 free_dev_mode( devmode );
4150 free_a_printer(&printer,2);
4155 /********************************************************************
4156 * construct_printer_info_2
4157 * fill a printer_info_2 struct
4158 ********************************************************************/
4160 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4163 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4165 print_status_struct status;
4167 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4170 count = print_queue_length(snum, &status);
4172 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4173 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4174 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4175 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4176 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4178 if (*ntprinter->info_2->comment == '\0')
4179 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4181 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4183 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4184 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4185 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4186 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4187 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4189 printer->attributes = ntprinter->info_2->attributes;
4191 printer->priority = ntprinter->info_2->priority; /* priority */
4192 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4193 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4194 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4195 printer->status = nt_printq_status(status.status); /* status */
4196 printer->cjobs = count; /* jobs */
4197 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4199 if ( !(printer->devmode = construct_dev_mode(
4200 lp_const_servicename(snum))) )
4201 DEBUG(8, ("Returning NULL Devicemode!\n"));
4203 printer->secdesc = NULL;
4205 if ( ntprinter->info_2->secdesc_buf
4206 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4208 /* don't use talloc_steal() here unless you do a deep steal of all
4209 the SEC_DESC members */
4211 printer->secdesc = dup_sec_desc( talloc_tos(),
4212 ntprinter->info_2->secdesc_buf->sd );
4215 free_a_printer(&ntprinter, 2);
4220 /********************************************************************
4221 * construct_printer_info_3
4222 * fill a printer_info_3 struct
4223 ********************************************************************/
4225 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4227 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4228 PRINTER_INFO_3 *printer = NULL;
4230 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4234 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4235 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4236 free_a_printer(&ntprinter, 2);
4240 ZERO_STRUCTP(printer);
4242 /* These are the components of the SD we are returning. */
4244 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4245 /* don't use talloc_steal() here unless you do a deep steal of all
4246 the SEC_DESC members */
4248 printer->secdesc = dup_sec_desc( talloc_tos(),
4249 ntprinter->info_2->secdesc_buf->sd );
4252 free_a_printer(&ntprinter, 2);
4254 *pp_printer = printer;
4258 /********************************************************************
4259 * construct_printer_info_4
4260 * fill a printer_info_4 struct
4261 ********************************************************************/
4263 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4265 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4267 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4270 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4271 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4272 printer->attributes = ntprinter->info_2->attributes;
4274 free_a_printer(&ntprinter, 2);
4278 /********************************************************************
4279 * construct_printer_info_5
4280 * fill a printer_info_5 struct
4281 ********************************************************************/
4283 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4285 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4287 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4290 init_unistr(&printer->printername, ntprinter->info_2->printername);
4291 init_unistr(&printer->portname, ntprinter->info_2->portname);
4292 printer->attributes = ntprinter->info_2->attributes;
4294 /* these two are not used by NT+ according to MSDN */
4296 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4297 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4299 free_a_printer(&ntprinter, 2);
4304 /********************************************************************
4305 * construct_printer_info_6
4306 * fill a printer_info_6 struct
4307 ********************************************************************/
4309 static bool construct_printer_info_6(Printer_entry *print_hnd,
4310 PRINTER_INFO_6 *printer,
4313 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4315 print_status_struct status;
4317 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4318 lp_const_servicename(snum))))
4321 count = print_queue_length(snum, &status);
4323 printer->status = nt_printq_status(status.status);
4325 free_a_printer(&ntprinter, 2);
4330 /********************************************************************
4331 * construct_printer_info_7
4332 * fill a printer_info_7 struct
4333 ********************************************************************/
4335 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4337 char *guid_str = NULL;
4340 if (is_printer_published(print_hnd, snum, &guid)) {
4341 if (asprintf(&guid_str, "{%s}",
4342 GUID_string(talloc_tos(), &guid)) == -1) {
4345 strupper_m(guid_str);
4346 init_unistr(&printer->guid, guid_str);
4347 SAFE_FREE(guid_str);
4348 printer->action = SPOOL_DS_PUBLISH;
4350 init_unistr(&printer->guid, "");
4351 printer->action = SPOOL_DS_UNPUBLISH;
4357 /********************************************************************
4358 Spoolss_enumprinters.
4359 ********************************************************************/
4361 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4365 int n_services=lp_numservices();
4366 PRINTER_INFO_1 *printers=NULL;
4367 PRINTER_INFO_1 current_prt;
4368 WERROR result = WERR_OK;
4370 DEBUG(4,("enum_all_printers_info_1\n"));
4372 for (snum=0; snum<n_services; snum++) {
4373 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4374 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4376 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4377 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4378 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4382 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4384 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4390 /* check the required size. */
4391 for (i=0; i<*returned; i++)
4392 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4394 if (*needed > offered) {
4395 result = WERR_INSUFFICIENT_BUFFER;
4399 if (!rpcbuf_alloc_size(buffer, *needed)) {
4400 result = WERR_NOMEM;
4404 /* fill the buffer with the structures */
4405 for (i=0; i<*returned; i++)
4406 smb_io_printer_info_1("", buffer, &printers[i], 0);
4411 SAFE_FREE(printers);
4413 if ( !W_ERROR_IS_OK(result) )
4419 /********************************************************************
4420 enum_all_printers_info_1_local.
4421 *********************************************************************/
4423 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4425 DEBUG(4,("enum_all_printers_info_1_local\n"));
4427 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4430 /********************************************************************
4431 enum_all_printers_info_1_name.
4432 *********************************************************************/
4434 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4438 DEBUG(4,("enum_all_printers_info_1_name\n"));
4440 if ((name[0] == '\\') && (name[1] == '\\'))
4443 if (is_myname_or_ipaddr(s)) {
4444 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4447 return WERR_INVALID_NAME;
4450 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4451 /********************************************************************
4452 enum_all_printers_info_1_remote.
4453 *********************************************************************/
4455 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4457 PRINTER_INFO_1 *printer;
4458 fstring printername;
4461 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4462 WERROR result = WERR_OK;
4464 /* JFM: currently it's more a place holder than anything else.
4465 * In the spooler world there is a notion of server registration.
4466 * the print servers are registered on the PDC (in the same domain)
4468 * We should have a TDB here. The registration is done thru an
4469 * undocumented RPC call.
4472 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4477 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4478 slprintf(desc, sizeof(desc)-1,"%s", name);
4479 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4481 init_unistr(&printer->description, desc);
4482 init_unistr(&printer->name, printername);
4483 init_unistr(&printer->comment, comment);
4484 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4486 /* check the required size. */
4487 *needed += spoolss_size_printer_info_1(printer);
4489 if (*needed > offered) {
4490 result = WERR_INSUFFICIENT_BUFFER;
4494 if (!rpcbuf_alloc_size(buffer, *needed)) {
4495 result = WERR_NOMEM;
4499 /* fill the buffer with the structures */
4500 smb_io_printer_info_1("", buffer, printer, 0);
4506 if ( !W_ERROR_IS_OK(result) )
4514 /********************************************************************
4515 enum_all_printers_info_1_network.
4516 *********************************************************************/
4518 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4522 DEBUG(4,("enum_all_printers_info_1_network\n"));
4524 /* If we respond to a enum_printers level 1 on our name with flags
4525 set to PRINTER_ENUM_REMOTE with a list of printers then these
4526 printers incorrectly appear in the APW browse list.
4527 Specifically the printers for the server appear at the workgroup
4528 level where all the other servers in the domain are
4529 listed. Windows responds to this call with a
4530 WERR_CAN_NOT_COMPLETE so we should do the same. */
4532 if (name[0] == '\\' && name[1] == '\\')
4535 if (is_myname_or_ipaddr(s))
4536 return WERR_CAN_NOT_COMPLETE;
4538 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4541 /********************************************************************
4542 * api_spoolss_enumprinters
4544 * called from api_spoolss_enumprinters (see this to understand)
4545 ********************************************************************/
4547 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4551 int n_services=lp_numservices();
4552 PRINTER_INFO_2 *printers=NULL;
4553 PRINTER_INFO_2 current_prt;
4554 WERROR result = WERR_OK;
4558 for (snum=0; snum<n_services; snum++) {
4559 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4560 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4562 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4563 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4564 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4569 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4571 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4578 /* check the required size. */
4579 for (i=0; i<*returned; i++)
4580 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4582 if (*needed > offered) {
4583 result = WERR_INSUFFICIENT_BUFFER;
4587 if (!rpcbuf_alloc_size(buffer, *needed)) {
4588 result = WERR_NOMEM;
4592 /* fill the buffer with the structures */
4593 for (i=0; i<*returned; i++)
4594 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4599 for (i=0; i<*returned; i++)
4600 free_devmode(printers[i].devmode);
4602 SAFE_FREE(printers);
4604 if ( !W_ERROR_IS_OK(result) )
4610 /********************************************************************
4611 * handle enumeration of printers at level 1
4612 ********************************************************************/
4614 static WERROR enumprinters_level1( uint32 flags, fstring name,
4615 RPC_BUFFER *buffer, uint32 offered,
4616 uint32 *needed, uint32 *returned)
4618 /* Not all the flags are equals */
4620 if (flags & PRINTER_ENUM_LOCAL)
4621 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4623 if (flags & PRINTER_ENUM_NAME)
4624 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4626 #if 0 /* JERRY - disabled for now */
4627 if (flags & PRINTER_ENUM_REMOTE)
4628 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4631 if (flags & PRINTER_ENUM_NETWORK)
4632 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4634 return WERR_OK; /* NT4sp5 does that */
4637 /********************************************************************
4638 * handle enumeration of printers at level 2
4639 ********************************************************************/
4641 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4642 RPC_BUFFER *buffer, uint32 offered,
4643 uint32 *needed, uint32 *returned)
4645 if (flags & PRINTER_ENUM_LOCAL) {
4646 return enum_all_printers_info_2(buffer, offered, needed, returned);
4649 if (flags & PRINTER_ENUM_NAME) {
4650 if (is_myname_or_ipaddr(canon_servername(servername)))
4651 return enum_all_printers_info_2(buffer, offered, needed, returned);
4653 return WERR_INVALID_NAME;
4656 if (flags & PRINTER_ENUM_REMOTE)
4657 return WERR_UNKNOWN_LEVEL;
4662 /********************************************************************
4663 * handle enumeration of printers at level 5
4664 ********************************************************************/
4666 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4667 RPC_BUFFER *buffer, uint32 offered,
4668 uint32 *needed, uint32 *returned)
4670 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4674 /********************************************************************
4675 * api_spoolss_enumprinters
4677 * called from api_spoolss_enumprinters (see this to understand)
4678 ********************************************************************/
4680 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4682 uint32 flags = q_u->flags;
4683 UNISTR2 *servername = &q_u->servername;
4684 uint32 level = q_u->level;
4685 RPC_BUFFER *buffer = NULL;
4686 uint32 offered = q_u->offered;
4687 uint32 *needed = &r_u->needed;
4688 uint32 *returned = &r_u->returned;
4692 /* that's an [in out] buffer */
4694 if (!q_u->buffer && (offered!=0)) {
4695 return WERR_INVALID_PARAM;
4698 if (offered > MAX_RPC_DATA_SIZE) {
4699 return WERR_INVALID_PARAM;
4702 rpcbuf_move(q_u->buffer, &r_u->buffer);
4703 buffer = r_u->buffer;
4705 DEBUG(4,("_spoolss_enumprinters\n"));
4712 * flags==PRINTER_ENUM_NAME
4713 * if name=="" then enumerates all printers
4714 * if name!="" then enumerate the printer
4715 * flags==PRINTER_ENUM_REMOTE
4716 * name is NULL, enumerate printers
4717 * Level 2: name!="" enumerates printers, name can't be NULL
4718 * Level 3: doesn't exist
4719 * Level 4: does a local registry lookup
4720 * Level 5: same as Level 2
4723 unistr2_to_ascii(name, servername, sizeof(name));
4728 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4730 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4732 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4737 return WERR_UNKNOWN_LEVEL;
4740 /****************************************************************************
4741 ****************************************************************************/
4743 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4745 PRINTER_INFO_0 *printer=NULL;
4746 WERROR result = WERR_OK;
4748 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4751 construct_printer_info_0(print_hnd, printer, snum);
4753 /* check the required size. */
4754 *needed += spoolss_size_printer_info_0(printer);
4756 if (*needed > offered) {
4757 result = WERR_INSUFFICIENT_BUFFER;
4761 if (!rpcbuf_alloc_size(buffer, *needed)) {
4762 result = WERR_NOMEM;
4766 /* fill the buffer with the structures */
4767 smb_io_printer_info_0("", buffer, printer, 0);
4777 /****************************************************************************
4778 ****************************************************************************/
4780 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4782 PRINTER_INFO_1 *printer=NULL;
4783 WERROR result = WERR_OK;
4785 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4788 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4790 /* check the required size. */
4791 *needed += spoolss_size_printer_info_1(printer);
4793 if (*needed > offered) {
4794 result = WERR_INSUFFICIENT_BUFFER;
4798 if (!rpcbuf_alloc_size(buffer, *needed)) {
4799 result = WERR_NOMEM;
4803 /* fill the buffer with the structures */
4804 smb_io_printer_info_1("", buffer, printer, 0);
4813 /****************************************************************************
4814 ****************************************************************************/
4816 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4818 PRINTER_INFO_2 *printer=NULL;
4819 WERROR result = WERR_OK;
4821 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4824 construct_printer_info_2(print_hnd, printer, snum);
4826 /* check the required size. */
4827 *needed += spoolss_size_printer_info_2(printer);
4829 if (*needed > offered) {
4830 result = WERR_INSUFFICIENT_BUFFER;
4834 if (!rpcbuf_alloc_size(buffer, *needed)) {
4835 result = WERR_NOMEM;
4839 /* fill the buffer with the structures */
4840 if (!smb_io_printer_info_2("", buffer, printer, 0))
4841 result = WERR_NOMEM;
4845 free_printer_info_2(printer);
4850 /****************************************************************************
4851 ****************************************************************************/
4853 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4855 PRINTER_INFO_3 *printer=NULL;
4856 WERROR result = WERR_OK;
4858 if (!construct_printer_info_3(print_hnd, &printer, snum))
4861 /* check the required size. */
4862 *needed += spoolss_size_printer_info_3(printer);
4864 if (*needed > offered) {
4865 result = WERR_INSUFFICIENT_BUFFER;
4869 if (!rpcbuf_alloc_size(buffer, *needed)) {
4870 result = WERR_NOMEM;
4874 /* fill the buffer with the structures */
4875 smb_io_printer_info_3("", buffer, printer, 0);
4879 free_printer_info_3(printer);
4884 /****************************************************************************
4885 ****************************************************************************/
4887 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4889 PRINTER_INFO_4 *printer=NULL;
4890 WERROR result = WERR_OK;
4892 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4895 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4900 /* check the required size. */
4901 *needed += spoolss_size_printer_info_4(printer);
4903 if (*needed > offered) {
4904 result = WERR_INSUFFICIENT_BUFFER;
4908 if (!rpcbuf_alloc_size(buffer, *needed)) {
4909 result = WERR_NOMEM;
4913 /* fill the buffer with the structures */
4914 smb_io_printer_info_4("", buffer, printer, 0);
4918 free_printer_info_4(printer);
4923 /****************************************************************************
4924 ****************************************************************************/
4926 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4928 PRINTER_INFO_5 *printer=NULL;
4929 WERROR result = WERR_OK;
4931 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4934 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4935 free_printer_info_5(printer);
4939 /* check the required size. */
4940 *needed += spoolss_size_printer_info_5(printer);
4942 if (*needed > offered) {
4943 result = WERR_INSUFFICIENT_BUFFER;
4947 if (!rpcbuf_alloc_size(buffer, *needed)) {
4948 result = WERR_NOMEM;
4952 /* fill the buffer with the structures */
4953 smb_io_printer_info_5("", buffer, printer, 0);
4957 free_printer_info_5(printer);
4962 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4964 RPC_BUFFER *buffer, uint32 offered,
4967 PRINTER_INFO_6 *printer;
4968 WERROR result = WERR_OK;
4970 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4974 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4975 free_printer_info_6(printer);
4979 /* check the required size. */
4980 *needed += spoolss_size_printer_info_6(printer);
4982 if (*needed > offered) {
4983 result = WERR_INSUFFICIENT_BUFFER;
4987 if (!rpcbuf_alloc_size(buffer, *needed)) {
4988 result = WERR_NOMEM;
4992 /* fill the buffer with the structures */
4993 smb_io_printer_info_6("", buffer, printer, 0);
4997 free_printer_info_6(printer);
5002 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5004 PRINTER_INFO_7 *printer=NULL;
5005 WERROR result = WERR_OK;
5007 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
5010 if (!construct_printer_info_7(print_hnd, printer, snum)) {
5011 result = WERR_NOMEM;
5015 /* check the required size. */
5016 *needed += spoolss_size_printer_info_7(printer);
5018 if (*needed > offered) {
5019 result = WERR_INSUFFICIENT_BUFFER;
5023 if (!rpcbuf_alloc_size(buffer, *needed)) {
5024 result = WERR_NOMEM;
5029 /* fill the buffer with the structures */
5030 smb_io_printer_info_7("", buffer, printer, 0);
5034 free_printer_info_7(printer);
5039 /****************************************************************************
5040 ****************************************************************************/
5042 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5044 POLICY_HND *handle = &q_u->handle;
5045 uint32 level = q_u->level;
5046 RPC_BUFFER *buffer = NULL;
5047 uint32 offered = q_u->offered;
5048 uint32 *needed = &r_u->needed;
5049 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5053 /* that's an [in out] buffer */
5055 if (!q_u->buffer && (offered!=0)) {
5056 return WERR_INVALID_PARAM;
5059 if (offered > MAX_RPC_DATA_SIZE) {
5060 return WERR_INVALID_PARAM;
5063 rpcbuf_move(q_u->buffer, &r_u->buffer);
5064 buffer = r_u->buffer;
5068 if (!get_printer_snum(p, handle, &snum, NULL))
5073 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5075 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5077 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5079 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5081 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5083 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5085 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5087 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5089 return WERR_UNKNOWN_LEVEL;
5092 /********************************************************************
5093 * fill a DRIVER_INFO_1 struct
5094 ********************************************************************/
5096 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5098 init_unistr( &info->name, driver.info_3->name);
5101 /********************************************************************
5102 * construct_printer_driver_info_1
5103 ********************************************************************/
5105 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5107 NT_PRINTER_INFO_LEVEL *printer = NULL;
5108 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5110 ZERO_STRUCT(driver);
5112 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5113 return WERR_INVALID_PRINTER_NAME;
5115 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5116 free_a_printer(&printer, 2);
5117 return WERR_UNKNOWN_PRINTER_DRIVER;
5120 fill_printer_driver_info_1(info, driver, servername, architecture);
5122 free_a_printer(&printer,2);
5127 /********************************************************************
5128 * construct_printer_driver_info_2
5129 * fill a printer_info_2 struct
5130 ********************************************************************/
5132 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5134 TALLOC_CTX *ctx = talloc_tos();
5136 const char *cservername = canon_servername(servername);
5138 info->version=driver.info_3->cversion;
5140 init_unistr( &info->name, driver.info_3->name );
5141 init_unistr( &info->architecture, driver.info_3->environment );
5143 if (strlen(driver.info_3->driverpath)) {
5144 temp = talloc_asprintf(ctx,
5147 driver.info_3->driverpath);
5148 init_unistr( &info->driverpath, temp );
5150 init_unistr( &info->driverpath, "" );
5154 if (strlen(driver.info_3->datafile)) {
5155 temp = talloc_asprintf(ctx,
5158 driver.info_3->datafile);
5159 init_unistr( &info->datafile, temp );
5161 init_unistr( &info->datafile, "" );
5164 if (strlen(driver.info_3->configfile)) {
5165 temp = talloc_asprintf(ctx,
5168 driver.info_3->configfile);
5169 init_unistr( &info->configfile, temp );
5171 init_unistr( &info->configfile, "" );
5174 /********************************************************************
5175 * construct_printer_driver_info_2
5176 * fill a printer_info_2 struct
5177 ********************************************************************/
5179 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5181 NT_PRINTER_INFO_LEVEL *printer = NULL;
5182 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5184 ZERO_STRUCT(printer);
5185 ZERO_STRUCT(driver);
5187 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5188 return WERR_INVALID_PRINTER_NAME;
5190 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5191 free_a_printer(&printer, 2);
5192 return WERR_UNKNOWN_PRINTER_DRIVER;
5195 fill_printer_driver_info_2(info, driver, servername);
5197 free_a_printer(&printer,2);
5202 /********************************************************************
5203 * copy a strings array and convert to UNICODE
5205 * convert an array of ascii string to a UNICODE string
5206 ********************************************************************/
5208 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5214 TALLOC_CTX *ctx = talloc_tos();
5216 DEBUG(6,("init_unistr_array\n"));
5220 if ( !char_array ) {
5225 v = ""; /* hack to handle null lists */
5228 /* hack to allow this to be used in places other than when generating
5229 the list of dependent files */
5233 line = talloc_asprintf(ctx,
5235 canon_servername(servername),
5238 line = talloc_strdup(ctx, v);
5242 SAFE_FREE(*uni_array);
5245 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5247 /* add one extra unit16 for the second terminating NULL */
5249 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5250 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5257 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5262 /* special case for ""; we need to add both NULL's here */
5264 (*uni_array)[j++]=0x0000;
5265 (*uni_array)[j]=0x0000;
5268 DEBUGADD(6,("last one:done\n"));
5270 /* return size of array in uint16's */
5275 /********************************************************************
5276 * construct_printer_info_3
5277 * fill a printer_info_3 struct
5278 ********************************************************************/
5280 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5283 TALLOC_CTX *ctx = talloc_tos();
5284 const char *cservername = canon_servername(servername);
5288 info->version=driver.info_3->cversion;
5290 init_unistr( &info->name, driver.info_3->name );
5291 init_unistr( &info->architecture, driver.info_3->environment );
5293 if (strlen(driver.info_3->driverpath)) {
5294 temp = talloc_asprintf(ctx,
5297 driver.info_3->driverpath);
5298 init_unistr( &info->driverpath, temp );
5300 init_unistr( &info->driverpath, "" );
5303 if (strlen(driver.info_3->datafile)) {
5304 temp = talloc_asprintf(ctx,
5307 driver.info_3->datafile);
5308 init_unistr( &info->datafile, temp );
5310 init_unistr( &info->datafile, "" );
5313 if (strlen(driver.info_3->configfile)) {
5314 temp = talloc_asprintf(ctx,
5317 driver.info_3->configfile);
5318 init_unistr( &info->configfile, temp );
5320 init_unistr( &info->configfile, "" );
5323 if (strlen(driver.info_3->helpfile)) {
5324 temp = talloc_asprintf(ctx,
5327 driver.info_3->helpfile);
5328 init_unistr( &info->helpfile, temp );
5330 init_unistr( &info->helpfile, "" );
5333 init_unistr( &info->monitorname, driver.info_3->monitorname );
5334 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5336 info->dependentfiles=NULL;
5337 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5340 /********************************************************************
5341 * construct_printer_info_3
5342 * fill a printer_info_3 struct
5343 ********************************************************************/
5345 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5347 NT_PRINTER_INFO_LEVEL *printer = NULL;
5348 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5350 ZERO_STRUCT(driver);
5352 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5353 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5354 if (!W_ERROR_IS_OK(status))
5355 return WERR_INVALID_PRINTER_NAME;
5357 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5358 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5363 * I put this code in during testing. Helpful when commenting out the
5364 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5365 * as win2k always queries the driver using an infor level of 6.
5366 * I've left it in (but ifdef'd out) because I'll probably
5367 * use it in experimentation again in the future. --jerry 22/01/2002
5370 if (!W_ERROR_IS_OK(status)) {
5372 * Is this a W2k client ?
5375 /* Yes - try again with a WinNT driver. */
5377 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5378 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5382 if (!W_ERROR_IS_OK(status)) {
5383 free_a_printer(&printer,2);
5384 return WERR_UNKNOWN_PRINTER_DRIVER;
5392 fill_printer_driver_info_3(info, driver, servername);
5394 free_a_printer(&printer,2);
5399 /********************************************************************
5400 * construct_printer_info_6
5401 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5402 ********************************************************************/
5404 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5408 TALLOC_CTX *ctx = talloc_tos();
5409 const char *cservername = canon_servername(servername);
5412 memset(&nullstr, '\0', sizeof(fstring));
5414 info->version=driver.info_3->cversion;
5416 init_unistr( &info->name, driver.info_3->name );
5417 init_unistr( &info->architecture, driver.info_3->environment );
5419 if (strlen(driver.info_3->driverpath)) {
5420 temp = talloc_asprintf(ctx,
5423 driver.info_3->driverpath);
5424 init_unistr( &info->driverpath, temp );
5426 init_unistr( &info->driverpath, "" );
5429 if (strlen(driver.info_3->datafile)) {
5430 temp = talloc_asprintf(ctx,
5433 driver.info_3->datafile);
5434 init_unistr( &info->datafile, temp );
5436 init_unistr( &info->datafile, "" );
5439 if (strlen(driver.info_3->configfile)) {
5440 temp = talloc_asprintf(ctx,
5443 driver.info_3->configfile);
5444 init_unistr( &info->configfile, temp );
5446 init_unistr( &info->configfile, "" );
5449 if (strlen(driver.info_3->helpfile)) {
5450 temp = talloc_asprintf(ctx,
5453 driver.info_3->helpfile);
5454 init_unistr( &info->helpfile, temp );
5456 init_unistr( &info->helpfile, "" );
5459 init_unistr( &info->monitorname, driver.info_3->monitorname );
5460 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5462 info->dependentfiles = NULL;
5463 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5465 info->previousdrivernames=NULL;
5466 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5468 info->driver_date=0;
5471 info->driver_version_low=0;
5472 info->driver_version_high=0;
5474 init_unistr( &info->mfgname, "");
5475 init_unistr( &info->oem_url, "");
5476 init_unistr( &info->hardware_id, "");
5477 init_unistr( &info->provider, "");
5480 /********************************************************************
5481 * construct_printer_info_6
5482 * fill a printer_info_6 struct
5483 ********************************************************************/
5485 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5486 const char *servername, fstring architecture, uint32 version)
5488 NT_PRINTER_INFO_LEVEL *printer = NULL;
5489 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5492 ZERO_STRUCT(driver);
5494 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5496 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5498 if (!W_ERROR_IS_OK(status))
5499 return WERR_INVALID_PRINTER_NAME;
5501 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5503 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5505 if (!W_ERROR_IS_OK(status))
5508 * Is this a W2k client ?
5512 free_a_printer(&printer,2);
5513 return WERR_UNKNOWN_PRINTER_DRIVER;
5516 /* Yes - try again with a WinNT driver. */
5518 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5519 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5520 if (!W_ERROR_IS_OK(status)) {
5521 free_a_printer(&printer,2);
5522 return WERR_UNKNOWN_PRINTER_DRIVER;
5526 fill_printer_driver_info_6(info, driver, servername);
5528 free_a_printer(&printer,2);
5529 free_a_printer_driver(driver, 3);
5534 /****************************************************************************
5535 ****************************************************************************/
5537 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5539 SAFE_FREE(info->dependentfiles);
5542 /****************************************************************************
5543 ****************************************************************************/
5545 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5547 SAFE_FREE(info->dependentfiles);
5550 /****************************************************************************
5551 ****************************************************************************/
5553 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5555 DRIVER_INFO_1 *info=NULL;
5558 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5561 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5562 if (!W_ERROR_IS_OK(result))
5565 /* check the required size. */
5566 *needed += spoolss_size_printer_driver_info_1(info);
5568 if (*needed > offered) {
5569 result = WERR_INSUFFICIENT_BUFFER;
5573 if (!rpcbuf_alloc_size(buffer, *needed)) {
5574 result = WERR_NOMEM;
5578 /* fill the buffer with the structures */
5579 smb_io_printer_driver_info_1("", buffer, info, 0);
5588 /****************************************************************************
5589 ****************************************************************************/
5591 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5593 DRIVER_INFO_2 *info=NULL;
5596 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5599 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5600 if (!W_ERROR_IS_OK(result))
5603 /* check the required size. */
5604 *needed += spoolss_size_printer_driver_info_2(info);
5606 if (*needed > offered) {
5607 result = WERR_INSUFFICIENT_BUFFER;
5611 if (!rpcbuf_alloc_size(buffer, *needed)) {
5612 result = WERR_NOMEM;
5616 /* fill the buffer with the structures */
5617 smb_io_printer_driver_info_2("", buffer, info, 0);
5626 /****************************************************************************
5627 ****************************************************************************/
5629 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5636 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5637 if (!W_ERROR_IS_OK(result))
5640 /* check the required size. */
5641 *needed += spoolss_size_printer_driver_info_3(&info);
5643 if (*needed > offered) {
5644 result = WERR_INSUFFICIENT_BUFFER;
5648 if (!rpcbuf_alloc_size(buffer, *needed)) {
5649 result = WERR_NOMEM;
5653 /* fill the buffer with the structures */
5654 smb_io_printer_driver_info_3("", buffer, &info, 0);
5657 free_printer_driver_info_3(&info);
5662 /****************************************************************************
5663 ****************************************************************************/
5665 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5672 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5673 if (!W_ERROR_IS_OK(result))
5676 /* check the required size. */
5677 *needed += spoolss_size_printer_driver_info_6(&info);
5679 if (*needed > offered) {
5680 result = WERR_INSUFFICIENT_BUFFER;
5684 if (!rpcbuf_alloc_size(buffer, *needed)) {
5685 result = WERR_NOMEM;
5689 /* fill the buffer with the structures */
5690 smb_io_printer_driver_info_6("", buffer, &info, 0);
5693 free_printer_driver_info_6(&info);
5698 /****************************************************************************
5699 ****************************************************************************/
5701 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5703 POLICY_HND *handle = &q_u->handle;
5704 UNISTR2 *uni_arch = &q_u->architecture;
5705 uint32 level = q_u->level;
5706 uint32 clientmajorversion = q_u->clientmajorversion;
5707 RPC_BUFFER *buffer = NULL;
5708 uint32 offered = q_u->offered;
5709 uint32 *needed = &r_u->needed;
5710 uint32 *servermajorversion = &r_u->servermajorversion;
5711 uint32 *serverminorversion = &r_u->serverminorversion;
5712 Printer_entry *printer;
5715 fstring architecture;
5718 /* that's an [in out] buffer */
5720 if (!q_u->buffer && (offered!=0)) {
5721 return WERR_INVALID_PARAM;
5724 if (offered > MAX_RPC_DATA_SIZE) {
5725 return WERR_INVALID_PARAM;
5728 rpcbuf_move(q_u->buffer, &r_u->buffer);
5729 buffer = r_u->buffer;
5731 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5733 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5734 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5735 return WERR_INVALID_PRINTER_NAME;
5739 *servermajorversion = 0;
5740 *serverminorversion = 0;
5742 fstrcpy(servername, get_server_name( printer ));
5743 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5745 if (!get_printer_snum(p, handle, &snum, NULL))
5750 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5752 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5754 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5756 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5759 /* apparently this call is the equivalent of
5760 EnumPrinterDataEx() for the DsDriver key */
5765 return WERR_UNKNOWN_LEVEL;
5769 /****************************************************************
5770 _spoolss_StartPagePrinter
5771 ****************************************************************/
5773 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5774 struct spoolss_StartPagePrinter *r)
5776 POLICY_HND *handle = r->in.handle;
5778 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5781 DEBUG(3,("_spoolss_StartPagePrinter: "
5782 "Error in startpageprinter printer handle\n"));
5786 Printer->page_started=True;
5790 /****************************************************************
5791 _spoolss_EndPagePrinter
5792 ****************************************************************/
5794 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5795 struct spoolss_EndPagePrinter *r)
5797 POLICY_HND *handle = r->in.handle;
5800 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5803 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5804 OUR_HANDLE(handle)));
5808 if (!get_printer_snum(p, handle, &snum, NULL))
5811 Printer->page_started=False;
5812 print_job_endpage(snum, Printer->jobid);
5817 /****************************************************************
5818 _spoolss_StartDocPrinter
5819 ****************************************************************/
5821 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5822 struct spoolss_StartDocPrinter *r)
5824 POLICY_HND *handle = r->in.handle;
5825 uint32_t *jobid = r->out.job_id;
5826 struct spoolss_DocumentInfo1 *info_1;
5828 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5831 DEBUG(2,("_spoolss_StartDocPrinter: "
5832 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5836 if (r->in.level != 1) {
5837 return WERR_UNKNOWN_LEVEL;
5840 info_1 = r->in.info.info1;
5843 * a nice thing with NT is it doesn't listen to what you tell it.
5844 * when asked to send _only_ RAW datas, it tries to send datas
5847 * So I add checks like in NT Server ...
5850 if (info_1->datatype) {
5851 if (strcmp(info_1->datatype, "RAW") != 0) {
5853 return WERR_INVALID_DATATYPE;
5857 /* get the share number of the printer */
5858 if (!get_printer_snum(p, handle, &snum, NULL)) {
5862 Printer->jobid = print_job_start(p->server_info, snum,
5863 CONST_DISCARD(char *,info_1->document_name),
5864 Printer->nt_devmode);
5866 /* An error occured in print_job_start() so return an appropriate
5869 if (Printer->jobid == -1) {
5870 return map_werror_from_unix(errno);
5873 Printer->document_started=True;
5874 (*jobid) = Printer->jobid;
5879 /****************************************************************
5880 _spoolss_EndDocPrinter
5881 ****************************************************************/
5883 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5884 struct spoolss_EndDocPrinter *r)
5886 POLICY_HND *handle = r->in.handle;
5888 return _spoolss_enddocprinter_internal(p, handle);
5891 /****************************************************************
5892 _spoolss_WritePrinter
5893 ****************************************************************/
5895 WERROR _spoolss_WritePrinter(pipes_struct *p,
5896 struct spoolss_WritePrinter *r)
5898 POLICY_HND *handle = r->in.handle;
5899 uint32 buffer_size = r->in._data_size;
5900 uint8 *buffer = r->in.data.data;
5901 uint32 *buffer_written = &r->in._data_size;
5903 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5906 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5907 OUR_HANDLE(handle)));
5908 *r->out.num_written = r->in._data_size;
5912 if (!get_printer_snum(p, handle, &snum, NULL))
5915 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5916 (SMB_OFF_T)-1, (size_t)buffer_size);
5917 if (*buffer_written == (uint32)-1) {
5918 *r->out.num_written = 0;
5919 if (errno == ENOSPC)
5920 return WERR_NO_SPOOL_SPACE;
5922 return WERR_ACCESS_DENIED;
5925 *r->out.num_written = r->in._data_size;
5930 /********************************************************************
5931 * api_spoolss_getprinter
5932 * called from the spoolss dispatcher
5934 ********************************************************************/
5936 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5940 WERROR errcode = WERR_BADFUNC;
5941 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5944 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5948 if (!get_printer_snum(p, handle, &snum, NULL))
5952 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5953 if (print_queue_pause(p->server_info, snum, &errcode)) {
5957 case SPOOLSS_PRINTER_CONTROL_RESUME:
5958 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5959 if (print_queue_resume(p->server_info, snum, &errcode)) {
5963 case SPOOLSS_PRINTER_CONTROL_PURGE:
5964 if (print_queue_purge(p->server_info, snum, &errcode)) {
5969 return WERR_UNKNOWN_LEVEL;
5976 /****************************************************************
5977 _spoolss_AbortPrinter
5978 * From MSDN: "Deletes printer's spool file if printer is configured
5980 ****************************************************************/
5982 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5983 struct spoolss_AbortPrinter *r)
5985 POLICY_HND *handle = r->in.handle;
5986 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5988 WERROR errcode = WERR_OK;
5991 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5992 OUR_HANDLE(handle)));
5996 if (!get_printer_snum(p, handle, &snum, NULL))
5999 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
6004 /********************************************************************
6005 * called by spoolss_api_setprinter
6006 * when updating a printer description
6007 ********************************************************************/
6009 static WERROR update_printer_sec(POLICY_HND *handle,
6010 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
6012 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
6016 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6018 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6019 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6020 OUR_HANDLE(handle)));
6022 result = WERR_BADFID;
6027 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6028 result = WERR_INVALID_PARAM;
6032 /* Check the user has permissions to change the security
6033 descriptor. By experimentation with two NT machines, the user
6034 requires Full Access to the printer to change security
6037 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6038 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6039 result = WERR_ACCESS_DENIED;
6043 /* NT seems to like setting the security descriptor even though
6044 nothing may have actually changed. */
6046 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6047 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6048 result = WERR_BADFID;
6052 if (DEBUGLEVEL >= 10) {
6056 the_acl = old_secdesc_ctr->sd->dacl;
6057 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6058 PRINTERNAME(snum), the_acl->num_aces));
6060 for (i = 0; i < the_acl->num_aces; i++) {
6061 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6062 &the_acl->aces[i].trustee),
6063 the_acl->aces[i].access_mask));
6066 the_acl = secdesc_ctr->sd->dacl;
6069 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6070 PRINTERNAME(snum), the_acl->num_aces));
6072 for (i = 0; i < the_acl->num_aces; i++) {
6073 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6074 &the_acl->aces[i].trustee),
6075 the_acl->aces[i].access_mask));
6078 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6082 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6083 if (!new_secdesc_ctr) {
6084 result = WERR_NOMEM;
6088 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6093 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6100 /********************************************************************
6101 Canonicalize printer info from a client
6103 ATTN: It does not matter what we set the servername to hear
6104 since we do the necessary work in get_a_printer() to set it to
6105 the correct value based on what the client sent in the
6106 _spoolss_open_printer_ex().
6107 ********************************************************************/
6109 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6111 fstring printername;
6114 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6115 "portname=%s drivername=%s comment=%s location=%s\n",
6116 info->servername, info->printername, info->sharename,
6117 info->portname, info->drivername, info->comment, info->location));
6119 /* we force some elements to "correct" values */
6120 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6121 fstrcpy(info->sharename, lp_servicename(snum));
6123 /* check to see if we allow printername != sharename */
6125 if ( lp_force_printername(snum) ) {
6126 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6127 global_myname(), info->sharename );
6130 /* make sure printername is in \\server\printername format */
6132 fstrcpy( printername, info->printername );
6134 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6135 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6139 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6140 global_myname(), p );
6143 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6144 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6151 /****************************************************************************
6152 ****************************************************************************/
6154 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6156 char *cmd = lp_addport_cmd();
6157 char *command = NULL;
6159 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6160 bool is_print_op = False;
6163 return WERR_ACCESS_DENIED;
6166 command = talloc_asprintf(ctx,
6167 "%s \"%s\" \"%s\"", cmd, portname, uri );
6173 is_print_op = user_has_privileges( token, &se_printop );
6175 DEBUG(10,("Running [%s]\n", command));
6177 /********* BEGIN SePrintOperatorPrivilege **********/
6182 ret = smbrun(command, NULL);
6187 /********* END SePrintOperatorPrivilege **********/
6189 DEBUGADD(10,("returned [%d]\n", ret));
6191 TALLOC_FREE(command);
6194 return WERR_ACCESS_DENIED;
6200 /****************************************************************************
6201 ****************************************************************************/
6203 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6205 char *cmd = lp_addprinter_cmd();
6207 char *command = NULL;
6211 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6212 bool is_print_op = False;
6213 char *remote_machine = talloc_strdup(ctx, "%m");
6215 if (!remote_machine) {
6218 remote_machine = talloc_sub_basic(ctx,
6219 current_user_info.smb_name,
6220 current_user_info.domain,
6222 if (!remote_machine) {
6226 command = talloc_asprintf(ctx,
6227 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6228 cmd, printer->info_2->printername, printer->info_2->sharename,
6229 printer->info_2->portname, printer->info_2->drivername,
6230 printer->info_2->location, printer->info_2->comment, remote_machine);
6236 is_print_op = user_has_privileges( token, &se_printop );
6238 DEBUG(10,("Running [%s]\n", command));
6240 /********* BEGIN SePrintOperatorPrivilege **********/
6245 if ( (ret = smbrun(command, &fd)) == 0 ) {
6246 /* Tell everyone we updated smb.conf. */
6247 message_send_all(smbd_messaging_context(),
6248 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6254 /********* END SePrintOperatorPrivilege **********/
6256 DEBUGADD(10,("returned [%d]\n", ret));
6258 TALLOC_FREE(command);
6259 TALLOC_FREE(remote_machine);
6267 /* reload our services immediately */
6268 reload_services( False );
6271 /* Get lines and convert them back to dos-codepage */
6272 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6273 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6276 /* Set the portname to what the script says the portname should be. */
6277 /* but don't require anything to be return from the script exit a good error code */
6280 /* Set the portname to what the script says the portname should be. */
6281 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6282 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6285 TALLOC_FREE(qlines);
6290 /********************************************************************
6291 * Called by spoolss_api_setprinter
6292 * when updating a printer description.
6293 ********************************************************************/
6295 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6296 struct spoolss_SetPrinterInfoCtr *info_ctr,
6297 struct spoolss_DeviceMode *devmode)
6300 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6301 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6306 DEBUG(8,("update_printer\n"));
6311 result = WERR_BADFID;
6315 if (!get_printer_snum(p, handle, &snum, NULL)) {
6316 result = WERR_BADFID;
6320 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6321 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6322 result = WERR_BADFID;
6326 DEBUGADD(8,("Converting info_2 struct\n"));
6329 * convert_printer_info converts the incoming
6330 * info from the client and overwrites the info
6331 * just read from the tdb in the pointer 'printer'.
6334 if (!convert_printer_info_new(info_ctr, printer)) {
6335 result = WERR_NOMEM;
6340 /* we have a valid devmode
6341 convert it and link it*/
6343 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6344 if (!convert_devicemode_new(printer->info_2->printername,
6346 &printer->info_2->devmode)) {
6347 result = WERR_NOMEM;
6352 /* Do sanity check on the requested changes for Samba */
6354 if (!check_printer_ok(printer->info_2, snum)) {
6355 result = WERR_INVALID_PARAM;
6359 /* FIXME!!! If the driver has changed we really should verify that
6360 it is installed before doing much else --jerry */
6362 /* Check calling user has permission to update printer description */
6364 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6365 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6366 result = WERR_ACCESS_DENIED;
6370 /* Call addprinter hook */
6371 /* Check changes to see if this is really needed */
6373 if ( *lp_addprinter_cmd()
6374 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6375 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6376 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6377 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6379 /* add_printer_hook() will call reload_services() */
6381 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6383 result = WERR_ACCESS_DENIED;
6389 * When a *new* driver is bound to a printer, the drivername is used to
6390 * lookup previously saved driver initialization info, which is then
6391 * bound to the printer, simulating what happens in the Windows arch.
6393 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6395 if (!set_driver_init(printer, 2))
6397 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6398 printer->info_2->drivername));
6401 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6402 printer->info_2->drivername));
6404 notify_printer_driver(snum, printer->info_2->drivername);
6408 * flag which changes actually occured. This is a small subset of
6409 * all the possible changes. We also have to update things in the
6413 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6414 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6415 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6416 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6418 notify_printer_comment(snum, printer->info_2->comment);
6421 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6422 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6423 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6424 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6426 notify_printer_sharename(snum, printer->info_2->sharename);
6429 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6432 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6435 pname = printer->info_2->printername;
6438 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6439 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6440 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6442 notify_printer_printername( snum, pname );
6445 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6446 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6447 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6448 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6450 notify_printer_port(snum, printer->info_2->portname);
6453 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6454 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6455 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6456 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6458 notify_printer_location(snum, printer->info_2->location);
6461 /* here we need to update some more DsSpooler keys */
6462 /* uNCName, serverName, shortServerName */
6464 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6465 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6466 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6467 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6468 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6470 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6471 global_myname(), printer->info_2->sharename );
6472 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6473 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6474 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6476 /* Update printer info */
6477 result = mod_a_printer(printer, 2);
6480 free_a_printer(&printer, 2);
6481 free_a_printer(&old_printer, 2);
6487 /****************************************************************************
6488 ****************************************************************************/
6489 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6490 struct spoolss_SetPrinterInfo7 *info7)
6494 Printer_entry *Printer;
6496 if ( lp_security() != SEC_ADS ) {
6497 return WERR_UNKNOWN_LEVEL;
6500 Printer = find_printer_index_by_hnd(p, handle);
6502 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6507 if (!get_printer_snum(p, handle, &snum, NULL))
6510 nt_printer_publish(Printer, snum, info7->action);
6514 return WERR_UNKNOWN_LEVEL;
6518 /****************************************************************
6520 ****************************************************************/
6522 WERROR _spoolss_SetPrinter(pipes_struct *p,
6523 struct spoolss_SetPrinter *r)
6525 POLICY_HND *handle = r->in.handle;
6528 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6531 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6532 OUR_HANDLE(handle)));
6536 /* check the level */
6537 switch (r->in.info_ctr->level) {
6539 return control_printer(handle, r->in.command, p);
6541 result = update_printer(p, handle,
6543 r->in.devmode_ctr->devmode);
6544 if (!W_ERROR_IS_OK(result))
6546 if (r->in.secdesc_ctr->sd)
6547 result = update_printer_sec(handle, p,
6551 return update_printer_sec(handle, p,
6554 return publish_or_unpublish_printer(p, handle,
6555 r->in.info_ctr->info.info7);
6557 return WERR_UNKNOWN_LEVEL;
6561 /****************************************************************
6562 _spoolss_FindClosePrinterNotify
6563 ****************************************************************/
6565 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6566 struct spoolss_FindClosePrinterNotify *r)
6568 POLICY_HND *handle = r->in.handle;
6569 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6572 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6573 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6577 if (Printer->notify.client_connected==True) {
6580 if ( Printer->printer_type == SPLHND_SERVER)
6582 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6583 !get_printer_snum(p, handle, &snum, NULL) )
6586 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6589 Printer->notify.flags=0;
6590 Printer->notify.options=0;
6591 Printer->notify.localmachine[0]='\0';
6592 Printer->notify.printerlocal=0;
6593 if (Printer->notify.option)
6594 free_spool_notify_option(&Printer->notify.option);
6595 Printer->notify.client_connected=False;
6600 /****************************************************************
6602 ****************************************************************/
6604 WERROR _spoolss_AddJob(pipes_struct *p,
6605 struct spoolss_AddJob *r)
6607 if (!r->in.buffer && (r->in.offered != 0)) {
6608 return WERR_INVALID_PARAM;
6611 /* this is what a NT server returns for AddJob. AddJob must fail on
6612 * non-local printers */
6614 return WERR_INVALID_PARAM;
6617 /****************************************************************************
6618 ****************************************************************************/
6620 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6621 int position, int snum,
6622 const NT_PRINTER_INFO_LEVEL *ntprinter)
6626 t=gmtime(&queue->time);
6628 job_info->jobid=queue->job;
6629 init_unistr(&job_info->printername, lp_servicename(snum));
6630 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6631 init_unistr(&job_info->username, queue->fs_user);
6632 init_unistr(&job_info->document, queue->fs_file);
6633 init_unistr(&job_info->datatype, "RAW");
6634 init_unistr(&job_info->text_status, "");
6635 job_info->status=nt_printj_status(queue->status);
6636 job_info->priority=queue->priority;
6637 job_info->position=position;
6638 job_info->totalpages=queue->page_count;
6639 job_info->pagesprinted=0;
6641 make_systemtime(&job_info->submitted, t);
6644 /****************************************************************************
6645 ****************************************************************************/
6647 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6648 int position, int snum,
6649 const NT_PRINTER_INFO_LEVEL *ntprinter,
6650 DEVICEMODE *devmode)
6654 t=gmtime(&queue->time);
6656 job_info->jobid=queue->job;
6658 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6660 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6661 init_unistr(&job_info->username, queue->fs_user);
6662 init_unistr(&job_info->document, queue->fs_file);
6663 init_unistr(&job_info->notifyname, queue->fs_user);
6664 init_unistr(&job_info->datatype, "RAW");
6665 init_unistr(&job_info->printprocessor, "winprint");
6666 init_unistr(&job_info->parameters, "");
6667 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6668 init_unistr(&job_info->text_status, "");
6670 /* and here the security descriptor */
6672 job_info->status=nt_printj_status(queue->status);
6673 job_info->priority=queue->priority;
6674 job_info->position=position;
6675 job_info->starttime=0;
6676 job_info->untiltime=0;
6677 job_info->totalpages=queue->page_count;
6678 job_info->size=queue->size;
6679 make_systemtime(&(job_info->submitted), t);
6680 job_info->timeelapsed=0;
6681 job_info->pagesprinted=0;
6683 job_info->devmode = devmode;
6688 /****************************************************************************
6689 Enumjobs at level 1.
6690 ****************************************************************************/
6692 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6693 const NT_PRINTER_INFO_LEVEL *ntprinter,
6694 RPC_BUFFER *buffer, uint32 offered,
6695 uint32 *needed, uint32 *returned)
6699 WERROR result = WERR_OK;
6701 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6707 for (i=0; i<*returned; i++)
6708 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6710 /* check the required size. */
6711 for (i=0; i<*returned; i++)
6712 (*needed) += spoolss_size_job_info_1(&info[i]);
6714 if (*needed > offered) {
6715 result = WERR_INSUFFICIENT_BUFFER;
6719 if (!rpcbuf_alloc_size(buffer, *needed)) {
6720 result = WERR_NOMEM;
6724 /* fill the buffer with the structures */
6725 for (i=0; i<*returned; i++)
6726 smb_io_job_info_1("", buffer, &info[i], 0);
6732 if ( !W_ERROR_IS_OK(result) )
6738 /****************************************************************************
6739 Enumjobs at level 2.
6740 ****************************************************************************/
6742 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6743 const NT_PRINTER_INFO_LEVEL *ntprinter,
6744 RPC_BUFFER *buffer, uint32 offered,
6745 uint32 *needed, uint32 *returned)
6747 JOB_INFO_2 *info = NULL;
6749 WERROR result = WERR_OK;
6750 DEVICEMODE *devmode = NULL;
6752 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6757 /* this should not be a failure condition if the devmode is NULL */
6759 devmode = construct_dev_mode(lp_const_servicename(snum));
6761 for (i=0; i<*returned; i++)
6762 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6764 /* check the required size. */
6765 for (i=0; i<*returned; i++)
6766 (*needed) += spoolss_size_job_info_2(&info[i]);
6768 if (*needed > offered) {
6769 result = WERR_INSUFFICIENT_BUFFER;
6773 if (!rpcbuf_alloc_size(buffer, *needed)) {
6774 result = WERR_NOMEM;
6778 /* fill the buffer with the structures */
6779 for (i=0; i<*returned; i++)
6780 smb_io_job_info_2("", buffer, &info[i], 0);
6783 free_devmode(devmode);
6786 if ( !W_ERROR_IS_OK(result) )
6793 /****************************************************************************
6795 ****************************************************************************/
6797 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6799 POLICY_HND *handle = &q_u->handle;
6800 uint32 level = q_u->level;
6801 RPC_BUFFER *buffer = NULL;
6802 uint32 offered = q_u->offered;
6803 uint32 *needed = &r_u->needed;
6804 uint32 *returned = &r_u->returned;
6806 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6808 print_status_struct prt_status;
6809 print_queue_struct *queue=NULL;
6811 /* that's an [in out] buffer */
6813 if (!q_u->buffer && (offered!=0)) {
6814 return WERR_INVALID_PARAM;
6817 if (offered > MAX_RPC_DATA_SIZE) {
6818 return WERR_INVALID_PARAM;
6821 rpcbuf_move(q_u->buffer, &r_u->buffer);
6822 buffer = r_u->buffer;
6824 DEBUG(4,("_spoolss_enumjobs\n"));
6829 /* lookup the printer snum and tdb entry */
6831 if (!get_printer_snum(p, handle, &snum, NULL))
6834 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6835 if ( !W_ERROR_IS_OK(wret) )
6838 *returned = print_queue_status(snum, &queue, &prt_status);
6839 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6841 if (*returned == 0) {
6843 free_a_printer(&ntprinter, 2);
6849 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6852 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6856 wret = WERR_UNKNOWN_LEVEL;
6861 free_a_printer( &ntprinter, 2 );
6865 /****************************************************************
6866 _spoolss_ScheduleJob
6867 ****************************************************************/
6869 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6870 struct spoolss_ScheduleJob *r)
6875 /****************************************************************
6877 ****************************************************************/
6879 WERROR _spoolss_SetJob(pipes_struct *p,
6880 struct spoolss_SetJob *r)
6882 POLICY_HND *handle = r->in.handle;
6883 uint32 jobid = r->in.job_id;
6884 uint32 command = r->in.command;
6887 WERROR errcode = WERR_BADFUNC;
6889 if (!get_printer_snum(p, handle, &snum, NULL)) {
6893 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6894 return WERR_INVALID_PRINTER_NAME;
6898 case SPOOLSS_JOB_CONTROL_CANCEL:
6899 case SPOOLSS_JOB_CONTROL_DELETE:
6900 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6904 case SPOOLSS_JOB_CONTROL_PAUSE:
6905 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6909 case SPOOLSS_JOB_CONTROL_RESTART:
6910 case SPOOLSS_JOB_CONTROL_RESUME:
6911 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6916 return WERR_UNKNOWN_LEVEL;
6922 /****************************************************************************
6923 Enumerates all printer drivers at level 1.
6924 ****************************************************************************/
6926 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6931 fstring *list = NULL;
6932 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6933 DRIVER_INFO_1 *driver_info_1=NULL;
6934 WERROR result = WERR_OK;
6938 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6940 ndrivers=get_ntdrivers(&list, architecture, version);
6941 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6943 if(ndrivers == -1) {
6944 SAFE_FREE(driver_info_1);
6949 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6950 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6956 for (i=0; i<ndrivers; i++) {
6958 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6959 ZERO_STRUCT(driver);
6960 status = get_a_printer_driver(&driver, 3, list[i],
6961 architecture, version);
6962 if (!W_ERROR_IS_OK(status)) {
6964 SAFE_FREE(driver_info_1);
6967 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6968 free_a_printer_driver(driver, 3);
6971 *returned+=ndrivers;
6975 /* check the required size. */
6976 for (i=0; i<*returned; i++) {
6977 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6978 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6981 if (*needed > offered) {
6982 result = WERR_INSUFFICIENT_BUFFER;
6986 if (!rpcbuf_alloc_size(buffer, *needed)) {
6987 result = WERR_NOMEM;
6991 /* fill the buffer with the driver structures */
6992 for (i=0; i<*returned; i++) {
6993 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
6994 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
6998 SAFE_FREE(driver_info_1);
7000 if ( !W_ERROR_IS_OK(result) )
7006 /****************************************************************************
7007 Enumerates all printer drivers at level 2.
7008 ****************************************************************************/
7010 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7015 fstring *list = NULL;
7016 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7017 DRIVER_INFO_2 *driver_info_2=NULL;
7018 WERROR result = WERR_OK;
7022 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7024 ndrivers=get_ntdrivers(&list, architecture, version);
7025 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7027 if(ndrivers == -1) {
7028 SAFE_FREE(driver_info_2);
7033 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7034 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7040 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_2);
7052 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
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_2(&(driver_info_2[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 form structures */
7077 for (i=0; i<*returned; i++) {
7078 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7079 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7083 SAFE_FREE(driver_info_2);
7085 if ( !W_ERROR_IS_OK(result) )
7091 /****************************************************************************
7092 Enumerates all printer drivers at level 3.
7093 ****************************************************************************/
7095 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7100 fstring *list = NULL;
7101 DRIVER_INFO_3 *driver_info_3=NULL;
7102 NT_PRINTER_DRIVER_INFO_LEVEL driver;
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_3);
7118 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7119 DEBUG(0,("enumprinterdrivers_level3: 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_3);
7137 fill_printer_driver_info_3(&driver_info_3[*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_3(&driver_info_3[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 driver structures */
7162 for (i=0; i<*returned; i++) {
7163 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7164 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7168 for (i=0; i<*returned; i++) {
7169 SAFE_FREE(driver_info_3[i].dependentfiles);
7172 SAFE_FREE(driver_info_3);
7174 if ( !W_ERROR_IS_OK(result) )
7180 /****************************************************************************
7181 Enumerates all printer drivers.
7182 ****************************************************************************/
7184 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7186 uint32 level = q_u->level;
7187 RPC_BUFFER *buffer = NULL;
7188 uint32 offered = q_u->offered;
7189 uint32 *needed = &r_u->needed;
7190 uint32 *returned = &r_u->returned;
7191 const char *cservername;
7193 fstring architecture;
7195 /* that's an [in out] buffer */
7197 if (!q_u->buffer && (offered!=0)) {
7198 return WERR_INVALID_PARAM;
7201 if (offered > MAX_RPC_DATA_SIZE) {
7202 return WERR_INVALID_PARAM;
7205 rpcbuf_move(q_u->buffer, &r_u->buffer);
7206 buffer = r_u->buffer;
7208 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7213 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7214 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7216 cservername = canon_servername(servername);
7218 if (!is_myname_or_ipaddr(cservername))
7219 return WERR_UNKNOWN_PRINTER_DRIVER;
7223 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7225 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7227 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7229 return WERR_UNKNOWN_LEVEL;
7233 /****************************************************************************
7234 ****************************************************************************/
7236 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7238 form->flag=list->flag;
7239 init_unistr(&form->name, list->name);
7240 form->width=list->width;
7241 form->length=list->length;
7242 form->left=list->left;
7243 form->top=list->top;
7244 form->right=list->right;
7245 form->bottom=list->bottom;
7248 /****************************************************************************
7249 ****************************************************************************/
7251 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7252 struct spoolss_FormInfo1 *form,
7253 nt_forms_struct *list)
7255 form->form_name = talloc_strdup(mem_ctx, list->name);
7256 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7258 form->flags = list->flag;
7259 form->size.width = list->width;
7260 form->size.height = list->length;
7261 form->area.left = list->left;
7262 form->area.top = list->top;
7263 form->area.right = list->right;
7264 form->area.bottom = list->bottom;
7269 /****************************************************************************
7270 ****************************************************************************/
7272 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7274 uint32 level = q_u->level;
7275 RPC_BUFFER *buffer = NULL;
7276 uint32 offered = q_u->offered;
7277 uint32 *needed = &r_u->needed;
7278 uint32 *numofforms = &r_u->numofforms;
7279 uint32 numbuiltinforms;
7281 nt_forms_struct *list=NULL;
7282 nt_forms_struct *builtinlist=NULL;
7287 /* that's an [in out] buffer */
7289 if (!q_u->buffer && (offered!=0) ) {
7290 return WERR_INVALID_PARAM;
7293 if (offered > MAX_RPC_DATA_SIZE) {
7294 return WERR_INVALID_PARAM;
7297 rpcbuf_move(q_u->buffer, &r_u->buffer);
7298 buffer = r_u->buffer;
7300 DEBUG(4,("_spoolss_enumforms\n"));
7301 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7302 DEBUGADD(5,("Info level [%d]\n", level));
7304 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7305 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7306 *numofforms = get_ntforms(&list);
7307 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7308 *numofforms += numbuiltinforms;
7310 if (*numofforms == 0) {
7311 SAFE_FREE(builtinlist);
7313 return WERR_NO_MORE_ITEMS;
7318 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7319 SAFE_FREE(builtinlist);
7325 /* construct the list of form structures */
7326 for (i=0; i<numbuiltinforms; i++) {
7327 DEBUGADD(6,("Filling form number [%d]\n",i));
7328 fill_form_1(&forms_1[i], &builtinlist[i]);
7331 SAFE_FREE(builtinlist);
7333 for (; i<*numofforms; i++) {
7334 DEBUGADD(6,("Filling form number [%d]\n",i));
7335 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7340 /* check the required size. */
7341 for (i=0; i<numbuiltinforms; i++) {
7342 DEBUGADD(6,("adding form [%d]'s size\n",i));
7343 buffer_size += spoolss_size_form_1(&forms_1[i]);
7345 for (; i<*numofforms; i++) {
7346 DEBUGADD(6,("adding form [%d]'s size\n",i));
7347 buffer_size += spoolss_size_form_1(&forms_1[i]);
7350 *needed=buffer_size;
7352 if (*needed > offered) {
7355 return WERR_INSUFFICIENT_BUFFER;
7358 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7364 /* fill the buffer with the form structures */
7365 for (i=0; i<numbuiltinforms; i++) {
7366 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7367 smb_io_form_1("", buffer, &forms_1[i], 0);
7369 for (; i<*numofforms; i++) {
7370 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7371 smb_io_form_1("", buffer, &forms_1[i], 0);
7380 SAFE_FREE(builtinlist);
7381 return WERR_UNKNOWN_LEVEL;
7385 /****************************************************************
7387 ****************************************************************/
7389 WERROR _spoolss_GetForm(pipes_struct *p,
7390 struct spoolss_GetForm *r)
7392 uint32 level = r->in.level;
7393 uint32 offered = r->in.offered;
7394 uint32 *needed = r->out.needed;
7396 nt_forms_struct *list=NULL;
7397 nt_forms_struct builtin_form;
7399 union spoolss_FormInfo info;
7400 struct spoolss_FormInfo1 form_1;
7401 int numofforms=0, i=0;
7403 /* that's an [in out] buffer */
7405 if (!r->in.buffer && (offered!=0)) {
7406 return WERR_INVALID_PARAM;
7409 DEBUG(4,("_spoolss_GetForm\n"));
7410 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7411 DEBUGADD(5,("Info level [%d]\n", level));
7413 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7414 if (!foundBuiltin) {
7415 numofforms = get_ntforms(&list);
7416 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7418 if (numofforms == 0)
7422 ZERO_STRUCT(form_1);
7427 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7430 /* Check if the requested name is in the list of form structures */
7431 for (i=0; i<numofforms; i++) {
7433 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7434 list[i].name, r->in.form_name));
7436 if (strequal(r->in.form_name, list[i].name)) {
7437 DEBUGADD(6,("Found form %s number [%d]\n",
7438 r->in.form_name, i));
7439 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7445 if (i == numofforms) {
7449 /* check the required size. */
7451 info.info1 = form_1;
7453 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7455 if (*needed > offered) {
7457 return WERR_INSUFFICIENT_BUFFER;
7460 r->out.info->info1 = form_1;
7462 /* fill the buffer with the form structures */
7463 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7464 r->in.form_name, i));
7470 return WERR_UNKNOWN_LEVEL;
7474 /****************************************************************************
7475 ****************************************************************************/
7477 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7479 init_unistr(&port->port_name, name);
7482 /****************************************************************************
7483 TODO: This probably needs distinguish between TCP/IP and Local ports
7485 ****************************************************************************/
7487 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7489 init_unistr(&port->port_name, name);
7490 init_unistr(&port->monitor_name, "Local Monitor");
7491 init_unistr(&port->description, SPL_LOCAL_PORT );
7492 port->port_type=PORT_TYPE_WRITE;
7497 /****************************************************************************
7498 wrapper around the enumer ports command
7499 ****************************************************************************/
7501 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7503 char *cmd = lp_enumports_cmd();
7504 char **qlines = NULL;
7505 char *command = NULL;
7513 /* if no hook then just fill in the default port */
7516 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7519 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7520 TALLOC_FREE(qlines);
7527 /* we have a valid enumport command */
7529 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7534 DEBUG(10,("Running [%s]\n", command));
7535 ret = smbrun(command, &fd);
7536 DEBUG(10,("Returned [%d]\n", ret));
7537 TALLOC_FREE(command);
7542 return WERR_ACCESS_DENIED;
7546 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7547 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7557 /****************************************************************************
7559 ****************************************************************************/
7561 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7563 PORT_INFO_1 *ports=NULL;
7565 WERROR result = WERR_OK;
7566 char **qlines = NULL;
7569 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7570 if (!W_ERROR_IS_OK(result)) {
7571 TALLOC_FREE(qlines);
7576 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7577 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7578 win_errstr(WERR_NOMEM)));
7579 TALLOC_FREE(qlines);
7583 for (i=0; i<numlines; i++) {
7584 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7585 fill_port_1(&ports[i], qlines[i]);
7588 TALLOC_FREE(qlines);
7590 *returned = numlines;
7592 /* check the required size. */
7593 for (i=0; i<*returned; i++) {
7594 DEBUGADD(6,("adding port [%d]'s size\n", i));
7595 *needed += spoolss_size_port_info_1(&ports[i]);
7598 if (*needed > offered) {
7599 result = WERR_INSUFFICIENT_BUFFER;
7603 if (!rpcbuf_alloc_size(buffer, *needed)) {
7604 result = WERR_NOMEM;
7608 /* fill the buffer with the ports structures */
7609 for (i=0; i<*returned; i++) {
7610 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7611 smb_io_port_1("", buffer, &ports[i], 0);
7617 if ( !W_ERROR_IS_OK(result) )
7623 /****************************************************************************
7625 ****************************************************************************/
7627 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7629 PORT_INFO_2 *ports=NULL;
7631 WERROR result = WERR_OK;
7632 char **qlines = NULL;
7635 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7636 if ( !W_ERROR_IS_OK(result)) {
7637 TALLOC_FREE(qlines);
7642 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7643 TALLOC_FREE(qlines);
7647 for (i=0; i<numlines; i++) {
7648 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7649 fill_port_2(&(ports[i]), qlines[i]);
7653 TALLOC_FREE(qlines);
7655 *returned = numlines;
7657 /* check the required size. */
7658 for (i=0; i<*returned; i++) {
7659 DEBUGADD(6,("adding port [%d]'s size\n", i));
7660 *needed += spoolss_size_port_info_2(&ports[i]);
7663 if (*needed > offered) {
7664 result = WERR_INSUFFICIENT_BUFFER;
7668 if (!rpcbuf_alloc_size(buffer, *needed)) {
7669 result = WERR_NOMEM;
7673 /* fill the buffer with the ports structures */
7674 for (i=0; i<*returned; i++) {
7675 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7676 smb_io_port_2("", buffer, &ports[i], 0);
7682 if ( !W_ERROR_IS_OK(result) )
7688 /****************************************************************************
7690 ****************************************************************************/
7692 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7694 uint32 level = q_u->level;
7695 RPC_BUFFER *buffer = NULL;
7696 uint32 offered = q_u->offered;
7697 uint32 *needed = &r_u->needed;
7698 uint32 *returned = &r_u->returned;
7700 /* that's an [in out] buffer */
7702 if (!q_u->buffer && (offered!=0)) {
7703 return WERR_INVALID_PARAM;
7706 if (offered > MAX_RPC_DATA_SIZE) {
7707 return WERR_INVALID_PARAM;
7710 rpcbuf_move(q_u->buffer, &r_u->buffer);
7711 buffer = r_u->buffer;
7713 DEBUG(4,("_spoolss_enumports\n"));
7720 return enumports_level_1(buffer, offered, needed, returned);
7722 return enumports_level_2(buffer, offered, needed, returned);
7724 return WERR_UNKNOWN_LEVEL;
7728 /****************************************************************************
7729 ****************************************************************************/
7731 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7733 struct spoolss_SetPrinterInfoCtr *info_ctr,
7734 struct spoolss_DeviceMode *devmode,
7735 struct security_descriptor *sec_desc,
7736 struct spoolss_UserLevelCtr *user_ctr,
7739 NT_PRINTER_INFO_LEVEL *printer = NULL;
7742 WERROR err = WERR_OK;
7744 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7745 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7749 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7750 if (!convert_printer_info_new(info_ctr, printer)) {
7751 free_a_printer(&printer, 2);
7755 /* check to see if the printer already exists */
7757 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7758 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7759 printer->info_2->sharename));
7760 free_a_printer(&printer, 2);
7761 return WERR_PRINTER_ALREADY_EXISTS;
7764 /* FIXME!!! smbd should check to see if the driver is installed before
7765 trying to add a printer like this --jerry */
7767 if (*lp_addprinter_cmd() ) {
7768 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7770 free_a_printer(&printer,2);
7771 return WERR_ACCESS_DENIED;
7774 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7775 "smb.conf parameter \"addprinter command\" is defined. This"
7776 "parameter must exist for this call to succeed\n",
7777 printer->info_2->sharename ));
7780 /* use our primary netbios name since get_a_printer() will convert
7781 it to what the client expects on a case by case basis */
7783 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7784 printer->info_2->sharename);
7787 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7788 free_a_printer(&printer,2);
7789 return WERR_ACCESS_DENIED;
7792 /* you must be a printer admin to add a new printer */
7793 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7794 free_a_printer(&printer,2);
7795 return WERR_ACCESS_DENIED;
7799 * Do sanity check on the requested changes for Samba.
7802 if (!check_printer_ok(printer->info_2, snum)) {
7803 free_a_printer(&printer,2);
7804 return WERR_INVALID_PARAM;
7808 * When a printer is created, the drivername bound to the printer is used
7809 * to lookup previously saved driver initialization info, which is then
7810 * bound to the new printer, simulating what happens in the Windows arch.
7815 set_driver_init(printer, 2);
7819 /* A valid devmode was included, convert and link it
7821 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7823 if (!convert_devicemode_new(printer->info_2->printername,
7825 &printer->info_2->devmode))
7829 /* write the ASCII on disk */
7830 err = mod_a_printer(printer, 2);
7831 if (!W_ERROR_IS_OK(err)) {
7832 free_a_printer(&printer,2);
7836 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7837 /* Handle open failed - remove addition. */
7838 del_a_printer(printer->info_2->sharename);
7839 free_a_printer(&printer,2);
7840 ZERO_STRUCTP(handle);
7841 return WERR_ACCESS_DENIED;
7844 update_c_setprinter(False);
7845 free_a_printer(&printer,2);
7850 /****************************************************************
7851 _spoolss_AddPrinterEx
7852 ****************************************************************/
7854 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7855 struct spoolss_AddPrinterEx *r)
7857 switch (r->in.info_ctr->level) {
7859 /* we don't handle yet */
7860 /* but I know what to do ... */
7861 return WERR_UNKNOWN_LEVEL;
7863 return spoolss_addprinterex_level_2(p, r->in.server,
7865 r->in.devmode_ctr->devmode,
7866 r->in.secdesc_ctr->sd,
7867 r->in.userlevel_ctr,
7870 return WERR_UNKNOWN_LEVEL;
7874 /****************************************************************
7875 _spoolss_AddPrinterDriver
7876 ****************************************************************/
7878 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7879 struct spoolss_AddPrinterDriver *r)
7881 uint32_t level = r->in.info_ctr->level;
7882 struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
7883 WERROR err = WERR_OK;
7884 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7885 fstring driver_name;
7889 switch (p->hdr_req.opnum) {
7890 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7891 fn = "_spoolss_AddPrinterDriver";
7893 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7894 fn = "_spoolss_AddPrinterDriverEx";
7897 return WERR_INVALID_PARAM;
7902 if (level != 3 && level != 6) {
7903 /* Clever hack from Martin Zielinski <mz@seh.de>
7904 * to allow downgrade from level 8 (Vista).
7906 DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
7907 return WERR_UNKNOWN_LEVEL;
7910 ZERO_STRUCT(driver);
7912 if (!convert_printer_driver_info(info, &driver, level)) {
7917 DEBUG(5,("Cleaning driver's information\n"));
7918 err = clean_up_driver_struct(p, driver, level);
7919 if (!W_ERROR_IS_OK(err))
7922 DEBUG(5,("Moving driver to final destination\n"));
7923 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7928 if (add_a_printer_driver(driver, level)!=0) {
7929 err = WERR_ACCESS_DENIED;
7935 fstrcpy(driver_name,
7936 driver.info_3->name ? driver.info_3->name : "");
7939 fstrcpy(driver_name,
7940 driver.info_6->name ? driver.info_6->name : "");
7945 * I think this is where he DrvUpgradePrinter() hook would be
7946 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7947 * server. Right now, we just need to send ourselves a message
7948 * to update each printer bound to this driver. --jerry
7951 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7952 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7957 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7958 * decide if the driver init data should be deleted. The rules are:
7959 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7960 * 2) delete init data only if there is no 2k/Xp driver
7961 * 3) always delete init data
7962 * The generalized rule is always use init data from the highest order driver.
7963 * It is necessary to follow the driver install by an initialization step to
7964 * finish off this process.
7967 version = driver.info_3->cversion;
7968 else if (level == 6)
7969 version = driver.info_6->version;
7974 * 9x printer driver - never delete init data
7977 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7982 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7983 * there is no 2k/Xp driver init data for this driver name.
7987 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7989 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7991 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7993 if (!del_driver_init(driver_name))
7994 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7998 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
8000 free_a_printer_driver(driver1,3);
8001 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
8008 * 2k or Xp printer driver - always delete init data
8011 if (!del_driver_init(driver_name))
8012 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
8017 DEBUG(0,("%s: invalid level=%d\n", fn, level));
8023 free_a_printer_driver(driver, level);
8027 /****************************************************************
8028 _spoolss_AddPrinterDriverEx
8029 ****************************************************************/
8031 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
8032 struct spoolss_AddPrinterDriverEx *r)
8034 struct spoolss_AddPrinterDriver a;
8037 * we only support the semantics of AddPrinterDriver()
8038 * i.e. only copy files that are newer than existing ones
8041 if (r->in.flags != APD_COPY_NEW_FILES) {
8042 return WERR_ACCESS_DENIED;
8045 a.in.servername = r->in.servername;
8046 a.in.info_ctr = r->in.info_ctr;
8048 return _spoolss_AddPrinterDriver(p, &a);
8051 /****************************************************************************
8052 ****************************************************************************/
8054 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8055 const char *servername,
8056 const char *environment,
8057 struct spoolss_DriverDirectoryInfo1 *info1,
8062 const char *pservername = NULL;
8063 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
8064 const char *short_archi;
8067 long_archi = environment;
8070 pservername = canon_servername(servername);
8072 if ( !is_myname_or_ipaddr(pservername))
8073 return WERR_INVALID_PARAM;
8075 if (!(short_archi = get_short_archi(long_archi)))
8076 return WERR_INVALID_ENVIRONMENT;
8078 path = talloc_asprintf(mem_ctx,
8079 "\\\\%s\\print$\\%s", pservername, short_archi);
8084 DEBUG(4,("printer driver directory: [%s]\n", path));
8086 info1->directory_name = path;
8088 *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0);
8090 if (*needed > offered) {
8092 ZERO_STRUCTP(info1);
8093 return WERR_INSUFFICIENT_BUFFER;
8099 /****************************************************************
8100 _spoolss_GetPrinterDriverDirectory
8101 ****************************************************************/
8103 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8104 struct spoolss_GetPrinterDriverDirectory *r)
8108 /* that's an [in out] buffer */
8110 if (!r->in.buffer && (r->in.offered != 0)) {
8111 return WERR_INVALID_PARAM;
8114 if (r->in.offered > MAX_RPC_DATA_SIZE) {
8115 return WERR_INVALID_PARAM;
8118 DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n"));
8122 switch (r->in.level) {
8124 werror = getprinterdriverdir_level_1(p->mem_ctx,
8127 &r->out.info->info1,
8130 if (!W_ERROR_IS_OK(werror)) {
8131 TALLOC_FREE(r->out.info);
8135 return WERR_UNKNOWN_LEVEL;
8141 /****************************************************************************
8142 ****************************************************************************/
8144 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8146 POLICY_HND *handle = &q_u->handle;
8147 uint32 idx = q_u->index;
8148 uint32 in_value_len = q_u->valuesize;
8149 uint32 in_data_len = q_u->datasize;
8150 uint32 *out_max_value_len = &r_u->valuesize;
8151 uint16 **out_value = &r_u->value;
8152 uint32 *out_value_len = &r_u->realvaluesize;
8153 uint32 *out_type = &r_u->type;
8154 uint32 *out_max_data_len = &r_u->datasize;
8155 uint8 **data_out = &r_u->data;
8156 uint32 *out_data_len = &r_u->realdatasize;
8158 NT_PRINTER_INFO_LEVEL *printer = NULL;
8160 uint32 biggest_valuesize;
8161 uint32 biggest_datasize;
8163 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8166 REGISTRY_VALUE *val = NULL;
8167 NT_PRINTER_DATA *p_data;
8168 int i, key_index, num_values;
8173 *out_max_data_len = 0;
8177 DEBUG(5,("spoolss_enumprinterdata\n"));
8180 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8184 if (!get_printer_snum(p,handle, &snum, NULL))
8187 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8188 if (!W_ERROR_IS_OK(result))
8191 p_data = printer->info_2->data;
8192 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8197 * The NT machine wants to know the biggest size of value and data
8199 * cf: MSDN EnumPrinterData remark section
8202 if ( !in_value_len && !in_data_len && (key_index != -1) )
8204 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8206 biggest_valuesize = 0;
8207 biggest_datasize = 0;
8209 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8211 for ( i=0; i<num_values; i++ )
8213 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8215 name_length = strlen(val->valuename);
8216 if ( strlen(val->valuename) > biggest_valuesize )
8217 biggest_valuesize = name_length;
8219 if ( val->size > biggest_datasize )
8220 biggest_datasize = val->size;
8222 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8226 /* the value is an UNICODE string but real_value_size is the length
8227 in bytes including the trailing 0 */
8229 *out_value_len = 2 * (1+biggest_valuesize);
8230 *out_data_len = biggest_datasize;
8232 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8238 * the value len is wrong in NT sp3
8239 * that's the number of bytes not the number of unicode chars
8242 if ( key_index != -1 )
8243 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8248 /* out_value should default to "" or else NT4 has
8249 problems unmarshalling the response */
8251 *out_max_value_len=(in_value_len/sizeof(uint16));
8254 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8256 result = WERR_NOMEM;
8259 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8265 /* the data is counted in bytes */
8267 *out_max_data_len = in_data_len;
8268 *out_data_len = in_data_len;
8270 /* only allocate when given a non-zero data_len */
8272 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8274 result = WERR_NOMEM;
8278 result = WERR_NO_MORE_ITEMS;
8284 * - counted in bytes in the request
8285 * - counted in UNICODE chars in the max reply
8286 * - counted in bytes in the real size
8288 * take a pause *before* coding not *during* coding
8292 *out_max_value_len=(in_value_len/sizeof(uint16));
8294 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8296 result = WERR_NOMEM;
8300 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8308 *out_type = regval_type( val );
8310 /* data - counted in bytes */
8312 *out_max_data_len = in_data_len;
8313 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8315 result = WERR_NOMEM;
8318 data_len = regval_size(val);
8319 if ( *data_out && data_len )
8320 memcpy( *data_out, regval_data_p(val), data_len );
8321 *out_data_len = data_len;
8325 free_a_printer(&printer, 2);
8329 /****************************************************************************
8330 ****************************************************************************/
8332 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8334 POLICY_HND *handle = &q_u->handle;
8335 UNISTR2 *value = &q_u->value;
8336 uint32 type = q_u->type;
8337 uint8 *data = q_u->data;
8338 uint32 real_len = q_u->real_len;
8340 NT_PRINTER_INFO_LEVEL *printer = NULL;
8342 WERROR status = WERR_OK;
8343 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8346 DEBUG(5,("spoolss_setprinterdata\n"));
8349 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8353 if ( Printer->printer_type == SPLHND_SERVER ) {
8354 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8355 return WERR_INVALID_PARAM;
8358 if (!get_printer_snum(p,handle, &snum, NULL))
8362 * Access check : NT returns "access denied" if you make a
8363 * SetPrinterData call without the necessary privildge.
8364 * we were originally returning OK if nothing changed
8365 * which made Win2k issue **a lot** of SetPrinterData
8366 * when connecting to a printer --jerry
8369 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8371 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8372 status = WERR_ACCESS_DENIED;
8376 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8377 if (!W_ERROR_IS_OK(status))
8380 unistr2_to_ascii(valuename, value, sizeof(valuename));
8383 * When client side code sets a magic printer data key, detect it and save
8384 * the current printer data and the magic key's data (its the DEVMODE) for
8385 * future printer/driver initializations.
8387 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8389 /* Set devmode and printer initialization info */
8390 status = save_driver_init( printer, 2, data, real_len );
8392 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8396 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8397 type, data, real_len );
8398 if ( W_ERROR_IS_OK(status) )
8399 status = mod_a_printer(printer, 2);
8403 free_a_printer(&printer, 2);
8408 /****************************************************************
8409 _spoolss_ResetPrinter
8410 ****************************************************************/
8412 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8413 struct spoolss_ResetPrinter *r)
8415 POLICY_HND *handle = r->in.handle;
8416 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8419 DEBUG(5,("_spoolss_ResetPrinter\n"));
8422 * All we do is to check to see if the handle and queue is valid.
8423 * This call really doesn't mean anything to us because we only
8424 * support RAW printing. --jerry
8428 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8429 OUR_HANDLE(handle)));
8433 if (!get_printer_snum(p,handle, &snum, NULL))
8437 /* blindly return success */
8441 /****************************************************************
8442 _spoolss_DeletePrinterData
8443 ****************************************************************/
8445 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8446 struct spoolss_DeletePrinterData *r)
8448 POLICY_HND *handle = r->in.handle;
8449 NT_PRINTER_INFO_LEVEL *printer = NULL;
8451 WERROR status = WERR_OK;
8452 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8454 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8457 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8458 OUR_HANDLE(handle)));
8462 if (!get_printer_snum(p, handle, &snum, NULL))
8465 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8466 DEBUG(3, ("_spoolss_DeletePrinterData: "
8467 "printer properties change denied by handle\n"));
8468 return WERR_ACCESS_DENIED;
8471 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8472 if (!W_ERROR_IS_OK(status))
8475 if (!r->in.value_name) {
8476 free_a_printer(&printer, 2);
8480 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8483 if ( W_ERROR_IS_OK(status) )
8484 mod_a_printer( printer, 2 );
8486 free_a_printer(&printer, 2);
8491 /****************************************************************
8493 ****************************************************************/
8495 WERROR _spoolss_AddForm(pipes_struct *p,
8496 struct spoolss_AddForm *r)
8498 POLICY_HND *handle = r->in.handle;
8499 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8500 nt_forms_struct tmpForm;
8502 WERROR status = WERR_OK;
8503 NT_PRINTER_INFO_LEVEL *printer = NULL;
8506 nt_forms_struct *list=NULL;
8507 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8509 DEBUG(5,("_spoolss_AddForm\n"));
8512 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8513 OUR_HANDLE(handle)));
8518 /* forms can be added on printer of on the print server handle */
8520 if ( Printer->printer_type == SPLHND_PRINTER )
8522 if (!get_printer_snum(p,handle, &snum, NULL))
8525 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8526 if (!W_ERROR_IS_OK(status))
8530 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8531 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8532 status = WERR_ACCESS_DENIED;
8536 /* can't add if builtin */
8538 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8539 status = WERR_FILE_EXISTS;
8543 count = get_ntforms(&list);
8545 if(!add_a_form(&list, form, &count)) {
8546 status = WERR_NOMEM;
8550 write_ntforms(&list, count);
8553 * ChangeID must always be set if this is a printer
8556 if ( Printer->printer_type == SPLHND_PRINTER )
8557 status = mod_a_printer(printer, 2);
8561 free_a_printer(&printer, 2);
8567 /****************************************************************
8569 ****************************************************************/
8571 WERROR _spoolss_DeleteForm(pipes_struct *p,
8572 struct spoolss_DeleteForm *r)
8574 POLICY_HND *handle = r->in.handle;
8575 const char *form_name = r->in.form_name;
8576 nt_forms_struct tmpForm;
8578 nt_forms_struct *list=NULL;
8579 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8581 WERROR status = WERR_OK;
8582 NT_PRINTER_INFO_LEVEL *printer = NULL;
8584 DEBUG(5,("_spoolss_DeleteForm\n"));
8587 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8588 OUR_HANDLE(handle)));
8592 /* forms can be deleted on printer of on the print server handle */
8594 if ( Printer->printer_type == SPLHND_PRINTER )
8596 if (!get_printer_snum(p,handle, &snum, NULL))
8599 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8600 if (!W_ERROR_IS_OK(status))
8604 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8605 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8606 status = WERR_ACCESS_DENIED;
8610 /* can't delete if builtin */
8612 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8613 status = WERR_INVALID_PARAM;
8617 count = get_ntforms(&list);
8619 if ( !delete_a_form(&list, form_name, &count, &status ))
8623 * ChangeID must always be set if this is a printer
8626 if ( Printer->printer_type == SPLHND_PRINTER )
8627 status = mod_a_printer(printer, 2);
8631 free_a_printer(&printer, 2);
8637 /****************************************************************
8639 ****************************************************************/
8641 WERROR _spoolss_SetForm(pipes_struct *p,
8642 struct spoolss_SetForm *r)
8644 POLICY_HND *handle = r->in.handle;
8645 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8646 nt_forms_struct tmpForm;
8648 WERROR status = WERR_OK;
8649 NT_PRINTER_INFO_LEVEL *printer = NULL;
8652 nt_forms_struct *list=NULL;
8653 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8655 DEBUG(5,("_spoolss_SetForm\n"));
8658 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8659 OUR_HANDLE(handle)));
8663 /* forms can be modified on printer of on the print server handle */
8665 if ( Printer->printer_type == SPLHND_PRINTER )
8667 if (!get_printer_snum(p,handle, &snum, NULL))
8670 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8671 if (!W_ERROR_IS_OK(status))
8675 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8676 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8677 status = WERR_ACCESS_DENIED;
8681 /* can't set if builtin */
8682 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8683 status = WERR_INVALID_PARAM;
8687 count = get_ntforms(&list);
8688 update_a_form(&list, form, count);
8689 write_ntforms(&list, count);
8692 * ChangeID must always be set if this is a printer
8695 if ( Printer->printer_type == SPLHND_PRINTER )
8696 status = mod_a_printer(printer, 2);
8701 free_a_printer(&printer, 2);
8707 /****************************************************************************
8708 enumprintprocessors level 1.
8709 ****************************************************************************/
8711 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8713 PRINTPROCESSOR_1 *info_1=NULL;
8714 WERROR result = WERR_OK;
8716 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8721 init_unistr(&info_1->name, "winprint");
8723 *needed += spoolss_size_printprocessor_info_1(info_1);
8725 if (*needed > offered) {
8726 result = WERR_INSUFFICIENT_BUFFER;
8730 if (!rpcbuf_alloc_size(buffer, *needed)) {
8731 result = WERR_NOMEM;
8735 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8740 if ( !W_ERROR_IS_OK(result) )
8746 /****************************************************************************
8747 ****************************************************************************/
8749 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8751 uint32 level = q_u->level;
8752 RPC_BUFFER *buffer = NULL;
8753 uint32 offered = q_u->offered;
8754 uint32 *needed = &r_u->needed;
8755 uint32 *returned = &r_u->returned;
8757 /* that's an [in out] buffer */
8759 if (!q_u->buffer && (offered!=0)) {
8760 return WERR_INVALID_PARAM;
8763 if (offered > MAX_RPC_DATA_SIZE) {
8764 return WERR_INVALID_PARAM;
8767 rpcbuf_move(q_u->buffer, &r_u->buffer);
8768 buffer = r_u->buffer;
8770 DEBUG(5,("spoolss_enumprintprocessors\n"));
8773 * Enumerate the print processors ...
8775 * Just reply with "winprint", to keep NT happy
8776 * and I can use my nice printer checker.
8784 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8786 return WERR_UNKNOWN_LEVEL;
8790 /****************************************************************************
8791 enumprintprocdatatypes level 1.
8792 ****************************************************************************/
8794 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8796 PRINTPROCDATATYPE_1 *info_1=NULL;
8797 WERROR result = WERR_OK;
8799 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8804 init_unistr(&info_1->name, "RAW");
8806 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8808 if (*needed > offered) {
8809 result = WERR_INSUFFICIENT_BUFFER;
8813 if (!rpcbuf_alloc_size(buffer, *needed)) {
8814 result = WERR_NOMEM;
8818 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8823 if ( !W_ERROR_IS_OK(result) )
8829 /****************************************************************************
8830 ****************************************************************************/
8832 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8834 uint32 level = q_u->level;
8835 RPC_BUFFER *buffer = NULL;
8836 uint32 offered = q_u->offered;
8837 uint32 *needed = &r_u->needed;
8838 uint32 *returned = &r_u->returned;
8840 /* that's an [in out] buffer */
8842 if (!q_u->buffer && (offered!=0)) {
8843 return WERR_INVALID_PARAM;
8846 if (offered > MAX_RPC_DATA_SIZE) {
8847 return WERR_INVALID_PARAM;
8850 rpcbuf_move(q_u->buffer, &r_u->buffer);
8851 buffer = r_u->buffer;
8853 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8860 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8862 return WERR_UNKNOWN_LEVEL;
8866 /****************************************************************************
8867 enumprintmonitors level 1.
8868 ****************************************************************************/
8870 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8872 PRINTMONITOR_1 *info_1;
8873 WERROR result = WERR_OK;
8876 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8881 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8882 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8884 for ( i=0; i<*returned; i++ ) {
8885 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8888 if (*needed > offered) {
8889 result = WERR_INSUFFICIENT_BUFFER;
8893 if (!rpcbuf_alloc_size(buffer, *needed)) {
8894 result = WERR_NOMEM;
8898 for ( i=0; i<*returned; i++ ) {
8899 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8905 if ( !W_ERROR_IS_OK(result) )
8911 /****************************************************************************
8912 enumprintmonitors level 2.
8913 ****************************************************************************/
8915 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8917 PRINTMONITOR_2 *info_2;
8918 WERROR result = WERR_OK;
8921 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8926 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8927 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8928 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8930 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8931 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8932 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8934 for ( i=0; i<*returned; i++ ) {
8935 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8938 if (*needed > offered) {
8939 result = WERR_INSUFFICIENT_BUFFER;
8943 if (!rpcbuf_alloc_size(buffer, *needed)) {
8944 result = WERR_NOMEM;
8948 for ( i=0; i<*returned; i++ ) {
8949 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8955 if ( !W_ERROR_IS_OK(result) )
8961 /****************************************************************************
8962 ****************************************************************************/
8964 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8966 uint32 level = q_u->level;
8967 RPC_BUFFER *buffer = NULL;
8968 uint32 offered = q_u->offered;
8969 uint32 *needed = &r_u->needed;
8970 uint32 *returned = &r_u->returned;
8972 /* that's an [in out] buffer */
8974 if (!q_u->buffer && (offered!=0)) {
8975 return WERR_INVALID_PARAM;
8978 if (offered > MAX_RPC_DATA_SIZE) {
8979 return WERR_INVALID_PARAM;
8982 rpcbuf_move(q_u->buffer, &r_u->buffer);
8983 buffer = r_u->buffer;
8985 DEBUG(5,("spoolss_enumprintmonitors\n"));
8988 * Enumerate the print monitors ...
8990 * Just reply with "Local Port", to keep NT happy
8991 * and I can use my nice printer checker.
8999 return enumprintmonitors_level_1(buffer, offered, needed, returned);
9001 return enumprintmonitors_level_2(buffer, offered, needed, returned);
9003 return WERR_UNKNOWN_LEVEL;
9007 /****************************************************************************
9008 ****************************************************************************/
9010 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
9011 NT_PRINTER_INFO_LEVEL *ntprinter,
9012 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9017 JOB_INFO_1 *info_1=NULL;
9018 WERROR result = WERR_OK;
9020 info_1=SMB_MALLOC_P(JOB_INFO_1);
9022 if (info_1 == NULL) {
9026 for (i=0; i<count && found==False; i++) {
9027 if ((*queue)[i].job==(int)jobid)
9033 /* NT treats not found as bad param... yet another bad choice */
9034 return WERR_INVALID_PARAM;
9037 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9039 *needed += spoolss_size_job_info_1(info_1);
9041 if (*needed > offered) {
9042 result = WERR_INSUFFICIENT_BUFFER;
9046 if (!rpcbuf_alloc_size(buffer, *needed)) {
9047 result = WERR_NOMEM;
9051 smb_io_job_info_1("", buffer, info_1, 0);
9059 /****************************************************************************
9060 ****************************************************************************/
9062 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9063 NT_PRINTER_INFO_LEVEL *ntprinter,
9064 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9071 DEVICEMODE *devmode = NULL;
9072 NT_DEVICEMODE *nt_devmode = NULL;
9074 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9077 ZERO_STRUCTP(info_2);
9079 for ( i=0; i<count && found==False; i++ )
9081 if ((*queue)[i].job == (int)jobid)
9086 /* NT treats not found as bad param... yet another bad
9088 result = WERR_INVALID_PARAM;
9093 * if the print job does not have a DEVMODE associated with it,
9094 * just use the one for the printer. A NULL devicemode is not
9095 * a failure condition
9098 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9099 devmode = construct_dev_mode(lp_const_servicename(snum));
9101 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9102 ZERO_STRUCTP( devmode );
9103 convert_nt_devicemode( devmode, nt_devmode );
9107 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9109 *needed += spoolss_size_job_info_2(info_2);
9111 if (*needed > offered) {
9112 result = WERR_INSUFFICIENT_BUFFER;
9116 if (!rpcbuf_alloc_size(buffer, *needed)) {
9117 result = WERR_NOMEM;
9121 smb_io_job_info_2("", buffer, info_2, 0);
9126 /* Cleanup allocated memory */
9128 free_job_info_2(info_2); /* Also frees devmode */
9134 /****************************************************************************
9135 ****************************************************************************/
9137 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9139 POLICY_HND *handle = &q_u->handle;
9140 uint32 jobid = q_u->jobid;
9141 uint32 level = q_u->level;
9142 RPC_BUFFER *buffer = NULL;
9143 uint32 offered = q_u->offered;
9144 uint32 *needed = &r_u->needed;
9145 WERROR wstatus = WERR_OK;
9146 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9149 print_queue_struct *queue = NULL;
9150 print_status_struct prt_status;
9152 /* that's an [in out] buffer */
9154 if (!q_u->buffer && (offered!=0)) {
9155 return WERR_INVALID_PARAM;
9158 if (offered > MAX_RPC_DATA_SIZE) {
9159 return WERR_INVALID_PARAM;
9162 rpcbuf_move(q_u->buffer, &r_u->buffer);
9163 buffer = r_u->buffer;
9165 DEBUG(5,("spoolss_getjob\n"));
9169 if (!get_printer_snum(p, handle, &snum, NULL))
9172 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9173 if ( !W_ERROR_IS_OK(wstatus) )
9176 count = print_queue_status(snum, &queue, &prt_status);
9178 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9179 count, prt_status.status, prt_status.message));
9183 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9184 buffer, offered, needed);
9187 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9188 buffer, offered, needed);
9191 wstatus = WERR_UNKNOWN_LEVEL;
9196 free_a_printer( &ntprinter, 2 );
9201 /****************************************************************
9202 _spoolss_GetPrinterDataEx
9204 From MSDN documentation of GetPrinterDataEx: pass request
9205 to GetPrinterData if key is "PrinterDriverData".
9206 ****************************************************************/
9208 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9209 struct spoolss_GetPrinterDataEx *r)
9211 POLICY_HND *handle = r->in.handle;
9213 const char *keyname = r->in.key_name;
9214 const char *valuename = r->in.value_name;
9216 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9218 NT_PRINTER_INFO_LEVEL *printer = NULL;
9220 WERROR status = WERR_OK;
9222 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9224 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9225 keyname, valuename));
9227 /* in case of problem, return some default values */
9233 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9234 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9235 status = WERR_BADFID;
9239 /* Is the handle to a printer or to the server? */
9241 if (Printer->printer_type == SPLHND_SERVER) {
9242 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9243 "Not implemented for server handles yet\n"));
9244 status = WERR_INVALID_PARAM;
9248 if ( !get_printer_snum(p,handle, &snum, NULL) )
9251 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9252 if ( !W_ERROR_IS_OK(status) )
9255 /* check to see if the keyname is valid */
9256 if ( !strlen(keyname) ) {
9257 status = WERR_INVALID_PARAM;
9261 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9262 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9263 "Invalid keyname [%s]\n", keyname ));
9264 free_a_printer( &printer, 2 );
9265 status = WERR_BADFILE;
9269 /* When given a new keyname, we should just create it */
9271 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9272 r->out.type, &data, r->out.needed,
9275 if (*r->out.needed > r->in.offered) {
9276 status = WERR_MORE_DATA;
9279 if (W_ERROR_IS_OK(status)) {
9280 memcpy(r->out.buffer, data, r->in.offered);
9285 free_a_printer( &printer, 2 );
9290 /****************************************************************
9291 _spoolss_SetPrinterDataEx
9292 ****************************************************************/
9294 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9295 struct spoolss_SetPrinterDataEx *r)
9297 POLICY_HND *handle = r->in.handle;
9298 NT_PRINTER_INFO_LEVEL *printer = NULL;
9300 WERROR status = WERR_OK;
9301 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9304 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9306 /* From MSDN documentation of SetPrinterDataEx: pass request to
9307 SetPrinterData if key is "PrinterDriverData" */
9310 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9311 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9315 if ( Printer->printer_type == SPLHND_SERVER ) {
9316 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9317 "Not implemented for server handles yet\n"));
9318 return WERR_INVALID_PARAM;
9321 if ( !get_printer_snum(p,handle, &snum, NULL) )
9325 * Access check : NT returns "access denied" if you make a
9326 * SetPrinterData call without the necessary privildge.
9327 * we were originally returning OK if nothing changed
9328 * which made Win2k issue **a lot** of SetPrinterData
9329 * when connecting to a printer --jerry
9332 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9334 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9335 "change denied by handle access permissions\n"));
9336 return WERR_ACCESS_DENIED;
9339 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9340 if (!W_ERROR_IS_OK(status))
9343 /* check for OID in valuename */
9345 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9351 /* save the registry data */
9353 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9354 r->in.type, r->in.buffer, r->in.offered );
9356 if ( W_ERROR_IS_OK(status) )
9358 /* save the OID if one was specified */
9360 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9361 r->in.key_name, SPOOL_OID_KEY);
9367 * I'm not checking the status here on purpose. Don't know
9368 * if this is right, but I'm returning the status from the
9369 * previous set_printer_dataex() call. I have no idea if
9370 * this is right. --jerry
9373 set_printer_dataex( printer, str, r->in.value_name,
9374 REG_SZ, (uint8 *)oid_string,
9375 strlen(oid_string)+1 );
9378 status = mod_a_printer(printer, 2);
9381 free_a_printer(&printer, 2);
9386 /****************************************************************
9387 _spoolss_DeletePrinterDataEx
9388 ****************************************************************/
9390 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9391 struct spoolss_DeletePrinterDataEx *r)
9393 POLICY_HND *handle = r->in.handle;
9394 NT_PRINTER_INFO_LEVEL *printer = NULL;
9396 WERROR status = WERR_OK;
9397 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9399 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9402 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9403 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9407 if (!get_printer_snum(p, handle, &snum, NULL))
9410 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9411 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9412 "printer properties change denied by handle\n"));
9413 return WERR_ACCESS_DENIED;
9416 if (!r->in.value_name || !r->in.key_name) {
9420 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9421 if (!W_ERROR_IS_OK(status))
9424 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9426 if ( W_ERROR_IS_OK(status) )
9427 mod_a_printer( printer, 2 );
9429 free_a_printer(&printer, 2);
9434 /********************************************************************
9435 * spoolss_enumprinterkey
9436 ********************************************************************/
9439 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9442 fstring *keynames = NULL;
9443 uint16 *enumkeys = NULL;
9446 POLICY_HND *handle = &q_u->handle;
9447 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9448 NT_PRINTER_DATA *data;
9449 NT_PRINTER_INFO_LEVEL *printer = NULL;
9451 WERROR status = WERR_BADFILE;
9454 DEBUG(4,("_spoolss_enumprinterkey\n"));
9457 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9461 if ( !get_printer_snum(p,handle, &snum, NULL) )
9464 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9465 if (!W_ERROR_IS_OK(status))
9468 /* get the list of subkey names */
9470 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9471 data = printer->info_2->data;
9473 num_keys = get_printer_subkeys( data, key, &keynames );
9475 if ( num_keys == -1 ) {
9476 status = WERR_BADFILE;
9480 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9482 r_u->needed = printerkey_len*2;
9484 if ( q_u->size < r_u->needed ) {
9485 status = WERR_MORE_DATA;
9489 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9490 status = WERR_NOMEM;
9496 if ( q_u->size < r_u->needed )
9497 status = WERR_MORE_DATA;
9500 free_a_printer( &printer, 2 );
9501 SAFE_FREE( keynames );
9506 /****************************************************************
9507 _spoolss_DeletePrinterKey
9508 ****************************************************************/
9510 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9511 struct spoolss_DeletePrinterKey *r)
9513 POLICY_HND *handle = r->in.handle;
9514 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9515 NT_PRINTER_INFO_LEVEL *printer = NULL;
9519 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9522 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9523 OUR_HANDLE(handle)));
9527 /* if keyname == NULL, return error */
9529 if ( !r->in.key_name )
9530 return WERR_INVALID_PARAM;
9532 if (!get_printer_snum(p, handle, &snum, NULL))
9535 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9536 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9537 "printer properties change denied by handle\n"));
9538 return WERR_ACCESS_DENIED;
9541 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9542 if (!W_ERROR_IS_OK(status))
9545 /* delete the key and all subneys */
9547 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9549 if ( W_ERROR_IS_OK(status) )
9550 status = mod_a_printer(printer, 2);
9552 free_a_printer( &printer, 2 );
9558 /********************************************************************
9559 * spoolss_enumprinterdataex
9560 ********************************************************************/
9562 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9564 POLICY_HND *handle = &q_u->handle;
9565 uint32 in_size = q_u->size;
9568 NT_PRINTER_INFO_LEVEL *printer = NULL;
9569 PRINTER_ENUM_VALUES *enum_values = NULL;
9570 NT_PRINTER_DATA *p_data;
9572 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9577 REGISTRY_VALUE *val;
9582 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9585 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9590 * first check for a keyname of NULL or "". Win2k seems to send
9591 * this a lot and we should send back WERR_INVALID_PARAM
9592 * no need to spend time looking up the printer in this case.
9596 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9597 if ( !strlen(key) ) {
9598 result = WERR_INVALID_PARAM;
9602 /* get the printer off of disk */
9604 if (!get_printer_snum(p,handle, &snum, NULL))
9607 ZERO_STRUCT(printer);
9608 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9609 if (!W_ERROR_IS_OK(result))
9612 /* now look for a match on the key name */
9614 p_data = printer->info_2->data;
9616 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9617 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9619 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9620 result = WERR_INVALID_PARAM;
9627 /* allocate the memory for the array of pointers -- if necessary */
9629 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9632 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9634 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9635 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9636 result = WERR_NOMEM;
9640 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9644 * loop through all params and build the array to pass
9645 * back to the client
9648 for ( i=0; i<num_entries; i++ )
9650 /* lookup the registry value */
9652 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9653 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9657 value_name = regval_name( val );
9658 init_unistr( &enum_values[i].valuename, value_name );
9659 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9660 enum_values[i].type = regval_type( val );
9662 data_len = regval_size( val );
9664 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9666 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9668 result = WERR_NOMEM;
9672 enum_values[i].data_len = data_len;
9674 /* keep track of the size of the array in bytes */
9676 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9679 /* housekeeping information in the reply */
9681 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9682 * the hand marshalled container size is a multiple
9683 * of 4 bytes for RPC alignment.
9687 needed += 4-(needed % 4);
9690 r_u->needed = needed;
9691 r_u->returned = num_entries;
9693 if (needed > in_size) {
9694 result = WERR_MORE_DATA;
9698 /* copy data into the reply */
9700 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9701 response buffer size is != the offered buffer size
9703 r_u->ctr.size = r_u->needed;
9705 r_u->ctr.size = in_size;
9707 r_u->ctr.size_of_array = r_u->returned;
9708 r_u->ctr.values = enum_values;
9712 free_a_printer(&printer, 2);
9717 /****************************************************************************
9718 ****************************************************************************/
9720 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9721 const char *servername,
9722 const char *environment,
9723 struct spoolss_PrintProcessorDirectoryInfo1 *info1,
9727 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
9728 const char *short_archi;
9731 long_archi = environment;
9734 short_archi = get_short_archi(long_archi);
9736 return WERR_INVALID_ENVIRONMENT;
9739 /* I think this should look like this - gd
9740 info1->directory_name = talloc_asprintf(mem_ctx,
9741 "C:\\WINNT\\System32\\spool\\PRTPROCS\\%s", short_archi);
9743 info1->directory_name = talloc_strdup(mem_ctx,
9744 "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9746 if (!info1->directory_name) {
9750 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(info1, NULL, 0);
9752 if (*needed > offered) {
9753 return WERR_INSUFFICIENT_BUFFER;
9759 /****************************************************************
9760 _spoolss_GetPrintProcessorDirectory
9761 ****************************************************************/
9763 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9764 struct spoolss_GetPrintProcessorDirectory *r)
9768 /* that's an [in out] buffer */
9770 if (!r->in.buffer && (r->in.offered != 0)) {
9771 return WERR_INVALID_PARAM;
9774 if (r->in.offered > MAX_RPC_DATA_SIZE) {
9775 return WERR_INVALID_PARAM;
9778 DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n"));
9782 switch (r->in.level) {
9784 result = getprintprocessordirectory_level_1(p->mem_ctx,
9787 &r->out.info->info1,
9790 if (!W_ERROR_IS_OK(result)) {
9791 TALLOC_FREE(r->out.info);
9795 result = WERR_UNKNOWN_LEVEL;
9801 /*******************************************************************
9802 ********************************************************************/
9804 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9805 const char *dllname)
9807 enum ndr_err_code ndr_err;
9808 struct spoolss_MonitorUi ui;
9810 ui.dll_name = dllname;
9812 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9813 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9814 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9815 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9817 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9820 /*******************************************************************
9821 Streams the monitor UI DLL name in UNICODE
9822 *******************************************************************/
9824 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9825 NT_USER_TOKEN *token, DATA_BLOB *in,
9826 DATA_BLOB *out, uint32_t *needed)
9828 const char *dllname = "tcpmonui.dll";
9830 *needed = (strlen(dllname)+1) * 2;
9832 if (out->length < *needed) {
9833 return WERR_INSUFFICIENT_BUFFER;
9836 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9843 /*******************************************************************
9844 ********************************************************************/
9846 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9847 struct spoolss_PortData1 *port1,
9848 const DATA_BLOB *buf)
9850 enum ndr_err_code ndr_err;
9851 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9852 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9853 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9854 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9856 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9859 /*******************************************************************
9860 ********************************************************************/
9862 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9863 struct spoolss_PortData2 *port2,
9864 const DATA_BLOB *buf)
9866 enum ndr_err_code ndr_err;
9867 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9868 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9869 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9870 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9872 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9875 /*******************************************************************
9876 Create a new TCP/IP port
9877 *******************************************************************/
9879 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9880 NT_USER_TOKEN *token, DATA_BLOB *in,
9881 DATA_BLOB *out, uint32_t *needed)
9883 struct spoolss_PortData1 port1;
9884 struct spoolss_PortData2 port2;
9885 char *device_uri = NULL;
9888 const char *portname;
9889 const char *hostaddress;
9891 uint32_t port_number;
9894 /* peek for spoolss_PortData version */
9896 if (!in || (in->length < (128 + 4))) {
9897 return WERR_GENERAL_FAILURE;
9900 version = IVAL(in->data, 128);
9906 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9910 portname = port1.portname;
9911 hostaddress = port1.hostaddress;
9912 queue = port1.queue;
9913 protocol = port1.protocol;
9914 port_number = port1.port_number;
9920 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9924 portname = port2.portname;
9925 hostaddress = port2.hostaddress;
9926 queue = port2.queue;
9927 protocol = port2.protocol;
9928 port_number = port2.port_number;
9932 DEBUG(1,("xcvtcp_addport: "
9933 "unknown version of port_data: %d\n", version));
9934 return WERR_UNKNOWN_PORT;
9937 /* create the device URI and call the add_port_hook() */
9940 case PROTOCOL_RAWTCP_TYPE:
9941 device_uri = talloc_asprintf(mem_ctx,
9942 "socket://%s:%d/", hostaddress,
9946 case PROTOCOL_LPR_TYPE:
9947 device_uri = talloc_asprintf(mem_ctx,
9948 "lpr://%s/%s", hostaddress, queue );
9952 return WERR_UNKNOWN_PORT;
9959 return add_port_hook(mem_ctx, token, portname, device_uri);
9962 /*******************************************************************
9963 *******************************************************************/
9965 struct xcv_api_table xcvtcp_cmds[] = {
9966 { "MonitorUI", xcvtcp_monitorui },
9967 { "AddPort", xcvtcp_addport},
9971 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9972 NT_USER_TOKEN *token, const char *command,
9979 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9981 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9982 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9983 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9986 return WERR_BADFUNC;
9989 /*******************************************************************
9990 *******************************************************************/
9991 #if 0 /* don't support management using the "Local Port" monitor */
9993 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9994 NT_USER_TOKEN *token, DATA_BLOB *in,
9995 DATA_BLOB *out, uint32_t *needed)
9997 const char *dllname = "localui.dll";
9999 *needed = (strlen(dllname)+1) * 2;
10001 if (out->length < *needed) {
10002 return WERR_INSUFFICIENT_BUFFER;
10005 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
10012 /*******************************************************************
10013 *******************************************************************/
10015 struct xcv_api_table xcvlocal_cmds[] = {
10016 { "MonitorUI", xcvlocal_monitorui },
10020 struct xcv_api_table xcvlocal_cmds[] = {
10027 /*******************************************************************
10028 *******************************************************************/
10030 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10031 NT_USER_TOKEN *token, const char *command,
10032 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10037 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10039 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10040 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10041 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10043 return WERR_BADFUNC;
10046 /****************************************************************
10048 ****************************************************************/
10050 WERROR _spoolss_XcvData(pipes_struct *p,
10051 struct spoolss_XcvData *r)
10053 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10054 DATA_BLOB out_data;
10058 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10059 OUR_HANDLE(r->in.handle)));
10060 return WERR_BADFID;
10063 /* Has to be a handle to the TCP/IP port monitor */
10065 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10066 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10067 return WERR_BADFID;
10070 /* requires administrative access to the server */
10072 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10073 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10074 return WERR_ACCESS_DENIED;
10077 /* Allocate the outgoing buffer */
10079 if (r->in.out_data_size) {
10080 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10081 if (out_data.data == NULL) {
10086 switch ( Printer->printer_type ) {
10087 case SPLHND_PORTMON_TCP:
10088 werror = process_xcvtcp_command(p->mem_ctx,
10089 p->server_info->ptok,
10090 r->in.function_name,
10091 &r->in.in_data, &out_data,
10094 case SPLHND_PORTMON_LOCAL:
10095 werror = process_xcvlocal_command(p->mem_ctx,
10096 p->server_info->ptok,
10097 r->in.function_name,
10098 &r->in.in_data, &out_data,
10102 werror = WERR_INVALID_PRINT_MONITOR;
10105 if (!W_ERROR_IS_OK(werror)) {
10109 *r->out.status_code = 0;
10111 memcpy(r->out.out_data, out_data.data, out_data.length);
10116 /****************************************************************
10117 _spoolss_AddPrintProcessor
10118 ****************************************************************/
10120 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10121 struct spoolss_AddPrintProcessor *r)
10123 /* for now, just indicate success and ignore the add. We'll
10124 automatically set the winprint processor for printer
10125 entries later. Used to debug the LexMark Optra S 1855 PCL
10131 /****************************************************************
10132 _spoolss_EnumPrinters
10133 ****************************************************************/
10135 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10136 struct spoolss_EnumPrinters *r)
10138 p->rng_fault_state = true;
10139 return WERR_NOT_SUPPORTED;
10142 /****************************************************************
10144 ****************************************************************/
10146 WERROR _spoolss_GetJob(pipes_struct *p,
10147 struct spoolss_GetJob *r)
10149 p->rng_fault_state = true;
10150 return WERR_NOT_SUPPORTED;
10153 /****************************************************************
10155 ****************************************************************/
10157 WERROR _spoolss_EnumJobs(pipes_struct *p,
10158 struct spoolss_EnumJobs *r)
10160 p->rng_fault_state = true;
10161 return WERR_NOT_SUPPORTED;
10164 /****************************************************************
10165 _spoolss_AddPrinter
10166 ****************************************************************/
10168 WERROR _spoolss_AddPrinter(pipes_struct *p,
10169 struct spoolss_AddPrinter *r)
10171 p->rng_fault_state = true;
10172 return WERR_NOT_SUPPORTED;
10175 /****************************************************************
10176 _spoolss_GetPrinter
10177 ****************************************************************/
10179 WERROR _spoolss_GetPrinter(pipes_struct *p,
10180 struct spoolss_GetPrinter *r)
10182 p->rng_fault_state = true;
10183 return WERR_NOT_SUPPORTED;
10186 /****************************************************************
10187 _spoolss_EnumPrinterDrivers
10188 ****************************************************************/
10190 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10191 struct spoolss_EnumPrinterDrivers *r)
10193 p->rng_fault_state = true;
10194 return WERR_NOT_SUPPORTED;
10197 /****************************************************************
10198 _spoolss_GetPrinterDriver
10199 ****************************************************************/
10201 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10202 struct spoolss_GetPrinterDriver *r)
10204 p->rng_fault_state = true;
10205 return WERR_NOT_SUPPORTED;
10208 /****************************************************************
10209 _spoolss_EnumPrintProcessors
10210 ****************************************************************/
10212 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10213 struct spoolss_EnumPrintProcessors *r)
10215 p->rng_fault_state = true;
10216 return WERR_NOT_SUPPORTED;
10219 /****************************************************************
10220 _spoolss_ReadPrinter
10221 ****************************************************************/
10223 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10224 struct spoolss_ReadPrinter *r)
10226 p->rng_fault_state = true;
10227 return WERR_NOT_SUPPORTED;
10230 /****************************************************************
10231 _spoolss_GetPrinterData
10232 ****************************************************************/
10234 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10235 struct spoolss_GetPrinterData *r)
10237 p->rng_fault_state = true;
10238 return WERR_NOT_SUPPORTED;
10241 /****************************************************************
10242 _spoolss_SetPrinterData
10243 ****************************************************************/
10245 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10246 struct spoolss_SetPrinterData *r)
10248 p->rng_fault_state = true;
10249 return WERR_NOT_SUPPORTED;
10252 /****************************************************************
10253 _spoolss_WaitForPrinterChange
10254 ****************************************************************/
10256 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10257 struct spoolss_WaitForPrinterChange *r)
10259 p->rng_fault_state = true;
10260 return WERR_NOT_SUPPORTED;
10263 /****************************************************************
10265 ****************************************************************/
10267 WERROR _spoolss_EnumForms(pipes_struct *p,
10268 struct spoolss_EnumForms *r)
10270 p->rng_fault_state = true;
10271 return WERR_NOT_SUPPORTED;
10274 /****************************************************************
10276 ****************************************************************/
10278 WERROR _spoolss_EnumPorts(pipes_struct *p,
10279 struct spoolss_EnumPorts *r)
10281 p->rng_fault_state = true;
10282 return WERR_NOT_SUPPORTED;
10285 /****************************************************************
10286 _spoolss_EnumMonitors
10287 ****************************************************************/
10289 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10290 struct spoolss_EnumMonitors *r)
10292 p->rng_fault_state = true;
10293 return WERR_NOT_SUPPORTED;
10296 /****************************************************************
10298 ****************************************************************/
10300 WERROR _spoolss_AddPort(pipes_struct *p,
10301 struct spoolss_AddPort *r)
10303 p->rng_fault_state = true;
10304 return WERR_NOT_SUPPORTED;
10307 /****************************************************************
10308 _spoolss_ConfigurePort
10309 ****************************************************************/
10311 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10312 struct spoolss_ConfigurePort *r)
10314 p->rng_fault_state = true;
10315 return WERR_NOT_SUPPORTED;
10318 /****************************************************************
10319 _spoolss_DeletePort
10320 ****************************************************************/
10322 WERROR _spoolss_DeletePort(pipes_struct *p,
10323 struct spoolss_DeletePort *r)
10325 p->rng_fault_state = true;
10326 return WERR_NOT_SUPPORTED;
10329 /****************************************************************
10330 _spoolss_CreatePrinterIC
10331 ****************************************************************/
10333 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10334 struct spoolss_CreatePrinterIC *r)
10336 p->rng_fault_state = true;
10337 return WERR_NOT_SUPPORTED;
10340 /****************************************************************
10341 _spoolss_PlayGDIScriptOnPrinterIC
10342 ****************************************************************/
10344 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10345 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10347 p->rng_fault_state = true;
10348 return WERR_NOT_SUPPORTED;
10351 /****************************************************************
10352 _spoolss_DeletePrinterIC
10353 ****************************************************************/
10355 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10356 struct spoolss_DeletePrinterIC *r)
10358 p->rng_fault_state = true;
10359 return WERR_NOT_SUPPORTED;
10362 /****************************************************************
10363 _spoolss_AddPrinterConnection
10364 ****************************************************************/
10366 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10367 struct spoolss_AddPrinterConnection *r)
10369 p->rng_fault_state = true;
10370 return WERR_NOT_SUPPORTED;
10373 /****************************************************************
10374 _spoolss_DeletePrinterConnection
10375 ****************************************************************/
10377 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10378 struct spoolss_DeletePrinterConnection *r)
10380 p->rng_fault_state = true;
10381 return WERR_NOT_SUPPORTED;
10384 /****************************************************************
10385 _spoolss_PrinterMessageBox
10386 ****************************************************************/
10388 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10389 struct spoolss_PrinterMessageBox *r)
10391 p->rng_fault_state = true;
10392 return WERR_NOT_SUPPORTED;
10395 /****************************************************************
10396 _spoolss_AddMonitor
10397 ****************************************************************/
10399 WERROR _spoolss_AddMonitor(pipes_struct *p,
10400 struct spoolss_AddMonitor *r)
10402 p->rng_fault_state = true;
10403 return WERR_NOT_SUPPORTED;
10406 /****************************************************************
10407 _spoolss_DeleteMonitor
10408 ****************************************************************/
10410 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10411 struct spoolss_DeleteMonitor *r)
10413 p->rng_fault_state = true;
10414 return WERR_NOT_SUPPORTED;
10417 /****************************************************************
10418 _spoolss_DeletePrintProcessor
10419 ****************************************************************/
10421 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10422 struct spoolss_DeletePrintProcessor *r)
10424 p->rng_fault_state = true;
10425 return WERR_NOT_SUPPORTED;
10428 /****************************************************************
10429 _spoolss_AddPrintProvidor
10430 ****************************************************************/
10432 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10433 struct spoolss_AddPrintProvidor *r)
10435 p->rng_fault_state = true;
10436 return WERR_NOT_SUPPORTED;
10439 /****************************************************************
10440 _spoolss_DeletePrintProvidor
10441 ****************************************************************/
10443 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10444 struct spoolss_DeletePrintProvidor *r)
10446 p->rng_fault_state = true;
10447 return WERR_NOT_SUPPORTED;
10450 /****************************************************************
10451 _spoolss_EnumPrintProcDataTypes
10452 ****************************************************************/
10454 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10455 struct spoolss_EnumPrintProcDataTypes *r)
10457 p->rng_fault_state = true;
10458 return WERR_NOT_SUPPORTED;
10461 /****************************************************************
10462 _spoolss_GetPrinterDriver2
10463 ****************************************************************/
10465 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10466 struct spoolss_GetPrinterDriver2 *r)
10468 p->rng_fault_state = true;
10469 return WERR_NOT_SUPPORTED;
10472 /****************************************************************
10473 _spoolss_FindFirstPrinterChangeNotification
10474 ****************************************************************/
10476 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10477 struct spoolss_FindFirstPrinterChangeNotification *r)
10479 p->rng_fault_state = true;
10480 return WERR_NOT_SUPPORTED;
10483 /****************************************************************
10484 _spoolss_FindNextPrinterChangeNotification
10485 ****************************************************************/
10487 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10488 struct spoolss_FindNextPrinterChangeNotification *r)
10490 p->rng_fault_state = true;
10491 return WERR_NOT_SUPPORTED;
10494 /****************************************************************
10495 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10496 ****************************************************************/
10498 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10499 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10501 p->rng_fault_state = true;
10502 return WERR_NOT_SUPPORTED;
10505 /****************************************************************
10506 _spoolss_ReplyOpenPrinter
10507 ****************************************************************/
10509 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10510 struct spoolss_ReplyOpenPrinter *r)
10512 p->rng_fault_state = true;
10513 return WERR_NOT_SUPPORTED;
10516 /****************************************************************
10517 _spoolss_RouterReplyPrinter
10518 ****************************************************************/
10520 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10521 struct spoolss_RouterReplyPrinter *r)
10523 p->rng_fault_state = true;
10524 return WERR_NOT_SUPPORTED;
10527 /****************************************************************
10528 _spoolss_ReplyClosePrinter
10529 ****************************************************************/
10531 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10532 struct spoolss_ReplyClosePrinter *r)
10534 p->rng_fault_state = true;
10535 return WERR_NOT_SUPPORTED;
10538 /****************************************************************
10540 ****************************************************************/
10542 WERROR _spoolss_AddPortEx(pipes_struct *p,
10543 struct spoolss_AddPortEx *r)
10545 p->rng_fault_state = true;
10546 return WERR_NOT_SUPPORTED;
10549 /****************************************************************
10550 _spoolss_RouterFindFirstPrinterChangeNotification
10551 ****************************************************************/
10553 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10554 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10556 p->rng_fault_state = true;
10557 return WERR_NOT_SUPPORTED;
10560 /****************************************************************
10561 _spoolss_SpoolerInit
10562 ****************************************************************/
10564 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10565 struct spoolss_SpoolerInit *r)
10567 p->rng_fault_state = true;
10568 return WERR_NOT_SUPPORTED;
10571 /****************************************************************
10572 _spoolss_ResetPrinterEx
10573 ****************************************************************/
10575 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10576 struct spoolss_ResetPrinterEx *r)
10578 p->rng_fault_state = true;
10579 return WERR_NOT_SUPPORTED;
10582 /****************************************************************
10583 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10584 ****************************************************************/
10586 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10587 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10589 p->rng_fault_state = true;
10590 return WERR_NOT_SUPPORTED;
10593 /****************************************************************
10594 _spoolss_RouterReplyPrinterEx
10595 ****************************************************************/
10597 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10598 struct spoolss_RouterReplyPrinterEx *r)
10600 p->rng_fault_state = true;
10601 return WERR_NOT_SUPPORTED;
10604 /****************************************************************
10606 ****************************************************************/
10608 WERROR _spoolss_44(pipes_struct *p,
10609 struct spoolss_44 *r)
10611 p->rng_fault_state = true;
10612 return WERR_NOT_SUPPORTED;
10615 /****************************************************************
10617 ****************************************************************/
10619 WERROR _spoolss_47(pipes_struct *p,
10620 struct spoolss_47 *r)
10622 p->rng_fault_state = true;
10623 return WERR_NOT_SUPPORTED;
10626 /****************************************************************
10627 _spoolss_EnumPrinterData
10628 ****************************************************************/
10630 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10631 struct spoolss_EnumPrinterData *r)
10633 p->rng_fault_state = true;
10634 return WERR_NOT_SUPPORTED;
10637 /****************************************************************
10639 ****************************************************************/
10641 WERROR _spoolss_4a(pipes_struct *p,
10642 struct spoolss_4a *r)
10644 p->rng_fault_state = true;
10645 return WERR_NOT_SUPPORTED;
10648 /****************************************************************
10650 ****************************************************************/
10652 WERROR _spoolss_4b(pipes_struct *p,
10653 struct spoolss_4b *r)
10655 p->rng_fault_state = true;
10656 return WERR_NOT_SUPPORTED;
10659 /****************************************************************
10661 ****************************************************************/
10663 WERROR _spoolss_4c(pipes_struct *p,
10664 struct spoolss_4c *r)
10666 p->rng_fault_state = true;
10667 return WERR_NOT_SUPPORTED;
10670 /****************************************************************
10671 _spoolss_EnumPrinterDataEx
10672 ****************************************************************/
10674 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10675 struct spoolss_EnumPrinterDataEx *r)
10677 p->rng_fault_state = true;
10678 return WERR_NOT_SUPPORTED;
10681 /****************************************************************
10682 _spoolss_EnumPrinterKey
10683 ****************************************************************/
10685 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10686 struct spoolss_EnumPrinterKey *r)
10688 p->rng_fault_state = true;
10689 return WERR_NOT_SUPPORTED;
10692 /****************************************************************
10694 ****************************************************************/
10696 WERROR _spoolss_53(pipes_struct *p,
10697 struct spoolss_53 *r)
10699 p->rng_fault_state = true;
10700 return WERR_NOT_SUPPORTED;
10703 /****************************************************************
10705 ****************************************************************/
10707 WERROR _spoolss_55(pipes_struct *p,
10708 struct spoolss_55 *r)
10710 p->rng_fault_state = true;
10711 return WERR_NOT_SUPPORTED;
10714 /****************************************************************
10716 ****************************************************************/
10718 WERROR _spoolss_56(pipes_struct *p,
10719 struct spoolss_56 *r)
10721 p->rng_fault_state = true;
10722 return WERR_NOT_SUPPORTED;
10725 /****************************************************************
10727 ****************************************************************/
10729 WERROR _spoolss_57(pipes_struct *p,
10730 struct spoolss_57 *r)
10732 p->rng_fault_state = true;
10733 return WERR_NOT_SUPPORTED;
10736 /****************************************************************
10738 ****************************************************************/
10740 WERROR _spoolss_5a(pipes_struct *p,
10741 struct spoolss_5a *r)
10743 p->rng_fault_state = true;
10744 return WERR_NOT_SUPPORTED;
10747 /****************************************************************
10749 ****************************************************************/
10751 WERROR _spoolss_5b(pipes_struct *p,
10752 struct spoolss_5b *r)
10754 p->rng_fault_state = true;
10755 return WERR_NOT_SUPPORTED;
10758 /****************************************************************
10760 ****************************************************************/
10762 WERROR _spoolss_5c(pipes_struct *p,
10763 struct spoolss_5c *r)
10765 p->rng_fault_state = true;
10766 return WERR_NOT_SUPPORTED;
10769 /****************************************************************
10771 ****************************************************************/
10773 WERROR _spoolss_5d(pipes_struct *p,
10774 struct spoolss_5d *r)
10776 p->rng_fault_state = true;
10777 return WERR_NOT_SUPPORTED;
10780 /****************************************************************
10782 ****************************************************************/
10784 WERROR _spoolss_5e(pipes_struct *p,
10785 struct spoolss_5e *r)
10787 p->rng_fault_state = true;
10788 return WERR_NOT_SUPPORTED;
10791 /****************************************************************
10793 ****************************************************************/
10795 WERROR _spoolss_5f(pipes_struct *p,
10796 struct spoolss_5f *r)
10798 p->rng_fault_state = true;
10799 return WERR_NOT_SUPPORTED;