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
3389 enum spoolss_NotifyType type;
3390 enum spoolss_Field field;
3392 enum spoolss_NotifyTable variable_type;
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_TABLE_STRING, spoolss_notify_server_name },
3405 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3406 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_share_name },
3407 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3408 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3409 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_TABLE_STRING, spoolss_notify_comment },
3410 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_TABLE_STRING, spoolss_notify_location },
3411 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3412 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_TABLE_STRING, spoolss_notify_sepfile },
3413 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3414 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3415 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3416 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, spoolss_notify_security_desc },
3417 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_TABLE_DWORD, spoolss_notify_attributes },
3418 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3419 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_default_priority },
3420 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3421 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3422 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_status },
3423 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, NULL },
3424 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_TABLE_DWORD, spoolss_notify_cjobs },
3425 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_TABLE_DWORD, spoolss_notify_average_ppm },
3426 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, NULL },
3427 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3428 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, NULL },
3429 { PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_TABLE_DWORD, NULL },
3430 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_printer_name },
3431 { JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_TABLE_STRING, spoolss_notify_server_name },
3432 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_TABLE_STRING, spoolss_notify_port_name },
3433 { JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3434 { JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_TABLE_STRING, spoolss_notify_username },
3435 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_TABLE_STRING, spoolss_notify_datatype },
3436 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_TABLE_STRING, spoolss_notify_print_processor },
3437 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_TABLE_STRING, spoolss_notify_parameters },
3438 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_TABLE_STRING, spoolss_notify_driver_name },
3439 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_TABLE_DEVMODE, spoolss_notify_devmode },
3440 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_TABLE_DWORD, spoolss_notify_job_status },
3441 { JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_TABLE_STRING, spoolss_notify_job_status_string },
3442 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_TABLE_SECURITYDESCRIPTOR, NULL },
3443 { JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_TABLE_STRING, spoolss_notify_job_name },
3444 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_TABLE_DWORD, spoolss_notify_priority },
3445 { JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_TABLE_DWORD, spoolss_notify_job_position },
3446 { JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_TABLE_TIME, spoolss_notify_submitted_time },
3447 { JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_start_time },
3448 { JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_until_time },
3449 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_TABLE_DWORD, spoolss_notify_job_time },
3450 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_TABLE_DWORD, spoolss_notify_total_pages },
3451 { JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_TABLE_DWORD, spoolss_notify_pages_printed },
3452 { JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_TABLE_DWORD, spoolss_notify_job_size },
3453 { PRINT_TABLE_END, 0x0, NULL, 0x0, NULL },
3456 /*******************************************************************
3457 Return the variable_type of info_data structure.
3458 ********************************************************************/
3460 static uint32_t variable_type_of_notify_info_data(enum spoolss_NotifyType type,
3461 enum spoolss_Field field)
3465 for (i = 0; i < ARRAY_SIZE(notify_info_data_table); i++) {
3466 if ( (notify_info_data_table[i].type == type) &&
3467 (notify_info_data_table[i].field == field) ) {
3468 return notify_info_data_table[i].variable_type;
3472 DEBUG(5, ("invalid notify data type %d/%d\n", type, field));
3477 /****************************************************************************
3478 ****************************************************************************/
3480 static bool search_notify(uint16 type, uint16 field, int *value)
3484 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) {
3485 if (notify_info_data_table[i].type == type &&
3486 notify_info_data_table[i].field == field &&
3487 notify_info_data_table[i].fn != NULL) {
3496 /****************************************************************************
3497 ****************************************************************************/
3499 void construct_info_data(struct spoolss_Notify *info_data, uint16 type, uint16 field, int id)
3501 info_data->type = type;
3502 info_data->field = field;
3503 info_data->variable_type = variable_type_of_notify_info_data(type, field);
3504 info_data->job_id = id;
3507 /*******************************************************************
3509 * fill a notify_info struct with info asked
3511 ********************************************************************/
3513 static bool construct_notify_printer_info(Printer_entry *print_hnd, struct spoolss_NotifyInfo *info, int
3514 snum, SPOOL_NOTIFY_OPTION_TYPE
3515 *option_type, uint32 id,
3516 TALLOC_CTX *mem_ctx)
3522 struct spoolss_Notify *current_data;
3523 NT_PRINTER_INFO_LEVEL *printer = NULL;
3524 print_queue_struct *queue=NULL;
3526 type=option_type->type;
3528 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n",
3529 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3530 option_type->count, lp_servicename(snum)));
3532 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum))))
3535 for(field_num=0; field_num<option_type->count; field_num++) {
3536 field = option_type->fields[field_num];
3538 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field));
3540 if (!search_notify(type, field, &j) )
3543 if((info->notifies = SMB_REALLOC_ARRAY(info->notifies, struct spoolss_Notify, info->count+1)) == NULL) {
3544 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n"));
3545 free_a_printer(&printer, 2);
3549 current_data = &info->notifies[info->count];
3551 construct_info_data(current_data, type, field, id);
3553 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n",
3554 notify_info_data_table[j].name, snum, printer->info_2->printername ));
3556 notify_info_data_table[j].fn(snum, current_data, queue,
3562 free_a_printer(&printer, 2);
3566 /*******************************************************************
3568 * fill a notify_info struct with info asked
3570 ********************************************************************/
3572 static bool construct_notify_jobs_info(print_queue_struct *queue,
3573 struct spoolss_NotifyInfo *info,
3574 NT_PRINTER_INFO_LEVEL *printer,
3575 int snum, SPOOL_NOTIFY_OPTION_TYPE
3576 *option_type, uint32 id,
3577 TALLOC_CTX *mem_ctx)
3583 struct spoolss_Notify *current_data;
3585 DEBUG(4,("construct_notify_jobs_info\n"));
3587 type = option_type->type;
3589 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n",
3590 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"),
3591 option_type->count));
3593 for(field_num=0; field_num<option_type->count; field_num++) {
3594 field = option_type->fields[field_num];
3596 if (!search_notify(type, field, &j) )
3599 if((info->notifies = SMB_REALLOC_ARRAY(info->notifies, struct spoolss_Notify, info->count+1)) == NULL) {
3600 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n"));
3604 current_data=&(info->notifies[info->count]);
3606 construct_info_data(current_data, type, field, id);
3607 notify_info_data_table[j].fn(snum, current_data, queue,
3616 * JFM: The enumeration is not that simple, it's even non obvious.
3618 * let's take an example: I want to monitor the PRINTER SERVER for
3619 * the printer's name and the number of jobs currently queued.
3620 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure.
3621 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS.
3623 * I have 3 printers on the back of my server.
3625 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA
3628 * 1 printer 1 name 1
3629 * 2 printer 1 cjob 1
3630 * 3 printer 2 name 2
3631 * 4 printer 2 cjob 2
3632 * 5 printer 3 name 3
3633 * 6 printer 3 name 3
3635 * that's the print server case, the printer case is even worse.
3638 /*******************************************************************
3640 * enumerate all printers on the printserver
3641 * fill a notify_info struct with info asked
3643 ********************************************************************/
3645 static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd,
3646 struct spoolss_NotifyInfo *info,
3647 TALLOC_CTX *mem_ctx)
3650 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3651 int n_services=lp_numservices();
3653 SPOOL_NOTIFY_OPTION *option;
3654 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3656 DEBUG(4,("printserver_notify_info\n"));
3661 option=Printer->notify.option;
3664 info->notifies = NULL;
3667 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3668 sending a ffpcn() request first */
3673 for (i=0; i<option->count; i++) {
3674 option_type=&(option->ctr.type[i]);
3676 if (option_type->type!=PRINTER_NOTIFY_TYPE)
3679 for (snum=0; snum<n_services; snum++)
3681 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) )
3682 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx );
3688 * Debugging information, don't delete.
3691 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3692 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3693 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3695 for (i=0; i<info->count; i++) {
3696 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3697 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3698 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3705 /*******************************************************************
3707 * fill a notify_info struct with info asked
3709 ********************************************************************/
3711 static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, struct spoolss_NotifyInfo *info,
3712 TALLOC_CTX *mem_ctx)
3715 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd);
3718 SPOOL_NOTIFY_OPTION *option;
3719 SPOOL_NOTIFY_OPTION_TYPE *option_type;
3721 print_queue_struct *queue=NULL;
3722 print_status_struct status;
3724 DEBUG(4,("printer_notify_info\n"));
3729 option=Printer->notify.option;
3733 info->notifies = NULL;
3736 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without
3737 sending a ffpcn() request first */
3742 get_printer_snum(p, hnd, &snum, NULL);
3744 for (i=0; i<option->count; i++) {
3745 option_type=&option->ctr.type[i];
3747 switch ( option_type->type ) {
3748 case PRINTER_NOTIFY_TYPE:
3749 if(construct_notify_printer_info(Printer, info, snum,
3755 case JOB_NOTIFY_TYPE: {
3756 NT_PRINTER_INFO_LEVEL *printer = NULL;
3758 count = print_queue_status(snum, &queue, &status);
3760 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))))
3763 for (j=0; j<count; j++) {
3764 construct_notify_jobs_info(&queue[j], info,
3771 free_a_printer(&printer, 2);
3781 * Debugging information, don't delete.
3784 DEBUG(1,("dumping the NOTIFY_INFO\n"));
3785 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count));
3786 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n"));
3788 for (i=0; i<info->count; i++) {
3789 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n",
3790 i, info->data[i].type, info->data[i].field, info->data[i].reserved,
3791 info->data[i].id, info->data[i].size, info->data[i].enc_type));
3797 /********************************************************************
3799 ********************************************************************/
3801 WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u)
3803 POLICY_HND *handle = &q_u->handle;
3804 SPOOL_NOTIFY_INFO *info = &r_u->info;
3806 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
3807 WERROR result = WERR_BADFID;
3809 /* we always have a NOTIFY_INFO struct */
3813 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n",
3814 OUR_HANDLE(handle)));
3818 DEBUG(4,("Printer type %x\n",Printer->printer_type));
3821 * We are now using the change value, and
3822 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as
3823 * I don't have a global notification system, I'm sending back all the
3824 * informations even when _NOTHING_ has changed.
3827 /* We need to keep track of the change value to send back in
3828 RRPCN replies otherwise our updates are ignored. */
3830 Printer->notify.fnpcn = True;
3832 if (Printer->notify.client_connected) {
3833 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
3834 Printer->notify.change = q_u->change;
3837 /* just ignore the SPOOL_NOTIFY_OPTION */
3839 switch (Printer->printer_type) {
3841 result = printserver_notify_info(p, handle, info, p->mem_ctx);
3844 case SPLHND_PRINTER:
3845 result = printer_notify_info(p, handle, info, p->mem_ctx);
3849 Printer->notify.fnpcn = False;
3855 /********************************************************************
3856 * construct_printer_info_0
3857 * fill a printer_info_0 struct
3858 ********************************************************************/
3860 static bool construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum)
3862 char *chaine = NULL;
3864 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3865 counter_printer_0 *session_counter;
3866 uint32 global_counter;
3869 print_status_struct status;
3870 TALLOC_CTX *ctx = talloc_tos();
3872 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3875 init_unistr(&printer->printername, ntprinter->info_2->printername);
3877 chaine = talloc_asprintf(ctx, "\\\\%s", get_server_name(print_hnd));
3879 free_a_printer(&ntprinter,2);
3883 count = print_queue_length(snum, &status);
3885 /* check if we already have a counter for this printer */
3886 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) {
3887 if (session_counter->snum == snum)
3891 init_unistr(&printer->servername, chaine);
3893 /* it's the first time, add it to the list */
3894 if (session_counter==NULL) {
3895 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) {
3896 free_a_printer(&ntprinter, 2);
3899 ZERO_STRUCTP(session_counter);
3900 session_counter->snum=snum;
3901 session_counter->counter=0;
3902 DLIST_ADD(counter_list, session_counter);
3906 session_counter->counter++;
3909 * the global_counter should be stored in a TDB as it's common to all the clients
3910 * and should be zeroed on samba startup
3912 global_counter=session_counter->counter;
3913 printer->cjobs = count;
3914 printer->total_jobs = 0;
3915 printer->total_bytes = 0;
3917 setuptime = (time_t)ntprinter->info_2->setuptime;
3918 t=gmtime(&setuptime);
3920 printer->year = t->tm_year+1900;
3921 printer->month = t->tm_mon+1;
3922 printer->dayofweek = t->tm_wday;
3923 printer->day = t->tm_mday;
3924 printer->hour = t->tm_hour;
3925 printer->minute = t->tm_min;
3926 printer->second = t->tm_sec;
3927 printer->milliseconds = 0;
3929 printer->global_counter = global_counter;
3930 printer->total_pages = 0;
3932 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */
3933 printer->major_version = 0x0005; /* NT 5 */
3934 printer->build_version = 0x0893; /* build 2195 */
3936 printer->unknown7 = 0x1;
3937 printer->unknown8 = 0x0;
3938 printer->unknown9 = 0x0;
3939 printer->session_counter = session_counter->counter;
3940 printer->unknown11 = 0x0;
3941 printer->printer_errors = 0x0; /* number of print failure */
3942 printer->unknown13 = 0x0;
3943 printer->unknown14 = 0x1;
3944 printer->unknown15 = 0x024a; /* 586 Pentium ? */
3945 printer->unknown16 = 0x0;
3946 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/
3947 printer->unknown18 = 0x0;
3948 printer->status = nt_printq_status(status.status);
3949 printer->unknown20 = 0x0;
3950 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */
3951 printer->unknown22 = 0x0;
3952 printer->unknown23 = 0x6; /* 6 ???*/
3953 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */
3954 printer->unknown25 = 0;
3955 printer->unknown26 = 0;
3956 printer->unknown27 = 0;
3957 printer->unknown28 = 0;
3958 printer->unknown29 = 0;
3960 free_a_printer(&ntprinter,2);
3964 /********************************************************************
3965 * construct_printer_info_1
3966 * fill a printer_info_1 struct
3967 ********************************************************************/
3968 static bool construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum)
3970 char *chaine = NULL;
3971 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
3972 TALLOC_CTX *ctx = talloc_tos();
3974 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
3977 printer->flags=flags;
3979 if (*ntprinter->info_2->comment == '\0') {
3980 init_unistr(&printer->comment, lp_comment(snum));
3981 chaine = talloc_asprintf(ctx,
3982 "%s,%s,%s", ntprinter->info_2->printername,
3983 ntprinter->info_2->drivername, lp_comment(snum));
3986 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
3987 chaine = talloc_asprintf(ctx,
3988 "%s,%s,%s", ntprinter->info_2->printername,
3989 ntprinter->info_2->drivername, ntprinter->info_2->comment);
3993 free_a_printer(&ntprinter,2);
3997 init_unistr(&printer->description, chaine);
3998 init_unistr(&printer->name, ntprinter->info_2->printername);
4000 free_a_printer(&ntprinter,2);
4005 /****************************************************************************
4006 Free a DEVMODE struct.
4007 ****************************************************************************/
4009 static void free_dev_mode(DEVICEMODE *dev)
4014 SAFE_FREE(dev->dev_private);
4019 /****************************************************************************
4020 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers
4021 should be valid upon entry
4022 ****************************************************************************/
4024 static bool convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode )
4026 if ( !devmode || !ntdevmode )
4029 init_unistr(&devmode->devicename, ntdevmode->devicename);
4031 init_unistr(&devmode->formname, ntdevmode->formname);
4033 devmode->specversion = ntdevmode->specversion;
4034 devmode->driverversion = ntdevmode->driverversion;
4035 devmode->size = ntdevmode->size;
4036 devmode->driverextra = ntdevmode->driverextra;
4037 devmode->fields = ntdevmode->fields;
4039 devmode->orientation = ntdevmode->orientation;
4040 devmode->papersize = ntdevmode->papersize;
4041 devmode->paperlength = ntdevmode->paperlength;
4042 devmode->paperwidth = ntdevmode->paperwidth;
4043 devmode->scale = ntdevmode->scale;
4044 devmode->copies = ntdevmode->copies;
4045 devmode->defaultsource = ntdevmode->defaultsource;
4046 devmode->printquality = ntdevmode->printquality;
4047 devmode->color = ntdevmode->color;
4048 devmode->duplex = ntdevmode->duplex;
4049 devmode->yresolution = ntdevmode->yresolution;
4050 devmode->ttoption = ntdevmode->ttoption;
4051 devmode->collate = ntdevmode->collate;
4052 devmode->icmmethod = ntdevmode->icmmethod;
4053 devmode->icmintent = ntdevmode->icmintent;
4054 devmode->mediatype = ntdevmode->mediatype;
4055 devmode->dithertype = ntdevmode->dithertype;
4057 if (ntdevmode->nt_dev_private != NULL) {
4058 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL)
4065 /****************************************************************************
4066 Create a DEVMODE struct. Returns malloced memory.
4067 ****************************************************************************/
4069 DEVICEMODE *construct_dev_mode(const char *servicename)
4071 NT_PRINTER_INFO_LEVEL *printer = NULL;
4072 DEVICEMODE *devmode = NULL;
4074 DEBUG(7,("construct_dev_mode\n"));
4076 DEBUGADD(8,("getting printer characteristics\n"));
4078 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
4081 if ( !printer->info_2->devmode ) {
4082 DEBUG(5, ("BONG! There was no device mode!\n"));
4086 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) {
4087 DEBUG(2,("construct_dev_mode: malloc fail.\n"));
4091 ZERO_STRUCTP(devmode);
4093 DEBUGADD(8,("loading DEVICEMODE\n"));
4095 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) {
4096 free_dev_mode( devmode );
4101 free_a_printer(&printer,2);
4106 /********************************************************************
4107 * construct_printer_info_2
4108 * fill a printer_info_2 struct
4109 ********************************************************************/
4111 static bool construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum)
4114 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4116 print_status_struct status;
4118 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4121 count = print_queue_length(snum, &status);
4123 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4124 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4125 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */
4126 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */
4127 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */
4129 if (*ntprinter->info_2->comment == '\0')
4130 init_unistr(&printer->comment, lp_comment(snum)); /* comment */
4132 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */
4134 init_unistr(&printer->location, ntprinter->info_2->location); /* location */
4135 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */
4136 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */
4137 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */
4138 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */
4140 printer->attributes = ntprinter->info_2->attributes;
4142 printer->priority = ntprinter->info_2->priority; /* priority */
4143 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */
4144 printer->starttime = ntprinter->info_2->starttime; /* starttime */
4145 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */
4146 printer->status = nt_printq_status(status.status); /* status */
4147 printer->cjobs = count; /* jobs */
4148 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */
4150 if ( !(printer->devmode = construct_dev_mode(
4151 lp_const_servicename(snum))) )
4152 DEBUG(8, ("Returning NULL Devicemode!\n"));
4154 printer->secdesc = NULL;
4156 if ( ntprinter->info_2->secdesc_buf
4157 && ntprinter->info_2->secdesc_buf->sd_size != 0 )
4159 /* don't use talloc_steal() here unless you do a deep steal of all
4160 the SEC_DESC members */
4162 printer->secdesc = dup_sec_desc( talloc_tos(),
4163 ntprinter->info_2->secdesc_buf->sd );
4166 free_a_printer(&ntprinter, 2);
4171 /********************************************************************
4172 * construct_printer_info_3
4173 * fill a printer_info_3 struct
4174 ********************************************************************/
4176 static bool construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum)
4178 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4179 PRINTER_INFO_3 *printer = NULL;
4181 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4185 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) {
4186 DEBUG(2,("construct_printer_info_3: malloc fail.\n"));
4187 free_a_printer(&ntprinter, 2);
4191 ZERO_STRUCTP(printer);
4193 /* These are the components of the SD we are returning. */
4195 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->sd_size != 0) {
4196 /* don't use talloc_steal() here unless you do a deep steal of all
4197 the SEC_DESC members */
4199 printer->secdesc = dup_sec_desc( talloc_tos(),
4200 ntprinter->info_2->secdesc_buf->sd );
4203 free_a_printer(&ntprinter, 2);
4205 *pp_printer = printer;
4209 /********************************************************************
4210 * construct_printer_info_4
4211 * fill a printer_info_4 struct
4212 ********************************************************************/
4214 static bool construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum)
4216 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4218 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4221 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/
4222 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/
4223 printer->attributes = ntprinter->info_2->attributes;
4225 free_a_printer(&ntprinter, 2);
4229 /********************************************************************
4230 * construct_printer_info_5
4231 * fill a printer_info_5 struct
4232 ********************************************************************/
4234 static bool construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum)
4236 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4238 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum))))
4241 init_unistr(&printer->printername, ntprinter->info_2->printername);
4242 init_unistr(&printer->portname, ntprinter->info_2->portname);
4243 printer->attributes = ntprinter->info_2->attributes;
4245 /* these two are not used by NT+ according to MSDN */
4247 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */
4248 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */
4250 free_a_printer(&ntprinter, 2);
4255 /********************************************************************
4256 * construct_printer_info_6
4257 * fill a printer_info_6 struct
4258 ********************************************************************/
4260 static bool construct_printer_info_6(Printer_entry *print_hnd,
4261 PRINTER_INFO_6 *printer,
4264 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
4266 print_status_struct status;
4268 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2,
4269 lp_const_servicename(snum))))
4272 count = print_queue_length(snum, &status);
4274 printer->status = nt_printq_status(status.status);
4276 free_a_printer(&ntprinter, 2);
4281 /********************************************************************
4282 * construct_printer_info_7
4283 * fill a printer_info_7 struct
4284 ********************************************************************/
4286 static bool construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum)
4288 char *guid_str = NULL;
4291 if (is_printer_published(print_hnd, snum, &guid)) {
4292 if (asprintf(&guid_str, "{%s}",
4293 GUID_string(talloc_tos(), &guid)) == -1) {
4296 strupper_m(guid_str);
4297 init_unistr(&printer->guid, guid_str);
4298 SAFE_FREE(guid_str);
4299 printer->action = SPOOL_DS_PUBLISH;
4301 init_unistr(&printer->guid, "");
4302 printer->action = SPOOL_DS_UNPUBLISH;
4308 /********************************************************************
4309 Spoolss_enumprinters.
4310 ********************************************************************/
4312 static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4316 int n_services=lp_numservices();
4317 PRINTER_INFO_1 *printers=NULL;
4318 PRINTER_INFO_1 current_prt;
4319 WERROR result = WERR_OK;
4321 DEBUG(4,("enum_all_printers_info_1\n"));
4323 for (snum=0; snum<n_services; snum++) {
4324 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4325 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4327 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) {
4328 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) {
4329 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n"));
4333 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned));
4335 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1));
4341 /* check the required size. */
4342 for (i=0; i<*returned; i++)
4343 (*needed) += spoolss_size_printer_info_1(&printers[i]);
4345 if (*needed > offered) {
4346 result = WERR_INSUFFICIENT_BUFFER;
4350 if (!rpcbuf_alloc_size(buffer, *needed)) {
4351 result = WERR_NOMEM;
4355 /* fill the buffer with the structures */
4356 for (i=0; i<*returned; i++)
4357 smb_io_printer_info_1("", buffer, &printers[i], 0);
4362 SAFE_FREE(printers);
4364 if ( !W_ERROR_IS_OK(result) )
4370 /********************************************************************
4371 enum_all_printers_info_1_local.
4372 *********************************************************************/
4374 static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4376 DEBUG(4,("enum_all_printers_info_1_local\n"));
4378 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4381 /********************************************************************
4382 enum_all_printers_info_1_name.
4383 *********************************************************************/
4385 static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4389 DEBUG(4,("enum_all_printers_info_1_name\n"));
4391 if ((name[0] == '\\') && (name[1] == '\\'))
4394 if (is_myname_or_ipaddr(s)) {
4395 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned);
4398 return WERR_INVALID_NAME;
4401 #if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */
4402 /********************************************************************
4403 enum_all_printers_info_1_remote.
4404 *********************************************************************/
4406 static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4408 PRINTER_INFO_1 *printer;
4409 fstring printername;
4412 DEBUG(4,("enum_all_printers_info_1_remote\n"));
4413 WERROR result = WERR_OK;
4415 /* JFM: currently it's more a place holder than anything else.
4416 * In the spooler world there is a notion of server registration.
4417 * the print servers are registered on the PDC (in the same domain)
4419 * We should have a TDB here. The registration is done thru an
4420 * undocumented RPC call.
4423 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4428 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name);
4429 slprintf(desc, sizeof(desc)-1,"%s", name);
4430 slprintf(comment, sizeof(comment)-1, "Logged on Domain");
4432 init_unistr(&printer->description, desc);
4433 init_unistr(&printer->name, printername);
4434 init_unistr(&printer->comment, comment);
4435 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER;
4437 /* check the required size. */
4438 *needed += spoolss_size_printer_info_1(printer);
4440 if (*needed > offered) {
4441 result = WERR_INSUFFICIENT_BUFFER;
4445 if (!rpcbuf_alloc_size(buffer, *needed)) {
4446 result = WERR_NOMEM;
4450 /* fill the buffer with the structures */
4451 smb_io_printer_info_1("", buffer, printer, 0);
4457 if ( !W_ERROR_IS_OK(result) )
4465 /********************************************************************
4466 enum_all_printers_info_1_network.
4467 *********************************************************************/
4469 static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4473 DEBUG(4,("enum_all_printers_info_1_network\n"));
4475 /* If we respond to a enum_printers level 1 on our name with flags
4476 set to PRINTER_ENUM_REMOTE with a list of printers then these
4477 printers incorrectly appear in the APW browse list.
4478 Specifically the printers for the server appear at the workgroup
4479 level where all the other servers in the domain are
4480 listed. Windows responds to this call with a
4481 WERR_CAN_NOT_COMPLETE so we should do the same. */
4483 if (name[0] == '\\' && name[1] == '\\')
4486 if (is_myname_or_ipaddr(s))
4487 return WERR_CAN_NOT_COMPLETE;
4489 return enum_all_printers_info_1(PRINTER_ENUM_NAME, buffer, offered, needed, returned);
4492 /********************************************************************
4493 * api_spoolss_enumprinters
4495 * called from api_spoolss_enumprinters (see this to understand)
4496 ********************************************************************/
4498 static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
4502 int n_services=lp_numservices();
4503 PRINTER_INFO_2 *printers=NULL;
4504 PRINTER_INFO_2 current_prt;
4505 WERROR result = WERR_OK;
4509 for (snum=0; snum<n_services; snum++) {
4510 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) {
4511 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum));
4513 if (construct_printer_info_2(NULL, ¤t_prt, snum)) {
4514 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) {
4515 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n"));
4520 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1));
4522 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2));
4529 /* check the required size. */
4530 for (i=0; i<*returned; i++)
4531 (*needed) += spoolss_size_printer_info_2(&printers[i]);
4533 if (*needed > offered) {
4534 result = WERR_INSUFFICIENT_BUFFER;
4538 if (!rpcbuf_alloc_size(buffer, *needed)) {
4539 result = WERR_NOMEM;
4543 /* fill the buffer with the structures */
4544 for (i=0; i<*returned; i++)
4545 smb_io_printer_info_2("", buffer, &(printers[i]), 0);
4550 for (i=0; i<*returned; i++)
4551 free_devmode(printers[i].devmode);
4553 SAFE_FREE(printers);
4555 if ( !W_ERROR_IS_OK(result) )
4561 /********************************************************************
4562 * handle enumeration of printers at level 1
4563 ********************************************************************/
4565 static WERROR enumprinters_level1( uint32 flags, fstring name,
4566 RPC_BUFFER *buffer, uint32 offered,
4567 uint32 *needed, uint32 *returned)
4569 /* Not all the flags are equals */
4571 if (flags & PRINTER_ENUM_LOCAL)
4572 return enum_all_printers_info_1_local(buffer, offered, needed, returned);
4574 if (flags & PRINTER_ENUM_NAME)
4575 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned);
4577 #if 0 /* JERRY - disabled for now */
4578 if (flags & PRINTER_ENUM_REMOTE)
4579 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned);
4582 if (flags & PRINTER_ENUM_NETWORK)
4583 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned);
4585 return WERR_OK; /* NT4sp5 does that */
4588 /********************************************************************
4589 * handle enumeration of printers at level 2
4590 ********************************************************************/
4592 static WERROR enumprinters_level2( uint32 flags, const char *servername,
4593 RPC_BUFFER *buffer, uint32 offered,
4594 uint32 *needed, uint32 *returned)
4596 if (flags & PRINTER_ENUM_LOCAL) {
4597 return enum_all_printers_info_2(buffer, offered, needed, returned);
4600 if (flags & PRINTER_ENUM_NAME) {
4601 if (is_myname_or_ipaddr(canon_servername(servername)))
4602 return enum_all_printers_info_2(buffer, offered, needed, returned);
4604 return WERR_INVALID_NAME;
4607 if (flags & PRINTER_ENUM_REMOTE)
4608 return WERR_UNKNOWN_LEVEL;
4613 /********************************************************************
4614 * handle enumeration of printers at level 5
4615 ********************************************************************/
4617 static WERROR enumprinters_level5( uint32 flags, const char *servername,
4618 RPC_BUFFER *buffer, uint32 offered,
4619 uint32 *needed, uint32 *returned)
4621 /* return enum_all_printers_info_5(buffer, offered, needed, returned);*/
4625 /********************************************************************
4626 * api_spoolss_enumprinters
4628 * called from api_spoolss_enumprinters (see this to understand)
4629 ********************************************************************/
4631 WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u)
4633 uint32 flags = q_u->flags;
4634 UNISTR2 *servername = &q_u->servername;
4635 uint32 level = q_u->level;
4636 RPC_BUFFER *buffer = NULL;
4637 uint32 offered = q_u->offered;
4638 uint32 *needed = &r_u->needed;
4639 uint32 *returned = &r_u->returned;
4643 /* that's an [in out] buffer */
4645 if (!q_u->buffer && (offered!=0)) {
4646 return WERR_INVALID_PARAM;
4649 if (offered > MAX_RPC_DATA_SIZE) {
4650 return WERR_INVALID_PARAM;
4653 rpcbuf_move(q_u->buffer, &r_u->buffer);
4654 buffer = r_u->buffer;
4656 DEBUG(4,("_spoolss_enumprinters\n"));
4663 * flags==PRINTER_ENUM_NAME
4664 * if name=="" then enumerates all printers
4665 * if name!="" then enumerate the printer
4666 * flags==PRINTER_ENUM_REMOTE
4667 * name is NULL, enumerate printers
4668 * Level 2: name!="" enumerates printers, name can't be NULL
4669 * Level 3: doesn't exist
4670 * Level 4: does a local registry lookup
4671 * Level 5: same as Level 2
4674 unistr2_to_ascii(name, servername, sizeof(name));
4679 return enumprinters_level1(flags, name, buffer, offered, needed, returned);
4681 return enumprinters_level2(flags, name, buffer, offered, needed, returned);
4683 return enumprinters_level5(flags, name, buffer, offered, needed, returned);
4688 return WERR_UNKNOWN_LEVEL;
4691 /****************************************************************************
4692 ****************************************************************************/
4694 static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4696 PRINTER_INFO_0 *printer=NULL;
4697 WERROR result = WERR_OK;
4699 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL)
4702 construct_printer_info_0(print_hnd, printer, snum);
4704 /* check the required size. */
4705 *needed += spoolss_size_printer_info_0(printer);
4707 if (*needed > offered) {
4708 result = WERR_INSUFFICIENT_BUFFER;
4712 if (!rpcbuf_alloc_size(buffer, *needed)) {
4713 result = WERR_NOMEM;
4717 /* fill the buffer with the structures */
4718 smb_io_printer_info_0("", buffer, printer, 0);
4728 /****************************************************************************
4729 ****************************************************************************/
4731 static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4733 PRINTER_INFO_1 *printer=NULL;
4734 WERROR result = WERR_OK;
4736 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL)
4739 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum);
4741 /* check the required size. */
4742 *needed += spoolss_size_printer_info_1(printer);
4744 if (*needed > offered) {
4745 result = WERR_INSUFFICIENT_BUFFER;
4749 if (!rpcbuf_alloc_size(buffer, *needed)) {
4750 result = WERR_NOMEM;
4754 /* fill the buffer with the structures */
4755 smb_io_printer_info_1("", buffer, printer, 0);
4764 /****************************************************************************
4765 ****************************************************************************/
4767 static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4769 PRINTER_INFO_2 *printer=NULL;
4770 WERROR result = WERR_OK;
4772 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL)
4775 construct_printer_info_2(print_hnd, printer, snum);
4777 /* check the required size. */
4778 *needed += spoolss_size_printer_info_2(printer);
4780 if (*needed > offered) {
4781 result = WERR_INSUFFICIENT_BUFFER;
4785 if (!rpcbuf_alloc_size(buffer, *needed)) {
4786 result = WERR_NOMEM;
4790 /* fill the buffer with the structures */
4791 if (!smb_io_printer_info_2("", buffer, printer, 0))
4792 result = WERR_NOMEM;
4796 free_printer_info_2(printer);
4801 /****************************************************************************
4802 ****************************************************************************/
4804 static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4806 PRINTER_INFO_3 *printer=NULL;
4807 WERROR result = WERR_OK;
4809 if (!construct_printer_info_3(print_hnd, &printer, snum))
4812 /* check the required size. */
4813 *needed += spoolss_size_printer_info_3(printer);
4815 if (*needed > offered) {
4816 result = WERR_INSUFFICIENT_BUFFER;
4820 if (!rpcbuf_alloc_size(buffer, *needed)) {
4821 result = WERR_NOMEM;
4825 /* fill the buffer with the structures */
4826 smb_io_printer_info_3("", buffer, printer, 0);
4830 free_printer_info_3(printer);
4835 /****************************************************************************
4836 ****************************************************************************/
4838 static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4840 PRINTER_INFO_4 *printer=NULL;
4841 WERROR result = WERR_OK;
4843 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL)
4846 if (!construct_printer_info_4(print_hnd, printer, snum)) {
4851 /* check the required size. */
4852 *needed += spoolss_size_printer_info_4(printer);
4854 if (*needed > offered) {
4855 result = WERR_INSUFFICIENT_BUFFER;
4859 if (!rpcbuf_alloc_size(buffer, *needed)) {
4860 result = WERR_NOMEM;
4864 /* fill the buffer with the structures */
4865 smb_io_printer_info_4("", buffer, printer, 0);
4869 free_printer_info_4(printer);
4874 /****************************************************************************
4875 ****************************************************************************/
4877 static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4879 PRINTER_INFO_5 *printer=NULL;
4880 WERROR result = WERR_OK;
4882 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL)
4885 if (!construct_printer_info_5(print_hnd, printer, snum)) {
4886 free_printer_info_5(printer);
4890 /* check the required size. */
4891 *needed += spoolss_size_printer_info_5(printer);
4893 if (*needed > offered) {
4894 result = WERR_INSUFFICIENT_BUFFER;
4898 if (!rpcbuf_alloc_size(buffer, *needed)) {
4899 result = WERR_NOMEM;
4903 /* fill the buffer with the structures */
4904 smb_io_printer_info_5("", buffer, printer, 0);
4908 free_printer_info_5(printer);
4913 static WERROR getprinter_level_6(Printer_entry *print_hnd,
4915 RPC_BUFFER *buffer, uint32 offered,
4918 PRINTER_INFO_6 *printer;
4919 WERROR result = WERR_OK;
4921 if ((printer = SMB_MALLOC_P(PRINTER_INFO_6)) == NULL) {
4925 if (!construct_printer_info_6(print_hnd, printer, snum)) {
4926 free_printer_info_6(printer);
4930 /* check the required size. */
4931 *needed += spoolss_size_printer_info_6(printer);
4933 if (*needed > offered) {
4934 result = WERR_INSUFFICIENT_BUFFER;
4938 if (!rpcbuf_alloc_size(buffer, *needed)) {
4939 result = WERR_NOMEM;
4943 /* fill the buffer with the structures */
4944 smb_io_printer_info_6("", buffer, printer, 0);
4948 free_printer_info_6(printer);
4953 static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
4955 PRINTER_INFO_7 *printer=NULL;
4956 WERROR result = WERR_OK;
4958 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL)
4961 if (!construct_printer_info_7(print_hnd, printer, snum)) {
4962 result = WERR_NOMEM;
4966 /* check the required size. */
4967 *needed += spoolss_size_printer_info_7(printer);
4969 if (*needed > offered) {
4970 result = WERR_INSUFFICIENT_BUFFER;
4974 if (!rpcbuf_alloc_size(buffer, *needed)) {
4975 result = WERR_NOMEM;
4980 /* fill the buffer with the structures */
4981 smb_io_printer_info_7("", buffer, printer, 0);
4985 free_printer_info_7(printer);
4990 /****************************************************************************
4991 ****************************************************************************/
4993 WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u)
4995 POLICY_HND *handle = &q_u->handle;
4996 uint32 level = q_u->level;
4997 RPC_BUFFER *buffer = NULL;
4998 uint32 offered = q_u->offered;
4999 uint32 *needed = &r_u->needed;
5000 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
5004 /* that's an [in out] buffer */
5006 if (!q_u->buffer && (offered!=0)) {
5007 return WERR_INVALID_PARAM;
5010 if (offered > MAX_RPC_DATA_SIZE) {
5011 return WERR_INVALID_PARAM;
5014 rpcbuf_move(q_u->buffer, &r_u->buffer);
5015 buffer = r_u->buffer;
5019 if (!get_printer_snum(p, handle, &snum, NULL))
5024 return getprinter_level_0(Printer, snum, buffer, offered, needed);
5026 return getprinter_level_1(Printer, snum, buffer, offered, needed);
5028 return getprinter_level_2(Printer, snum, buffer, offered, needed);
5030 return getprinter_level_3(Printer, snum, buffer, offered, needed);
5032 return getprinter_level_4(Printer, snum, buffer, offered, needed);
5034 return getprinter_level_5(Printer, snum, buffer, offered, needed);
5036 return getprinter_level_6(Printer, snum, buffer, offered, needed);
5038 return getprinter_level_7(Printer, snum, buffer, offered, needed);
5040 return WERR_UNKNOWN_LEVEL;
5043 /********************************************************************
5044 * fill a DRIVER_INFO_1 struct
5045 ********************************************************************/
5047 static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername, fstring architecture)
5049 init_unistr( &info->name, driver.info_3->name);
5052 /********************************************************************
5053 * construct_printer_driver_info_1
5054 ********************************************************************/
5056 static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, const char *servername, fstring architecture, uint32 version)
5058 NT_PRINTER_INFO_LEVEL *printer = NULL;
5059 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5061 ZERO_STRUCT(driver);
5063 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5064 return WERR_INVALID_PRINTER_NAME;
5066 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5067 free_a_printer(&printer, 2);
5068 return WERR_UNKNOWN_PRINTER_DRIVER;
5071 fill_printer_driver_info_1(info, driver, servername, architecture);
5073 free_a_printer(&printer,2);
5078 /********************************************************************
5079 * construct_printer_driver_info_2
5080 * fill a printer_info_2 struct
5081 ********************************************************************/
5083 static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5085 TALLOC_CTX *ctx = talloc_tos();
5087 const char *cservername = canon_servername(servername);
5089 info->version=driver.info_3->cversion;
5091 init_unistr( &info->name, driver.info_3->name );
5092 init_unistr( &info->architecture, driver.info_3->environment );
5094 if (strlen(driver.info_3->driverpath)) {
5095 temp = talloc_asprintf(ctx,
5098 driver.info_3->driverpath);
5099 init_unistr( &info->driverpath, temp );
5101 init_unistr( &info->driverpath, "" );
5105 if (strlen(driver.info_3->datafile)) {
5106 temp = talloc_asprintf(ctx,
5109 driver.info_3->datafile);
5110 init_unistr( &info->datafile, temp );
5112 init_unistr( &info->datafile, "" );
5115 if (strlen(driver.info_3->configfile)) {
5116 temp = talloc_asprintf(ctx,
5119 driver.info_3->configfile);
5120 init_unistr( &info->configfile, temp );
5122 init_unistr( &info->configfile, "" );
5125 /********************************************************************
5126 * construct_printer_driver_info_2
5127 * fill a printer_info_2 struct
5128 ********************************************************************/
5130 static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, const char *servername, fstring architecture, uint32 version)
5132 NT_PRINTER_INFO_LEVEL *printer = NULL;
5133 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5135 ZERO_STRUCT(printer);
5136 ZERO_STRUCT(driver);
5138 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum))))
5139 return WERR_INVALID_PRINTER_NAME;
5141 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) {
5142 free_a_printer(&printer, 2);
5143 return WERR_UNKNOWN_PRINTER_DRIVER;
5146 fill_printer_driver_info_2(info, driver, servername);
5148 free_a_printer(&printer,2);
5153 /********************************************************************
5154 * copy a strings array and convert to UNICODE
5156 * convert an array of ascii string to a UNICODE string
5157 ********************************************************************/
5159 static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername)
5165 TALLOC_CTX *ctx = talloc_tos();
5167 DEBUG(6,("init_unistr_array\n"));
5171 if ( !char_array ) {
5176 v = ""; /* hack to handle null lists */
5179 /* hack to allow this to be used in places other than when generating
5180 the list of dependent files */
5184 line = talloc_asprintf(ctx,
5186 canon_servername(servername),
5189 line = talloc_strdup(ctx, v);
5193 SAFE_FREE(*uni_array);
5196 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line)));
5198 /* add one extra unit16 for the second terminating NULL */
5200 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) {
5201 DEBUG(2,("init_unistr_array: Realloc error\n" ));
5208 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16));
5213 /* special case for ""; we need to add both NULL's here */
5215 (*uni_array)[j++]=0x0000;
5216 (*uni_array)[j]=0x0000;
5219 DEBUGADD(6,("last one:done\n"));
5221 /* return size of array in uint16's */
5226 /********************************************************************
5227 * construct_printer_info_3
5228 * fill a printer_info_3 struct
5229 ********************************************************************/
5231 static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5234 TALLOC_CTX *ctx = talloc_tos();
5235 const char *cservername = canon_servername(servername);
5239 info->version=driver.info_3->cversion;
5241 init_unistr( &info->name, driver.info_3->name );
5242 init_unistr( &info->architecture, driver.info_3->environment );
5244 if (strlen(driver.info_3->driverpath)) {
5245 temp = talloc_asprintf(ctx,
5248 driver.info_3->driverpath);
5249 init_unistr( &info->driverpath, temp );
5251 init_unistr( &info->driverpath, "" );
5254 if (strlen(driver.info_3->datafile)) {
5255 temp = talloc_asprintf(ctx,
5258 driver.info_3->datafile);
5259 init_unistr( &info->datafile, temp );
5261 init_unistr( &info->datafile, "" );
5264 if (strlen(driver.info_3->configfile)) {
5265 temp = talloc_asprintf(ctx,
5268 driver.info_3->configfile);
5269 init_unistr( &info->configfile, temp );
5271 init_unistr( &info->configfile, "" );
5274 if (strlen(driver.info_3->helpfile)) {
5275 temp = talloc_asprintf(ctx,
5278 driver.info_3->helpfile);
5279 init_unistr( &info->helpfile, temp );
5281 init_unistr( &info->helpfile, "" );
5284 init_unistr( &info->monitorname, driver.info_3->monitorname );
5285 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5287 info->dependentfiles=NULL;
5288 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, cservername);
5291 /********************************************************************
5292 * construct_printer_info_3
5293 * fill a printer_info_3 struct
5294 ********************************************************************/
5296 static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, const char *servername, fstring architecture, uint32 version)
5298 NT_PRINTER_INFO_LEVEL *printer = NULL;
5299 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5301 ZERO_STRUCT(driver);
5303 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5304 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5305 if (!W_ERROR_IS_OK(status))
5306 return WERR_INVALID_PRINTER_NAME;
5308 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5309 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5314 * I put this code in during testing. Helpful when commenting out the
5315 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general
5316 * as win2k always queries the driver using an infor level of 6.
5317 * I've left it in (but ifdef'd out) because I'll probably
5318 * use it in experimentation again in the future. --jerry 22/01/2002
5321 if (!W_ERROR_IS_OK(status)) {
5323 * Is this a W2k client ?
5326 /* Yes - try again with a WinNT driver. */
5328 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5329 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status)));
5333 if (!W_ERROR_IS_OK(status)) {
5334 free_a_printer(&printer,2);
5335 return WERR_UNKNOWN_PRINTER_DRIVER;
5343 fill_printer_driver_info_3(info, driver, servername);
5345 free_a_printer(&printer,2);
5350 /********************************************************************
5351 * construct_printer_info_6
5352 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA.
5353 ********************************************************************/
5355 static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, const char *servername)
5359 TALLOC_CTX *ctx = talloc_tos();
5360 const char *cservername = canon_servername(servername);
5363 memset(&nullstr, '\0', sizeof(fstring));
5365 info->version=driver.info_3->cversion;
5367 init_unistr( &info->name, driver.info_3->name );
5368 init_unistr( &info->architecture, driver.info_3->environment );
5370 if (strlen(driver.info_3->driverpath)) {
5371 temp = talloc_asprintf(ctx,
5374 driver.info_3->driverpath);
5375 init_unistr( &info->driverpath, temp );
5377 init_unistr( &info->driverpath, "" );
5380 if (strlen(driver.info_3->datafile)) {
5381 temp = talloc_asprintf(ctx,
5384 driver.info_3->datafile);
5385 init_unistr( &info->datafile, temp );
5387 init_unistr( &info->datafile, "" );
5390 if (strlen(driver.info_3->configfile)) {
5391 temp = talloc_asprintf(ctx,
5394 driver.info_3->configfile);
5395 init_unistr( &info->configfile, temp );
5397 init_unistr( &info->configfile, "" );
5400 if (strlen(driver.info_3->helpfile)) {
5401 temp = talloc_asprintf(ctx,
5404 driver.info_3->helpfile);
5405 init_unistr( &info->helpfile, temp );
5407 init_unistr( &info->helpfile, "" );
5410 init_unistr( &info->monitorname, driver.info_3->monitorname );
5411 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
5413 info->dependentfiles = NULL;
5414 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername );
5416 info->previousdrivernames=NULL;
5417 init_unistr_array(&info->previousdrivernames, &nullstr, servername);
5419 info->driver_date=0;
5422 info->driver_version_low=0;
5423 info->driver_version_high=0;
5425 init_unistr( &info->mfgname, "");
5426 init_unistr( &info->oem_url, "");
5427 init_unistr( &info->hardware_id, "");
5428 init_unistr( &info->provider, "");
5431 /********************************************************************
5432 * construct_printer_info_6
5433 * fill a printer_info_6 struct
5434 ********************************************************************/
5436 static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum,
5437 const char *servername, fstring architecture, uint32 version)
5439 NT_PRINTER_INFO_LEVEL *printer = NULL;
5440 NT_PRINTER_DRIVER_INFO_LEVEL driver;
5443 ZERO_STRUCT(driver);
5445 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) );
5447 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5449 if (!W_ERROR_IS_OK(status))
5450 return WERR_INVALID_PRINTER_NAME;
5452 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5454 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5456 if (!W_ERROR_IS_OK(status))
5459 * Is this a W2k client ?
5463 free_a_printer(&printer,2);
5464 return WERR_UNKNOWN_PRINTER_DRIVER;
5467 /* Yes - try again with a WinNT driver. */
5469 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
5470 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status)));
5471 if (!W_ERROR_IS_OK(status)) {
5472 free_a_printer(&printer,2);
5473 return WERR_UNKNOWN_PRINTER_DRIVER;
5477 fill_printer_driver_info_6(info, driver, servername);
5479 free_a_printer(&printer,2);
5480 free_a_printer_driver(driver, 3);
5485 /****************************************************************************
5486 ****************************************************************************/
5488 static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
5490 SAFE_FREE(info->dependentfiles);
5493 /****************************************************************************
5494 ****************************************************************************/
5496 static void free_printer_driver_info_6(DRIVER_INFO_6 *info)
5498 SAFE_FREE(info->dependentfiles);
5501 /****************************************************************************
5502 ****************************************************************************/
5504 static WERROR getprinterdriver2_level1(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5506 DRIVER_INFO_1 *info=NULL;
5509 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL)
5512 result = construct_printer_driver_info_1(info, snum, servername, architecture, version);
5513 if (!W_ERROR_IS_OK(result))
5516 /* check the required size. */
5517 *needed += spoolss_size_printer_driver_info_1(info);
5519 if (*needed > offered) {
5520 result = WERR_INSUFFICIENT_BUFFER;
5524 if (!rpcbuf_alloc_size(buffer, *needed)) {
5525 result = WERR_NOMEM;
5529 /* fill the buffer with the structures */
5530 smb_io_printer_driver_info_1("", buffer, info, 0);
5539 /****************************************************************************
5540 ****************************************************************************/
5542 static WERROR getprinterdriver2_level2(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5544 DRIVER_INFO_2 *info=NULL;
5547 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL)
5550 result = construct_printer_driver_info_2(info, snum, servername, architecture, version);
5551 if (!W_ERROR_IS_OK(result))
5554 /* check the required size. */
5555 *needed += spoolss_size_printer_driver_info_2(info);
5557 if (*needed > offered) {
5558 result = WERR_INSUFFICIENT_BUFFER;
5562 if (!rpcbuf_alloc_size(buffer, *needed)) {
5563 result = WERR_NOMEM;
5567 /* fill the buffer with the structures */
5568 smb_io_printer_driver_info_2("", buffer, info, 0);
5577 /****************************************************************************
5578 ****************************************************************************/
5580 static WERROR getprinterdriver2_level3(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5587 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version);
5588 if (!W_ERROR_IS_OK(result))
5591 /* check the required size. */
5592 *needed += spoolss_size_printer_driver_info_3(&info);
5594 if (*needed > offered) {
5595 result = WERR_INSUFFICIENT_BUFFER;
5599 if (!rpcbuf_alloc_size(buffer, *needed)) {
5600 result = WERR_NOMEM;
5604 /* fill the buffer with the structures */
5605 smb_io_printer_driver_info_3("", buffer, &info, 0);
5608 free_printer_driver_info_3(&info);
5613 /****************************************************************************
5614 ****************************************************************************/
5616 static WERROR getprinterdriver2_level6(const char *servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed)
5623 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version);
5624 if (!W_ERROR_IS_OK(result))
5627 /* check the required size. */
5628 *needed += spoolss_size_printer_driver_info_6(&info);
5630 if (*needed > offered) {
5631 result = WERR_INSUFFICIENT_BUFFER;
5635 if (!rpcbuf_alloc_size(buffer, *needed)) {
5636 result = WERR_NOMEM;
5640 /* fill the buffer with the structures */
5641 smb_io_printer_driver_info_6("", buffer, &info, 0);
5644 free_printer_driver_info_6(&info);
5649 /****************************************************************************
5650 ****************************************************************************/
5652 WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u)
5654 POLICY_HND *handle = &q_u->handle;
5655 UNISTR2 *uni_arch = &q_u->architecture;
5656 uint32 level = q_u->level;
5657 uint32 clientmajorversion = q_u->clientmajorversion;
5658 RPC_BUFFER *buffer = NULL;
5659 uint32 offered = q_u->offered;
5660 uint32 *needed = &r_u->needed;
5661 uint32 *servermajorversion = &r_u->servermajorversion;
5662 uint32 *serverminorversion = &r_u->serverminorversion;
5663 Printer_entry *printer;
5666 fstring architecture;
5669 /* that's an [in out] buffer */
5671 if (!q_u->buffer && (offered!=0)) {
5672 return WERR_INVALID_PARAM;
5675 if (offered > MAX_RPC_DATA_SIZE) {
5676 return WERR_INVALID_PARAM;
5679 rpcbuf_move(q_u->buffer, &r_u->buffer);
5680 buffer = r_u->buffer;
5682 DEBUG(4,("_spoolss_getprinterdriver2\n"));
5684 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) {
5685 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n"));
5686 return WERR_INVALID_PRINTER_NAME;
5690 *servermajorversion = 0;
5691 *serverminorversion = 0;
5693 fstrcpy(servername, get_server_name( printer ));
5694 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture));
5696 if (!get_printer_snum(p, handle, &snum, NULL))
5701 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5703 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5705 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5707 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
5710 /* apparently this call is the equivalent of
5711 EnumPrinterDataEx() for the DsDriver key */
5716 return WERR_UNKNOWN_LEVEL;
5720 /****************************************************************
5721 _spoolss_StartPagePrinter
5722 ****************************************************************/
5724 WERROR _spoolss_StartPagePrinter(pipes_struct *p,
5725 struct spoolss_StartPagePrinter *r)
5727 POLICY_HND *handle = r->in.handle;
5729 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5732 DEBUG(3,("_spoolss_StartPagePrinter: "
5733 "Error in startpageprinter printer handle\n"));
5737 Printer->page_started=True;
5741 /****************************************************************
5742 _spoolss_EndPagePrinter
5743 ****************************************************************/
5745 WERROR _spoolss_EndPagePrinter(pipes_struct *p,
5746 struct spoolss_EndPagePrinter *r)
5748 POLICY_HND *handle = r->in.handle;
5751 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5754 DEBUG(2,("_spoolss_EndPagePrinter: Invalid handle (%s:%u:%u).\n",
5755 OUR_HANDLE(handle)));
5759 if (!get_printer_snum(p, handle, &snum, NULL))
5762 Printer->page_started=False;
5763 print_job_endpage(snum, Printer->jobid);
5768 /****************************************************************
5769 _spoolss_StartDocPrinter
5770 ****************************************************************/
5772 WERROR _spoolss_StartDocPrinter(pipes_struct *p,
5773 struct spoolss_StartDocPrinter *r)
5775 POLICY_HND *handle = r->in.handle;
5776 uint32_t *jobid = r->out.job_id;
5777 struct spoolss_DocumentInfo1 *info_1;
5779 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5782 DEBUG(2,("_spoolss_StartDocPrinter: "
5783 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5787 if (r->in.level != 1) {
5788 return WERR_UNKNOWN_LEVEL;
5791 info_1 = r->in.info.info1;
5794 * a nice thing with NT is it doesn't listen to what you tell it.
5795 * when asked to send _only_ RAW datas, it tries to send datas
5798 * So I add checks like in NT Server ...
5801 if (info_1->datatype) {
5802 if (strcmp(info_1->datatype, "RAW") != 0) {
5804 return WERR_INVALID_DATATYPE;
5808 /* get the share number of the printer */
5809 if (!get_printer_snum(p, handle, &snum, NULL)) {
5813 Printer->jobid = print_job_start(p->server_info, snum,
5814 CONST_DISCARD(char *,info_1->document_name),
5815 Printer->nt_devmode);
5817 /* An error occured in print_job_start() so return an appropriate
5820 if (Printer->jobid == -1) {
5821 return map_werror_from_unix(errno);
5824 Printer->document_started=True;
5825 (*jobid) = Printer->jobid;
5830 /****************************************************************
5831 _spoolss_EndDocPrinter
5832 ****************************************************************/
5834 WERROR _spoolss_EndDocPrinter(pipes_struct *p,
5835 struct spoolss_EndDocPrinter *r)
5837 POLICY_HND *handle = r->in.handle;
5839 return _spoolss_enddocprinter_internal(p, handle);
5842 /****************************************************************
5843 _spoolss_WritePrinter
5844 ****************************************************************/
5846 WERROR _spoolss_WritePrinter(pipes_struct *p,
5847 struct spoolss_WritePrinter *r)
5849 POLICY_HND *handle = r->in.handle;
5850 uint32 buffer_size = r->in._data_size;
5851 uint8 *buffer = r->in.data.data;
5852 uint32 *buffer_written = &r->in._data_size;
5854 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5857 DEBUG(2,("_spoolss_WritePrinter: Invalid handle (%s:%u:%u)\n",
5858 OUR_HANDLE(handle)));
5859 *r->out.num_written = r->in._data_size;
5863 if (!get_printer_snum(p, handle, &snum, NULL))
5866 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer,
5867 (SMB_OFF_T)-1, (size_t)buffer_size);
5868 if (*buffer_written == (uint32)-1) {
5869 *r->out.num_written = 0;
5870 if (errno == ENOSPC)
5871 return WERR_NO_SPOOL_SPACE;
5873 return WERR_ACCESS_DENIED;
5876 *r->out.num_written = r->in._data_size;
5881 /********************************************************************
5882 * api_spoolss_getprinter
5883 * called from the spoolss dispatcher
5885 ********************************************************************/
5887 static WERROR control_printer(POLICY_HND *handle, uint32 command,
5891 WERROR errcode = WERR_BADFUNC;
5892 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5895 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
5899 if (!get_printer_snum(p, handle, &snum, NULL))
5903 case SPOOLSS_PRINTER_CONTROL_PAUSE:
5904 if (print_queue_pause(p->server_info, snum, &errcode)) {
5908 case SPOOLSS_PRINTER_CONTROL_RESUME:
5909 case SPOOLSS_PRINTER_CONTROL_UNPAUSE:
5910 if (print_queue_resume(p->server_info, snum, &errcode)) {
5914 case SPOOLSS_PRINTER_CONTROL_PURGE:
5915 if (print_queue_purge(p->server_info, snum, &errcode)) {
5920 return WERR_UNKNOWN_LEVEL;
5927 /****************************************************************
5928 _spoolss_AbortPrinter
5929 * From MSDN: "Deletes printer's spool file if printer is configured
5931 ****************************************************************/
5933 WERROR _spoolss_AbortPrinter(pipes_struct *p,
5934 struct spoolss_AbortPrinter *r)
5936 POLICY_HND *handle = r->in.handle;
5937 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5939 WERROR errcode = WERR_OK;
5942 DEBUG(2,("_spoolss_AbortPrinter: Invalid handle (%s:%u:%u)\n",
5943 OUR_HANDLE(handle)));
5947 if (!get_printer_snum(p, handle, &snum, NULL))
5950 print_job_delete(p->server_info, snum, Printer->jobid, &errcode );
5955 /********************************************************************
5956 * called by spoolss_api_setprinter
5957 * when updating a printer description
5958 ********************************************************************/
5960 static WERROR update_printer_sec(POLICY_HND *handle,
5961 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr)
5963 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL;
5967 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
5969 if (!Printer || !get_printer_snum(p, handle, &snum, NULL)) {
5970 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n",
5971 OUR_HANDLE(handle)));
5973 result = WERR_BADFID;
5978 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n"));
5979 result = WERR_INVALID_PARAM;
5983 /* Check the user has permissions to change the security
5984 descriptor. By experimentation with two NT machines, the user
5985 requires Full Access to the printer to change security
5988 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) {
5989 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n"));
5990 result = WERR_ACCESS_DENIED;
5994 /* NT seems to like setting the security descriptor even though
5995 nothing may have actually changed. */
5997 if ( !nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr)) {
5998 DEBUG(2,("update_printer_sec: nt_printing_getsec() failed\n"));
5999 result = WERR_BADFID;
6003 if (DEBUGLEVEL >= 10) {
6007 the_acl = old_secdesc_ctr->sd->dacl;
6008 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n",
6009 PRINTERNAME(snum), the_acl->num_aces));
6011 for (i = 0; i < the_acl->num_aces; i++) {
6012 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6013 &the_acl->aces[i].trustee),
6014 the_acl->aces[i].access_mask));
6017 the_acl = secdesc_ctr->sd->dacl;
6020 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
6021 PRINTERNAME(snum), the_acl->num_aces));
6023 for (i = 0; i < the_acl->num_aces; i++) {
6024 DEBUG(10, ("%s 0x%08x\n", sid_string_dbg(
6025 &the_acl->aces[i].trustee),
6026 the_acl->aces[i].access_mask));
6029 DEBUG(10, ("dacl for secdesc_ctr is NULL\n"));
6033 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr);
6034 if (!new_secdesc_ctr) {
6035 result = WERR_NOMEM;
6039 if (sec_desc_equal(new_secdesc_ctr->sd, old_secdesc_ctr->sd)) {
6044 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr);
6051 /********************************************************************
6052 Canonicalize printer info from a client
6054 ATTN: It does not matter what we set the servername to hear
6055 since we do the necessary work in get_a_printer() to set it to
6056 the correct value based on what the client sent in the
6057 _spoolss_open_printer_ex().
6058 ********************************************************************/
6060 static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum)
6062 fstring printername;
6065 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s "
6066 "portname=%s drivername=%s comment=%s location=%s\n",
6067 info->servername, info->printername, info->sharename,
6068 info->portname, info->drivername, info->comment, info->location));
6070 /* we force some elements to "correct" values */
6071 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname());
6072 fstrcpy(info->sharename, lp_servicename(snum));
6074 /* check to see if we allow printername != sharename */
6076 if ( lp_force_printername(snum) ) {
6077 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6078 global_myname(), info->sharename );
6081 /* make sure printername is in \\server\printername format */
6083 fstrcpy( printername, info->printername );
6085 if ( printername[0] == '\\' && printername[1] == '\\' ) {
6086 if ( (p = strchr_m( &printername[2], '\\' )) != NULL )
6090 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
6091 global_myname(), p );
6094 info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
6095 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
6102 /****************************************************************************
6103 ****************************************************************************/
6105 WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname, const char *uri )
6107 char *cmd = lp_addport_cmd();
6108 char *command = NULL;
6110 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6111 bool is_print_op = False;
6114 return WERR_ACCESS_DENIED;
6117 command = talloc_asprintf(ctx,
6118 "%s \"%s\" \"%s\"", cmd, portname, uri );
6124 is_print_op = user_has_privileges( token, &se_printop );
6126 DEBUG(10,("Running [%s]\n", command));
6128 /********* BEGIN SePrintOperatorPrivilege **********/
6133 ret = smbrun(command, NULL);
6138 /********* END SePrintOperatorPrivilege **********/
6140 DEBUGADD(10,("returned [%d]\n", ret));
6142 TALLOC_FREE(command);
6145 return WERR_ACCESS_DENIED;
6151 /****************************************************************************
6152 ****************************************************************************/
6154 bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer)
6156 char *cmd = lp_addprinter_cmd();
6158 char *command = NULL;
6162 SE_PRIV se_printop = SE_PRINT_OPERATOR;
6163 bool is_print_op = False;
6164 char *remote_machine = talloc_strdup(ctx, "%m");
6166 if (!remote_machine) {
6169 remote_machine = talloc_sub_basic(ctx,
6170 current_user_info.smb_name,
6171 current_user_info.domain,
6173 if (!remote_machine) {
6177 command = talloc_asprintf(ctx,
6178 "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
6179 cmd, printer->info_2->printername, printer->info_2->sharename,
6180 printer->info_2->portname, printer->info_2->drivername,
6181 printer->info_2->location, printer->info_2->comment, remote_machine);
6187 is_print_op = user_has_privileges( token, &se_printop );
6189 DEBUG(10,("Running [%s]\n", command));
6191 /********* BEGIN SePrintOperatorPrivilege **********/
6196 if ( (ret = smbrun(command, &fd)) == 0 ) {
6197 /* Tell everyone we updated smb.conf. */
6198 message_send_all(smbd_messaging_context(),
6199 MSG_SMB_CONF_UPDATED, NULL, 0, NULL);
6205 /********* END SePrintOperatorPrivilege **********/
6207 DEBUGADD(10,("returned [%d]\n", ret));
6209 TALLOC_FREE(command);
6210 TALLOC_FREE(remote_machine);
6218 /* reload our services immediately */
6219 reload_services( False );
6222 /* Get lines and convert them back to dos-codepage */
6223 qlines = fd_lines_load(fd, &numlines, 0, NULL);
6224 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
6227 /* Set the portname to what the script says the portname should be. */
6228 /* but don't require anything to be return from the script exit a good error code */
6231 /* Set the portname to what the script says the portname should be. */
6232 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname));
6233 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0]));
6236 TALLOC_FREE(qlines);
6241 /********************************************************************
6242 * Called by spoolss_api_setprinter
6243 * when updating a printer description.
6244 ********************************************************************/
6246 static WERROR update_printer(pipes_struct *p, POLICY_HND *handle,
6247 struct spoolss_SetPrinterInfoCtr *info_ctr,
6248 struct spoolss_DeviceMode *devmode)
6251 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL;
6252 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6257 DEBUG(8,("update_printer\n"));
6262 result = WERR_BADFID;
6266 if (!get_printer_snum(p, handle, &snum, NULL)) {
6267 result = WERR_BADFID;
6271 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) ||
6272 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) {
6273 result = WERR_BADFID;
6277 DEBUGADD(8,("Converting info_2 struct\n"));
6280 * convert_printer_info converts the incoming
6281 * info from the client and overwrites the info
6282 * just read from the tdb in the pointer 'printer'.
6285 if (!convert_printer_info_new(info_ctr, printer)) {
6286 result = WERR_NOMEM;
6291 /* we have a valid devmode
6292 convert it and link it*/
6294 DEBUGADD(8,("update_printer: Converting the devicemode struct\n"));
6295 if (!convert_devicemode_new(printer->info_2->printername,
6297 &printer->info_2->devmode)) {
6298 result = WERR_NOMEM;
6303 /* Do sanity check on the requested changes for Samba */
6305 if (!check_printer_ok(printer->info_2, snum)) {
6306 result = WERR_INVALID_PARAM;
6310 /* FIXME!!! If the driver has changed we really should verify that
6311 it is installed before doing much else --jerry */
6313 /* Check calling user has permission to update printer description */
6315 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
6316 DEBUG(3, ("update_printer: printer property change denied by handle\n"));
6317 result = WERR_ACCESS_DENIED;
6321 /* Call addprinter hook */
6322 /* Check changes to see if this is really needed */
6324 if ( *lp_addprinter_cmd()
6325 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)
6326 || !strequal(printer->info_2->comment, old_printer->info_2->comment)
6327 || !strequal(printer->info_2->portname, old_printer->info_2->portname)
6328 || !strequal(printer->info_2->location, old_printer->info_2->location)) )
6330 /* add_printer_hook() will call reload_services() */
6332 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
6334 result = WERR_ACCESS_DENIED;
6340 * When a *new* driver is bound to a printer, the drivername is used to
6341 * lookup previously saved driver initialization info, which is then
6342 * bound to the printer, simulating what happens in the Windows arch.
6344 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername))
6346 if (!set_driver_init(printer, 2))
6348 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n",
6349 printer->info_2->drivername));
6352 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n",
6353 printer->info_2->drivername));
6355 notify_printer_driver(snum, printer->info_2->drivername);
6359 * flag which changes actually occured. This is a small subset of
6360 * all the possible changes. We also have to update things in the
6364 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) {
6365 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE);
6366 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description",
6367 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6369 notify_printer_comment(snum, printer->info_2->comment);
6372 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) {
6373 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE);
6374 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName",
6375 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6377 notify_printer_sharename(snum, printer->info_2->sharename);
6380 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) {
6383 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL )
6386 pname = printer->info_2->printername;
6389 init_unistr2( &buffer, pname, UNI_STR_TERMINATE);
6390 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName",
6391 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6393 notify_printer_printername( snum, pname );
6396 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) {
6397 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE);
6398 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName",
6399 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6401 notify_printer_port(snum, printer->info_2->portname);
6404 if (!strequal(printer->info_2->location, old_printer->info_2->location)) {
6405 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE);
6406 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location",
6407 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6409 notify_printer_location(snum, printer->info_2->location);
6412 /* here we need to update some more DsSpooler keys */
6413 /* uNCName, serverName, shortServerName */
6415 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE);
6416 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName",
6417 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6418 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName",
6419 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6421 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s",
6422 global_myname(), printer->info_2->sharename );
6423 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE);
6424 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName",
6425 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 );
6427 /* Update printer info */
6428 result = mod_a_printer(printer, 2);
6431 free_a_printer(&printer, 2);
6432 free_a_printer(&old_printer, 2);
6438 /****************************************************************************
6439 ****************************************************************************/
6440 static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle,
6441 struct spoolss_SetPrinterInfo7 *info7)
6445 Printer_entry *Printer;
6447 if ( lp_security() != SEC_ADS ) {
6448 return WERR_UNKNOWN_LEVEL;
6451 Printer = find_printer_index_by_hnd(p, handle);
6453 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action));
6458 if (!get_printer_snum(p, handle, &snum, NULL))
6461 nt_printer_publish(Printer, snum, info7->action);
6465 return WERR_UNKNOWN_LEVEL;
6469 /****************************************************************
6471 ****************************************************************/
6473 WERROR _spoolss_SetPrinter(pipes_struct *p,
6474 struct spoolss_SetPrinter *r)
6476 POLICY_HND *handle = r->in.handle;
6479 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
6482 DEBUG(2,("_spoolss_SetPrinter: Invalid handle (%s:%u:%u)\n",
6483 OUR_HANDLE(handle)));
6487 /* check the level */
6488 switch (r->in.info_ctr->level) {
6490 return control_printer(handle, r->in.command, p);
6492 result = update_printer(p, handle,
6494 r->in.devmode_ctr->devmode);
6495 if (!W_ERROR_IS_OK(result))
6497 if (r->in.secdesc_ctr->sd)
6498 result = update_printer_sec(handle, p,
6502 return update_printer_sec(handle, p,
6505 return publish_or_unpublish_printer(p, handle,
6506 r->in.info_ctr->info.info7);
6508 return WERR_UNKNOWN_LEVEL;
6512 /****************************************************************
6513 _spoolss_FindClosePrinterNotify
6514 ****************************************************************/
6516 WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p,
6517 struct spoolss_FindClosePrinterNotify *r)
6519 POLICY_HND *handle = r->in.handle;
6520 Printer_entry *Printer= find_printer_index_by_hnd(p, handle);
6523 DEBUG(2,("_spoolss_FindClosePrinterNotify: "
6524 "Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle)));
6528 if (Printer->notify.client_connected==True) {
6531 if ( Printer->printer_type == SPLHND_SERVER)
6533 else if ( (Printer->printer_type == SPLHND_PRINTER) &&
6534 !get_printer_snum(p, handle, &snum, NULL) )
6537 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd);
6540 Printer->notify.flags=0;
6541 Printer->notify.options=0;
6542 Printer->notify.localmachine[0]='\0';
6543 Printer->notify.printerlocal=0;
6544 if (Printer->notify.option)
6545 free_spool_notify_option(&Printer->notify.option);
6546 Printer->notify.client_connected=False;
6551 /****************************************************************
6553 ****************************************************************/
6555 WERROR _spoolss_AddJob(pipes_struct *p,
6556 struct spoolss_AddJob *r)
6558 if (!r->in.buffer && (r->in.offered != 0)) {
6559 return WERR_INVALID_PARAM;
6562 /* this is what a NT server returns for AddJob. AddJob must fail on
6563 * non-local printers */
6565 return WERR_INVALID_PARAM;
6568 /****************************************************************************
6569 ****************************************************************************/
6571 static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue,
6572 int position, int snum,
6573 const NT_PRINTER_INFO_LEVEL *ntprinter)
6577 t=gmtime(&queue->time);
6579 job_info->jobid=queue->job;
6580 init_unistr(&job_info->printername, lp_servicename(snum));
6581 init_unistr(&job_info->machinename, ntprinter->info_2->servername);
6582 init_unistr(&job_info->username, queue->fs_user);
6583 init_unistr(&job_info->document, queue->fs_file);
6584 init_unistr(&job_info->datatype, "RAW");
6585 init_unistr(&job_info->text_status, "");
6586 job_info->status=nt_printj_status(queue->status);
6587 job_info->priority=queue->priority;
6588 job_info->position=position;
6589 job_info->totalpages=queue->page_count;
6590 job_info->pagesprinted=0;
6592 make_systemtime(&job_info->submitted, t);
6595 /****************************************************************************
6596 ****************************************************************************/
6598 static bool fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue,
6599 int position, int snum,
6600 const NT_PRINTER_INFO_LEVEL *ntprinter,
6601 DEVICEMODE *devmode)
6605 t=gmtime(&queue->time);
6607 job_info->jobid=queue->job;
6609 init_unistr(&job_info->printername, ntprinter->info_2->printername);
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->notifyname, queue->fs_user);
6615 init_unistr(&job_info->datatype, "RAW");
6616 init_unistr(&job_info->printprocessor, "winprint");
6617 init_unistr(&job_info->parameters, "");
6618 init_unistr(&job_info->drivername, ntprinter->info_2->drivername);
6619 init_unistr(&job_info->text_status, "");
6621 /* and here the security descriptor */
6623 job_info->status=nt_printj_status(queue->status);
6624 job_info->priority=queue->priority;
6625 job_info->position=position;
6626 job_info->starttime=0;
6627 job_info->untiltime=0;
6628 job_info->totalpages=queue->page_count;
6629 job_info->size=queue->size;
6630 make_systemtime(&(job_info->submitted), t);
6631 job_info->timeelapsed=0;
6632 job_info->pagesprinted=0;
6634 job_info->devmode = devmode;
6639 /****************************************************************************
6640 Enumjobs at level 1.
6641 ****************************************************************************/
6643 static WERROR enumjobs_level1(const print_queue_struct *queue, int snum,
6644 const NT_PRINTER_INFO_LEVEL *ntprinter,
6645 RPC_BUFFER *buffer, uint32 offered,
6646 uint32 *needed, uint32 *returned)
6650 WERROR result = WERR_OK;
6652 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned);
6658 for (i=0; i<*returned; i++)
6659 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter );
6661 /* check the required size. */
6662 for (i=0; i<*returned; i++)
6663 (*needed) += spoolss_size_job_info_1(&info[i]);
6665 if (*needed > offered) {
6666 result = WERR_INSUFFICIENT_BUFFER;
6670 if (!rpcbuf_alloc_size(buffer, *needed)) {
6671 result = WERR_NOMEM;
6675 /* fill the buffer with the structures */
6676 for (i=0; i<*returned; i++)
6677 smb_io_job_info_1("", buffer, &info[i], 0);
6683 if ( !W_ERROR_IS_OK(result) )
6689 /****************************************************************************
6690 Enumjobs at level 2.
6691 ****************************************************************************/
6693 static WERROR enumjobs_level2(const print_queue_struct *queue, int snum,
6694 const NT_PRINTER_INFO_LEVEL *ntprinter,
6695 RPC_BUFFER *buffer, uint32 offered,
6696 uint32 *needed, uint32 *returned)
6698 JOB_INFO_2 *info = NULL;
6700 WERROR result = WERR_OK;
6701 DEVICEMODE *devmode = NULL;
6703 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) {
6708 /* this should not be a failure condition if the devmode is NULL */
6710 devmode = construct_dev_mode(lp_const_servicename(snum));
6712 for (i=0; i<*returned; i++)
6713 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode);
6715 /* check the required size. */
6716 for (i=0; i<*returned; i++)
6717 (*needed) += spoolss_size_job_info_2(&info[i]);
6719 if (*needed > offered) {
6720 result = WERR_INSUFFICIENT_BUFFER;
6724 if (!rpcbuf_alloc_size(buffer, *needed)) {
6725 result = WERR_NOMEM;
6729 /* fill the buffer with the structures */
6730 for (i=0; i<*returned; i++)
6731 smb_io_job_info_2("", buffer, &info[i], 0);
6734 free_devmode(devmode);
6737 if ( !W_ERROR_IS_OK(result) )
6744 /****************************************************************************
6746 ****************************************************************************/
6748 WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u)
6750 POLICY_HND *handle = &q_u->handle;
6751 uint32 level = q_u->level;
6752 RPC_BUFFER *buffer = NULL;
6753 uint32 offered = q_u->offered;
6754 uint32 *needed = &r_u->needed;
6755 uint32 *returned = &r_u->returned;
6757 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
6759 print_status_struct prt_status;
6760 print_queue_struct *queue=NULL;
6762 /* that's an [in out] buffer */
6764 if (!q_u->buffer && (offered!=0)) {
6765 return WERR_INVALID_PARAM;
6768 if (offered > MAX_RPC_DATA_SIZE) {
6769 return WERR_INVALID_PARAM;
6772 rpcbuf_move(q_u->buffer, &r_u->buffer);
6773 buffer = r_u->buffer;
6775 DEBUG(4,("_spoolss_enumjobs\n"));
6780 /* lookup the printer snum and tdb entry */
6782 if (!get_printer_snum(p, handle, &snum, NULL))
6785 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
6786 if ( !W_ERROR_IS_OK(wret) )
6789 *returned = print_queue_status(snum, &queue, &prt_status);
6790 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message));
6792 if (*returned == 0) {
6794 free_a_printer(&ntprinter, 2);
6800 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned);
6803 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned);
6807 wret = WERR_UNKNOWN_LEVEL;
6812 free_a_printer( &ntprinter, 2 );
6816 /****************************************************************
6817 _spoolss_ScheduleJob
6818 ****************************************************************/
6820 WERROR _spoolss_ScheduleJob(pipes_struct *p,
6821 struct spoolss_ScheduleJob *r)
6826 /****************************************************************
6828 ****************************************************************/
6830 WERROR _spoolss_SetJob(pipes_struct *p,
6831 struct spoolss_SetJob *r)
6833 POLICY_HND *handle = r->in.handle;
6834 uint32 jobid = r->in.job_id;
6835 uint32 command = r->in.command;
6838 WERROR errcode = WERR_BADFUNC;
6840 if (!get_printer_snum(p, handle, &snum, NULL)) {
6844 if (!print_job_exists(lp_const_servicename(snum), jobid)) {
6845 return WERR_INVALID_PRINTER_NAME;
6849 case SPOOLSS_JOB_CONTROL_CANCEL:
6850 case SPOOLSS_JOB_CONTROL_DELETE:
6851 if (print_job_delete(p->server_info, snum, jobid, &errcode)) {
6855 case SPOOLSS_JOB_CONTROL_PAUSE:
6856 if (print_job_pause(p->server_info, snum, jobid, &errcode)) {
6860 case SPOOLSS_JOB_CONTROL_RESTART:
6861 case SPOOLSS_JOB_CONTROL_RESUME:
6862 if (print_job_resume(p->server_info, snum, jobid, &errcode)) {
6867 return WERR_UNKNOWN_LEVEL;
6873 /****************************************************************************
6874 Enumerates all printer drivers at level 1.
6875 ****************************************************************************/
6877 static WERROR enumprinterdrivers_level1(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6882 fstring *list = NULL;
6883 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6884 DRIVER_INFO_1 *driver_info_1=NULL;
6885 WERROR result = WERR_OK;
6889 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6891 ndrivers=get_ntdrivers(&list, architecture, version);
6892 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6894 if(ndrivers == -1) {
6895 SAFE_FREE(driver_info_1);
6900 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) {
6901 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n"));
6907 for (i=0; i<ndrivers; i++) {
6909 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6910 ZERO_STRUCT(driver);
6911 status = get_a_printer_driver(&driver, 3, list[i],
6912 architecture, version);
6913 if (!W_ERROR_IS_OK(status)) {
6915 SAFE_FREE(driver_info_1);
6918 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture );
6919 free_a_printer_driver(driver, 3);
6922 *returned+=ndrivers;
6926 /* check the required size. */
6927 for (i=0; i<*returned; i++) {
6928 DEBUGADD(6,("adding driver [%d]'s size\n",i));
6929 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]);
6932 if (*needed > offered) {
6933 result = WERR_INSUFFICIENT_BUFFER;
6937 if (!rpcbuf_alloc_size(buffer, *needed)) {
6938 result = WERR_NOMEM;
6942 /* fill the buffer with the driver structures */
6943 for (i=0; i<*returned; i++) {
6944 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
6945 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0);
6949 SAFE_FREE(driver_info_1);
6951 if ( !W_ERROR_IS_OK(result) )
6957 /****************************************************************************
6958 Enumerates all printer drivers at level 2.
6959 ****************************************************************************/
6961 static WERROR enumprinterdrivers_level2(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
6966 fstring *list = NULL;
6967 NT_PRINTER_DRIVER_INFO_LEVEL driver;
6968 DRIVER_INFO_2 *driver_info_2=NULL;
6969 WERROR result = WERR_OK;
6973 for (version=0; version<DRIVER_MAX_VERSION; version++) {
6975 ndrivers=get_ntdrivers(&list, architecture, version);
6976 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
6978 if(ndrivers == -1) {
6979 SAFE_FREE(driver_info_2);
6984 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) {
6985 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n"));
6991 for (i=0; i<ndrivers; i++) {
6994 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
6995 ZERO_STRUCT(driver);
6996 status = get_a_printer_driver(&driver, 3, list[i],
6997 architecture, version);
6998 if (!W_ERROR_IS_OK(status)) {
7000 SAFE_FREE(driver_info_2);
7003 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername);
7004 free_a_printer_driver(driver, 3);
7007 *returned+=ndrivers;
7011 /* check the required size. */
7012 for (i=0; i<*returned; i++) {
7013 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7014 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i]));
7017 if (*needed > offered) {
7018 result = WERR_INSUFFICIENT_BUFFER;
7022 if (!rpcbuf_alloc_size(buffer, *needed)) {
7023 result = WERR_NOMEM;
7027 /* fill the buffer with the form structures */
7028 for (i=0; i<*returned; i++) {
7029 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7030 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0);
7034 SAFE_FREE(driver_info_2);
7036 if ( !W_ERROR_IS_OK(result) )
7042 /****************************************************************************
7043 Enumerates all printer drivers at level 3.
7044 ****************************************************************************/
7046 static WERROR enumprinterdrivers_level3(const char *servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7051 fstring *list = NULL;
7052 DRIVER_INFO_3 *driver_info_3=NULL;
7053 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7054 WERROR result = WERR_OK;
7058 for (version=0; version<DRIVER_MAX_VERSION; version++) {
7060 ndrivers=get_ntdrivers(&list, architecture, version);
7061 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
7063 if(ndrivers == -1) {
7064 SAFE_FREE(driver_info_3);
7069 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) {
7070 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n"));
7076 for (i=0; i<ndrivers; i++) {
7079 DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
7080 ZERO_STRUCT(driver);
7081 status = get_a_printer_driver(&driver, 3, list[i],
7082 architecture, version);
7083 if (!W_ERROR_IS_OK(status)) {
7085 SAFE_FREE(driver_info_3);
7088 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername);
7089 free_a_printer_driver(driver, 3);
7092 *returned+=ndrivers;
7096 /* check the required size. */
7097 for (i=0; i<*returned; i++) {
7098 DEBUGADD(6,("adding driver [%d]'s size\n",i));
7099 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]);
7102 if (*needed > offered) {
7103 result = WERR_INSUFFICIENT_BUFFER;
7107 if (!rpcbuf_alloc_size(buffer, *needed)) {
7108 result = WERR_NOMEM;
7112 /* fill the buffer with the driver structures */
7113 for (i=0; i<*returned; i++) {
7114 DEBUGADD(6,("adding driver [%d] to buffer\n",i));
7115 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0);
7119 for (i=0; i<*returned; i++) {
7120 SAFE_FREE(driver_info_3[i].dependentfiles);
7123 SAFE_FREE(driver_info_3);
7125 if ( !W_ERROR_IS_OK(result) )
7131 /****************************************************************************
7132 Enumerates all printer drivers.
7133 ****************************************************************************/
7135 WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u)
7137 uint32 level = q_u->level;
7138 RPC_BUFFER *buffer = NULL;
7139 uint32 offered = q_u->offered;
7140 uint32 *needed = &r_u->needed;
7141 uint32 *returned = &r_u->returned;
7142 const char *cservername;
7144 fstring architecture;
7146 /* that's an [in out] buffer */
7148 if (!q_u->buffer && (offered!=0)) {
7149 return WERR_INVALID_PARAM;
7152 if (offered > MAX_RPC_DATA_SIZE) {
7153 return WERR_INVALID_PARAM;
7156 rpcbuf_move(q_u->buffer, &r_u->buffer);
7157 buffer = r_u->buffer;
7159 DEBUG(4,("_spoolss_enumprinterdrivers\n"));
7164 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture));
7165 unistr2_to_ascii(servername, &q_u->name, sizeof(servername));
7167 cservername = canon_servername(servername);
7169 if (!is_myname_or_ipaddr(cservername))
7170 return WERR_UNKNOWN_PRINTER_DRIVER;
7174 return enumprinterdrivers_level1(cservername, architecture, buffer, offered, needed, returned);
7176 return enumprinterdrivers_level2(cservername, architecture, buffer, offered, needed, returned);
7178 return enumprinterdrivers_level3(cservername, architecture, buffer, offered, needed, returned);
7180 return WERR_UNKNOWN_LEVEL;
7184 /****************************************************************************
7185 ****************************************************************************/
7187 static void fill_form_1(FORM_1 *form, nt_forms_struct *list)
7189 form->flag=list->flag;
7190 init_unistr(&form->name, list->name);
7191 form->width=list->width;
7192 form->length=list->length;
7193 form->left=list->left;
7194 form->top=list->top;
7195 form->right=list->right;
7196 form->bottom=list->bottom;
7199 /****************************************************************************
7200 ****************************************************************************/
7202 static WERROR fill_form_info_1(TALLOC_CTX *mem_ctx,
7203 struct spoolss_FormInfo1 *form,
7204 nt_forms_struct *list)
7206 form->form_name = talloc_strdup(mem_ctx, list->name);
7207 W_ERROR_HAVE_NO_MEMORY(form->form_name);
7209 form->flags = list->flag;
7210 form->size.width = list->width;
7211 form->size.height = list->length;
7212 form->area.left = list->left;
7213 form->area.top = list->top;
7214 form->area.right = list->right;
7215 form->area.bottom = list->bottom;
7220 /****************************************************************************
7221 ****************************************************************************/
7223 WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u)
7225 uint32 level = q_u->level;
7226 RPC_BUFFER *buffer = NULL;
7227 uint32 offered = q_u->offered;
7228 uint32 *needed = &r_u->needed;
7229 uint32 *numofforms = &r_u->numofforms;
7230 uint32 numbuiltinforms;
7232 nt_forms_struct *list=NULL;
7233 nt_forms_struct *builtinlist=NULL;
7238 /* that's an [in out] buffer */
7240 if (!q_u->buffer && (offered!=0) ) {
7241 return WERR_INVALID_PARAM;
7244 if (offered > MAX_RPC_DATA_SIZE) {
7245 return WERR_INVALID_PARAM;
7248 rpcbuf_move(q_u->buffer, &r_u->buffer);
7249 buffer = r_u->buffer;
7251 DEBUG(4,("_spoolss_enumforms\n"));
7252 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7253 DEBUGADD(5,("Info level [%d]\n", level));
7255 numbuiltinforms = get_builtin_ntforms(&builtinlist);
7256 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms));
7257 *numofforms = get_ntforms(&list);
7258 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms));
7259 *numofforms += numbuiltinforms;
7261 if (*numofforms == 0) {
7262 SAFE_FREE(builtinlist);
7264 return WERR_NO_MORE_ITEMS;
7269 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) {
7270 SAFE_FREE(builtinlist);
7276 /* construct the list of form structures */
7277 for (i=0; i<numbuiltinforms; i++) {
7278 DEBUGADD(6,("Filling form number [%d]\n",i));
7279 fill_form_1(&forms_1[i], &builtinlist[i]);
7282 SAFE_FREE(builtinlist);
7284 for (; i<*numofforms; i++) {
7285 DEBUGADD(6,("Filling form number [%d]\n",i));
7286 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]);
7291 /* check the required size. */
7292 for (i=0; i<numbuiltinforms; i++) {
7293 DEBUGADD(6,("adding form [%d]'s size\n",i));
7294 buffer_size += spoolss_size_form_1(&forms_1[i]);
7296 for (; i<*numofforms; i++) {
7297 DEBUGADD(6,("adding form [%d]'s size\n",i));
7298 buffer_size += spoolss_size_form_1(&forms_1[i]);
7301 *needed=buffer_size;
7303 if (*needed > offered) {
7306 return WERR_INSUFFICIENT_BUFFER;
7309 if (!rpcbuf_alloc_size(buffer, buffer_size)){
7315 /* fill the buffer with the form structures */
7316 for (i=0; i<numbuiltinforms; i++) {
7317 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7318 smb_io_form_1("", buffer, &forms_1[i], 0);
7320 for (; i<*numofforms; i++) {
7321 DEBUGADD(6,("adding form [%d] to buffer\n",i));
7322 smb_io_form_1("", buffer, &forms_1[i], 0);
7331 SAFE_FREE(builtinlist);
7332 return WERR_UNKNOWN_LEVEL;
7336 /****************************************************************
7338 ****************************************************************/
7340 WERROR _spoolss_GetForm(pipes_struct *p,
7341 struct spoolss_GetForm *r)
7343 uint32 level = r->in.level;
7344 uint32 offered = r->in.offered;
7345 uint32 *needed = r->out.needed;
7347 nt_forms_struct *list=NULL;
7348 nt_forms_struct builtin_form;
7350 union spoolss_FormInfo info;
7351 struct spoolss_FormInfo1 form_1;
7352 int numofforms=0, i=0;
7354 /* that's an [in out] buffer */
7356 if (!r->in.buffer && (offered!=0)) {
7357 return WERR_INVALID_PARAM;
7360 DEBUG(4,("_spoolss_GetForm\n"));
7361 DEBUGADD(5,("Offered buffer size [%d]\n", offered));
7362 DEBUGADD(5,("Info level [%d]\n", level));
7364 foundBuiltin = get_a_builtin_ntform_by_string(r->in.form_name, &builtin_form);
7365 if (!foundBuiltin) {
7366 numofforms = get_ntforms(&list);
7367 DEBUGADD(5,("Number of forms [%d]\n", numofforms));
7369 if (numofforms == 0)
7373 ZERO_STRUCT(form_1);
7378 fill_form_info_1(p->mem_ctx, &form_1, &builtin_form);
7381 /* Check if the requested name is in the list of form structures */
7382 for (i=0; i<numofforms; i++) {
7384 DEBUG(4,("_spoolss_GetForm: checking form %s (want %s)\n",
7385 list[i].name, r->in.form_name));
7387 if (strequal(r->in.form_name, list[i].name)) {
7388 DEBUGADD(6,("Found form %s number [%d]\n",
7389 r->in.form_name, i));
7390 fill_form_info_1(p->mem_ctx, &form_1, &list[i]);
7396 if (i == numofforms) {
7400 /* check the required size. */
7402 info.info1 = form_1;
7404 *needed = ndr_size_spoolss_FormInfo(&info, 1, NULL, 0);
7406 if (*needed > offered) {
7408 return WERR_INSUFFICIENT_BUFFER;
7411 r->out.info->info1 = form_1;
7413 /* fill the buffer with the form structures */
7414 DEBUGADD(6,("adding form %s [%d] to buffer\n",
7415 r->in.form_name, i));
7421 return WERR_UNKNOWN_LEVEL;
7425 /****************************************************************************
7426 ****************************************************************************/
7428 static void fill_port_1(PORT_INFO_1 *port, const char *name)
7430 init_unistr(&port->port_name, name);
7433 /****************************************************************************
7434 TODO: This probably needs distinguish between TCP/IP and Local ports
7436 ****************************************************************************/
7438 static void fill_port_2(PORT_INFO_2 *port, const char *name)
7440 init_unistr(&port->port_name, name);
7441 init_unistr(&port->monitor_name, "Local Monitor");
7442 init_unistr(&port->description, SPL_LOCAL_PORT );
7443 port->port_type=PORT_TYPE_WRITE;
7448 /****************************************************************************
7449 wrapper around the enumer ports command
7450 ****************************************************************************/
7452 WERROR enumports_hook(TALLOC_CTX *ctx, int *count, char ***lines )
7454 char *cmd = lp_enumports_cmd();
7455 char **qlines = NULL;
7456 char *command = NULL;
7464 /* if no hook then just fill in the default port */
7467 if (!(qlines = TALLOC_ARRAY( NULL, char*, 2 ))) {
7470 if (!(qlines[0] = talloc_strdup(qlines, SAMBA_PRINTER_PORT_NAME ))) {
7471 TALLOC_FREE(qlines);
7478 /* we have a valid enumport command */
7480 command = talloc_asprintf(ctx, "%s \"%d\"", cmd, 1);
7485 DEBUG(10,("Running [%s]\n", command));
7486 ret = smbrun(command, &fd);
7487 DEBUG(10,("Returned [%d]\n", ret));
7488 TALLOC_FREE(command);
7493 return WERR_ACCESS_DENIED;
7497 qlines = fd_lines_load(fd, &numlines, 0, NULL);
7498 DEBUGADD(10,("Lines returned = [%d]\n", numlines));
7508 /****************************************************************************
7510 ****************************************************************************/
7512 static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7514 PORT_INFO_1 *ports=NULL;
7516 WERROR result = WERR_OK;
7517 char **qlines = NULL;
7520 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7521 if (!W_ERROR_IS_OK(result)) {
7522 TALLOC_FREE(qlines);
7527 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) {
7528 DEBUG(10,("Returning WERR_NOMEM [%s]\n",
7529 win_errstr(WERR_NOMEM)));
7530 TALLOC_FREE(qlines);
7534 for (i=0; i<numlines; i++) {
7535 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7536 fill_port_1(&ports[i], qlines[i]);
7539 TALLOC_FREE(qlines);
7541 *returned = numlines;
7543 /* check the required size. */
7544 for (i=0; i<*returned; i++) {
7545 DEBUGADD(6,("adding port [%d]'s size\n", i));
7546 *needed += spoolss_size_port_info_1(&ports[i]);
7549 if (*needed > offered) {
7550 result = WERR_INSUFFICIENT_BUFFER;
7554 if (!rpcbuf_alloc_size(buffer, *needed)) {
7555 result = WERR_NOMEM;
7559 /* fill the buffer with the ports structures */
7560 for (i=0; i<*returned; i++) {
7561 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7562 smb_io_port_1("", buffer, &ports[i], 0);
7568 if ( !W_ERROR_IS_OK(result) )
7574 /****************************************************************************
7576 ****************************************************************************/
7578 static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
7580 PORT_INFO_2 *ports=NULL;
7582 WERROR result = WERR_OK;
7583 char **qlines = NULL;
7586 result = enumports_hook(talloc_tos(), &numlines, &qlines );
7587 if ( !W_ERROR_IS_OK(result)) {
7588 TALLOC_FREE(qlines);
7593 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) {
7594 TALLOC_FREE(qlines);
7598 for (i=0; i<numlines; i++) {
7599 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i]));
7600 fill_port_2(&(ports[i]), qlines[i]);
7604 TALLOC_FREE(qlines);
7606 *returned = numlines;
7608 /* check the required size. */
7609 for (i=0; i<*returned; i++) {
7610 DEBUGADD(6,("adding port [%d]'s size\n", i));
7611 *needed += spoolss_size_port_info_2(&ports[i]);
7614 if (*needed > offered) {
7615 result = WERR_INSUFFICIENT_BUFFER;
7619 if (!rpcbuf_alloc_size(buffer, *needed)) {
7620 result = WERR_NOMEM;
7624 /* fill the buffer with the ports structures */
7625 for (i=0; i<*returned; i++) {
7626 DEBUGADD(6,("adding port [%d] to buffer\n", i));
7627 smb_io_port_2("", buffer, &ports[i], 0);
7633 if ( !W_ERROR_IS_OK(result) )
7639 /****************************************************************************
7641 ****************************************************************************/
7643 WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u)
7645 uint32 level = q_u->level;
7646 RPC_BUFFER *buffer = NULL;
7647 uint32 offered = q_u->offered;
7648 uint32 *needed = &r_u->needed;
7649 uint32 *returned = &r_u->returned;
7651 /* that's an [in out] buffer */
7653 if (!q_u->buffer && (offered!=0)) {
7654 return WERR_INVALID_PARAM;
7657 if (offered > MAX_RPC_DATA_SIZE) {
7658 return WERR_INVALID_PARAM;
7661 rpcbuf_move(q_u->buffer, &r_u->buffer);
7662 buffer = r_u->buffer;
7664 DEBUG(4,("_spoolss_enumports\n"));
7671 return enumports_level_1(buffer, offered, needed, returned);
7673 return enumports_level_2(buffer, offered, needed, returned);
7675 return WERR_UNKNOWN_LEVEL;
7679 /****************************************************************************
7680 ****************************************************************************/
7682 static WERROR spoolss_addprinterex_level_2(pipes_struct *p,
7684 struct spoolss_SetPrinterInfoCtr *info_ctr,
7685 struct spoolss_DeviceMode *devmode,
7686 struct security_descriptor *sec_desc,
7687 struct spoolss_UserLevelCtr *user_ctr,
7690 NT_PRINTER_INFO_LEVEL *printer = NULL;
7693 WERROR err = WERR_OK;
7695 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
7696 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n"));
7700 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/
7701 if (!convert_printer_info_new(info_ctr, printer)) {
7702 free_a_printer(&printer, 2);
7706 /* check to see if the printer already exists */
7708 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) {
7709 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n",
7710 printer->info_2->sharename));
7711 free_a_printer(&printer, 2);
7712 return WERR_PRINTER_ALREADY_EXISTS;
7715 /* FIXME!!! smbd should check to see if the driver is installed before
7716 trying to add a printer like this --jerry */
7718 if (*lp_addprinter_cmd() ) {
7719 if ( !add_printer_hook(p->mem_ctx, p->server_info->ptok,
7721 free_a_printer(&printer,2);
7722 return WERR_ACCESS_DENIED;
7725 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no"
7726 "smb.conf parameter \"addprinter command\" is defined. This"
7727 "parameter must exist for this call to succeed\n",
7728 printer->info_2->sharename ));
7731 /* use our primary netbios name since get_a_printer() will convert
7732 it to what the client expects on a case by case basis */
7734 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(),
7735 printer->info_2->sharename);
7738 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) {
7739 free_a_printer(&printer,2);
7740 return WERR_ACCESS_DENIED;
7743 /* you must be a printer admin to add a new printer */
7744 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) {
7745 free_a_printer(&printer,2);
7746 return WERR_ACCESS_DENIED;
7750 * Do sanity check on the requested changes for Samba.
7753 if (!check_printer_ok(printer->info_2, snum)) {
7754 free_a_printer(&printer,2);
7755 return WERR_INVALID_PARAM;
7759 * When a printer is created, the drivername bound to the printer is used
7760 * to lookup previously saved driver initialization info, which is then
7761 * bound to the new printer, simulating what happens in the Windows arch.
7766 set_driver_init(printer, 2);
7770 /* A valid devmode was included, convert and link it
7772 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n"));
7774 if (!convert_devicemode_new(printer->info_2->printername,
7776 &printer->info_2->devmode))
7780 /* write the ASCII on disk */
7781 err = mod_a_printer(printer, 2);
7782 if (!W_ERROR_IS_OK(err)) {
7783 free_a_printer(&printer,2);
7787 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) {
7788 /* Handle open failed - remove addition. */
7789 del_a_printer(printer->info_2->sharename);
7790 free_a_printer(&printer,2);
7791 ZERO_STRUCTP(handle);
7792 return WERR_ACCESS_DENIED;
7795 update_c_setprinter(False);
7796 free_a_printer(&printer,2);
7801 /****************************************************************
7802 _spoolss_AddPrinterEx
7803 ****************************************************************/
7805 WERROR _spoolss_AddPrinterEx(pipes_struct *p,
7806 struct spoolss_AddPrinterEx *r)
7808 switch (r->in.info_ctr->level) {
7810 /* we don't handle yet */
7811 /* but I know what to do ... */
7812 return WERR_UNKNOWN_LEVEL;
7814 return spoolss_addprinterex_level_2(p, r->in.server,
7816 r->in.devmode_ctr->devmode,
7817 r->in.secdesc_ctr->sd,
7818 r->in.userlevel_ctr,
7821 return WERR_UNKNOWN_LEVEL;
7825 /****************************************************************
7826 _spoolss_AddPrinterDriver
7827 ****************************************************************/
7829 WERROR _spoolss_AddPrinterDriver(pipes_struct *p,
7830 struct spoolss_AddPrinterDriver *r)
7832 uint32_t level = r->in.info_ctr->level;
7833 struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr;
7834 WERROR err = WERR_OK;
7835 NT_PRINTER_DRIVER_INFO_LEVEL driver;
7836 fstring driver_name;
7840 switch (p->hdr_req.opnum) {
7841 case NDR_SPOOLSS_ADDPRINTERDRIVER:
7842 fn = "_spoolss_AddPrinterDriver";
7844 case NDR_SPOOLSS_ADDPRINTERDRIVEREX:
7845 fn = "_spoolss_AddPrinterDriverEx";
7848 return WERR_INVALID_PARAM;
7853 if (level != 3 && level != 6) {
7854 /* Clever hack from Martin Zielinski <mz@seh.de>
7855 * to allow downgrade from level 8 (Vista).
7857 DEBUG(0,("%s: level %d not yet implemented\n", fn, level));
7858 return WERR_UNKNOWN_LEVEL;
7861 ZERO_STRUCT(driver);
7863 if (!convert_printer_driver_info(info, &driver, level)) {
7868 DEBUG(5,("Cleaning driver's information\n"));
7869 err = clean_up_driver_struct(p, driver, level);
7870 if (!W_ERROR_IS_OK(err))
7873 DEBUG(5,("Moving driver to final destination\n"));
7874 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(p, driver, level,
7879 if (add_a_printer_driver(driver, level)!=0) {
7880 err = WERR_ACCESS_DENIED;
7886 fstrcpy(driver_name,
7887 driver.info_3->name ? driver.info_3->name : "");
7890 fstrcpy(driver_name,
7891 driver.info_6->name ? driver.info_6->name : "");
7896 * I think this is where he DrvUpgradePrinter() hook would be
7897 * be called in a driver's interface DLL on a Windows NT 4.0/2k
7898 * server. Right now, we just need to send ourselves a message
7899 * to update each printer bound to this driver. --jerry
7902 if (!srv_spoolss_drv_upgrade_printer(driver_name)) {
7903 DEBUG(0,("%s: Failed to send message about upgrading driver [%s]!\n",
7908 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp),
7909 * decide if the driver init data should be deleted. The rules are:
7910 * 1) never delete init data if it is a 9x driver, they don't use it anyway
7911 * 2) delete init data only if there is no 2k/Xp driver
7912 * 3) always delete init data
7913 * The generalized rule is always use init data from the highest order driver.
7914 * It is necessary to follow the driver install by an initialization step to
7915 * finish off this process.
7918 version = driver.info_3->cversion;
7919 else if (level == 6)
7920 version = driver.info_6->version;
7925 * 9x printer driver - never delete init data
7928 DEBUG(10,("%s: init data not deleted for 9x driver [%s]\n",
7933 * Nt or 2k (compatiblity mode) printer driver - only delete init data if
7934 * there is no 2k/Xp driver init data for this driver name.
7938 NT_PRINTER_DRIVER_INFO_LEVEL driver1;
7940 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) {
7942 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver.
7944 if (!del_driver_init(driver_name))
7945 DEBUG(6,("%s: del_driver_init(%s) Nt failed!\n",
7949 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it.
7951 free_a_printer_driver(driver1,3);
7952 DEBUG(10,("%s: init data not deleted for Nt driver [%s]\n",
7959 * 2k or Xp printer driver - always delete init data
7962 if (!del_driver_init(driver_name))
7963 DEBUG(6,("%s: del_driver_init(%s) 2k/Xp failed!\n",
7968 DEBUG(0,("%s: invalid level=%d\n", fn, level));
7974 free_a_printer_driver(driver, level);
7978 /****************************************************************
7979 _spoolss_AddPrinterDriverEx
7980 ****************************************************************/
7982 WERROR _spoolss_AddPrinterDriverEx(pipes_struct *p,
7983 struct spoolss_AddPrinterDriverEx *r)
7985 struct spoolss_AddPrinterDriver a;
7988 * we only support the semantics of AddPrinterDriver()
7989 * i.e. only copy files that are newer than existing ones
7992 if (r->in.flags != APD_COPY_NEW_FILES) {
7993 return WERR_ACCESS_DENIED;
7996 a.in.servername = r->in.servername;
7997 a.in.info_ctr = r->in.info_ctr;
7999 return _spoolss_AddPrinterDriver(p, &a);
8002 /****************************************************************************
8003 ****************************************************************************/
8005 static WERROR getprinterdriverdir_level_1(TALLOC_CTX *mem_ctx,
8006 const char *servername,
8007 const char *environment,
8008 struct spoolss_DriverDirectoryInfo1 *info1,
8013 const char *pservername = NULL;
8014 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
8015 const char *short_archi;
8018 long_archi = environment;
8021 pservername = canon_servername(servername);
8023 if ( !is_myname_or_ipaddr(pservername))
8024 return WERR_INVALID_PARAM;
8026 if (!(short_archi = get_short_archi(long_archi)))
8027 return WERR_INVALID_ENVIRONMENT;
8029 path = talloc_asprintf(mem_ctx,
8030 "\\\\%s\\print$\\%s", pservername, short_archi);
8035 DEBUG(4,("printer driver directory: [%s]\n", path));
8037 info1->directory_name = path;
8039 *needed += ndr_size_spoolss_DriverDirectoryInfo1(info1, NULL, 0);
8041 if (*needed > offered) {
8043 ZERO_STRUCTP(info1);
8044 return WERR_INSUFFICIENT_BUFFER;
8050 /****************************************************************
8051 _spoolss_GetPrinterDriverDirectory
8052 ****************************************************************/
8054 WERROR _spoolss_GetPrinterDriverDirectory(pipes_struct *p,
8055 struct spoolss_GetPrinterDriverDirectory *r)
8059 /* that's an [in out] buffer */
8061 if (!r->in.buffer && (r->in.offered != 0)) {
8062 return WERR_INVALID_PARAM;
8065 if (r->in.offered > MAX_RPC_DATA_SIZE) {
8066 return WERR_INVALID_PARAM;
8069 DEBUG(4,("_spoolss_GetPrinterDriverDirectory\n"));
8073 switch (r->in.level) {
8075 werror = getprinterdriverdir_level_1(p->mem_ctx,
8078 &r->out.info->info1,
8081 if (!W_ERROR_IS_OK(werror)) {
8082 TALLOC_FREE(r->out.info);
8086 return WERR_UNKNOWN_LEVEL;
8092 /****************************************************************************
8093 ****************************************************************************/
8095 WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u)
8097 POLICY_HND *handle = &q_u->handle;
8098 uint32 idx = q_u->index;
8099 uint32 in_value_len = q_u->valuesize;
8100 uint32 in_data_len = q_u->datasize;
8101 uint32 *out_max_value_len = &r_u->valuesize;
8102 uint16 **out_value = &r_u->value;
8103 uint32 *out_value_len = &r_u->realvaluesize;
8104 uint32 *out_type = &r_u->type;
8105 uint32 *out_max_data_len = &r_u->datasize;
8106 uint8 **data_out = &r_u->data;
8107 uint32 *out_data_len = &r_u->realdatasize;
8109 NT_PRINTER_INFO_LEVEL *printer = NULL;
8111 uint32 biggest_valuesize;
8112 uint32 biggest_datasize;
8114 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8117 REGISTRY_VALUE *val = NULL;
8118 NT_PRINTER_DATA *p_data;
8119 int i, key_index, num_values;
8124 *out_max_data_len = 0;
8128 DEBUG(5,("spoolss_enumprinterdata\n"));
8131 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8135 if (!get_printer_snum(p,handle, &snum, NULL))
8138 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8139 if (!W_ERROR_IS_OK(result))
8142 p_data = printer->info_2->data;
8143 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY );
8148 * The NT machine wants to know the biggest size of value and data
8150 * cf: MSDN EnumPrinterData remark section
8153 if ( !in_value_len && !in_data_len && (key_index != -1) )
8155 DEBUGADD(6,("Activating NT mega-hack to find sizes\n"));
8157 biggest_valuesize = 0;
8158 biggest_datasize = 0;
8160 num_values = regval_ctr_numvals( p_data->keys[key_index].values );
8162 for ( i=0; i<num_values; i++ )
8164 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
8166 name_length = strlen(val->valuename);
8167 if ( strlen(val->valuename) > biggest_valuesize )
8168 biggest_valuesize = name_length;
8170 if ( val->size > biggest_datasize )
8171 biggest_datasize = val->size;
8173 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize,
8177 /* the value is an UNICODE string but real_value_size is the length
8178 in bytes including the trailing 0 */
8180 *out_value_len = 2 * (1+biggest_valuesize);
8181 *out_data_len = biggest_datasize;
8183 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len));
8189 * the value len is wrong in NT sp3
8190 * that's the number of bytes not the number of unicode chars
8193 if ( key_index != -1 )
8194 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx );
8199 /* out_value should default to "" or else NT4 has
8200 problems unmarshalling the response */
8202 *out_max_value_len=(in_value_len/sizeof(uint16));
8205 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL)
8207 result = WERR_NOMEM;
8210 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0);
8216 /* the data is counted in bytes */
8218 *out_max_data_len = in_data_len;
8219 *out_data_len = in_data_len;
8221 /* only allocate when given a non-zero data_len */
8223 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) )
8225 result = WERR_NOMEM;
8229 result = WERR_NO_MORE_ITEMS;
8235 * - counted in bytes in the request
8236 * - counted in UNICODE chars in the max reply
8237 * - counted in bytes in the real size
8239 * take a pause *before* coding not *during* coding
8243 *out_max_value_len=(in_value_len/sizeof(uint16));
8245 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL )
8247 result = WERR_NOMEM;
8251 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0);
8259 *out_type = regval_type( val );
8261 /* data - counted in bytes */
8263 *out_max_data_len = in_data_len;
8264 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL)
8266 result = WERR_NOMEM;
8269 data_len = regval_size(val);
8270 if ( *data_out && data_len )
8271 memcpy( *data_out, regval_data_p(val), data_len );
8272 *out_data_len = data_len;
8276 free_a_printer(&printer, 2);
8280 /****************************************************************************
8281 ****************************************************************************/
8283 WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u)
8285 POLICY_HND *handle = &q_u->handle;
8286 UNISTR2 *value = &q_u->value;
8287 uint32 type = q_u->type;
8288 uint8 *data = q_u->data;
8289 uint32 real_len = q_u->real_len;
8291 NT_PRINTER_INFO_LEVEL *printer = NULL;
8293 WERROR status = WERR_OK;
8294 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8297 DEBUG(5,("spoolss_setprinterdata\n"));
8300 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
8304 if ( Printer->printer_type == SPLHND_SERVER ) {
8305 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n"));
8306 return WERR_INVALID_PARAM;
8309 if (!get_printer_snum(p,handle, &snum, NULL))
8313 * Access check : NT returns "access denied" if you make a
8314 * SetPrinterData call without the necessary privildge.
8315 * we were originally returning OK if nothing changed
8316 * which made Win2k issue **a lot** of SetPrinterData
8317 * when connecting to a printer --jerry
8320 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
8322 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n"));
8323 status = WERR_ACCESS_DENIED;
8327 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8328 if (!W_ERROR_IS_OK(status))
8331 unistr2_to_ascii(valuename, value, sizeof(valuename));
8334 * When client side code sets a magic printer data key, detect it and save
8335 * the current printer data and the magic key's data (its the DEVMODE) for
8336 * future printer/driver initializations.
8338 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY))
8340 /* Set devmode and printer initialization info */
8341 status = save_driver_init( printer, 2, data, real_len );
8343 srv_spoolss_reset_printerdata( printer->info_2->drivername );
8347 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename,
8348 type, data, real_len );
8349 if ( W_ERROR_IS_OK(status) )
8350 status = mod_a_printer(printer, 2);
8354 free_a_printer(&printer, 2);
8359 /****************************************************************
8360 _spoolss_ResetPrinter
8361 ****************************************************************/
8363 WERROR _spoolss_ResetPrinter(pipes_struct *p,
8364 struct spoolss_ResetPrinter *r)
8366 POLICY_HND *handle = r->in.handle;
8367 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8370 DEBUG(5,("_spoolss_ResetPrinter\n"));
8373 * All we do is to check to see if the handle and queue is valid.
8374 * This call really doesn't mean anything to us because we only
8375 * support RAW printing. --jerry
8379 DEBUG(2,("_spoolss_ResetPrinter: Invalid handle (%s:%u:%u).\n",
8380 OUR_HANDLE(handle)));
8384 if (!get_printer_snum(p,handle, &snum, NULL))
8388 /* blindly return success */
8392 /****************************************************************
8393 _spoolss_DeletePrinterData
8394 ****************************************************************/
8396 WERROR _spoolss_DeletePrinterData(pipes_struct *p,
8397 struct spoolss_DeletePrinterData *r)
8399 POLICY_HND *handle = r->in.handle;
8400 NT_PRINTER_INFO_LEVEL *printer = NULL;
8402 WERROR status = WERR_OK;
8403 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
8405 DEBUG(5,("_spoolss_DeletePrinterData\n"));
8408 DEBUG(2,("_spoolss_DeletePrinterData: Invalid handle (%s:%u:%u).\n",
8409 OUR_HANDLE(handle)));
8413 if (!get_printer_snum(p, handle, &snum, NULL))
8416 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
8417 DEBUG(3, ("_spoolss_DeletePrinterData: "
8418 "printer properties change denied by handle\n"));
8419 return WERR_ACCESS_DENIED;
8422 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8423 if (!W_ERROR_IS_OK(status))
8426 if (!r->in.value_name) {
8427 free_a_printer(&printer, 2);
8431 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY,
8434 if ( W_ERROR_IS_OK(status) )
8435 mod_a_printer( printer, 2 );
8437 free_a_printer(&printer, 2);
8442 /****************************************************************
8444 ****************************************************************/
8446 WERROR _spoolss_AddForm(pipes_struct *p,
8447 struct spoolss_AddForm *r)
8449 POLICY_HND *handle = r->in.handle;
8450 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8451 nt_forms_struct tmpForm;
8453 WERROR status = WERR_OK;
8454 NT_PRINTER_INFO_LEVEL *printer = NULL;
8457 nt_forms_struct *list=NULL;
8458 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8460 DEBUG(5,("_spoolss_AddForm\n"));
8463 DEBUG(2,("_spoolss_AddForm: Invalid handle (%s:%u:%u).\n",
8464 OUR_HANDLE(handle)));
8469 /* forms can be added on printer of on the print server handle */
8471 if ( Printer->printer_type == SPLHND_PRINTER )
8473 if (!get_printer_snum(p,handle, &snum, NULL))
8476 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8477 if (!W_ERROR_IS_OK(status))
8481 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8482 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n"));
8483 status = WERR_ACCESS_DENIED;
8487 /* can't add if builtin */
8489 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8490 status = WERR_FILE_EXISTS;
8494 count = get_ntforms(&list);
8496 if(!add_a_form(&list, form, &count)) {
8497 status = WERR_NOMEM;
8501 write_ntforms(&list, count);
8504 * ChangeID must always be set if this is a printer
8507 if ( Printer->printer_type == SPLHND_PRINTER )
8508 status = mod_a_printer(printer, 2);
8512 free_a_printer(&printer, 2);
8518 /****************************************************************
8520 ****************************************************************/
8522 WERROR _spoolss_DeleteForm(pipes_struct *p,
8523 struct spoolss_DeleteForm *r)
8525 POLICY_HND *handle = r->in.handle;
8526 const char *form_name = r->in.form_name;
8527 nt_forms_struct tmpForm;
8529 nt_forms_struct *list=NULL;
8530 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8532 WERROR status = WERR_OK;
8533 NT_PRINTER_INFO_LEVEL *printer = NULL;
8535 DEBUG(5,("_spoolss_DeleteForm\n"));
8538 DEBUG(2,("_spoolss_DeleteForm: Invalid handle (%s:%u:%u).\n",
8539 OUR_HANDLE(handle)));
8543 /* forms can be deleted on printer of on the print server handle */
8545 if ( Printer->printer_type == SPLHND_PRINTER )
8547 if (!get_printer_snum(p,handle, &snum, NULL))
8550 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8551 if (!W_ERROR_IS_OK(status))
8555 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8556 DEBUG(2,("_spoolss_DeleteForm: denied by handle permissions.\n"));
8557 status = WERR_ACCESS_DENIED;
8561 /* can't delete if builtin */
8563 if (get_a_builtin_ntform_by_string(form_name,&tmpForm)) {
8564 status = WERR_INVALID_PARAM;
8568 count = get_ntforms(&list);
8570 if ( !delete_a_form(&list, form_name, &count, &status ))
8574 * ChangeID must always be set if this is a printer
8577 if ( Printer->printer_type == SPLHND_PRINTER )
8578 status = mod_a_printer(printer, 2);
8582 free_a_printer(&printer, 2);
8588 /****************************************************************
8590 ****************************************************************/
8592 WERROR _spoolss_SetForm(pipes_struct *p,
8593 struct spoolss_SetForm *r)
8595 POLICY_HND *handle = r->in.handle;
8596 struct spoolss_AddFormInfo1 *form = r->in.info.info1;
8597 nt_forms_struct tmpForm;
8599 WERROR status = WERR_OK;
8600 NT_PRINTER_INFO_LEVEL *printer = NULL;
8603 nt_forms_struct *list=NULL;
8604 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
8606 DEBUG(5,("_spoolss_SetForm\n"));
8609 DEBUG(2,("_spoolss_SetForm: Invalid handle (%s:%u:%u).\n",
8610 OUR_HANDLE(handle)));
8614 /* forms can be modified on printer of on the print server handle */
8616 if ( Printer->printer_type == SPLHND_PRINTER )
8618 if (!get_printer_snum(p,handle, &snum, NULL))
8621 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
8622 if (!W_ERROR_IS_OK(status))
8626 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) {
8627 DEBUG(2,("_spoolss_SetForm: denied by handle permissions\n"));
8628 status = WERR_ACCESS_DENIED;
8632 /* can't set if builtin */
8633 if (get_a_builtin_ntform_by_string(form->form_name, &tmpForm)) {
8634 status = WERR_INVALID_PARAM;
8638 count = get_ntforms(&list);
8639 update_a_form(&list, form, count);
8640 write_ntforms(&list, count);
8643 * ChangeID must always be set if this is a printer
8646 if ( Printer->printer_type == SPLHND_PRINTER )
8647 status = mod_a_printer(printer, 2);
8652 free_a_printer(&printer, 2);
8658 /****************************************************************************
8659 enumprintprocessors level 1.
8660 ****************************************************************************/
8662 static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8664 PRINTPROCESSOR_1 *info_1=NULL;
8665 WERROR result = WERR_OK;
8667 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL)
8672 init_unistr(&info_1->name, "winprint");
8674 *needed += spoolss_size_printprocessor_info_1(info_1);
8676 if (*needed > offered) {
8677 result = WERR_INSUFFICIENT_BUFFER;
8681 if (!rpcbuf_alloc_size(buffer, *needed)) {
8682 result = WERR_NOMEM;
8686 smb_io_printprocessor_info_1("", buffer, info_1, 0);
8691 if ( !W_ERROR_IS_OK(result) )
8697 /****************************************************************************
8698 ****************************************************************************/
8700 WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u)
8702 uint32 level = q_u->level;
8703 RPC_BUFFER *buffer = NULL;
8704 uint32 offered = q_u->offered;
8705 uint32 *needed = &r_u->needed;
8706 uint32 *returned = &r_u->returned;
8708 /* that's an [in out] buffer */
8710 if (!q_u->buffer && (offered!=0)) {
8711 return WERR_INVALID_PARAM;
8714 if (offered > MAX_RPC_DATA_SIZE) {
8715 return WERR_INVALID_PARAM;
8718 rpcbuf_move(q_u->buffer, &r_u->buffer);
8719 buffer = r_u->buffer;
8721 DEBUG(5,("spoolss_enumprintprocessors\n"));
8724 * Enumerate the print processors ...
8726 * Just reply with "winprint", to keep NT happy
8727 * and I can use my nice printer checker.
8735 return enumprintprocessors_level_1(buffer, offered, needed, returned);
8737 return WERR_UNKNOWN_LEVEL;
8741 /****************************************************************************
8742 enumprintprocdatatypes level 1.
8743 ****************************************************************************/
8745 static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8747 PRINTPROCDATATYPE_1 *info_1=NULL;
8748 WERROR result = WERR_OK;
8750 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL)
8755 init_unistr(&info_1->name, "RAW");
8757 *needed += spoolss_size_printprocdatatype_info_1(info_1);
8759 if (*needed > offered) {
8760 result = WERR_INSUFFICIENT_BUFFER;
8764 if (!rpcbuf_alloc_size(buffer, *needed)) {
8765 result = WERR_NOMEM;
8769 smb_io_printprocdatatype_info_1("", buffer, info_1, 0);
8774 if ( !W_ERROR_IS_OK(result) )
8780 /****************************************************************************
8781 ****************************************************************************/
8783 WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u)
8785 uint32 level = q_u->level;
8786 RPC_BUFFER *buffer = NULL;
8787 uint32 offered = q_u->offered;
8788 uint32 *needed = &r_u->needed;
8789 uint32 *returned = &r_u->returned;
8791 /* that's an [in out] buffer */
8793 if (!q_u->buffer && (offered!=0)) {
8794 return WERR_INVALID_PARAM;
8797 if (offered > MAX_RPC_DATA_SIZE) {
8798 return WERR_INVALID_PARAM;
8801 rpcbuf_move(q_u->buffer, &r_u->buffer);
8802 buffer = r_u->buffer;
8804 DEBUG(5,("_spoolss_enumprintprocdatatypes\n"));
8811 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned);
8813 return WERR_UNKNOWN_LEVEL;
8817 /****************************************************************************
8818 enumprintmonitors level 1.
8819 ****************************************************************************/
8821 static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8823 PRINTMONITOR_1 *info_1;
8824 WERROR result = WERR_OK;
8827 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL)
8832 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT );
8833 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT );
8835 for ( i=0; i<*returned; i++ ) {
8836 *needed += spoolss_size_printmonitor_info_1(&info_1[i]);
8839 if (*needed > offered) {
8840 result = WERR_INSUFFICIENT_BUFFER;
8844 if (!rpcbuf_alloc_size(buffer, *needed)) {
8845 result = WERR_NOMEM;
8849 for ( i=0; i<*returned; i++ ) {
8850 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0);
8856 if ( !W_ERROR_IS_OK(result) )
8862 /****************************************************************************
8863 enumprintmonitors level 2.
8864 ****************************************************************************/
8866 static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
8868 PRINTMONITOR_2 *info_2;
8869 WERROR result = WERR_OK;
8872 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL)
8877 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT );
8878 init_unistr( &(info_2[0].environment), "Windows NT X86" );
8879 init_unistr( &(info_2[0].dll_name), "localmon.dll" );
8881 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT );
8882 init_unistr( &(info_2[1].environment), "Windows NT X86" );
8883 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" );
8885 for ( i=0; i<*returned; i++ ) {
8886 *needed += spoolss_size_printmonitor_info_2(&info_2[i]);
8889 if (*needed > offered) {
8890 result = WERR_INSUFFICIENT_BUFFER;
8894 if (!rpcbuf_alloc_size(buffer, *needed)) {
8895 result = WERR_NOMEM;
8899 for ( i=0; i<*returned; i++ ) {
8900 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0);
8906 if ( !W_ERROR_IS_OK(result) )
8912 /****************************************************************************
8913 ****************************************************************************/
8915 WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u)
8917 uint32 level = q_u->level;
8918 RPC_BUFFER *buffer = NULL;
8919 uint32 offered = q_u->offered;
8920 uint32 *needed = &r_u->needed;
8921 uint32 *returned = &r_u->returned;
8923 /* that's an [in out] buffer */
8925 if (!q_u->buffer && (offered!=0)) {
8926 return WERR_INVALID_PARAM;
8929 if (offered > MAX_RPC_DATA_SIZE) {
8930 return WERR_INVALID_PARAM;
8933 rpcbuf_move(q_u->buffer, &r_u->buffer);
8934 buffer = r_u->buffer;
8936 DEBUG(5,("spoolss_enumprintmonitors\n"));
8939 * Enumerate the print monitors ...
8941 * Just reply with "Local Port", to keep NT happy
8942 * and I can use my nice printer checker.
8950 return enumprintmonitors_level_1(buffer, offered, needed, returned);
8952 return enumprintmonitors_level_2(buffer, offered, needed, returned);
8954 return WERR_UNKNOWN_LEVEL;
8958 /****************************************************************************
8959 ****************************************************************************/
8961 static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum,
8962 NT_PRINTER_INFO_LEVEL *ntprinter,
8963 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
8968 JOB_INFO_1 *info_1=NULL;
8969 WERROR result = WERR_OK;
8971 info_1=SMB_MALLOC_P(JOB_INFO_1);
8973 if (info_1 == NULL) {
8977 for (i=0; i<count && found==False; i++) {
8978 if ((*queue)[i].job==(int)jobid)
8984 /* NT treats not found as bad param... yet another bad choice */
8985 return WERR_INVALID_PARAM;
8988 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter );
8990 *needed += spoolss_size_job_info_1(info_1);
8992 if (*needed > offered) {
8993 result = WERR_INSUFFICIENT_BUFFER;
8997 if (!rpcbuf_alloc_size(buffer, *needed)) {
8998 result = WERR_NOMEM;
9002 smb_io_job_info_1("", buffer, info_1, 0);
9010 /****************************************************************************
9011 ****************************************************************************/
9013 static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum,
9014 NT_PRINTER_INFO_LEVEL *ntprinter,
9015 uint32 jobid, RPC_BUFFER *buffer, uint32 offered,
9022 DEVICEMODE *devmode = NULL;
9023 NT_DEVICEMODE *nt_devmode = NULL;
9025 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) )
9028 ZERO_STRUCTP(info_2);
9030 for ( i=0; i<count && found==False; i++ )
9032 if ((*queue)[i].job == (int)jobid)
9037 /* NT treats not found as bad param... yet another bad
9039 result = WERR_INVALID_PARAM;
9044 * if the print job does not have a DEVMODE associated with it,
9045 * just use the one for the printer. A NULL devicemode is not
9046 * a failure condition
9049 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) )
9050 devmode = construct_dev_mode(lp_const_servicename(snum));
9052 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) {
9053 ZERO_STRUCTP( devmode );
9054 convert_nt_devicemode( devmode, nt_devmode );
9058 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode);
9060 *needed += spoolss_size_job_info_2(info_2);
9062 if (*needed > offered) {
9063 result = WERR_INSUFFICIENT_BUFFER;
9067 if (!rpcbuf_alloc_size(buffer, *needed)) {
9068 result = WERR_NOMEM;
9072 smb_io_job_info_2("", buffer, info_2, 0);
9077 /* Cleanup allocated memory */
9079 free_job_info_2(info_2); /* Also frees devmode */
9085 /****************************************************************************
9086 ****************************************************************************/
9088 WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u)
9090 POLICY_HND *handle = &q_u->handle;
9091 uint32 jobid = q_u->jobid;
9092 uint32 level = q_u->level;
9093 RPC_BUFFER *buffer = NULL;
9094 uint32 offered = q_u->offered;
9095 uint32 *needed = &r_u->needed;
9096 WERROR wstatus = WERR_OK;
9097 NT_PRINTER_INFO_LEVEL *ntprinter = NULL;
9100 print_queue_struct *queue = NULL;
9101 print_status_struct prt_status;
9103 /* that's an [in out] buffer */
9105 if (!q_u->buffer && (offered!=0)) {
9106 return WERR_INVALID_PARAM;
9109 if (offered > MAX_RPC_DATA_SIZE) {
9110 return WERR_INVALID_PARAM;
9113 rpcbuf_move(q_u->buffer, &r_u->buffer);
9114 buffer = r_u->buffer;
9116 DEBUG(5,("spoolss_getjob\n"));
9120 if (!get_printer_snum(p, handle, &snum, NULL))
9123 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum));
9124 if ( !W_ERROR_IS_OK(wstatus) )
9127 count = print_queue_status(snum, &queue, &prt_status);
9129 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n",
9130 count, prt_status.status, prt_status.message));
9134 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid,
9135 buffer, offered, needed);
9138 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid,
9139 buffer, offered, needed);
9142 wstatus = WERR_UNKNOWN_LEVEL;
9147 free_a_printer( &ntprinter, 2 );
9152 /****************************************************************
9153 _spoolss_GetPrinterDataEx
9155 From MSDN documentation of GetPrinterDataEx: pass request
9156 to GetPrinterData if key is "PrinterDriverData".
9157 ****************************************************************/
9159 WERROR _spoolss_GetPrinterDataEx(pipes_struct *p,
9160 struct spoolss_GetPrinterDataEx *r)
9162 POLICY_HND *handle = r->in.handle;
9164 const char *keyname = r->in.key_name;
9165 const char *valuename = r->in.value_name;
9167 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9169 NT_PRINTER_INFO_LEVEL *printer = NULL;
9171 WERROR status = WERR_OK;
9173 DEBUG(4,("_spoolss_GetPrinterDataEx\n"));
9175 DEBUG(10, ("_spoolss_GetPrinterDataEx: key => [%s], value => [%s]\n",
9176 keyname, valuename));
9178 /* in case of problem, return some default values */
9184 DEBUG(2,("_spoolss_GetPrinterDataEx: "
9185 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9186 status = WERR_BADFID;
9190 /* Is the handle to a printer or to the server? */
9192 if (Printer->printer_type == SPLHND_SERVER) {
9193 DEBUG(10,("_spoolss_GetPrinterDataEx: "
9194 "Not implemented for server handles yet\n"));
9195 status = WERR_INVALID_PARAM;
9199 if ( !get_printer_snum(p,handle, &snum, NULL) )
9202 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9203 if ( !W_ERROR_IS_OK(status) )
9206 /* check to see if the keyname is valid */
9207 if ( !strlen(keyname) ) {
9208 status = WERR_INVALID_PARAM;
9212 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) {
9213 DEBUG(4,("_spoolss_GetPrinterDataEx: "
9214 "Invalid keyname [%s]\n", keyname ));
9215 free_a_printer( &printer, 2 );
9216 status = WERR_BADFILE;
9220 /* When given a new keyname, we should just create it */
9222 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename,
9223 r->out.type, &data, r->out.needed,
9226 if (*r->out.needed > r->in.offered) {
9227 status = WERR_MORE_DATA;
9230 if (W_ERROR_IS_OK(status)) {
9231 memcpy(r->out.buffer, data, r->in.offered);
9236 free_a_printer( &printer, 2 );
9241 /****************************************************************
9242 _spoolss_SetPrinterDataEx
9243 ****************************************************************/
9245 WERROR _spoolss_SetPrinterDataEx(pipes_struct *p,
9246 struct spoolss_SetPrinterDataEx *r)
9248 POLICY_HND *handle = r->in.handle;
9249 NT_PRINTER_INFO_LEVEL *printer = NULL;
9251 WERROR status = WERR_OK;
9252 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9255 DEBUG(4,("_spoolss_SetPrinterDataEx\n"));
9257 /* From MSDN documentation of SetPrinterDataEx: pass request to
9258 SetPrinterData if key is "PrinterDriverData" */
9261 DEBUG(2,("_spoolss_SetPrinterDataEx: "
9262 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9266 if ( Printer->printer_type == SPLHND_SERVER ) {
9267 DEBUG(10,("_spoolss_SetPrinterDataEx: "
9268 "Not implemented for server handles yet\n"));
9269 return WERR_INVALID_PARAM;
9272 if ( !get_printer_snum(p,handle, &snum, NULL) )
9276 * Access check : NT returns "access denied" if you make a
9277 * SetPrinterData call without the necessary privildge.
9278 * we were originally returning OK if nothing changed
9279 * which made Win2k issue **a lot** of SetPrinterData
9280 * when connecting to a printer --jerry
9283 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER)
9285 DEBUG(3, ("_spoolss_SetPrinterDataEx: "
9286 "change denied by handle access permissions\n"));
9287 return WERR_ACCESS_DENIED;
9290 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum));
9291 if (!W_ERROR_IS_OK(status))
9294 /* check for OID in valuename */
9296 if ( (oid_string = strchr( r->in.value_name, ',' )) != NULL )
9302 /* save the registry data */
9304 status = set_printer_dataex( printer, r->in.key_name, r->in.value_name,
9305 r->in.type, r->in.buffer, r->in.offered );
9307 if ( W_ERROR_IS_OK(status) )
9309 /* save the OID if one was specified */
9311 char *str = talloc_asprintf(p->mem_ctx, "%s\\%s",
9312 r->in.key_name, SPOOL_OID_KEY);
9318 * I'm not checking the status here on purpose. Don't know
9319 * if this is right, but I'm returning the status from the
9320 * previous set_printer_dataex() call. I have no idea if
9321 * this is right. --jerry
9324 set_printer_dataex( printer, str, r->in.value_name,
9325 REG_SZ, (uint8 *)oid_string,
9326 strlen(oid_string)+1 );
9329 status = mod_a_printer(printer, 2);
9332 free_a_printer(&printer, 2);
9337 /****************************************************************
9338 _spoolss_DeletePrinterDataEx
9339 ****************************************************************/
9341 WERROR _spoolss_DeletePrinterDataEx(pipes_struct *p,
9342 struct spoolss_DeletePrinterDataEx *r)
9344 POLICY_HND *handle = r->in.handle;
9345 NT_PRINTER_INFO_LEVEL *printer = NULL;
9347 WERROR status = WERR_OK;
9348 Printer_entry *Printer=find_printer_index_by_hnd(p, handle);
9350 DEBUG(5,("_spoolss_DeletePrinterDataEx\n"));
9353 DEBUG(2,("_spoolss_DeletePrinterDataEx: "
9354 "Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9358 if (!get_printer_snum(p, handle, &snum, NULL))
9361 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9362 DEBUG(3, ("_spoolss_DeletePrinterDataEx: "
9363 "printer properties change denied by handle\n"));
9364 return WERR_ACCESS_DENIED;
9367 if (!r->in.value_name || !r->in.key_name) {
9371 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9372 if (!W_ERROR_IS_OK(status))
9375 status = delete_printer_dataex( printer, r->in.key_name, r->in.value_name );
9377 if ( W_ERROR_IS_OK(status) )
9378 mod_a_printer( printer, 2 );
9380 free_a_printer(&printer, 2);
9385 /********************************************************************
9386 * spoolss_enumprinterkey
9387 ********************************************************************/
9390 WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u)
9393 fstring *keynames = NULL;
9394 uint16 *enumkeys = NULL;
9397 POLICY_HND *handle = &q_u->handle;
9398 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9399 NT_PRINTER_DATA *data;
9400 NT_PRINTER_INFO_LEVEL *printer = NULL;
9402 WERROR status = WERR_BADFILE;
9405 DEBUG(4,("_spoolss_enumprinterkey\n"));
9408 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle)));
9412 if ( !get_printer_snum(p,handle, &snum, NULL) )
9415 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9416 if (!W_ERROR_IS_OK(status))
9419 /* get the list of subkey names */
9421 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9422 data = printer->info_2->data;
9424 num_keys = get_printer_subkeys( data, key, &keynames );
9426 if ( num_keys == -1 ) {
9427 status = WERR_BADFILE;
9431 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL );
9433 r_u->needed = printerkey_len*2;
9435 if ( q_u->size < r_u->needed ) {
9436 status = WERR_MORE_DATA;
9440 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) {
9441 status = WERR_NOMEM;
9447 if ( q_u->size < r_u->needed )
9448 status = WERR_MORE_DATA;
9451 free_a_printer( &printer, 2 );
9452 SAFE_FREE( keynames );
9457 /****************************************************************
9458 _spoolss_DeletePrinterKey
9459 ****************************************************************/
9461 WERROR _spoolss_DeletePrinterKey(pipes_struct *p,
9462 struct spoolss_DeletePrinterKey *r)
9464 POLICY_HND *handle = r->in.handle;
9465 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9466 NT_PRINTER_INFO_LEVEL *printer = NULL;
9470 DEBUG(5,("_spoolss_DeletePrinterKey\n"));
9473 DEBUG(2,("_spoolss_DeletePrinterKey: Invalid handle (%s:%u:%u).\n",
9474 OUR_HANDLE(handle)));
9478 /* if keyname == NULL, return error */
9480 if ( !r->in.key_name )
9481 return WERR_INVALID_PARAM;
9483 if (!get_printer_snum(p, handle, &snum, NULL))
9486 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) {
9487 DEBUG(3, ("_spoolss_DeletePrinterKey: "
9488 "printer properties change denied by handle\n"));
9489 return WERR_ACCESS_DENIED;
9492 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9493 if (!W_ERROR_IS_OK(status))
9496 /* delete the key and all subneys */
9498 status = delete_all_printer_data( printer->info_2, r->in.key_name );
9500 if ( W_ERROR_IS_OK(status) )
9501 status = mod_a_printer(printer, 2);
9503 free_a_printer( &printer, 2 );
9509 /********************************************************************
9510 * spoolss_enumprinterdataex
9511 ********************************************************************/
9513 WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u)
9515 POLICY_HND *handle = &q_u->handle;
9516 uint32 in_size = q_u->size;
9519 NT_PRINTER_INFO_LEVEL *printer = NULL;
9520 PRINTER_ENUM_VALUES *enum_values = NULL;
9521 NT_PRINTER_DATA *p_data;
9523 Printer_entry *Printer = find_printer_index_by_hnd(p, handle);
9528 REGISTRY_VALUE *val;
9533 DEBUG(4,("_spoolss_enumprinterdataex\n"));
9536 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle)));
9541 * first check for a keyname of NULL or "". Win2k seems to send
9542 * this a lot and we should send back WERR_INVALID_PARAM
9543 * no need to spend time looking up the printer in this case.
9547 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9548 if ( !strlen(key) ) {
9549 result = WERR_INVALID_PARAM;
9553 /* get the printer off of disk */
9555 if (!get_printer_snum(p,handle, &snum, NULL))
9558 ZERO_STRUCT(printer);
9559 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum));
9560 if (!W_ERROR_IS_OK(result))
9563 /* now look for a match on the key name */
9565 p_data = printer->info_2->data;
9567 unistr2_to_ascii(key, &q_u->key, sizeof(key));
9568 if ( (key_index = lookup_printerkey( p_data, key)) == -1 )
9570 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key));
9571 result = WERR_INVALID_PARAM;
9578 /* allocate the memory for the array of pointers -- if necessary */
9580 num_entries = regval_ctr_numvals( p_data->keys[key_index].values );
9583 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL )
9585 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n",
9586 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES)));
9587 result = WERR_NOMEM;
9591 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) );
9595 * loop through all params and build the array to pass
9596 * back to the client
9599 for ( i=0; i<num_entries; i++ )
9601 /* lookup the registry value */
9603 val = regval_ctr_specific_value( p_data->keys[key_index].values, i );
9604 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) ));
9608 value_name = regval_name( val );
9609 init_unistr( &enum_values[i].valuename, value_name );
9610 enum_values[i].value_len = (strlen(value_name)+1) * 2;
9611 enum_values[i].type = regval_type( val );
9613 data_len = regval_size( val );
9615 if ( !(enum_values[i].data = (uint8 *)TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) )
9617 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n",
9619 result = WERR_NOMEM;
9623 enum_values[i].data_len = data_len;
9625 /* keep track of the size of the array in bytes */
9627 needed += spoolss_size_printer_enum_values(&enum_values[i]);
9630 /* housekeeping information in the reply */
9632 /* Fix from Martin Zielinski <mz@seh.de> - ensure
9633 * the hand marshalled container size is a multiple
9634 * of 4 bytes for RPC alignment.
9638 needed += 4-(needed % 4);
9641 r_u->needed = needed;
9642 r_u->returned = num_entries;
9644 if (needed > in_size) {
9645 result = WERR_MORE_DATA;
9649 /* copy data into the reply */
9651 /* mz: Vista x64 returns 0x6f7 (The stub received bad data), if the
9652 response buffer size is != the offered buffer size
9654 r_u->ctr.size = r_u->needed;
9656 r_u->ctr.size = in_size;
9658 r_u->ctr.size_of_array = r_u->returned;
9659 r_u->ctr.values = enum_values;
9663 free_a_printer(&printer, 2);
9668 /****************************************************************************
9669 ****************************************************************************/
9671 static WERROR getprintprocessordirectory_level_1(TALLOC_CTX *mem_ctx,
9672 const char *servername,
9673 const char *environment,
9674 struct spoolss_PrintProcessorDirectoryInfo1 *info1,
9678 const char *long_archi = SPOOLSS_ARCHITECTURE_NT_X86;
9679 const char *short_archi;
9682 long_archi = environment;
9685 short_archi = get_short_archi(long_archi);
9687 return WERR_INVALID_ENVIRONMENT;
9690 /* I think this should look like this - gd
9691 info1->directory_name = talloc_asprintf(mem_ctx,
9692 "C:\\WINNT\\System32\\spool\\PRTPROCS\\%s", short_archi);
9694 info1->directory_name = talloc_strdup(mem_ctx,
9695 "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86");
9697 if (!info1->directory_name) {
9701 *needed += ndr_size_spoolss_PrintProcessorDirectoryInfo1(info1, NULL, 0);
9703 if (*needed > offered) {
9704 return WERR_INSUFFICIENT_BUFFER;
9710 /****************************************************************
9711 _spoolss_GetPrintProcessorDirectory
9712 ****************************************************************/
9714 WERROR _spoolss_GetPrintProcessorDirectory(pipes_struct *p,
9715 struct spoolss_GetPrintProcessorDirectory *r)
9719 /* that's an [in out] buffer */
9721 if (!r->in.buffer && (r->in.offered != 0)) {
9722 return WERR_INVALID_PARAM;
9725 if (r->in.offered > MAX_RPC_DATA_SIZE) {
9726 return WERR_INVALID_PARAM;
9729 DEBUG(5,("_spoolss_GetPrintProcessorDirectory\n"));
9733 switch (r->in.level) {
9735 result = getprintprocessordirectory_level_1(p->mem_ctx,
9738 &r->out.info->info1,
9741 if (!W_ERROR_IS_OK(result)) {
9742 TALLOC_FREE(r->out.info);
9746 result = WERR_UNKNOWN_LEVEL;
9752 /*******************************************************************
9753 ********************************************************************/
9755 static bool push_monitorui_buf(TALLOC_CTX *mem_ctx, DATA_BLOB *buf,
9756 const char *dllname)
9758 enum ndr_err_code ndr_err;
9759 struct spoolss_MonitorUi ui;
9761 ui.dll_name = dllname;
9763 ndr_err = ndr_push_struct_blob(buf, mem_ctx, NULL, &ui,
9764 (ndr_push_flags_fn_t)ndr_push_spoolss_MonitorUi);
9765 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9766 NDR_PRINT_DEBUG(spoolss_MonitorUi, &ui);
9768 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9771 /*******************************************************************
9772 Streams the monitor UI DLL name in UNICODE
9773 *******************************************************************/
9775 static WERROR xcvtcp_monitorui(TALLOC_CTX *mem_ctx,
9776 NT_USER_TOKEN *token, DATA_BLOB *in,
9777 DATA_BLOB *out, uint32_t *needed)
9779 const char *dllname = "tcpmonui.dll";
9781 *needed = (strlen(dllname)+1) * 2;
9783 if (out->length < *needed) {
9784 return WERR_INSUFFICIENT_BUFFER;
9787 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9794 /*******************************************************************
9795 ********************************************************************/
9797 static bool pull_port_data_1(TALLOC_CTX *mem_ctx,
9798 struct spoolss_PortData1 *port1,
9799 const DATA_BLOB *buf)
9801 enum ndr_err_code ndr_err;
9802 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port1,
9803 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData1);
9804 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9805 NDR_PRINT_DEBUG(spoolss_PortData1, port1);
9807 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9810 /*******************************************************************
9811 ********************************************************************/
9813 static bool pull_port_data_2(TALLOC_CTX *mem_ctx,
9814 struct spoolss_PortData2 *port2,
9815 const DATA_BLOB *buf)
9817 enum ndr_err_code ndr_err;
9818 ndr_err = ndr_pull_struct_blob(buf, mem_ctx, NULL, port2,
9819 (ndr_pull_flags_fn_t)ndr_pull_spoolss_PortData2);
9820 if (NDR_ERR_CODE_IS_SUCCESS(ndr_err) && (DEBUGLEVEL >= 10)) {
9821 NDR_PRINT_DEBUG(spoolss_PortData2, port2);
9823 return NDR_ERR_CODE_IS_SUCCESS(ndr_err);
9826 /*******************************************************************
9827 Create a new TCP/IP port
9828 *******************************************************************/
9830 static WERROR xcvtcp_addport(TALLOC_CTX *mem_ctx,
9831 NT_USER_TOKEN *token, DATA_BLOB *in,
9832 DATA_BLOB *out, uint32_t *needed)
9834 struct spoolss_PortData1 port1;
9835 struct spoolss_PortData2 port2;
9836 char *device_uri = NULL;
9839 const char *portname;
9840 const char *hostaddress;
9842 uint32_t port_number;
9845 /* peek for spoolss_PortData version */
9847 if (!in || (in->length < (128 + 4))) {
9848 return WERR_GENERAL_FAILURE;
9851 version = IVAL(in->data, 128);
9857 if (!pull_port_data_1(mem_ctx, &port1, in)) {
9861 portname = port1.portname;
9862 hostaddress = port1.hostaddress;
9863 queue = port1.queue;
9864 protocol = port1.protocol;
9865 port_number = port1.port_number;
9871 if (!pull_port_data_2(mem_ctx, &port2, in)) {
9875 portname = port2.portname;
9876 hostaddress = port2.hostaddress;
9877 queue = port2.queue;
9878 protocol = port2.protocol;
9879 port_number = port2.port_number;
9883 DEBUG(1,("xcvtcp_addport: "
9884 "unknown version of port_data: %d\n", version));
9885 return WERR_UNKNOWN_PORT;
9888 /* create the device URI and call the add_port_hook() */
9891 case PROTOCOL_RAWTCP_TYPE:
9892 device_uri = talloc_asprintf(mem_ctx,
9893 "socket://%s:%d/", hostaddress,
9897 case PROTOCOL_LPR_TYPE:
9898 device_uri = talloc_asprintf(mem_ctx,
9899 "lpr://%s/%s", hostaddress, queue );
9903 return WERR_UNKNOWN_PORT;
9910 return add_port_hook(mem_ctx, token, portname, device_uri);
9913 /*******************************************************************
9914 *******************************************************************/
9916 struct xcv_api_table xcvtcp_cmds[] = {
9917 { "MonitorUI", xcvtcp_monitorui },
9918 { "AddPort", xcvtcp_addport},
9922 static WERROR process_xcvtcp_command(TALLOC_CTX *mem_ctx,
9923 NT_USER_TOKEN *token, const char *command,
9930 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command));
9932 for ( i=0; xcvtcp_cmds[i].name; i++ ) {
9933 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 )
9934 return xcvtcp_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9937 return WERR_BADFUNC;
9940 /*******************************************************************
9941 *******************************************************************/
9942 #if 0 /* don't support management using the "Local Port" monitor */
9944 static WERROR xcvlocal_monitorui(TALLOC_CTX *mem_ctx,
9945 NT_USER_TOKEN *token, DATA_BLOB *in,
9946 DATA_BLOB *out, uint32_t *needed)
9948 const char *dllname = "localui.dll";
9950 *needed = (strlen(dllname)+1) * 2;
9952 if (out->length < *needed) {
9953 return WERR_INSUFFICIENT_BUFFER;
9956 if (!push_monitorui_buf(mem_ctx, out, dllname)) {
9963 /*******************************************************************
9964 *******************************************************************/
9966 struct xcv_api_table xcvlocal_cmds[] = {
9967 { "MonitorUI", xcvlocal_monitorui },
9971 struct xcv_api_table xcvlocal_cmds[] = {
9978 /*******************************************************************
9979 *******************************************************************/
9981 static WERROR process_xcvlocal_command(TALLOC_CTX *mem_ctx,
9982 NT_USER_TOKEN *token, const char *command,
9983 DATA_BLOB *inbuf, DATA_BLOB *outbuf,
9988 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command));
9990 for ( i=0; xcvlocal_cmds[i].name; i++ ) {
9991 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 )
9992 return xcvlocal_cmds[i].fn(mem_ctx, token, inbuf, outbuf, needed);
9994 return WERR_BADFUNC;
9997 /****************************************************************
9999 ****************************************************************/
10001 WERROR _spoolss_XcvData(pipes_struct *p,
10002 struct spoolss_XcvData *r)
10004 Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle);
10005 DATA_BLOB out_data;
10009 DEBUG(2,("_spoolss_XcvData: Invalid handle (%s:%u:%u).\n",
10010 OUR_HANDLE(r->in.handle)));
10011 return WERR_BADFID;
10014 /* Has to be a handle to the TCP/IP port monitor */
10016 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) {
10017 DEBUG(2,("_spoolss_XcvData: Call only valid for Port Monitors\n"));
10018 return WERR_BADFID;
10021 /* requires administrative access to the server */
10023 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) {
10024 DEBUG(2,("_spoolss_XcvData: denied by handle permissions.\n"));
10025 return WERR_ACCESS_DENIED;
10028 /* Allocate the outgoing buffer */
10030 if (r->in.out_data_size) {
10031 out_data = data_blob_talloc_zero(p->mem_ctx, r->in.out_data_size);
10032 if (out_data.data == NULL) {
10037 switch ( Printer->printer_type ) {
10038 case SPLHND_PORTMON_TCP:
10039 werror = process_xcvtcp_command(p->mem_ctx,
10040 p->server_info->ptok,
10041 r->in.function_name,
10042 &r->in.in_data, &out_data,
10045 case SPLHND_PORTMON_LOCAL:
10046 werror = process_xcvlocal_command(p->mem_ctx,
10047 p->server_info->ptok,
10048 r->in.function_name,
10049 &r->in.in_data, &out_data,
10053 werror = WERR_INVALID_PRINT_MONITOR;
10056 if (!W_ERROR_IS_OK(werror)) {
10060 *r->out.status_code = 0;
10062 memcpy(r->out.out_data, out_data.data, out_data.length);
10067 /****************************************************************
10068 _spoolss_AddPrintProcessor
10069 ****************************************************************/
10071 WERROR _spoolss_AddPrintProcessor(pipes_struct *p,
10072 struct spoolss_AddPrintProcessor *r)
10074 /* for now, just indicate success and ignore the add. We'll
10075 automatically set the winprint processor for printer
10076 entries later. Used to debug the LexMark Optra S 1855 PCL
10082 /****************************************************************
10083 _spoolss_EnumPrinters
10084 ****************************************************************/
10086 WERROR _spoolss_EnumPrinters(pipes_struct *p,
10087 struct spoolss_EnumPrinters *r)
10089 p->rng_fault_state = true;
10090 return WERR_NOT_SUPPORTED;
10093 /****************************************************************
10095 ****************************************************************/
10097 WERROR _spoolss_GetJob(pipes_struct *p,
10098 struct spoolss_GetJob *r)
10100 p->rng_fault_state = true;
10101 return WERR_NOT_SUPPORTED;
10104 /****************************************************************
10106 ****************************************************************/
10108 WERROR _spoolss_EnumJobs(pipes_struct *p,
10109 struct spoolss_EnumJobs *r)
10111 p->rng_fault_state = true;
10112 return WERR_NOT_SUPPORTED;
10115 /****************************************************************
10116 _spoolss_AddPrinter
10117 ****************************************************************/
10119 WERROR _spoolss_AddPrinter(pipes_struct *p,
10120 struct spoolss_AddPrinter *r)
10122 p->rng_fault_state = true;
10123 return WERR_NOT_SUPPORTED;
10126 /****************************************************************
10127 _spoolss_GetPrinter
10128 ****************************************************************/
10130 WERROR _spoolss_GetPrinter(pipes_struct *p,
10131 struct spoolss_GetPrinter *r)
10133 p->rng_fault_state = true;
10134 return WERR_NOT_SUPPORTED;
10137 /****************************************************************
10138 _spoolss_EnumPrinterDrivers
10139 ****************************************************************/
10141 WERROR _spoolss_EnumPrinterDrivers(pipes_struct *p,
10142 struct spoolss_EnumPrinterDrivers *r)
10144 p->rng_fault_state = true;
10145 return WERR_NOT_SUPPORTED;
10148 /****************************************************************
10149 _spoolss_GetPrinterDriver
10150 ****************************************************************/
10152 WERROR _spoolss_GetPrinterDriver(pipes_struct *p,
10153 struct spoolss_GetPrinterDriver *r)
10155 p->rng_fault_state = true;
10156 return WERR_NOT_SUPPORTED;
10159 /****************************************************************
10160 _spoolss_EnumPrintProcessors
10161 ****************************************************************/
10163 WERROR _spoolss_EnumPrintProcessors(pipes_struct *p,
10164 struct spoolss_EnumPrintProcessors *r)
10166 p->rng_fault_state = true;
10167 return WERR_NOT_SUPPORTED;
10170 /****************************************************************
10171 _spoolss_ReadPrinter
10172 ****************************************************************/
10174 WERROR _spoolss_ReadPrinter(pipes_struct *p,
10175 struct spoolss_ReadPrinter *r)
10177 p->rng_fault_state = true;
10178 return WERR_NOT_SUPPORTED;
10181 /****************************************************************
10182 _spoolss_GetPrinterData
10183 ****************************************************************/
10185 WERROR _spoolss_GetPrinterData(pipes_struct *p,
10186 struct spoolss_GetPrinterData *r)
10188 p->rng_fault_state = true;
10189 return WERR_NOT_SUPPORTED;
10192 /****************************************************************
10193 _spoolss_SetPrinterData
10194 ****************************************************************/
10196 WERROR _spoolss_SetPrinterData(pipes_struct *p,
10197 struct spoolss_SetPrinterData *r)
10199 p->rng_fault_state = true;
10200 return WERR_NOT_SUPPORTED;
10203 /****************************************************************
10204 _spoolss_WaitForPrinterChange
10205 ****************************************************************/
10207 WERROR _spoolss_WaitForPrinterChange(pipes_struct *p,
10208 struct spoolss_WaitForPrinterChange *r)
10210 p->rng_fault_state = true;
10211 return WERR_NOT_SUPPORTED;
10214 /****************************************************************
10216 ****************************************************************/
10218 WERROR _spoolss_EnumForms(pipes_struct *p,
10219 struct spoolss_EnumForms *r)
10221 p->rng_fault_state = true;
10222 return WERR_NOT_SUPPORTED;
10225 /****************************************************************
10227 ****************************************************************/
10229 WERROR _spoolss_EnumPorts(pipes_struct *p,
10230 struct spoolss_EnumPorts *r)
10232 p->rng_fault_state = true;
10233 return WERR_NOT_SUPPORTED;
10236 /****************************************************************
10237 _spoolss_EnumMonitors
10238 ****************************************************************/
10240 WERROR _spoolss_EnumMonitors(pipes_struct *p,
10241 struct spoolss_EnumMonitors *r)
10243 p->rng_fault_state = true;
10244 return WERR_NOT_SUPPORTED;
10247 /****************************************************************
10249 ****************************************************************/
10251 WERROR _spoolss_AddPort(pipes_struct *p,
10252 struct spoolss_AddPort *r)
10254 p->rng_fault_state = true;
10255 return WERR_NOT_SUPPORTED;
10258 /****************************************************************
10259 _spoolss_ConfigurePort
10260 ****************************************************************/
10262 WERROR _spoolss_ConfigurePort(pipes_struct *p,
10263 struct spoolss_ConfigurePort *r)
10265 p->rng_fault_state = true;
10266 return WERR_NOT_SUPPORTED;
10269 /****************************************************************
10270 _spoolss_DeletePort
10271 ****************************************************************/
10273 WERROR _spoolss_DeletePort(pipes_struct *p,
10274 struct spoolss_DeletePort *r)
10276 p->rng_fault_state = true;
10277 return WERR_NOT_SUPPORTED;
10280 /****************************************************************
10281 _spoolss_CreatePrinterIC
10282 ****************************************************************/
10284 WERROR _spoolss_CreatePrinterIC(pipes_struct *p,
10285 struct spoolss_CreatePrinterIC *r)
10287 p->rng_fault_state = true;
10288 return WERR_NOT_SUPPORTED;
10291 /****************************************************************
10292 _spoolss_PlayGDIScriptOnPrinterIC
10293 ****************************************************************/
10295 WERROR _spoolss_PlayGDIScriptOnPrinterIC(pipes_struct *p,
10296 struct spoolss_PlayGDIScriptOnPrinterIC *r)
10298 p->rng_fault_state = true;
10299 return WERR_NOT_SUPPORTED;
10302 /****************************************************************
10303 _spoolss_DeletePrinterIC
10304 ****************************************************************/
10306 WERROR _spoolss_DeletePrinterIC(pipes_struct *p,
10307 struct spoolss_DeletePrinterIC *r)
10309 p->rng_fault_state = true;
10310 return WERR_NOT_SUPPORTED;
10313 /****************************************************************
10314 _spoolss_AddPrinterConnection
10315 ****************************************************************/
10317 WERROR _spoolss_AddPrinterConnection(pipes_struct *p,
10318 struct spoolss_AddPrinterConnection *r)
10320 p->rng_fault_state = true;
10321 return WERR_NOT_SUPPORTED;
10324 /****************************************************************
10325 _spoolss_DeletePrinterConnection
10326 ****************************************************************/
10328 WERROR _spoolss_DeletePrinterConnection(pipes_struct *p,
10329 struct spoolss_DeletePrinterConnection *r)
10331 p->rng_fault_state = true;
10332 return WERR_NOT_SUPPORTED;
10335 /****************************************************************
10336 _spoolss_PrinterMessageBox
10337 ****************************************************************/
10339 WERROR _spoolss_PrinterMessageBox(pipes_struct *p,
10340 struct spoolss_PrinterMessageBox *r)
10342 p->rng_fault_state = true;
10343 return WERR_NOT_SUPPORTED;
10346 /****************************************************************
10347 _spoolss_AddMonitor
10348 ****************************************************************/
10350 WERROR _spoolss_AddMonitor(pipes_struct *p,
10351 struct spoolss_AddMonitor *r)
10353 p->rng_fault_state = true;
10354 return WERR_NOT_SUPPORTED;
10357 /****************************************************************
10358 _spoolss_DeleteMonitor
10359 ****************************************************************/
10361 WERROR _spoolss_DeleteMonitor(pipes_struct *p,
10362 struct spoolss_DeleteMonitor *r)
10364 p->rng_fault_state = true;
10365 return WERR_NOT_SUPPORTED;
10368 /****************************************************************
10369 _spoolss_DeletePrintProcessor
10370 ****************************************************************/
10372 WERROR _spoolss_DeletePrintProcessor(pipes_struct *p,
10373 struct spoolss_DeletePrintProcessor *r)
10375 p->rng_fault_state = true;
10376 return WERR_NOT_SUPPORTED;
10379 /****************************************************************
10380 _spoolss_AddPrintProvidor
10381 ****************************************************************/
10383 WERROR _spoolss_AddPrintProvidor(pipes_struct *p,
10384 struct spoolss_AddPrintProvidor *r)
10386 p->rng_fault_state = true;
10387 return WERR_NOT_SUPPORTED;
10390 /****************************************************************
10391 _spoolss_DeletePrintProvidor
10392 ****************************************************************/
10394 WERROR _spoolss_DeletePrintProvidor(pipes_struct *p,
10395 struct spoolss_DeletePrintProvidor *r)
10397 p->rng_fault_state = true;
10398 return WERR_NOT_SUPPORTED;
10401 /****************************************************************
10402 _spoolss_EnumPrintProcDataTypes
10403 ****************************************************************/
10405 WERROR _spoolss_EnumPrintProcDataTypes(pipes_struct *p,
10406 struct spoolss_EnumPrintProcDataTypes *r)
10408 p->rng_fault_state = true;
10409 return WERR_NOT_SUPPORTED;
10412 /****************************************************************
10413 _spoolss_GetPrinterDriver2
10414 ****************************************************************/
10416 WERROR _spoolss_GetPrinterDriver2(pipes_struct *p,
10417 struct spoolss_GetPrinterDriver2 *r)
10419 p->rng_fault_state = true;
10420 return WERR_NOT_SUPPORTED;
10423 /****************************************************************
10424 _spoolss_FindFirstPrinterChangeNotification
10425 ****************************************************************/
10427 WERROR _spoolss_FindFirstPrinterChangeNotification(pipes_struct *p,
10428 struct spoolss_FindFirstPrinterChangeNotification *r)
10430 p->rng_fault_state = true;
10431 return WERR_NOT_SUPPORTED;
10434 /****************************************************************
10435 _spoolss_FindNextPrinterChangeNotification
10436 ****************************************************************/
10438 WERROR _spoolss_FindNextPrinterChangeNotification(pipes_struct *p,
10439 struct spoolss_FindNextPrinterChangeNotification *r)
10441 p->rng_fault_state = true;
10442 return WERR_NOT_SUPPORTED;
10445 /****************************************************************
10446 _spoolss_RouterFindFirstPrinterChangeNotificationOld
10447 ****************************************************************/
10449 WERROR _spoolss_RouterFindFirstPrinterChangeNotificationOld(pipes_struct *p,
10450 struct spoolss_RouterFindFirstPrinterChangeNotificationOld *r)
10452 p->rng_fault_state = true;
10453 return WERR_NOT_SUPPORTED;
10456 /****************************************************************
10457 _spoolss_ReplyOpenPrinter
10458 ****************************************************************/
10460 WERROR _spoolss_ReplyOpenPrinter(pipes_struct *p,
10461 struct spoolss_ReplyOpenPrinter *r)
10463 p->rng_fault_state = true;
10464 return WERR_NOT_SUPPORTED;
10467 /****************************************************************
10468 _spoolss_RouterReplyPrinter
10469 ****************************************************************/
10471 WERROR _spoolss_RouterReplyPrinter(pipes_struct *p,
10472 struct spoolss_RouterReplyPrinter *r)
10474 p->rng_fault_state = true;
10475 return WERR_NOT_SUPPORTED;
10478 /****************************************************************
10479 _spoolss_ReplyClosePrinter
10480 ****************************************************************/
10482 WERROR _spoolss_ReplyClosePrinter(pipes_struct *p,
10483 struct spoolss_ReplyClosePrinter *r)
10485 p->rng_fault_state = true;
10486 return WERR_NOT_SUPPORTED;
10489 /****************************************************************
10491 ****************************************************************/
10493 WERROR _spoolss_AddPortEx(pipes_struct *p,
10494 struct spoolss_AddPortEx *r)
10496 p->rng_fault_state = true;
10497 return WERR_NOT_SUPPORTED;
10500 /****************************************************************
10501 _spoolss_RouterFindFirstPrinterChangeNotification
10502 ****************************************************************/
10504 WERROR _spoolss_RouterFindFirstPrinterChangeNotification(pipes_struct *p,
10505 struct spoolss_RouterFindFirstPrinterChangeNotification *r)
10507 p->rng_fault_state = true;
10508 return WERR_NOT_SUPPORTED;
10511 /****************************************************************
10512 _spoolss_SpoolerInit
10513 ****************************************************************/
10515 WERROR _spoolss_SpoolerInit(pipes_struct *p,
10516 struct spoolss_SpoolerInit *r)
10518 p->rng_fault_state = true;
10519 return WERR_NOT_SUPPORTED;
10522 /****************************************************************
10523 _spoolss_ResetPrinterEx
10524 ****************************************************************/
10526 WERROR _spoolss_ResetPrinterEx(pipes_struct *p,
10527 struct spoolss_ResetPrinterEx *r)
10529 p->rng_fault_state = true;
10530 return WERR_NOT_SUPPORTED;
10533 /****************************************************************
10534 _spoolss_RemoteFindFirstPrinterChangeNotifyEx
10535 ****************************************************************/
10537 WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p,
10538 struct spoolss_RemoteFindFirstPrinterChangeNotifyEx *r)
10540 p->rng_fault_state = true;
10541 return WERR_NOT_SUPPORTED;
10544 /****************************************************************
10545 _spoolss_RouterReplyPrinterEx
10546 ****************************************************************/
10548 WERROR _spoolss_RouterReplyPrinterEx(pipes_struct *p,
10549 struct spoolss_RouterReplyPrinterEx *r)
10551 p->rng_fault_state = true;
10552 return WERR_NOT_SUPPORTED;
10555 /****************************************************************
10556 _dcesrv_spoolss_RouterRefreshPrinterChangeNotify
10557 ****************************************************************/
10559 WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p,
10560 struct spoolss_RouterRefreshPrinterChangeNotify *r)
10562 p->rng_fault_state = true;
10563 return WERR_NOT_SUPPORTED;
10566 /****************************************************************
10568 ****************************************************************/
10570 WERROR _spoolss_44(pipes_struct *p,
10571 struct spoolss_44 *r)
10573 p->rng_fault_state = true;
10574 return WERR_NOT_SUPPORTED;
10577 /****************************************************************
10579 ****************************************************************/
10581 WERROR _spoolss_47(pipes_struct *p,
10582 struct spoolss_47 *r)
10584 p->rng_fault_state = true;
10585 return WERR_NOT_SUPPORTED;
10588 /****************************************************************
10589 _spoolss_EnumPrinterData
10590 ****************************************************************/
10592 WERROR _spoolss_EnumPrinterData(pipes_struct *p,
10593 struct spoolss_EnumPrinterData *r)
10595 p->rng_fault_state = true;
10596 return WERR_NOT_SUPPORTED;
10599 /****************************************************************
10601 ****************************************************************/
10603 WERROR _spoolss_4a(pipes_struct *p,
10604 struct spoolss_4a *r)
10606 p->rng_fault_state = true;
10607 return WERR_NOT_SUPPORTED;
10610 /****************************************************************
10612 ****************************************************************/
10614 WERROR _spoolss_4b(pipes_struct *p,
10615 struct spoolss_4b *r)
10617 p->rng_fault_state = true;
10618 return WERR_NOT_SUPPORTED;
10621 /****************************************************************
10623 ****************************************************************/
10625 WERROR _spoolss_4c(pipes_struct *p,
10626 struct spoolss_4c *r)
10628 p->rng_fault_state = true;
10629 return WERR_NOT_SUPPORTED;
10632 /****************************************************************
10633 _spoolss_EnumPrinterDataEx
10634 ****************************************************************/
10636 WERROR _spoolss_EnumPrinterDataEx(pipes_struct *p,
10637 struct spoolss_EnumPrinterDataEx *r)
10639 p->rng_fault_state = true;
10640 return WERR_NOT_SUPPORTED;
10643 /****************************************************************
10644 _spoolss_EnumPrinterKey
10645 ****************************************************************/
10647 WERROR _spoolss_EnumPrinterKey(pipes_struct *p,
10648 struct spoolss_EnumPrinterKey *r)
10650 p->rng_fault_state = true;
10651 return WERR_NOT_SUPPORTED;
10654 /****************************************************************
10656 ****************************************************************/
10658 WERROR _spoolss_53(pipes_struct *p,
10659 struct spoolss_53 *r)
10661 p->rng_fault_state = true;
10662 return WERR_NOT_SUPPORTED;
10665 /****************************************************************
10667 ****************************************************************/
10669 WERROR _spoolss_55(pipes_struct *p,
10670 struct spoolss_55 *r)
10672 p->rng_fault_state = true;
10673 return WERR_NOT_SUPPORTED;
10676 /****************************************************************
10678 ****************************************************************/
10680 WERROR _spoolss_56(pipes_struct *p,
10681 struct spoolss_56 *r)
10683 p->rng_fault_state = true;
10684 return WERR_NOT_SUPPORTED;
10687 /****************************************************************
10689 ****************************************************************/
10691 WERROR _spoolss_57(pipes_struct *p,
10692 struct spoolss_57 *r)
10694 p->rng_fault_state = true;
10695 return WERR_NOT_SUPPORTED;
10698 /****************************************************************
10700 ****************************************************************/
10702 WERROR _spoolss_5a(pipes_struct *p,
10703 struct spoolss_5a *r)
10705 p->rng_fault_state = true;
10706 return WERR_NOT_SUPPORTED;
10709 /****************************************************************
10711 ****************************************************************/
10713 WERROR _spoolss_5b(pipes_struct *p,
10714 struct spoolss_5b *r)
10716 p->rng_fault_state = true;
10717 return WERR_NOT_SUPPORTED;
10720 /****************************************************************
10722 ****************************************************************/
10724 WERROR _spoolss_5c(pipes_struct *p,
10725 struct spoolss_5c *r)
10727 p->rng_fault_state = true;
10728 return WERR_NOT_SUPPORTED;
10731 /****************************************************************
10733 ****************************************************************/
10735 WERROR _spoolss_5d(pipes_struct *p,
10736 struct spoolss_5d *r)
10738 p->rng_fault_state = true;
10739 return WERR_NOT_SUPPORTED;
10742 /****************************************************************
10744 ****************************************************************/
10746 WERROR _spoolss_5e(pipes_struct *p,
10747 struct spoolss_5e *r)
10749 p->rng_fault_state = true;
10750 return WERR_NOT_SUPPORTED;
10753 /****************************************************************
10755 ****************************************************************/
10757 WERROR _spoolss_5f(pipes_struct *p,
10758 struct spoolss_5f *r)
10760 p->rng_fault_state = true;
10761 return WERR_NOT_SUPPORTED;