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 ) {
1090 rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd,
1091 data_len, data, p->notify.change, 0 );
1096 DEBUG(8,("send_notify2_changes: Exit...\n"));
1100 /***********************************************************************
1101 **********************************************************************/
1103 static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len )
1106 uint32 tv_sec, tv_usec;
1109 /* Unpack message */
1111 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f",
1114 offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd",
1116 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags);
1119 tdb_unpack((uint8 *)buf + offset, len - offset, "dd",
1120 &msg->notify.value[0], &msg->notify.value[1]);
1122 tdb_unpack((uint8 *)buf + offset, len - offset, "B",
1123 &msg->len, &msg->notify.data);
1125 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n",
1126 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags));
1128 tv->tv_sec = tv_sec;
1129 tv->tv_usec = tv_usec;
1132 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0],
1133 msg->notify.value[1]));
1135 dump_data(3, (uint8 *)msg->notify.data, msg->len);
1140 /********************************************************************
1141 Receive a notify2 message list
1142 ********************************************************************/
1144 static void receive_notify2_message_list(struct messaging_context *msg,
1147 struct server_id server_id,
1150 size_t msg_count, i;
1151 char *buf = (char *)data->data;
1154 SPOOLSS_NOTIFY_MSG notify;
1155 SPOOLSS_NOTIFY_MSG_CTR messages;
1158 if (data->length < 4) {
1159 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n"));
1163 msg_count = IVAL(buf, 0);
1166 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count));
1168 if (msg_count == 0) {
1169 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n"));
1173 /* initialize the container */
1175 ZERO_STRUCT( messages );
1176 notify_msg_ctr_init( &messages );
1179 * build message groups for each printer identified
1180 * in a change_notify msg. Remember that a PCN message
1181 * includes the handle returned for the srv_spoolss_replyopenprinter()
1182 * call. Therefore messages are grouped according to printer handle.
1185 for ( i=0; i<msg_count; i++ ) {
1186 struct timeval msg_tv;
1188 if (msg_ptr + 4 - buf > data->length) {
1189 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n"));
1193 msg_len = IVAL(msg_ptr,0);
1196 if (msg_ptr + msg_len - buf > data->length) {
1197 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n"));
1201 /* unpack messages */
1203 ZERO_STRUCT( notify );
1204 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len );
1207 /* add to correct list in container */
1209 notify_msg_ctr_addmsg( &messages, ¬ify );
1211 /* free memory that might have been allocated by notify2_unpack_msg() */
1213 if ( notify.len != 0 )
1214 SAFE_FREE( notify.notify.data );
1217 /* process each group of messages */
1219 num_groups = notify_msg_ctr_numgroups( &messages );
1220 for ( i=0; i<num_groups; i++ )
1221 send_notify2_changes( &messages, i );
1226 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count ));
1228 notify_msg_ctr_destroy( &messages );
1233 /********************************************************************
1234 Send a message to ourself about new driver being installed
1235 so we can upgrade the information for each printer bound to this
1237 ********************************************************************/
1239 static bool srv_spoolss_drv_upgrade_printer(char* drivername)
1241 int len = strlen(drivername);
1246 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n",
1249 messaging_send_buf(smbd_messaging_context(), procid_self(),
1250 MSG_PRINTER_DRVUPGRADE,
1251 (uint8 *)drivername, len+1);
1256 /**********************************************************************
1257 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate
1258 over all printers, upgrading ones as necessary
1259 **********************************************************************/
1261 void do_drv_upgrade_printer(struct messaging_context *msg,
1264 struct server_id server_id,
1269 int n_services = lp_numservices();
1272 len = MIN(data->length,sizeof(drivername)-1);
1273 strncpy(drivername, (const char *)data->data, len);
1275 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername ));
1277 /* Iterate the printer list */
1279 for (snum=0; snum<n_services; snum++)
1281 if (lp_snum_ok(snum) && lp_print_ok(snum) )
1284 NT_PRINTER_INFO_LEVEL *printer = NULL;
1286 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum));
1287 if (!W_ERROR_IS_OK(result))
1290 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername))
1292 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername));
1294 /* all we care about currently is the change_id */
1296 result = mod_a_printer(printer, 2);
1297 if (!W_ERROR_IS_OK(result)) {
1298 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n",
1299 win_errstr(result)));
1303 free_a_printer(&printer, 2);
1310 /********************************************************************
1311 Update the cache for all printq's with a registered client
1313 ********************************************************************/
1315 void update_monitored_printq_cache( void )
1317 Printer_entry *printer = printers_list;
1320 /* loop through all printers and update the cache where
1321 client_connected == True */
1324 if ( (printer->printer_type == SPLHND_PRINTER)
1325 && printer->notify.client_connected )
1327 snum = print_queue_snum(printer->sharename);
1328 print_queue_status( snum, NULL, NULL );
1331 printer = printer->next;
1336 /********************************************************************
1337 Send a message to ourself about new driver being installed
1338 so we can upgrade the information for each printer bound to this
1340 ********************************************************************/
1342 static bool srv_spoolss_reset_printerdata(char* drivername)
1344 int len = strlen(drivername);
1349 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n",
1352 messaging_send_buf(smbd_messaging_context(), procid_self(),
1353 MSG_PRINTERDATA_INIT_RESET,
1354 (uint8 *)drivername, len+1);
1359 /**********************************************************************
1360 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate
1361 over all printers, resetting printer data as neessary
1362 **********************************************************************/
1364 void reset_all_printerdata(struct messaging_context *msg,
1367 struct server_id server_id,
1372 int n_services = lp_numservices();
1375 len = MIN( data->length, sizeof(drivername)-1 );
1376 strncpy( drivername, (const char *)data->data, len );
1378 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername ));
1380 /* Iterate the printer list */
1382 for ( snum=0; snum<n_services; snum++ )
1384 if ( lp_snum_ok(snum) && lp_print_ok(snum) )
1387 NT_PRINTER_INFO_LEVEL *printer = NULL;
1389 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) );
1390 if ( !W_ERROR_IS_OK(result) )
1394 * if the printer is bound to the driver,
1395 * then reset to the new driver initdata
1398 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) )
1400 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername));
1402 if ( !set_driver_init(printer, 2) ) {
1403 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n",
1404 printer->info_2->printername, printer->info_2->drivername));
1407 result = mod_a_printer( printer, 2 );
1408 if ( !W_ERROR_IS_OK(result) ) {
1409 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n",
1410 get_dos_error_msg(result)));
1414 free_a_printer( &printer, 2 );
1423 /****************************************************************
1424 _spoolss_OpenPrinter
1425 ****************************************************************/
1427 WERROR _spoolss_OpenPrinter(pipes_struct *p,
1428 struct spoolss_OpenPrinter *r)
1430 struct spoolss_OpenPrinterEx e;
1433 ZERO_STRUCT(e.in.userlevel);
1435 e.in.printername = r->in.printername;
1436 e.in.datatype = r->in.datatype;
1437 e.in.devmode_ctr = r->in.devmode_ctr;
1438 e.in.access_mask = r->in.access_mask;
1441 e.out.handle = r->out.handle;
1443 werr = _spoolss_OpenPrinterEx(p, &e);
1445 if (W_ERROR_EQUAL(werr, WERR_INVALID_PARAM)) {
1446 /* OpenPrinterEx returns this for a bad
1447 * printer name. We must return WERR_INVALID_PRINTER_NAME
1450 werr = WERR_INVALID_PRINTER_NAME;
1456 /********************************************************************
1457 FIXME: temporary convert_devicemode_new function
1458 ********************************************************************/
1460 static bool convert_devicemode_new(const char *printername,
1461 struct spoolss_DeviceMode *devmode,
1462 NT_DEVICEMODE **pp_nt_devmode)
1464 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
1467 * Ensure nt_devmode is a valid pointer
1468 * as we will be overwriting it.
1471 if (nt_devmode == NULL) {
1472 DEBUG(5, ("convert_devicemode_new: allocating a generic devmode\n"));
1473 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
1477 rpcstr_push(nt_devmode->devicename, devmode->devicename, 31, 0);
1478 rpcstr_push(nt_devmode->formname, devmode->formname, 31, 0);
1480 nt_devmode->specversion = devmode->specversion;
1481 nt_devmode->driverversion = devmode->driverversion;
1482 nt_devmode->size = devmode->size;
1483 nt_devmode->fields = devmode->fields;
1484 nt_devmode->orientation = devmode->orientation;
1485 nt_devmode->papersize = devmode->papersize;
1486 nt_devmode->paperlength = devmode->paperlength;
1487 nt_devmode->paperwidth = devmode->paperwidth;
1488 nt_devmode->scale = devmode->scale;
1489 nt_devmode->copies = devmode->copies;
1490 nt_devmode->defaultsource = devmode->defaultsource;
1491 nt_devmode->printquality = devmode->printquality;
1492 nt_devmode->color = devmode->color;
1493 nt_devmode->duplex = devmode->duplex;
1494 nt_devmode->yresolution = devmode->yresolution;
1495 nt_devmode->ttoption = devmode->ttoption;
1496 nt_devmode->collate = devmode->collate;
1498 nt_devmode->logpixels = devmode->logpixels;
1499 nt_devmode->bitsperpel = devmode->bitsperpel;
1500 nt_devmode->pelswidth = devmode->pelswidth;
1501 nt_devmode->pelsheight = devmode->pelsheight;
1502 nt_devmode->displayflags = devmode->displayflags;
1503 nt_devmode->displayfrequency = devmode->displayfrequency;
1504 nt_devmode->icmmethod = devmode->icmmethod;
1505 nt_devmode->icmintent = devmode->icmintent;
1506 nt_devmode->mediatype = devmode->mediatype;
1507 nt_devmode->dithertype = devmode->dithertype;
1508 nt_devmode->reserved1 = devmode->reserved1;
1509 nt_devmode->reserved2 = devmode->reserved2;
1510 nt_devmode->panningwidth = devmode->panningwidth;
1511 nt_devmode->panningheight = devmode->panningheight;
1514 * Only change private and driverextra if the incoming devmode
1515 * has a new one. JRA.
1518 if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) {
1519 SAFE_FREE(nt_devmode->nt_dev_private);
1520 nt_devmode->driverextra = devmode->__driverextra_length;
1521 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
1523 memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra);
1526 *pp_nt_devmode = nt_devmode;
1531 /****************************************************************
1532 _spoolss_OpenPrinterEx
1533 ****************************************************************/
1535 WERROR _spoolss_OpenPrinterEx(pipes_struct *p,
1536 struct spoolss_OpenPrinterEx *r)
1538 POLICY_HND *handle = r->out.handle;
1539 char *name = CONST_DISCARD(char *, r->in.printername);
1541 Printer_entry *Printer=NULL;
1544 return WERR_INVALID_PARAM;
1547 /* some sanity check because you can open a printer or a print server */
1548 /* aka: \\server\printer or \\server */
1550 DEBUGADD(3,("checking name: %s\n",name));
1552 if (!open_printer_hnd(p, handle, name, 0)) {
1553 ZERO_STRUCTP(r->out.handle);
1554 return WERR_INVALID_PARAM;
1557 Printer=find_printer_index_by_hnd(p, handle);
1559 DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer "
1560 "handle we created for printer %s\n", name ));
1561 close_printer_handle(p,handle);
1562 ZERO_STRUCTP(r->out.handle);
1563 return WERR_INVALID_PARAM;
1567 * First case: the user is opening the print server:
1569 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k
1570 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed.
1572 * Then both Win2k and WinNT clients try an OpenPrinterEx with
1573 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0)
1574 * or if the user is listed in the smb.conf printer admin parameter.
1576 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the
1577 * client view printer folder, but does not show the MSAPW.
1579 * Note: this test needs code to check access rights here too. Jeremy
1580 * could you look at this?
1582 * Second case: the user is opening a printer:
1583 * NT doesn't let us connect to a printer if the connecting user
1584 * doesn't have print permission.
1586 * Third case: user is opening a Port Monitor
1587 * access checks same as opening a handle to the print server.
1590 switch (Printer->printer_type )
1593 case SPLHND_PORTMON_TCP:
1594 case SPLHND_PORTMON_LOCAL:
1595 /* Printserver handles use global struct... */
1599 /* Map standard access rights to object specific access rights */
1601 se_map_standard(&r->in.access_mask,
1602 &printserver_std_mapping);
1604 /* Deny any object specific bits that don't apply to print
1605 servers (i.e printer and job specific bits) */
1607 r->in.access_mask &= SPECIFIC_RIGHTS_MASK;
1609 if (r->in.access_mask &
1610 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) {
1611 DEBUG(3, ("access DENIED for non-printserver bits\n"));
1612 close_printer_handle(p, handle);
1613 ZERO_STRUCTP(r->out.handle);
1614 return WERR_ACCESS_DENIED;
1617 /* Allow admin access */
1619 if ( r->in.access_mask & SERVER_ACCESS_ADMINISTER )
1621 SE_PRIV se_printop = SE_PRINT_OPERATOR;
1623 if (!lp_ms_add_printer_wizard()) {
1624 close_printer_handle(p, handle);
1625 ZERO_STRUCTP(r->out.handle);
1626 return WERR_ACCESS_DENIED;
1629 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
1630 and not a printer admin, then fail */
1632 if ((p->server_info->utok.uid != 0) &&
1633 !user_has_privileges(p->server_info->ptok,
1635 !token_contains_name_in_list(
1636 uidtoname(p->server_info->utok.uid),
1638 p->server_info->ptok,
1639 lp_printer_admin(snum))) {
1640 close_printer_handle(p, handle);
1641 ZERO_STRUCTP(r->out.handle);
1642 return WERR_ACCESS_DENIED;
1645 r->in.access_mask = SERVER_ACCESS_ADMINISTER;
1649 r->in.access_mask = SERVER_ACCESS_ENUMERATE;
1652 DEBUG(4,("Setting print server access = %s\n", (r->in.access_mask == SERVER_ACCESS_ADMINISTER)
1653 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" ));
1655 /* We fall through to return WERR_OK */
1658 case SPLHND_PRINTER:
1659 /* NT doesn't let us connect to a printer if the connecting user
1660 doesn't have print permission. */
1662 if (!get_printer_snum(p, handle, &snum, NULL)) {
1663 close_printer_handle(p, handle);
1664 ZERO_STRUCTP(r->out.handle);
1668 se_map_standard(&r->in.access_mask, &printer_std_mapping);
1670 /* map an empty access mask to the minimum access mask */
1671 if (r->in.access_mask == 0x0)
1672 r->in.access_mask = PRINTER_ACCESS_USE;
1675 * If we are not serving the printer driver for this printer,
1676 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This
1677 * will keep NT clients happy --jerry
1680 if (lp_use_client_driver(snum)
1681 && (r->in.access_mask & PRINTER_ACCESS_ADMINISTER))
1683 r->in.access_mask = PRINTER_ACCESS_USE;
1686 /* check smb.conf parameters and the the sec_desc */
1688 if ( !check_access(get_client_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) {
1689 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n"));
1690 ZERO_STRUCTP(r->out.handle);
1691 return WERR_ACCESS_DENIED;
1694 if (!user_ok_token(uidtoname(p->server_info->utok.uid), NULL,
1695 p->server_info->ptok, snum) ||
1696 !print_access_check(p->server_info, snum,
1697 r->in.access_mask)) {
1698 DEBUG(3, ("access DENIED for printer open\n"));
1699 close_printer_handle(p, handle);
1700 ZERO_STRUCTP(r->out.handle);
1701 return WERR_ACCESS_DENIED;
1704 if ((r->in.access_mask & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) {
1705 DEBUG(3, ("access DENIED for printer open - unknown bits\n"));
1706 close_printer_handle(p, handle);
1707 ZERO_STRUCTP(r->out.handle);
1708 return WERR_ACCESS_DENIED;
1711 if (r->in.access_mask & PRINTER_ACCESS_ADMINISTER)
1712 r->in.access_mask = PRINTER_ACCESS_ADMINISTER;
1714 r->in.access_mask = PRINTER_ACCESS_USE;
1716 DEBUG(4,("Setting printer access = %s\n", (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1717 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" ));
1722 /* sanity check to prevent programmer error */
1723 ZERO_STRUCTP(r->out.handle);
1727 Printer->access_granted = r->in.access_mask;
1730 * If the client sent a devmode in the OpenPrinter() call, then
1731 * save it here in case we get a job submission on this handle
1734 if ( (Printer->printer_type != SPLHND_SERVER)
1735 && r->in.devmode_ctr.devmode )
1737 convert_devicemode_new(Printer->sharename,
1738 r->in.devmode_ctr.devmode,
1739 &Printer->nt_devmode);
1742 #if 0 /* JERRY -- I'm doubtful this is really effective */
1743 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN
1744 optimization in Windows 2000 clients --jerry */
1746 if ( (r->in.access_mask == PRINTER_ACCESS_ADMINISTER)
1747 && (RA_WIN2K == get_remote_arch()) )
1749 DEBUG(10,("_spoolss_OpenPrinterEx: Enabling LAN/WAN hack for Win2k clients.\n"));
1750 sys_usleep( 500000 );
1757 /****************************************************************************
1758 ****************************************************************************/
1760 static bool printer_info2_to_nt_printer_info2(struct spoolss_SetPrinterInfo2 *r,
1761 NT_PRINTER_INFO_LEVEL_2 *d)
1763 DEBUG(7,("printer_info2_to_nt_printer_info2\n"));
1769 d->attributes = r->attributes;
1770 d->priority = r->priority;
1771 d->default_priority = r->defaultpriority;
1772 d->starttime = r->starttime;
1773 d->untiltime = r->untiltime;
1774 d->status = r->status;
1775 d->cjobs = r->cjobs;
1777 fstrcpy(d->servername, r->servername);
1778 fstrcpy(d->printername, r->printername);
1779 fstrcpy(d->sharename, r->sharename);
1780 fstrcpy(d->portname, r->portname);
1781 fstrcpy(d->drivername, r->drivername);
1782 slprintf(d->comment, sizeof(d->comment)-1, "%s", r->comment);
1783 fstrcpy(d->location, r->location);
1784 fstrcpy(d->sepfile, r->sepfile);
1785 fstrcpy(d->printprocessor, r->printprocessor);
1786 fstrcpy(d->datatype, r->datatype);
1787 fstrcpy(d->parameters, r->parameters);
1792 /****************************************************************************
1793 ****************************************************************************/
1795 static bool convert_printer_info_new(struct spoolss_SetPrinterInfoCtr *info_ctr,
1796 NT_PRINTER_INFO_LEVEL *printer)
1800 switch (info_ctr->level) {
1802 /* allocate memory if needed. Messy because
1803 convert_printer_info is used to update an existing
1804 printer or build a new one */
1806 if (!printer->info_2) {
1807 printer->info_2 = TALLOC_ZERO_P(printer, NT_PRINTER_INFO_LEVEL_2);
1808 if (!printer->info_2) {
1809 DEBUG(0,("convert_printer_info_new: "
1810 "talloc() failed!\n"));
1815 ret = printer_info2_to_nt_printer_info2(info_ctr->info.info2,
1817 printer->info_2->setuptime = time(NULL);
1824 /*******************************************************************
1825 ********************************************************************/
1827 static bool string_array_to_fstring_array(const char **sarray, fstring **farray)
1836 *farray = SMB_MALLOC_ARRAY(fstring, 1);
1841 for (i=0; sarray[i] != NULL; i++) {
1842 *farray = SMB_REALLOC_ARRAY(*farray, fstring, i+2);
1846 fstrcpy((*farray)[i], sarray[i]);
1849 fstrcpy((*farray)[i], "");
1854 /*******************************************************************
1855 ********************************************************************/
1857 static bool driver_info3_to_nt_driver_info3(struct spoolss_AddDriverInfo3 *r,
1858 NT_PRINTER_DRIVER_INFO_LEVEL_3 **p)
1860 NT_PRINTER_DRIVER_INFO_LEVEL_3 *d;
1862 DEBUG(7,("driver_info3_to_nt_driver_info3: Converting from UNICODE to ASCII\n"));
1865 *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_3);
1874 d->cversion = r->version;
1876 fstrcpy(d->name, r->driver_name);
1877 fstrcpy(d->environment, r->architecture);
1878 fstrcpy(d->driverpath, r->driver_path);
1879 fstrcpy(d->datafile, r->data_file);
1880 fstrcpy(d->configfile, r->config_file);
1881 fstrcpy(d->helpfile, r->help_file);
1882 fstrcpy(d->monitorname, r->monitor_name);
1883 fstrcpy(d->defaultdatatype, r->default_datatype);
1885 DEBUGADD(8,( "version: %d\n", d->cversion));
1886 DEBUGADD(8,( "name: %s\n", d->name));
1887 DEBUGADD(8,( "environment: %s\n", d->environment));
1888 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
1889 DEBUGADD(8,( "datafile: %s\n", d->datafile));
1890 DEBUGADD(8,( "configfile: %s\n", d->configfile));
1891 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
1892 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
1893 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
1895 if (r->dependent_files) {
1896 if (!string_array_to_fstring_array(r->dependent_files->string,
1897 &d->dependentfiles)) {
1906 /*******************************************************************
1907 ********************************************************************/
1909 static bool driver_info6_to_nt_driver_info6(struct spoolss_AddDriverInfo6 *r,
1910 NT_PRINTER_DRIVER_INFO_LEVEL_6 **p)
1912 NT_PRINTER_DRIVER_INFO_LEVEL_6 *d;
1914 DEBUG(7,("driver_info6_to_nt_driver_info6: Converting from UNICODE to ASCII\n"));
1917 *p = SMB_MALLOC_P(NT_PRINTER_DRIVER_INFO_LEVEL_6);
1926 d->version = r->version;
1928 fstrcpy(d->name, r->driver_name);
1929 fstrcpy(d->environment, r->architecture);
1930 fstrcpy(d->driverpath, r->driver_path);
1931 fstrcpy(d->datafile, r->data_file);
1932 fstrcpy(d->configfile, r->config_file);
1933 fstrcpy(d->helpfile, r->help_file);
1934 fstrcpy(d->monitorname, r->monitor_name);
1935 fstrcpy(d->defaultdatatype, r->default_datatype);
1937 DEBUGADD(8,( "version: %d\n", d->version));
1938 DEBUGADD(8,( "name: %s\n", d->name));
1939 DEBUGADD(8,( "environment: %s\n", d->environment));
1940 DEBUGADD(8,( "driverpath: %s\n", d->driverpath));
1941 DEBUGADD(8,( "datafile: %s\n", d->datafile));
1942 DEBUGADD(8,( "configfile: %s\n", d->configfile));
1943 DEBUGADD(8,( "helpfile: %s\n", d->helpfile));
1944 DEBUGADD(8,( "monitorname: %s\n", d->monitorname));
1945 DEBUGADD(8,( "defaultdatatype: %s\n", d->defaultdatatype));
1947 if (r->dependent_files) {
1948 if (!string_array_to_fstring_array(r->dependent_files->string,
1949 &d->dependentfiles)) {
1954 if (r->previous_names) {
1955 if (!string_array_to_fstring_array(r->previous_names->string,
1956 &d->previousnames)) {
1968 /********************************************************************
1969 ********************************************************************/
1971 static bool convert_printer_driver_info(const struct spoolss_AddDriverInfoCtr *r,
1972 NT_PRINTER_DRIVER_INFO_LEVEL *printer,
1977 printer->info_3 = NULL;
1978 if (!driver_info3_to_nt_driver_info3(r->info.info3, &printer->info_3)) {
1983 printer->info_6 = NULL;
1984 if (!driver_info6_to_nt_driver_info6(r->info.info6, &printer->info_6)) {
1995 bool convert_devicemode(const char *printername, const DEVICEMODE *devmode,
1996 NT_DEVICEMODE **pp_nt_devmode)
1998 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode;
2001 * Ensure nt_devmode is a valid pointer
2002 * as we will be overwriting it.
2005 if (nt_devmode == NULL) {
2006 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n"));
2007 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL)
2011 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0);
2012 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0);
2014 nt_devmode->specversion=devmode->specversion;
2015 nt_devmode->driverversion=devmode->driverversion;
2016 nt_devmode->size=devmode->size;
2017 nt_devmode->fields=devmode->fields;
2018 nt_devmode->orientation=devmode->orientation;
2019 nt_devmode->papersize=devmode->papersize;
2020 nt_devmode->paperlength=devmode->paperlength;
2021 nt_devmode->paperwidth=devmode->paperwidth;
2022 nt_devmode->scale=devmode->scale;
2023 nt_devmode->copies=devmode->copies;
2024 nt_devmode->defaultsource=devmode->defaultsource;
2025 nt_devmode->printquality=devmode->printquality;
2026 nt_devmode->color=devmode->color;
2027 nt_devmode->duplex=devmode->duplex;
2028 nt_devmode->yresolution=devmode->yresolution;
2029 nt_devmode->ttoption=devmode->ttoption;
2030 nt_devmode->collate=devmode->collate;
2032 nt_devmode->logpixels=devmode->logpixels;
2033 nt_devmode->bitsperpel=devmode->bitsperpel;
2034 nt_devmode->pelswidth=devmode->pelswidth;
2035 nt_devmode->pelsheight=devmode->pelsheight;
2036 nt_devmode->displayflags=devmode->displayflags;
2037 nt_devmode->displayfrequency=devmode->displayfrequency;
2038 nt_devmode->icmmethod=devmode->icmmethod;
2039 nt_devmode->icmintent=devmode->icmintent;
2040 nt_devmode->mediatype=devmode->mediatype;
2041 nt_devmode->dithertype=devmode->dithertype;
2042 nt_devmode->reserved1=devmode->reserved1;
2043 nt_devmode->reserved2=devmode->reserved2;
2044 nt_devmode->panningwidth=devmode->panningwidth;
2045 nt_devmode->panningheight=devmode->panningheight;
2048 * Only change private and driverextra if the incoming devmode
2049 * has a new one. JRA.
2052 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) {
2053 SAFE_FREE(nt_devmode->nt_dev_private);
2054 nt_devmode->driverextra=devmode->driverextra;
2055 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL)
2057 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra);
2060 *pp_nt_devmode = nt_devmode;
2065 /********************************************************************
2066 * _spoolss_enddocprinter_internal.
2067 ********************************************************************/
2069 static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle)
2071 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2075 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
2079 if (!get_printer_snum(p, handle, &snum, NULL))
2082 Printer->document_started=False;
2083 print_job_end(snum, Printer->jobid,NORMAL_CLOSE);
2084 /* error codes unhandled so far ... */
2089 /****************************************************************
2090 _spoolss_ClosePrinter
2091 ****************************************************************/
2093 WERROR _spoolss_ClosePrinter(pipes_struct *p,
2094 struct spoolss_ClosePrinter *r)
2096 POLICY_HND *handle = r->in.handle;
2098 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2100 if (Printer && Printer->document_started)
2101 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2103 if (!close_printer_handle(p, handle))
2106 /* clear the returned printer handle. Observed behavior
2107 from Win2k server. Don't think this really matters.
2108 Previous code just copied the value of the closed
2111 ZERO_STRUCTP(r->out.handle);
2116 /****************************************************************
2117 _spoolss_DeletePrinter
2118 ****************************************************************/
2120 WERROR _spoolss_DeletePrinter(pipes_struct *p,
2121 struct spoolss_DeletePrinter *r)
2123 POLICY_HND *handle = r->in.handle;
2124 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2127 if (Printer && Printer->document_started)
2128 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */
2130 result = delete_printer_handle(p, handle);
2132 update_c_setprinter(False);
2137 /*******************************************************************
2138 * static function to lookup the version id corresponding to an
2139 * long architecture string
2140 ******************************************************************/
2142 static int get_version_id (char * arch)
2145 struct table_node archi_table[]= {
2147 {"Windows 4.0", "WIN40", 0 },
2148 {"Windows NT x86", "W32X86", 2 },
2149 {"Windows NT R4000", "W32MIPS", 2 },
2150 {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
2151 {"Windows NT PowerPC", "W32PPC", 2 },
2152 {"Windows IA64", "IA64", 3 },
2153 {"Windows x64", "x64", 3 },
2157 for (i=0; archi_table[i].long_archi != NULL; i++)
2159 if (strcmp(arch, archi_table[i].long_archi) == 0)
2160 return (archi_table[i].version);
2166 /****************************************************************
2167 _spoolss_DeletePrinterDriver
2168 ****************************************************************/
2170 WERROR _spoolss_DeletePrinterDriver(pipes_struct *p,
2171 struct spoolss_DeletePrinterDriver *r)
2175 NT_PRINTER_DRIVER_INFO_LEVEL info;
2176 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2179 WERROR status_win2k = WERR_ACCESS_DENIED;
2180 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2182 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2183 and not a printer admin, then fail */
2185 if ( (p->server_info->utok.uid != 0)
2186 && !user_has_privileges(p->server_info->ptok, &se_printop )
2187 && !token_contains_name_in_list(
2188 uidtoname(p->server_info->utok.uid), NULL,
2189 NULL, p->server_info->ptok,
2190 lp_printer_admin(-1)) )
2192 return WERR_ACCESS_DENIED;
2195 driver = CONST_DISCARD(char *, r->in.driver);
2196 arch = CONST_DISCARD(char *, r->in.architecture);
2198 /* check that we have a valid driver name first */
2200 if ((version=get_version_id(arch)) == -1)
2201 return WERR_INVALID_ENVIRONMENT;
2204 ZERO_STRUCT(info_win2k);
2206 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version)))
2208 /* try for Win2k driver if "Windows NT x86" */
2210 if ( version == 2 ) {
2212 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2213 status = WERR_UNKNOWN_PRINTER_DRIVER;
2217 /* otherwise it was a failure */
2219 status = WERR_UNKNOWN_PRINTER_DRIVER;
2225 if (printer_driver_in_use(info.info_3)) {
2226 status = WERR_PRINTER_DRIVER_IN_USE;
2232 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2234 /* if we get to here, we now have 2 driver info structures to remove */
2235 /* remove the Win2k driver first*/
2237 status_win2k = delete_printer_driver(
2238 p, info_win2k.info_3, 3, False );
2239 free_a_printer_driver( info_win2k, 3 );
2241 /* this should not have failed---if it did, report to client */
2242 if ( !W_ERROR_IS_OK(status_win2k) )
2244 status = status_win2k;
2250 status = delete_printer_driver(p, info.info_3, version, False);
2252 /* if at least one of the deletes succeeded return OK */
2254 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2258 free_a_printer_driver( info, 3 );
2263 /****************************************************************
2264 _spoolss_DeletePrinterDriverEx
2265 ****************************************************************/
2267 WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p,
2268 struct spoolss_DeletePrinterDriverEx *r)
2272 NT_PRINTER_DRIVER_INFO_LEVEL info;
2273 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k;
2275 uint32_t flags = r->in.delete_flags;
2278 WERROR status_win2k = WERR_ACCESS_DENIED;
2279 SE_PRIV se_printop = SE_PRINT_OPERATOR;
2281 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege,
2282 and not a printer admin, then fail */
2284 if ( (p->server_info->utok.uid != 0)
2285 && !user_has_privileges(p->server_info->ptok, &se_printop )
2286 && !token_contains_name_in_list(
2287 uidtoname(p->server_info->utok.uid), NULL, NULL,
2288 p->server_info->ptok, lp_printer_admin(-1)) )
2290 return WERR_ACCESS_DENIED;
2293 driver = CONST_DISCARD(char *, r->in.driver);
2294 arch = CONST_DISCARD(char *, r->in.architecture);
2296 /* check that we have a valid driver name first */
2297 if ((version=get_version_id(arch)) == -1) {
2298 /* this is what NT returns */
2299 return WERR_INVALID_ENVIRONMENT;
2302 if ( flags & DPD_DELETE_SPECIFIC_VERSION )
2303 version = r->in.version;
2306 ZERO_STRUCT(info_win2k);
2308 status = get_a_printer_driver(&info, 3, driver, arch, version);
2310 if ( !W_ERROR_IS_OK(status) )
2313 * if the client asked for a specific version,
2314 * or this is something other than Windows NT x86,
2318 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) )
2321 /* try for Win2k driver if "Windows NT x86" */
2324 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) {
2325 status = WERR_UNKNOWN_PRINTER_DRIVER;
2330 if ( printer_driver_in_use(info.info_3) ) {
2331 status = WERR_PRINTER_DRIVER_IN_USE;
2336 * we have a couple of cases to consider.
2337 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set,
2338 * then the delete should fail if **any** files overlap with
2340 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all
2341 * non-overlapping files
2342 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES
2343 * is set, the do not delete any files
2344 * Refer to MSDN docs on DeletePrinterDriverEx() for details.
2347 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES);
2349 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */
2351 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2352 /* no idea of the correct error here */
2353 status = WERR_ACCESS_DENIED;
2358 /* also check for W32X86/3 if necessary; maybe we already have? */
2360 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) {
2361 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3)))
2364 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) {
2365 /* no idea of the correct error here */
2366 free_a_printer_driver( info_win2k, 3 );
2367 status = WERR_ACCESS_DENIED;
2371 /* if we get to here, we now have 2 driver info structures to remove */
2372 /* remove the Win2k driver first*/
2374 status_win2k = delete_printer_driver(
2375 p, info_win2k.info_3, 3, delete_files);
2376 free_a_printer_driver( info_win2k, 3 );
2378 /* this should not have failed---if it did, report to client */
2380 if ( !W_ERROR_IS_OK(status_win2k) )
2385 status = delete_printer_driver(p, info.info_3, version, delete_files);
2387 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) )
2390 free_a_printer_driver( info, 3 );
2396 /****************************************************************************
2397 Internal routine for retreiving printerdata
2398 ***************************************************************************/
2400 static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer,
2401 const char *key, const char *value, uint32 *type, uint8 **data,
2402 uint32 *needed, uint32 in_size )
2404 REGISTRY_VALUE *val;
2408 if ( !(val = get_printer_data( printer->info_2, key, value)) )
2409 return WERR_BADFILE;
2411 *type = regval_type( val );
2413 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size));
2415 size = regval_size( val );
2417 /* copy the min(in_size, len) */
2420 data_len = (size > in_size) ? in_size : size*sizeof(uint8);
2422 /* special case for 0 length values */
2424 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL )
2428 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL )
2437 DEBUG(5,("get_printer_dataex: copy done\n"));
2442 /****************************************************************************
2443 Internal routine for removing printerdata
2444 ***************************************************************************/
2446 static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value )
2448 return delete_printer_data( printer->info_2, key, value );
2451 /****************************************************************************
2452 Internal routine for storing printerdata
2453 ***************************************************************************/
2455 WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value,
2456 uint32 type, uint8 *data, int real_len )
2458 /* the registry objects enforce uniqueness based on value name */
2460 return add_printer_data( printer->info_2, key, value, type, data, real_len );
2463 /********************************************************************
2464 GetPrinterData on a printer server Handle.
2465 ********************************************************************/
2467 static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size)
2471 DEBUG(8,("getprinterdata_printer_server:%s\n", value));
2473 if (!StrCaseCmp(value, "W3SvcInstalled")) {
2475 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2477 SIVAL(*data, 0, 0x00);
2482 if (!StrCaseCmp(value, "BeepEnabled")) {
2484 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2486 SIVAL(*data, 0, 0x00);
2491 if (!StrCaseCmp(value, "EventLog")) {
2493 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2495 /* formally was 0x1b */
2496 SIVAL(*data, 0, 0x0);
2501 if (!StrCaseCmp(value, "NetPopup")) {
2503 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2505 SIVAL(*data, 0, 0x00);
2510 if (!StrCaseCmp(value, "MajorVersion")) {
2512 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2515 /* Windows NT 4.0 seems to not allow uploading of drivers
2516 to a server that reports 0x3 as the MajorVersion.
2517 need to investigate more how Win2k gets around this .
2520 if ( RA_WINNT == get_remote_arch() )
2529 if (!StrCaseCmp(value, "MinorVersion")) {
2531 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2539 * uint32 size = 0x114
2541 * uint32 minor = [0|1]
2542 * uint32 build = [2195|2600]
2543 * extra unicode string = e.g. "Service Pack 3"
2545 if (!StrCaseCmp(value, "OSVersion")) {
2549 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) )
2552 SIVAL(*data, 0, *needed); /* size */
2553 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */
2555 SIVAL(*data, 12, 2195); /* build */
2557 /* leave extra string empty */
2563 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) {
2564 const char *string="C:\\PRINTERS";
2566 *needed = 2*(strlen(string)+1);
2567 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2569 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2571 /* it's done by hand ready to go on the wire */
2572 for (i=0; i<strlen(string); i++) {
2573 (*data)[2*i]=string[i];
2574 (*data)[2*i+1]='\0';
2579 if (!StrCaseCmp(value, "Architecture")) {
2580 const char *string="Windows NT x86";
2582 *needed = 2*(strlen(string)+1);
2583 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL)
2585 memset(*data, 0, (*needed > in_size) ? *needed:in_size);
2586 for (i=0; i<strlen(string); i++) {
2587 (*data)[2*i]=string[i];
2588 (*data)[2*i+1]='\0';
2593 if (!StrCaseCmp(value, "DsPresent")) {
2595 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) )
2598 /* only show the publish check box if we are a
2599 memeber of a AD domain */
2601 if ( lp_security() == SEC_ADS )
2602 SIVAL(*data, 0, 0x01);
2604 SIVAL(*data, 0, 0x00);
2610 if (!StrCaseCmp(value, "DNSMachineName")) {
2611 const char *hostname = get_mydnsfullname();
2614 return WERR_BADFILE;
2616 *needed = 2*(strlen(hostname)+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(hostname); i++) {
2621 (*data)[2*i]=hostname[i];
2622 (*data)[2*i+1]='\0';
2628 return WERR_BADFILE;
2631 /********************************************************************
2632 * spoolss_getprinterdata
2633 ********************************************************************/
2635 WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u)
2637 POLICY_HND *handle = &q_u->handle;
2638 UNISTR2 *valuename = &q_u->valuename;
2639 uint32 in_size = q_u->size;
2640 uint32 *type = &r_u->type;
2641 uint32 *out_size = &r_u->size;
2642 uint8 **data = &r_u->data;
2643 uint32 *needed = &r_u->needed;
2646 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
2647 NT_PRINTER_INFO_LEVEL *printer = NULL;
2651 * Reminder: when it's a string, the length is in BYTES
2652 * even if UNICODE is negociated.
2657 *out_size = in_size;
2659 /* in case of problem, return some default values */
2664 DEBUG(4,("_spoolss_getprinterdata\n"));
2667 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2668 status = WERR_BADFID;
2672 unistr2_to_ascii(value, valuename, sizeof(value));
2674 if ( Printer->printer_type == SPLHND_SERVER )
2675 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size );
2678 if ( !get_printer_snum(p,handle, &snum, NULL) ) {
2679 status = WERR_BADFID;
2683 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
2684 if ( !W_ERROR_IS_OK(status) )
2687 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */
2689 if ( strequal(value, "ChangeId") ) {
2691 *needed = sizeof(uint32);
2692 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) {
2693 status = WERR_NOMEM;
2696 SIVAL( *data, 0, printer->info_2->changeid );
2700 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size );
2703 if (*needed > *out_size)
2704 status = WERR_MORE_DATA;
2707 if ( !W_ERROR_IS_OK(status) )
2709 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size));
2711 /* reply this param doesn't exist */
2714 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) {
2716 free_a_printer( &printer, 2 );
2724 /* cleanup & exit */
2727 free_a_printer( &printer, 2 );
2732 /*********************************************************
2733 Connect to the client machine.
2734 **********************************************************/
2736 static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe,
2737 struct sockaddr_storage *client_ss, const char *remote_machine)
2740 struct cli_state *the_cli;
2741 struct sockaddr_storage rm_addr;
2743 if ( is_zero_addr((struct sockaddr *)client_ss) ) {
2744 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) {
2745 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine));
2749 if (ismyaddr((struct sockaddr *)&rm_addr)) {
2750 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine));
2754 char addr[INET6_ADDRSTRLEN];
2755 rm_addr = *client_ss;
2756 print_sockaddr(addr, sizeof(addr), &rm_addr);
2757 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n",
2761 /* setup the connection */
2763 ret = cli_full_connection( &the_cli, global_myname(), remote_machine,
2764 &rm_addr, 0, "IPC$", "IPC",
2768 0, lp_client_signing(), NULL );
2770 if ( !NT_STATUS_IS_OK( ret ) ) {
2771 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n",
2776 if ( the_cli->protocol != PROTOCOL_NT1 ) {
2777 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine));
2778 cli_shutdown(the_cli);
2783 * Ok - we have an anonymous connection to the IPC$ share.
2784 * Now start the NT Domain stuff :-).
2787 ret = cli_rpc_pipe_open_noauth(the_cli, &syntax_spoolss, pp_pipe);
2788 if (!NT_STATUS_IS_OK(ret)) {
2789 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n",
2790 remote_machine, nt_errstr(ret)));
2791 cli_shutdown(the_cli);
2798 /***************************************************************************
2799 Connect to the client.
2800 ****************************************************************************/
2802 static bool srv_spoolss_replyopenprinter(int snum, const char *printer,
2803 uint32 localprinter, uint32 type,
2804 POLICY_HND *handle, struct sockaddr_storage *client_ss)
2810 * If it's the first connection, contact the client
2811 * and connect to the IPC$ share anonymously
2813 if (smb_connections==0) {
2814 fstring unix_printer;
2816 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */
2818 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer ))
2821 messaging_register(smbd_messaging_context(), NULL,
2822 MSG_PRINTER_NOTIFY2,
2823 receive_notify2_message_list);
2824 /* Tell the connections db we're now interested in printer
2825 * notify messages. */
2826 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY );
2830 * Tell the specific printing tdb we want messages for this printer
2831 * by registering our PID.
2834 if (!print_notify_register_pid(snum))
2835 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer ));
2839 status = rpccli_spoolss_ReplyOpenPrinter(notify_cli_pipe, talloc_tos(),
2847 if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result))
2848 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n",
2849 win_errstr(result)));
2851 return (W_ERROR_IS_OK(result));
2854 /********************************************************************
2856 * ReplyFindFirstPrinterChangeNotifyEx
2858 * before replying OK: status=0 a rpc call is made to the workstation
2859 * asking ReplyOpenPrinter
2861 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe
2862 * called from api_spoolss_rffpcnex
2863 ********************************************************************/
2865 WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u)
2867 POLICY_HND *handle = &q_u->handle;
2868 uint32 flags = q_u->flags;
2869 uint32 options = q_u->options;
2870 UNISTR2 *localmachine = &q_u->localmachine;
2871 uint32 printerlocal = q_u->printerlocal;
2873 SPOOL_NOTIFY_OPTION *option = q_u->option;
2874 struct sockaddr_storage client_ss;
2876 /* store the notify value in the printer struct */
2878 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
2881 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
2885 Printer->notify.flags=flags;
2886 Printer->notify.options=options;
2887 Printer->notify.printerlocal=printerlocal;
2889 if (Printer->notify.option)
2890 free_spool_notify_option(&Printer->notify.option);
2892 Printer->notify.option=dup_spool_notify_option(option);
2894 unistr2_to_ascii(Printer->notify.localmachine, localmachine,
2895 sizeof(Printer->notify.localmachine));
2897 /* Connect to the client machine and send a ReplyOpenPrinter */
2899 if ( Printer->printer_type == SPLHND_SERVER)
2901 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
2902 !get_printer_snum(p, handle, &snum, NULL) )
2905 if (!interpret_string_addr(&client_ss, p->client_address,
2907 return WERR_SERVER_UNAVAILABLE;
2910 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine,
2911 Printer->notify.printerlocal, 1,
2912 &Printer->notify.client_hnd, &client_ss))
2913 return WERR_SERVER_UNAVAILABLE;
2915 Printer->notify.client_connected=True;
2920 /*******************************************************************
2921 * fill a notify_info_data with the servername
2922 ********************************************************************/
2924 void spoolss_notify_server_name(int snum,
2925 struct spoolss_Notify *data,
2926 print_queue_struct *queue,
2927 NT_PRINTER_INFO_LEVEL *printer,
2928 TALLOC_CTX *mem_ctx)
2930 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->servername);
2933 /*******************************************************************
2934 * fill a notify_info_data with the printername (not including the servername).
2935 ********************************************************************/
2937 void spoolss_notify_printer_name(int snum,
2938 struct spoolss_Notify *data,
2939 print_queue_struct *queue,
2940 NT_PRINTER_INFO_LEVEL *printer,
2941 TALLOC_CTX *mem_ctx)
2943 /* the notify name should not contain the \\server\ part */
2944 char *p = strrchr(printer->info_2->printername, '\\');
2947 p = printer->info_2->printername;
2952 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
2955 /*******************************************************************
2956 * fill a notify_info_data with the servicename
2957 ********************************************************************/
2959 void spoolss_notify_share_name(int snum,
2960 struct spoolss_Notify *data,
2961 print_queue_struct *queue,
2962 NT_PRINTER_INFO_LEVEL *printer,
2963 TALLOC_CTX *mem_ctx)
2965 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, lp_servicename(snum));
2968 /*******************************************************************
2969 * fill a notify_info_data with the port name
2970 ********************************************************************/
2972 void spoolss_notify_port_name(int snum,
2973 struct spoolss_Notify *data,
2974 print_queue_struct *queue,
2975 NT_PRINTER_INFO_LEVEL *printer,
2976 TALLOC_CTX *mem_ctx)
2978 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->portname);
2981 /*******************************************************************
2982 * fill a notify_info_data with the printername
2983 * but it doesn't exist, have to see what to do
2984 ********************************************************************/
2986 void spoolss_notify_driver_name(int snum,
2987 struct spoolss_Notify *data,
2988 print_queue_struct *queue,
2989 NT_PRINTER_INFO_LEVEL *printer,
2990 TALLOC_CTX *mem_ctx)
2992 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->drivername);
2995 /*******************************************************************
2996 * fill a notify_info_data with the comment
2997 ********************************************************************/
2999 void spoolss_notify_comment(int snum,
3000 struct spoolss_Notify *data,
3001 print_queue_struct *queue,
3002 NT_PRINTER_INFO_LEVEL *printer,
3003 TALLOC_CTX *mem_ctx)
3007 if (*printer->info_2->comment == '\0') {
3008 p = lp_comment(snum);
3010 p = printer->info_2->comment;
3013 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->comment);
3016 /*******************************************************************
3017 * fill a notify_info_data with the comment
3018 * location = "Room 1, floor 2, building 3"
3019 ********************************************************************/
3021 void spoolss_notify_location(int snum,
3022 struct spoolss_Notify *data,
3023 print_queue_struct *queue,
3024 NT_PRINTER_INFO_LEVEL *printer,
3025 TALLOC_CTX *mem_ctx)
3027 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->location);
3030 /*******************************************************************
3031 * fill a notify_info_data with the device mode
3032 * jfm:xxxx don't to it for know but that's a real problem !!!
3033 ********************************************************************/
3035 static void spoolss_notify_devmode(int snum,
3036 struct spoolss_Notify *data,
3037 print_queue_struct *queue,
3038 NT_PRINTER_INFO_LEVEL *printer,
3039 TALLOC_CTX *mem_ctx)
3041 /* for a dummy implementation we have to zero the fields */
3042 SETUP_SPOOLSS_NOTIFY_DATA_DEVMODE(data, NULL);
3045 /*******************************************************************
3046 * fill a notify_info_data with the separator file name
3047 ********************************************************************/
3049 void spoolss_notify_sepfile(int snum,
3050 struct spoolss_Notify *data,
3051 print_queue_struct *queue,
3052 NT_PRINTER_INFO_LEVEL *printer,
3053 TALLOC_CTX *mem_ctx)
3055 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->sepfile);
3058 /*******************************************************************
3059 * fill a notify_info_data with the print processor
3060 * jfm:xxxx return always winprint to indicate we don't do anything to it
3061 ********************************************************************/
3063 void spoolss_notify_print_processor(int snum,
3064 struct spoolss_Notify *data,
3065 print_queue_struct *queue,
3066 NT_PRINTER_INFO_LEVEL *printer,
3067 TALLOC_CTX *mem_ctx)
3069 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->printprocessor);
3072 /*******************************************************************
3073 * fill a notify_info_data with the print processor options
3074 * jfm:xxxx send an empty string
3075 ********************************************************************/
3077 void spoolss_notify_parameters(int snum,
3078 struct spoolss_Notify *data,
3079 print_queue_struct *queue,
3080 NT_PRINTER_INFO_LEVEL *printer,
3081 TALLOC_CTX *mem_ctx)
3083 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->parameters);
3086 /*******************************************************************
3087 * fill a notify_info_data with the data type
3088 * jfm:xxxx always send RAW as data type
3089 ********************************************************************/
3091 void spoolss_notify_datatype(int snum,
3092 struct spoolss_Notify *data,
3093 print_queue_struct *queue,
3094 NT_PRINTER_INFO_LEVEL *printer,
3095 TALLOC_CTX *mem_ctx)
3097 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, printer->info_2->datatype);
3100 /*******************************************************************
3101 * fill a notify_info_data with the security descriptor
3102 * jfm:xxxx send an null pointer to say no security desc
3103 * have to implement security before !
3104 ********************************************************************/
3106 static void spoolss_notify_security_desc(int snum,
3107 struct spoolss_Notify *data,
3108 print_queue_struct *queue,
3109 NT_PRINTER_INFO_LEVEL *printer,
3110 TALLOC_CTX *mem_ctx)
3112 SETUP_SPOOLSS_NOTIFY_DATA_SECDESC(data,
3113 printer->info_2->secdesc_buf->sd_size,
3114 printer->info_2->secdesc_buf->sd);
3117 /*******************************************************************
3118 * fill a notify_info_data with the attributes
3119 * jfm:xxxx a samba printer is always shared
3120 ********************************************************************/
3122 void spoolss_notify_attributes(int snum,
3123 struct spoolss_Notify *data,
3124 print_queue_struct *queue,
3125 NT_PRINTER_INFO_LEVEL *printer,
3126 TALLOC_CTX *mem_ctx)
3128 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->attributes);
3131 /*******************************************************************
3132 * fill a notify_info_data with the priority
3133 ********************************************************************/
3135 static void spoolss_notify_priority(int snum,
3136 struct spoolss_Notify *data,
3137 print_queue_struct *queue,
3138 NT_PRINTER_INFO_LEVEL *printer,
3139 TALLOC_CTX *mem_ctx)
3141 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->priority);
3144 /*******************************************************************
3145 * fill a notify_info_data with the default priority
3146 ********************************************************************/
3148 static void spoolss_notify_default_priority(int snum,
3149 struct spoolss_Notify *data,
3150 print_queue_struct *queue,
3151 NT_PRINTER_INFO_LEVEL *printer,
3152 TALLOC_CTX *mem_ctx)
3154 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->default_priority);
3157 /*******************************************************************
3158 * fill a notify_info_data with the start time
3159 ********************************************************************/
3161 static void spoolss_notify_start_time(int snum,
3162 struct spoolss_Notify *data,
3163 print_queue_struct *queue,
3164 NT_PRINTER_INFO_LEVEL *printer,
3165 TALLOC_CTX *mem_ctx)
3167 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->starttime);
3170 /*******************************************************************
3171 * fill a notify_info_data with the until time
3172 ********************************************************************/
3174 static void spoolss_notify_until_time(int snum,
3175 struct spoolss_Notify *data,
3176 print_queue_struct *queue,
3177 NT_PRINTER_INFO_LEVEL *printer,
3178 TALLOC_CTX *mem_ctx)
3180 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->untiltime);
3183 /*******************************************************************
3184 * fill a notify_info_data with the status
3185 ********************************************************************/
3187 static void spoolss_notify_status(int snum,
3188 struct spoolss_Notify *data,
3189 print_queue_struct *queue,
3190 NT_PRINTER_INFO_LEVEL *printer,
3191 TALLOC_CTX *mem_ctx)
3193 print_status_struct status;
3195 print_queue_length(snum, &status);
3196 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, status.status);
3199 /*******************************************************************
3200 * fill a notify_info_data with the number of jobs queued
3201 ********************************************************************/
3203 void spoolss_notify_cjobs(int snum,
3204 struct spoolss_Notify *data,
3205 print_queue_struct *queue,
3206 NT_PRINTER_INFO_LEVEL *printer,
3207 TALLOC_CTX *mem_ctx)
3209 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, print_queue_length(snum, NULL));
3212 /*******************************************************************
3213 * fill a notify_info_data with the average ppm
3214 ********************************************************************/
3216 static void spoolss_notify_average_ppm(int snum,
3217 struct spoolss_Notify *data,
3218 print_queue_struct *queue,
3219 NT_PRINTER_INFO_LEVEL *printer,
3220 TALLOC_CTX *mem_ctx)
3222 /* always respond 8 pages per minutes */
3223 /* a little hard ! */
3224 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, printer->info_2->averageppm);
3227 /*******************************************************************
3228 * fill a notify_info_data with username
3229 ********************************************************************/
3231 static void spoolss_notify_username(int snum,
3232 struct spoolss_Notify *data,
3233 print_queue_struct *queue,
3234 NT_PRINTER_INFO_LEVEL *printer,
3235 TALLOC_CTX *mem_ctx)
3237 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_user);
3240 /*******************************************************************
3241 * fill a notify_info_data with job status
3242 ********************************************************************/
3244 static void spoolss_notify_job_status(int snum,
3245 struct spoolss_Notify *data,
3246 print_queue_struct *queue,
3247 NT_PRINTER_INFO_LEVEL *printer,
3248 TALLOC_CTX *mem_ctx)
3250 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, nt_printj_status(queue->status));
3253 /*******************************************************************
3254 * fill a notify_info_data with job name
3255 ********************************************************************/
3257 static void spoolss_notify_job_name(int snum,
3258 struct spoolss_Notify *data,
3259 print_queue_struct *queue,
3260 NT_PRINTER_INFO_LEVEL *printer,
3261 TALLOC_CTX *mem_ctx)
3263 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, queue->fs_file);
3266 /*******************************************************************
3267 * fill a notify_info_data with job status
3268 ********************************************************************/
3270 static void spoolss_notify_job_status_string(int snum,
3271 struct spoolss_Notify *data,
3272 print_queue_struct *queue,
3273 NT_PRINTER_INFO_LEVEL *printer,
3274 TALLOC_CTX *mem_ctx)
3277 * Now we're returning job status codes we just return a "" here. JRA.
3282 #if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */
3285 switch (queue->status) {
3290 p = ""; /* NT provides the paused string */
3299 #endif /* NO LONGER NEEDED. */
3301 SETUP_SPOOLSS_NOTIFY_DATA_STRING(data, p);
3304 /*******************************************************************
3305 * fill a notify_info_data with job time
3306 ********************************************************************/
3308 static void spoolss_notify_job_time(int snum,
3309 struct spoolss_Notify *data,
3310 print_queue_struct *queue,
3311 NT_PRINTER_INFO_LEVEL *printer,
3312 TALLOC_CTX *mem_ctx)
3314 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3317 /*******************************************************************
3318 * fill a notify_info_data with job size
3319 ********************************************************************/
3321 static void spoolss_notify_job_size(int snum,
3322 struct spoolss_Notify *data,
3323 print_queue_struct *queue,
3324 NT_PRINTER_INFO_LEVEL *printer,
3325 TALLOC_CTX *mem_ctx)
3327 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->size);
3330 /*******************************************************************
3331 * fill a notify_info_data with page info
3332 ********************************************************************/
3333 static void spoolss_notify_total_pages(int snum,
3334 struct spoolss_Notify *data,
3335 print_queue_struct *queue,
3336 NT_PRINTER_INFO_LEVEL *printer,
3337 TALLOC_CTX *mem_ctx)
3339 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->page_count);
3342 /*******************************************************************
3343 * fill a notify_info_data with pages printed info.
3344 ********************************************************************/
3345 static void spoolss_notify_pages_printed(int snum,
3346 struct spoolss_Notify *data,
3347 print_queue_struct *queue,
3348 NT_PRINTER_INFO_LEVEL *printer,
3349 TALLOC_CTX *mem_ctx)
3351 /* Add code when back-end tracks this */
3352 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, 0);
3355 /*******************************************************************
3356 Fill a notify_info_data with job position.
3357 ********************************************************************/
3359 static void spoolss_notify_job_position(int snum,
3360 struct spoolss_Notify *data,
3361 print_queue_struct *queue,
3362 NT_PRINTER_INFO_LEVEL *printer,
3363 TALLOC_CTX *mem_ctx)
3365 SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(data, queue->job);
3368 /*******************************************************************
3369 Fill a notify_info_data with submitted time.
3370 ********************************************************************/
3372 static void spoolss_notify_submitted_time(int snum,
3373 struct spoolss_Notify *data,
3374 print_queue_struct *queue,
3375 NT_PRINTER_INFO_LEVEL *printer,
3376 TALLOC_CTX *mem_ctx)
3378 data->data.string.string = NULL;
3379 data->data.string.size = 0;
3381 init_systemtime_buffer(mem_ctx, gmtime(&queue->time),
3382 &data->data.string.string,
3383 &data->data.string.size);
3387 struct s_notify_info_data_table
3393 void (*fn) (int snum, struct spoolss_Notify *data,
3394 print_queue_struct *queue,
3395 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx);
3398 /* A table describing the various print notification constants and
3399 whether the notification data is a pointer to a variable sized
3400 buffer, a one value uint32 or a two value uint32. */
3402 static const struct s_notify_info_data_table notify_info_data_table[] =
3404 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3405 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3406 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name },
3407 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3408 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3409 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment },
3410 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location },
3411 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3412 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile },
3413 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3414 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3415 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3416 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc },
3417 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes },
3418 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3419 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority },
3420 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3421 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3422 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status },
3423 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL },
3424 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs },
3425 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm },
3426 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL },
3427 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL },
3428 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL },
3429 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL },
3430 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name },
3431 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name },
3432 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name },
3433 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username },
3434 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username },
3435 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype },
3436 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor },
3437 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters },
3438 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name },
3439 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode },
3440 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status },
3441 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string },
3442 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL },
3443 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name },
3444 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority },
3445 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position },
3446 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time },
3447 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time },
3448 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time },
3449 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time },
3450 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages },
3451 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed },
3452 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size },
3453 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3456 /*******************************************************************
3457 Return the size of info_data structure.
3458 ********************************************************************/
3460 static uint32 size_of_notify_info_data(uint16 type, uint16 field)
3464 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3465 if ( (notify_info_data_table[i].type == type)
3466 && (notify_info_data_table[i].field == field) ) {
3467 switch(notify_info_data_table[i].size) {
3468 case NOTIFY_ONE_VALUE:
3469 case NOTIFY_TWO_VALUE:
3474 /* The only pointer notify data I have seen on
3475 the wire is the submitted time and this has
3476 the notify size set to 4. -tpot */
3478 case NOTIFY_POINTER:
3481 case NOTIFY_SECDESC:
3487 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3492 /*******************************************************************
3493 Return the type of notify_info_data.
3494 ********************************************************************/
3496 static uint32 type_of_notify_info_data(uint16 type, uint16 field)
3500 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) {
3501 if (notify_info_data_table[i].type == type &&
3502 notify_info_data_table[i].field == field)
3503 return notify_info_data_table[i].size;
3509 /****************************************************************************
3510 ****************************************************************************/
3512 static bool search_notify(uint16 type, uint16 field, int *value)
3516 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3517 if (notify_info_data_table[i].type == type &&
3518 notify_info_data_table[i].field == field &&
3519 notify_info_data_table[i].fn != NULL) {
3528 /****************************************************************************
3529 ****************************************************************************/
3531 void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id)
3533 info_data->type = type;
3534 info_data->field = field;
3535 info_data->variable_type = size_of_notify_info_data(type, field);
3536 info_data->job_id = id;
3539 /*******************************************************************
3541 * fill a notify_info struct with info asked
3543 ********************************************************************/
3545 static bool construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int
3546 snum, SPOOL_NOTIFY_OPTION_TYPE
3547 *option_type, uint32 id,
3548 TALLOC_CTX *mem_ctx)
3554 struct spoolss_Notify *current_data;
3555 NT_PRINTER_INFO_LEVEL *printer = NULL;
3556 print_queue_struct *queue=NULL;
3558 type=option_type->type;
3560 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3561 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3562 option_type->count, lp_servicename(snum)));
3564 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3567 for(field_num=0; field_num<option_type->count; field_num++) {
3568 field = option_type->fields[field_num];
3570 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3572 if (!search_notify(type, field, &j) )
3575 if((info->data=SMB_REALLOC_ARRAY(info->data, struct spoolss_Notify, info->count+1)) == NULL) {
3576 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3577 free_a_printer(&printer, 2);
3581 current_data = &info->data[info->count];
3583 construct_info_data(current_data, type, field, id);
3585 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3586 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3588 notify_info_data_table[j].fn(snum, current_data, queue,
3594 free_a_printer(&printer, 2);
3598 /*******************************************************************
3600 * fill a notify_info struct with info asked
3602 ********************************************************************/
3604 static bool construct_notify_jobs_info(print_queue_struct *queue,
3605 SPOOL_NOTIFY_INFO *info,
3606 NT_PRINTER_INFO_LEVEL *printer,
3607 int snum, SPOOL_NOTIFY_OPTION_TYPE
3608 *option_type, uint32 id,
3609 TALLOC_CTX *mem_ctx)
3615 struct spoolss_Notify *current_data;
3617 DEBUG(4,("construct_notify_jobs_info\n"));
3619 type = option_type->type;
3621 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3622 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3623 option_type->count));
3625 for(field_num=0; field_num<option_type->count; field_num++) {
3626 field = option_type->fields[field_num];
3628 if (!search_notify(type, field, &j) )
3631 if((info->data=SMB_REALLOC_ARRAY(info->data, struct spoolss_Notify, info->count+1)) == NULL) {
3632 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3636 current_data=&(info->data[info->count]);
3638 construct_info_data(current_data, type, field, id);
3639 notify_info_data_table[j].fn(snum, current_data, queue,
3648 * JFM: The enumeration is not that simple, it's even non obvious.
3650 * let's take an example: I want to monitor the PRINTER SERVER for
3651 * the printer's name and the number of jobs currently queued.
3652 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3653 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3655 * I have 3 printers on the back of my server.
3657 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3660 * 1 printer 1 name 1
3661 * 2 printer 1 cjob 1
3662 * 3 printer 2 name 2
3663 * 4 printer 2 cjob 2
3664 * 5 printer 3 name 3
3665 * 6 printer 3 name 3
3667 * that's the print server case, the printer case is even worse.
3670 /*******************************************************************
3672 * enumerate all printers on the printserver
3673 * fill a notify_info struct with info asked
3675 ********************************************************************/
3677 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3678 SPOOL_NOTIFY_INFO *info,
3679 TALLOC_CTX *mem_ctx)
3682 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3683 int n_services=lp_numservices();
3685 SPOOL_NOTIFY_OPTION *option;
3686 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3688 DEBUG(4,("printserver_notify_info\n"));
3693 option=Printer->notify.option;
3698 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3699 sending a ffpcn() request first */
3704 for (i=0; i<option->count; i++) {
3705 option_type=&(option->ctr.type[i]);
3707 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3710 for (snum=0; snum<n_services; snum++)
3712 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3713 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3719 * Debugging information, don't delete.
3722 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3723 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3724 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3726 for (i=0; i<info->count; i++) {
3727 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3728 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3729 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3736 /*******************************************************************
3738 * fill a notify_info struct with info asked
3740 ********************************************************************/
3742 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info,
3743 TALLOC_CTX *mem_ctx)
3746 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3749 SPOOL_NOTIFY_OPTION *option;
3750 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3752 print_queue_struct *queue=NULL;
3753 print_status_struct status;
3755 DEBUG(4,("printer_notify_info\n"));
3760 option=Printer->notify.option;
3766 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3767 sending a ffpcn() request first */
3772 get_printer_snum(p, hnd, &snum, NULL);
3774 for (i=0; i<option->count; i++) {
3775 option_type=&option->ctr.type[i];
3777 switch ( option_type->type ) {
3778 case PRINTER_NOTIFY_TYPE:
3779 if(construct_notify_printer_info(Printer, info, snum,
3785 case JOB_NOTIFY_TYPE: {
3786 NT_PRINTER_INFO_LEVEL *printer = NULL;
3788 count = print_queue_status(snum, &queue, &status);
3790 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3793 for (j=0; j<count; j++) {
3794 construct_notify_jobs_info(&queue[j], info,
3801 free_a_printer(&printer, 2);
3811 * Debugging information, don't delete.
3814 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3815 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3816 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3818 for (i=0; i<info->count; i++) {
3819 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3820 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3821 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3827 /********************************************************************
3829 ********************************************************************/
3831 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
3833 POLICY_HND *handle = &q_u->handle;
3834 SPOOL_NOTIFY_INFO *info = &r_u->info;
3836 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3837 WERROR result = WERR_BADFID;
3839 /* we always have a NOTIFY_INFO struct */
3843 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3844 OUR_HANDLE(handle)));
3848 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3851 * We are now using the change value, and
3852 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3853 * I don't have a global notification system, I'm sending back all the
3854 * informations even when _NOTHING_ has changed.
3857 /* We need to keep track of the change value to send back in
3858 RRPCN replies otherwise our updates are ignored. */
3860 Printer->notify.fnpcn = True;
3862 if (Printer->notify.client_connected) {
3863 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
3864 Printer->notify.change = q_u->change;
3867 /* just ignore the SPOOL_NOTIFY_OPTION */
3869 switch (Printer->printer_type) {
3871 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3874 case SPLHND_PRINTER:
3875 result = printer_notify_info(p, handle, info, p->mem_ctx);
3879 Printer->notify.fnpcn = False;
3885 /********************************************************************
3886 * construct_printer_info_0
3887 * fill a printer_info_0 struct
3888 ********************************************************************/
3890 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3892 char *chaine = NULL;
3894 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3895 counter_printer_0 *session_counter;
3896 uint32 global_counter;
3899 print_status_struct status;
3900 TALLOC_CTX *ctx = talloc_tos();
3902 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3905 init_unistr(&printer->printername, ntprinter->info_2->printername);
3907 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3909 free_a_printer(&ntprinter,2);
3913 count = print_queue_length(snum, &status);
3915 /* check if we already have a counter for this printer */
3916 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3917 if (session_counter->snum == snum)
3921 init_unistr(&printer->servername, chaine);
3923 /* it's the first time, add it to the list */
3924 if (session_counter==NULL) {
3925 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3926 free_a_printer(&ntprinter, 2);
3929 ZERO_STRUCTP(session_counter);
3930 session_counter->snum=snum;
3931 session_counter->counter=0;
3932 DLIST_ADD(counter_list, session_counter);
3936 session_counter->counter++;
3939 * the global_counter should be stored in a TDB as it's common to all the clients
3940 * and should be zeroed on samba startup
3942 global_counter=session_counter->counter;
3943 printer->cjobs = count;
3944 printer->total_jobs = 0;
3945 printer->total_bytes = 0;
3947 setuptime = (time_t)ntprinter->info_2->setuptime;
3948 t=gmtime(&setuptime);
3950 printer->year = t->tm_year+1900;
3951 printer->month = t->tm_mon+1;
3952 printer->dayofweek = t->tm_wday;
3953 printer->day = t->tm_mday;
3954 printer->hour = t->tm_hour;
3955 printer->minute = t->tm_min;
3956 printer->second = t->tm_sec;
3957 printer->milliseconds = 0;
3959 printer->global_counter = global_counter;
3960 printer->total_pages = 0;
3962 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3963 printer->major_version = 0x0005; /* NT 5 */
3964 printer->build_version = 0x0893; /* build 2195 */
3966 printer->unknown7 = 0x1;
3967 printer->unknown8 = 0x0;
3968 printer->unknown9 = 0x0;
3969 printer->session_counter = session_counter->counter;
3970 printer->unknown11 = 0x0;
3971 printer->printer_errors = 0x0; /* number of print failure */
3972 printer->unknown13 = 0x0;
3973 printer->unknown14 = 0x1;
3974 printer->unknown15 = 0x024a; /* 586 Pentium ? */
3975 printer->unknown16 = 0x0;
3976 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3977 printer->unknown18 = 0x0;
3978 printer->status = nt_printq_status(status.status);
3979 printer->unknown20 = 0x0;
3980 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3981 printer->unknown22 = 0x0;
3982 printer->unknown23 = 0x6; /* 6 ???*/
3983 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
3984 printer->unknown25 = 0;
3985 printer->unknown26 = 0;
3986 printer->unknown27 = 0;
3987 printer->unknown28 = 0;
3988 printer->unknown29 = 0;
3990 free_a_printer(&ntprinter,2);
3994 /********************************************************************
3995 * construct_printer_info_1
3996 * fill a printer_info_1 struct
3997 ********************************************************************/
3998 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
4000 char *chaine = NULL;
4001 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4002 TALLOC_CTX *ctx = talloc_tos();
4004 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4007 printer->flags=flags;
4009 if (*ntprinter->info_2->comment == '\0') {
4010 init_unistr(&printer->comment, lp_comment(snum));
4011 chaine = talloc_asprintf(ctx,
4012 "%s,%s,%s", ntprinter->info_2->printername,
4013 ntprinter->info_2->drivername, lp_comment(snum));
4016 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4017 chaine = talloc_asprintf(ctx,
4018 "%s,%s,%s", ntprinter->info_2->printername,
4019 ntprinter->info_2->drivername, ntprinter->info_2->comment);
4023 free_a_printer(&ntprinter,2);
4027 init_unistr(&printer->description, chaine);
4028 init_unistr(&printer->name, ntprinter->info_2->printername);
4030 free_a_printer(&ntprinter,2);
4035 /****************************************************************************
4036 Free a DEVMODE struct.
4037 ****************************************************************************/
4039 static void free_dev_mode(DEVICEMODE *dev)
4044 SAFE_FREE(dev->dev_private);
4049 /****************************************************************************
4050 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4051 should be valid upon entry
4052 ****************************************************************************/
4054 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4056 if ( !devmode || !ntdevmode )
4059 init_unistr(&devmode->devicename, ntdevmode->devicename);
4061 init_unistr(&devmode->formname, ntdevmode->formname);
4063 devmode->specversion = ntdevmode->specversion;
4064 devmode->driverversion = ntdevmode->driverversion;
4065 devmode->size = ntdevmode->size;
4066 devmode->driverextra = ntdevmode->driverextra;
4067 devmode->fields = ntdevmode->fields;
4069 devmode->orientation = ntdevmode->orientation;
4070 devmode->papersize = ntdevmode->papersize;
4071 devmode->paperlength = ntdevmode->paperlength;
4072 devmode->paperwidth = ntdevmode->paperwidth;
4073 devmode->scale = ntdevmode->scale;
4074 devmode->copies = ntdevmode->copies;
4075 devmode->defaultsource = ntdevmode->defaultsource;
4076 devmode->printquality = ntdevmode->printquality;
4077 devmode->color = ntdevmode->color;
4078 devmode->duplex = ntdevmode->duplex;
4079 devmode->yresolution = ntdevmode->yresolution;
4080 devmode->ttoption = ntdevmode->ttoption;
4081 devmode->collate = ntdevmode->collate;
4082 devmode->icmmethod = ntdevmode->icmmethod;
4083 devmode->icmintent = ntdevmode->icmintent;
4084 devmode->mediatype = ntdevmode->mediatype;
4085 devmode->dithertype = ntdevmode->dithertype;
4087 if (ntdevmode->nt_dev_private != NULL) {
4088 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4095 /****************************************************************************
4096 Create a DEVMODE struct. Returns malloced memory.
4097 ****************************************************************************/
4099 DEVICEMODE *construct_dev_mode(const char *servicename)
4101 NT_PRINTER_INFO_LEVEL *printer = NULL;
4102 DEVICEMODE *devmode = NULL;
4104 DEBUG(7,("construct_dev_mode\n"));
4106 DEBUGADD(8,("getting printer characteristics\n"));
4108 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4111 if ( !printer->info_2->devmode ) {
4112 DEBUG(5, ("BONG! There was no device mode!\n"));
4116 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4117 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4121 ZERO_STRUCTP(devmode);
4123 DEBUGADD(8,("loading DEVICEMODE\n"));
4125 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4126 free_dev_mode( devmode );
4131 free_a_printer(&printer,2);
4136 /********************************************************************
4137 * construct_printer_info_2
4138 * fill a printer_info_2 struct
4139 ********************************************************************/
4141 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4144 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4146 print_status_struct status;
4148 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4151 count = print_queue_length(snum, &status);
4153 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4154 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4155 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4156 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4157 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4159 if (*ntprinter->info_2->comment == '\0')
4160 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4162 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4164 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4165 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4166 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4167 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4168 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4170 printer->attributes = ntprinter->info_2->attributes;
4172 printer->priority = ntprinter->info_2->priority; /* priority */
4173 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4174 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4175 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4176 printer->status = nt_printq_status(status.status); /* status */
4177 printer->cjobs = count; /* jobs */
4178 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4180 if ( !(printer->devmode = construct_dev_mode(
4181 lp_const_servicename(snum))) )
4182 DEBUG(8, ("Returning NULL Devicemode!\n"));
4184 printer->secdesc = NULL;
4186 if ( ntprinter->info_2->secdesc_buf
4187 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4189 /* don't use talloc_steal() here unless you do a deep steal of all
4190 the SEC_DESC members */
4192 printer->secdesc = dup_sec_desc( talloc_tos(),
4193 ntprinter->info_2->secdesc_buf->sd );
4196 free_a_printer(&ntprinter, 2);
4201 /********************************************************************
4202 * construct_printer_info_3
4203 * fill a printer_info_3 struct
4204 ********************************************************************/
4206 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4208 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4209 PRINTER_INFO_3 *printer = NULL;
4211 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4215 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4216 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4217 free_a_printer(&ntprinter, 2);
4221 ZERO_STRUCTP(printer);
4223 /* These are the components of the SD we are returning. */
4225 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4226 /* don't use talloc_steal() here unless you do a deep steal of all
4227 the SEC_DESC members */
4229 printer->secdesc = dup_sec_desc( talloc_tos(),
4230 ntprinter->info_2->secdesc_buf->sd );
4233 free_a_printer(&ntprinter, 2);
4235 *pp_printer = printer;
4239 /********************************************************************
4240 * construct_printer_info_4
4241 * fill a printer_info_4 struct
4242 ********************************************************************/
4244 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4246 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4248 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4251 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4252 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4253 printer->attributes = ntprinter->info_2->attributes;
4255 free_a_printer(&ntprinter, 2);
4259 /********************************************************************
4260 * construct_printer_info_5
4261 * fill a printer_info_5 struct
4262 ********************************************************************/
4264 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4266 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4268 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4271 init_unistr(&printer->printername, ntprinter->info_2->printername);
4272 init_unistr(&printer->portname, ntprinter->info_2->portname);
4273 printer->attributes = ntprinter->info_2->attributes;
4275 /* these two are not used by NT+ according to MSDN */
4277 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4278 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4280 free_a_printer(&ntprinter, 2);
4285 /********************************************************************
4286 * construct_printer_info_6
4287 * fill a printer_info_6 struct
4288 ********************************************************************/
4290 static bool construct_printer_info_6(Printer_entry *print_hnd,
4291 PRINTER_INFO_6 *printer,
4294 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4296 print_status_struct status;
4298 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4299 lp_const_servicename(snum))))
4302 count = print_queue_length(snum, &status);
4304 printer->status = nt_printq_status(status.status);
4306 free_a_printer(&ntprinter, 2);
4311 /********************************************************************
4312 * construct_printer_info_7
4313 * fill a printer_info_7 struct
4314 ********************************************************************/
4316 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4318 char *guid_str = NULL;
4321 if (is_printer_published(print_hnd, snum, &guid)) {
4322 if (asprintf(&guid_str, "{%s}",
4323 GUID_string(talloc_tos(), &guid)) == -1) {
4326 strupper_m(guid_str);
4327 init_unistr(&printer->guid, guid_str);
4328 SAFE_FREE(guid_str);
4329 printer->action = SPOOL_DS_PUBLISH;
4331 init_unistr(&printer->guid, "");
4332 printer->action = SPOOL_DS_UNPUBLISH;
4338 /********************************************************************
4339 Spoolss_enumprinters.
4340 ********************************************************************/
4342 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4346 int n_services=lp_numservices();
4347 PRINTER_INFO_1 *printers=NULL;
4348 PRINTER_INFO_1 current_prt;
4349 WERROR result = WERR_OK;
4351 DEBUG(4,("enum_all_printers_info_1\n"));
4353 for (snum=0; snum<n_services; snum++) {
4354 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4355 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4357 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4358 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4359 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4363 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4365 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4371 /* check the required size. */
4372 for (i=0; i<*returned; i++)
4373 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4375 if (*needed > offered) {
4376 result = WERR_INSUFFICIENT_BUFFER;
4380 if (!rpcbuf_alloc_size(buffer, *needed)) {
4381 result = WERR_NOMEM;
4385 /* fill the buffer with the structures */
4386 for (i=0; i<*returned; i++)
4387 smb_io_printer_info_1("", buffer, &printers[i], 0);
4392 SAFE_FREE(printers);
4394 if ( !W_ERROR_IS_OK(result) )
4400 /********************************************************************
4401 enum_all_printers_info_1_local.
4402 *********************************************************************/
4404 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4406 DEBUG(4,("enum_all_printers_info_1_local\n"));
4408 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4411 /********************************************************************
4412 enum_all_printers_info_1_name.
4413 *********************************************************************/
4415 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4419 DEBUG(4,("enum_all_printers_info_1_name\n"));
4421 if ((name[0] == '\\') && (name[1] == '\\'))
4424 if (is_myname_or_ipaddr(s)) {
4425 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4428 return WERR_INVALID_NAME;
4431 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4432 /********************************************************************
4433 enum_all_printers_info_1_remote.
4434 *********************************************************************/
4436 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4438 PRINTER_INFO_1 *printer;
4439 fstring printername;
4442 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4443 WERROR result = WERR_OK;
4445 /* JFM: currently it's more a place holder than anything else.
4446 * In the spooler world there is a notion of server registration.
4447 * the print servers are registered on the PDC (in the same domain)
4449 * We should have a TDB here. The registration is done thru an
4450 * undocumented RPC call.
4453 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4458 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4459 slprintf(desc, sizeof(desc)-1,"%s", name);
4460 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4462 init_unistr(&printer->description, desc);
4463 init_unistr(&printer->name, printername);
4464 init_unistr(&printer->comment, comment);
4465 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4467 /* check the required size. */
4468 *needed += spoolss_size_printer_info_1(printer);
4470 if (*needed > offered) {
4471 result = WERR_INSUFFICIENT_BUFFER;
4475 if (!rpcbuf_alloc_size(buffer, *needed)) {
4476 result = WERR_NOMEM;
4480 /* fill the buffer with the structures */
4481 smb_io_printer_info_1("", buffer, printer, 0);
4487 if ( !W_ERROR_IS_OK(result) )
4495 /********************************************************************
4496 enum_all_printers_info_1_network.
4497 *********************************************************************/
4499 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4503 DEBUG(4,("enum_all_printers_info_1_network\n"));
4505 /* If we respond to a enum_printers level 1 on our name with flags
4506 set to PRINTER_ENUM_REMOTE with a list of printers then these
4507 printers incorrectly appear in the APW browse list.
4508 Specifically the printers for the server appear at the workgroup
4509 level where all the other servers in the domain are
4510 listed. Windows responds to this call with a
4511 WERR_CAN_NOT_COMPLETE so we should do the same. */
4513 if (name[0] == '\\' && name[1] == '\\')
4516 if (is_myname_or_ipaddr(s))
4517 return WERR_CAN_NOT_COMPLETE;
4519 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4522 /********************************************************************
4523 * api_spoolss_enumprinters
4525 * called from api_spoolss_enumprinters (see this to understand)
4526 ********************************************************************/
4528 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4532 int n_services=lp_numservices();
4533 PRINTER_INFO_2 *printers=NULL;
4534 PRINTER_INFO_2 current_prt;
4535 WERROR result = WERR_OK;
4539 for (snum=0; snum<n_services; snum++) {
4540 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4541 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4543 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4544 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4545 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4550 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4552 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4559 /* check the required size. */
4560 for (i=0; i<*returned; i++)
4561 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4563 if (*needed > offered) {
4564 result = WERR_INSUFFICIENT_BUFFER;
4568 if (!rpcbuf_alloc_size(buffer, *needed)) {
4569 result = WERR_NOMEM;
4573 /* fill the buffer with the structures */
4574 for (i=0; i<*returned; i++)
4575 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4580 for (i=0; i<*returned; i++)
4581 free_devmode(printers[i].devmode);
4583 SAFE_FREE(printers);
4585 if ( !W_ERROR_IS_OK(result) )
4591 /********************************************************************
4592 * handle enumeration of printers at level 1
4593 ********************************************************************/
4595 static WERROR enumprinters_level1( uint32 flags, fstring name,
4596 RPC_BUFFER *buffer, uint32 offered,
4597 uint32 *needed, uint32 *returned)
4599 /* Not all the flags are equals */
4601 if (flags & PRINTER_ENUM_LOCAL)
4602 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4604 if (flags & PRINTER_ENUM_NAME)
4605 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4607 #if 0 /* JERRY - disabled for now */
4608 if (flags & PRINTER_ENUM_REMOTE)
4609 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4612 if (flags & PRINTER_ENUM_NETWORK)
4613 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4615 return WERR_OK; /* NT4sp5 does that */
4618 /********************************************************************
4619 * handle enumeration of printers at level 2
4620 ********************************************************************/
4622 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4623 RPC_BUFFER *buffer, uint32 offered,
4624 uint32 *needed, uint32 *returned)
4626 if (flags & PRINTER_ENUM_LOCAL) {
4627 return enum_all_printers_info_2(buffer, offered, needed, returned);
4630 if (flags & PRINTER_ENUM_NAME) {
4631 if (is_myname_or_ipaddr(canon_servername(servername)))
4632 return enum_all_printers_info_2(buffer, offered, needed, returned);
4634 return WERR_INVALID_NAME;
4637 if (flags & PRINTER_ENUM_REMOTE)
4638 return WERR_UNKNOWN_LEVEL;
4643 /********************************************************************
4644 * handle enumeration of printers at level 5
4645 ********************************************************************/
4647 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4648 RPC_BUFFER *buffer, uint32 offered,
4649 uint32 *needed, uint32 *returned)
4651 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4655 /********************************************************************
4656 * api_spoolss_enumprinters
4658 * called from api_spoolss_enumprinters (see this to understand)
4659 ********************************************************************/
4661 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4663 uint32 flags = q_u->flags;
4664 UNISTR2 *servername = &q_u->servername;
4665 uint32 level = q_u->level;
4666 RPC_BUFFER *buffer = NULL;
4667 uint32 offered = q_u->offered;
4668 uint32 *needed = &r_u->needed;
4669 uint32 *returned = &r_u->returned;
4673 /* that's an [in out] buffer */
4675 if (!q_u->buffer && (offered!=0)) {
4676 return WERR_INVALID_PARAM;
4679 if (offered > MAX_RPC_DATA_SIZE) {
4680 return WERR_INVALID_PARAM;
4683 rpcbuf_move(q_u->buffer, &r_u->buffer);
4684 buffer = r_u->buffer;
4686 DEBUG(4,("_spoolss_enumprinters\n"));
4693 * flags==PRINTER_ENUM_NAME
4694 * if name=="" then enumerates all printers
4695 * if name!="" then enumerate the printer
4696 * flags==PRINTER_ENUM_REMOTE
4697 * name is NULL, enumerate printers
4698 * Level 2: name!="" enumerates printers, name can't be NULL
4699 * Level 3: doesn't exist
4700 * Level 4: does a local registry lookup
4701 * Level 5: same as Level 2
4704 unistr2_to_ascii(name, servername, sizeof(name));
4709 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4711 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4713 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4718 return WERR_UNKNOWN_LEVEL;
4721 /****************************************************************************
4722 ****************************************************************************/
4724 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4726 PRINTER_INFO_0 *printer=NULL;
4727 WERROR result = WERR_OK;
4729 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4732 construct_printer_info_0(print_hnd, printer, snum);
4734 /* check the required size. */
4735 *needed += spoolss_size_printer_info_0(printer);
4737 if (*needed > offered) {
4738 result = WERR_INSUFFICIENT_BUFFER;
4742 if (!rpcbuf_alloc_size(buffer, *needed)) {
4743 result = WERR_NOMEM;
4747 /* fill the buffer with the structures */
4748 smb_io_printer_info_0("", buffer, printer, 0);
4758 /****************************************************************************
4759 ****************************************************************************/
4761 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4763 PRINTER_INFO_1 *printer=NULL;
4764 WERROR result = WERR_OK;
4766 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4769 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4771 /* check the required size. */
4772 *needed += spoolss_size_printer_info_1(printer);
4774 if (*needed > offered) {
4775 result = WERR_INSUFFICIENT_BUFFER;
4779 if (!rpcbuf_alloc_size(buffer, *needed)) {
4780 result = WERR_NOMEM;
4784 /* fill the buffer with the structures */
4785 smb_io_printer_info_1("", buffer, printer, 0);
4794 /****************************************************************************
4795 ****************************************************************************/
4797 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4799 PRINTER_INFO_2 *printer=NULL;
4800 WERROR result = WERR_OK;
4802 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4805 construct_printer_info_2(print_hnd, printer, snum);
4807 /* check the required size. */
4808 *needed += spoolss_size_printer_info_2(printer);
4810 if (*needed > offered) {
4811 result = WERR_INSUFFICIENT_BUFFER;
4815 if (!rpcbuf_alloc_size(buffer, *needed)) {
4816 result = WERR_NOMEM;
4820 /* fill the buffer with the structures */
4821 if (!smb_io_printer_info_2("", buffer, printer, 0))
4822 result = WERR_NOMEM;
4826 free_printer_info_2(printer);
4831 /****************************************************************************
4832 ****************************************************************************/
4834 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4836 PRINTER_INFO_3 *printer=NULL;
4837 WERROR result = WERR_OK;
4839 if (!construct_printer_info_3(print_hnd, &printer, snum))
4842 /* check the required size. */
4843 *needed += spoolss_size_printer_info_3(printer);
4845 if (*needed > offered) {
4846 result = WERR_INSUFFICIENT_BUFFER;
4850 if (!rpcbuf_alloc_size(buffer, *needed)) {
4851 result = WERR_NOMEM;
4855 /* fill the buffer with the structures */
4856 smb_io_printer_info_3("", buffer, printer, 0);
4860 free_printer_info_3(printer);
4865 /****************************************************************************
4866 ****************************************************************************/
4868 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4870 PRINTER_INFO_4 *printer=NULL;
4871 WERROR result = WERR_OK;
4873 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4876 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4881 /* check the required size. */
4882 *needed += spoolss_size_printer_info_4(printer);
4884 if (*needed > offered) {
4885 result = WERR_INSUFFICIENT_BUFFER;
4889 if (!rpcbuf_alloc_size(buffer, *needed)) {
4890 result = WERR_NOMEM;
4894 /* fill the buffer with the structures */
4895 smb_io_printer_info_4("", buffer, printer, 0);
4899 free_printer_info_4(printer);
4904 /****************************************************************************
4905 ****************************************************************************/
4907 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4909 PRINTER_INFO_5 *printer=NULL;
4910 WERROR result = WERR_OK;
4912 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4915 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4916 free_printer_info_5(printer);
4920 /* check the required size. */
4921 *needed += spoolss_size_printer_info_5(printer);
4923 if (*needed > offered) {
4924 result = WERR_INSUFFICIENT_BUFFER;
4928 if (!rpcbuf_alloc_size(buffer, *needed)) {
4929 result = WERR_NOMEM;
4933 /* fill the buffer with the structures */
4934 smb_io_printer_info_5("", buffer, printer, 0);
4938 free_printer_info_5(printer);
4943 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4945 RPC_BUFFER *buffer, uint32 offered,
4948 PRINTER_INFO_6 *printer;
4949 WERROR result = WERR_OK;
4951 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4955 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4956 free_printer_info_6(printer);
4960 /* check the required size. */
4961 *needed += spoolss_size_printer_info_6(printer);
4963 if (*needed > offered) {
4964 result = WERR_INSUFFICIENT_BUFFER;
4968 if (!rpcbuf_alloc_size(buffer, *needed)) {
4969 result = WERR_NOMEM;
4973 /* fill the buffer with the structures */
4974 smb_io_printer_info_6("", buffer, printer, 0);
4978 free_printer_info_6(printer);
4983 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4985 PRINTER_INFO_7 *printer=NULL;
4986 WERROR result = WERR_OK;
4988 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
4991 if (!construct_printer_info_7(print_hnd, printer, snum)) {
4992 result = WERR_NOMEM;
4996 /* check the required size. */
4997 *needed += spoolss_size_printer_info_7(printer);
4999 if (*needed > offered) {
5000 result = WERR_INSUFFICIENT_BUFFER;
5004 if (!rpcbuf_alloc_size(buffer, *needed)) {
5005 result = WERR_NOMEM;
5010 /* fill the buffer with the structures */
5011 smb_io_printer_info_7("", buffer, printer, 0);
5015 free_printer_info_7(printer);
5020 /****************************************************************************
5021 ****************************************************************************/
5023 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
5025 POLICY_HND *handle = &q_u->handle;
5026 uint32 level = q_u->level;
5027 RPC_BUFFER *buffer = NULL;
5028 uint32 offered = q_u->offered;
5029 uint32 *needed = &r_u->needed;
5030 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5034 /* that's an [in out] buffer */
5036 if (!q_u->buffer && (offered!=0)) {
5037 return WERR_INVALID_PARAM;
5040 if (offered > MAX_RPC_DATA_SIZE) {
5041 return WERR_INVALID_PARAM;
5044 rpcbuf_move(q_u->buffer, &r_u->buffer);
5045 buffer = r_u->buffer;
5049 if (!get_printer_snum(p, handle, &snum, NULL))
5054 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5056 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5058 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5060 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5062 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5064 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5066 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5068 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5070 return WERR_UNKNOWN_LEVEL;
5073 /********************************************************************
5074 * fill a DRIVER_INFO_1 struct
5075 ********************************************************************/
5077 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5079 init_unistr( &info->name, driver.info_3->name);
5082 /********************************************************************
5083 * construct_printer_driver_info_1
5084 ********************************************************************/
5086 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5088 NT_PRINTER_INFO_LEVEL *printer = NULL;
5089 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5091 ZERO_STRUCT(driver);
5093 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5094 return WERR_INVALID_PRINTER_NAME;
5096 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5097 free_a_printer(&printer, 2);
5098 return WERR_UNKNOWN_PRINTER_DRIVER;
5101 fill_printer_driver_info_1(info, driver, servername, architecture);
5103 free_a_printer(&printer,2);
5108 /********************************************************************
5109 * construct_printer_driver_info_2
5110 * fill a printer_info_2 struct
5111 ********************************************************************/
5113 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5115 TALLOC_CTX *ctx = talloc_tos();
5117 const char *cservername = canon_servername(servername);
5119 info->version=driver.info_3->cversion;
5121 init_unistr( &info->name, driver.info_3->name );
5122 init_unistr( &info->architecture, driver.info_3->environment );
5124 if (strlen(driver.info_3->driverpath)) {
5125 temp = talloc_asprintf(ctx,
5128 driver.info_3->driverpath);
5129 init_unistr( &info->driverpath, temp );
5131 init_unistr( &info->driverpath, "" );
5135 if (strlen(driver.info_3->datafile)) {
5136 temp = talloc_asprintf(ctx,
5139 driver.info_3->datafile);
5140 init_unistr( &info->datafile, temp );
5142 init_unistr( &info->datafile, "" );
5145 if (strlen(driver.info_3->configfile)) {
5146 temp = talloc_asprintf(ctx,
5149 driver.info_3->configfile);
5150 init_unistr( &info->configfile, temp );
5152 init_unistr( &info->configfile, "" );
5155 /********************************************************************
5156 * construct_printer_driver_info_2
5157 * fill a printer_info_2 struct
5158 ********************************************************************/
5160 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5162 NT_PRINTER_INFO_LEVEL *printer = NULL;
5163 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5165 ZERO_STRUCT(printer);
5166 ZERO_STRUCT(driver);
5168 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5169 return WERR_INVALID_PRINTER_NAME;
5171 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5172 free_a_printer(&printer, 2);
5173 return WERR_UNKNOWN_PRINTER_DRIVER;
5176 fill_printer_driver_info_2(info, driver, servername);
5178 free_a_printer(&printer,2);
5183 /********************************************************************
5184 * copy a strings array and convert to UNICODE
5186 * convert an array of ascii string to a UNICODE string
5187 ********************************************************************/
5189 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5195 TALLOC_CTX *ctx = talloc_tos();
5197 DEBUG(6,("init_unistr_array\n"));
5201 if ( !char_array ) {
5206 v = ""; /* hack to handle null lists */
5209 /* hack to allow this to be used in places other than when generating
5210 the list of dependent files */
5214 line = talloc_asprintf(ctx,
5216 canon_servername(servername),
5219 line = talloc_strdup(ctx, v);
5223 SAFE_FREE(*uni_array);
5226 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5228 /* add one extra unit16 for the second terminating NULL */
5230 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5231 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5238 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5243 /* special case for ""; we need to add both NULL's here */
5245 (*uni_array)[j++]=0x0000;
5246 (*uni_array)[j]=0x0000;
5249 DEBUGADD(6,("last one:done\n"));
5251 /* return size of array in uint16's */
5256 /********************************************************************
5257 * construct_printer_info_3
5258 * fill a printer_info_3 struct
5259 ********************************************************************/
5261 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5264 TALLOC_CTX *ctx = talloc_tos();
5265 const char *cservername = canon_servername(servername);
5269 info->version=driver.info_3->cversion;
5271 init_unistr( &info->name, driver.info_3->name );
5272 init_unistr( &info->architecture, driver.info_3->environment );
5274 if (strlen(driver.info_3->driverpath)) {
5275 temp = talloc_asprintf(ctx,
5278 driver.info_3->driverpath);
5279 init_unistr( &info->driverpath, temp );
5281 init_unistr( &info->driverpath, "" );
5284 if (strlen(driver.info_3->datafile)) {
5285 temp = talloc_asprintf(ctx,
5288 driver.info_3->datafile);
5289 init_unistr( &info->datafile, temp );
5291 init_unistr( &info->datafile, "" );
5294 if (strlen(driver.info_3->configfile)) {
5295 temp = talloc_asprintf(ctx,
5298 driver.info_3->configfile);
5299 init_unistr( &info->configfile, temp );
5301 init_unistr( &info->configfile, "" );
5304 if (strlen(driver.info_3->helpfile)) {
5305 temp = talloc_asprintf(ctx,
5308 driver.info_3->helpfile);
5309 init_unistr( &info->helpfile, temp );
5311 init_unistr( &info->helpfile, "" );
5314 init_unistr( &info->monitorname, driver.info_3->monitorname );
5315 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5317 info->dependentfiles=NULL;
5318 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5321 /********************************************************************
5322 * construct_printer_info_3
5323 * fill a printer_info_3 struct
5324 ********************************************************************/
5326 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5328 NT_PRINTER_INFO_LEVEL *printer = NULL;
5329 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5331 ZERO_STRUCT(driver);
5333 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5334 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5335 if (!W_ERROR_IS_OK(status))
5336 return WERR_INVALID_PRINTER_NAME;
5338 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5339 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5344 * I put this code in during testing. Helpful when commenting out the
5345 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5346 * as win2k always queries the driver using an infor level of 6.
5347 * I've left it in (but ifdef'd out) because I'll probably
5348 * use it in experimentation again in the future. --jerry 22/01/2002
5351 if (!W_ERROR_IS_OK(status)) {
5353 * Is this a W2k client ?
5356 /* Yes - try again with a WinNT driver. */
5358 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5359 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5363 if (!W_ERROR_IS_OK(status)) {
5364 free_a_printer(&printer,2);
5365 return WERR_UNKNOWN_PRINTER_DRIVER;
5373 fill_printer_driver_info_3(info, driver, servername);
5375 free_a_printer(&printer,2);
5380 /********************************************************************
5381 * construct_printer_info_6
5382 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5383 ********************************************************************/
5385 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5389 TALLOC_CTX *ctx = talloc_tos();
5390 const char *cservername = canon_servername(servername);
5393 memset(&nullstr, '\0', sizeof(fstring));
5395 info->version=driver.info_3->cversion;
5397 init_unistr( &info->name, driver.info_3->name );
5398 init_unistr( &info->architecture, driver.info_3->environment );
5400 if (strlen(driver.info_3->driverpath)) {
5401 temp = talloc_asprintf(ctx,
5404 driver.info_3->driverpath);
5405 init_unistr( &info->driverpath, temp );
5407 init_unistr( &info->driverpath, "" );
5410 if (strlen(driver.info_3->datafile)) {
5411 temp = talloc_asprintf(ctx,
5414 driver.info_3->datafile);
5415 init_unistr( &info->datafile, temp );
5417 init_unistr( &info->datafile, "" );
5420 if (strlen(driver.info_3->configfile)) {
5421 temp = talloc_asprintf(ctx,
5424 driver.info_3->configfile);
5425 init_unistr( &info->configfile, temp );
5427 init_unistr( &info->configfile, "" );
5430 if (strlen(driver.info_3->helpfile)) {
5431 temp = talloc_asprintf(ctx,
5434 driver.info_3->helpfile);
5435 init_unistr( &info->helpfile, temp );
5437 init_unistr( &info->helpfile, "" );
5440 init_unistr( &info->monitorname, driver.info_3->monitorname );
5441 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5443 info->dependentfiles = NULL;
5444 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5446 info->previousdrivernames=NULL;
5447 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5449 info->driver_date=0;
5452 info->driver_version_low=0;
5453 info->driver_version_high=0;
5455 init_unistr( &info->mfgname, "");
5456 init_unistr( &info->oem_url, "");
5457 init_unistr( &info->hardware_id, "");
5458 init_unistr( &info->provider, "");
5461 /********************************************************************
5462 * construct_printer_info_6
5463 * fill a printer_info_6 struct
5464 ********************************************************************/
5466 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5467 const char *servername, fstring architecture, uint32 version)
5469 NT_PRINTER_INFO_LEVEL *printer = NULL;
5470 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5473 ZERO_STRUCT(driver);
5475 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5477 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5479 if (!W_ERROR_IS_OK(status))
5480 return WERR_INVALID_PRINTER_NAME;
5482 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5484 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5486 if (!W_ERROR_IS_OK(status))
5489 * Is this a W2k client ?
5493 free_a_printer(&printer,2);
5494 return WERR_UNKNOWN_PRINTER_DRIVER;
5497 /* Yes - try again with a WinNT driver. */
5499 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5500 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5501 if (!W_ERROR_IS_OK(status)) {
5502 free_a_printer(&printer,2);
5503 return WERR_UNKNOWN_PRINTER_DRIVER;
5507 fill_printer_driver_info_6(info, driver, servername);
5509 free_a_printer(&printer,2);
5510 free_a_printer_driver(driver, 3);
5515 /****************************************************************************
5516 ****************************************************************************/
5518 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5520 SAFE_FREE(info->dependentfiles);
5523 /****************************************************************************
5524 ****************************************************************************/
5526 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5528 SAFE_FREE(info->dependentfiles);
5531 /****************************************************************************
5532 ****************************************************************************/
5534 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5536 DRIVER_INFO_1 *info=NULL;
5539 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5542 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5543 if (!W_ERROR_IS_OK(result))
5546 /* check the required size. */
5547 *needed += spoolss_size_printer_driver_info_1(info);
5549 if (*needed > offered) {
5550 result = WERR_INSUFFICIENT_BUFFER;
5554 if (!rpcbuf_alloc_size(buffer, *needed)) {
5555 result = WERR_NOMEM;
5559 /* fill the buffer with the structures */
5560 smb_io_printer_driver_info_1("", buffer, info, 0);
5569 /****************************************************************************
5570 ****************************************************************************/
5572 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5574 DRIVER_INFO_2 *info=NULL;
5577 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5580 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5581 if (!W_ERROR_IS_OK(result))
5584 /* check the required size. */
5585 *needed += spoolss_size_printer_driver_info_2(info);
5587 if (*needed > offered) {
5588 result = WERR_INSUFFICIENT_BUFFER;
5592 if (!rpcbuf_alloc_size(buffer, *needed)) {
5593 result = WERR_NOMEM;
5597 /* fill the buffer with the structures */
5598 smb_io_printer_driver_info_2("", buffer, info, 0);
5607 /****************************************************************************
5608 ****************************************************************************/
5610 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5617 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5618 if (!W_ERROR_IS_OK(result))
5621 /* check the required size. */
5622 *needed += spoolss_size_printer_driver_info_3(&info);
5624 if (*needed > offered) {
5625 result = WERR_INSUFFICIENT_BUFFER;
5629 if (!rpcbuf_alloc_size(buffer, *needed)) {
5630 result = WERR_NOMEM;
5634 /* fill the buffer with the structures */
5635 smb_io_printer_driver_info_3("", buffer, &info, 0);
5638 free_printer_driver_info_3(&info);
5643 /****************************************************************************
5644 ****************************************************************************/
5646 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5653 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5654 if (!W_ERROR_IS_OK(result))
5657 /* check the required size. */
5658 *needed += spoolss_size_printer_driver_info_6(&info);
5660 if (*needed > offered) {
5661 result = WERR_INSUFFICIENT_BUFFER;
5665 if (!rpcbuf_alloc_size(buffer, *needed)) {
5666 result = WERR_NOMEM;
5670 /* fill the buffer with the structures */
5671 smb_io_printer_driver_info_6("", buffer, &info, 0);
5674 free_printer_driver_info_6(&info);
5679 /****************************************************************************
5680 ****************************************************************************/
5682 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5684 POLICY_HND *handle = &q_u->handle;
5685 UNISTR2 *uni_arch = &q_u->architecture;
5686 uint32 level = q_u->level;
5687 uint32 clientmajorversion = q_u->clientmajorversion;
5688 RPC_BUFFER *buffer = NULL;
5689 uint32 offered = q_u->offered;
5690 uint32 *needed = &r_u->needed;
5691 uint32 *servermajorversion = &r_u->servermajorversion;
5692 uint32 *serverminorversion = &r_u->serverminorversion;
5693 Printer_entry *printer;
5696 fstring architecture;
5699 /* that's an [in out] buffer */
5701 if (!q_u->buffer && (offered!=0)) {
5702 return WERR_INVALID_PARAM;
5705 if (offered > MAX_RPC_DATA_SIZE) {
5706 return WERR_INVALID_PARAM;
5709 rpcbuf_move(q_u->buffer, &r_u->buffer);
5710 buffer = r_u->buffer;
5712 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5714 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5715 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5716 return WERR_INVALID_PRINTER_NAME;
5720 *servermajorversion = 0;
5721 *serverminorversion = 0;
5723 fstrcpy(servername, get_server_name( printer ));
5724 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5726 if (!get_printer_snum(p, handle, &snum, NULL))
5731 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5733 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5735 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5737 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5740 /* apparently this call is the equivalent of
5741 EnumPrinterDataEx() for the DsDriver key */
5746 return WERR_UNKNOWN_LEVEL;
5750 /****************************************************************
5751 _spoolss_StartPagePrinter
5752 ****************************************************************/
5754 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5755 struct spoolss_StartPagePrinter *r)
5757 POLICY_HND *handle = r->in.handle;
5759 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5762 DEBUG(3,("_spoolss_StartPagePrinter: "
5763 "Error in startpageprinter printer handle\n"));
5767 Printer->page_started=True;
5771 /****************************************************************
5772 _spoolss_EndPagePrinter
5773 ****************************************************************/
5775 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5776 struct spoolss_EndPagePrinter *r)
5778 POLICY_HND *handle = r->in.handle;
5781 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5784 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5785 OUR_HANDLE(handle)));
5789 if (!get_printer_snum(p, handle, &snum, NULL))
5792 Printer->page_started=False;
5793 print_job_endpage(snum, Printer->jobid);
5798 /****************************************************************
5799 _spoolss_StartDocPrinter
5800 ****************************************************************/
5802 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5803 struct spoolss_StartDocPrinter *r)
5805 POLICY_HND *handle = r->in.handle;
5806 uint32_t *jobid = r->out.job_id;
5807 struct spoolss_DocumentInfo1 *info_1;
5809 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5812 DEBUG(2,("_spoolss_StartDocPrinter: "
5813 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5817 if (r->in.level != 1) {
5818 return WERR_UNKNOWN_LEVEL;
5821 info_1 = r->in.info.info1;
5824 * a nice thing with NT is it doesn't listen to what you tell it.
5825 * when asked to send _only_ RAW datas, it tries to send datas
5828 * So I add checks like in NT Server ...
5831 if (info_1->datatype) {
5832 if (strcmp(info_1->datatype, "RAW") != 0) {
5834 return WERR_INVALID_DATATYPE;
5838 /* get the share number of the printer */
5839 if (!get_printer_snum(p, handle, &snum, NULL)) {
5843 Printer->jobid = print_job_start(p->server_info, snum,
5844 CONST_DISCARD(char *,info_1->document_name),
5845 Printer->nt_devmode);
5847 /* An error occured in print_job_start() so return an appropriate
5850 if (Printer->jobid == -1) {
5851 return map_werror_from_unix(errno);
5854 Printer->document_started=True;
5855 (*jobid) = Printer->jobid;
5860 /****************************************************************
5861 _spoolss_EndDocPrinter
5862 ****************************************************************/
5864 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5865 struct spoolss_EndDocPrinter *r)
5867 POLICY_HND *handle = r->in.handle;
5869 return _spoolss_enddocprinter_internal(p, handle);
5872 /****************************************************************
5873 _spoolss_WritePrinter
5874 ****************************************************************/
5876 WERROR _spoolss_WritePrinter(pipes_struct *p,
5877 struct spoolss_WritePrinter *r)
5879 POLICY_HND *handle = r->in.handle;
5880 uint32 buffer_size = r->in._data_size;
5881 uint8 *buffer = r->in.data.data;
5882 uint32 *buffer_written = &r->in._data_size;
5884 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5887 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5888 OUR_HANDLE(handle)));
5889 *r->out.num_written = r->in._data_size;
5893 if (!get_printer_snum(p, handle, &snum, NULL))
5896 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5897 (SMB_OFF_T)-1, (size_t)buffer_size);
5898 if (*buffer_written == (uint32)-1) {
5899 *r->out.num_written = 0;
5900 if (errno == ENOSPC)
5901 return WERR_NO_SPOOL_SPACE;
5903 return WERR_ACCESS_DENIED;
5906 *r->out.num_written = r->in._data_size;
5911 /********************************************************************
5912 * api_spoolss_getprinter
5913 * called from the spoolss dispatcher
5915 ********************************************************************/
5917 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5921 WERROR errcode = WERR_BADFUNC;
5922 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5925 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5929 if (!get_printer_snum(p, handle, &snum, NULL))
5933 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5934 if (print_queue_pause(p->server_info, snum, &errcode)) {
5938 case SPOOLSS_PRINTER_CONTROL_RESUME:
5939 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5940 if (print_queue_resume(p->server_info, snum, &errcode)) {
5944 case SPOOLSS_PRINTER_CONTROL_PURGE:
5945 if (print_queue_purge(p->server_info, snum, &errcode)) {
5950 return WERR_UNKNOWN_LEVEL;
5957 /****************************************************************
5958 _spoolss_AbortPrinter
5959 * From MSDN: "Deletes printer's spool file if printer is configured
5961 ****************************************************************/
5963 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5964 struct spoolss_AbortPrinter *r)
5966 POLICY_HND *handle = r->in.handle;
5967 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5969 WERROR errcode = WERR_OK;
5972 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5973 OUR_HANDLE(handle)));
5977 if (!get_printer_snum(p, handle, &snum, NULL))
5980 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5985 /********************************************************************
5986 * called by spoolss_api_setprinter
5987 * when updating a printer description
5988 ********************************************************************/
5990 static WERROR update_printer_sec(POLICY_HND *handle,
5991 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
5993 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
5997 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5999 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
6000 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
6001 OUR_HANDLE(handle)));
6003 result = WERR_BADFID;
6008 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
6009 result = WERR_INVALID_PARAM;
6013 /* Check the user has permissions to change the security
6014 descriptor. By experimentation with two NT machines, the user
6015 requires Full Access to the printer to change security
6018 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
6019 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
6020 result = WERR_ACCESS_DENIED;
6024 /* NT seems to like setting the security descriptor even though
6025 nothing may have actually changed. */
6027 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
6028 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
6029 result = WERR_BADFID;
6033 if (DEBUGLEVEL >= 10) {
6037 the_acl = old_secdesc_ctr->sd->dacl;
6038 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6039 PRINTERNAME(snum), the_acl->num_aces));
6041 for (i = 0; i < the_acl->num_aces; i++) {
6042 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6043 &the_acl->aces[i].trustee),
6044 the_acl->aces[i].access_mask));
6047 the_acl = secdesc_ctr->sd->dacl;
6050 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6051 PRINTERNAME(snum), the_acl->num_aces));
6053 for (i = 0; i < the_acl->num_aces; i++) {
6054 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6055 &the_acl->aces[i].trustee),
6056 the_acl->aces[i].access_mask));
6059 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6063 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6064 if (!new_secdesc_ctr) {
6065 result = WERR_NOMEM;
6069 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6074 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6081 /********************************************************************
6082 Canonicalize printer info from a client
6084 ATTN: It does not matter what we set the servername to hear
6085 since we do the necessary work in get_a_printer() to set it to
6086 the correct value based on what the client sent in the
6087 _spoolss_open_printer_ex().
6088 ********************************************************************/
6090 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6092 fstring printername;
6095 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6096 "portname=%s drivername=%s comment=%s location=%s\n",
6097 info->servername, info->printername, info->sharename,
6098 info->portname, info->drivername, info->comment, info->location));
6100 /* we force some elements to "correct" values */
6101 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6102 fstrcpy(info->sharename, lp_servicename(snum));
6104 /* check to see if we allow printername != sharename */
6106 if ( lp_force_printername(snum) ) {
6107 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6108 global_myname(), info->sharename );
6111 /* make sure printername is in \\server\printername format */
6113 fstrcpy( printername, info->printername );
6115 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6116 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6120 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6121 global_myname(), p );
6124 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6125 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6132 /****************************************************************************
6133 ****************************************************************************/
6135 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6137 char *cmd = lp_addport_cmd();
6138 char *command = NULL;
6140 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6141 bool is_print_op = False;
6144 return WERR_ACCESS_DENIED;
6147 command = talloc_asprintf(ctx,
6148 "%s \"%s\" \"%s\"", cmd, portname, uri );
6154 is_print_op = user_has_privileges( token, &se_printop );
6156 DEBUG(10,("Running [%s]\n", command));
6158 /********* BEGIN SePrintOperatorPrivilege **********/
6163 ret = smbrun(command, NULL);
6168 /********* END SePrintOperatorPrivilege **********/
6170 DEBUGADD(10,("returned [%d]\n", ret));
6172 TALLOC_FREE(command);
6175 return WERR_ACCESS_DENIED;
6181 /****************************************************************************
6182 ****************************************************************************/
6184 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6186 char *cmd = lp_addprinter_cmd();
6188 char *command = NULL;
6192 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6193 bool is_print_op = False;
6194 char *remote_machine = talloc_strdup(ctx, "%m");
6196 if (!remote_machine) {
6199 remote_machine = talloc_sub_basic(ctx,
6200 current_user_info.smb_name,
6201 current_user_info.domain,
6203 if (!remote_machine) {
6207 command = talloc_asprintf(ctx,
6208 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6209 cmd, printer->info_2->printername, printer->info_2->sharename,
6210 printer->info_2->portname, printer->info_2->drivername,
6211 printer->info_2->location, printer->info_2->comment, remote_machine);
6217 is_print_op = user_has_privileges( token, &se_printop );
6219 DEBUG(10,("Running [%s]\n", command));
6221 /********* BEGIN SePrintOperatorPrivilege **********/
6226 if ( (ret = smbrun(command, &fd)) == 0 ) {
6227 /* Tell everyone we updated smb.conf. */
6228 message_send_all(smbd_messaging_context(),
6229 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6235 /********* END SePrintOperatorPrivilege **********/
6237 DEBUGADD(10,("returned [%d]\n", ret));
6239 TALLOC_FREE(command);
6240 TALLOC_FREE(remote_machine);
6248 /* reload our services immediately */
6249 reload_services( False );
6252 /* Get lines and convert them back to dos-codepage */
6253 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6254 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6257 /* Set the portname to what the script says the portname should be. */
6258 /* but don't require anything to be return from the script exit a good error code */
6261 /* Set the portname to what the script says the portname should be. */
6262 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6263 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6266 TALLOC_FREE(qlines);
6271 /********************************************************************
6272 * Called by spoolss_api_setprinter
6273 * when updating a printer description.
6274 ********************************************************************/
6276 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6277 struct spoolss_SetPrinterInfoCtr *info_ctr,
6278 struct spoolss_DeviceMode *devmode)
6281 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6282 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6287 DEBUG(8,("update_printer\n"));
6292 result = WERR_BADFID;
6296 if (!get_printer_snum(p, handle, &snum, NULL)) {
6297 result = WERR_BADFID;
6301 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6302 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6303 result = WERR_BADFID;
6307 DEBUGADD(8,("Converting info_2 struct\n"));
6310 * convert_printer_info converts the incoming
6311 * info from the client and overwrites the info
6312 * just read from the tdb in the pointer 'printer'.
6315 if (!convert_printer_info_new(info_ctr, printer)) {
6316 result = WERR_NOMEM;
6321 /* we have a valid devmode
6322 convert it and link it*/
6324 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6325 if (!convert_devicemode_new(printer->info_2->printername,
6327 &printer->info_2->devmode)) {
6328 result = WERR_NOMEM;
6333 /* Do sanity check on the requested changes for Samba */
6335 if (!check_printer_ok(printer->info_2, snum)) {
6336 result = WERR_INVALID_PARAM;
6340 /* FIXME!!! If the driver has changed we really should verify that
6341 it is installed before doing much else --jerry */
6343 /* Check calling user has permission to update printer description */
6345 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6346 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6347 result = WERR_ACCESS_DENIED;
6351 /* Call addprinter hook */
6352 /* Check changes to see if this is really needed */
6354 if ( *lp_addprinter_cmd()
6355 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6356 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6357 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6358 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6360 /* add_printer_hook() will call reload_services() */
6362 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6364 result = WERR_ACCESS_DENIED;
6370 * When a *new* driver is bound to a printer, the drivername is used to
6371 * lookup previously saved driver initialization info, which is then
6372 * bound to the printer, simulating what happens in the Windows arch.
6374 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6376 if (!set_driver_init(printer, 2))
6378 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6379 printer->info_2->drivername));
6382 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6383 printer->info_2->drivername));
6385 notify_printer_driver(snum, printer->info_2->drivername);
6389 * flag which changes actually occured. This is a small subset of
6390 * all the possible changes. We also have to update things in the
6394 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6395 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6396 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6397 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6399 notify_printer_comment(snum, printer->info_2->comment);
6402 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6403 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6404 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6405 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6407 notify_printer_sharename(snum, printer->info_2->sharename);
6410 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6413 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6416 pname = printer->info_2->printername;
6419 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6420 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6421 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6423 notify_printer_printername( snum, pname );
6426 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6427 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6428 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6429 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6431 notify_printer_port(snum, printer->info_2->portname);
6434 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6435 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6436 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6437 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6439 notify_printer_location(snum, printer->info_2->location);
6442 /* here we need to update some more DsSpooler keys */
6443 /* uNCName, serverName, shortServerName */
6445 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6446 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6447 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6448 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6449 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6451 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6452 global_myname(), printer->info_2->sharename );
6453 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6454 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6455 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6457 /* Update printer info */
6458 result = mod_a_printer(printer, 2);
6461 free_a_printer(&printer, 2);
6462 free_a_printer(&old_printer, 2);
6468 /****************************************************************************
6469 ****************************************************************************/
6470 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6471 struct spoolss_SetPrinterInfo7 *info7)
6475 Printer_entry *Printer;
6477 if ( lp_security() != SEC_ADS ) {
6478 return WERR_UNKNOWN_LEVEL;
6481 Printer = find_printer_index_by_hnd(p, handle);
6483 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6488 if (!get_printer_snum(p, handle, &snum, NULL))
6491 nt_printer_publish(Printer, snum, info7->action);
6495 return WERR_UNKNOWN_LEVEL;
6499 /****************************************************************
6501 ****************************************************************/
6503 WERROR _spoolss_SetPrinter(pipes_struct *p,
6504 struct spoolss_SetPrinter *r)
6506 POLICY_HND *handle = r->in.handle;
6509 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6512 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6513 OUR_HANDLE(handle)));
6517 /* check the level */
6518 switch (r->in.info_ctr->level) {
6520 return control_printer(handle, r->in.command, p);
6522 result = update_printer(p, handle,
6524 r->in.devmode_ctr->devmode);
6525 if (!W_ERROR_IS_OK(result))
6527 if (r->in.secdesc_ctr->sd)
6528 result = update_printer_sec(handle, p,
6532 return update_printer_sec(handle, p,
6535 return publish_or_unpublish_printer(p, handle,
6536 r->in.info_ctr->info.info7);
6538 return WERR_UNKNOWN_LEVEL;
6542 /****************************************************************
6543 _spoolss_FindClosePrinterNotify
6544 ****************************************************************/
6546 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6547 struct spoolss_FindClosePrinterNotify *r)
6549 POLICY_HND *handle = r->in.handle;
6550 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6553 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6554 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6558 if (Printer->notify.client_connected==True) {
6561 if ( Printer->printer_type == SPLHND_SERVER)
6563 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6564 !get_printer_snum(p, handle, &snum, NULL) )
6567 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6570 Printer->notify.flags=0;
6571 Printer->notify.options=0;
6572 Printer->notify.localmachine[0]='\0';
6573 Printer->notify.printerlocal=0;
6574 if (Printer->notify.option)
6575 free_spool_notify_option(&Printer->notify.option);
6576 Printer->notify.client_connected=False;
6581 /****************************************************************
6583 ****************************************************************/
6585 WERROR _spoolss_AddJob(pipes_struct *p,
6586 struct spoolss_AddJob *r)
6588 if (!r->in.buffer && (r->in.offered != 0)) {
6589 return WERR_INVALID_PARAM;
6592 /* this is what a NT server returns for AddJob. AddJob must fail on
6593 * non-local printers */
6595 return WERR_INVALID_PARAM;
6598 /****************************************************************************
6599 ****************************************************************************/
6601 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6602 int position, int snum,
6603 const NT_PRINTER_INFO_LEVEL *ntprinter)
6607 t=gmtime(&queue->time);
6609 job_info->jobid=queue->job;
6610 init_unistr(&job_info->printername, lp_servicename(snum));
6611 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6612 init_unistr(&job_info->username, queue->fs_user);
6613 init_unistr(&job_info->document, queue->fs_file);
6614 init_unistr(&job_info->datatype, "RAW");
6615 init_unistr(&job_info->text_status, "");
6616 job_info->status=nt_printj_status(queue->status);
6617 job_info->priority=queue->priority;
6618 job_info->position=position;
6619 job_info->totalpages=queue->page_count;
6620 job_info->pagesprinted=0;
6622 make_systemtime(&job_info->submitted, t);
6625 /****************************************************************************
6626 ****************************************************************************/
6628 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6629 int position, int snum,
6630 const NT_PRINTER_INFO_LEVEL *ntprinter,
6631 DEVICEMODE *devmode)
6635 t=gmtime(&queue->time);
6637 job_info->jobid=queue->job;
6639 init_unistr(&job_info->printername, ntprinter->info_2->printername);
6641 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6642 init_unistr(&job_info->username, queue->fs_user);
6643 init_unistr(&job_info->document, queue->fs_file);
6644 init_unistr(&job_info->notifyname, queue->fs_user);
6645 init_unistr(&job_info->datatype, "RAW");
6646 init_unistr(&job_info->printprocessor, "winprint");
6647 init_unistr(&job_info->parameters, "");
6648 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6649 init_unistr(&job_info->text_status, "");
6651 /* and here the security descriptor */
6653 job_info->status=nt_printj_status(queue->status);
6654 job_info->priority=queue->priority;
6655 job_info->position=position;
6656 job_info->starttime=0;
6657 job_info->untiltime=0;
6658 job_info->totalpages=queue->page_count;
6659 job_info->size=queue->size;
6660 make_systemtime(&(job_info->submitted), t);
6661 job_info->timeelapsed=0;
6662 job_info->pagesprinted=0;
6664 job_info->devmode = devmode;
6669 /****************************************************************************
6670 Enumjobs at level 1.
6671 ****************************************************************************/
6673 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6674 const NT_PRINTER_INFO_LEVEL *ntprinter,
6675 RPC_BUFFER *buffer, uint32 offered,
6676 uint32 *needed, uint32 *returned)
6680 WERROR result = WERR_OK;
6682 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6688 for (i=0; i<*returned; i++)
6689 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6691 /* check the required size. */
6692 for (i=0; i<*returned; i++)
6693 (*needed) += spoolss_size_job_info_1(&info[i]);
6695 if (*needed > offered) {
6696 result = WERR_INSUFFICIENT_BUFFER;
6700 if (!rpcbuf_alloc_size(buffer, *needed)) {
6701 result = WERR_NOMEM;
6705 /* fill the buffer with the structures */
6706 for (i=0; i<*returned; i++)
6707 smb_io_job_info_1("", buffer, &info[i], 0);
6713 if ( !W_ERROR_IS_OK(result) )
6719 /****************************************************************************
6720 Enumjobs at level 2.
6721 ****************************************************************************/
6723 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6724 const NT_PRINTER_INFO_LEVEL *ntprinter,
6725 RPC_BUFFER *buffer, uint32 offered,
6726 uint32 *needed, uint32 *returned)
6728 JOB_INFO_2 *info = NULL;
6730 WERROR result = WERR_OK;
6731 DEVICEMODE *devmode = NULL;
6733 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6738 /* this should not be a failure condition if the devmode is NULL */
6740 devmode = construct_dev_mode(lp_const_servicename(snum));
6742 for (i=0; i<*returned; i++)
6743 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6745 /* check the required size. */
6746 for (i=0; i<*returned; i++)
6747 (*needed) += spoolss_size_job_info_2(&info[i]);
6749 if (*needed > offered) {
6750 result = WERR_INSUFFICIENT_BUFFER;
6754 if (!rpcbuf_alloc_size(buffer, *needed)) {
6755 result = WERR_NOMEM;
6759 /* fill the buffer with the structures */
6760 for (i=0; i<*returned; i++)
6761 smb_io_job_info_2("", buffer, &info[i], 0);
6764 free_devmode(devmode);
6767 if ( !W_ERROR_IS_OK(result) )
6774 /****************************************************************************
6776 ****************************************************************************/
6778 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6780 POLICY_HND *handle = &q_u->handle;
6781 uint32 level = q_u->level;
6782 RPC_BUFFER *buffer = NULL;
6783 uint32 offered = q_u->offered;
6784 uint32 *needed = &r_u->needed;
6785 uint32 *returned = &r_u->returned;
6787 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6789 print_status_struct prt_status;
6790 print_queue_struct *queue=NULL;
6792 /* that's an [in out] buffer */
6794 if (!q_u->buffer && (offered!=0)) {
6795 return WERR_INVALID_PARAM;
6798 if (offered > MAX_RPC_DATA_SIZE) {
6799 return WERR_INVALID_PARAM;
6802 rpcbuf_move(q_u->buffer, &r_u->buffer);
6803 buffer = r_u->buffer;
6805 DEBUG(4,("_spoolss_enumjobs\n"));
6810 /* lookup the printer snum and tdb entry */
6812 if (!get_printer_snum(p, handle, &snum, NULL))
6815 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6816 if ( !W_ERROR_IS_OK(wret) )
6819 *returned = print_queue_status(snum, &queue, &prt_status);
6820 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6822 if (*returned == 0) {
6824 free_a_printer(&ntprinter, 2);
6830 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6833 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6837 wret = WERR_UNKNOWN_LEVEL;
6842 free_a_printer( &ntprinter, 2 );
6846 /****************************************************************
6847 _spoolss_ScheduleJob
6848 ****************************************************************/
6850 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6851 struct spoolss_ScheduleJob *r)
6856 /****************************************************************
6858 ****************************************************************/
6860 WERROR _spoolss_SetJob(pipes_struct *p,
6861 struct spoolss_SetJob *r)
6863 POLICY_HND *handle = r->in.handle;
6864 uint32 jobid = r->in.job_id;
6865 uint32 command = r->in.command;
6868 WERROR errcode = WERR_BADFUNC;
6870 if (!get_printer_snum(p, handle, &snum, NULL)) {
6874 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6875 return WERR_INVALID_PRINTER_NAME;
6879 case SPOOLSS_JOB_CONTROL_CANCEL:
6880 case SPOOLSS_JOB_CONTROL_DELETE:
6881 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6885 case SPOOLSS_JOB_CONTROL_PAUSE:
6886 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6890 case SPOOLSS_JOB_CONTROL_RESTART:
6891 case SPOOLSS_JOB_CONTROL_RESUME:
6892 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6897 return WERR_UNKNOWN_LEVEL;
6903 /****************************************************************************
6904 Enumerates all printer drivers at level 1.
6905 ****************************************************************************/
6907 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6912 fstring *list = NULL;
6913 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6914 DRIVER_INFO_1 *driver_info_1=NULL;
6915 WERROR result = WERR_OK;
6919 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6921 ndrivers=get_ntdrivers(&list, architecture, version);
6922 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6924 if(ndrivers == -1) {
6925 SAFE_FREE(driver_info_1);
6930 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6931 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6937 for (i=0; i<ndrivers; i++) {
6939 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6940 ZERO_STRUCT(driver);
6941 status = get_a_printer_driver(&driver, 3, list[i],
6942 architecture, version);
6943 if (!W_ERROR_IS_OK(status)) {
6945 SAFE_FREE(driver_info_1);
6948 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6949 free_a_printer_driver(driver, 3);
6952 *returned+=ndrivers;
6956 /* check the required size. */
6957 for (i=0; i<*returned; i++) {
6958 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6959 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6962 if (*needed > offered) {
6963 result = WERR_INSUFFICIENT_BUFFER;
6967 if (!rpcbuf_alloc_size(buffer, *needed)) {
6968 result = WERR_NOMEM;
6972 /* fill the buffer with the driver structures */
6973 for (i=0; i<*returned; i++) {
6974 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
6975 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
6979 SAFE_FREE(driver_info_1);
6981 if ( !W_ERROR_IS_OK(result) )
6987 /****************************************************************************
6988 Enumerates all printer drivers at level 2.
6989 ****************************************************************************/
6991 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6996 fstring *list = NULL;
6997 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6998 DRIVER_INFO_2 *driver_info_2=NULL;
6999 WERROR result = WERR_OK;
7003 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7005 ndrivers=get_ntdrivers(&list, architecture, version);
7006 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7008 if(ndrivers == -1) {
7009 SAFE_FREE(driver_info_2);
7014 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
7015 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
7021 for (i=0; i<ndrivers; i++) {
7024 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7025 ZERO_STRUCT(driver);
7026 status = get_a_printer_driver(&driver, 3, list[i],
7027 architecture, version);
7028 if (!W_ERROR_IS_OK(status)) {
7030 SAFE_FREE(driver_info_2);
7033 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7034 free_a_printer_driver(driver, 3);
7037 *returned+=ndrivers;
7041 /* check the required size. */
7042 for (i=0; i<*returned; i++) {
7043 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7044 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7047 if (*needed > offered) {
7048 result = WERR_INSUFFICIENT_BUFFER;
7052 if (!rpcbuf_alloc_size(buffer, *needed)) {
7053 result = WERR_NOMEM;
7057 /* fill the buffer with the form structures */
7058 for (i=0; i<*returned; i++) {
7059 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7060 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7064 SAFE_FREE(driver_info_2);
7066 if ( !W_ERROR_IS_OK(result) )
7072 /****************************************************************************
7073 Enumerates all printer drivers at level 3.
7074 ****************************************************************************/
7076 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7081 fstring *list = NULL;
7082 DRIVER_INFO_3 *driver_info_3=NULL;
7083 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7084 WERROR result = WERR_OK;
7088 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7090 ndrivers=get_ntdrivers(&list, architecture, version);
7091 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7093 if(ndrivers == -1) {
7094 SAFE_FREE(driver_info_3);
7099 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7100 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7106 for (i=0; i<ndrivers; i++) {
7109 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7110 ZERO_STRUCT(driver);
7111 status = get_a_printer_driver(&driver, 3, list[i],
7112 architecture, version);
7113 if (!W_ERROR_IS_OK(status)) {
7115 SAFE_FREE(driver_info_3);
7118 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7119 free_a_printer_driver(driver, 3);
7122 *returned+=ndrivers;
7126 /* check the required size. */
7127 for (i=0; i<*returned; i++) {
7128 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7129 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7132 if (*needed > offered) {
7133 result = WERR_INSUFFICIENT_BUFFER;
7137 if (!rpcbuf_alloc_size(buffer, *needed)) {
7138 result = WERR_NOMEM;
7142 /* fill the buffer with the driver structures */
7143 for (i=0; i<*returned; i++) {
7144 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7145 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7149 for (i=0; i<*returned; i++) {
7150 SAFE_FREE(driver_info_3[i].dependentfiles);
7153 SAFE_FREE(driver_info_3);
7155 if ( !W_ERROR_IS_OK(result) )
7161 /****************************************************************************
7162 Enumerates all printer drivers.
7163 ****************************************************************************/
7165 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7167 uint32 level = q_u->level;
7168 RPC_BUFFER *buffer = NULL;
7169 uint32 offered = q_u->offered;
7170 uint32 *needed = &r_u->needed;
7171 uint32 *returned = &r_u->returned;
7172 const char *cservername;
7174 fstring architecture;
7176 /* that's an [in out] buffer */
7178 if (!q_u->buffer && (offered!=0)) {
7179 return WERR_INVALID_PARAM;
7182 if (offered > MAX_RPC_DATA_SIZE) {
7183 return WERR_INVALID_PARAM;
7186 rpcbuf_move(q_u->buffer, &r_u->buffer);
7187 buffer = r_u->buffer;
7189 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7194 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7195 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7197 cservername = canon_servername(servername);
7199 if (!is_myname_or_ipaddr(cservername))
7200 return WERR_UNKNOWN_PRINTER_DRIVER;
7204 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7206 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7208 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7210 return WERR_UNKNOWN_LEVEL;
7214 /****************************************************************************
7215 ****************************************************************************/
7217 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7219 form->flag=list->flag;
7220 init_unistr(&form->name, list->name);
7221 form->width=list->width;
7222 form->length=list->length;
7223 form->left=list->left;
7224 form->top=list->top;
7225 form->right=list->right;
7226 form->bottom=list->bottom;
7229 /****************************************************************************
7230 ****************************************************************************/
7232 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7233 struct spoolss_FormInfo1 *form,
7234 nt_forms_struct *list)
7236 form->form_name = talloc_strdup(mem_ctx, list->name);
7237 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7239 form->flags = list->flag;
7240 form->size.width = list->width;
7241 form->size.height = list->length;
7242 form->area.left = list->left;
7243 form->area.top = list->top;
7244 form->area.right = list->right;
7245 form->area.bottom = list->bottom;
7250 /****************************************************************************
7251 ****************************************************************************/
7253 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7255 uint32 level = q_u->level;
7256 RPC_BUFFER *buffer = NULL;
7257 uint32 offered = q_u->offered;
7258 uint32 *needed = &r_u->needed;
7259 uint32 *numofforms = &r_u->numofforms;
7260 uint32 numbuiltinforms;
7262 nt_forms_struct *list=NULL;
7263 nt_forms_struct *builtinlist=NULL;
7268 /* that's an [in out] buffer */
7270 if (!q_u->buffer && (offered!=0) ) {
7271 return WERR_INVALID_PARAM;
7274 if (offered > MAX_RPC_DATA_SIZE) {
7275 return WERR_INVALID_PARAM;
7278 rpcbuf_move(q_u->buffer, &r_u->buffer);
7279 buffer = r_u->buffer;
7281 DEBUG(4,("_spoolss_enumforms\n"));
7282 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7283 DEBUGADD(5,("Info level [%d]\n", level));
7285 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7286 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7287 *numofforms = get_ntforms(&list);
7288 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7289 *numofforms += numbuiltinforms;
7291 if (*numofforms == 0) {
7292 SAFE_FREE(builtinlist);
7294 return WERR_NO_MORE_ITEMS;
7299 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7300 SAFE_FREE(builtinlist);
7306 /* construct the list of form structures */
7307 for (i=0; i<numbuiltinforms; i++) {
7308 DEBUGADD(6,("Filling form number [%d]\n",i));
7309 fill_form_1(&forms_1[i], &builtinlist[i]);
7312 SAFE_FREE(builtinlist);
7314 for (; i<*numofforms; i++) {
7315 DEBUGADD(6,("Filling form number [%d]\n",i));
7316 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7321 /* check the required size. */
7322 for (i=0; i<numbuiltinforms; i++) {
7323 DEBUGADD(6,("adding form [%d]'s size\n",i));
7324 buffer_size += spoolss_size_form_1(&forms_1[i]);
7326 for (; i<*numofforms; i++) {
7327 DEBUGADD(6,("adding form [%d]'s size\n",i));
7328 buffer_size += spoolss_size_form_1(&forms_1[i]);
7331 *needed=buffer_size;
7333 if (*needed > offered) {
7336 return WERR_INSUFFICIENT_BUFFER;
7339 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7345 /* fill the buffer with the form structures */
7346 for (i=0; i<numbuiltinforms; i++) {
7347 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7348 smb_io_form_1("", buffer, &forms_1[i], 0);
7350 for (; i<*numofforms; i++) {
7351 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7352 smb_io_form_1("", buffer, &forms_1[i], 0);
7361 SAFE_FREE(builtinlist);
7362 return WERR_UNKNOWN_LEVEL;
7366 /****************************************************************
7368 ****************************************************************/
7370 WERROR _spoolss_GetForm(pipes_struct *p,
7371 struct spoolss_GetForm *r)
7373 uint32 level = r->in.level;
7374 uint32 offered = r->in.offered;
7375 uint32 *needed = r->out.needed;
7377 nt_forms_struct *list=NULL;
7378 nt_forms_struct builtin_form;
7380 union spoolss_FormInfo info;
7381 struct spoolss_FormInfo1 form_1;
7382 int numofforms=0, i=0;
7384 /* that's an [in out] buffer */
7386 if (!r->in.buffer && (offered!=0)) {
7387 return WERR_INVALID_PARAM;
7390 DEBUG(4,("_spoolss_GetForm\n"));
7391 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7392 DEBUGADD(5,("Info level [%d]\n", level));
7394 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7395 if (!foundBuiltin) {
7396 numofforms = get_ntforms(&list);
7397 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7399 if (numofforms == 0)
7403 ZERO_STRUCT(form_1);
7408 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7411 /* Check if the requested name is in the list of form structures */
7412 for (i=0; i<numofforms; i++) {
7414 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7415 list[i].name, r->in.form_name));
7417 if (strequal(r->in.form_name, list[i].name)) {
7418 DEBUGADD(6,("Found form %s number [%d]\n",
7419 r->in.form_name, i));
7420 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7426 if (i == numofforms) {
7430 /* check the required size. */
7432 info.info1 = form_1;
7434 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7436 if (*needed > offered) {
7438 return WERR_INSUFFICIENT_BUFFER;
7441 r->out.info->info1 = form_1;
7443 /* fill the buffer with the form structures */
7444 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7445 r->in.form_name, i));
7451 return WERR_UNKNOWN_LEVEL;
7455 /****************************************************************************
7456 ****************************************************************************/
7458 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7460 init_unistr(&port->port_name, name);
7463 /****************************************************************************
7464 TODO: This probably needs distinguish between TCP/IP and Local ports
7466 ****************************************************************************/
7468 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7470 init_unistr(&port->port_name, name);
7471 init_unistr(&port->monitor_name, "Local Monitor");
7472 init_unistr(&port->description, SPL_LOCAL_PORT );
7473 port->port_type=PORT_TYPE_WRITE;
7478 /****************************************************************************
7479 wrapper around the enumer ports command
7480 ****************************************************************************/
7482 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7484 char *cmd = lp_enumports_cmd();
7485 char **qlines = NULL;
7486 char *command = NULL;
7494 /* if no hook then just fill in the default port */
7497 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7500 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7501 TALLOC_FREE(qlines);
7508 /* we have a valid enumport command */
7510 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7515 DEBUG(10,("Running [%s]\n", command));
7516 ret = smbrun(command, &fd);
7517 DEBUG(10,("Returned [%d]\n", ret));
7518 TALLOC_FREE(command);
7523 return WERR_ACCESS_DENIED;
7527 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7528 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7538 /****************************************************************************
7540 ****************************************************************************/
7542 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7544 PORT_INFO_1 *ports=NULL;
7546 WERROR result = WERR_OK;
7547 char **qlines = NULL;
7550 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7551 if (!W_ERROR_IS_OK(result)) {
7552 TALLOC_FREE(qlines);
7557 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7558 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7559 win_errstr(WERR_NOMEM)));
7560 TALLOC_FREE(qlines);
7564 for (i=0; i<numlines; i++) {
7565 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7566 fill_port_1(&ports[i], qlines[i]);
7569 TALLOC_FREE(qlines);
7571 *returned = numlines;
7573 /* check the required size. */
7574 for (i=0; i<*returned; i++) {
7575 DEBUGADD(6,("adding port [%d]'s size\n", i));
7576 *needed += spoolss_size_port_info_1(&ports[i]);
7579 if (*needed > offered) {
7580 result = WERR_INSUFFICIENT_BUFFER;
7584 if (!rpcbuf_alloc_size(buffer, *needed)) {
7585 result = WERR_NOMEM;
7589 /* fill the buffer with the ports structures */
7590 for (i=0; i<*returned; i++) {
7591 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7592 smb_io_port_1("", buffer, &ports[i], 0);
7598 if ( !W_ERROR_IS_OK(result) )
7604 /****************************************************************************
7606 ****************************************************************************/
7608 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7610 PORT_INFO_2 *ports=NULL;
7612 WERROR result = WERR_OK;
7613 char **qlines = NULL;
7616 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7617 if ( !W_ERROR_IS_OK(result)) {
7618 TALLOC_FREE(qlines);
7623 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7624 TALLOC_FREE(qlines);
7628 for (i=0; i<numlines; i++) {
7629 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7630 fill_port_2(&(ports[i]), qlines[i]);
7634 TALLOC_FREE(qlines);
7636 *returned = numlines;
7638 /* check the required size. */
7639 for (i=0; i<*returned; i++) {
7640 DEBUGADD(6,("adding port [%d]'s size\n", i));
7641 *needed += spoolss_size_port_info_2(&ports[i]);
7644 if (*needed > offered) {
7645 result = WERR_INSUFFICIENT_BUFFER;
7649 if (!rpcbuf_alloc_size(buffer, *needed)) {
7650 result = WERR_NOMEM;
7654 /* fill the buffer with the ports structures */
7655 for (i=0; i<*returned; i++) {
7656 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7657 smb_io_port_2("", buffer, &ports[i], 0);
7663 if ( !W_ERROR_IS_OK(result) )
7669 /****************************************************************************
7671 ****************************************************************************/
7673 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7675 uint32 level = q_u->level;
7676 RPC_BUFFER *buffer = NULL;
7677 uint32 offered = q_u->offered;
7678 uint32 *needed = &r_u->needed;
7679 uint32 *returned = &r_u->returned;
7681 /* that's an [in out] buffer */
7683 if (!q_u->buffer && (offered!=0)) {
7684 return WERR_INVALID_PARAM;
7687 if (offered > MAX_RPC_DATA_SIZE) {
7688 return WERR_INVALID_PARAM;
7691 rpcbuf_move(q_u->buffer, &r_u->buffer);
7692 buffer = r_u->buffer;
7694 DEBUG(4,("_spoolss_enumports\n"));
7701 return enumports_level_1(buffer, offered, needed, returned);
7703 return enumports_level_2(buffer, offered, needed, returned);
7705 return WERR_UNKNOWN_LEVEL;
7709 /****************************************************************************
7710 ****************************************************************************/
7712 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7714 struct spoolss_SetPrinterInfoCtr *info_ctr,
7715 struct spoolss_DeviceMode *devmode,
7716 struct security_descriptor *sec_desc,
7717 struct spoolss_UserLevelCtr *user_ctr,
7720 NT_PRINTER_INFO_LEVEL *printer = NULL;
7723 WERROR err = WERR_OK;
7725 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7726 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7730 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7731 if (!convert_printer_info_new(info_ctr, printer)) {
7732 free_a_printer(&printer, 2);
7736 /* check to see if the printer already exists */
7738 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7739 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7740 printer->info_2->sharename));
7741 free_a_printer(&printer, 2);
7742 return WERR_PRINTER_ALREADY_EXISTS;
7745 /* FIXME!!! smbd should check to see if the driver is installed before
7746 trying to add a printer like this --jerry */
7748 if (*lp_addprinter_cmd() ) {
7749 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7751 free_a_printer(&printer,2);
7752 return WERR_ACCESS_DENIED;
7755 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7756 "smb.conf parameter \"addprinter command\" is defined. This"
7757 "parameter must exist for this call to succeed\n",
7758 printer->info_2->sharename ));
7761 /* use our primary netbios name since get_a_printer() will convert
7762 it to what the client expects on a case by case basis */
7764 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7765 printer->info_2->sharename);
7768 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7769 free_a_printer(&printer,2);
7770 return WERR_ACCESS_DENIED;
7773 /* you must be a printer admin to add a new printer */
7774 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7775 free_a_printer(&printer,2);
7776 return WERR_ACCESS_DENIED;
7780 * Do sanity check on the requested changes for Samba.
7783 if (!check_printer_ok(printer->info_2, snum)) {
7784 free_a_printer(&printer,2);
7785 return WERR_INVALID_PARAM;
7789 * When a printer is created, the drivername bound to the printer is used
7790 * to lookup previously saved driver initialization info, which is then
7791 * bound to the new printer, simulating what happens in the Windows arch.
7796 set_driver_init(printer, 2);
7800 /* A valid devmode was included, convert and link it
7802 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7804 if (!convert_devicemode_new(printer->info_2->printername,
7806 &printer->info_2->devmode))
7810 /* write the ASCII on disk */
7811 err = mod_a_printer(printer, 2);
7812 if (!W_ERROR_IS_OK(err)) {
7813 free_a_printer(&printer,2);
7817 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7818 /* Handle open failed - remove addition. */
7819 del_a_printer(printer->info_2->sharename);
7820 free_a_printer(&printer,2);
7821 ZERO_STRUCTP(handle);
7822 return WERR_ACCESS_DENIED;
7825 update_c_setprinter(False);
7826 free_a_printer(&printer,2);
7831 /****************************************************************
7832 _spoolss_AddPrinterEx
7833 ****************************************************************/
7835 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7836 struct spoolss_AddPrinterEx *r)
7838 switch (r->in.info_ctr->level) {
7840 /* we don't handle yet */
7841 /* but I know what to do ... */
7842 return WERR_UNKNOWN_LEVEL;
7844 return spoolss_addprinterex_level_2(p, r->in.server,
7846 r->in.devmode_ctr->devmode,
7847 r->in.secdesc_ctr->sd,
7848 r->in.userlevel_ctr,
7851 return WERR_UNKNOWN_LEVEL;
7855 /****************************************************************
7856 _spoolss_AddPrinterDriver
7857 ****************************************************************/
7859 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7860 struct spoolss_AddPrinterDriver *r)
7862 uint32_t level = r->in.info_ctr->level;
7863 struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
7864 WERROR err = WERR_OK;
7865 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7866 fstring driver_name;
7870 switch (p->hdr_req.opnum) {
7871 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7872 fn = "_spoolss_AddPrinterDriver";
7874 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7875 fn = "_spoolss_AddPrinterDriverEx";
7878 return WERR_INVALID_PARAM;
7883 if (level != 3 && level != 6) {
7884 /* Clever hack from Martin Zielinski <mz@seh.de>
7885 * to allow downgrade from level 8 (Vista).
7887 DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
7888 return WERR_UNKNOWN_LEVEL;
7891 ZERO_STRUCT(driver);
7893 if (!convert_printer_driver_info(info, &driver, level)) {
7898 DEBUG(5,("Cleaning driver's information\n"));
7899 err = clean_up_driver_struct(p, driver, level);
7900 if (!W_ERROR_IS_OK(err))
7903 DEBUG(5,("Moving driver to final destination\n"));
7904 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7909 if (add_a_printer_driver(driver, level)!=0) {
7910 err = WERR_ACCESS_DENIED;
7916 fstrcpy(driver_name,
7917 driver.info_3->name ? driver.info_3->name : "");
7920 fstrcpy(driver_name,
7921 driver.info_6->name ? driver.info_6->name : "");
7926 * I think this is where he DrvUpgradePrinter() hook would be
7927 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7928 * server. Right now, we just need to send ourselves a message
7929 * to update each printer bound to this driver. --jerry
7932 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7933 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7938 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7939 * decide if the driver init data should be deleted. The rules are:
7940 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7941 * 2) delete init data only if there is no 2k/Xp driver
7942 * 3) always delete init data
7943 * The generalized rule is always use init data from the highest order driver.
7944 * It is necessary to follow the driver install by an initialization step to
7945 * finish off this process.
7948 version = driver.info_3->cversion;
7949 else if (level == 6)
7950 version = driver.info_6->version;
7955 * 9x printer driver - never delete init data
7958 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7963 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7964 * there is no 2k/Xp driver init data for this driver name.
7968 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7970 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7972 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7974 if (!del_driver_init(driver_name))
7975 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7979 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7981 free_a_printer_driver(driver1,3);
7982 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7989 * 2k or Xp printer driver - always delete init data
7992 if (!del_driver_init(driver_name))
7993 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7998 DEBUG(0,("%s: invalid level=%d\n", fn, level));
8004 free_a_printer_driver(driver, level);
8008 /****************************************************************
8009 _spoolss_AddPrinterDriverEx
8010 ****************************************************************/
8012 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
8013 struct spoolss_AddPrinterDriverEx *r)
8015 struct spoolss_AddPrinterDriver a;
8018 * we only support the semantics of AddPrinterDriver()
8019 * i.e. only copy files that are newer than existing ones
8022 if (r->in.flags != APD_COPY_NEW_FILES) {
8023 return WERR_ACCESS_DENIED;
8026 a.in.servername = r->in.servername;
8027 a.in.info_ctr = r->in.info_ctr;
8029 return _spoolss_AddPrinterDriver(p, &a);
8032 /****************************************************************************
8033 ****************************************************************************/
8035 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8036 const char *servername,
8037 const char *environment,
8038 struct spoolss_DriverDirectoryInfo1 *info1,
8043 const char *pservername = NULL;
8044 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
8045 const char *short_archi;
8048 long_archi = environment;
8051 pservername = canon_servername(servername);
8053 if ( !is_myname_or_ipaddr(pservername))
8054 return WERR_INVALID_PARAM;
8056 if (!(short_archi = get_short_archi(long_archi)))
8057 return WERR_INVALID_ENVIRONMENT;
8059 path = talloc_asprintf(mem_ctx,
8060 "\\\\%s\\print$\\%s", pservername, short_archi);
8065 DEBUG(4,("printer driver directory: [%s]\n", path));
8067 info1->directory_name = path;
8069 *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0);
8071 if (*needed > offered) {
8073 ZERO_STRUCTP(info1);
8074 return WERR_INSUFFICIENT_BUFFER;
8080 /****************************************************************
8081 _spoolss_GetPrinterDriverDirectory
8082 ****************************************************************/
8084 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8085 struct spoolss_GetPrinterDriverDirectory *r)
8089 /* that's an [in out] buffer */
8091 if (!r->in.buffer && (r->in.offered != 0)) {
8092 return WERR_INVALID_PARAM;
8095 if (r->in.offered > MAX_RPC_DATA_SIZE) {
8096 return WERR_INVALID_PARAM;
8099 DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n"));
8103 switch (r->in.level) {
8105 werror = getprinterdriverdir_level_1(p->mem_ctx,
8108 &r->out.info->info1,
8111 if (!W_ERROR_IS_OK(werror)) {
8112 TALLOC_FREE(r->out.info);
8116 return WERR_UNKNOWN_LEVEL;
8122 /****************************************************************************
8123 ****************************************************************************/
8125 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8127 POLICY_HND *handle = &q_u->handle;
8128 uint32 idx = q_u->index;
8129 uint32 in_value_len = q_u->valuesize;
8130 uint32 in_data_len = q_u->datasize;
8131 uint32 *out_max_value_len = &r_u->valuesize;
8132 uint16 **out_value = &r_u->value;
8133 uint32 *out_value_len = &r_u->realvaluesize;
8134 uint32 *out_type = &r_u->type;
8135 uint32 *out_max_data_len = &r_u->datasize;
8136 uint8 **data_out = &r_u->data;
8137 uint32 *out_data_len = &r_u->realdatasize;
8139 NT_PRINTER_INFO_LEVEL *printer = NULL;
8141 uint32 biggest_valuesize;
8142 uint32 biggest_datasize;
8144 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8147 REGISTRY_VALUE *val = NULL;
8148 NT_PRINTER_DATA *p_data;
8149 int i, key_index, num_values;
8154 *out_max_data_len = 0;
8158 DEBUG(5,("spoolss_enumprinterdata\n"));
8161 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8165 if (!get_printer_snum(p,handle, &snum, NULL))
8168 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8169 if (!W_ERROR_IS_OK(result))
8172 p_data = printer->info_2->data;
8173 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8178 * The NT machine wants to know the biggest size of value and data
8180 * cf: MSDN EnumPrinterData remark section
8183 if ( !in_value_len && !in_data_len && (key_index != -1) )
8185 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8187 biggest_valuesize = 0;
8188 biggest_datasize = 0;
8190 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8192 for ( i=0; i<num_values; i++ )
8194 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8196 name_length = strlen(val->valuename);
8197 if ( strlen(val->valuename) > biggest_valuesize )
8198 biggest_valuesize = name_length;
8200 if ( val->size > biggest_datasize )
8201 biggest_datasize = val->size;
8203 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8207 /* the value is an UNICODE string but real_value_size is the length
8208 in bytes including the trailing 0 */
8210 *out_value_len = 2 * (1+biggest_valuesize);
8211 *out_data_len = biggest_datasize;
8213 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8219 * the value len is wrong in NT sp3
8220 * that's the number of bytes not the number of unicode chars
8223 if ( key_index != -1 )
8224 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8229 /* out_value should default to "" or else NT4 has
8230 problems unmarshalling the response */
8232 *out_max_value_len=(in_value_len/sizeof(uint16));
8235 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8237 result = WERR_NOMEM;
8240 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8246 /* the data is counted in bytes */
8248 *out_max_data_len = in_data_len;
8249 *out_data_len = in_data_len;
8251 /* only allocate when given a non-zero data_len */
8253 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8255 result = WERR_NOMEM;
8259 result = WERR_NO_MORE_ITEMS;
8265 * - counted in bytes in the request
8266 * - counted in UNICODE chars in the max reply
8267 * - counted in bytes in the real size
8269 * take a pause *before* coding not *during* coding
8273 *out_max_value_len=(in_value_len/sizeof(uint16));
8275 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8277 result = WERR_NOMEM;
8281 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8289 *out_type = regval_type( val );
8291 /* data - counted in bytes */
8293 *out_max_data_len = in_data_len;
8294 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8296 result = WERR_NOMEM;
8299 data_len = regval_size(val);
8300 if ( *data_out && data_len )
8301 memcpy( *data_out, regval_data_p(val), data_len );
8302 *out_data_len = data_len;
8306 free_a_printer(&printer, 2);
8310 /****************************************************************************
8311 ****************************************************************************/
8313 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8315 POLICY_HND *handle = &q_u->handle;
8316 UNISTR2 *value = &q_u->value;
8317 uint32 type = q_u->type;
8318 uint8 *data = q_u->data;
8319 uint32 real_len = q_u->real_len;
8321 NT_PRINTER_INFO_LEVEL *printer = NULL;
8323 WERROR status = WERR_OK;
8324 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8327 DEBUG(5,("spoolss_setprinterdata\n"));
8330 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8334 if ( Printer->printer_type == SPLHND_SERVER ) {
8335 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8336 return WERR_INVALID_PARAM;
8339 if (!get_printer_snum(p,handle, &snum, NULL))
8343 * Access check : NT returns "access denied" if you make a
8344 * SetPrinterData call without the necessary privildge.
8345 * we were originally returning OK if nothing changed
8346 * which made Win2k issue **a lot** of SetPrinterData
8347 * when connecting to a printer --jerry
8350 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8352 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8353 status = WERR_ACCESS_DENIED;
8357 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8358 if (!W_ERROR_IS_OK(status))
8361 unistr2_to_ascii(valuename, value, sizeof(valuename));
8364 * When client side code sets a magic printer data key, detect it and save
8365 * the current printer data and the magic key's data (its the DEVMODE) for
8366 * future printer/driver initializations.
8368 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8370 /* Set devmode and printer initialization info */
8371 status = save_driver_init( printer, 2, data, real_len );
8373 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8377 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8378 type, data, real_len );
8379 if ( W_ERROR_IS_OK(status) )
8380 status = mod_a_printer(printer, 2);
8384 free_a_printer(&printer, 2);
8389 /****************************************************************
8390 _spoolss_ResetPrinter
8391 ****************************************************************/
8393 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8394 struct spoolss_ResetPrinter *r)
8396 POLICY_HND *handle = r->in.handle;
8397 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8400 DEBUG(5,("_spoolss_ResetPrinter\n"));
8403 * All we do is to check to see if the handle and queue is valid.
8404 * This call really doesn't mean anything to us because we only
8405 * support RAW printing. --jerry
8409 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8410 OUR_HANDLE(handle)));
8414 if (!get_printer_snum(p,handle, &snum, NULL))
8418 /* blindly return success */
8422 /****************************************************************
8423 _spoolss_DeletePrinterData
8424 ****************************************************************/
8426 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8427 struct spoolss_DeletePrinterData *r)
8429 POLICY_HND *handle = r->in.handle;
8430 NT_PRINTER_INFO_LEVEL *printer = NULL;
8432 WERROR status = WERR_OK;
8433 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8435 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8438 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8439 OUR_HANDLE(handle)));
8443 if (!get_printer_snum(p, handle, &snum, NULL))
8446 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8447 DEBUG(3, ("_spoolss_DeletePrinterData: "
8448 "printer properties change denied by handle\n"));
8449 return WERR_ACCESS_DENIED;
8452 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8453 if (!W_ERROR_IS_OK(status))
8456 if (!r->in.value_name) {
8457 free_a_printer(&printer, 2);
8461 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8464 if ( W_ERROR_IS_OK(status) )
8465 mod_a_printer( printer, 2 );
8467 free_a_printer(&printer, 2);
8472 /****************************************************************
8474 ****************************************************************/
8476 WERROR _spoolss_AddForm(pipes_struct *p,
8477 struct spoolss_AddForm *r)
8479 POLICY_HND *handle = r->in.handle;
8480 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8481 nt_forms_struct tmpForm;
8483 WERROR status = WERR_OK;
8484 NT_PRINTER_INFO_LEVEL *printer = NULL;
8487 nt_forms_struct *list=NULL;
8488 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8490 DEBUG(5,("_spoolss_AddForm\n"));
8493 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8494 OUR_HANDLE(handle)));
8499 /* forms can be added on printer of on the print server handle */
8501 if ( Printer->printer_type == SPLHND_PRINTER )
8503 if (!get_printer_snum(p,handle, &snum, NULL))
8506 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8507 if (!W_ERROR_IS_OK(status))
8511 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8512 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8513 status = WERR_ACCESS_DENIED;
8517 /* can't add if builtin */
8519 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8520 status = WERR_FILE_EXISTS;
8524 count = get_ntforms(&list);
8526 if(!add_a_form(&list, form, &count)) {
8527 status = WERR_NOMEM;
8531 write_ntforms(&list, count);
8534 * ChangeID must always be set if this is a printer
8537 if ( Printer->printer_type == SPLHND_PRINTER )
8538 status = mod_a_printer(printer, 2);
8542 free_a_printer(&printer, 2);
8548 /****************************************************************
8550 ****************************************************************/
8552 WERROR _spoolss_DeleteForm(pipes_struct *p,
8553 struct spoolss_DeleteForm *r)
8555 POLICY_HND *handle = r->in.handle;
8556 const char *form_name = r->in.form_name;
8557 nt_forms_struct tmpForm;
8559 nt_forms_struct *list=NULL;
8560 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8562 WERROR status = WERR_OK;
8563 NT_PRINTER_INFO_LEVEL *printer = NULL;
8565 DEBUG(5,("_spoolss_DeleteForm\n"));
8568 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8569 OUR_HANDLE(handle)));
8573 /* forms can be deleted on printer of on the print server handle */
8575 if ( Printer->printer_type == SPLHND_PRINTER )
8577 if (!get_printer_snum(p,handle, &snum, NULL))
8580 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8581 if (!W_ERROR_IS_OK(status))
8585 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8586 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8587 status = WERR_ACCESS_DENIED;
8591 /* can't delete if builtin */
8593 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8594 status = WERR_INVALID_PARAM;
8598 count = get_ntforms(&list);
8600 if ( !delete_a_form(&list, form_name, &count, &status ))
8604 * ChangeID must always be set if this is a printer
8607 if ( Printer->printer_type == SPLHND_PRINTER )
8608 status = mod_a_printer(printer, 2);
8612 free_a_printer(&printer, 2);
8618 /****************************************************************
8620 ****************************************************************/
8622 WERROR _spoolss_SetForm(pipes_struct *p,
8623 struct spoolss_SetForm *r)
8625 POLICY_HND *handle = r->in.handle;
8626 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8627 nt_forms_struct tmpForm;
8629 WERROR status = WERR_OK;
8630 NT_PRINTER_INFO_LEVEL *printer = NULL;
8633 nt_forms_struct *list=NULL;
8634 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8636 DEBUG(5,("_spoolss_SetForm\n"));
8639 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8640 OUR_HANDLE(handle)));
8644 /* forms can be modified on printer of on the print server handle */
8646 if ( Printer->printer_type == SPLHND_PRINTER )
8648 if (!get_printer_snum(p,handle, &snum, NULL))
8651 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8652 if (!W_ERROR_IS_OK(status))
8656 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8657 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8658 status = WERR_ACCESS_DENIED;
8662 /* can't set if builtin */
8663 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8664 status = WERR_INVALID_PARAM;
8668 count = get_ntforms(&list);
8669 update_a_form(&list, form, count);
8670 write_ntforms(&list, count);
8673 * ChangeID must always be set if this is a printer
8676 if ( Printer->printer_type == SPLHND_PRINTER )
8677 status = mod_a_printer(printer, 2);
8682 free_a_printer(&printer, 2);
8688 /****************************************************************************
8689 enumprintprocessors level 1.
8690 ****************************************************************************/
8692 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8694 PRINTPROCESSOR_1 *info_1=NULL;
8695 WERROR result = WERR_OK;
8697 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8702 init_unistr(&info_1->name, "winprint");
8704 *needed += spoolss_size_printprocessor_info_1(info_1);
8706 if (*needed > offered) {
8707 result = WERR_INSUFFICIENT_BUFFER;
8711 if (!rpcbuf_alloc_size(buffer, *needed)) {
8712 result = WERR_NOMEM;
8716 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8721 if ( !W_ERROR_IS_OK(result) )
8727 /****************************************************************************
8728 ****************************************************************************/
8730 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8732 uint32 level = q_u->level;
8733 RPC_BUFFER *buffer = NULL;
8734 uint32 offered = q_u->offered;
8735 uint32 *needed = &r_u->needed;
8736 uint32 *returned = &r_u->returned;
8738 /* that's an [in out] buffer */
8740 if (!q_u->buffer && (offered!=0)) {
8741 return WERR_INVALID_PARAM;
8744 if (offered > MAX_RPC_DATA_SIZE) {
8745 return WERR_INVALID_PARAM;
8748 rpcbuf_move(q_u->buffer, &r_u->buffer);
8749 buffer = r_u->buffer;
8751 DEBUG(5,("spoolss_enumprintprocessors\n"));
8754 * Enumerate the print processors ...
8756 * Just reply with "winprint", to keep NT happy
8757 * and I can use my nice printer checker.
8765 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8767 return WERR_UNKNOWN_LEVEL;
8771 /****************************************************************************
8772 enumprintprocdatatypes level 1.
8773 ****************************************************************************/
8775 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8777 PRINTPROCDATATYPE_1 *info_1=NULL;
8778 WERROR result = WERR_OK;
8780 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8785 init_unistr(&info_1->name, "RAW");
8787 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8789 if (*needed > offered) {
8790 result = WERR_INSUFFICIENT_BUFFER;
8794 if (!rpcbuf_alloc_size(buffer, *needed)) {
8795 result = WERR_NOMEM;
8799 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8804 if ( !W_ERROR_IS_OK(result) )
8810 /****************************************************************************
8811 ****************************************************************************/
8813 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8815 uint32 level = q_u->level;
8816 RPC_BUFFER *buffer = NULL;
8817 uint32 offered = q_u->offered;
8818 uint32 *needed = &r_u->needed;
8819 uint32 *returned = &r_u->returned;
8821 /* that's an [in out] buffer */
8823 if (!q_u->buffer && (offered!=0)) {
8824 return WERR_INVALID_PARAM;
8827 if (offered > MAX_RPC_DATA_SIZE) {
8828 return WERR_INVALID_PARAM;
8831 rpcbuf_move(q_u->buffer, &r_u->buffer);
8832 buffer = r_u->buffer;
8834 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8841 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8843 return WERR_UNKNOWN_LEVEL;
8847 /****************************************************************************
8848 enumprintmonitors level 1.
8849 ****************************************************************************/
8851 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8853 PRINTMONITOR_1 *info_1;
8854 WERROR result = WERR_OK;
8857 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8862 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8863 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8865 for ( i=0; i<*returned; i++ ) {
8866 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8869 if (*needed > offered) {
8870 result = WERR_INSUFFICIENT_BUFFER;
8874 if (!rpcbuf_alloc_size(buffer, *needed)) {
8875 result = WERR_NOMEM;
8879 for ( i=0; i<*returned; i++ ) {
8880 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8886 if ( !W_ERROR_IS_OK(result) )
8892 /****************************************************************************
8893 enumprintmonitors level 2.
8894 ****************************************************************************/
8896 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8898 PRINTMONITOR_2 *info_2;
8899 WERROR result = WERR_OK;
8902 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8907 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8908 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8909 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8911 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8912 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8913 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8915 for ( i=0; i<*returned; i++ ) {
8916 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8919 if (*needed > offered) {
8920 result = WERR_INSUFFICIENT_BUFFER;
8924 if (!rpcbuf_alloc_size(buffer, *needed)) {
8925 result = WERR_NOMEM;
8929 for ( i=0; i<*returned; i++ ) {
8930 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8936 if ( !W_ERROR_IS_OK(result) )
8942 /****************************************************************************
8943 ****************************************************************************/
8945 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8947 uint32 level = q_u->level;
8948 RPC_BUFFER *buffer = NULL;
8949 uint32 offered = q_u->offered;
8950 uint32 *needed = &r_u->needed;
8951 uint32 *returned = &r_u->returned;
8953 /* that's an [in out] buffer */
8955 if (!q_u->buffer && (offered!=0)) {
8956 return WERR_INVALID_PARAM;
8959 if (offered > MAX_RPC_DATA_SIZE) {
8960 return WERR_INVALID_PARAM;
8963 rpcbuf_move(q_u->buffer, &r_u->buffer);
8964 buffer = r_u->buffer;
8966 DEBUG(5,("spoolss_enumprintmonitors\n"));
8969 * Enumerate the print monitors ...
8971 * Just reply with "Local Port", to keep NT happy
8972 * and I can use my nice printer checker.
8980 return enumprintmonitors_level_1(buffer, offered, needed, returned);
8982 return enumprintmonitors_level_2(buffer, offered, needed, returned);
8984 return WERR_UNKNOWN_LEVEL;
8988 /****************************************************************************
8989 ****************************************************************************/
8991 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
8992 NT_PRINTER_INFO_LEVEL *ntprinter,
8993 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
8998 JOB_INFO_1 *info_1=NULL;
8999 WERROR result = WERR_OK;
9001 info_1=SMB_MALLOC_P(JOB_INFO_1);
9003 if (info_1 == NULL) {
9007 for (i=0; i<count && found==False; i++) {
9008 if ((*queue)[i].job==(int)jobid)
9014 /* NT treats not found as bad param... yet another bad choice */
9015 return WERR_INVALID_PARAM;
9018 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
9020 *needed += spoolss_size_job_info_1(info_1);
9022 if (*needed > offered) {
9023 result = WERR_INSUFFICIENT_BUFFER;
9027 if (!rpcbuf_alloc_size(buffer, *needed)) {
9028 result = WERR_NOMEM;
9032 smb_io_job_info_1("", buffer, info_1, 0);
9040 /****************************************************************************
9041 ****************************************************************************/
9043 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9044 NT_PRINTER_INFO_LEVEL *ntprinter,
9045 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9052 DEVICEMODE *devmode = NULL;
9053 NT_DEVICEMODE *nt_devmode = NULL;
9055 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9058 ZERO_STRUCTP(info_2);
9060 for ( i=0; i<count && found==False; i++ )
9062 if ((*queue)[i].job == (int)jobid)
9067 /* NT treats not found as bad param... yet another bad
9069 result = WERR_INVALID_PARAM;
9074 * if the print job does not have a DEVMODE associated with it,
9075 * just use the one for the printer. A NULL devicemode is not
9076 * a failure condition
9079 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9080 devmode = construct_dev_mode(lp_const_servicename(snum));
9082 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9083 ZERO_STRUCTP( devmode );
9084 convert_nt_devicemode( devmode, nt_devmode );
9088 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9090 *needed += spoolss_size_job_info_2(info_2);
9092 if (*needed > offered) {
9093 result = WERR_INSUFFICIENT_BUFFER;
9097 if (!rpcbuf_alloc_size(buffer, *needed)) {
9098 result = WERR_NOMEM;
9102 smb_io_job_info_2("", buffer, info_2, 0);
9107 /* Cleanup allocated memory */
9109 free_job_info_2(info_2); /* Also frees devmode */
9115 /****************************************************************************
9116 ****************************************************************************/
9118 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9120 POLICY_HND *handle = &q_u->handle;
9121 uint32 jobid = q_u->jobid;
9122 uint32 level = q_u->level;
9123 RPC_BUFFER *buffer = NULL;
9124 uint32 offered = q_u->offered;
9125 uint32 *needed = &r_u->needed;
9126 WERROR wstatus = WERR_OK;
9127 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9130 print_queue_struct *queue = NULL;
9131 print_status_struct prt_status;
9133 /* that's an [in out] buffer */
9135 if (!q_u->buffer && (offered!=0)) {
9136 return WERR_INVALID_PARAM;
9139 if (offered > MAX_RPC_DATA_SIZE) {
9140 return WERR_INVALID_PARAM;
9143 rpcbuf_move(q_u->buffer, &r_u->buffer);
9144 buffer = r_u->buffer;
9146 DEBUG(5,("spoolss_getjob\n"));
9150 if (!get_printer_snum(p, handle, &snum, NULL))
9153 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9154 if ( !W_ERROR_IS_OK(wstatus) )
9157 count = print_queue_status(snum, &queue, &prt_status);
9159 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9160 count, prt_status.status, prt_status.message));
9164 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9165 buffer, offered, needed);
9168 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9169 buffer, offered, needed);
9172 wstatus = WERR_UNKNOWN_LEVEL;
9177 free_a_printer( &ntprinter, 2 );
9182 /****************************************************************
9183 _spoolss_GetPrinterDataEx
9185 From MSDN documentation of GetPrinterDataEx: pass request
9186 to GetPrinterData if key is "PrinterDriverData".
9187 ****************************************************************/
9189 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9190 struct spoolss_GetPrinterDataEx *r)
9192 POLICY_HND *handle = r->in.handle;
9194 const char *keyname = r->in.key_name;
9195 const char *valuename = r->in.value_name;
9197 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9199 NT_PRINTER_INFO_LEVEL *printer = NULL;
9201 WERROR status = WERR_OK;
9203 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9205 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9206 keyname, valuename));
9208 /* in case of problem, return some default values */
9214 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9215 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9216 status = WERR_BADFID;
9220 /* Is the handle to a printer or to the server? */
9222 if (Printer->printer_type == SPLHND_SERVER) {
9223 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9224 "Not implemented for server handles yet\n"));
9225 status = WERR_INVALID_PARAM;
9229 if ( !get_printer_snum(p,handle, &snum, NULL) )
9232 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9233 if ( !W_ERROR_IS_OK(status) )
9236 /* check to see if the keyname is valid */
9237 if ( !strlen(keyname) ) {
9238 status = WERR_INVALID_PARAM;
9242 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9243 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9244 "Invalid keyname [%s]\n", keyname ));
9245 free_a_printer( &printer, 2 );
9246 status = WERR_BADFILE;
9250 /* When given a new keyname, we should just create it */
9252 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9253 r->out.type, &data, r->out.needed,
9256 if (*r->out.needed > r->in.offered) {
9257 status = WERR_MORE_DATA;
9260 if (W_ERROR_IS_OK(status)) {
9261 memcpy(r->out.buffer, data, r->in.offered);
9266 free_a_printer( &printer, 2 );
9271 /****************************************************************
9272 _spoolss_SetPrinterDataEx
9273 ****************************************************************/
9275 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9276 struct spoolss_SetPrinterDataEx *r)
9278 POLICY_HND *handle = r->in.handle;
9279 NT_PRINTER_INFO_LEVEL *printer = NULL;
9281 WERROR status = WERR_OK;
9282 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9285 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9287 /* From MSDN documentation of SetPrinterDataEx: pass request to
9288 SetPrinterData if key is "PrinterDriverData" */
9291 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9292 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9296 if ( Printer->printer_type == SPLHND_SERVER ) {
9297 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9298 "Not implemented for server handles yet\n"));
9299 return WERR_INVALID_PARAM;
9302 if ( !get_printer_snum(p,handle, &snum, NULL) )
9306 * Access check : NT returns "access denied" if you make a
9307 * SetPrinterData call without the necessary privildge.
9308 * we were originally returning OK if nothing changed
9309 * which made Win2k issue **a lot** of SetPrinterData
9310 * when connecting to a printer --jerry
9313 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9315 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9316 "change denied by handle access permissions\n"));
9317 return WERR_ACCESS_DENIED;
9320 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9321 if (!W_ERROR_IS_OK(status))
9324 /* check for OID in valuename */
9326 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9332 /* save the registry data */
9334 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9335 r->in.type, r->in.buffer, r->in.offered );
9337 if ( W_ERROR_IS_OK(status) )
9339 /* save the OID if one was specified */
9341 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9342 r->in.key_name, SPOOL_OID_KEY);
9348 * I'm not checking the status here on purpose. Don't know
9349 * if this is right, but I'm returning the status from the
9350 * previous set_printer_dataex() call. I have no idea if
9351 * this is right. --jerry
9354 set_printer_dataex( printer, str, r->in.value_name,
9355 REG_SZ, (uint8 *)oid_string,
9356 strlen(oid_string)+1 );
9359 status = mod_a_printer(printer, 2);
9362 free_a_printer(&printer, 2);
9367 /****************************************************************
9368 _spoolss_DeletePrinterDataEx
9369 ****************************************************************/
9371 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9372 struct spoolss_DeletePrinterDataEx *r)
9374 POLICY_HND *handle = r->in.handle;
9375 NT_PRINTER_INFO_LEVEL *printer = NULL;
9377 WERROR status = WERR_OK;
9378 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9380 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9383 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9384 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9388 if (!get_printer_snum(p, handle, &snum, NULL))
9391 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9392 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9393 "printer properties change denied by handle\n"));
9394 return WERR_ACCESS_DENIED;
9397 if (!r->in.value_name || !r->in.key_name) {
9401 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9402 if (!W_ERROR_IS_OK(status))
9405 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9407 if ( W_ERROR_IS_OK(status) )
9408 mod_a_printer( printer, 2 );
9410 free_a_printer(&printer, 2);
9415 /********************************************************************
9416 * spoolss_enumprinterkey
9417 ********************************************************************/
9420 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9423 fstring *keynames = NULL;
9424 uint16 *enumkeys = NULL;
9427 POLICY_HND *handle = &q_u->handle;
9428 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9429 NT_PRINTER_DATA *data;
9430 NT_PRINTER_INFO_LEVEL *printer = NULL;
9432 WERROR status = WERR_BADFILE;
9435 DEBUG(4,("_spoolss_enumprinterkey\n"));
9438 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9442 if ( !get_printer_snum(p,handle, &snum, NULL) )
9445 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9446 if (!W_ERROR_IS_OK(status))
9449 /* get the list of subkey names */
9451 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9452 data = printer->info_2->data;
9454 num_keys = get_printer_subkeys( data, key, &keynames );
9456 if ( num_keys == -1 ) {
9457 status = WERR_BADFILE;
9461 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9463 r_u->needed = printerkey_len*2;
9465 if ( q_u->size < r_u->needed ) {
9466 status = WERR_MORE_DATA;
9470 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9471 status = WERR_NOMEM;
9477 if ( q_u->size < r_u->needed )
9478 status = WERR_MORE_DATA;
9481 free_a_printer( &printer, 2 );
9482 SAFE_FREE( keynames );
9487 /****************************************************************
9488 _spoolss_DeletePrinterKey
9489 ****************************************************************/
9491 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9492 struct spoolss_DeletePrinterKey *r)
9494 POLICY_HND *handle = r->in.handle;
9495 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9496 NT_PRINTER_INFO_LEVEL *printer = NULL;
9500 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9503 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9504 OUR_HANDLE(handle)));
9508 /* if keyname == NULL, return error */
9510 if ( !r->in.key_name )
9511 return WERR_INVALID_PARAM;
9513 if (!get_printer_snum(p, handle, &snum, NULL))
9516 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9517 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9518 "printer properties change denied by handle\n"));
9519 return WERR_ACCESS_DENIED;
9522 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9523 if (!W_ERROR_IS_OK(status))
9526 /* delete the key and all subneys */
9528 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9530 if ( W_ERROR_IS_OK(status) )
9531 status = mod_a_printer(printer, 2);
9533 free_a_printer( &printer, 2 );
9539 /********************************************************************
9540 * spoolss_enumprinterdataex
9541 ********************************************************************/
9543 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9545 POLICY_HND *handle = &q_u->handle;
9546 uint32 in_size = q_u->size;
9549 NT_PRINTER_INFO_LEVEL *printer = NULL;
9550 PRINTER_ENUM_VALUES *enum_values = NULL;
9551 NT_PRINTER_DATA *p_data;
9553 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9558 REGISTRY_VALUE *val;
9563 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9566 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9571 * first check for a keyname of NULL or "". Win2k seems to send
9572 * this a lot and we should send back WERR_INVALID_PARAM
9573 * no need to spend time looking up the printer in this case.
9577 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9578 if ( !strlen(key) ) {
9579 result = WERR_INVALID_PARAM;
9583 /* get the printer off of disk */
9585 if (!get_printer_snum(p,handle, &snum, NULL))
9588 ZERO_STRUCT(printer);
9589 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9590 if (!W_ERROR_IS_OK(result))
9593 /* now look for a match on the key name */
9595 p_data = printer->info_2->data;
9597 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9598 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9600 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9601 result = WERR_INVALID_PARAM;
9608 /* allocate the memory for the array of pointers -- if necessary */
9610 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9613 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9615 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9616 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9617 result = WERR_NOMEM;
9621 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9625 * loop through all params and build the array to pass
9626 * back to the client
9629 for ( i=0; i<num_entries; i++ )
9631 /* lookup the registry value */
9633 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9634 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9638 value_name = regval_name( val );
9639 init_unistr( &enum_values[i].valuename, value_name );
9640 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9641 enum_values[i].type = regval_type( val );
9643 data_len = regval_size( val );
9645 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9647 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9649 result = WERR_NOMEM;
9653 enum_values[i].data_len = data_len;
9655 /* keep track of the size of the array in bytes */
9657 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9660 /* housekeeping information in the reply */
9662 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9663 * the hand marshalled container size is a multiple
9664 * of 4 bytes for RPC alignment.
9668 needed += 4-(needed % 4);
9671 r_u->needed = needed;
9672 r_u->returned = num_entries;
9674 if (needed > in_size) {
9675 result = WERR_MORE_DATA;
9679 /* copy data into the reply */
9681 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9682 response buffer size is != the offered buffer size
9684 r_u->ctr.size = r_u->needed;
9686 r_u->ctr.size = in_size;
9688 r_u->ctr.size_of_array = r_u->returned;
9689 r_u->ctr.values = enum_values;
9693 free_a_printer(&printer, 2);
9698 /****************************************************************************
9699 ****************************************************************************/
9701 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9702 const char *servername,
9703 const char *environment,
9704 struct spoolss_PrintProcessorDirectoryInfo1 *info1,
9708 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
9709 const char *short_archi;
9712 long_archi = environment;
9715 short_archi = get_short_archi(long_archi);
9717 return WERR_INVALID_ENVIRONMENT;
9720 /* I think this should look like this - gd
9721 info1->directory_name = talloc_asprintf(mem_ctx,
9722 "C:\\WINNT\\System32\\spool\\PRTPROCS\\%s", short_archi);
9724 info1->directory_name = talloc_strdup(mem_ctx,
9725 "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9727 if (!info1->directory_name) {
9731 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(info1, NULL, 0);
9733 if (*needed > offered) {
9734 return WERR_INSUFFICIENT_BUFFER;
9740 /****************************************************************
9741 _spoolss_GetPrintProcessorDirectory
9742 ****************************************************************/
9744 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9745 struct spoolss_GetPrintProcessorDirectory *r)
9749 /* that's an [in out] buffer */
9751 if (!r->in.buffer && (r->in.offered != 0)) {
9752 return WERR_INVALID_PARAM;
9755 if (r->in.offered > MAX_RPC_DATA_SIZE) {
9756 return WERR_INVALID_PARAM;
9759 DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n"));
9763 switch (r->in.level) {
9765 result = getprintprocessordirectory_level_1(p->mem_ctx,
9768 &r->out.info->info1,
9771 if (!W_ERROR_IS_OK(result)) {
9772 TALLOC_FREE(r->out.info);
9776 result = WERR_UNKNOWN_LEVEL;
9782 /*******************************************************************
9783 ********************************************************************/
9785 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9786 const char *dllname)
9788 enum ndr_err_code ndr_err;
9789 struct spoolss_MonitorUi ui;
9791 ui.dll_name = dllname;
9793 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9794 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9795 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9796 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9798 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9801 /*******************************************************************
9802 Streams the monitor UI DLL name in UNICODE
9803 *******************************************************************/
9805 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9806 NT_USER_TOKEN *token, DATA_BLOB *in,
9807 DATA_BLOB *out, uint32_t *needed)
9809 const char *dllname = "tcpmonui.dll";
9811 *needed = (strlen(dllname)+1) * 2;
9813 if (out->length < *needed) {
9814 return WERR_INSUFFICIENT_BUFFER;
9817 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9824 /*******************************************************************
9825 ********************************************************************/
9827 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9828 struct spoolss_PortData1 *port1,
9829 const DATA_BLOB *buf)
9831 enum ndr_err_code ndr_err;
9832 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9833 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9834 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9835 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9837 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9840 /*******************************************************************
9841 ********************************************************************/
9843 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9844 struct spoolss_PortData2 *port2,
9845 const DATA_BLOB *buf)
9847 enum ndr_err_code ndr_err;
9848 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9849 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9850 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9851 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9853 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9856 /*******************************************************************
9857 Create a new TCP/IP port
9858 *******************************************************************/
9860 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9861 NT_USER_TOKEN *token, DATA_BLOB *in,
9862 DATA_BLOB *out, uint32_t *needed)
9864 struct spoolss_PortData1 port1;
9865 struct spoolss_PortData2 port2;
9866 char *device_uri = NULL;
9869 const char *portname;
9870 const char *hostaddress;
9872 uint32_t port_number;
9875 /* peek for spoolss_PortData version */
9877 if (!in || (in->length < (128 + 4))) {
9878 return WERR_GENERAL_FAILURE;
9881 version = IVAL(in->data, 128);
9887 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9891 portname = port1.portname;
9892 hostaddress = port1.hostaddress;
9893 queue = port1.queue;
9894 protocol = port1.protocol;
9895 port_number = port1.port_number;
9901 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9905 portname = port2.portname;
9906 hostaddress = port2.hostaddress;
9907 queue = port2.queue;
9908 protocol = port2.protocol;
9909 port_number = port2.port_number;
9913 DEBUG(1,("xcvtcp_addport: "
9914 "unknown version of port_data: %d\n", version));
9915 return WERR_UNKNOWN_PORT;
9918 /* create the device URI and call the add_port_hook() */
9921 case PROTOCOL_RAWTCP_TYPE:
9922 device_uri = talloc_asprintf(mem_ctx,
9923 "socket://%s:%d/", hostaddress,
9927 case PROTOCOL_LPR_TYPE:
9928 device_uri = talloc_asprintf(mem_ctx,
9929 "lpr://%s/%s", hostaddress, queue );
9933 return WERR_UNKNOWN_PORT;
9940 return add_port_hook(mem_ctx, token, portname, device_uri);
9943 /*******************************************************************
9944 *******************************************************************/
9946 struct xcv_api_table xcvtcp_cmds[] = {
9947 { "MonitorUI", xcvtcp_monitorui },
9948 { "AddPort", xcvtcp_addport},
9952 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9953 NT_USER_TOKEN *token, const char *command,
9960 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9962 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9963 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9964 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9967 return WERR_BADFUNC;
9970 /*******************************************************************
9971 *******************************************************************/
9972 #if 0 /* don't support management using the "Local Port" monitor */
9974 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9975 NT_USER_TOKEN *token, DATA_BLOB *in,
9976 DATA_BLOB *out, uint32_t *needed)
9978 const char *dllname = "localui.dll";
9980 *needed = (strlen(dllname)+1) * 2;
9982 if (out->length < *needed) {
9983 return WERR_INSUFFICIENT_BUFFER;
9986 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9993 /*******************************************************************
9994 *******************************************************************/
9996 struct xcv_api_table xcvlocal_cmds[] = {
9997 { "MonitorUI", xcvlocal_monitorui },
10001 struct xcv_api_table xcvlocal_cmds[] = {
10008 /*******************************************************************
10009 *******************************************************************/
10011 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
10012 NT_USER_TOKEN *token, const char *command,
10013 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
10018 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
10020 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
10021 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
10022 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
10024 return WERR_BADFUNC;
10027 /****************************************************************
10029 ****************************************************************/
10031 WERROR _spoolss_XcvData(pipes_struct *p,
10032 struct spoolss_XcvData *r)
10034 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10035 DATA_BLOB out_data;
10039 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10040 OUR_HANDLE(r->in.handle)));
10041 return WERR_BADFID;
10044 /* Has to be a handle to the TCP/IP port monitor */
10046 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10047 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10048 return WERR_BADFID;
10051 /* requires administrative access to the server */
10053 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10054 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10055 return WERR_ACCESS_DENIED;
10058 /* Allocate the outgoing buffer */
10060 if (r->in.out_data_size) {
10061 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10062 if (out_data.data == NULL) {
10067 switch ( Printer->printer_type ) {
10068 case SPLHND_PORTMON_TCP:
10069 werror = process_xcvtcp_command(p->mem_ctx,
10070 p->server_info->ptok,
10071 r->in.function_name,
10072 &r->in.in_data, &out_data,
10075 case SPLHND_PORTMON_LOCAL:
10076 werror = process_xcvlocal_command(p->mem_ctx,
10077 p->server_info->ptok,
10078 r->in.function_name,
10079 &r->in.in_data, &out_data,
10083 werror = WERR_INVALID_PRINT_MONITOR;
10086 if (!W_ERROR_IS_OK(werror)) {
10090 *r->out.status_code = 0;
10092 memcpy(r->out.out_data, out_data.data, out_data.length);
10097 /****************************************************************
10098 _spoolss_AddPrintProcessor
10099 ****************************************************************/
10101 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10102 struct spoolss_AddPrintProcessor *r)
10104 /* for now, just indicate success and ignore the add. We'll
10105 automatically set the winprint processor for printer
10106 entries later. Used to debug the LexMark Optra S 1855 PCL
10112 /****************************************************************
10113 _spoolss_EnumPrinters
10114 ****************************************************************/
10116 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10117 struct spoolss_EnumPrinters *r)
10119 p->rng_fault_state = true;
10120 return WERR_NOT_SUPPORTED;
10123 /****************************************************************
10125 ****************************************************************/
10127 WERROR _spoolss_GetJob(pipes_struct *p,
10128 struct spoolss_GetJob *r)
10130 p->rng_fault_state = true;
10131 return WERR_NOT_SUPPORTED;
10134 /****************************************************************
10136 ****************************************************************/
10138 WERROR _spoolss_EnumJobs(pipes_struct *p,
10139 struct spoolss_EnumJobs *r)
10141 p->rng_fault_state = true;
10142 return WERR_NOT_SUPPORTED;
10145 /****************************************************************
10146 _spoolss_AddPrinter
10147 ****************************************************************/
10149 WERROR _spoolss_AddPrinter(pipes_struct *p,
10150 struct spoolss_AddPrinter *r)
10152 p->rng_fault_state = true;
10153 return WERR_NOT_SUPPORTED;
10156 /****************************************************************
10157 _spoolss_GetPrinter
10158 ****************************************************************/
10160 WERROR _spoolss_GetPrinter(pipes_struct *p,
10161 struct spoolss_GetPrinter *r)
10163 p->rng_fault_state = true;
10164 return WERR_NOT_SUPPORTED;
10167 /****************************************************************
10168 _spoolss_EnumPrinterDrivers
10169 ****************************************************************/
10171 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10172 struct spoolss_EnumPrinterDrivers *r)
10174 p->rng_fault_state = true;
10175 return WERR_NOT_SUPPORTED;
10178 /****************************************************************
10179 _spoolss_GetPrinterDriver
10180 ****************************************************************/
10182 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10183 struct spoolss_GetPrinterDriver *r)
10185 p->rng_fault_state = true;
10186 return WERR_NOT_SUPPORTED;
10189 /****************************************************************
10190 _spoolss_EnumPrintProcessors
10191 ****************************************************************/
10193 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10194 struct spoolss_EnumPrintProcessors *r)
10196 p->rng_fault_state = true;
10197 return WERR_NOT_SUPPORTED;
10200 /****************************************************************
10201 _spoolss_ReadPrinter
10202 ****************************************************************/
10204 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10205 struct spoolss_ReadPrinter *r)
10207 p->rng_fault_state = true;
10208 return WERR_NOT_SUPPORTED;
10211 /****************************************************************
10212 _spoolss_GetPrinterData
10213 ****************************************************************/
10215 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10216 struct spoolss_GetPrinterData *r)
10218 p->rng_fault_state = true;
10219 return WERR_NOT_SUPPORTED;
10222 /****************************************************************
10223 _spoolss_SetPrinterData
10224 ****************************************************************/
10226 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10227 struct spoolss_SetPrinterData *r)
10229 p->rng_fault_state = true;
10230 return WERR_NOT_SUPPORTED;
10233 /****************************************************************
10234 _spoolss_WaitForPrinterChange
10235 ****************************************************************/
10237 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10238 struct spoolss_WaitForPrinterChange *r)
10240 p->rng_fault_state = true;
10241 return WERR_NOT_SUPPORTED;
10244 /****************************************************************
10246 ****************************************************************/
10248 WERROR _spoolss_EnumForms(pipes_struct *p,
10249 struct spoolss_EnumForms *r)
10251 p->rng_fault_state = true;
10252 return WERR_NOT_SUPPORTED;
10255 /****************************************************************
10257 ****************************************************************/
10259 WERROR _spoolss_EnumPorts(pipes_struct *p,
10260 struct spoolss_EnumPorts *r)
10262 p->rng_fault_state = true;
10263 return WERR_NOT_SUPPORTED;
10266 /****************************************************************
10267 _spoolss_EnumMonitors
10268 ****************************************************************/
10270 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10271 struct spoolss_EnumMonitors *r)
10273 p->rng_fault_state = true;
10274 return WERR_NOT_SUPPORTED;
10277 /****************************************************************
10279 ****************************************************************/
10281 WERROR _spoolss_AddPort(pipes_struct *p,
10282 struct spoolss_AddPort *r)
10284 p->rng_fault_state = true;
10285 return WERR_NOT_SUPPORTED;
10288 /****************************************************************
10289 _spoolss_ConfigurePort
10290 ****************************************************************/
10292 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10293 struct spoolss_ConfigurePort *r)
10295 p->rng_fault_state = true;
10296 return WERR_NOT_SUPPORTED;
10299 /****************************************************************
10300 _spoolss_DeletePort
10301 ****************************************************************/
10303 WERROR _spoolss_DeletePort(pipes_struct *p,
10304 struct spoolss_DeletePort *r)
10306 p->rng_fault_state = true;
10307 return WERR_NOT_SUPPORTED;
10310 /****************************************************************
10311 _spoolss_CreatePrinterIC
10312 ****************************************************************/
10314 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10315 struct spoolss_CreatePrinterIC *r)
10317 p->rng_fault_state = true;
10318 return WERR_NOT_SUPPORTED;
10321 /****************************************************************
10322 _spoolss_PlayGDIScriptOnPrinterIC
10323 ****************************************************************/
10325 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10326 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10328 p->rng_fault_state = true;
10329 return WERR_NOT_SUPPORTED;
10332 /****************************************************************
10333 _spoolss_DeletePrinterIC
10334 ****************************************************************/
10336 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10337 struct spoolss_DeletePrinterIC *r)
10339 p->rng_fault_state = true;
10340 return WERR_NOT_SUPPORTED;
10343 /****************************************************************
10344 _spoolss_AddPrinterConnection
10345 ****************************************************************/
10347 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10348 struct spoolss_AddPrinterConnection *r)
10350 p->rng_fault_state = true;
10351 return WERR_NOT_SUPPORTED;
10354 /****************************************************************
10355 _spoolss_DeletePrinterConnection
10356 ****************************************************************/
10358 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10359 struct spoolss_DeletePrinterConnection *r)
10361 p->rng_fault_state = true;
10362 return WERR_NOT_SUPPORTED;
10365 /****************************************************************
10366 _spoolss_PrinterMessageBox
10367 ****************************************************************/
10369 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10370 struct spoolss_PrinterMessageBox *r)
10372 p->rng_fault_state = true;
10373 return WERR_NOT_SUPPORTED;
10376 /****************************************************************
10377 _spoolss_AddMonitor
10378 ****************************************************************/
10380 WERROR _spoolss_AddMonitor(pipes_struct *p,
10381 struct spoolss_AddMonitor *r)
10383 p->rng_fault_state = true;
10384 return WERR_NOT_SUPPORTED;
10387 /****************************************************************
10388 _spoolss_DeleteMonitor
10389 ****************************************************************/
10391 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10392 struct spoolss_DeleteMonitor *r)
10394 p->rng_fault_state = true;
10395 return WERR_NOT_SUPPORTED;
10398 /****************************************************************
10399 _spoolss_DeletePrintProcessor
10400 ****************************************************************/
10402 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10403 struct spoolss_DeletePrintProcessor *r)
10405 p->rng_fault_state = true;
10406 return WERR_NOT_SUPPORTED;
10409 /****************************************************************
10410 _spoolss_AddPrintProvidor
10411 ****************************************************************/
10413 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10414 struct spoolss_AddPrintProvidor *r)
10416 p->rng_fault_state = true;
10417 return WERR_NOT_SUPPORTED;
10420 /****************************************************************
10421 _spoolss_DeletePrintProvidor
10422 ****************************************************************/
10424 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10425 struct spoolss_DeletePrintProvidor *r)
10427 p->rng_fault_state = true;
10428 return WERR_NOT_SUPPORTED;
10431 /****************************************************************
10432 _spoolss_EnumPrintProcDataTypes
10433 ****************************************************************/
10435 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10436 struct spoolss_EnumPrintProcDataTypes *r)
10438 p->rng_fault_state = true;
10439 return WERR_NOT_SUPPORTED;
10442 /****************************************************************
10443 _spoolss_GetPrinterDriver2
10444 ****************************************************************/
10446 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10447 struct spoolss_GetPrinterDriver2 *r)
10449 p->rng_fault_state = true;
10450 return WERR_NOT_SUPPORTED;
10453 /****************************************************************
10454 _spoolss_FindFirstPrinterChangeNotification
10455 ****************************************************************/
10457 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10458 struct spoolss_FindFirstPrinterChangeNotification *r)
10460 p->rng_fault_state = true;
10461 return WERR_NOT_SUPPORTED;
10464 /****************************************************************
10465 _spoolss_FindNextPrinterChangeNotification
10466 ****************************************************************/
10468 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10469 struct spoolss_FindNextPrinterChangeNotification *r)
10471 p->rng_fault_state = true;
10472 return WERR_NOT_SUPPORTED;
10475 /****************************************************************
10476 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10477 ****************************************************************/
10479 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10480 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10482 p->rng_fault_state = true;
10483 return WERR_NOT_SUPPORTED;
10486 /****************************************************************
10487 _spoolss_ReplyOpenPrinter
10488 ****************************************************************/
10490 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10491 struct spoolss_ReplyOpenPrinter *r)
10493 p->rng_fault_state = true;
10494 return WERR_NOT_SUPPORTED;
10497 /****************************************************************
10498 _spoolss_RouterReplyPrinter
10499 ****************************************************************/
10501 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10502 struct spoolss_RouterReplyPrinter *r)
10504 p->rng_fault_state = true;
10505 return WERR_NOT_SUPPORTED;
10508 /****************************************************************
10509 _spoolss_ReplyClosePrinter
10510 ****************************************************************/
10512 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10513 struct spoolss_ReplyClosePrinter *r)
10515 p->rng_fault_state = true;
10516 return WERR_NOT_SUPPORTED;
10519 /****************************************************************
10521 ****************************************************************/
10523 WERROR _spoolss_AddPortEx(pipes_struct *p,
10524 struct spoolss_AddPortEx *r)
10526 p->rng_fault_state = true;
10527 return WERR_NOT_SUPPORTED;
10530 /****************************************************************
10531 _spoolss_RouterFindFirstPrinterChangeNotification
10532 ****************************************************************/
10534 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10535 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10537 p->rng_fault_state = true;
10538 return WERR_NOT_SUPPORTED;
10541 /****************************************************************
10542 _spoolss_SpoolerInit
10543 ****************************************************************/
10545 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10546 struct spoolss_SpoolerInit *r)
10548 p->rng_fault_state = true;
10549 return WERR_NOT_SUPPORTED;
10552 /****************************************************************
10553 _spoolss_ResetPrinterEx
10554 ****************************************************************/
10556 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10557 struct spoolss_ResetPrinterEx *r)
10559 p->rng_fault_state = true;
10560 return WERR_NOT_SUPPORTED;
10563 /****************************************************************
10564 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10565 ****************************************************************/
10567 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10568 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10570 p->rng_fault_state = true;
10571 return WERR_NOT_SUPPORTED;
10574 /****************************************************************
10575 _spoolss_RouterReplyPrinterEx
10576 ****************************************************************/
10578 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10579 struct spoolss_RouterReplyPrinterEx *r)
10581 p->rng_fault_state = true;
10582 return WERR_NOT_SUPPORTED;
10585 /****************************************************************
10586 _dcesrv_spoolss_RouterRefreshPrinterChangeNotify
10587 ****************************************************************/
10589 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
10590 struct spoolss_RouterRefreshPrinterChangeNotify *r)
10592 p->rng_fault_state = true;
10593 return WERR_NOT_SUPPORTED;
10596 /****************************************************************
10598 ****************************************************************/
10600 WERROR _spoolss_44(pipes_struct *p,
10601 struct spoolss_44 *r)
10603 p->rng_fault_state = true;
10604 return WERR_NOT_SUPPORTED;
10607 /****************************************************************
10609 ****************************************************************/
10611 WERROR _spoolss_47(pipes_struct *p,
10612 struct spoolss_47 *r)
10614 p->rng_fault_state = true;
10615 return WERR_NOT_SUPPORTED;
10618 /****************************************************************
10619 _spoolss_EnumPrinterData
10620 ****************************************************************/
10622 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10623 struct spoolss_EnumPrinterData *r)
10625 p->rng_fault_state = true;
10626 return WERR_NOT_SUPPORTED;
10629 /****************************************************************
10631 ****************************************************************/
10633 WERROR _spoolss_4a(pipes_struct *p,
10634 struct spoolss_4a *r)
10636 p->rng_fault_state = true;
10637 return WERR_NOT_SUPPORTED;
10640 /****************************************************************
10642 ****************************************************************/
10644 WERROR _spoolss_4b(pipes_struct *p,
10645 struct spoolss_4b *r)
10647 p->rng_fault_state = true;
10648 return WERR_NOT_SUPPORTED;
10651 /****************************************************************
10653 ****************************************************************/
10655 WERROR _spoolss_4c(pipes_struct *p,
10656 struct spoolss_4c *r)
10658 p->rng_fault_state = true;
10659 return WERR_NOT_SUPPORTED;
10662 /****************************************************************
10663 _spoolss_EnumPrinterDataEx
10664 ****************************************************************/
10666 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10667 struct spoolss_EnumPrinterDataEx *r)
10669 p->rng_fault_state = true;
10670 return WERR_NOT_SUPPORTED;
10673 /****************************************************************
10674 _spoolss_EnumPrinterKey
10675 ****************************************************************/
10677 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10678 struct spoolss_EnumPrinterKey *r)
10680 p->rng_fault_state = true;
10681 return WERR_NOT_SUPPORTED;
10684 /****************************************************************
10686 ****************************************************************/
10688 WERROR _spoolss_53(pipes_struct *p,
10689 struct spoolss_53 *r)
10691 p->rng_fault_state = true;
10692 return WERR_NOT_SUPPORTED;
10695 /****************************************************************
10697 ****************************************************************/
10699 WERROR _spoolss_55(pipes_struct *p,
10700 struct spoolss_55 *r)
10702 p->rng_fault_state = true;
10703 return WERR_NOT_SUPPORTED;
10706 /****************************************************************
10708 ****************************************************************/
10710 WERROR _spoolss_56(pipes_struct *p,
10711 struct spoolss_56 *r)
10713 p->rng_fault_state = true;
10714 return WERR_NOT_SUPPORTED;
10717 /****************************************************************
10719 ****************************************************************/
10721 WERROR _spoolss_57(pipes_struct *p,
10722 struct spoolss_57 *r)
10724 p->rng_fault_state = true;
10725 return WERR_NOT_SUPPORTED;
10728 /****************************************************************
10730 ****************************************************************/
10732 WERROR _spoolss_5a(pipes_struct *p,
10733 struct spoolss_5a *r)
10735 p->rng_fault_state = true;
10736 return WERR_NOT_SUPPORTED;
10739 /****************************************************************
10741 ****************************************************************/
10743 WERROR _spoolss_5b(pipes_struct *p,
10744 struct spoolss_5b *r)
10746 p->rng_fault_state = true;
10747 return WERR_NOT_SUPPORTED;
10750 /****************************************************************
10752 ****************************************************************/
10754 WERROR _spoolss_5c(pipes_struct *p,
10755 struct spoolss_5c *r)
10757 p->rng_fault_state = true;
10758 return WERR_NOT_SUPPORTED;
10761 /****************************************************************
10763 ****************************************************************/
10765 WERROR _spoolss_5d(pipes_struct *p,
10766 struct spoolss_5d *r)
10768 p->rng_fault_state = true;
10769 return WERR_NOT_SUPPORTED;
10772 /****************************************************************
10774 ****************************************************************/
10776 WERROR _spoolss_5e(pipes_struct *p,
10777 struct spoolss_5e *r)
10779 p->rng_fault_state = true;
10780 return WERR_NOT_SUPPORTED;
10783 /****************************************************************
10785 ****************************************************************/
10787 WERROR _spoolss_5f(pipes_struct *p,
10788 struct spoolss_5f *r)
10790 p->rng_fault_state = true;
10791 return WERR_NOT_SUPPORTED;