1/* 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. 10 * 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 2 of the License, or 14 * (at your option) any later version. 15 * 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. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 24 */ 25 26/* Since the SPOOLSS rpc routines are basically DOS 16-bit calls wrapped 27 up, all the errors returned are DOS errors, not NT status codes. */ 28 29#include "includes.h" 30 31extern userdom_struct current_user_info; 32 33#undef DBGC_CLASS 34#define DBGC_CLASS DBGC_RPC_SRV 35 36#ifndef MAX_OPEN_PRINTER_EXS 37#define MAX_OPEN_PRINTER_EXS 50 38#endif 39 40#define MAGIC_DISPLAY_FREQUENCY 0xfade2bad 41#define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_" 42 43struct table_node { 44 const char *long_archi; 45 const char *short_archi; 46 int version; 47}; 48 49static Printer_entry *printers_list; 50 51typedef struct _counter_printer_0 { 52 struct _counter_printer_0 *next; 53 struct _counter_printer_0 *prev; 54 55 int snum; 56 uint32 counter; 57} counter_printer_0; 58 59static counter_printer_0 *counter_list; 60 61static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/ 62static uint32 smb_connections=0; 63 64 65/* in printing/nt_printing.c */ 66 67extern STANDARD_MAPPING printer_std_mapping, printserver_std_mapping; 68 69/* API table for Xcv Monitor functions */ 70 71struct xcv_api_table { 72 const char *name; 73 WERROR(*fn) (NT_USER_TOKEN *token, RPC_BUFFER *in, RPC_BUFFER *out, uint32 *needed); 74}; 75 76 77/* translate between internal status numbers and NT status numbers */ 78static int nt_printj_status(int v) 79{ 80 switch (v) { 81 case LPQ_QUEUED: 82 return 0; 83 case LPQ_PAUSED: 84 return JOB_STATUS_PAUSED; 85 case LPQ_SPOOLING: 86 return JOB_STATUS_SPOOLING; 87 case LPQ_PRINTING: 88 return JOB_STATUS_PRINTING; 89 case LPQ_ERROR: 90 return JOB_STATUS_ERROR; 91 case LPQ_DELETING: 92 return JOB_STATUS_DELETING; 93 case LPQ_OFFLINE: 94 return JOB_STATUS_OFFLINE; 95 case LPQ_PAPEROUT: 96 return JOB_STATUS_PAPEROUT; 97 case LPQ_PRINTED: 98 return JOB_STATUS_PRINTED; 99 case LPQ_DELETED: 100 return JOB_STATUS_DELETED; 101 case LPQ_BLOCKED: 102 return JOB_STATUS_BLOCKED; 103 case LPQ_USER_INTERVENTION: 104 return JOB_STATUS_USER_INTERVENTION; 105 } 106 return 0; 107} 108 109static int nt_printq_status(int v) 110{ 111 switch (v) { 112 case LPQ_PAUSED: 113 return PRINTER_STATUS_PAUSED; 114 case LPQ_QUEUED: 115 case LPQ_SPOOLING: 116 case LPQ_PRINTING: 117 return 0; 118 } 119 return 0; 120} 121 122/**************************************************************************** 123 Functions to handle SPOOL_NOTIFY_OPTION struct stored in Printer_entry. 124****************************************************************************/ 125 126static void free_spool_notify_option(SPOOL_NOTIFY_OPTION **pp) 127{ 128 if (*pp == NULL) 129 return; 130 131 SAFE_FREE((*pp)->ctr.type); 132 SAFE_FREE(*pp); 133} 134 135/*************************************************************************** 136 Disconnect from the client 137****************************************************************************/ 138 139static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle) 140{ 141 WERROR result; 142 143 /* 144 * Tell the specific printing tdb we no longer want messages for this printer 145 * by deregistering our PID. 146 */ 147 148 if (!print_notify_deregister_pid(snum)) 149 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", lp_const_servicename(snum) )); 150 151 /* weird if the test succeds !!! */ 152 if (smb_connections==0) { 153 DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n")); 154 return; 155 } 156 157 result = rpccli_spoolss_reply_close_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, handle); 158 159 if (!W_ERROR_IS_OK(result)) 160 DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n", 161 dos_errstr(result))); 162 163 /* if it's the last connection, deconnect the IPC$ share */ 164 if (smb_connections==1) { 165 166 cli_shutdown( notify_cli_pipe->cli ); 167 notify_cli_pipe = NULL; /* The above call shuts downn the pipe also. */ 168 169 message_deregister(MSG_PRINTER_NOTIFY2); 170 171 /* Tell the connections db we're no longer interested in 172 * printer notify messages. */ 173 174 register_message_flags( False, FLAG_MSG_PRINT_NOTIFY ); 175 } 176 177 smb_connections--; 178} 179 180/**************************************************************************** 181 Functions to free a printer entry datastruct. 182****************************************************************************/ 183 184static void free_printer_entry(void *ptr) 185{ 186 Printer_entry *Printer = (Printer_entry *)ptr; 187 188 if (Printer->notify.client_connected==True) { 189 int snum = -1; 190 191 if ( Printer->printer_type == SPLHND_SERVER) { 192 snum = -1; 193 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd); 194 } else if (Printer->printer_type == SPLHND_PRINTER) { 195 snum = print_queue_snum(Printer->sharename); 196 if (snum != -1) 197 srv_spoolss_replycloseprinter(snum, 198 &Printer->notify.client_hnd); 199 } 200 } 201 202 Printer->notify.flags=0; 203 Printer->notify.options=0; 204 Printer->notify.localmachine[0]='\0'; 205 Printer->notify.printerlocal=0; 206 free_spool_notify_option(&Printer->notify.option); 207 Printer->notify.option=NULL; 208 Printer->notify.client_connected=False; 209 210 free_nt_devicemode( &Printer->nt_devmode ); 211 free_a_printer( &Printer->printer_info, 2 ); 212 213 talloc_destroy( Printer->ctx ); 214 215 /* Remove from the internal list. */ 216 DLIST_REMOVE(printers_list, Printer); 217 218 SAFE_FREE(Printer); 219} 220 221/**************************************************************************** 222 Functions to duplicate a SPOOL_NOTIFY_OPTION struct stored in Printer_entry. 223****************************************************************************/ 224 225static SPOOL_NOTIFY_OPTION *dup_spool_notify_option(SPOOL_NOTIFY_OPTION *sp) 226{ 227 SPOOL_NOTIFY_OPTION *new_sp = NULL; 228 229 if (!sp) 230 return NULL; 231 232 new_sp = SMB_MALLOC_P(SPOOL_NOTIFY_OPTION); 233 if (!new_sp) 234 return NULL; 235 236 *new_sp = *sp; 237 238 if (sp->ctr.count) { 239 new_sp->ctr.type = (SPOOL_NOTIFY_OPTION_TYPE *)memdup(sp->ctr.type, sizeof(SPOOL_NOTIFY_OPTION_TYPE) * sp->ctr.count); 240 241 if (!new_sp->ctr.type) { 242 SAFE_FREE(new_sp); 243 return NULL; 244 } 245 } 246 247 return new_sp; 248} 249 250/**************************************************************************** 251 find printer index by handle 252****************************************************************************/ 253 254static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd) 255{ 256 Printer_entry *find_printer = NULL; 257 258 if(!find_policy_by_hnd(p,hnd,(void **)(void *)&find_printer)) { 259 DEBUG(2,("find_printer_index_by_hnd: Printer handle not found: ")); 260 return NULL; 261 } 262 263 return find_printer; 264} 265 266/**************************************************************************** 267 Close printer index by handle. 268****************************************************************************/ 269 270static BOOL close_printer_handle(pipes_struct *p, POLICY_HND *hnd) 271{ 272 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); 273 274 if (!Printer) { 275 DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); 276 return False; 277 } 278 279 close_policy_hnd(p, hnd); 280 281 return True; 282} 283 284/**************************************************************************** 285 Delete a printer given a handle. 286****************************************************************************/ 287WERROR delete_printer_hook( NT_USER_TOKEN *token, const char *sharename ) 288{ 289 char *cmd = lp_deleteprinter_cmd(); 290 pstring command; 291 int ret; 292 SE_PRIV se_printop = SE_PRINT_OPERATOR; 293 BOOL is_print_op = False; 294 295 /* can't fail if we don't try */ 296 297 if ( !*cmd ) 298 return WERR_OK; 299 300 pstr_sprintf(command, "%s \"%s\"", cmd, sharename); 301 302 if ( token ) 303 is_print_op = user_has_privileges( token, &se_printop ); 304 305 DEBUG(10,("Running [%s]\n", command)); 306 307 /********** BEGIN SePrintOperatorPrivlege BLOCK **********/ 308 309 if ( is_print_op ) 310 become_root(); 311 312 if ( (ret = smbrun(command, NULL)) == 0 ) { 313 /* Tell everyone we updated smb.conf. */ 314 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL); 315 } 316 317 if ( is_print_op ) 318 unbecome_root(); 319 320 /********** END SePrintOperatorPrivlege BLOCK **********/ 321 322 DEBUGADD(10,("returned [%d]\n", ret)); 323 324 if (ret != 0) 325 return WERR_BADFID; /* What to return here? */ 326 327 /* go ahead and re-read the services immediately */ 328 reload_services( False ); 329 330 if ( lp_servicenumber( sharename ) < 0 ) 331 return WERR_ACCESS_DENIED; 332 333 return WERR_OK; 334} 335 336/**************************************************************************** 337 Delete a printer given a handle. 338****************************************************************************/ 339 340static WERROR delete_printer_handle(pipes_struct *p, POLICY_HND *hnd) 341{ 342 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); 343 344 if (!Printer) { 345 DEBUG(2,("delete_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); 346 return WERR_BADFID; 347 } 348 349 /* 350 * It turns out that Windows allows delete printer on a handle 351 * opened by an admin user, then used on a pipe handle created 352 * by an anonymous user..... but they're working on security.... riiight ! 353 * JRA. 354 */ 355 356 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { 357 DEBUG(3, ("delete_printer_handle: denied by handle\n")); 358 return WERR_ACCESS_DENIED; 359 } 360 361 /* this does not need a become root since the access check has been 362 done on the handle already */ 363 364 if (del_a_printer( Printer->sharename ) != 0) { 365 DEBUG(3,("Error deleting printer %s\n", Printer->sharename)); 366 return WERR_BADFID; 367 } 368 369 return delete_printer_hook( p->pipe_user.nt_user_token, Printer->sharename ); 370} 371 372/**************************************************************************** 373 Return the snum of a printer corresponding to an handle. 374****************************************************************************/ 375 376static BOOL get_printer_snum(pipes_struct *p, POLICY_HND *hnd, int *number) 377{ 378 Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); 379 380 if (!Printer) { 381 DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); 382 return False; 383 } 384 385 switch (Printer->printer_type) { 386 case SPLHND_PRINTER: 387 DEBUG(4,("short name:%s\n", Printer->sharename)); 388 *number = print_queue_snum(Printer->sharename); 389 return (*number != -1); 390 case SPLHND_SERVER: 391 return False; 392 default: 393 return False; 394 } 395} 396 397/**************************************************************************** 398 Set printer handle type. 399 Check if it's \\server or \\server\printer 400****************************************************************************/ 401 402static BOOL set_printer_hnd_printertype(Printer_entry *Printer, char *handlename) 403{ 404 DEBUG(3,("Setting printer type=%s\n", handlename)); 405 406 if ( strlen(handlename) < 3 ) { 407 DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename)); 408 return False; 409 } 410 411 /* it's a print server */ 412 if (*handlename=='\\' && *(handlename+1)=='\\' && !strchr_m(handlename+2, '\\')) { 413 DEBUGADD(4,("Printer is a print server\n")); 414 Printer->printer_type = SPLHND_SERVER; 415 } 416 /* it's a printer (set_printer_hnd_name() will handle port monitors */ 417 else { 418 DEBUGADD(4,("Printer is a printer\n")); 419 Printer->printer_type = SPLHND_PRINTER; 420 } 421 422 return True; 423} 424 425/**************************************************************************** 426 Set printer handle name.. Accept names like \\server, \\server\printer, 427 \\server\SHARE, & "\\server\,XcvMonitor Standard TCP/IP Port" See 428 the MSDN docs regarding OpenPrinter() for details on the XcvData() and 429 XcvDataPort() interface. 430****************************************************************************/ 431 432static BOOL set_printer_hnd_name(Printer_entry *Printer, char *handlename) 433{ 434 int snum; 435 int n_services=lp_numservices(); 436 char *aprinter, *printername; 437 const char *servername; 438 fstring sname; 439 BOOL found=False; 440 NT_PRINTER_INFO_LEVEL *printer = NULL; 441 WERROR result; 442 443 DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename))); 444 445 aprinter = handlename; 446 if ( *handlename == '\\' ) { 447 servername = handlename + 2; 448 if ( (aprinter = strchr_m( handlename+2, '\\' )) != NULL ) { 449 *aprinter = '\0'; 450 aprinter++; 451 } 452 } 453 else { 454 servername = ""; 455 } 456 457 /* save the servername to fill in replies on this handle */ 458 459 if ( !is_myname_or_ipaddr( servername ) ) 460 return False; 461 462 fstrcpy( Printer->servername, servername ); 463 464 if ( Printer->printer_type == SPLHND_SERVER ) 465 return True; 466 467 if ( Printer->printer_type != SPLHND_PRINTER ) 468 return False; 469 470 DEBUGADD(5, ("searching for [%s]\n", aprinter )); 471 472 /* check for the Port Monitor Interface */ 473 474 if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) { 475 Printer->printer_type = SPLHND_PORTMON_TCP; 476 fstrcpy(sname, SPL_XCV_MONITOR_TCPMON); 477 found = True; 478 } 479 else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) { 480 Printer->printer_type = SPLHND_PORTMON_LOCAL; 481 fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON); 482 found = True; 483 } 484 485 /* Search all sharenames first as this is easier than pulling 486 the printer_info_2 off of disk. Don't use find_service() since 487 that calls out to map_username() */ 488 489 /* do another loop to look for printernames */ 490 491 for (snum=0; !found && snum<n_services; snum++) { 492 493 /* no point going on if this is not a printer */ 494 495 if ( !(lp_snum_ok(snum) && lp_print_ok(snum)) ) 496 continue; 497 498 fstrcpy(sname, lp_servicename(snum)); 499 if ( strequal( aprinter, sname ) ) { 500 found = True; 501 break; 502 } 503 504 /* no point looking up the printer object if 505 we aren't allowing printername != sharename */ 506 507 if ( lp_force_printername(snum) ) 508 continue; 509 510 fstrcpy(sname, lp_servicename(snum)); 511 512 printer = NULL; 513 result = get_a_printer( NULL, &printer, 2, sname ); 514 if ( !W_ERROR_IS_OK(result) ) { 515 DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n", 516 sname, dos_errstr(result))); 517 continue; 518 } 519 520 /* printername is always returned as \\server\printername */ 521 if ( !(printername = strchr_m(&printer->info_2->printername[2], '\\')) ) { 522 DEBUG(0,("set_printer_hnd_name: info2->printername in wrong format! [%s]\n", 523 printer->info_2->printername)); 524 free_a_printer( &printer, 2); 525 continue; 526 } 527 528 printername++; 529 530 if ( strequal(printername, aprinter) ) { 531 free_a_printer( &printer, 2); 532 found = True; 533 break; 534 } 535 536 DEBUGADD(10, ("printername: %s\n", printername)); 537 538 free_a_printer( &printer, 2); 539 } 540 541 free_a_printer( &printer, 2); 542 543 if ( !found ) { 544 DEBUGADD(4,("Printer not found\n")); 545 return False; 546 } 547 548 DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname)); 549 550 fstrcpy(Printer->sharename, sname); 551 552 return True; 553} 554 555/**************************************************************************** 556 Find first available printer slot. creates a printer handle for you. 557 ****************************************************************************/ 558 559static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint32 access_granted) 560{ 561 Printer_entry *new_printer; 562 563 DEBUG(10,("open_printer_hnd: name [%s]\n", name)); 564 565 if((new_printer=SMB_MALLOC_P(Printer_entry)) == NULL) 566 return False; 567 568 ZERO_STRUCTP(new_printer); 569 570 if (!create_policy_hnd(p, hnd, free_printer_entry, new_printer)) { 571 SAFE_FREE(new_printer); 572 return False; 573 } 574 575 /* Add to the internal list. */ 576 DLIST_ADD(printers_list, new_printer); 577 578 new_printer->notify.option=NULL; 579 580 if ( !(new_printer->ctx = talloc_init("Printer Entry [%p]", hnd)) ) { 581 DEBUG(0,("open_printer_hnd: talloc_init() failed!\n")); 582 close_printer_handle(p, hnd); 583 return False; 584 } 585 586 if (!set_printer_hnd_printertype(new_printer, name)) { 587 close_printer_handle(p, hnd); 588 return False; 589 } 590 591 if (!set_printer_hnd_name(new_printer, name)) { 592 close_printer_handle(p, hnd); 593 return False; 594 } 595 596 new_printer->access_granted = access_granted; 597 598 DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count )); 599 600 return True; 601} 602 603/*************************************************************************** 604 check to see if the client motify handle is monitoring the notification 605 given by (notify_type, notify_field). 606 **************************************************************************/ 607 608static BOOL is_monitoring_event_flags(uint32 flags, uint16 notify_type, 609 uint16 notify_field) 610{ 611 return True; 612} 613 614static BOOL is_monitoring_event(Printer_entry *p, uint16 notify_type, 615 uint16 notify_field) 616{ 617 SPOOL_NOTIFY_OPTION *option = p->notify.option; 618 uint32 i, j; 619 620 /* 621 * Flags should always be zero when the change notify 622 * is registered by the client's spooler. A user Win32 app 623 * might use the flags though instead of the NOTIFY_OPTION_INFO 624 * --jerry 625 */ 626 627 if (!option) { 628 return False; 629 } 630 631 if (p->notify.flags) 632 return is_monitoring_event_flags( 633 p->notify.flags, notify_type, notify_field); 634 635 for (i = 0; i < option->count; i++) { 636 637 /* Check match for notify_type */ 638 639 if (option->ctr.type[i].type != notify_type) 640 continue; 641 642 /* Check match for field */ 643 644 for (j = 0; j < option->ctr.type[i].count; j++) { 645 if (option->ctr.type[i].fields[j] == notify_field) { 646 return True; 647 } 648 } 649 } 650 651 DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n", 652 p->servername, p->sharename, notify_type, notify_field)); 653 654 return False; 655} 656 657/* Convert a notification message to a SPOOL_NOTIFY_INFO_DATA struct */ 658 659static void notify_one_value(struct spoolss_notify_msg *msg, 660 SPOOL_NOTIFY_INFO_DATA *data, 661 TALLOC_CTX *mem_ctx) 662{ 663 data->notify_data.value[0] = msg->notify.value[0]; 664 data->notify_data.value[1] = 0; 665} 666 667static void notify_string(struct spoolss_notify_msg *msg, 668 SPOOL_NOTIFY_INFO_DATA *data, 669 TALLOC_CTX *mem_ctx) 670{ 671 UNISTR2 unistr; 672 673 /* The length of the message includes the trailing \0 */ 674 675 init_unistr2(&unistr, msg->notify.data, UNI_STR_TERMINATE); 676 677 data->notify_data.data.length = msg->len * 2; 678 data->notify_data.data.string = TALLOC_ARRAY(mem_ctx, uint16, msg->len); 679 680 if (!data->notify_data.data.string) { 681 data->notify_data.data.length = 0; 682 return; 683 } 684 685 memcpy(data->notify_data.data.string, unistr.buffer, msg->len * 2); 686} 687 688static void notify_system_time(struct spoolss_notify_msg *msg, 689 SPOOL_NOTIFY_INFO_DATA *data, 690 TALLOC_CTX *mem_ctx) 691{ 692 SYSTEMTIME systime; 693 prs_struct ps; 694 695 if (msg->len != sizeof(time_t)) { 696 DEBUG(5, ("notify_system_time: received wrong sized message (%d)\n", 697 msg->len)); 698 return; 699 } 700 701 if (!prs_init(&ps, RPC_MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL)) { 702 DEBUG(5, ("notify_system_time: prs_init() failed\n")); 703 return; 704 } 705 706 if (!make_systemtime(&systime, gmtime((time_t *)msg->notify.data))) { 707 DEBUG(5, ("notify_system_time: unable to make systemtime\n")); 708 prs_mem_free(&ps); 709 return; 710 } 711 712 if (!spoolss_io_system_time("", &ps, 0, &systime)) { 713 prs_mem_free(&ps); 714 return; 715 } 716 717 data->notify_data.data.length = prs_offset(&ps); 718 if (prs_offset(&ps)) { 719 data->notify_data.data.string = (uint16 *) 720 TALLOC(mem_ctx, prs_offset(&ps)); 721 if (!data->notify_data.data.string) { 722 prs_mem_free(&ps); 723 return; 724 } 725 prs_copy_all_data_out((char *)data->notify_data.data.string, &ps); 726 } else { 727 data->notify_data.data.string = NULL; 728 } 729 730 prs_mem_free(&ps); 731} 732 733struct notify2_message_table { 734 const char *name; 735 void (*fn)(struct spoolss_notify_msg *msg, 736 SPOOL_NOTIFY_INFO_DATA *data, TALLOC_CTX *mem_ctx); 737}; 738 739static struct notify2_message_table printer_notify_table[] = { 740 /* 0x00 */ { "PRINTER_NOTIFY_SERVER_NAME", notify_string }, 741 /* 0x01 */ { "PRINTER_NOTIFY_PRINTER_NAME", notify_string }, 742 /* 0x02 */ { "PRINTER_NOTIFY_SHARE_NAME", notify_string }, 743 /* 0x03 */ { "PRINTER_NOTIFY_PORT_NAME", notify_string }, 744 /* 0x04 */ { "PRINTER_NOTIFY_DRIVER_NAME", notify_string }, 745 /* 0x05 */ { "PRINTER_NOTIFY_COMMENT", notify_string }, 746 /* 0x06 */ { "PRINTER_NOTIFY_LOCATION", notify_string }, 747 /* 0x07 */ { "PRINTER_NOTIFY_DEVMODE", NULL }, 748 /* 0x08 */ { "PRINTER_NOTIFY_SEPFILE", notify_string }, 749 /* 0x09 */ { "PRINTER_NOTIFY_PRINT_PROCESSOR", notify_string }, 750 /* 0x0a */ { "PRINTER_NOTIFY_PARAMETERS", NULL }, 751 /* 0x0b */ { "PRINTER_NOTIFY_DATATYPE", notify_string }, 752 /* 0x0c */ { "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NULL }, 753 /* 0x0d */ { "PRINTER_NOTIFY_ATTRIBUTES", notify_one_value }, 754 /* 0x0e */ { "PRINTER_NOTIFY_PRIORITY", notify_one_value }, 755 /* 0x0f */ { "PRINTER_NOTIFY_DEFAULT_PRIORITY", NULL }, 756 /* 0x10 */ { "PRINTER_NOTIFY_START_TIME", NULL }, 757 /* 0x11 */ { "PRINTER_NOTIFY_UNTIL_TIME", NULL }, 758 /* 0x12 */ { "PRINTER_NOTIFY_STATUS", notify_one_value }, 759}; 760 761static struct notify2_message_table job_notify_table[] = { 762 /* 0x00 */ { "JOB_NOTIFY_PRINTER_NAME", NULL }, 763 /* 0x01 */ { "JOB_NOTIFY_MACHINE_NAME", NULL }, 764 /* 0x02 */ { "JOB_NOTIFY_PORT_NAME", NULL }, 765 /* 0x03 */ { "JOB_NOTIFY_USER_NAME", notify_string }, 766 /* 0x04 */ { "JOB_NOTIFY_NOTIFY_NAME", NULL }, 767 /* 0x05 */ { "JOB_NOTIFY_DATATYPE", NULL }, 768 /* 0x06 */ { "JOB_NOTIFY_PRINT_PROCESSOR", NULL }, 769 /* 0x07 */ { "JOB_NOTIFY_PARAMETERS", NULL }, 770 /* 0x08 */ { "JOB_NOTIFY_DRIVER_NAME", NULL }, 771 /* 0x09 */ { "JOB_NOTIFY_DEVMODE", NULL }, 772 /* 0x0a */ { "JOB_NOTIFY_STATUS", notify_one_value }, 773 /* 0x0b */ { "JOB_NOTIFY_STATUS_STRING", NULL }, 774 /* 0x0c */ { "JOB_NOTIFY_SECURITY_DESCRIPTOR", NULL }, 775 /* 0x0d */ { "JOB_NOTIFY_DOCUMENT", notify_string }, 776 /* 0x0e */ { "JOB_NOTIFY_PRIORITY", NULL }, 777 /* 0x0f */ { "JOB_NOTIFY_POSITION", NULL }, 778 /* 0x10 */ { "JOB_NOTIFY_SUBMITTED", notify_system_time }, 779 /* 0x11 */ { "JOB_NOTIFY_START_TIME", NULL }, 780 /* 0x12 */ { "JOB_NOTIFY_UNTIL_TIME", NULL }, 781 /* 0x13 */ { "JOB_NOTIFY_TIME", NULL }, 782 /* 0x14 */ { "JOB_NOTIFY_TOTAL_PAGES", notify_one_value }, 783 /* 0x15 */ { "JOB_NOTIFY_PAGES_PRINTED", NULL }, 784 /* 0x16 */ { "JOB_NOTIFY_TOTAL_BYTES", notify_one_value }, 785 /* 0x17 */ { "JOB_NOTIFY_BYTES_PRINTED", NULL }, 786}; 787 788 789/*********************************************************************** 790 Allocate talloc context for container object 791 **********************************************************************/ 792 793static void notify_msg_ctr_init( SPOOLSS_NOTIFY_MSG_CTR *ctr ) 794{ 795 if ( !ctr ) 796 return; 797 798 ctr->ctx = talloc_init("notify_msg_ctr_init %p", ctr); 799 800 return; 801} 802 803/*********************************************************************** 804 release all allocated memory and zero out structure 805 **********************************************************************/ 806 807static void notify_msg_ctr_destroy( SPOOLSS_NOTIFY_MSG_CTR *ctr ) 808{ 809 if ( !ctr ) 810 return; 811 812 if ( ctr->ctx ) 813 talloc_destroy(ctr->ctx); 814 815 ZERO_STRUCTP(ctr); 816 817 return; 818} 819 820/*********************************************************************** 821 **********************************************************************/ 822 823static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr ) 824{ 825 if ( !ctr ) 826 return NULL; 827 828 return ctr->ctx; 829} 830 831/*********************************************************************** 832 **********************************************************************/ 833 834static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) 835{ 836 if ( !ctr || !ctr->msg_groups ) 837 return NULL; 838 839 if ( idx >= ctr->num_groups ) 840 return NULL; 841 842 return &ctr->msg_groups[idx]; 843 844} 845 846/*********************************************************************** 847 How many groups of change messages do we have ? 848 **********************************************************************/ 849 850static int notify_msg_ctr_numgroups( SPOOLSS_NOTIFY_MSG_CTR *ctr ) 851{ 852 if ( !ctr ) 853 return 0; 854 855 return ctr->num_groups; 856} 857 858/*********************************************************************** 859 Add a SPOOLSS_NOTIFY_MSG_CTR to the correct group 860 **********************************************************************/ 861 862static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MSG *msg ) 863{ 864 SPOOLSS_NOTIFY_MSG_GROUP *groups = NULL; 865 SPOOLSS_NOTIFY_MSG_GROUP *msg_grp = NULL; 866 SPOOLSS_NOTIFY_MSG *msg_list = NULL; 867 int i, new_slot; 868 869 if ( !ctr || !msg ) 870 return 0; 871 872 /* loop over all groups looking for a matching printer name */ 873 874 for ( i=0; i<ctr->num_groups; i++ ) { 875 if ( strcmp(ctr->msg_groups[i].printername, msg->printer) == 0 ) 876 break; 877 } 878 879 /* add a new group? */ 880 881 if ( i == ctr->num_groups ) { 882 ctr->num_groups++; 883 884 if ( !(groups = TALLOC_REALLOC_ARRAY( ctr->ctx, ctr->msg_groups, SPOOLSS_NOTIFY_MSG_GROUP, ctr->num_groups)) ) { 885 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed!\n")); 886 return 0; 887 } 888 ctr->msg_groups = groups; 889 890 /* clear the new entry and set the printer name */ 891 892 ZERO_STRUCT( ctr->msg_groups[ctr->num_groups-1] ); 893 fstrcpy( ctr->msg_groups[ctr->num_groups-1].printername, msg->printer ); 894 } 895 896 /* add the change messages; 'i' is the correct index now regardless */ 897 898 msg_grp = &ctr->msg_groups[i]; 899 900 msg_grp->num_msgs++; 901 902 if ( !(msg_list = TALLOC_REALLOC_ARRAY( ctr->ctx, msg_grp->msgs, SPOOLSS_NOTIFY_MSG, msg_grp->num_msgs )) ) { 903 DEBUG(0,("notify_msg_ctr_addmsg: talloc_realloc() failed for new message [%d]!\n", msg_grp->num_msgs)); 904 return 0; 905 } 906 msg_grp->msgs = msg_list; 907 908 new_slot = msg_grp->num_msgs-1; 909 memcpy( &msg_grp->msgs[new_slot], msg, sizeof(SPOOLSS_NOTIFY_MSG) ); 910 911 /* need to allocate own copy of data */ 912 913 if ( msg->len != 0 ) 914 msg_grp->msgs[new_slot].notify.data = (char *) 915 TALLOC_MEMDUP( ctr->ctx, msg->notify.data, msg->len ); 916 917 return ctr->num_groups; 918} 919 920/*********************************************************************** 921 Send a change notication message on all handles which have a call 922 back registered 923 **********************************************************************/ 924 925static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) 926{ 927 Printer_entry *p; 928 TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr ); 929 SPOOLSS_NOTIFY_MSG_GROUP *msg_group = notify_ctr_getgroup( ctr, idx ); 930 SPOOLSS_NOTIFY_MSG *messages; 931 int sending_msg_count; 932 933 if ( !msg_group ) { 934 DEBUG(5,("send_notify2_changes() called with no msg group!\n")); 935 return; 936 } 937 938 messages = msg_group->msgs; 939 940 if ( !messages ) { 941 DEBUG(5,("send_notify2_changes() called with no messages!\n")); 942 return; 943 } 944 945 DEBUG(8,("send_notify2_changes: Enter...[%s]\n", msg_group->printername)); 946 947 /* loop over all printers */ 948 949 for (p = printers_list; p; p = p->next) { 950 SPOOL_NOTIFY_INFO_DATA *data; 951 uint32 data_len = 0; 952 uint32 id; 953 int i; 954 955 /* Is there notification on this handle? */ 956 957 if ( !p->notify.client_connected ) 958 continue; 959 960 DEBUG(10,("Client connected! [\\\\%s\\%s]\n", p->servername, p->sharename)); 961 962 /* For this printer? Print servers always receive 963 notifications. */ 964 965 if ( ( p->printer_type == SPLHND_PRINTER ) && 966 ( !strequal(msg_group->printername, p->sharename) ) ) 967 continue; 968 969 DEBUG(10,("Our printer\n")); 970 971 /* allocate the max entries possible */ 972 973 data = TALLOC_ARRAY( mem_ctx, SPOOL_NOTIFY_INFO_DATA, msg_group->num_msgs); 974 if (!data) { 975 return; 976 } 977 978 ZERO_STRUCTP(data); 979 980 /* build the array of change notifications */ 981 982 sending_msg_count = 0; 983 984 for ( i=0; i<msg_group->num_msgs; i++ ) { 985 SPOOLSS_NOTIFY_MSG *msg = &messages[i]; 986 987 /* Are we monitoring this event? */ 988 989 if (!is_monitoring_event(p, msg->type, msg->field)) 990 continue; 991 992 sending_msg_count++; 993 994 995 DEBUG(10,("process_notify2_message: Sending message type [0x%x] field [0x%2x] for printer [%s]\n", 996 msg->type, msg->field, p->sharename)); 997 998 /* 999 * if the is a printer notification handle and not a job notification 1000 * type, then set the id to 0. Other wise just use what was specified 1001 * in the message. 1002 * 1003 * When registering change notification on a print server handle 1004 * we always need to send back the id (snum) matching the printer 1005 * for which the change took place. For change notify registered 1006 * on a printer handle, this does not matter and the id should be 0. 1007 * 1008 * --jerry 1009 */ 1010 1011 if ( ( p->printer_type == SPLHND_PRINTER ) && ( msg->type == PRINTER_NOTIFY_TYPE ) ) 1012 id = 0; 1013 else 1014 id = msg->id; 1015 1016 1017 /* Convert unix jobid to smb jobid */ 1018 1019 if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) { 1020 id = sysjob_to_jobid(msg->id); 1021 1022 if (id == -1) { 1023 DEBUG(3, ("no such unix jobid %d\n", msg->id)); 1024 goto done; 1025 } 1026 } 1027 1028 construct_info_data( &data[data_len], msg->type, msg->field, id ); 1029 1030 switch(msg->type) { 1031 case PRINTER_NOTIFY_TYPE: 1032 if ( printer_notify_table[msg->field].fn ) 1033 printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx); 1034 break; 1035 1036 case JOB_NOTIFY_TYPE: 1037 if ( job_notify_table[msg->field].fn ) 1038 job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx); 1039 break; 1040 1041 default: 1042 DEBUG(5, ("Unknown notification type %d\n", msg->type)); 1043 goto done; 1044 } 1045 1046 data_len++; 1047 } 1048 1049 if ( sending_msg_count ) { 1050 rpccli_spoolss_rrpcn( notify_cli_pipe, mem_ctx, &p->notify.client_hnd, 1051 data_len, data, p->notify.change, 0 ); 1052 } 1053 } 1054 1055done: 1056 DEBUG(8,("send_notify2_changes: Exit...\n")); 1057 return; 1058} 1059 1060/*********************************************************************** 1061 **********************************************************************/ 1062 1063static BOOL notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len ) 1064{ 1065 1066 uint32 tv_sec, tv_usec; 1067 size_t offset = 0; 1068 1069 /* Unpack message */ 1070 1071 offset += tdb_unpack((char *)buf + offset, len - offset, "f", 1072 msg->printer); 1073 1074 offset += tdb_unpack((char *)buf + offset, len - offset, "ddddddd", 1075 &tv_sec, &tv_usec, 1076 &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags); 1077 1078 if (msg->len == 0) 1079 tdb_unpack((char *)buf + offset, len - offset, "dd", 1080 &msg->notify.value[0], &msg->notify.value[1]); 1081 else 1082 tdb_unpack((char *)buf + offset, len - offset, "B", 1083 &msg->len, &msg->notify.data); 1084 1085 DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n", 1086 msg->printer, (unsigned int)msg->id, msg->type, msg->field, msg->flags)); 1087 1088 tv->tv_sec = tv_sec; 1089 tv->tv_usec = tv_usec; 1090 1091 if (msg->len == 0) 1092 DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0], 1093 msg->notify.value[1])); 1094 else 1095 dump_data(3, msg->notify.data, msg->len); 1096 1097 return True; 1098} 1099 1100/******************************************************************** 1101 Receive a notify2 message list 1102 ********************************************************************/ 1103 1104static void receive_notify2_message_list(int msg_type, struct process_id src, 1105 void *msg, size_t len, 1106 void *private_data) 1107{ 1108 size_t msg_count, i; 1109 char *buf = (char *)msg; 1110 char *msg_ptr; 1111 size_t msg_len; 1112 SPOOLSS_NOTIFY_MSG notify; 1113 SPOOLSS_NOTIFY_MSG_CTR messages; 1114 int num_groups; 1115 1116 if (len < 4) { 1117 DEBUG(0,("receive_notify2_message_list: bad message format (len < 4)!\n")); 1118 return; 1119 } 1120 1121 msg_count = IVAL(buf, 0); 1122 msg_ptr = buf + 4; 1123 1124 DEBUG(5, ("receive_notify2_message_list: got %lu messages in list\n", (unsigned long)msg_count)); 1125 1126 if (msg_count == 0) { 1127 DEBUG(0,("receive_notify2_message_list: bad message format (msg_count == 0) !\n")); 1128 return; 1129 } 1130 1131 /* initialize the container */ 1132 1133 ZERO_STRUCT( messages ); 1134 notify_msg_ctr_init( &messages ); 1135 1136 /* 1137 * build message groups for each printer identified 1138 * in a change_notify msg. Remember that a PCN message 1139 * includes the handle returned for the srv_spoolss_replyopenprinter() 1140 * call. Therefore messages are grouped according to printer handle. 1141 */ 1142 1143 for ( i=0; i<msg_count; i++ ) { 1144 struct timeval msg_tv; 1145 1146 if (msg_ptr + 4 - buf > len) { 1147 DEBUG(0,("receive_notify2_message_list: bad message format (len > buf_size) !\n")); 1148 return; 1149 } 1150 1151 msg_len = IVAL(msg_ptr,0); 1152 msg_ptr += 4; 1153 1154 if (msg_ptr + msg_len - buf > len) { 1155 DEBUG(0,("receive_notify2_message_list: bad message format (bad len) !\n")); 1156 return; 1157 } 1158 1159 /* unpack messages */ 1160 1161 ZERO_STRUCT( notify ); 1162 notify2_unpack_msg( ¬ify, &msg_tv, msg_ptr, msg_len ); 1163 msg_ptr += msg_len; 1164 1165 /* add to correct list in container */ 1166 1167 notify_msg_ctr_addmsg( &messages, ¬ify ); 1168 1169 /* free memory that might have been allocated by notify2_unpack_msg() */ 1170 1171 if ( notify.len != 0 ) 1172 SAFE_FREE( notify.notify.data ); 1173 } 1174 1175 /* process each group of messages */ 1176 1177 num_groups = notify_msg_ctr_numgroups( &messages ); 1178 for ( i=0; i<num_groups; i++ ) 1179 send_notify2_changes( &messages, i ); 1180 1181 1182 /* cleanup */ 1183 1184 DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count )); 1185 1186 notify_msg_ctr_destroy( &messages ); 1187 1188 return; 1189} 1190 1191/******************************************************************** 1192 Send a message to ourself about new driver being installed 1193 so we can upgrade the information for each printer bound to this 1194 driver 1195 ********************************************************************/ 1196 1197static BOOL srv_spoolss_drv_upgrade_printer(char* drivername) 1198{ 1199 int len = strlen(drivername); 1200 1201 if (!len) 1202 return False; 1203 1204 DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n", 1205 drivername)); 1206 1207 message_send_pid(pid_to_procid(sys_getpid()), 1208 MSG_PRINTER_DRVUPGRADE, drivername, len+1, False); 1209 1210 return True; 1211} 1212 1213/********************************************************************** 1214 callback to receive a MSG_PRINTER_DRVUPGRADE message and interate 1215 over all printers, upgrading ones as necessary 1216 **********************************************************************/ 1217 1218void do_drv_upgrade_printer(int msg_type, struct process_id src, 1219 void *buf, size_t len, void *private_data) 1220{ 1221 fstring drivername; 1222 int snum; 1223 int n_services = lp_numservices(); 1224 1225 len = MIN(len,sizeof(drivername)-1); 1226 strncpy(drivername, (const char *)buf, len); 1227 1228 DEBUG(10,("do_drv_upgrade_printer: Got message for new driver [%s]\n", drivername )); 1229 1230 /* Iterate the printer list */ 1231 1232 for (snum=0; snum<n_services; snum++) 1233 { 1234 if (lp_snum_ok(snum) && lp_print_ok(snum) ) 1235 { 1236 WERROR result; 1237 NT_PRINTER_INFO_LEVEL *printer = NULL; 1238 1239 result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum)); 1240 if (!W_ERROR_IS_OK(result)) 1241 continue; 1242 1243 if (printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername)) 1244 { 1245 DEBUG(6,("Updating printer [%s]\n", printer->info_2->printername)); 1246 1247 /* all we care about currently is the change_id */ 1248 1249 result = mod_a_printer(printer, 2); 1250 if (!W_ERROR_IS_OK(result)) { 1251 DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n", 1252 dos_errstr(result))); 1253 } 1254 } 1255 1256 free_a_printer(&printer, 2); 1257 } 1258 } 1259 1260 /* all done */ 1261} 1262 1263/******************************************************************** 1264 Update the cache for all printq's with a registered client 1265 connection 1266 ********************************************************************/ 1267 1268void update_monitored_printq_cache( void ) 1269{ 1270 Printer_entry *printer = printers_list; 1271 int snum; 1272 1273 /* loop through all printers and update the cache where 1274 client_connected == True */ 1275 while ( printer ) 1276 { 1277 if ( (printer->printer_type == SPLHND_PRINTER) 1278 && printer->notify.client_connected ) 1279 { 1280 snum = print_queue_snum(printer->sharename); 1281 print_queue_status( snum, NULL, NULL ); 1282 } 1283 1284 printer = printer->next; 1285 } 1286 1287 return; 1288} 1289/******************************************************************** 1290 Send a message to ourself about new driver being installed 1291 so we can upgrade the information for each printer bound to this 1292 driver 1293 ********************************************************************/ 1294 1295static BOOL srv_spoolss_reset_printerdata(char* drivername) 1296{ 1297 int len = strlen(drivername); 1298 1299 if (!len) 1300 return False; 1301 1302 DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n", 1303 drivername)); 1304 1305 message_send_pid(pid_to_procid(sys_getpid()), 1306 MSG_PRINTERDATA_INIT_RESET, drivername, len+1, False); 1307 1308 return True; 1309} 1310 1311/********************************************************************** 1312 callback to receive a MSG_PRINTERDATA_INIT_RESET message and interate 1313 over all printers, resetting printer data as neessary 1314 **********************************************************************/ 1315 1316void reset_all_printerdata(int msg_type, struct process_id src, 1317 void *buf, size_t len, void *private_data) 1318{ 1319 fstring drivername; 1320 int snum; 1321 int n_services = lp_numservices(); 1322 1323 len = MIN( len, sizeof(drivername)-1 ); 1324 strncpy( drivername, (const char *)buf, len ); 1325 1326 DEBUG(10,("reset_all_printerdata: Got message for new driver [%s]\n", drivername )); 1327 1328 /* Iterate the printer list */ 1329 1330 for ( snum=0; snum<n_services; snum++ ) 1331 { 1332 if ( lp_snum_ok(snum) && lp_print_ok(snum) ) 1333 { 1334 WERROR result; 1335 NT_PRINTER_INFO_LEVEL *printer = NULL; 1336 1337 result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) ); 1338 if ( !W_ERROR_IS_OK(result) ) 1339 continue; 1340 1341 /* 1342 * if the printer is bound to the driver, 1343 * then reset to the new driver initdata 1344 */ 1345 1346 if ( printer && printer->info_2 && !strcmp(drivername, printer->info_2->drivername) ) 1347 { 1348 DEBUG(6,("reset_all_printerdata: Updating printer [%s]\n", printer->info_2->printername)); 1349 1350 if ( !set_driver_init(printer, 2) ) { 1351 DEBUG(5,("reset_all_printerdata: Error resetting printer data for printer [%s], driver [%s]!\n", 1352 printer->info_2->printername, printer->info_2->drivername)); 1353 } 1354 1355 result = mod_a_printer( printer, 2 ); 1356 if ( !W_ERROR_IS_OK(result) ) { 1357 DEBUG(3,("reset_all_printerdata: mod_a_printer() failed! (%s)\n", 1358 get_dos_error_msg(result))); 1359 } 1360 } 1361 1362 free_a_printer( &printer, 2 ); 1363 } 1364 } 1365 1366 /* all done */ 1367 1368 return; 1369} 1370 1371/******************************************************************** 1372 Copy routines used by convert_to_openprinterex() 1373 *******************************************************************/ 1374 1375static DEVICEMODE* dup_devicemode(TALLOC_CTX *ctx, DEVICEMODE *devmode) 1376{ 1377 DEVICEMODE *d; 1378 int len; 1379 1380 if (!devmode) 1381 return NULL; 1382 1383 DEBUG (8,("dup_devmode\n")); 1384 1385 /* bulk copy first */ 1386 1387 d = (DEVICEMODE *)TALLOC_MEMDUP(ctx, devmode, sizeof(DEVICEMODE)); 1388 if (!d) 1389 return NULL; 1390 1391 /* dup the pointer members separately */ 1392 1393 len = unistrlen(devmode->devicename.buffer); 1394 if (len != -1) { 1395 d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len); 1396 if (!d->devicename.buffer) { 1397 return NULL; 1398 } 1399 if (unistrcpy(d->devicename.buffer, devmode->devicename.buffer) != len) 1400 return NULL; 1401 } 1402 1403 1404 len = unistrlen(devmode->formname.buffer); 1405 if (len != -1) { 1406 d->devicename.buffer = TALLOC_ARRAY(ctx, uint16, len); 1407 if (!d->devicename.buffer) { 1408 return NULL; 1409 } 1410 if (unistrcpy(d->formname.buffer, devmode->formname.buffer) != len) 1411 return NULL; 1412 } 1413 1414 if (devmode->driverextra) { 1415 d->dev_private = (uint8 *)TALLOC_MEMDUP(ctx, devmode->dev_private, 1416 devmode->driverextra); 1417 if (!d->dev_private) { 1418 return NULL; 1419 } 1420 } else { 1421 d->dev_private = NULL; 1422 } 1423 return d; 1424} 1425 1426static void copy_devmode_ctr(TALLOC_CTX *ctx, DEVMODE_CTR *new_ctr, DEVMODE_CTR *ctr) 1427{ 1428 if (!new_ctr || !ctr) 1429 return; 1430 1431 DEBUG(8,("copy_devmode_ctr\n")); 1432 1433 new_ctr->size = ctr->size; 1434 new_ctr->devmode_ptr = ctr->devmode_ptr; 1435 1436 if(ctr->devmode_ptr) 1437 new_ctr->devmode = dup_devicemode(ctx, ctr->devmode); 1438} 1439 1440static void copy_printer_default(TALLOC_CTX *ctx, PRINTER_DEFAULT *new_def, PRINTER_DEFAULT *def) 1441{ 1442 if (!new_def || !def) 1443 return; 1444 1445 DEBUG(8,("copy_printer_defaults\n")); 1446 1447 new_def->datatype_ptr = def->datatype_ptr; 1448 1449 if (def->datatype_ptr) 1450 copy_unistr2(&new_def->datatype, &def->datatype); 1451 1452 copy_devmode_ctr(ctx, &new_def->devmode_cont, &def->devmode_cont); 1453 1454 new_def->access_required = def->access_required; 1455} 1456 1457/******************************************************************** 1458 * Convert a SPOOL_Q_OPEN_PRINTER structure to a 1459 * SPOOL_Q_OPEN_PRINTER_EX structure 1460 ********************************************************************/ 1461 1462static WERROR convert_to_openprinterex(TALLOC_CTX *ctx, SPOOL_Q_OPEN_PRINTER_EX *q_u_ex, SPOOL_Q_OPEN_PRINTER *q_u) 1463{ 1464 if (!q_u_ex || !q_u) 1465 return WERR_OK; 1466 1467 DEBUG(8,("convert_to_openprinterex\n")); 1468 1469 if ( q_u->printername ) { 1470 q_u_ex->printername = TALLOC_ZERO_P( ctx, UNISTR2 ); 1471 if (q_u_ex->printername == NULL) 1472 return WERR_NOMEM; 1473 copy_unistr2(q_u_ex->printername, q_u->printername); 1474 } 1475 1476 copy_printer_default(ctx, &q_u_ex->printer_default, &q_u->printer_default); 1477 1478 return WERR_OK; 1479} 1480 1481/******************************************************************** 1482 * spoolss_open_printer 1483 * 1484 * called from the spoolss dispatcher 1485 ********************************************************************/ 1486 1487WERROR _spoolss_open_printer(pipes_struct *p, SPOOL_Q_OPEN_PRINTER *q_u, SPOOL_R_OPEN_PRINTER *r_u) 1488{ 1489 SPOOL_Q_OPEN_PRINTER_EX q_u_ex; 1490 SPOOL_R_OPEN_PRINTER_EX r_u_ex; 1491 1492 if (!q_u || !r_u) 1493 return WERR_NOMEM; 1494 1495 ZERO_STRUCT(q_u_ex); 1496 ZERO_STRUCT(r_u_ex); 1497 1498 /* convert the OpenPrinter() call to OpenPrinterEx() */ 1499 1500 r_u_ex.status = convert_to_openprinterex(p->mem_ctx, &q_u_ex, q_u); 1501 if (!W_ERROR_IS_OK(r_u_ex.status)) 1502 return r_u_ex.status; 1503 1504 r_u_ex.status = _spoolss_open_printer_ex(p, &q_u_ex, &r_u_ex); 1505 1506 /* convert back to OpenPrinter() */ 1507 1508 memcpy(r_u, &r_u_ex, sizeof(*r_u)); 1509 1510 return r_u->status; 1511} 1512 1513/******************************************************************** 1514 ********************************************************************/ 1515 1516WERROR _spoolss_open_printer_ex( pipes_struct *p, SPOOL_Q_OPEN_PRINTER_EX *q_u, SPOOL_R_OPEN_PRINTER_EX *r_u) 1517{ 1518 PRINTER_DEFAULT *printer_default = &q_u->printer_default; 1519 POLICY_HND *handle = &r_u->handle; 1520 1521 fstring name; 1522 int snum; 1523 struct current_user user; 1524 Printer_entry *Printer=NULL; 1525 1526 if ( !q_u->printername ) 1527 return WERR_INVALID_PRINTER_NAME; 1528 1529 /* some sanity check because you can open a printer or a print server */ 1530 /* aka: \\server\printer or \\server */ 1531 1532 unistr2_to_ascii(name, q_u->printername, sizeof(name)-1); 1533 1534 DEBUGADD(3,("checking name: %s\n",name)); 1535 1536 if (!open_printer_hnd(p, handle, name, 0)) 1537 return WERR_INVALID_PRINTER_NAME; 1538 1539 Printer=find_printer_index_by_hnd(p, handle); 1540 if ( !Printer ) { 1541 DEBUG(0,(" _spoolss_open_printer_ex: logic error. Can't find printer " 1542 "handle we created for printer %s\n", name )); 1543 close_printer_handle(p,handle); 1544 return WERR_INVALID_PRINTER_NAME; 1545 } 1546 1547 get_current_user(&user, p); 1548 1549 /* 1550 * First case: the user is opening the print server: 1551 * 1552 * Disallow MS AddPrinterWizard if parameter disables it. A Win2k 1553 * client 1st tries an OpenPrinterEx with access==0, MUST be allowed. 1554 * 1555 * Then both Win2k and WinNT clients try an OpenPrinterEx with 1556 * SERVER_ALL_ACCESS, which we allow only if the user is root (uid=0) 1557 * or if the user is listed in the smb.conf printer admin parameter. 1558 * 1559 * Then they try OpenPrinterEx with SERVER_READ which we allow. This lets the 1560 * client view printer folder, but does not show the MSAPW. 1561 * 1562 * Note: this test needs code to check access rights here too. Jeremy 1563 * could you look at this? 1564 * 1565 * Second case: the user is opening a printer: 1566 * NT doesn't let us connect to a printer if the connecting user 1567 * doesn't have print permission. 1568 * 1569 * Third case: user is opening a Port Monitor 1570 * access checks same as opening a handle to the print server. 1571 */ 1572 1573 switch (Printer->printer_type ) 1574 { 1575 case SPLHND_SERVER: 1576 case SPLHND_PORTMON_TCP: 1577 case SPLHND_PORTMON_LOCAL: 1578 /* Printserver handles use global struct... */ 1579 1580 snum = -1; 1581 1582 /* Map standard access rights to object specific access rights */ 1583 1584 se_map_standard(&printer_default->access_required, 1585 &printserver_std_mapping); 1586 1587 /* Deny any object specific bits that don't apply to print 1588 servers (i.e printer and job specific bits) */ 1589 1590 printer_default->access_required &= SPECIFIC_RIGHTS_MASK; 1591 1592 if (printer_default->access_required & 1593 ~(SERVER_ACCESS_ADMINISTER | SERVER_ACCESS_ENUMERATE)) { 1594 DEBUG(3, ("access DENIED for non-printserver bits\n")); 1595 close_printer_handle(p, handle); 1596 return WERR_ACCESS_DENIED; 1597 } 1598 1599 /* Allow admin access */ 1600 1601 if ( printer_default->access_required & SERVER_ACCESS_ADMINISTER ) 1602 { 1603 SE_PRIV se_printop = SE_PRINT_OPERATOR; 1604 1605 if (!lp_ms_add_printer_wizard()) { 1606 close_printer_handle(p, handle); 1607 return WERR_ACCESS_DENIED; 1608 } 1609 1610 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege, 1611 and not a printer admin, then fail */ 1612 1613 if ((user.ut.uid != 0) && 1614 !user_has_privileges(user.nt_user_token, 1615 &se_printop ) && 1616 !token_contains_name_in_list( 1617 uidtoname(user.ut.uid), NULL, 1618 user.nt_user_token, 1619 lp_printer_admin(snum))) { 1620 close_printer_handle(p, handle); 1621 return WERR_ACCESS_DENIED; 1622 } 1623 1624 printer_default->access_required = SERVER_ACCESS_ADMINISTER; 1625 } 1626 else 1627 { 1628 printer_default->access_required = SERVER_ACCESS_ENUMERATE; 1629 } 1630 1631 DEBUG(4,("Setting print server access = %s\n", (printer_default->access_required == SERVER_ACCESS_ADMINISTER) 1632 ? "SERVER_ACCESS_ADMINISTER" : "SERVER_ACCESS_ENUMERATE" )); 1633 1634 /* We fall through to return WERR_OK */ 1635 break; 1636 1637 case SPLHND_PRINTER: 1638 /* NT doesn't let us connect to a printer if the connecting user 1639 doesn't have print permission. */ 1640 1641 if (!get_printer_snum(p, handle, &snum)) { 1642 close_printer_handle(p, handle); 1643 return WERR_BADFID; 1644 } 1645 1646 se_map_standard(&printer_default->access_required, &printer_std_mapping); 1647 1648 /* map an empty access mask to the minimum access mask */ 1649 if (printer_default->access_required == 0x0) 1650 printer_default->access_required = PRINTER_ACCESS_USE; 1651 1652 /* 1653 * If we are not serving the printer driver for this printer, 1654 * map PRINTER_ACCESS_ADMINISTER to PRINTER_ACCESS_USE. This 1655 * will keep NT clients happy --jerry 1656 */ 1657 1658 if (lp_use_client_driver(snum) 1659 && (printer_default->access_required & PRINTER_ACCESS_ADMINISTER)) 1660 { 1661 printer_default->access_required = PRINTER_ACCESS_USE; 1662 } 1663 1664 /* check smb.conf parameters and the the sec_desc */ 1665 1666 if ( !check_access(smbd_server_fd(), lp_hostsallow(snum), lp_hostsdeny(snum)) ) { 1667 DEBUG(3, ("access DENIED (hosts allow/deny) for printer open\n")); 1668 return WERR_ACCESS_DENIED; 1669 } 1670 1671 if (!user_ok_token(uidtoname(user.ut.uid), user.nt_user_token, 1672 snum) || 1673 !print_access_check(&user, snum, 1674 printer_default->access_required)) { 1675 DEBUG(3, ("access DENIED for printer open\n")); 1676 close_printer_handle(p, handle); 1677 return WERR_ACCESS_DENIED; 1678 } 1679 1680 if ((printer_default->access_required & SPECIFIC_RIGHTS_MASK)& ~(PRINTER_ACCESS_ADMINISTER|PRINTER_ACCESS_USE)) { 1681 DEBUG(3, ("access DENIED for printer open - unknown bits\n")); 1682 close_printer_handle(p, handle); 1683 return WERR_ACCESS_DENIED; 1684 } 1685 1686 if (printer_default->access_required & PRINTER_ACCESS_ADMINISTER) 1687 printer_default->access_required = PRINTER_ACCESS_ADMINISTER; 1688 else 1689 printer_default->access_required = PRINTER_ACCESS_USE; 1690 1691 DEBUG(4,("Setting printer access = %s\n", (printer_default->access_required == PRINTER_ACCESS_ADMINISTER) 1692 ? "PRINTER_ACCESS_ADMINISTER" : "PRINTER_ACCESS_USE" )); 1693 1694 break; 1695 1696 default: 1697 /* sanity check to prevent programmer error */ 1698 return WERR_BADFID; 1699 } 1700 1701 Printer->access_granted = printer_default->access_required; 1702 1703 /* 1704 * If the client sent a devmode in the OpenPrinter() call, then 1705 * save it here in case we get a job submission on this handle 1706 */ 1707 1708 if ( (Printer->printer_type != SPLHND_SERVER) 1709 && q_u->printer_default.devmode_cont.devmode_ptr ) 1710 { 1711 convert_devicemode( Printer->sharename, q_u->printer_default.devmode_cont.devmode, 1712 &Printer->nt_devmode ); 1713 } 1714 1715#if 0 /* JERRY -- I'm doubtful this is really effective */ 1716 /* HACK ALERT!!! Sleep for 1/3 of a second to try trigger a LAN/WAN 1717 optimization in Windows 2000 clients --jerry */ 1718 1719 if ( (printer_default->access_required == PRINTER_ACCESS_ADMINISTER) 1720 && (RA_WIN2K == get_remote_arch()) ) 1721 { 1722 DEBUG(10,("_spoolss_open_printer_ex: Enabling LAN/WAN hack for Win2k clients.\n")); 1723 sys_usleep( 500000 ); 1724 } 1725#endif 1726 1727 return WERR_OK; 1728} 1729 1730/**************************************************************************** 1731****************************************************************************/ 1732 1733static BOOL convert_printer_info(const SPOOL_PRINTER_INFO_LEVEL *uni, 1734 NT_PRINTER_INFO_LEVEL *printer, uint32 level) 1735{ 1736 BOOL ret; 1737 1738 switch (level) { 1739 case 2: 1740 /* allocate memory if needed. Messy because 1741 convert_printer_info is used to update an existing 1742 printer or build a new one */ 1743 1744 if ( !printer->info_2 ) { 1745 printer->info_2 = TALLOC_ZERO_P( printer, NT_PRINTER_INFO_LEVEL_2 ); 1746 if ( !printer->info_2 ) { 1747 DEBUG(0,("convert_printer_info: talloc() failed!\n")); 1748 return False; 1749 } 1750 } 1751 1752 ret = uni_2_asc_printer_info_2(uni->info_2, printer->info_2); 1753 printer->info_2->setuptime = time(NULL); 1754 1755 return ret; 1756 } 1757 1758 return False; 1759} 1760 1761static BOOL convert_printer_driver_info(const SPOOL_PRINTER_DRIVER_INFO_LEVEL *uni, 1762 NT_PRINTER_DRIVER_INFO_LEVEL *printer, uint32 level) 1763{ 1764 BOOL result = True; 1765 1766 switch (level) { 1767 case 3: 1768 printer->info_3=NULL; 1769 if (!uni_2_asc_printer_driver_3(uni->info_3, &printer->info_3)) 1770 result = False; 1771 break; 1772 case 6: 1773 printer->info_6=NULL; 1774 if (!uni_2_asc_printer_driver_6(uni->info_6, &printer->info_6)) 1775 result = False; 1776 break; 1777 default: 1778 break; 1779 } 1780 1781 return result; 1782} 1783 1784BOOL convert_devicemode(const char *printername, const DEVICEMODE *devmode, 1785 NT_DEVICEMODE **pp_nt_devmode) 1786{ 1787 NT_DEVICEMODE *nt_devmode = *pp_nt_devmode; 1788 1789 /* 1790 * Ensure nt_devmode is a valid pointer 1791 * as we will be overwriting it. 1792 */ 1793 1794 if (nt_devmode == NULL) { 1795 DEBUG(5, ("convert_devicemode: allocating a generic devmode\n")); 1796 if ((nt_devmode = construct_nt_devicemode(printername)) == NULL) 1797 return False; 1798 } 1799 1800 rpcstr_pull(nt_devmode->devicename,devmode->devicename.buffer, 31, -1, 0); 1801 rpcstr_pull(nt_devmode->formname,devmode->formname.buffer, 31, -1, 0); 1802 1803 nt_devmode->specversion=devmode->specversion; 1804 nt_devmode->driverversion=devmode->driverversion; 1805 nt_devmode->size=devmode->size; 1806 nt_devmode->fields=devmode->fields; 1807 nt_devmode->orientation=devmode->orientation; 1808 nt_devmode->papersize=devmode->papersize; 1809 nt_devmode->paperlength=devmode->paperlength; 1810 nt_devmode->paperwidth=devmode->paperwidth; 1811 nt_devmode->scale=devmode->scale; 1812 nt_devmode->copies=devmode->copies; 1813 nt_devmode->defaultsource=devmode->defaultsource; 1814 nt_devmode->printquality=devmode->printquality; 1815 nt_devmode->color=devmode->color; 1816 nt_devmode->duplex=devmode->duplex; 1817 nt_devmode->yresolution=devmode->yresolution; 1818 nt_devmode->ttoption=devmode->ttoption; 1819 nt_devmode->collate=devmode->collate; 1820 1821 nt_devmode->logpixels=devmode->logpixels; 1822 nt_devmode->bitsperpel=devmode->bitsperpel; 1823 nt_devmode->pelswidth=devmode->pelswidth; 1824 nt_devmode->pelsheight=devmode->pelsheight; 1825 nt_devmode->displayflags=devmode->displayflags; 1826 nt_devmode->displayfrequency=devmode->displayfrequency; 1827 nt_devmode->icmmethod=devmode->icmmethod; 1828 nt_devmode->icmintent=devmode->icmintent; 1829 nt_devmode->mediatype=devmode->mediatype; 1830 nt_devmode->dithertype=devmode->dithertype; 1831 nt_devmode->reserved1=devmode->reserved1; 1832 nt_devmode->reserved2=devmode->reserved2; 1833 nt_devmode->panningwidth=devmode->panningwidth; 1834 nt_devmode->panningheight=devmode->panningheight; 1835 1836 /* 1837 * Only change private and driverextra if the incoming devmode 1838 * has a new one. JRA. 1839 */ 1840 1841 if ((devmode->driverextra != 0) && (devmode->dev_private != NULL)) { 1842 SAFE_FREE(nt_devmode->nt_dev_private); 1843 nt_devmode->driverextra=devmode->driverextra; 1844 if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL) 1845 return False; 1846 memcpy(nt_devmode->nt_dev_private, devmode->dev_private, nt_devmode->driverextra); 1847 } 1848 1849 *pp_nt_devmode = nt_devmode; 1850 1851 return True; 1852} 1853 1854/******************************************************************** 1855 * _spoolss_enddocprinter_internal. 1856 ********************************************************************/ 1857 1858static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, POLICY_HND *handle) 1859{ 1860 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 1861 int snum; 1862 1863 if (!Printer) { 1864 DEBUG(2,("_spoolss_enddocprinter_internal: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); 1865 return WERR_BADFID; 1866 } 1867 1868 if (!get_printer_snum(p, handle, &snum)) 1869 return WERR_BADFID; 1870 1871 Printer->document_started=False; 1872 print_job_end(snum, Printer->jobid,NORMAL_CLOSE); 1873 /* error codes unhandled so far ... */ 1874 1875 return WERR_OK; 1876} 1877 1878/******************************************************************** 1879 * api_spoolss_closeprinter 1880 ********************************************************************/ 1881 1882WERROR _spoolss_closeprinter(pipes_struct *p, SPOOL_Q_CLOSEPRINTER *q_u, SPOOL_R_CLOSEPRINTER *r_u) 1883{ 1884 POLICY_HND *handle = &q_u->handle; 1885 1886 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 1887 1888 if (Printer && Printer->document_started) 1889 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */ 1890 1891 if (!close_printer_handle(p, handle)) 1892 return WERR_BADFID; 1893 1894 /* clear the returned printer handle. Observed behavior 1895 from Win2k server. Don't think this really matters. 1896 Previous code just copied the value of the closed 1897 handle. --jerry */ 1898 1899 memset(&r_u->handle, '\0', sizeof(r_u->handle)); 1900 1901 return WERR_OK; 1902} 1903 1904/******************************************************************** 1905 * api_spoolss_deleteprinter 1906 1907 ********************************************************************/ 1908 1909WERROR _spoolss_deleteprinter(pipes_struct *p, SPOOL_Q_DELETEPRINTER *q_u, SPOOL_R_DELETEPRINTER *r_u) 1910{ 1911 POLICY_HND *handle = &q_u->handle; 1912 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 1913 WERROR result; 1914 1915 if (Printer && Printer->document_started) 1916 _spoolss_enddocprinter_internal(p, handle); /* print job was not closed */ 1917 1918 memcpy(&r_u->handle, &q_u->handle, sizeof(r_u->handle)); 1919 1920 result = delete_printer_handle(p, handle); 1921 1922 update_c_setprinter(False); 1923 1924 return result; 1925} 1926 1927/******************************************************************* 1928 * static function to lookup the version id corresponding to an 1929 * long architecture string 1930 ******************************************************************/ 1931 1932static int get_version_id (char * arch) 1933{ 1934 int i; 1935 struct table_node archi_table[]= { 1936 1937 {"Windows 4.0", "WIN40", 0 }, 1938 {"Windows NT x86", "W32X86", 2 }, 1939 {"Windows NT R4000", "W32MIPS", 2 }, 1940 {"Windows NT Alpha_AXP", "W32ALPHA", 2 }, 1941 {"Windows NT PowerPC", "W32PPC", 2 }, 1942 {"Windows IA64", "IA64", 3 }, 1943 {"Windows x64", "x64", 3 }, 1944 {NULL, "", -1 } 1945 }; 1946 1947 for (i=0; archi_table[i].long_archi != NULL; i++) 1948 { 1949 if (strcmp(arch, archi_table[i].long_archi) == 0) 1950 return (archi_table[i].version); 1951 } 1952 1953 return -1; 1954} 1955 1956/******************************************************************** 1957 * _spoolss_deleteprinterdriver 1958 ********************************************************************/ 1959 1960WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u) 1961{ 1962 fstring driver; 1963 fstring arch; 1964 NT_PRINTER_DRIVER_INFO_LEVEL info; 1965 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; 1966 int version; 1967 struct current_user user; 1968 WERROR status; 1969 WERROR status_win2k = WERR_ACCESS_DENIED; 1970 SE_PRIV se_printop = SE_PRINT_OPERATOR; 1971 1972 get_current_user(&user, p); 1973 1974 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege, 1975 and not a printer admin, then fail */ 1976 1977 if ( (user.ut.uid != 0) 1978 && !user_has_privileges(user.nt_user_token, &se_printop ) 1979 && !token_contains_name_in_list( uidtoname(user.ut.uid), 1980 NULL, user.nt_user_token, lp_printer_admin(-1)) ) 1981 { 1982 return WERR_ACCESS_DENIED; 1983 } 1984 1985 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 ); 1986 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); 1987 1988 /* check that we have a valid driver name first */ 1989 1990 if ((version=get_version_id(arch)) == -1) 1991 return WERR_INVALID_ENVIRONMENT; 1992 1993 ZERO_STRUCT(info); 1994 ZERO_STRUCT(info_win2k); 1995 1996 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) 1997 { 1998 /* try for Win2k driver if "Windows NT x86" */ 1999 2000 if ( version == 2 ) { 2001 version = 3; 2002 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { 2003 status = WERR_UNKNOWN_PRINTER_DRIVER; 2004 goto done; 2005 } 2006 } 2007 /* otherwise it was a failure */ 2008 else { 2009 status = WERR_UNKNOWN_PRINTER_DRIVER; 2010 goto done; 2011 } 2012 2013 } 2014 2015 if (printer_driver_in_use(info.info_3)) { 2016 status = WERR_PRINTER_DRIVER_IN_USE; 2017 goto done; 2018 } 2019 2020 if ( version == 2 ) 2021 { 2022 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) 2023 { 2024 /* if we get to here, we now have 2 driver info structures to remove */ 2025 /* remove the Win2k driver first*/ 2026 2027 status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, False ); 2028 free_a_printer_driver( info_win2k, 3 ); 2029 2030 /* this should not have failed---if it did, report to client */ 2031 if ( !W_ERROR_IS_OK(status_win2k) ) 2032 { 2033 status = status_win2k; 2034 goto done; 2035 } 2036 } 2037 } 2038 2039 status = delete_printer_driver(info.info_3, &user, version, False); 2040 2041 /* if at least one of the deletes succeeded return OK */ 2042 2043 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) ) 2044 status = WERR_OK; 2045 2046done: 2047 free_a_printer_driver( info, 3 ); 2048 2049 return status; 2050} 2051 2052/******************************************************************** 2053 * spoolss_deleteprinterdriverex 2054 ********************************************************************/ 2055 2056WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVEREX *q_u, SPOOL_R_DELETEPRINTERDRIVEREX *r_u) 2057{ 2058 fstring driver; 2059 fstring arch; 2060 NT_PRINTER_DRIVER_INFO_LEVEL info; 2061 NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; 2062 int version; 2063 uint32 flags = q_u->delete_flags; 2064 BOOL delete_files; 2065 struct current_user user; 2066 WERROR status; 2067 WERROR status_win2k = WERR_ACCESS_DENIED; 2068 SE_PRIV se_printop = SE_PRINT_OPERATOR; 2069 2070 get_current_user(&user, p); 2071 2072 /* if the user is not root, doesn't have SE_PRINT_OPERATOR privilege, 2073 and not a printer admin, then fail */ 2074 2075 if ( (user.ut.uid != 0) 2076 && !user_has_privileges(user.nt_user_token, &se_printop ) 2077 && !token_contains_name_in_list( uidtoname(user.ut.uid), 2078 NULL, user.nt_user_token, lp_printer_admin(-1)) ) 2079 { 2080 return WERR_ACCESS_DENIED; 2081 } 2082 2083 unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 ); 2084 unistr2_to_ascii(arch, &q_u->arch, sizeof(arch)-1 ); 2085 2086 /* check that we have a valid driver name first */ 2087 if ((version=get_version_id(arch)) == -1) { 2088 /* this is what NT returns */ 2089 return WERR_INVALID_ENVIRONMENT; 2090 } 2091 2092 if ( flags & DPD_DELETE_SPECIFIC_VERSION ) 2093 version = q_u->version; 2094 2095 ZERO_STRUCT(info); 2096 ZERO_STRUCT(info_win2k); 2097 2098 status = get_a_printer_driver(&info, 3, driver, arch, version); 2099 2100 if ( !W_ERROR_IS_OK(status) ) 2101 { 2102 /* 2103 * if the client asked for a specific version, 2104 * or this is something other than Windows NT x86, 2105 * then we've failed 2106 */ 2107 2108 if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) ) 2109 goto done; 2110 2111 /* try for Win2k driver if "Windows NT x86" */ 2112 2113 version = 3; 2114 if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { 2115 status = WERR_UNKNOWN_PRINTER_DRIVER; 2116 goto done; 2117 } 2118 } 2119 2120 if ( printer_driver_in_use(info.info_3) ) { 2121 status = WERR_PRINTER_DRIVER_IN_USE; 2122 goto done; 2123 } 2124 2125 /* 2126 * we have a couple of cases to consider. 2127 * (1) Are any files in use? If so and DPD_DELTE_ALL_FILE is set, 2128 * then the delete should fail if **any** files overlap with 2129 * other drivers 2130 * (2) If DPD_DELTE_UNUSED_FILES is sert, then delete all 2131 * non-overlapping files 2132 * (3) If neither DPD_DELTE_ALL_FILE nor DPD_DELTE_ALL_FILES 2133 * is set, the do not delete any files 2134 * Refer to MSDN docs on DeletePrinterDriverEx() for details. 2135 */ 2136 2137 delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES); 2138 2139 /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */ 2140 2141 if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { 2142 /* no idea of the correct error here */ 2143 status = WERR_ACCESS_DENIED; 2144 goto done; 2145 } 2146 2147 2148 /* also check for W32X86/3 if necessary; maybe we already have? */ 2149 2150 if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) { 2151 if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) 2152 { 2153 2154 if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { 2155 /* no idea of the correct error here */ 2156 free_a_printer_driver( info_win2k, 3 ); 2157 status = WERR_ACCESS_DENIED; 2158 goto done; 2159 } 2160 2161 /* if we get to here, we now have 2 driver info structures to remove */ 2162 /* remove the Win2k driver first*/ 2163 2164 status_win2k = delete_printer_driver(info_win2k.info_3, &user, 3, delete_files); 2165 free_a_printer_driver( info_win2k, 3 ); 2166 2167 /* this should not have failed---if it did, report to client */ 2168 2169 if ( !W_ERROR_IS_OK(status_win2k) ) 2170 goto done; 2171 } 2172 } 2173 2174 status = delete_printer_driver(info.info_3, &user, version, delete_files); 2175 2176 if ( W_ERROR_IS_OK(status) || W_ERROR_IS_OK(status_win2k) ) 2177 status = WERR_OK; 2178done: 2179 free_a_printer_driver( info, 3 ); 2180 2181 return status; 2182} 2183 2184 2185/**************************************************************************** 2186 Internal routine for retreiving printerdata 2187 ***************************************************************************/ 2188 2189static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printer, 2190 const char *key, const char *value, uint32 *type, uint8 **data, 2191 uint32 *needed, uint32 in_size ) 2192{ 2193 REGISTRY_VALUE *val; 2194 uint32 size; 2195 int data_len; 2196 2197 if ( !(val = get_printer_data( printer->info_2, key, value)) ) 2198 return WERR_BADFILE; 2199 2200 *type = regval_type( val ); 2201 2202 DEBUG(5,("get_printer_dataex: allocating %d\n", in_size)); 2203 2204 size = regval_size( val ); 2205 2206 /* copy the min(in_size, len) */ 2207 2208 if ( in_size ) { 2209 data_len = (size > in_size) ? in_size : size*sizeof(uint8); 2210 2211 /* special case for 0 length values */ 2212 if ( data_len ) { 2213 if ( (*data = (uint8 *)TALLOC_MEMDUP(ctx, regval_data_p(val), data_len)) == NULL ) 2214 return WERR_NOMEM; 2215 } 2216 else { 2217 if ( (*data = (uint8 *)TALLOC_ZERO(ctx, in_size)) == NULL ) 2218 return WERR_NOMEM; 2219 } 2220 } 2221 else 2222 *data = NULL; 2223 2224 *needed = size; 2225 2226 DEBUG(5,("get_printer_dataex: copy done\n")); 2227 2228 return WERR_OK; 2229} 2230 2231/**************************************************************************** 2232 Internal routine for removing printerdata 2233 ***************************************************************************/ 2234 2235static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value ) 2236{ 2237 return delete_printer_data( printer->info_2, key, value ); 2238} 2239 2240/**************************************************************************** 2241 Internal routine for storing printerdata 2242 ***************************************************************************/ 2243 2244WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, 2245 uint32 type, uint8 *data, int real_len ) 2246{ 2247 /* the registry objects enforce uniqueness based on value name */ 2248 2249 return add_printer_data( printer->info_2, key, value, type, data, real_len ); 2250} 2251 2252/******************************************************************** 2253 GetPrinterData on a printer server Handle. 2254********************************************************************/ 2255 2256static WERROR getprinterdata_printer_server(TALLOC_CTX *ctx, fstring value, uint32 *type, uint8 **data, uint32 *needed, uint32 in_size) 2257{ 2258 int i; 2259 2260 DEBUG(8,("getprinterdata_printer_server:%s\n", value)); 2261 2262 if (!StrCaseCmp(value, "W3SvcInstalled")) { 2263 *type = REG_DWORD; 2264 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) 2265 return WERR_NOMEM; 2266 *needed = 0x4; 2267 return WERR_OK; 2268 } 2269 2270 if (!StrCaseCmp(value, "BeepEnabled")) { 2271 *type = REG_DWORD; 2272 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) 2273 return WERR_NOMEM; 2274 SIVAL(*data, 0, 0x00); 2275 *needed = 0x4; 2276 return WERR_OK; 2277 } 2278 2279 if (!StrCaseCmp(value, "EventLog")) { 2280 *type = REG_DWORD; 2281 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) 2282 return WERR_NOMEM; 2283 /* formally was 0x1b */ 2284 SIVAL(*data, 0, 0x0); 2285 *needed = 0x4; 2286 return WERR_OK; 2287 } 2288 2289 if (!StrCaseCmp(value, "NetPopup")) { 2290 *type = REG_DWORD; 2291 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) 2292 return WERR_NOMEM; 2293 SIVAL(*data, 0, 0x00); 2294 *needed = 0x4; 2295 return WERR_OK; 2296 } 2297 2298 if (!StrCaseCmp(value, "MajorVersion")) { 2299 *type = REG_DWORD; 2300 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) 2301 return WERR_NOMEM; 2302 2303 /* Windows NT 4.0 seems to not allow uploading of drivers 2304 to a server that reports 0x3 as the MajorVersion. 2305 need to investigate more how Win2k gets around this . 2306 -- jerry */ 2307 2308 if ( RA_WINNT == get_remote_arch() ) 2309 SIVAL(*data, 0, 2); 2310 else 2311 SIVAL(*data, 0, 3); 2312 2313 *needed = 0x4; 2314 return WERR_OK; 2315 } 2316 2317 if (!StrCaseCmp(value, "MinorVersion")) { 2318 *type = REG_DWORD; 2319 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) 2320 return WERR_NOMEM; 2321 SIVAL(*data, 0, 0); 2322 *needed = 0x4; 2323 return WERR_OK; 2324 } 2325 2326 /* REG_BINARY 2327 * uint32 size = 0x114 2328 * uint32 major = 5 2329 * uint32 minor = [0|1] 2330 * uint32 build = [2195|2600] 2331 * extra unicode string = e.g. "Service Pack 3" 2332 */ 2333 if (!StrCaseCmp(value, "OSVersion")) { 2334 *type = REG_BINARY; 2335 *needed = 0x114; 2336 2337 if ( !(*data = TALLOC_ZERO_ARRAY(ctx, uint8, (*needed > in_size) ? *needed:in_size )) ) 2338 return WERR_NOMEM; 2339 2340 SIVAL(*data, 0, *needed); /* size */ 2341 SIVAL(*data, 4, 5); /* Windows 2000 == 5.0 */ 2342 SIVAL(*data, 8, 0); 2343 SIVAL(*data, 12, 2195); /* build */ 2344 2345 /* leave extra string empty */ 2346 2347 return WERR_OK; 2348 } 2349 2350 2351 if (!StrCaseCmp(value, "DefaultSpoolDirectory")) { 2352 const char *string="C:\\PRINTERS"; 2353 *type = REG_SZ; 2354 *needed = 2*(strlen(string)+1); 2355 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL) 2356 return WERR_NOMEM; 2357 memset(*data, 0, (*needed > in_size) ? *needed:in_size); 2358 2359 /* it's done by hand ready to go on the wire */ 2360 for (i=0; i<strlen(string); i++) { 2361 (*data)[2*i]=string[i]; 2362 (*data)[2*i+1]='\0'; 2363 } 2364 return WERR_OK; 2365 } 2366 2367 if (!StrCaseCmp(value, "Architecture")) { 2368 const char *string="Windows NT x86"; 2369 *type = REG_SZ; 2370 *needed = 2*(strlen(string)+1); 2371 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL) 2372 return WERR_NOMEM; 2373 memset(*data, 0, (*needed > in_size) ? *needed:in_size); 2374 for (i=0; i<strlen(string); i++) { 2375 (*data)[2*i]=string[i]; 2376 (*data)[2*i+1]='\0'; 2377 } 2378 return WERR_OK; 2379 } 2380 2381 if (!StrCaseCmp(value, "DsPresent")) { 2382 *type = REG_DWORD; 2383 if ( !(*data = TALLOC_ARRAY(ctx, uint8, sizeof(uint32) )) ) 2384 return WERR_NOMEM; 2385 2386 /* only show the publish check box if we are a 2387 memeber of a AD domain */ 2388 2389 if ( lp_security() == SEC_ADS ) 2390 SIVAL(*data, 0, 0x01); 2391 else 2392 SIVAL(*data, 0, 0x00); 2393 2394 *needed = 0x4; 2395 return WERR_OK; 2396 } 2397 2398 if (!StrCaseCmp(value, "DNSMachineName")) { 2399 pstring hostname; 2400 2401 if (!get_mydnsfullname(hostname)) 2402 return WERR_BADFILE; 2403 *type = REG_SZ; 2404 *needed = 2*(strlen(hostname)+1); 2405 if((*data = (uint8 *)TALLOC(ctx, (*needed > in_size) ? *needed:in_size )) == NULL) 2406 return WERR_NOMEM; 2407 memset(*data, 0, (*needed > in_size) ? *needed:in_size); 2408 for (i=0; i<strlen(hostname); i++) { 2409 (*data)[2*i]=hostname[i]; 2410 (*data)[2*i+1]='\0'; 2411 } 2412 return WERR_OK; 2413 } 2414 2415 2416 return WERR_BADFILE; 2417} 2418 2419/******************************************************************** 2420 * spoolss_getprinterdata 2421 ********************************************************************/ 2422 2423WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPOOL_R_GETPRINTERDATA *r_u) 2424{ 2425 POLICY_HND *handle = &q_u->handle; 2426 UNISTR2 *valuename = &q_u->valuename; 2427 uint32 in_size = q_u->size; 2428 uint32 *type = &r_u->type; 2429 uint32 *out_size = &r_u->size; 2430 uint8 **data = &r_u->data; 2431 uint32 *needed = &r_u->needed; 2432 WERROR status; 2433 fstring value; 2434 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 2435 NT_PRINTER_INFO_LEVEL *printer = NULL; 2436 int snum = 0; 2437 2438 /* 2439 * Reminder: when it's a string, the length is in BYTES 2440 * even if UNICODE is negociated. 2441 * 2442 * JFM, 4/19/1999 2443 */ 2444 2445 *out_size = in_size; 2446 2447 /* in case of problem, return some default values */ 2448 2449 *needed = 0; 2450 *type = 0; 2451 2452 DEBUG(4,("_spoolss_getprinterdata\n")); 2453 2454 if ( !Printer ) { 2455 DEBUG(2,("_spoolss_getprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 2456 status = WERR_BADFID; 2457 goto done; 2458 } 2459 2460 unistr2_to_ascii(value, valuename, sizeof(value)-1); 2461 2462 if ( Printer->printer_type == SPLHND_SERVER ) 2463 status = getprinterdata_printer_server( p->mem_ctx, value, type, data, needed, *out_size ); 2464 else 2465 { 2466 if ( !get_printer_snum(p,handle, &snum) ) { 2467 status = WERR_BADFID; 2468 goto done; 2469 } 2470 2471 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); 2472 if ( !W_ERROR_IS_OK(status) ) 2473 goto done; 2474 2475 /* XP sends this and wants to change id value from the PRINTER_INFO_0 */ 2476 2477 if ( strequal(value, "ChangeId") ) { 2478 *type = REG_DWORD; 2479 *needed = sizeof(uint32); 2480 if ( (*data = (uint8*)TALLOC(p->mem_ctx, sizeof(uint32))) == NULL) { 2481 status = WERR_NOMEM; 2482 goto done; 2483 } 2484 SIVAL( *data, 0, printer->info_2->changeid ); 2485 status = WERR_OK; 2486 } 2487 else 2488 status = get_printer_dataex( p->mem_ctx, printer, SPOOL_PRINTERDATA_KEY, value, type, data, needed, *out_size ); 2489 } 2490 2491 if (*needed > *out_size) 2492 status = WERR_MORE_DATA; 2493 2494done: 2495 if ( !W_ERROR_IS_OK(status) ) 2496 { 2497 DEBUG(5, ("error %d: allocating %d\n", W_ERROR_V(status),*out_size)); 2498 2499 /* reply this param doesn't exist */ 2500 2501 if ( *out_size ) { 2502 if((*data=(uint8 *)TALLOC_ZERO_ARRAY(p->mem_ctx, uint8, *out_size)) == NULL) { 2503 if ( printer ) 2504 free_a_printer( &printer, 2 ); 2505 return WERR_NOMEM; 2506 } 2507 } else { 2508 *data = NULL; 2509 } 2510 } 2511 2512 /* cleanup & exit */ 2513 2514 if ( printer ) 2515 free_a_printer( &printer, 2 ); 2516 2517 return status; 2518} 2519 2520/********************************************************* 2521 Connect to the client machine. 2522**********************************************************/ 2523 2524static BOOL spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, 2525 struct in_addr *client_ip, const char *remote_machine) 2526{ 2527 NTSTATUS ret; 2528 struct cli_state *the_cli; 2529 struct in_addr rm_addr; 2530 2531 if ( is_zero_ip(*client_ip) ) { 2532 if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) { 2533 DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine)); 2534 return False; 2535 } 2536 2537 if ( ismyip( rm_addr )) { 2538 DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine)); 2539 return False; 2540 } 2541 } else { 2542 rm_addr.s_addr = client_ip->s_addr; 2543 DEBUG(5,("spoolss_connect_to_client: Using address %s (no name resolution necessary)\n", 2544 inet_ntoa(*client_ip) )); 2545 } 2546 2547 /* setup the connection */ 2548 2549 ret = cli_full_connection( &the_cli, global_myname(), remote_machine, 2550 &rm_addr, 0, "IPC$", "IPC", 2551 "", /* username */ 2552 "", /* domain */ 2553 "", /* password */ 2554 0, lp_client_signing(), NULL ); 2555 2556 if ( !NT_STATUS_IS_OK( ret ) ) { 2557 DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n", 2558 remote_machine )); 2559 return False; 2560 } 2561 2562 if ( the_cli->protocol != PROTOCOL_NT1 ) { 2563 DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine)); 2564 cli_shutdown(the_cli); 2565 return False; 2566 } 2567 2568 /* 2569 * Ok - we have an anonymous connection to the IPC$ share. 2570 * Now start the NT Domain stuff :-). 2571 */ 2572 2573 if ( !(*pp_pipe = cli_rpc_pipe_open_noauth(the_cli, PI_SPOOLSS, &ret)) ) { 2574 DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n", 2575 remote_machine, nt_errstr(ret))); 2576 cli_shutdown(the_cli); 2577 return False; 2578 } 2579 2580 /* make sure to save the cli_state pointer. Keep its own talloc_ctx */ 2581 2582 (*pp_pipe)->cli = the_cli; 2583 2584 return True; 2585} 2586 2587/*************************************************************************** 2588 Connect to the client. 2589****************************************************************************/ 2590 2591static BOOL srv_spoolss_replyopenprinter(int snum, const char *printer, 2592 uint32 localprinter, uint32 type, 2593 POLICY_HND *handle, struct in_addr *client_ip) 2594{ 2595 WERROR result; 2596 2597 /* 2598 * If it's the first connection, contact the client 2599 * and connect to the IPC$ share anonymously 2600 */ 2601 if (smb_connections==0) { 2602 fstring unix_printer; 2603 2604 fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */ 2605 2606 if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ip, unix_printer )) 2607 return False; 2608 2609 message_register(MSG_PRINTER_NOTIFY2, 2610 receive_notify2_message_list, NULL); 2611 /* Tell the connections db we're now interested in printer 2612 * notify messages. */ 2613 register_message_flags( True, FLAG_MSG_PRINT_NOTIFY ); 2614 } 2615 2616 /* 2617 * Tell the specific printing tdb we want messages for this printer 2618 * by registering our PID. 2619 */ 2620 2621 if (!print_notify_register_pid(snum)) 2622 DEBUG(0,("print_notify_register_pid: Failed to register our pid for printer %s\n", printer )); 2623 2624 smb_connections++; 2625 2626 result = rpccli_spoolss_reply_open_printer(notify_cli_pipe, notify_cli_pipe->cli->mem_ctx, printer, localprinter, 2627 type, handle); 2628 2629 if (!W_ERROR_IS_OK(result)) 2630 DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n", 2631 dos_errstr(result))); 2632 2633 return (W_ERROR_IS_OK(result)); 2634} 2635 2636/******************************************************************** 2637 * _spoolss_rffpcnex 2638 * ReplyFindFirstPrinterChangeNotifyEx 2639 * 2640 * before replying OK: status=0 a rpc call is made to the workstation 2641 * asking ReplyOpenPrinter 2642 * 2643 * in fact ReplyOpenPrinter is the changenotify equivalent on the spoolss pipe 2644 * called from api_spoolss_rffpcnex 2645 ********************************************************************/ 2646 2647WERROR _spoolss_rffpcnex(pipes_struct *p, SPOOL_Q_RFFPCNEX *q_u, SPOOL_R_RFFPCNEX *r_u) 2648{ 2649 POLICY_HND *handle = &q_u->handle; 2650 uint32 flags = q_u->flags; 2651 uint32 options = q_u->options; 2652 UNISTR2 *localmachine = &q_u->localmachine; 2653 uint32 printerlocal = q_u->printerlocal; 2654 int snum = -1; 2655 SPOOL_NOTIFY_OPTION *option = q_u->option; 2656 struct in_addr client_ip; 2657 2658 /* store the notify value in the printer struct */ 2659 2660 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 2661 2662 if (!Printer) { 2663 DEBUG(2,("_spoolss_rffpcnex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 2664 return WERR_BADFID; 2665 } 2666 2667 Printer->notify.flags=flags; 2668 Printer->notify.options=options; 2669 Printer->notify.printerlocal=printerlocal; 2670 2671 if (Printer->notify.option) 2672 free_spool_notify_option(&Printer->notify.option); 2673 2674 Printer->notify.option=dup_spool_notify_option(option); 2675 2676 unistr2_to_ascii(Printer->notify.localmachine, localmachine, 2677 sizeof(Printer->notify.localmachine)-1); 2678 2679 /* Connect to the client machine and send a ReplyOpenPrinter */ 2680 2681 if ( Printer->printer_type == SPLHND_SERVER) 2682 snum = -1; 2683 else if ( (Printer->printer_type == SPLHND_PRINTER) && 2684 !get_printer_snum(p, handle, &snum) ) 2685 return WERR_BADFID; 2686 2687 client_ip.s_addr = inet_addr(p->conn->client_address); 2688 2689 if(!srv_spoolss_replyopenprinter(snum, Printer->notify.localmachine, 2690 Printer->notify.printerlocal, 1, 2691 &Printer->notify.client_hnd, &client_ip)) 2692 return WERR_SERVER_UNAVAILABLE; 2693 2694 Printer->notify.client_connected=True; 2695 2696 return WERR_OK; 2697} 2698 2699/******************************************************************* 2700 * fill a notify_info_data with the servername 2701 ********************************************************************/ 2702 2703void spoolss_notify_server_name(int snum, 2704 SPOOL_NOTIFY_INFO_DATA *data, 2705 print_queue_struct *queue, 2706 NT_PRINTER_INFO_LEVEL *printer, 2707 TALLOC_CTX *mem_ctx) 2708{ 2709 pstring temp; 2710 uint32 len; 2711 2712 len = rpcstr_push(temp, printer->info_2->servername, sizeof(temp)-2, STR_TERMINATE); 2713 2714 data->notify_data.data.length = len; 2715 if (len) { 2716 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2717 if (!data->notify_data.data.string) { 2718 data->notify_data.data.length = 0; 2719 return; 2720 } 2721 2722 memcpy(data->notify_data.data.string, temp, len); 2723 } else { 2724 data->notify_data.data.string = NULL; 2725 } 2726} 2727 2728/******************************************************************* 2729 * fill a notify_info_data with the printername (not including the servername). 2730 ********************************************************************/ 2731 2732void spoolss_notify_printer_name(int snum, 2733 SPOOL_NOTIFY_INFO_DATA *data, 2734 print_queue_struct *queue, 2735 NT_PRINTER_INFO_LEVEL *printer, 2736 TALLOC_CTX *mem_ctx) 2737{ 2738 pstring temp; 2739 uint32 len; 2740 2741 /* the notify name should not contain the \\server\ part */ 2742 char *p = strrchr(printer->info_2->printername, '\\'); 2743 2744 if (!p) { 2745 p = printer->info_2->printername; 2746 } else { 2747 p++; 2748 } 2749 2750 len = rpcstr_push(temp, p, sizeof(temp)-2, STR_TERMINATE); 2751 2752 data->notify_data.data.length = len; 2753 if (len) { 2754 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2755 if (!data->notify_data.data.string) { 2756 data->notify_data.data.length = 0; 2757 return; 2758 } 2759 memcpy(data->notify_data.data.string, temp, len); 2760 } else { 2761 data->notify_data.data.string = NULL; 2762 } 2763} 2764 2765/******************************************************************* 2766 * fill a notify_info_data with the servicename 2767 ********************************************************************/ 2768 2769void spoolss_notify_share_name(int snum, 2770 SPOOL_NOTIFY_INFO_DATA *data, 2771 print_queue_struct *queue, 2772 NT_PRINTER_INFO_LEVEL *printer, 2773 TALLOC_CTX *mem_ctx) 2774{ 2775 pstring temp; 2776 uint32 len; 2777 2778 len = rpcstr_push(temp, lp_servicename(snum), sizeof(temp)-2, STR_TERMINATE); 2779 2780 data->notify_data.data.length = len; 2781 if (len) { 2782 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2783 if (!data->notify_data.data.string) { 2784 data->notify_data.data.length = 0; 2785 return; 2786 } 2787 memcpy(data->notify_data.data.string, temp, len); 2788 } else { 2789 data->notify_data.data.string = NULL; 2790 } 2791 2792} 2793 2794/******************************************************************* 2795 * fill a notify_info_data with the port name 2796 ********************************************************************/ 2797 2798void spoolss_notify_port_name(int snum, 2799 SPOOL_NOTIFY_INFO_DATA *data, 2800 print_queue_struct *queue, 2801 NT_PRINTER_INFO_LEVEL *printer, 2802 TALLOC_CTX *mem_ctx) 2803{ 2804 pstring temp; 2805 uint32 len; 2806 2807 /* even if it's strange, that's consistant in all the code */ 2808 2809 len = rpcstr_push(temp, printer->info_2->portname, sizeof(temp)-2, STR_TERMINATE); 2810 2811 data->notify_data.data.length = len; 2812 if (len) { 2813 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2814 2815 if (!data->notify_data.data.string) { 2816 data->notify_data.data.length = 0; 2817 return; 2818 } 2819 2820 memcpy(data->notify_data.data.string, temp, len); 2821 } else { 2822 data->notify_data.data.string = NULL; 2823 } 2824} 2825 2826/******************************************************************* 2827 * fill a notify_info_data with the printername 2828 * but it doesn't exist, have to see what to do 2829 ********************************************************************/ 2830 2831void spoolss_notify_driver_name(int snum, 2832 SPOOL_NOTIFY_INFO_DATA *data, 2833 print_queue_struct *queue, 2834 NT_PRINTER_INFO_LEVEL *printer, 2835 TALLOC_CTX *mem_ctx) 2836{ 2837 pstring temp; 2838 uint32 len; 2839 2840 len = rpcstr_push(temp, printer->info_2->drivername, sizeof(temp)-2, STR_TERMINATE); 2841 2842 data->notify_data.data.length = len; 2843 if (len) { 2844 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2845 2846 if (!data->notify_data.data.string) { 2847 data->notify_data.data.length = 0; 2848 return; 2849 } 2850 2851 memcpy(data->notify_data.data.string, temp, len); 2852 } else { 2853 data->notify_data.data.string = NULL; 2854 } 2855} 2856 2857/******************************************************************* 2858 * fill a notify_info_data with the comment 2859 ********************************************************************/ 2860 2861void spoolss_notify_comment(int snum, 2862 SPOOL_NOTIFY_INFO_DATA *data, 2863 print_queue_struct *queue, 2864 NT_PRINTER_INFO_LEVEL *printer, 2865 TALLOC_CTX *mem_ctx) 2866{ 2867 pstring temp; 2868 uint32 len; 2869 2870 if (*printer->info_2->comment == '\0') 2871 len = rpcstr_push(temp, lp_comment(snum), sizeof(temp)-2, STR_TERMINATE); 2872 else 2873 len = rpcstr_push(temp, printer->info_2->comment, sizeof(temp)-2, STR_TERMINATE); 2874 2875 data->notify_data.data.length = len; 2876 if (len) { 2877 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2878 2879 if (!data->notify_data.data.string) { 2880 data->notify_data.data.length = 0; 2881 return; 2882 } 2883 2884 memcpy(data->notify_data.data.string, temp, len); 2885 } else { 2886 data->notify_data.data.string = NULL; 2887 } 2888} 2889 2890/******************************************************************* 2891 * fill a notify_info_data with the comment 2892 * location = "Room 1, floor 2, building 3" 2893 ********************************************************************/ 2894 2895void spoolss_notify_location(int snum, 2896 SPOOL_NOTIFY_INFO_DATA *data, 2897 print_queue_struct *queue, 2898 NT_PRINTER_INFO_LEVEL *printer, 2899 TALLOC_CTX *mem_ctx) 2900{ 2901 pstring temp; 2902 uint32 len; 2903 2904 len = rpcstr_push(temp, printer->info_2->location,sizeof(temp)-2, STR_TERMINATE); 2905 2906 data->notify_data.data.length = len; 2907 if (len) { 2908 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2909 2910 if (!data->notify_data.data.string) { 2911 data->notify_data.data.length = 0; 2912 return; 2913 } 2914 2915 memcpy(data->notify_data.data.string, temp, len); 2916 } else { 2917 data->notify_data.data.string = NULL; 2918 } 2919} 2920 2921/******************************************************************* 2922 * fill a notify_info_data with the device mode 2923 * jfm:xxxx don't to it for know but that's a real problem !!! 2924 ********************************************************************/ 2925 2926static void spoolss_notify_devmode(int snum, 2927 SPOOL_NOTIFY_INFO_DATA *data, 2928 print_queue_struct *queue, 2929 NT_PRINTER_INFO_LEVEL *printer, 2930 TALLOC_CTX *mem_ctx) 2931{ 2932 /* for a dummy implementation we have to zero the fields */ 2933 data->notify_data.data.length = 0; 2934 data->notify_data.data.string = NULL; 2935} 2936 2937/******************************************************************* 2938 * fill a notify_info_data with the separator file name 2939 ********************************************************************/ 2940 2941void spoolss_notify_sepfile(int snum, 2942 SPOOL_NOTIFY_INFO_DATA *data, 2943 print_queue_struct *queue, 2944 NT_PRINTER_INFO_LEVEL *printer, 2945 TALLOC_CTX *mem_ctx) 2946{ 2947 pstring temp; 2948 uint32 len; 2949 2950 len = rpcstr_push(temp, printer->info_2->sepfile, sizeof(temp)-2, STR_TERMINATE); 2951 2952 data->notify_data.data.length = len; 2953 if (len) { 2954 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2955 2956 if (!data->notify_data.data.string) { 2957 data->notify_data.data.length = 0; 2958 return; 2959 } 2960 2961 memcpy(data->notify_data.data.string, temp, len); 2962 } else { 2963 data->notify_data.data.string = NULL; 2964 } 2965} 2966 2967/******************************************************************* 2968 * fill a notify_info_data with the print processor 2969 * jfm:xxxx return always winprint to indicate we don't do anything to it 2970 ********************************************************************/ 2971 2972void spoolss_notify_print_processor(int snum, 2973 SPOOL_NOTIFY_INFO_DATA *data, 2974 print_queue_struct *queue, 2975 NT_PRINTER_INFO_LEVEL *printer, 2976 TALLOC_CTX *mem_ctx) 2977{ 2978 pstring temp; 2979 uint32 len; 2980 2981 len = rpcstr_push(temp, printer->info_2->printprocessor, sizeof(temp)-2, STR_TERMINATE); 2982 2983 data->notify_data.data.length = len; 2984 if (len) { 2985 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 2986 2987 if (!data->notify_data.data.string) { 2988 data->notify_data.data.length = 0; 2989 return; 2990 } 2991 2992 memcpy(data->notify_data.data.string, temp, len); 2993 } else { 2994 data->notify_data.data.string = NULL; 2995 } 2996} 2997 2998/******************************************************************* 2999 * fill a notify_info_data with the print processor options 3000 * jfm:xxxx send an empty string 3001 ********************************************************************/ 3002 3003void spoolss_notify_parameters(int snum, 3004 SPOOL_NOTIFY_INFO_DATA *data, 3005 print_queue_struct *queue, 3006 NT_PRINTER_INFO_LEVEL *printer, 3007 TALLOC_CTX *mem_ctx) 3008{ 3009 pstring temp; 3010 uint32 len; 3011 3012 len = rpcstr_push(temp, printer->info_2->parameters, sizeof(temp)-2, STR_TERMINATE); 3013 3014 data->notify_data.data.length = len; 3015 if (len) { 3016 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 3017 3018 if (!data->notify_data.data.string) { 3019 data->notify_data.data.length = 0; 3020 return; 3021 } 3022 3023 memcpy(data->notify_data.data.string, temp, len); 3024 } else { 3025 data->notify_data.data.string = NULL; 3026 } 3027} 3028 3029/******************************************************************* 3030 * fill a notify_info_data with the data type 3031 * jfm:xxxx always send RAW as data type 3032 ********************************************************************/ 3033 3034void spoolss_notify_datatype(int snum, 3035 SPOOL_NOTIFY_INFO_DATA *data, 3036 print_queue_struct *queue, 3037 NT_PRINTER_INFO_LEVEL *printer, 3038 TALLOC_CTX *mem_ctx) 3039{ 3040 pstring temp; 3041 uint32 len; 3042 3043 len = rpcstr_push(temp, printer->info_2->datatype, sizeof(pstring)-2, STR_TERMINATE); 3044 3045 data->notify_data.data.length = len; 3046 if (len) { 3047 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 3048 3049 if (!data->notify_data.data.string) { 3050 data->notify_data.data.length = 0; 3051 return; 3052 } 3053 3054 memcpy(data->notify_data.data.string, temp, len); 3055 } else { 3056 data->notify_data.data.string = NULL; 3057 } 3058} 3059 3060/******************************************************************* 3061 * fill a notify_info_data with the security descriptor 3062 * jfm:xxxx send an null pointer to say no security desc 3063 * have to implement security before ! 3064 ********************************************************************/ 3065 3066static void spoolss_notify_security_desc(int snum, 3067 SPOOL_NOTIFY_INFO_DATA *data, 3068 print_queue_struct *queue, 3069 NT_PRINTER_INFO_LEVEL *printer, 3070 TALLOC_CTX *mem_ctx) 3071{ 3072 data->notify_data.sd.size = printer->info_2->secdesc_buf->len; 3073 data->notify_data.sd.desc = dup_sec_desc( mem_ctx, printer->info_2->secdesc_buf->sec ) ; 3074} 3075 3076/******************************************************************* 3077 * fill a notify_info_data with the attributes 3078 * jfm:xxxx a samba printer is always shared 3079 ********************************************************************/ 3080 3081void spoolss_notify_attributes(int snum, 3082 SPOOL_NOTIFY_INFO_DATA *data, 3083 print_queue_struct *queue, 3084 NT_PRINTER_INFO_LEVEL *printer, 3085 TALLOC_CTX *mem_ctx) 3086{ 3087 data->notify_data.value[0] = printer->info_2->attributes; 3088 data->notify_data.value[1] = 0; 3089} 3090 3091/******************************************************************* 3092 * fill a notify_info_data with the priority 3093 ********************************************************************/ 3094 3095static void spoolss_notify_priority(int snum, 3096 SPOOL_NOTIFY_INFO_DATA *data, 3097 print_queue_struct *queue, 3098 NT_PRINTER_INFO_LEVEL *printer, 3099 TALLOC_CTX *mem_ctx) 3100{ 3101 data->notify_data.value[0] = printer->info_2->priority; 3102 data->notify_data.value[1] = 0; 3103} 3104 3105/******************************************************************* 3106 * fill a notify_info_data with the default priority 3107 ********************************************************************/ 3108 3109static void spoolss_notify_default_priority(int snum, 3110 SPOOL_NOTIFY_INFO_DATA *data, 3111 print_queue_struct *queue, 3112 NT_PRINTER_INFO_LEVEL *printer, 3113 TALLOC_CTX *mem_ctx) 3114{ 3115 data->notify_data.value[0] = printer->info_2->default_priority; 3116 data->notify_data.value[1] = 0; 3117} 3118 3119/******************************************************************* 3120 * fill a notify_info_data with the start time 3121 ********************************************************************/ 3122 3123static void spoolss_notify_start_time(int snum, 3124 SPOOL_NOTIFY_INFO_DATA *data, 3125 print_queue_struct *queue, 3126 NT_PRINTER_INFO_LEVEL *printer, 3127 TALLOC_CTX *mem_ctx) 3128{ 3129 data->notify_data.value[0] = printer->info_2->starttime; 3130 data->notify_data.value[1] = 0; 3131} 3132 3133/******************************************************************* 3134 * fill a notify_info_data with the until time 3135 ********************************************************************/ 3136 3137static void spoolss_notify_until_time(int snum, 3138 SPOOL_NOTIFY_INFO_DATA *data, 3139 print_queue_struct *queue, 3140 NT_PRINTER_INFO_LEVEL *printer, 3141 TALLOC_CTX *mem_ctx) 3142{ 3143 data->notify_data.value[0] = printer->info_2->untiltime; 3144 data->notify_data.value[1] = 0; 3145} 3146 3147/******************************************************************* 3148 * fill a notify_info_data with the status 3149 ********************************************************************/ 3150 3151static void spoolss_notify_status(int snum, 3152 SPOOL_NOTIFY_INFO_DATA *data, 3153 print_queue_struct *queue, 3154 NT_PRINTER_INFO_LEVEL *printer, 3155 TALLOC_CTX *mem_ctx) 3156{ 3157 print_status_struct status; 3158 3159 print_queue_length(snum, &status); 3160 data->notify_data.value[0]=(uint32) status.status; 3161 data->notify_data.value[1] = 0; 3162} 3163 3164/******************************************************************* 3165 * fill a notify_info_data with the number of jobs queued 3166 ********************************************************************/ 3167 3168void spoolss_notify_cjobs(int snum, 3169 SPOOL_NOTIFY_INFO_DATA *data, 3170 print_queue_struct *queue, 3171 NT_PRINTER_INFO_LEVEL *printer, 3172 TALLOC_CTX *mem_ctx) 3173{ 3174 data->notify_data.value[0] = print_queue_length(snum, NULL); 3175 data->notify_data.value[1] = 0; 3176} 3177 3178/******************************************************************* 3179 * fill a notify_info_data with the average ppm 3180 ********************************************************************/ 3181 3182static void spoolss_notify_average_ppm(int snum, 3183 SPOOL_NOTIFY_INFO_DATA *data, 3184 print_queue_struct *queue, 3185 NT_PRINTER_INFO_LEVEL *printer, 3186 TALLOC_CTX *mem_ctx) 3187{ 3188 /* always respond 8 pages per minutes */ 3189 /* a little hard ! */ 3190 data->notify_data.value[0] = printer->info_2->averageppm; 3191 data->notify_data.value[1] = 0; 3192} 3193 3194/******************************************************************* 3195 * fill a notify_info_data with username 3196 ********************************************************************/ 3197 3198static void spoolss_notify_username(int snum, 3199 SPOOL_NOTIFY_INFO_DATA *data, 3200 print_queue_struct *queue, 3201 NT_PRINTER_INFO_LEVEL *printer, 3202 TALLOC_CTX *mem_ctx) 3203{ 3204 pstring temp; 3205 uint32 len; 3206 3207 len = rpcstr_push(temp, queue->fs_user, sizeof(temp)-2, STR_TERMINATE); 3208 3209 data->notify_data.data.length = len; 3210 if (len) { 3211 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 3212 3213 if (!data->notify_data.data.string) { 3214 data->notify_data.data.length = 0; 3215 return; 3216 } 3217 3218 memcpy(data->notify_data.data.string, temp, len); 3219 } else { 3220 data->notify_data.data.string = NULL; 3221 } 3222} 3223 3224/******************************************************************* 3225 * fill a notify_info_data with job status 3226 ********************************************************************/ 3227 3228static void spoolss_notify_job_status(int snum, 3229 SPOOL_NOTIFY_INFO_DATA *data, 3230 print_queue_struct *queue, 3231 NT_PRINTER_INFO_LEVEL *printer, 3232 TALLOC_CTX *mem_ctx) 3233{ 3234 data->notify_data.value[0]=nt_printj_status(queue->status); 3235 data->notify_data.value[1] = 0; 3236} 3237 3238/******************************************************************* 3239 * fill a notify_info_data with job name 3240 ********************************************************************/ 3241 3242static void spoolss_notify_job_name(int snum, 3243 SPOOL_NOTIFY_INFO_DATA *data, 3244 print_queue_struct *queue, 3245 NT_PRINTER_INFO_LEVEL *printer, 3246 TALLOC_CTX *mem_ctx) 3247{ 3248 pstring temp; 3249 uint32 len; 3250 3251 len = rpcstr_push(temp, queue->fs_file, sizeof(temp)-2, STR_TERMINATE); 3252 3253 data->notify_data.data.length = len; 3254 if (len) { 3255 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 3256 3257 if (!data->notify_data.data.string) { 3258 data->notify_data.data.length = 0; 3259 return; 3260 } 3261 3262 memcpy(data->notify_data.data.string, temp, len); 3263 } else { 3264 data->notify_data.data.string = NULL; 3265 } 3266} 3267 3268/******************************************************************* 3269 * fill a notify_info_data with job status 3270 ********************************************************************/ 3271 3272static void spoolss_notify_job_status_string(int snum, 3273 SPOOL_NOTIFY_INFO_DATA *data, 3274 print_queue_struct *queue, 3275 NT_PRINTER_INFO_LEVEL *printer, 3276 TALLOC_CTX *mem_ctx) 3277{ 3278 /* 3279 * Now we're returning job status codes we just return a "" here. JRA. 3280 */ 3281 3282 const char *p = ""; 3283 pstring temp; 3284 uint32 len; 3285 3286#if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */ 3287 p = "unknown"; 3288 3289 switch (queue->status) { 3290 case LPQ_QUEUED: 3291 p = "Queued"; 3292 break; 3293 case LPQ_PAUSED: 3294 p = ""; /* NT provides the paused string */ 3295 break; 3296 case LPQ_SPOOLING: 3297 p = "Spooling"; 3298 break; 3299 case LPQ_PRINTING: 3300 p = "Printing"; 3301 break; 3302 } 3303#endif /* NO LONGER NEEDED. */ 3304 3305 len = rpcstr_push(temp, p, sizeof(temp) - 2, STR_TERMINATE); 3306 3307 data->notify_data.data.length = len; 3308 if (len) { 3309 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 3310 3311 if (!data->notify_data.data.string) { 3312 data->notify_data.data.length = 0; 3313 return; 3314 } 3315 3316 memcpy(data->notify_data.data.string, temp, len); 3317 } else { 3318 data->notify_data.data.string = NULL; 3319 } 3320} 3321 3322/******************************************************************* 3323 * fill a notify_info_data with job time 3324 ********************************************************************/ 3325 3326static void spoolss_notify_job_time(int snum, 3327 SPOOL_NOTIFY_INFO_DATA *data, 3328 print_queue_struct *queue, 3329 NT_PRINTER_INFO_LEVEL *printer, 3330 TALLOC_CTX *mem_ctx) 3331{ 3332 data->notify_data.value[0]=0x0; 3333 data->notify_data.value[1]=0; 3334} 3335 3336/******************************************************************* 3337 * fill a notify_info_data with job size 3338 ********************************************************************/ 3339 3340static void spoolss_notify_job_size(int snum, 3341 SPOOL_NOTIFY_INFO_DATA *data, 3342 print_queue_struct *queue, 3343 NT_PRINTER_INFO_LEVEL *printer, 3344 TALLOC_CTX *mem_ctx) 3345{ 3346 data->notify_data.value[0]=queue->size; 3347 data->notify_data.value[1]=0; 3348} 3349 3350/******************************************************************* 3351 * fill a notify_info_data with page info 3352 ********************************************************************/ 3353static void spoolss_notify_total_pages(int snum, 3354 SPOOL_NOTIFY_INFO_DATA *data, 3355 print_queue_struct *queue, 3356 NT_PRINTER_INFO_LEVEL *printer, 3357 TALLOC_CTX *mem_ctx) 3358{ 3359 data->notify_data.value[0]=queue->page_count; 3360 data->notify_data.value[1]=0; 3361} 3362 3363/******************************************************************* 3364 * fill a notify_info_data with pages printed info. 3365 ********************************************************************/ 3366static void spoolss_notify_pages_printed(int snum, 3367 SPOOL_NOTIFY_INFO_DATA *data, 3368 print_queue_struct *queue, 3369 NT_PRINTER_INFO_LEVEL *printer, 3370 TALLOC_CTX *mem_ctx) 3371{ 3372 data->notify_data.value[0]=0; /* Add code when back-end tracks this */ 3373 data->notify_data.value[1]=0; 3374} 3375 3376/******************************************************************* 3377 Fill a notify_info_data with job position. 3378 ********************************************************************/ 3379 3380static void spoolss_notify_job_position(int snum, 3381 SPOOL_NOTIFY_INFO_DATA *data, 3382 print_queue_struct *queue, 3383 NT_PRINTER_INFO_LEVEL *printer, 3384 TALLOC_CTX *mem_ctx) 3385{ 3386 data->notify_data.value[0]=queue->job; 3387 data->notify_data.value[1]=0; 3388} 3389 3390/******************************************************************* 3391 Fill a notify_info_data with submitted time. 3392 ********************************************************************/ 3393 3394static void spoolss_notify_submitted_time(int snum, 3395 SPOOL_NOTIFY_INFO_DATA *data, 3396 print_queue_struct *queue, 3397 NT_PRINTER_INFO_LEVEL *printer, 3398 TALLOC_CTX *mem_ctx) 3399{ 3400 struct tm *t; 3401 uint32 len; 3402 SYSTEMTIME st; 3403 char *p; 3404 3405 t=gmtime(&queue->time); 3406 3407 len = sizeof(SYSTEMTIME); 3408 3409 data->notify_data.data.length = len; 3410 data->notify_data.data.string = (uint16 *)TALLOC(mem_ctx, len); 3411 3412 if (!data->notify_data.data.string) { 3413 data->notify_data.data.length = 0; 3414 return; 3415 } 3416 3417 make_systemtime(&st, t); 3418 3419 /* 3420 * Systemtime must be linearized as a set of UINT16's. 3421 * Fix from Benjamin (Bj) Kuit bj@it.uts.edu.au 3422 */ 3423 3424 p = (char *)data->notify_data.data.string; 3425 SSVAL(p, 0, st.year); 3426 SSVAL(p, 2, st.month); 3427 SSVAL(p, 4, st.dayofweek); 3428 SSVAL(p, 6, st.day); 3429 SSVAL(p, 8, st.hour); 3430 SSVAL(p, 10, st.minute); 3431 SSVAL(p, 12, st.second); 3432 SSVAL(p, 14, st.milliseconds); 3433} 3434 3435struct s_notify_info_data_table 3436{ 3437 uint16 type; 3438 uint16 field; 3439 const char *name; 3440 uint32 size; 3441 void (*fn) (int snum, SPOOL_NOTIFY_INFO_DATA *data, 3442 print_queue_struct *queue, 3443 NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx); 3444}; 3445 3446/* A table describing the various print notification constants and 3447 whether the notification data is a pointer to a variable sized 3448 buffer, a one value uint32 or a two value uint32. */ 3449 3450static const struct s_notify_info_data_table notify_info_data_table[] = 3451{ 3452{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SERVER_NAME, "PRINTER_NOTIFY_SERVER_NAME", NOTIFY_STRING, spoolss_notify_server_name }, 3453{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME, "PRINTER_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name }, 3454{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME, "PRINTER_NOTIFY_SHARE_NAME", NOTIFY_STRING, spoolss_notify_share_name }, 3455{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME, "PRINTER_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name }, 3456{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME, "PRINTER_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name }, 3457{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT, "PRINTER_NOTIFY_COMMENT", NOTIFY_STRING, spoolss_notify_comment }, 3458{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION, "PRINTER_NOTIFY_LOCATION", NOTIFY_STRING, spoolss_notify_location }, 3459{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEVMODE, "PRINTER_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode }, 3460{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SEPFILE, "PRINTER_NOTIFY_SEPFILE", NOTIFY_STRING, spoolss_notify_sepfile }, 3461{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINT_PROCESSOR, "PRINTER_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor }, 3462{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PARAMETERS, "PRINTER_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters }, 3463{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DATATYPE, "PRINTER_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype }, 3464{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SECURITY_DESCRIPTOR, "PRINTER_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_SECDESC, spoolss_notify_security_desc }, 3465{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_ATTRIBUTES, "PRINTER_NOTIFY_ATTRIBUTES", NOTIFY_ONE_VALUE, spoolss_notify_attributes }, 3466{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRIORITY, "PRINTER_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority }, 3467{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DEFAULT_PRIORITY, "PRINTER_NOTIFY_DEFAULT_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_default_priority }, 3468{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_START_TIME, "PRINTER_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time }, 3469{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_UNTIL_TIME, "PRINTER_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time }, 3470{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS, "PRINTER_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_status }, 3471{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_STATUS_STRING, "PRINTER_NOTIFY_STATUS_STRING", NOTIFY_POINTER, NULL }, 3472{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_CJOBS, "PRINTER_NOTIFY_CJOBS", NOTIFY_ONE_VALUE, spoolss_notify_cjobs }, 3473{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_AVERAGE_PPM, "PRINTER_NOTIFY_AVERAGE_PPM", NOTIFY_ONE_VALUE, spoolss_notify_average_ppm }, 3474{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_PAGES, "PRINTER_NOTIFY_TOTAL_PAGES", NOTIFY_POINTER, NULL }, 3475{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PAGES_PRINTED, "PRINTER_NOTIFY_PAGES_PRINTED", NOTIFY_POINTER, NULL }, 3476{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_TOTAL_BYTES, "PRINTER_NOTIFY_TOTAL_BYTES", NOTIFY_POINTER, NULL }, 3477{ PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_BYTES_PRINTED, "PRINTER_NOTIFY_BYTES_PRINTED", NOTIFY_POINTER, NULL }, 3478{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINTER_NAME, "JOB_NOTIFY_PRINTER_NAME", NOTIFY_STRING, spoolss_notify_printer_name }, 3479{ JOB_NOTIFY_TYPE, JOB_NOTIFY_MACHINE_NAME, "JOB_NOTIFY_MACHINE_NAME", NOTIFY_STRING, spoolss_notify_server_name }, 3480{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PORT_NAME, "JOB_NOTIFY_PORT_NAME", NOTIFY_STRING, spoolss_notify_port_name }, 3481{ JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME, "JOB_NOTIFY_USER_NAME", NOTIFY_STRING, spoolss_notify_username }, 3482{ JOB_NOTIFY_TYPE, JOB_NOTIFY_NOTIFY_NAME, "JOB_NOTIFY_NOTIFY_NAME", NOTIFY_STRING, spoolss_notify_username }, 3483{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DATATYPE, "JOB_NOTIFY_DATATYPE", NOTIFY_STRING, spoolss_notify_datatype }, 3484{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRINT_PROCESSOR, "JOB_NOTIFY_PRINT_PROCESSOR", NOTIFY_STRING, spoolss_notify_print_processor }, 3485{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PARAMETERS, "JOB_NOTIFY_PARAMETERS", NOTIFY_STRING, spoolss_notify_parameters }, 3486{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DRIVER_NAME, "JOB_NOTIFY_DRIVER_NAME", NOTIFY_STRING, spoolss_notify_driver_name }, 3487{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DEVMODE, "JOB_NOTIFY_DEVMODE", NOTIFY_POINTER, spoolss_notify_devmode }, 3488{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS, "JOB_NOTIFY_STATUS", NOTIFY_ONE_VALUE, spoolss_notify_job_status }, 3489{ JOB_NOTIFY_TYPE, JOB_NOTIFY_STATUS_STRING, "JOB_NOTIFY_STATUS_STRING", NOTIFY_STRING, spoolss_notify_job_status_string }, 3490{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SECURITY_DESCRIPTOR, "JOB_NOTIFY_SECURITY_DESCRIPTOR", NOTIFY_POINTER, NULL }, 3491{ JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT, "JOB_NOTIFY_DOCUMENT", NOTIFY_STRING, spoolss_notify_job_name }, 3492{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PRIORITY, "JOB_NOTIFY_PRIORITY", NOTIFY_ONE_VALUE, spoolss_notify_priority }, 3493{ JOB_NOTIFY_TYPE, JOB_NOTIFY_POSITION, "JOB_NOTIFY_POSITION", NOTIFY_ONE_VALUE, spoolss_notify_job_position }, 3494{ JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED, "JOB_NOTIFY_SUBMITTED", NOTIFY_POINTER, spoolss_notify_submitted_time }, 3495{ JOB_NOTIFY_TYPE, JOB_NOTIFY_START_TIME, "JOB_NOTIFY_START_TIME", NOTIFY_ONE_VALUE, spoolss_notify_start_time }, 3496{ JOB_NOTIFY_TYPE, JOB_NOTIFY_UNTIL_TIME, "JOB_NOTIFY_UNTIL_TIME", NOTIFY_ONE_VALUE, spoolss_notify_until_time }, 3497{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TIME, "JOB_NOTIFY_TIME", NOTIFY_ONE_VALUE, spoolss_notify_job_time }, 3498{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_PAGES, "JOB_NOTIFY_TOTAL_PAGES", NOTIFY_ONE_VALUE, spoolss_notify_total_pages }, 3499{ JOB_NOTIFY_TYPE, JOB_NOTIFY_PAGES_PRINTED, "JOB_NOTIFY_PAGES_PRINTED", NOTIFY_ONE_VALUE, spoolss_notify_pages_printed }, 3500{ JOB_NOTIFY_TYPE, JOB_NOTIFY_TOTAL_BYTES, "JOB_NOTIFY_TOTAL_BYTES", NOTIFY_ONE_VALUE, spoolss_notify_job_size }, 3501{ PRINT_TABLE_END, 0x0, NULL, 0x0, NULL }, 3502}; 3503 3504/******************************************************************* 3505 Return the size of info_data structure. 3506********************************************************************/ 3507 3508static uint32 size_of_notify_info_data(uint16 type, uint16 field) 3509{ 3510 int i=0; 3511 3512 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) { 3513 if ( (notify_info_data_table[i].type == type) 3514 && (notify_info_data_table[i].field == field) ) { 3515 switch(notify_info_data_table[i].size) { 3516 case NOTIFY_ONE_VALUE: 3517 case NOTIFY_TWO_VALUE: 3518 return 1; 3519 case NOTIFY_STRING: 3520 return 2; 3521 3522 /* The only pointer notify data I have seen on 3523 the wire is the submitted time and this has 3524 the notify size set to 4. -tpot */ 3525 3526 case NOTIFY_POINTER: 3527 return 4; 3528 3529 case NOTIFY_SECDESC: 3530 return 5; 3531 } 3532 } 3533 } 3534 3535 DEBUG(5, ("invalid notify data type %d/%d\n", type, field)); 3536 3537 return 0; 3538} 3539 3540/******************************************************************* 3541 Return the type of notify_info_data. 3542********************************************************************/ 3543 3544static uint32 type_of_notify_info_data(uint16 type, uint16 field) 3545{ 3546 uint32 i=0; 3547 3548 for (i = 0; i < (sizeof(notify_info_data_table)/sizeof(struct s_notify_info_data_table)); i++) { 3549 if (notify_info_data_table[i].type == type && 3550 notify_info_data_table[i].field == field) 3551 return notify_info_data_table[i].size; 3552 } 3553 3554 return 0; 3555} 3556 3557/**************************************************************************** 3558****************************************************************************/ 3559 3560static BOOL search_notify(uint16 type, uint16 field, int *value) 3561{ 3562 int i; 3563 3564 for (i = 0; notify_info_data_table[i].type != PRINT_TABLE_END; i++) { 3565 if (notify_info_data_table[i].type == type && 3566 notify_info_data_table[i].field == field && 3567 notify_info_data_table[i].fn != NULL) { 3568 *value = i; 3569 return True; 3570 } 3571 } 3572 3573 return False; 3574} 3575 3576/**************************************************************************** 3577****************************************************************************/ 3578 3579void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 field, int id) 3580{ 3581 info_data->type = type; 3582 info_data->field = field; 3583 info_data->reserved = 0; 3584 3585 info_data->size = size_of_notify_info_data(type, field); 3586 info_data->enc_type = type_of_notify_info_data(type, field); 3587 3588 info_data->id = id; 3589} 3590 3591/******************************************************************* 3592 * 3593 * fill a notify_info struct with info asked 3594 * 3595 ********************************************************************/ 3596 3597static BOOL construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int 3598 snum, SPOOL_NOTIFY_OPTION_TYPE 3599 *option_type, uint32 id, 3600 TALLOC_CTX *mem_ctx) 3601{ 3602 int field_num,j; 3603 uint16 type; 3604 uint16 field; 3605 3606 SPOOL_NOTIFY_INFO_DATA *current_data; 3607 NT_PRINTER_INFO_LEVEL *printer = NULL; 3608 print_queue_struct *queue=NULL; 3609 3610 type=option_type->type; 3611 3612 DEBUG(4,("construct_notify_printer_info: Notify type: [%s], number of notify info: [%d] on printer: [%s]\n", 3613 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"), 3614 option_type->count, lp_servicename(snum))); 3615 3616 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum)))) 3617 return False; 3618 3619 for(field_num=0; field_num<option_type->count; field_num++) { 3620 field = option_type->fields[field_num]; 3621 3622 DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field)); 3623 3624 if (!search_notify(type, field, &j) ) 3625 continue; 3626 3627 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) { 3628 DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n")); 3629 free_a_printer(&printer, 2); 3630 return False; 3631 } 3632 3633 current_data = &info->data[info->count]; 3634 3635 construct_info_data(current_data, type, field, id); 3636 3637 DEBUG(10,("construct_notify_printer_info: calling [%s] snum=%d printername=[%s])\n", 3638 notify_info_data_table[j].name, snum, printer->info_2->printername )); 3639 3640 notify_info_data_table[j].fn(snum, current_data, queue, 3641 printer, mem_ctx); 3642 3643 info->count++; 3644 } 3645 3646 free_a_printer(&printer, 2); 3647 return True; 3648} 3649 3650/******************************************************************* 3651 * 3652 * fill a notify_info struct with info asked 3653 * 3654 ********************************************************************/ 3655 3656static BOOL construct_notify_jobs_info(print_queue_struct *queue, 3657 SPOOL_NOTIFY_INFO *info, 3658 NT_PRINTER_INFO_LEVEL *printer, 3659 int snum, SPOOL_NOTIFY_OPTION_TYPE 3660 *option_type, uint32 id, 3661 TALLOC_CTX *mem_ctx) 3662{ 3663 int field_num,j; 3664 uint16 type; 3665 uint16 field; 3666 3667 SPOOL_NOTIFY_INFO_DATA *current_data; 3668 3669 DEBUG(4,("construct_notify_jobs_info\n")); 3670 3671 type = option_type->type; 3672 3673 DEBUGADD(4,("Notify type: [%s], number of notify info: [%d]\n", 3674 (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"), 3675 option_type->count)); 3676 3677 for(field_num=0; field_num<option_type->count; field_num++) { 3678 field = option_type->fields[field_num]; 3679 3680 if (!search_notify(type, field, &j) ) 3681 continue; 3682 3683 if((info->data=SMB_REALLOC_ARRAY(info->data, SPOOL_NOTIFY_INFO_DATA, info->count+1)) == NULL) { 3684 DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n")); 3685 return False; 3686 } 3687 3688 current_data=&(info->data[info->count]); 3689 3690 construct_info_data(current_data, type, field, id); 3691 notify_info_data_table[j].fn(snum, current_data, queue, 3692 printer, mem_ctx); 3693 info->count++; 3694 } 3695 3696 return True; 3697} 3698 3699/* 3700 * JFM: The enumeration is not that simple, it's even non obvious. 3701 * 3702 * let's take an example: I want to monitor the PRINTER SERVER for 3703 * the printer's name and the number of jobs currently queued. 3704 * So in the NOTIFY_OPTION, I have one NOTIFY_OPTION_TYPE structure. 3705 * Its type is PRINTER_NOTIFY_TYPE and it has 2 fields NAME and CJOBS. 3706 * 3707 * I have 3 printers on the back of my server. 3708 * 3709 * Now the response is a NOTIFY_INFO structure, with 6 NOTIFY_INFO_DATA 3710 * structures. 3711 * Number Data Id 3712 * 1 printer 1 name 1 3713 * 2 printer 1 cjob 1 3714 * 3 printer 2 name 2 3715 * 4 printer 2 cjob 2 3716 * 5 printer 3 name 3 3717 * 6 printer 3 name 3 3718 * 3719 * that's the print server case, the printer case is even worse. 3720 */ 3721 3722/******************************************************************* 3723 * 3724 * enumerate all printers on the printserver 3725 * fill a notify_info struct with info asked 3726 * 3727 ********************************************************************/ 3728 3729static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, 3730 SPOOL_NOTIFY_INFO *info, 3731 TALLOC_CTX *mem_ctx) 3732{ 3733 int snum; 3734 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd); 3735 int n_services=lp_numservices(); 3736 int i; 3737 SPOOL_NOTIFY_OPTION *option; 3738 SPOOL_NOTIFY_OPTION_TYPE *option_type; 3739 3740 DEBUG(4,("printserver_notify_info\n")); 3741 3742 if (!Printer) 3743 return WERR_BADFID; 3744 3745 option=Printer->notify.option; 3746 info->version=2; 3747 info->data=NULL; 3748 info->count=0; 3749 3750 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without 3751 sending a ffpcn() request first */ 3752 3753 if ( !option ) 3754 return WERR_BADFID; 3755 3756 for (i=0; i<option->count; i++) { 3757 option_type=&(option->ctr.type[i]); 3758 3759 if (option_type->type!=PRINTER_NOTIFY_TYPE) 3760 continue; 3761 3762 for (snum=0; snum<n_services; snum++) 3763 { 3764 if ( lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) 3765 construct_notify_printer_info ( Printer, info, snum, option_type, snum, mem_ctx ); 3766 } 3767 } 3768 3769#if 0 3770 /* 3771 * Debugging information, don't delete. 3772 */ 3773 3774 DEBUG(1,("dumping the NOTIFY_INFO\n")); 3775 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count)); 3776 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n")); 3777 3778 for (i=0; i<info->count; i++) { 3779 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n", 3780 i, info->data[i].type, info->data[i].field, info->data[i].reserved, 3781 info->data[i].id, info->data[i].size, info->data[i].enc_type)); 3782 } 3783#endif 3784 3785 return WERR_OK; 3786} 3787 3788/******************************************************************* 3789 * 3790 * fill a notify_info struct with info asked 3791 * 3792 ********************************************************************/ 3793 3794static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info, 3795 TALLOC_CTX *mem_ctx) 3796{ 3797 int snum; 3798 Printer_entry *Printer=find_printer_index_by_hnd(p, hnd); 3799 int i; 3800 uint32 id; 3801 SPOOL_NOTIFY_OPTION *option; 3802 SPOOL_NOTIFY_OPTION_TYPE *option_type; 3803 int count,j; 3804 print_queue_struct *queue=NULL; 3805 print_status_struct status; 3806 3807 DEBUG(4,("printer_notify_info\n")); 3808 3809 if (!Printer) 3810 return WERR_BADFID; 3811 3812 option=Printer->notify.option; 3813 id = 0x0; 3814 info->version=2; 3815 info->data=NULL; 3816 info->count=0; 3817 3818 /* a bug in xp sp2 rc2 causes it to send a fnpcn request without 3819 sending a ffpcn() request first */ 3820 3821 if ( !option ) 3822 return WERR_BADFID; 3823 3824 get_printer_snum(p, hnd, &snum); 3825 3826 for (i=0; i<option->count; i++) { 3827 option_type=&option->ctr.type[i]; 3828 3829 switch ( option_type->type ) { 3830 case PRINTER_NOTIFY_TYPE: 3831 if(construct_notify_printer_info(Printer, info, snum, 3832 option_type, id, 3833 mem_ctx)) 3834 id--; 3835 break; 3836 3837 case JOB_NOTIFY_TYPE: { 3838 NT_PRINTER_INFO_LEVEL *printer = NULL; 3839 3840 count = print_queue_status(snum, &queue, &status); 3841 3842 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)))) 3843 goto done; 3844 3845 for (j=0; j<count; j++) { 3846 construct_notify_jobs_info(&queue[j], info, 3847 printer, snum, 3848 option_type, 3849 queue[j].job, 3850 mem_ctx); 3851 } 3852 3853 free_a_printer(&printer, 2); 3854 3855 done: 3856 SAFE_FREE(queue); 3857 break; 3858 } 3859 } 3860 } 3861 3862 /* 3863 * Debugging information, don't delete. 3864 */ 3865 /* 3866 DEBUG(1,("dumping the NOTIFY_INFO\n")); 3867 DEBUGADD(1,("info->version:[%d], info->flags:[%d], info->count:[%d]\n", info->version, info->flags, info->count)); 3868 DEBUGADD(1,("num\ttype\tfield\tres\tid\tsize\tenc_type\n")); 3869 3870 for (i=0; i<info->count; i++) { 3871 DEBUGADD(1,("[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\t[%d]\n", 3872 i, info->data[i].type, info->data[i].field, info->data[i].reserved, 3873 info->data[i].id, info->data[i].size, info->data[i].enc_type)); 3874 } 3875 */ 3876 return WERR_OK; 3877} 3878 3879/******************************************************************** 3880 * spoolss_rfnpcnex 3881 ********************************************************************/ 3882 3883WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCNEX *r_u) 3884{ 3885 POLICY_HND *handle = &q_u->handle; 3886 SPOOL_NOTIFY_INFO *info = &r_u->info; 3887 3888 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 3889 WERROR result = WERR_BADFID; 3890 3891 /* we always have a NOTIFY_INFO struct */ 3892 r_u->info_ptr=0x1; 3893 3894 if (!Printer) { 3895 DEBUG(2,("_spoolss_rfnpcnex: Invalid handle (%s:%u:%u).\n", 3896 OUR_HANDLE(handle))); 3897 goto done; 3898 } 3899 3900 DEBUG(4,("Printer type %x\n",Printer->printer_type)); 3901 3902 /* 3903 * We are now using the change value, and 3904 * I should check for PRINTER_NOTIFY_OPTIONS_REFRESH but as 3905 * I don't have a global notification system, I'm sending back all the 3906 * informations even when _NOTHING_ has changed. 3907 */ 3908 3909 /* We need to keep track of the change value to send back in 3910 RRPCN replies otherwise our updates are ignored. */ 3911 3912 Printer->notify.fnpcn = True; 3913 3914 if (Printer->notify.client_connected) { 3915 DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change)); 3916 Printer->notify.change = q_u->change; 3917 } 3918 3919 /* just ignore the SPOOL_NOTIFY_OPTION */ 3920 3921 switch (Printer->printer_type) { 3922 case SPLHND_SERVER: 3923 result = printserver_notify_info(p, handle, info, p->mem_ctx); 3924 break; 3925 3926 case SPLHND_PRINTER: 3927 result = printer_notify_info(p, handle, info, p->mem_ctx); 3928 break; 3929 } 3930 3931 Printer->notify.fnpcn = False; 3932 3933done: 3934 return result; 3935} 3936 3937/******************************************************************** 3938 * construct_printer_info_0 3939 * fill a printer_info_0 struct 3940 ********************************************************************/ 3941 3942static BOOL construct_printer_info_0(Printer_entry *print_hnd, PRINTER_INFO_0 *printer, int snum) 3943{ 3944 pstring chaine; 3945 int count; 3946 NT_PRINTER_INFO_LEVEL *ntprinter = NULL; 3947 counter_printer_0 *session_counter; 3948 uint32 global_counter; 3949 struct tm *t; 3950 time_t setuptime; 3951 print_status_struct status; 3952 3953 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) 3954 return False; 3955 3956 count = print_queue_length(snum, &status); 3957 3958 /* check if we already have a counter for this printer */ 3959 for(session_counter = counter_list; session_counter; session_counter = session_counter->next) { 3960 if (session_counter->snum == snum) 3961 break; 3962 } 3963 3964 /* it's the first time, add it to the list */ 3965 if (session_counter==NULL) { 3966 if((session_counter=SMB_MALLOC_P(counter_printer_0)) == NULL) { 3967 free_a_printer(&ntprinter, 2); 3968 return False; 3969 } 3970 ZERO_STRUCTP(session_counter); 3971 session_counter->snum=snum; 3972 session_counter->counter=0; 3973 DLIST_ADD(counter_list, session_counter); 3974 } 3975 3976 /* increment it */ 3977 session_counter->counter++; 3978 3979 /* JFM: 3980 * the global_counter should be stored in a TDB as it's common to all the clients 3981 * and should be zeroed on samba startup 3982 */ 3983 global_counter=session_counter->counter; 3984 3985 pstrcpy(chaine,ntprinter->info_2->printername); 3986 3987 init_unistr(&printer->printername, chaine); 3988 3989 slprintf(chaine,sizeof(chaine)-1,"\\\\%s", get_server_name(print_hnd)); 3990 init_unistr(&printer->servername, chaine); 3991 3992 printer->cjobs = count; 3993 printer->total_jobs = 0; 3994 printer->total_bytes = 0; 3995 3996 setuptime = (time_t)ntprinter->info_2->setuptime; 3997 t=gmtime(&setuptime); 3998 3999 printer->year = t->tm_year+1900; 4000 printer->month = t->tm_mon+1; 4001 printer->dayofweek = t->tm_wday; 4002 printer->day = t->tm_mday; 4003 printer->hour = t->tm_hour; 4004 printer->minute = t->tm_min; 4005 printer->second = t->tm_sec; 4006 printer->milliseconds = 0; 4007 4008 printer->global_counter = global_counter; 4009 printer->total_pages = 0; 4010 4011 /* in 2.2 we reported ourselves as 0x0004 and 0x0565 */ 4012 printer->major_version = 0x0005; /* NT 5 */ 4013 printer->build_version = 0x0893; /* build 2195 */ 4014 4015 printer->unknown7 = 0x1; 4016 printer->unknown8 = 0x0; 4017 printer->unknown9 = 0x0; 4018 printer->session_counter = session_counter->counter; 4019 printer->unknown11 = 0x0; 4020 printer->printer_errors = 0x0; /* number of print failure */ 4021 printer->unknown13 = 0x0; 4022 printer->unknown14 = 0x1; 4023 printer->unknown15 = 0x024a; /* 586 Pentium ? */ 4024 printer->unknown16 = 0x0; 4025 printer->change_id = ntprinter->info_2->changeid; /* ChangeID in milliseconds*/ 4026 printer->unknown18 = 0x0; 4027 printer->status = nt_printq_status(status.status); 4028 printer->unknown20 = 0x0; 4029 printer->c_setprinter = get_c_setprinter(); /* monotonically increasing sum of delta printer counts */ 4030 printer->unknown22 = 0x0; 4031 printer->unknown23 = 0x6; /* 6 ???*/ 4032 printer->unknown24 = 0; /* unknown 24 to 26 are always 0 */ 4033 printer->unknown25 = 0; 4034 printer->unknown26 = 0; 4035 printer->unknown27 = 0; 4036 printer->unknown28 = 0; 4037 printer->unknown29 = 0; 4038 4039 free_a_printer(&ntprinter,2); 4040 return (True); 4041} 4042 4043/******************************************************************** 4044 * construct_printer_info_1 4045 * fill a printer_info_1 struct 4046 ********************************************************************/ 4047static BOOL construct_printer_info_1(Printer_entry *print_hnd, uint32 flags, PRINTER_INFO_1 *printer, int snum) 4048{ 4049 pstring chaine; 4050 pstring chaine2; 4051 NT_PRINTER_INFO_LEVEL *ntprinter = NULL; 4052 4053 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) 4054 return False; 4055 4056 printer->flags=flags; 4057 4058 if (*ntprinter->info_2->comment == '\0') { 4059 init_unistr(&printer->comment, lp_comment(snum)); 4060 slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername, 4061 ntprinter->info_2->drivername, lp_comment(snum)); 4062 } 4063 else { 4064 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */ 4065 slprintf(chaine,sizeof(chaine)-1,"%s,%s,%s", ntprinter->info_2->printername, 4066 ntprinter->info_2->drivername, ntprinter->info_2->comment); 4067 } 4068 4069 slprintf(chaine2,sizeof(chaine)-1,"%s", ntprinter->info_2->printername); 4070 4071 init_unistr(&printer->description, chaine); 4072 init_unistr(&printer->name, chaine2); 4073 4074 free_a_printer(&ntprinter,2); 4075 4076 return True; 4077} 4078 4079/**************************************************************************** 4080 Free a DEVMODE struct. 4081****************************************************************************/ 4082 4083static void free_dev_mode(DEVICEMODE *dev) 4084{ 4085 if (dev == NULL) 4086 return; 4087 4088 SAFE_FREE(dev->dev_private); 4089 SAFE_FREE(dev); 4090} 4091 4092 4093/**************************************************************************** 4094 Convert an NT_DEVICEMODE to a DEVICEMODE structure. Both pointers 4095 should be valid upon entry 4096****************************************************************************/ 4097 4098static BOOL convert_nt_devicemode( DEVICEMODE *devmode, NT_DEVICEMODE *ntdevmode ) 4099{ 4100 if ( !devmode || !ntdevmode ) 4101 return False; 4102 4103 init_unistr(&devmode->devicename, ntdevmode->devicename); 4104 4105 init_unistr(&devmode->formname, ntdevmode->formname); 4106 4107 devmode->specversion = ntdevmode->specversion; 4108 devmode->driverversion = ntdevmode->driverversion; 4109 devmode->size = ntdevmode->size; 4110 devmode->driverextra = ntdevmode->driverextra; 4111 devmode->fields = ntdevmode->fields; 4112 4113 devmode->orientation = ntdevmode->orientation; 4114 devmode->papersize = ntdevmode->papersize; 4115 devmode->paperlength = ntdevmode->paperlength; 4116 devmode->paperwidth = ntdevmode->paperwidth; 4117 devmode->scale = ntdevmode->scale; 4118 devmode->copies = ntdevmode->copies; 4119 devmode->defaultsource = ntdevmode->defaultsource; 4120 devmode->printquality = ntdevmode->printquality; 4121 devmode->color = ntdevmode->color; 4122 devmode->duplex = ntdevmode->duplex; 4123 devmode->yresolution = ntdevmode->yresolution; 4124 devmode->ttoption = ntdevmode->ttoption; 4125 devmode->collate = ntdevmode->collate; 4126 devmode->icmmethod = ntdevmode->icmmethod; 4127 devmode->icmintent = ntdevmode->icmintent; 4128 devmode->mediatype = ntdevmode->mediatype; 4129 devmode->dithertype = ntdevmode->dithertype; 4130 4131 if (ntdevmode->nt_dev_private != NULL) { 4132 if ((devmode->dev_private=(uint8 *)memdup(ntdevmode->nt_dev_private, ntdevmode->driverextra)) == NULL) 4133 return False; 4134 } 4135 4136 return True; 4137} 4138 4139/**************************************************************************** 4140 Create a DEVMODE struct. Returns malloced memory. 4141****************************************************************************/ 4142 4143DEVICEMODE *construct_dev_mode(const char *servicename) 4144{ 4145 NT_PRINTER_INFO_LEVEL *printer = NULL; 4146 DEVICEMODE *devmode = NULL; 4147 4148 DEBUG(7,("construct_dev_mode\n")); 4149 4150 DEBUGADD(8,("getting printer characteristics\n")); 4151 4152 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename))) 4153 return NULL; 4154 4155 if ( !printer->info_2->devmode ) { 4156 DEBUG(5, ("BONG! There was no device mode!\n")); 4157 goto done; 4158 } 4159 4160 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) == NULL) { 4161 DEBUG(2,("construct_dev_mode: malloc fail.\n")); 4162 goto done; 4163 } 4164 4165 ZERO_STRUCTP(devmode); 4166 4167 DEBUGADD(8,("loading DEVICEMODE\n")); 4168 4169 if ( !convert_nt_devicemode( devmode, printer->info_2->devmode ) ) { 4170 free_dev_mode( devmode ); 4171 devmode = NULL; 4172 } 4173 4174done: 4175 free_a_printer(&printer,2); 4176 4177 return devmode; 4178} 4179 4180/******************************************************************** 4181 * construct_printer_info_2 4182 * fill a printer_info_2 struct 4183 ********************************************************************/ 4184 4185static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum) 4186{ 4187 int count; 4188 NT_PRINTER_INFO_LEVEL *ntprinter = NULL; 4189 4190 print_status_struct status; 4191 4192 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) 4193 return False; 4194 4195 count = print_queue_length(snum, &status); 4196 4197 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/ 4198 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/ 4199 init_unistr(&printer->sharename, lp_servicename(snum)); /* sharename */ 4200 init_unistr(&printer->portname, ntprinter->info_2->portname); /* port */ 4201 init_unistr(&printer->drivername, ntprinter->info_2->drivername); /* drivername */ 4202 4203 if (*ntprinter->info_2->comment == '\0') 4204 init_unistr(&printer->comment, lp_comment(snum)); /* comment */ 4205 else 4206 init_unistr(&printer->comment, ntprinter->info_2->comment); /* saved comment. */ 4207 4208 init_unistr(&printer->location, ntprinter->info_2->location); /* location */ 4209 init_unistr(&printer->sepfile, ntprinter->info_2->sepfile); /* separator file */ 4210 init_unistr(&printer->printprocessor, ntprinter->info_2->printprocessor);/* print processor */ 4211 init_unistr(&printer->datatype, ntprinter->info_2->datatype); /* datatype */ 4212 init_unistr(&printer->parameters, ntprinter->info_2->parameters); /* parameters (of print processor) */ 4213 4214 printer->attributes = ntprinter->info_2->attributes; 4215 4216 printer->priority = ntprinter->info_2->priority; /* priority */ 4217 printer->defaultpriority = ntprinter->info_2->default_priority; /* default priority */ 4218 printer->starttime = ntprinter->info_2->starttime; /* starttime */ 4219 printer->untiltime = ntprinter->info_2->untiltime; /* untiltime */ 4220 printer->status = nt_printq_status(status.status); /* status */ 4221 printer->cjobs = count; /* jobs */ 4222 printer->averageppm = ntprinter->info_2->averageppm; /* average pages per minute */ 4223 4224 if ( !(printer->devmode = construct_dev_mode( 4225 lp_const_servicename(snum))) ) 4226 DEBUG(8, ("Returning NULL Devicemode!\n")); 4227 4228 printer->secdesc = NULL; 4229 4230 if ( ntprinter->info_2->secdesc_buf 4231 && ntprinter->info_2->secdesc_buf->len != 0 ) 4232 { 4233 /* don't use talloc_steal() here unless you do a deep steal of all 4234 the SEC_DESC members */ 4235 4236 printer->secdesc = dup_sec_desc( get_talloc_ctx(), 4237 ntprinter->info_2->secdesc_buf->sec ); 4238 } 4239 4240 free_a_printer(&ntprinter, 2); 4241 4242 return True; 4243} 4244 4245/******************************************************************** 4246 * construct_printer_info_3 4247 * fill a printer_info_3 struct 4248 ********************************************************************/ 4249 4250static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum) 4251{ 4252 NT_PRINTER_INFO_LEVEL *ntprinter = NULL; 4253 PRINTER_INFO_3 *printer = NULL; 4254 4255 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) 4256 return False; 4257 4258 *pp_printer = NULL; 4259 if ((printer = SMB_MALLOC_P(PRINTER_INFO_3)) == NULL) { 4260 DEBUG(2,("construct_printer_info_3: malloc fail.\n")); 4261 free_a_printer(&ntprinter, 2); 4262 return False; 4263 } 4264 4265 ZERO_STRUCTP(printer); 4266 4267 /* These are the components of the SD we are returning. */ 4268 4269 if (ntprinter->info_2->secdesc_buf && ntprinter->info_2->secdesc_buf->len != 0) { 4270 /* don't use talloc_steal() here unless you do a deep steal of all 4271 the SEC_DESC members */ 4272 4273 printer->secdesc = dup_sec_desc( get_talloc_ctx(), 4274 ntprinter->info_2->secdesc_buf->sec ); 4275 } 4276 4277 free_a_printer(&ntprinter, 2); 4278 4279 *pp_printer = printer; 4280 return True; 4281} 4282 4283/******************************************************************** 4284 * construct_printer_info_4 4285 * fill a printer_info_4 struct 4286 ********************************************************************/ 4287 4288static BOOL construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum) 4289{ 4290 NT_PRINTER_INFO_LEVEL *ntprinter = NULL; 4291 4292 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) 4293 return False; 4294 4295 init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/ 4296 init_unistr(&printer->servername, ntprinter->info_2->servername); /* servername*/ 4297 printer->attributes = ntprinter->info_2->attributes; 4298 4299 free_a_printer(&ntprinter, 2); 4300 return True; 4301} 4302 4303/******************************************************************** 4304 * construct_printer_info_5 4305 * fill a printer_info_5 struct 4306 ********************************************************************/ 4307 4308static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum) 4309{ 4310 NT_PRINTER_INFO_LEVEL *ntprinter = NULL; 4311 4312 if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) 4313 return False; 4314 4315 init_unistr(&printer->printername, ntprinter->info_2->printername); 4316 init_unistr(&printer->portname, ntprinter->info_2->portname); 4317 printer->attributes = ntprinter->info_2->attributes; 4318 4319 /* these two are not used by NT+ according to MSDN */ 4320 4321 printer->device_not_selected_timeout = 0x0; /* have seen 0x3a98 */ 4322 printer->transmission_retry_timeout = 0x0; /* have seen 0xafc8 */ 4323 4324 free_a_printer(&ntprinter, 2); 4325 4326 return True; 4327} 4328 4329/******************************************************************** 4330 * construct_printer_info_7 4331 * fill a printer_info_7 struct 4332 ********************************************************************/ 4333 4334static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum) 4335{ 4336 char *guid_str = NULL; 4337 struct GUID guid; 4338 4339 if (is_printer_published(print_hnd, snum, &guid)) { 4340 asprintf(&guid_str, "{%s}", smb_uuid_string_static(guid)); 4341 strupper_m(guid_str); 4342 init_unistr(&printer->guid, guid_str); 4343 printer->action = SPOOL_DS_PUBLISH; 4344 } else { 4345 init_unistr(&printer->guid, ""); 4346 printer->action = SPOOL_DS_UNPUBLISH; 4347 } 4348 4349 return True; 4350} 4351 4352/******************************************************************** 4353 Spoolss_enumprinters. 4354********************************************************************/ 4355 4356static WERROR enum_all_printers_info_1(uint32 flags, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 4357{ 4358 int snum; 4359 int i; 4360 int n_services=lp_numservices(); 4361 PRINTER_INFO_1 *printers=NULL; 4362 PRINTER_INFO_1 current_prt; 4363 WERROR result = WERR_OK; 4364 4365 DEBUG(4,("enum_all_printers_info_1\n")); 4366 4367 for (snum=0; snum<n_services; snum++) { 4368 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { 4369 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); 4370 4371 if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) { 4372 if((printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_1, *returned +1)) == NULL) { 4373 DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n")); 4374 *returned=0; 4375 return WERR_NOMEM; 4376 } 4377 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *returned)); 4378 4379 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_1)); 4380 (*returned)++; 4381 } 4382 } 4383 } 4384 4385 /* check the required size. */ 4386 for (i=0; i<*returned; i++) 4387 (*needed) += spoolss_size_printer_info_1(&printers[i]); 4388 4389 if (*needed > offered) { 4390 result = WERR_INSUFFICIENT_BUFFER; 4391 goto out; 4392 } 4393 4394 if (!rpcbuf_alloc_size(buffer, *needed)) { 4395 result = WERR_NOMEM; 4396 goto out; 4397 } 4398 4399 /* fill the buffer with the structures */ 4400 for (i=0; i<*returned; i++) 4401 smb_io_printer_info_1("", buffer, &printers[i], 0); 4402 4403out: 4404 /* clear memory */ 4405 4406 SAFE_FREE(printers); 4407 4408 if ( !W_ERROR_IS_OK(result) ) 4409 *returned = 0; 4410 4411 return result; 4412} 4413 4414/******************************************************************** 4415 enum_all_printers_info_1_local. 4416*********************************************************************/ 4417 4418static WERROR enum_all_printers_info_1_local(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 4419{ 4420 DEBUG(4,("enum_all_printers_info_1_local\n")); 4421 4422 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned); 4423} 4424 4425/******************************************************************** 4426 enum_all_printers_info_1_name. 4427*********************************************************************/ 4428 4429static WERROR enum_all_printers_info_1_name(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 4430{ 4431 char *s = name; 4432 4433 DEBUG(4,("enum_all_printers_info_1_name\n")); 4434 4435 if ((name[0] == '\\') && (name[1] == '\\')) 4436 s = name + 2; 4437 4438 if (is_myname_or_ipaddr(s)) { 4439 return enum_all_printers_info_1(PRINTER_ENUM_ICON8, buffer, offered, needed, returned); 4440 } 4441 else 4442 return WERR_INVALID_NAME; 4443} 4444 4445#if 0 /* JERRY -- disabled for now. Don't think this is used, tested, or correct */ 4446/******************************************************************** 4447 enum_all_printers_info_1_remote. 4448*********************************************************************/ 4449 4450static WERROR enum_all_printers_info_1_remote(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 4451{ 4452 PRINTER_INFO_1 *printer; 4453 fstring printername; 4454 fstring desc; 4455 fstring comment; 4456 DEBUG(4,("enum_all_printers_info_1_remote\n")); 4457 WERROR result = WERR_OK; 4458 4459 /* JFM: currently it's more a place holder than anything else. 4460 * In the spooler world there is a notion of server registration. 4461 * the print servers are registered on the PDC (in the same domain) 4462 * 4463 * We should have a TDB here. The registration is done thru an 4464 * undocumented RPC call. 4465 */ 4466 4467 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL) 4468 return WERR_NOMEM; 4469 4470 *returned=1; 4471 4472 slprintf(printername, sizeof(printername)-1,"Windows NT Remote Printers!!\\\\%s", name); 4473 slprintf(desc, sizeof(desc)-1,"%s", name); 4474 slprintf(comment, sizeof(comment)-1, "Logged on Domain"); 4475 4476 init_unistr(&printer->description, desc); 4477 init_unistr(&printer->name, printername); 4478 init_unistr(&printer->comment, comment); 4479 printer->flags=PRINTER_ENUM_ICON3|PRINTER_ENUM_CONTAINER; 4480 4481 /* check the required size. */ 4482 *needed += spoolss_size_printer_info_1(printer); 4483 4484 if (*needed > offered) { 4485 result = WERR_INSUFFICIENT_BUFFER; 4486 goto out; 4487 } 4488 4489 if (!rpcbuf_alloc_size(buffer, *needed)) { 4490 result = WERR_NOMEM; 4491 goto out; 4492 } 4493 4494 /* fill the buffer with the structures */ 4495 smb_io_printer_info_1("", buffer, printer, 0); 4496 4497out: 4498 /* clear memory */ 4499 SAFE_FREE(printer); 4500 4501 if ( !W_ERROR_IS_OK(result) ) 4502 *returned = 0; 4503 4504 return result; 4505} 4506 4507#endif 4508 4509/******************************************************************** 4510 enum_all_printers_info_1_network. 4511*********************************************************************/ 4512 4513static WERROR enum_all_printers_info_1_network(fstring name, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 4514{ 4515 char *s = name; 4516 4517 DEBUG(4,("enum_all_printers_info_1_network\n")); 4518 4519 /* If we respond to a enum_printers level 1 on our name with flags 4520 set to PRINTER_ENUM_REMOTE with a list of printers then these 4521 printers incorrectly appear in the APW browse list. 4522 Specifically the printers for the server appear at the workgroup 4523 level where all the other servers in the domain are 4524 listed. Windows responds to this call with a 4525 WERR_CAN_NOT_COMPLETE so we should do the same. */ 4526 4527 if (name[0] == '\\' && name[1] == '\\') 4528 s = name + 2; 4529 4530 if (is_myname_or_ipaddr(s)) 4531 return WERR_CAN_NOT_COMPLETE; 4532 4533 return enum_all_printers_info_1(PRINTER_ENUM_UNKNOWN_8, buffer, offered, needed, returned); 4534} 4535 4536/******************************************************************** 4537 * api_spoolss_enumprinters 4538 * 4539 * called from api_spoolss_enumprinters (see this to understand) 4540 ********************************************************************/ 4541 4542static WERROR enum_all_printers_info_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 4543{ 4544 int snum; 4545 int i; 4546 int n_services=lp_numservices(); 4547 PRINTER_INFO_2 *printers=NULL; 4548 PRINTER_INFO_2 current_prt; 4549 WERROR result = WERR_OK; 4550 4551 *returned = 0; 4552 4553 for (snum=0; snum<n_services; snum++) { 4554 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { 4555 DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); 4556 4557 if (construct_printer_info_2(NULL, ¤t_prt, snum)) { 4558 if ( !(printers=SMB_REALLOC_ARRAY(printers, PRINTER_INFO_2, *returned +1)) ) { 4559 DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n")); 4560 *returned = 0; 4561 return WERR_NOMEM; 4562 } 4563 4564 DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *returned + 1)); 4565 4566 memcpy(&printers[*returned], ¤t_prt, sizeof(PRINTER_INFO_2)); 4567 4568 (*returned)++; 4569 } 4570 } 4571 } 4572 4573 /* check the required size. */ 4574 for (i=0; i<*returned; i++) 4575 (*needed) += spoolss_size_printer_info_2(&printers[i]); 4576 4577 if (*needed > offered) { 4578 result = WERR_INSUFFICIENT_BUFFER; 4579 goto out; 4580 } 4581 4582 if (!rpcbuf_alloc_size(buffer, *needed)) { 4583 result = WERR_NOMEM; 4584 goto out; 4585 } 4586 4587 /* fill the buffer with the structures */ 4588 for (i=0; i<*returned; i++) 4589 smb_io_printer_info_2("", buffer, &(printers[i]), 0); 4590 4591out: 4592 /* clear memory */ 4593 4594 for (i=0; i<*returned; i++) 4595 free_devmode(printers[i].devmode); 4596 4597 SAFE_FREE(printers); 4598 4599 if ( !W_ERROR_IS_OK(result) ) 4600 *returned = 0; 4601 4602 return result; 4603} 4604 4605/******************************************************************** 4606 * handle enumeration of printers at level 1 4607 ********************************************************************/ 4608 4609static WERROR enumprinters_level1( uint32 flags, fstring name, 4610 RPC_BUFFER *buffer, uint32 offered, 4611 uint32 *needed, uint32 *returned) 4612{ 4613 /* Not all the flags are equals */ 4614 4615 if (flags & PRINTER_ENUM_LOCAL) 4616 return enum_all_printers_info_1_local(buffer, offered, needed, returned); 4617 4618 if (flags & PRINTER_ENUM_NAME) 4619 return enum_all_printers_info_1_name(name, buffer, offered, needed, returned); 4620 4621#if 0 /* JERRY - disabled for now */ 4622 if (flags & PRINTER_ENUM_REMOTE) 4623 return enum_all_printers_info_1_remote(name, buffer, offered, needed, returned); 4624#endif 4625 4626 if (flags & PRINTER_ENUM_NETWORK) 4627 return enum_all_printers_info_1_network(name, buffer, offered, needed, returned); 4628 4629 return WERR_OK; /* NT4sp5 does that */ 4630} 4631 4632/******************************************************************** 4633 * handle enumeration of printers at level 2 4634 ********************************************************************/ 4635 4636static WERROR enumprinters_level2( uint32 flags, fstring servername, 4637 RPC_BUFFER *buffer, uint32 offered, 4638 uint32 *needed, uint32 *returned) 4639{ 4640 char *s = servername; 4641 4642 if (flags & PRINTER_ENUM_LOCAL) { 4643 return enum_all_printers_info_2(buffer, offered, needed, returned); 4644 } 4645 4646 if (flags & PRINTER_ENUM_NAME) { 4647 if ((servername[0] == '\\') && (servername[1] == '\\')) 4648 s = servername + 2; 4649 if (is_myname_or_ipaddr(s)) 4650 return enum_all_printers_info_2(buffer, offered, needed, returned); 4651 else 4652 return WERR_INVALID_NAME; 4653 } 4654 4655 if (flags & PRINTER_ENUM_REMOTE) 4656 return WERR_UNKNOWN_LEVEL; 4657 4658 return WERR_OK; 4659} 4660 4661/******************************************************************** 4662 * handle enumeration of printers at level 5 4663 ********************************************************************/ 4664 4665static WERROR enumprinters_level5( uint32 flags, fstring servername, 4666 RPC_BUFFER *buffer, uint32 offered, 4667 uint32 *needed, uint32 *returned) 4668{ 4669/* return enum_all_printers_info_5(buffer, offered, needed, returned);*/ 4670 return WERR_OK; 4671} 4672 4673/******************************************************************** 4674 * api_spoolss_enumprinters 4675 * 4676 * called from api_spoolss_enumprinters (see this to understand) 4677 ********************************************************************/ 4678 4679WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_R_ENUMPRINTERS *r_u) 4680{ 4681 uint32 flags = q_u->flags; 4682 UNISTR2 *servername = &q_u->servername; 4683 uint32 level = q_u->level; 4684 RPC_BUFFER *buffer = NULL; 4685 uint32 offered = q_u->offered; 4686 uint32 *needed = &r_u->needed; 4687 uint32 *returned = &r_u->returned; 4688 4689 fstring name; 4690 4691 /* that's an [in out] buffer */ 4692 4693 if (!q_u->buffer && (offered!=0)) { 4694 return WERR_INVALID_PARAM; 4695 } 4696 4697 rpcbuf_move(q_u->buffer, &r_u->buffer); 4698 buffer = r_u->buffer; 4699 4700 DEBUG(4,("_spoolss_enumprinters\n")); 4701 4702 *needed=0; 4703 *returned=0; 4704 4705 /* 4706 * Level 1: 4707 * flags==PRINTER_ENUM_NAME 4708 * if name=="" then enumerates all printers 4709 * if name!="" then enumerate the printer 4710 * flags==PRINTER_ENUM_REMOTE 4711 * name is NULL, enumerate printers 4712 * Level 2: name!="" enumerates printers, name can't be NULL 4713 * Level 3: doesn't exist 4714 * Level 4: does a local registry lookup 4715 * Level 5: same as Level 2 4716 */ 4717 4718 unistr2_to_ascii(name, servername, sizeof(name)-1); 4719 strupper_m(name); 4720 4721 switch (level) { 4722 case 1: 4723 return enumprinters_level1(flags, name, buffer, offered, needed, returned); 4724 case 2: 4725 return enumprinters_level2(flags, name, buffer, offered, needed, returned); 4726 case 5: 4727 return enumprinters_level5(flags, name, buffer, offered, needed, returned); 4728 case 3: 4729 case 4: 4730 break; 4731 } 4732 return WERR_UNKNOWN_LEVEL; 4733} 4734 4735/**************************************************************************** 4736****************************************************************************/ 4737 4738static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 4739{ 4740 PRINTER_INFO_0 *printer=NULL; 4741 WERROR result = WERR_OK; 4742 4743 if((printer=SMB_MALLOC_P(PRINTER_INFO_0)) == NULL) 4744 return WERR_NOMEM; 4745 4746 construct_printer_info_0(print_hnd, printer, snum); 4747 4748 /* check the required size. */ 4749 *needed += spoolss_size_printer_info_0(printer); 4750 4751 if (*needed > offered) { 4752 result = WERR_INSUFFICIENT_BUFFER; 4753 goto out; 4754 } 4755 4756 if (!rpcbuf_alloc_size(buffer, *needed)) { 4757 result = WERR_NOMEM; 4758 goto out; 4759 } 4760 4761 /* fill the buffer with the structures */ 4762 smb_io_printer_info_0("", buffer, printer, 0); 4763 4764out: 4765 /* clear memory */ 4766 4767 SAFE_FREE(printer); 4768 4769 return result; 4770} 4771 4772/**************************************************************************** 4773****************************************************************************/ 4774 4775static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 4776{ 4777 PRINTER_INFO_1 *printer=NULL; 4778 WERROR result = WERR_OK; 4779 4780 if((printer=SMB_MALLOC_P(PRINTER_INFO_1)) == NULL) 4781 return WERR_NOMEM; 4782 4783 construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum); 4784 4785 /* check the required size. */ 4786 *needed += spoolss_size_printer_info_1(printer); 4787 4788 if (*needed > offered) { 4789 result = WERR_INSUFFICIENT_BUFFER; 4790 goto out; 4791 } 4792 4793 if (!rpcbuf_alloc_size(buffer, *needed)) { 4794 result = WERR_NOMEM; 4795 goto out; 4796 } 4797 4798 /* fill the buffer with the structures */ 4799 smb_io_printer_info_1("", buffer, printer, 0); 4800 4801out: 4802 /* clear memory */ 4803 SAFE_FREE(printer); 4804 4805 return result; 4806} 4807 4808/**************************************************************************** 4809****************************************************************************/ 4810 4811static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 4812{ 4813 PRINTER_INFO_2 *printer=NULL; 4814 WERROR result = WERR_OK; 4815 4816 if((printer=SMB_MALLOC_P(PRINTER_INFO_2))==NULL) 4817 return WERR_NOMEM; 4818 4819 construct_printer_info_2(print_hnd, printer, snum); 4820 4821 /* check the required size. */ 4822 *needed += spoolss_size_printer_info_2(printer); 4823 4824 if (*needed > offered) { 4825 result = WERR_INSUFFICIENT_BUFFER; 4826 goto out; 4827 } 4828 4829 if (!rpcbuf_alloc_size(buffer, *needed)) { 4830 result = WERR_NOMEM; 4831 goto out; 4832 } 4833 4834 /* fill the buffer with the structures */ 4835 if (!smb_io_printer_info_2("", buffer, printer, 0)) 4836 result = WERR_NOMEM; 4837 4838out: 4839 /* clear memory */ 4840 free_printer_info_2(printer); 4841 4842 return result; 4843} 4844 4845/**************************************************************************** 4846****************************************************************************/ 4847 4848static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 4849{ 4850 PRINTER_INFO_3 *printer=NULL; 4851 WERROR result = WERR_OK; 4852 4853 if (!construct_printer_info_3(print_hnd, &printer, snum)) 4854 return WERR_NOMEM; 4855 4856 /* check the required size. */ 4857 *needed += spoolss_size_printer_info_3(printer); 4858 4859 if (*needed > offered) { 4860 result = WERR_INSUFFICIENT_BUFFER; 4861 goto out; 4862 } 4863 4864 if (!rpcbuf_alloc_size(buffer, *needed)) { 4865 result = WERR_NOMEM; 4866 goto out; 4867 } 4868 4869 /* fill the buffer with the structures */ 4870 smb_io_printer_info_3("", buffer, printer, 0); 4871 4872out: 4873 /* clear memory */ 4874 free_printer_info_3(printer); 4875 4876 return result; 4877} 4878 4879/**************************************************************************** 4880****************************************************************************/ 4881 4882static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 4883{ 4884 PRINTER_INFO_4 *printer=NULL; 4885 WERROR result = WERR_OK; 4886 4887 if((printer=SMB_MALLOC_P(PRINTER_INFO_4))==NULL) 4888 return WERR_NOMEM; 4889 4890 if (!construct_printer_info_4(print_hnd, printer, snum)) { 4891 SAFE_FREE(printer); 4892 return WERR_NOMEM; 4893 } 4894 4895 /* check the required size. */ 4896 *needed += spoolss_size_printer_info_4(printer); 4897 4898 if (*needed > offered) { 4899 result = WERR_INSUFFICIENT_BUFFER; 4900 goto out; 4901 } 4902 4903 if (!rpcbuf_alloc_size(buffer, *needed)) { 4904 result = WERR_NOMEM; 4905 goto out; 4906 } 4907 4908 /* fill the buffer with the structures */ 4909 smb_io_printer_info_4("", buffer, printer, 0); 4910 4911out: 4912 /* clear memory */ 4913 free_printer_info_4(printer); 4914 4915 return result; 4916} 4917 4918/**************************************************************************** 4919****************************************************************************/ 4920 4921static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 4922{ 4923 PRINTER_INFO_5 *printer=NULL; 4924 WERROR result = WERR_OK; 4925 4926 if((printer=SMB_MALLOC_P(PRINTER_INFO_5))==NULL) 4927 return WERR_NOMEM; 4928 4929 if (!construct_printer_info_5(print_hnd, printer, snum)) { 4930 free_printer_info_5(printer); 4931 return WERR_NOMEM; 4932 } 4933 4934 /* check the required size. */ 4935 *needed += spoolss_size_printer_info_5(printer); 4936 4937 if (*needed > offered) { 4938 result = WERR_INSUFFICIENT_BUFFER; 4939 goto out; 4940 } 4941 4942 if (!rpcbuf_alloc_size(buffer, *needed)) { 4943 result = WERR_NOMEM; 4944 goto out; 4945 } 4946 4947 /* fill the buffer with the structures */ 4948 smb_io_printer_info_5("", buffer, printer, 0); 4949 4950out: 4951 /* clear memory */ 4952 free_printer_info_5(printer); 4953 4954 return result; 4955} 4956 4957static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 4958{ 4959 PRINTER_INFO_7 *printer=NULL; 4960 WERROR result = WERR_OK; 4961 4962 if((printer=SMB_MALLOC_P(PRINTER_INFO_7))==NULL) 4963 return WERR_NOMEM; 4964 4965 if (!construct_printer_info_7(print_hnd, printer, snum)) 4966 return WERR_NOMEM; 4967 4968 /* check the required size. */ 4969 *needed += spoolss_size_printer_info_7(printer); 4970 4971 if (*needed > offered) { 4972 result = WERR_INSUFFICIENT_BUFFER; 4973 goto out; 4974 } 4975 4976 if (!rpcbuf_alloc_size(buffer, *needed)) { 4977 result = WERR_NOMEM; 4978 goto out; 4979 4980 } 4981 4982 /* fill the buffer with the structures */ 4983 smb_io_printer_info_7("", buffer, printer, 0); 4984 4985out: 4986 /* clear memory */ 4987 free_printer_info_7(printer); 4988 4989 return result; 4990} 4991 4992/**************************************************************************** 4993****************************************************************************/ 4994 4995WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GETPRINTER *r_u) 4996{ 4997 POLICY_HND *handle = &q_u->handle; 4998 uint32 level = q_u->level; 4999 RPC_BUFFER *buffer = NULL; 5000 uint32 offered = q_u->offered; 5001 uint32 *needed = &r_u->needed; 5002 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 5003 5004 int snum; 5005 5006 /* that's an [in out] buffer */ 5007 5008 if (!q_u->buffer && (offered!=0)) { 5009 return WERR_INVALID_PARAM; 5010 } 5011 5012 rpcbuf_move(q_u->buffer, &r_u->buffer); 5013 buffer = r_u->buffer; 5014 5015 *needed=0; 5016 5017 if (!get_printer_snum(p, handle, &snum)) 5018 return WERR_BADFID; 5019 5020 switch (level) { 5021 case 0: 5022 return getprinter_level_0(Printer, snum, buffer, offered, needed); 5023 case 1: 5024 return getprinter_level_1(Printer, snum, buffer, offered, needed); 5025 case 2: 5026 return getprinter_level_2(Printer, snum, buffer, offered, needed); 5027 case 3: 5028 return getprinter_level_3(Printer, snum, buffer, offered, needed); 5029 case 4: 5030 return getprinter_level_4(Printer, snum, buffer, offered, needed); 5031 case 5: 5032 return getprinter_level_5(Printer, snum, buffer, offered, needed); 5033 case 7: 5034 return getprinter_level_7(Printer, snum, buffer, offered, needed); 5035 } 5036 return WERR_UNKNOWN_LEVEL; 5037} 5038 5039/******************************************************************** 5040 * fill a DRIVER_INFO_1 struct 5041 ********************************************************************/ 5042 5043static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture) 5044{ 5045 init_unistr( &info->name, driver.info_3->name); 5046} 5047 5048/******************************************************************** 5049 * construct_printer_driver_info_1 5050 ********************************************************************/ 5051 5052static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version) 5053{ 5054 NT_PRINTER_INFO_LEVEL *printer = NULL; 5055 NT_PRINTER_DRIVER_INFO_LEVEL driver; 5056 5057 ZERO_STRUCT(driver); 5058 5059 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum)))) 5060 return WERR_INVALID_PRINTER_NAME; 5061 5062 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) { 5063 free_a_printer(&printer, 2); 5064 return WERR_UNKNOWN_PRINTER_DRIVER; 5065 } 5066 5067 fill_printer_driver_info_1(info, driver, servername, architecture); 5068 5069 free_a_printer(&printer,2); 5070 5071 return WERR_OK; 5072} 5073 5074/******************************************************************** 5075 * construct_printer_driver_info_2 5076 * fill a printer_info_2 struct 5077 ********************************************************************/ 5078 5079static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername) 5080{ 5081 pstring temp; 5082 5083 info->version=driver.info_3->cversion; 5084 5085 init_unistr( &info->name, driver.info_3->name ); 5086 init_unistr( &info->architecture, driver.info_3->environment ); 5087 5088 5089 if (strlen(driver.info_3->driverpath)) { 5090 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath); 5091 init_unistr( &info->driverpath, temp ); 5092 } else 5093 init_unistr( &info->driverpath, "" ); 5094 5095 if (strlen(driver.info_3->datafile)) { 5096 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile); 5097 init_unistr( &info->datafile, temp ); 5098 } else 5099 init_unistr( &info->datafile, "" ); 5100 5101 if (strlen(driver.info_3->configfile)) { 5102 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile); 5103 init_unistr( &info->configfile, temp ); 5104 } else 5105 init_unistr( &info->configfile, "" ); 5106} 5107 5108/******************************************************************** 5109 * construct_printer_driver_info_2 5110 * fill a printer_info_2 struct 5111 ********************************************************************/ 5112 5113static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version) 5114{ 5115 NT_PRINTER_INFO_LEVEL *printer = NULL; 5116 NT_PRINTER_DRIVER_INFO_LEVEL driver; 5117 5118 ZERO_STRUCT(printer); 5119 ZERO_STRUCT(driver); 5120 5121 if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum)))) 5122 return WERR_INVALID_PRINTER_NAME; 5123 5124 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) { 5125 free_a_printer(&printer, 2); 5126 return WERR_UNKNOWN_PRINTER_DRIVER; 5127 } 5128 5129 fill_printer_driver_info_2(info, driver, servername); 5130 5131 free_a_printer(&printer,2); 5132 5133 return WERR_OK; 5134} 5135 5136/******************************************************************** 5137 * copy a strings array and convert to UNICODE 5138 * 5139 * convert an array of ascii string to a UNICODE string 5140 ********************************************************************/ 5141 5142static uint32 init_unistr_array(uint16 **uni_array, fstring *char_array, const char *servername) 5143{ 5144 int i=0; 5145 int j=0; 5146 const char *v; 5147 pstring line; 5148 5149 DEBUG(6,("init_unistr_array\n")); 5150 *uni_array=NULL; 5151 5152 while (True) 5153 { 5154 if ( !char_array ) 5155 v = ""; 5156 else 5157 { 5158 v = char_array[i]; 5159 if (!v) 5160 v = ""; /* hack to handle null lists */ 5161 } 5162 5163 /* hack to allow this to be used in places other than when generating 5164 the list of dependent files */ 5165 5166 if ( servername ) 5167 slprintf( line, sizeof(line)-1, "\\\\%s%s", servername, v ); 5168 else 5169 pstrcpy( line, v ); 5170 5171 DEBUGADD(6,("%d:%s:%lu\n", i, line, (unsigned long)strlen(line))); 5172 5173 /* add one extra unit16 for the second terminating NULL */ 5174 5175 if ( (*uni_array=SMB_REALLOC_ARRAY(*uni_array, uint16, j+1+strlen(line)+2)) == NULL ) { 5176 DEBUG(2,("init_unistr_array: Realloc error\n" )); 5177 return 0; 5178 } 5179 5180 if ( !strlen(v) ) 5181 break; 5182 5183 j += (rpcstr_push((*uni_array+j), line, sizeof(uint16)*strlen(line)+2, STR_TERMINATE) / sizeof(uint16)); 5184 i++; 5185 } 5186 5187 if (*uni_array) { 5188 /* special case for ""; we need to add both NULL's here */ 5189 if (!j) 5190 (*uni_array)[j++]=0x0000; 5191 (*uni_array)[j]=0x0000; 5192 } 5193 5194 DEBUGADD(6,("last one:done\n")); 5195 5196 /* return size of array in uint16's */ 5197 5198 return j+1; 5199} 5200 5201/******************************************************************** 5202 * construct_printer_info_3 5203 * fill a printer_info_3 struct 5204 ********************************************************************/ 5205 5206static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername) 5207{ 5208 pstring temp; 5209 5210 ZERO_STRUCTP(info); 5211 5212 info->version=driver.info_3->cversion; 5213 5214 init_unistr( &info->name, driver.info_3->name ); 5215 init_unistr( &info->architecture, driver.info_3->environment ); 5216 5217 if (strlen(driver.info_3->driverpath)) { 5218 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath); 5219 init_unistr( &info->driverpath, temp ); 5220 } else 5221 init_unistr( &info->driverpath, "" ); 5222 5223 if (strlen(driver.info_3->datafile)) { 5224 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile); 5225 init_unistr( &info->datafile, temp ); 5226 } else 5227 init_unistr( &info->datafile, "" ); 5228 5229 if (strlen(driver.info_3->configfile)) { 5230 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile); 5231 init_unistr( &info->configfile, temp ); 5232 } else 5233 init_unistr( &info->configfile, "" ); 5234 5235 if (strlen(driver.info_3->helpfile)) { 5236 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile); 5237 init_unistr( &info->helpfile, temp ); 5238 } else 5239 init_unistr( &info->helpfile, "" ); 5240 5241 init_unistr( &info->monitorname, driver.info_3->monitorname ); 5242 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype ); 5243 5244 info->dependentfiles=NULL; 5245 init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername); 5246} 5247 5248/******************************************************************** 5249 * construct_printer_info_3 5250 * fill a printer_info_3 struct 5251 ********************************************************************/ 5252 5253static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version) 5254{ 5255 NT_PRINTER_INFO_LEVEL *printer = NULL; 5256 NT_PRINTER_DRIVER_INFO_LEVEL driver; 5257 WERROR status; 5258 ZERO_STRUCT(driver); 5259 5260 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) ); 5261 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); 5262 if (!W_ERROR_IS_OK(status)) 5263 return WERR_INVALID_PRINTER_NAME; 5264 5265 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); 5266 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); 5267 5268#if 0 /* JERRY */ 5269 5270 /* 5271 * I put this code in during testing. Helpful when commenting out the 5272 * support for DRIVER_INFO_6 in regards to win2k. Not needed in general 5273 * as win2k always queries the driver using an infor level of 6. 5274 * I've left it in (but ifdef'd out) because I'll probably 5275 * use it in experimentation again in the future. --jerry 22/01/2002 5276 */ 5277 5278 if (!W_ERROR_IS_OK(status)) { 5279 /* 5280 * Is this a W2k client ? 5281 */ 5282 if (version == 3) { 5283 /* Yes - try again with a WinNT driver. */ 5284 version = 2; 5285 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); 5286 DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); 5287 } 5288#endif 5289 5290 if (!W_ERROR_IS_OK(status)) { 5291 free_a_printer(&printer,2); 5292 return WERR_UNKNOWN_PRINTER_DRIVER; 5293 } 5294 5295#if 0 /* JERRY */ 5296 } 5297#endif 5298 5299 5300 fill_printer_driver_info_3(info, driver, servername); 5301 5302 free_a_printer(&printer,2); 5303 5304 return WERR_OK; 5305} 5306 5307/******************************************************************** 5308 * construct_printer_info_6 5309 * fill a printer_info_6 struct - we know that driver is really level 3. This sucks. JRA. 5310 ********************************************************************/ 5311 5312static void fill_printer_driver_info_6(DRIVER_INFO_6 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername) 5313{ 5314 pstring temp; 5315 fstring nullstr; 5316 5317 ZERO_STRUCTP(info); 5318 memset(&nullstr, '\0', sizeof(fstring)); 5319 5320 info->version=driver.info_3->cversion; 5321 5322 init_unistr( &info->name, driver.info_3->name ); 5323 init_unistr( &info->architecture, driver.info_3->environment ); 5324 5325 if (strlen(driver.info_3->driverpath)) { 5326 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->driverpath); 5327 init_unistr( &info->driverpath, temp ); 5328 } else 5329 init_unistr( &info->driverpath, "" ); 5330 5331 if (strlen(driver.info_3->datafile)) { 5332 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->datafile); 5333 init_unistr( &info->datafile, temp ); 5334 } else 5335 init_unistr( &info->datafile, "" ); 5336 5337 if (strlen(driver.info_3->configfile)) { 5338 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->configfile); 5339 init_unistr( &info->configfile, temp ); 5340 } else 5341 init_unistr( &info->configfile, "" ); 5342 5343 if (strlen(driver.info_3->helpfile)) { 5344 slprintf(temp, sizeof(temp)-1, "\\\\%s%s", servername, driver.info_3->helpfile); 5345 init_unistr( &info->helpfile, temp ); 5346 } else 5347 init_unistr( &info->helpfile, "" ); 5348 5349 init_unistr( &info->monitorname, driver.info_3->monitorname ); 5350 init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype ); 5351 5352 info->dependentfiles = NULL; 5353 init_unistr_array( &info->dependentfiles, driver.info_3->dependentfiles, servername ); 5354 5355 info->previousdrivernames=NULL; 5356 init_unistr_array(&info->previousdrivernames, &nullstr, servername); 5357 5358 info->driver_date=0; 5359 5360 info->padding=0; 5361 info->driver_version_low=0; 5362 info->driver_version_high=0; 5363 5364 init_unistr( &info->mfgname, ""); 5365 init_unistr( &info->oem_url, ""); 5366 init_unistr( &info->hardware_id, ""); 5367 init_unistr( &info->provider, ""); 5368} 5369 5370/******************************************************************** 5371 * construct_printer_info_6 5372 * fill a printer_info_6 struct 5373 ********************************************************************/ 5374 5375static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, 5376 fstring servername, fstring architecture, uint32 version) 5377{ 5378 NT_PRINTER_INFO_LEVEL *printer = NULL; 5379 NT_PRINTER_DRIVER_INFO_LEVEL driver; 5380 WERROR status; 5381 5382 ZERO_STRUCT(driver); 5383 5384 status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) ); 5385 5386 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); 5387 5388 if (!W_ERROR_IS_OK(status)) 5389 return WERR_INVALID_PRINTER_NAME; 5390 5391 status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); 5392 5393 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); 5394 5395 if (!W_ERROR_IS_OK(status)) 5396 { 5397 /* 5398 * Is this a W2k client ? 5399 */ 5400 5401 if (version < 3) { 5402 free_a_printer(&printer,2); 5403 return WERR_UNKNOWN_PRINTER_DRIVER; 5404 } 5405 5406 /* Yes - try again with a WinNT driver. */ 5407 version = 2; 5408 status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); 5409 DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); 5410 if (!W_ERROR_IS_OK(status)) { 5411 free_a_printer(&printer,2); 5412 return WERR_UNKNOWN_PRINTER_DRIVER; 5413 } 5414 } 5415 5416 fill_printer_driver_info_6(info, driver, servername); 5417 5418 free_a_printer(&printer,2); 5419 free_a_printer_driver(driver, 3); 5420 5421 return WERR_OK; 5422} 5423 5424/**************************************************************************** 5425****************************************************************************/ 5426 5427static void free_printer_driver_info_3(DRIVER_INFO_3 *info) 5428{ 5429 SAFE_FREE(info->dependentfiles); 5430} 5431 5432/**************************************************************************** 5433****************************************************************************/ 5434 5435static void free_printer_driver_info_6(DRIVER_INFO_6 *info) 5436{ 5437 SAFE_FREE(info->dependentfiles); 5438} 5439 5440/**************************************************************************** 5441****************************************************************************/ 5442 5443static WERROR getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 5444{ 5445 DRIVER_INFO_1 *info=NULL; 5446 WERROR result; 5447 5448 if((info=SMB_MALLOC_P(DRIVER_INFO_1)) == NULL) 5449 return WERR_NOMEM; 5450 5451 result = construct_printer_driver_info_1(info, snum, servername, architecture, version); 5452 if (!W_ERROR_IS_OK(result)) 5453 goto out; 5454 5455 /* check the required size. */ 5456 *needed += spoolss_size_printer_driver_info_1(info); 5457 5458 if (*needed > offered) { 5459 result = WERR_INSUFFICIENT_BUFFER; 5460 goto out; 5461 } 5462 5463 if (!rpcbuf_alloc_size(buffer, *needed)) { 5464 result = WERR_NOMEM; 5465 goto out; 5466 } 5467 5468 /* fill the buffer with the structures */ 5469 smb_io_printer_driver_info_1("", buffer, info, 0); 5470 5471out: 5472 /* clear memory */ 5473 SAFE_FREE(info); 5474 5475 return result; 5476} 5477 5478/**************************************************************************** 5479****************************************************************************/ 5480 5481static WERROR getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 5482{ 5483 DRIVER_INFO_2 *info=NULL; 5484 WERROR result; 5485 5486 if((info=SMB_MALLOC_P(DRIVER_INFO_2)) == NULL) 5487 return WERR_NOMEM; 5488 5489 result = construct_printer_driver_info_2(info, snum, servername, architecture, version); 5490 if (!W_ERROR_IS_OK(result)) 5491 goto out; 5492 5493 /* check the required size. */ 5494 *needed += spoolss_size_printer_driver_info_2(info); 5495 5496 if (*needed > offered) { 5497 result = WERR_INSUFFICIENT_BUFFER; 5498 goto out; 5499 } 5500 5501 if (!rpcbuf_alloc_size(buffer, *needed)) { 5502 result = WERR_NOMEM; 5503 goto out; 5504 } 5505 5506 /* fill the buffer with the structures */ 5507 smb_io_printer_driver_info_2("", buffer, info, 0); 5508 5509out: 5510 /* clear memory */ 5511 SAFE_FREE(info); 5512 5513 return result; 5514} 5515 5516/**************************************************************************** 5517****************************************************************************/ 5518 5519static WERROR getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 5520{ 5521 DRIVER_INFO_3 info; 5522 WERROR result; 5523 5524 ZERO_STRUCT(info); 5525 5526 result = construct_printer_driver_info_3(&info, snum, servername, architecture, version); 5527 if (!W_ERROR_IS_OK(result)) 5528 goto out; 5529 5530 /* check the required size. */ 5531 *needed += spoolss_size_printer_driver_info_3(&info); 5532 5533 if (*needed > offered) { 5534 result = WERR_INSUFFICIENT_BUFFER; 5535 goto out; 5536 } 5537 5538 if (!rpcbuf_alloc_size(buffer, *needed)) { 5539 result = WERR_NOMEM; 5540 goto out; 5541 } 5542 5543 /* fill the buffer with the structures */ 5544 smb_io_printer_driver_info_3("", buffer, &info, 0); 5545 5546out: 5547 free_printer_driver_info_3(&info); 5548 5549 return result; 5550} 5551 5552/**************************************************************************** 5553****************************************************************************/ 5554 5555static WERROR getprinterdriver2_level6(fstring servername, fstring architecture, uint32 version, int snum, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 5556{ 5557 DRIVER_INFO_6 info; 5558 WERROR result; 5559 5560 ZERO_STRUCT(info); 5561 5562 result = construct_printer_driver_info_6(&info, snum, servername, architecture, version); 5563 if (!W_ERROR_IS_OK(result)) 5564 goto out; 5565 5566 /* check the required size. */ 5567 *needed += spoolss_size_printer_driver_info_6(&info); 5568 5569 if (*needed > offered) { 5570 result = WERR_INSUFFICIENT_BUFFER; 5571 goto out; 5572 } 5573 5574 if (!rpcbuf_alloc_size(buffer, *needed)) { 5575 result = WERR_NOMEM; 5576 goto out; 5577 } 5578 5579 /* fill the buffer with the structures */ 5580 smb_io_printer_driver_info_6("", buffer, &info, 0); 5581 5582out: 5583 free_printer_driver_info_6(&info); 5584 5585 return result; 5586} 5587 5588/**************************************************************************** 5589****************************************************************************/ 5590 5591WERROR _spoolss_getprinterdriver2(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVER2 *q_u, SPOOL_R_GETPRINTERDRIVER2 *r_u) 5592{ 5593 POLICY_HND *handle = &q_u->handle; 5594 UNISTR2 *uni_arch = &q_u->architecture; 5595 uint32 level = q_u->level; 5596 uint32 clientmajorversion = q_u->clientmajorversion; 5597 RPC_BUFFER *buffer = NULL; 5598 uint32 offered = q_u->offered; 5599 uint32 *needed = &r_u->needed; 5600 uint32 *servermajorversion = &r_u->servermajorversion; 5601 uint32 *serverminorversion = &r_u->serverminorversion; 5602 Printer_entry *printer; 5603 5604 fstring servername; 5605 fstring architecture; 5606 int snum; 5607 5608 /* that's an [in out] buffer */ 5609 5610 if (!q_u->buffer && (offered!=0)) { 5611 return WERR_INVALID_PARAM; 5612 } 5613 5614 rpcbuf_move(q_u->buffer, &r_u->buffer); 5615 buffer = r_u->buffer; 5616 5617 DEBUG(4,("_spoolss_getprinterdriver2\n")); 5618 5619 if ( !(printer = find_printer_index_by_hnd( p, handle )) ) { 5620 DEBUG(0,("_spoolss_getprinterdriver2: invalid printer handle!\n")); 5621 return WERR_INVALID_PRINTER_NAME; 5622 } 5623 5624 *needed = 0; 5625 *servermajorversion = 0; 5626 *serverminorversion = 0; 5627 5628 fstrcpy(servername, get_server_name( printer )); 5629 unistr2_to_ascii(architecture, uni_arch, sizeof(architecture)-1); 5630 5631 if (!get_printer_snum(p, handle, &snum)) 5632 return WERR_BADFID; 5633 5634 switch (level) { 5635 case 1: 5636 return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed); 5637 case 2: 5638 return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed); 5639 case 3: 5640 return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed); 5641 case 6: 5642 return getprinterdriver2_level6(servername, architecture, clientmajorversion, snum, buffer, offered, needed); 5643#if 0 /* JERRY */ 5644 case 101: 5645 /* apparently this call is the equivalent of 5646 EnumPrinterDataEx() for the DsDriver key */ 5647 break; 5648#endif 5649 } 5650 5651 return WERR_UNKNOWN_LEVEL; 5652} 5653 5654/**************************************************************************** 5655****************************************************************************/ 5656 5657WERROR _spoolss_startpageprinter(pipes_struct *p, SPOOL_Q_STARTPAGEPRINTER *q_u, SPOOL_R_STARTPAGEPRINTER *r_u) 5658{ 5659 POLICY_HND *handle = &q_u->handle; 5660 5661 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 5662 5663 if (!Printer) { 5664 DEBUG(3,("Error in startpageprinter printer handle\n")); 5665 return WERR_BADFID; 5666 } 5667 5668 Printer->page_started=True; 5669 return WERR_OK; 5670} 5671 5672/**************************************************************************** 5673****************************************************************************/ 5674 5675WERROR _spoolss_endpageprinter(pipes_struct *p, SPOOL_Q_ENDPAGEPRINTER *q_u, SPOOL_R_ENDPAGEPRINTER *r_u) 5676{ 5677 POLICY_HND *handle = &q_u->handle; 5678 int snum; 5679 5680 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 5681 5682 if (!Printer) { 5683 DEBUG(2,("_spoolss_endpageprinter: Invalid handle (%s:%u:%u).\n",OUR_HANDLE(handle))); 5684 return WERR_BADFID; 5685 } 5686 5687 if (!get_printer_snum(p, handle, &snum)) 5688 return WERR_BADFID; 5689 5690 Printer->page_started=False; 5691 print_job_endpage(snum, Printer->jobid); 5692 5693 return WERR_OK; 5694} 5695 5696/******************************************************************** 5697 * api_spoolss_getprinter 5698 * called from the spoolss dispatcher 5699 * 5700 ********************************************************************/ 5701 5702WERROR _spoolss_startdocprinter(pipes_struct *p, SPOOL_Q_STARTDOCPRINTER *q_u, SPOOL_R_STARTDOCPRINTER *r_u) 5703{ 5704 POLICY_HND *handle = &q_u->handle; 5705 DOC_INFO *docinfo = &q_u->doc_info_container.docinfo; 5706 uint32 *jobid = &r_u->jobid; 5707 5708 DOC_INFO_1 *info_1 = &docinfo->doc_info_1; 5709 int snum; 5710 pstring jobname; 5711 fstring datatype; 5712 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 5713 struct current_user user; 5714 5715 if (!Printer) { 5716 DEBUG(2,("_spoolss_startdocprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); 5717 return WERR_BADFID; 5718 } 5719 5720 get_current_user(&user, p); 5721 5722 /* 5723 * a nice thing with NT is it doesn't listen to what you tell it. 5724 * when asked to send _only_ RAW datas, it tries to send datas 5725 * in EMF format. 5726 * 5727 * So I add checks like in NT Server ... 5728 */ 5729 5730 if (info_1->p_datatype != 0) { 5731 unistr2_to_ascii(datatype, &info_1->datatype, sizeof(datatype)); 5732 if (strcmp(datatype, "RAW") != 0) { 5733 (*jobid)=0; 5734 return WERR_INVALID_DATATYPE; 5735 } 5736 } 5737 5738 /* get the share number of the printer */ 5739 if (!get_printer_snum(p, handle, &snum)) { 5740 return WERR_BADFID; 5741 } 5742 5743 unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname)); 5744 5745 Printer->jobid = print_job_start(&user, snum, jobname, Printer->nt_devmode); 5746 5747 /* An error occured in print_job_start() so return an appropriate 5748 NT error code. */ 5749 5750 if (Printer->jobid == -1) { 5751 return map_werror_from_unix(errno); 5752 } 5753 5754 Printer->document_started=True; 5755 (*jobid) = Printer->jobid; 5756 5757 return WERR_OK; 5758} 5759 5760/******************************************************************** 5761 * api_spoolss_getprinter 5762 * called from the spoolss dispatcher 5763 * 5764 ********************************************************************/ 5765 5766WERROR _spoolss_enddocprinter(pipes_struct *p, SPOOL_Q_ENDDOCPRINTER *q_u, SPOOL_R_ENDDOCPRINTER *r_u) 5767{ 5768 POLICY_HND *handle = &q_u->handle; 5769 5770 return _spoolss_enddocprinter_internal(p, handle); 5771} 5772 5773/**************************************************************************** 5774****************************************************************************/ 5775 5776WERROR _spoolss_writeprinter(pipes_struct *p, SPOOL_Q_WRITEPRINTER *q_u, SPOOL_R_WRITEPRINTER *r_u) 5777{ 5778 POLICY_HND *handle = &q_u->handle; 5779 uint32 buffer_size = q_u->buffer_size; 5780 uint8 *buffer = q_u->buffer; 5781 uint32 *buffer_written = &q_u->buffer_size2; 5782 int snum; 5783 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 5784 5785 if (!Printer) { 5786 DEBUG(2,("_spoolss_writeprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle))); 5787 r_u->buffer_written = q_u->buffer_size2; 5788 return WERR_BADFID; 5789 } 5790 5791 if (!get_printer_snum(p, handle, &snum)) 5792 return WERR_BADFID; 5793 5794 (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer, 5795 (SMB_OFF_T)-1, (size_t)buffer_size); 5796 if (*buffer_written == (uint32)-1) { 5797 r_u->buffer_written = 0; 5798 if (errno == ENOSPC) 5799 return WERR_NO_SPOOL_SPACE; 5800 else 5801 return WERR_ACCESS_DENIED; 5802 } 5803 5804 r_u->buffer_written = q_u->buffer_size2; 5805 5806 return WERR_OK; 5807} 5808 5809/******************************************************************** 5810 * api_spoolss_getprinter 5811 * called from the spoolss dispatcher 5812 * 5813 ********************************************************************/ 5814 5815static WERROR control_printer(POLICY_HND *handle, uint32 command, 5816 pipes_struct *p) 5817{ 5818 struct current_user user; 5819 int snum; 5820 WERROR errcode = WERR_BADFUNC; 5821 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 5822 5823 get_current_user(&user, p); 5824 5825 if (!Printer) { 5826 DEBUG(2,("control_printer: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); 5827 return WERR_BADFID; 5828 } 5829 5830 if (!get_printer_snum(p, handle, &snum)) 5831 return WERR_BADFID; 5832 5833 switch (command) { 5834 case PRINTER_CONTROL_PAUSE: 5835 if (print_queue_pause(&user, snum, &errcode)) { 5836 errcode = WERR_OK; 5837 } 5838 break; 5839 case PRINTER_CONTROL_RESUME: 5840 case PRINTER_CONTROL_UNPAUSE: 5841 if (print_queue_resume(&user, snum, &errcode)) { 5842 errcode = WERR_OK; 5843 } 5844 break; 5845 case PRINTER_CONTROL_PURGE: 5846 if (print_queue_purge(&user, snum, &errcode)) { 5847 errcode = WERR_OK; 5848 } 5849 break; 5850 default: 5851 return WERR_UNKNOWN_LEVEL; 5852 } 5853 5854 return errcode; 5855} 5856 5857/******************************************************************** 5858 * api_spoolss_abortprinter 5859 * From MSDN: "Deletes printer's spool file if printer is configured 5860 * for spooling" 5861 ********************************************************************/ 5862 5863WERROR _spoolss_abortprinter(pipes_struct *p, SPOOL_Q_ABORTPRINTER *q_u, SPOOL_R_ABORTPRINTER *r_u) 5864{ 5865 POLICY_HND *handle = &q_u->handle; 5866 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 5867 int snum; 5868 struct current_user user; 5869 WERROR errcode = WERR_OK; 5870 5871 if (!Printer) { 5872 DEBUG(2,("_spoolss_abortprinter: Invalid handle (%s:%u:%u)\n",OUR_HANDLE(handle))); 5873 return WERR_BADFID; 5874 } 5875 5876 if (!get_printer_snum(p, handle, &snum)) 5877 return WERR_BADFID; 5878 5879 get_current_user( &user, p ); 5880 5881 print_job_delete( &user, snum, Printer->jobid, &errcode ); 5882 5883 return errcode; 5884} 5885 5886/******************************************************************** 5887 * called by spoolss_api_setprinter 5888 * when updating a printer description 5889 ********************************************************************/ 5890 5891static WERROR update_printer_sec(POLICY_HND *handle, uint32 level, 5892 const SPOOL_PRINTER_INFO_LEVEL *info, 5893 pipes_struct *p, SEC_DESC_BUF *secdesc_ctr) 5894{ 5895 SEC_DESC_BUF *new_secdesc_ctr = NULL, *old_secdesc_ctr = NULL; 5896 WERROR result; 5897 int snum; 5898 5899 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 5900 5901 if (!Printer || !get_printer_snum(p, handle, &snum)) { 5902 DEBUG(2,("update_printer_sec: Invalid handle (%s:%u:%u)\n", 5903 OUR_HANDLE(handle))); 5904 5905 result = WERR_BADFID; 5906 goto done; 5907 } 5908 5909 if (!secdesc_ctr) { 5910 DEBUG(10,("update_printer_sec: secdesc_ctr is NULL !\n")); 5911 result = WERR_INVALID_PARAM; 5912 goto done; 5913 } 5914 5915 /* Check the user has permissions to change the security 5916 descriptor. By experimentation with two NT machines, the user 5917 requires Full Access to the printer to change security 5918 information. */ 5919 5920 if ( Printer->access_granted != PRINTER_ACCESS_ADMINISTER ) { 5921 DEBUG(4,("update_printer_sec: updated denied by printer permissions\n")); 5922 result = WERR_ACCESS_DENIED; 5923 goto done; 5924 } 5925 5926 /* NT seems to like setting the security descriptor even though 5927 nothing may have actually changed. */ 5928 5929 nt_printing_getsec(p->mem_ctx, Printer->sharename, &old_secdesc_ctr); 5930 5931 if (DEBUGLEVEL >= 10) { 5932 SEC_ACL *the_acl; 5933 int i; 5934 5935 the_acl = old_secdesc_ctr->sec->dacl; 5936 DEBUG(10, ("old_secdesc_ctr for %s has %d aces:\n", 5937 PRINTERNAME(snum), the_acl->num_aces)); 5938 5939 for (i = 0; i < the_acl->num_aces; i++) { 5940 fstring sid_str; 5941 5942 sid_to_string(sid_str, &the_acl->aces[i].trustee); 5943 5944 DEBUG(10, ("%s 0x%08x\n", sid_str, 5945 the_acl->aces[i].access_mask)); 5946 } 5947 5948 the_acl = secdesc_ctr->sec->dacl; 5949 5950 if (the_acl) { 5951 DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", 5952 PRINTERNAME(snum), the_acl->num_aces)); 5953 5954 for (i = 0; i < the_acl->num_aces; i++) { 5955 fstring sid_str; 5956 5957 sid_to_string(sid_str, &the_acl->aces[i].trustee); 5958 5959 DEBUG(10, ("%s 0x%08x\n", sid_str, 5960 the_acl->aces[i].access_mask)); 5961 } 5962 } else { 5963 DEBUG(10, ("dacl for secdesc_ctr is NULL\n")); 5964 } 5965 } 5966 5967 new_secdesc_ctr = sec_desc_merge(p->mem_ctx, secdesc_ctr, old_secdesc_ctr); 5968 if (!new_secdesc_ctr) { 5969 result = WERR_NOMEM; 5970 goto done; 5971 } 5972 5973 if (sec_desc_equal(new_secdesc_ctr->sec, old_secdesc_ctr->sec)) { 5974 result = WERR_OK; 5975 goto done; 5976 } 5977 5978 result = nt_printing_setsec(Printer->sharename, new_secdesc_ctr); 5979 5980 done: 5981 5982 return result; 5983} 5984 5985/******************************************************************** 5986 Canonicalize printer info from a client 5987 5988 ATTN: It does not matter what we set the servername to hear 5989 since we do the necessary work in get_a_printer() to set it to 5990 the correct value based on what the client sent in the 5991 _spoolss_open_printer_ex(). 5992 ********************************************************************/ 5993 5994static BOOL check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) 5995{ 5996 fstring printername; 5997 const char *p; 5998 5999 DEBUG(5,("check_printer_ok: servername=%s printername=%s sharename=%s " 6000 "portname=%s drivername=%s comment=%s location=%s\n", 6001 info->servername, info->printername, info->sharename, 6002 info->portname, info->drivername, info->comment, info->location)); 6003 6004 /* we force some elements to "correct" values */ 6005 slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", global_myname()); 6006 fstrcpy(info->sharename, lp_servicename(snum)); 6007 6008 /* check to see if we allow printername != sharename */ 6009 6010 if ( lp_force_printername(snum) ) { 6011 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", 6012 global_myname(), info->sharename ); 6013 } else { 6014 6015 /* make sure printername is in \\server\printername format */ 6016 6017 fstrcpy( printername, info->printername ); 6018 p = printername; 6019 if ( printername[0] == '\\' && printername[1] == '\\' ) { 6020 if ( (p = strchr_m( &printername[2], '\\' )) != NULL ) 6021 p++; 6022 } 6023 6024 slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", 6025 global_myname(), p ); 6026 } 6027 6028 info->attributes |= PRINTER_ATTRIBUTE_SAMBA; 6029 info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA; 6030 6031 6032 6033 return True; 6034} 6035 6036/**************************************************************************** 6037****************************************************************************/ 6038 6039WERROR add_port_hook(NT_USER_TOKEN *token, const char *portname, const char *uri ) 6040{ 6041 char *cmd = lp_addport_cmd(); 6042 pstring command; 6043 int ret; 6044 int fd; 6045 SE_PRIV se_printop = SE_PRINT_OPERATOR; 6046 BOOL is_print_op = False; 6047 6048 if ( !*cmd ) { 6049 return WERR_ACCESS_DENIED; 6050 } 6051 6052 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\"", cmd, portname, uri ); 6053 6054 if ( token ) 6055 is_print_op = user_has_privileges( token, &se_printop ); 6056 6057 DEBUG(10,("Running [%s]\n", command)); 6058 6059 /********* BEGIN SePrintOperatorPrivilege **********/ 6060 6061 if ( is_print_op ) 6062 become_root(); 6063 6064 ret = smbrun(command, &fd); 6065 6066 if ( is_print_op ) 6067 unbecome_root(); 6068 6069 /********* END SePrintOperatorPrivilege **********/ 6070 6071 DEBUGADD(10,("returned [%d]\n", ret)); 6072 6073 if ( ret != 0 ) { 6074 if (fd != -1) 6075 close(fd); 6076 return WERR_ACCESS_DENIED; 6077 } 6078 6079 return WERR_OK; 6080} 6081 6082/**************************************************************************** 6083****************************************************************************/ 6084 6085BOOL add_printer_hook(NT_USER_TOKEN *token, NT_PRINTER_INFO_LEVEL *printer) 6086{ 6087 char *cmd = lp_addprinter_cmd(); 6088 char **qlines; 6089 pstring command; 6090 int numlines; 6091 int ret; 6092 int fd; 6093 fstring remote_machine = "%m"; 6094 SE_PRIV se_printop = SE_PRINT_OPERATOR; 6095 BOOL is_print_op = False; 6096 6097 standard_sub_basic(current_user_info.smb_name, 6098 current_user_info.domain, 6099 remote_machine,sizeof(remote_machine)); 6100 6101 slprintf(command, sizeof(command)-1, "%s \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"", 6102 cmd, printer->info_2->printername, printer->info_2->sharename, 6103 printer->info_2->portname, printer->info_2->drivername, 6104 printer->info_2->location, printer->info_2->comment, remote_machine); 6105 6106 if ( token ) 6107 is_print_op = user_has_privileges( token, &se_printop ); 6108 6109 DEBUG(10,("Running [%s]\n", command)); 6110 6111 /********* BEGIN SePrintOperatorPrivilege **********/ 6112 6113 if ( is_print_op ) 6114 become_root(); 6115 6116 if ( (ret = smbrun(command, &fd)) == 0 ) { 6117 /* Tell everyone we updated smb.conf. */ 6118 message_send_all(conn_tdb_ctx(), MSG_SMB_CONF_UPDATED, NULL, 0, False, NULL); 6119 } 6120 6121 if ( is_print_op ) 6122 unbecome_root(); 6123 6124 /********* END SePrintOperatorPrivilege **********/ 6125 6126 DEBUGADD(10,("returned [%d]\n", ret)); 6127 6128 if ( ret != 0 ) { 6129 if (fd != -1) 6130 close(fd); 6131 return False; 6132 } 6133 6134 /* reload our services immediately */ 6135 reload_services( False ); 6136 6137 numlines = 0; 6138 /* Get lines and convert them back to dos-codepage */ 6139 qlines = fd_lines_load(fd, &numlines, 0); 6140 DEBUGADD(10,("Lines returned = [%d]\n", numlines)); 6141 close(fd); 6142 6143 /* Set the portname to what the script says the portname should be. */ 6144 /* but don't require anything to be return from the script exit a good error code */ 6145 6146 if (numlines) { 6147 /* Set the portname to what the script says the portname should be. */ 6148 strncpy(printer->info_2->portname, qlines[0], sizeof(printer->info_2->portname)); 6149 DEBUGADD(6,("Line[0] = [%s]\n", qlines[0])); 6150 } 6151 6152 file_lines_free(qlines); 6153 return True; 6154} 6155 6156 6157/******************************************************************** 6158 * Called by spoolss_api_setprinter 6159 * when updating a printer description. 6160 ********************************************************************/ 6161 6162static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, 6163 const SPOOL_PRINTER_INFO_LEVEL *info, 6164 DEVICEMODE *devmode) 6165{ 6166 int snum; 6167 NT_PRINTER_INFO_LEVEL *printer = NULL, *old_printer = NULL; 6168 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 6169 WERROR result; 6170 UNISTR2 buffer; 6171 fstring asc_buffer; 6172 6173 DEBUG(8,("update_printer\n")); 6174 6175 result = WERR_OK; 6176 6177 if (!Printer) { 6178 result = WERR_BADFID; 6179 goto done; 6180 } 6181 6182 if (!get_printer_snum(p, handle, &snum)) { 6183 result = WERR_BADFID; 6184 goto done; 6185 } 6186 6187 if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) || 6188 (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) { 6189 result = WERR_BADFID; 6190 goto done; 6191 } 6192 6193 DEBUGADD(8,("Converting info_2 struct\n")); 6194 6195 /* 6196 * convert_printer_info converts the incoming 6197 * info from the client and overwrites the info 6198 * just read from the tdb in the pointer 'printer'. 6199 */ 6200 6201 if (!convert_printer_info(info, printer, level)) { 6202 result = WERR_NOMEM; 6203 goto done; 6204 } 6205 6206 if (devmode) { 6207 /* we have a valid devmode 6208 convert it and link it*/ 6209 6210 DEBUGADD(8,("update_printer: Converting the devicemode struct\n")); 6211 if (!convert_devicemode(printer->info_2->printername, devmode, 6212 &printer->info_2->devmode)) { 6213 result = WERR_NOMEM; 6214 goto done; 6215 } 6216 } 6217 6218 /* Do sanity check on the requested changes for Samba */ 6219 6220 if (!check_printer_ok(printer->info_2, snum)) { 6221 result = WERR_INVALID_PARAM; 6222 goto done; 6223 } 6224 6225 /* FIXME!!! If the driver has changed we really should verify that 6226 it is installed before doing much else --jerry */ 6227 6228 /* Check calling user has permission to update printer description */ 6229 6230 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { 6231 DEBUG(3, ("update_printer: printer property change denied by handle\n")); 6232 result = WERR_ACCESS_DENIED; 6233 goto done; 6234 } 6235 6236 /* Call addprinter hook */ 6237 /* Check changes to see if this is really needed */ 6238 6239 if ( *lp_addprinter_cmd() 6240 && (!strequal(printer->info_2->drivername, old_printer->info_2->drivername) 6241 || !strequal(printer->info_2->comment, old_printer->info_2->comment) 6242 || !strequal(printer->info_2->portname, old_printer->info_2->portname) 6243 || !strequal(printer->info_2->location, old_printer->info_2->location)) ) 6244 { 6245 /* add_printer_hook() will call reload_services() */ 6246 6247 if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) { 6248 result = WERR_ACCESS_DENIED; 6249 goto done; 6250 } 6251 } 6252 6253 /* 6254 * When a *new* driver is bound to a printer, the drivername is used to 6255 * lookup previously saved driver initialization info, which is then 6256 * bound to the printer, simulating what happens in the Windows arch. 6257 */ 6258 if (!strequal(printer->info_2->drivername, old_printer->info_2->drivername)) 6259 { 6260 if (!set_driver_init(printer, 2)) 6261 { 6262 DEBUG(5,("update_printer: Error restoring driver initialization data for driver [%s]!\n", 6263 printer->info_2->drivername)); 6264 } 6265 6266 DEBUG(10,("update_printer: changing driver [%s]! Sending event!\n", 6267 printer->info_2->drivername)); 6268 6269 notify_printer_driver(snum, printer->info_2->drivername); 6270 } 6271 6272 /* 6273 * flag which changes actually occured. This is a small subset of 6274 * all the possible changes. We also have to update things in the 6275 * DsSpooler key. 6276 */ 6277 6278 if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) { 6279 init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE); 6280 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description", 6281 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); 6282 6283 notify_printer_comment(snum, printer->info_2->comment); 6284 } 6285 6286 if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) { 6287 init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE); 6288 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName", 6289 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); 6290 6291 notify_printer_sharename(snum, printer->info_2->sharename); 6292 } 6293 6294 if (!strequal(printer->info_2->printername, old_printer->info_2->printername)) { 6295 char *pname; 6296 6297 if ( (pname = strchr_m( printer->info_2->printername+2, '\\' )) != NULL ) 6298 pname++; 6299 else 6300 pname = printer->info_2->printername; 6301 6302 6303 init_unistr2( &buffer, pname, UNI_STR_TERMINATE); 6304 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName", 6305 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); 6306 6307 notify_printer_printername( snum, pname ); 6308 } 6309 6310 if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) { 6311 init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE); 6312 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName", 6313 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); 6314 6315 notify_printer_port(snum, printer->info_2->portname); 6316 } 6317 6318 if (!strequal(printer->info_2->location, old_printer->info_2->location)) { 6319 init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE); 6320 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location", 6321 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); 6322 6323 notify_printer_location(snum, printer->info_2->location); 6324 } 6325 6326 /* here we need to update some more DsSpooler keys */ 6327 /* uNCName, serverName, shortServerName */ 6328 6329 init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE); 6330 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName", 6331 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); 6332 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName", 6333 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); 6334 6335 slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s", 6336 global_myname(), printer->info_2->sharename ); 6337 init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE); 6338 set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName", 6339 REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); 6340 6341 /* Update printer info */ 6342 result = mod_a_printer(printer, 2); 6343 6344done: 6345 free_a_printer(&printer, 2); 6346 free_a_printer(&old_printer, 2); 6347 6348 6349 return result; 6350} 6351 6352/**************************************************************************** 6353****************************************************************************/ 6354static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle, 6355 const SPOOL_PRINTER_INFO_LEVEL *info) 6356{ 6357#ifdef HAVE_ADS 6358 SPOOL_PRINTER_INFO_LEVEL_7 *info7 = info->info_7; 6359 int snum; 6360 Printer_entry *Printer; 6361 6362 if ( lp_security() != SEC_ADS ) { 6363 return WERR_UNKNOWN_LEVEL; 6364 } 6365 6366 Printer = find_printer_index_by_hnd(p, handle); 6367 6368 DEBUG(5,("publish_or_unpublish_printer, action = %d\n",info7->action)); 6369 6370 if (!Printer) 6371 return WERR_BADFID; 6372 6373 if (!get_printer_snum(p, handle, &snum)) 6374 return WERR_BADFID; 6375 6376 nt_printer_publish(Printer, snum, info7->action); 6377 6378 return WERR_OK; 6379#else 6380 return WERR_UNKNOWN_LEVEL; 6381#endif 6382} 6383/**************************************************************************** 6384****************************************************************************/ 6385 6386WERROR _spoolss_setprinter(pipes_struct *p, SPOOL_Q_SETPRINTER *q_u, SPOOL_R_SETPRINTER *r_u) 6387{ 6388 POLICY_HND *handle = &q_u->handle; 6389 uint32 level = q_u->level; 6390 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info; 6391 DEVMODE_CTR devmode_ctr = q_u->devmode_ctr; 6392 SEC_DESC_BUF *secdesc_ctr = q_u->secdesc_ctr; 6393 uint32 command = q_u->command; 6394 WERROR result; 6395 6396 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 6397 6398 if (!Printer) { 6399 DEBUG(2,("_spoolss_setprinter: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); 6400 return WERR_BADFID; 6401 } 6402 6403 /* check the level */ 6404 switch (level) { 6405 case 0: 6406 return control_printer(handle, command, p); 6407 case 2: 6408 result = update_printer(p, handle, level, info, devmode_ctr.devmode); 6409 if (!W_ERROR_IS_OK(result)) 6410 return result; 6411 if (secdesc_ctr) 6412 result = update_printer_sec(handle, level, info, p, secdesc_ctr); 6413 return result; 6414 case 3: 6415 return update_printer_sec(handle, level, info, p, 6416 secdesc_ctr); 6417 case 7: 6418 return publish_or_unpublish_printer(p, handle, info); 6419 default: 6420 return WERR_UNKNOWN_LEVEL; 6421 } 6422} 6423 6424/**************************************************************************** 6425****************************************************************************/ 6426 6427WERROR _spoolss_fcpn(pipes_struct *p, SPOOL_Q_FCPN *q_u, SPOOL_R_FCPN *r_u) 6428{ 6429 POLICY_HND *handle = &q_u->handle; 6430 Printer_entry *Printer= find_printer_index_by_hnd(p, handle); 6431 6432 if (!Printer) { 6433 DEBUG(2,("_spoolss_fcpn: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(handle))); 6434 return WERR_BADFID; 6435 } 6436 6437 if (Printer->notify.client_connected==True) { 6438 int snum = -1; 6439 6440 if ( Printer->printer_type == SPLHND_SERVER) 6441 snum = -1; 6442 else if ( (Printer->printer_type == SPLHND_PRINTER) && 6443 !get_printer_snum(p, handle, &snum) ) 6444 return WERR_BADFID; 6445 6446 srv_spoolss_replycloseprinter(snum, &Printer->notify.client_hnd); 6447 } 6448 6449 Printer->notify.flags=0; 6450 Printer->notify.options=0; 6451 Printer->notify.localmachine[0]='\0'; 6452 Printer->notify.printerlocal=0; 6453 if (Printer->notify.option) 6454 free_spool_notify_option(&Printer->notify.option); 6455 Printer->notify.client_connected=False; 6456 6457 return WERR_OK; 6458} 6459 6460/**************************************************************************** 6461****************************************************************************/ 6462 6463WERROR _spoolss_addjob(pipes_struct *p, SPOOL_Q_ADDJOB *q_u, SPOOL_R_ADDJOB *r_u) 6464{ 6465 /* that's an [in out] buffer */ 6466 6467 if (!q_u->buffer && (q_u->offered!=0)) { 6468 return WERR_INVALID_PARAM; 6469 } 6470 6471 rpcbuf_move(q_u->buffer, &r_u->buffer); 6472 6473 r_u->needed = 0; 6474 return WERR_INVALID_PARAM; /* this is what a NT server 6475 returns for AddJob. AddJob 6476 must fail on non-local 6477 printers */ 6478} 6479 6480/**************************************************************************** 6481****************************************************************************/ 6482 6483static void fill_job_info_1(JOB_INFO_1 *job_info, const print_queue_struct *queue, 6484 int position, int snum, 6485 const NT_PRINTER_INFO_LEVEL *ntprinter) 6486{ 6487 struct tm *t; 6488 6489 t=gmtime(&queue->time); 6490 6491 job_info->jobid=queue->job; 6492 init_unistr(&job_info->printername, lp_servicename(snum)); 6493 init_unistr(&job_info->machinename, ntprinter->info_2->servername); 6494 init_unistr(&job_info->username, queue->fs_user); 6495 init_unistr(&job_info->document, queue->fs_file); 6496 init_unistr(&job_info->datatype, "RAW"); 6497 init_unistr(&job_info->text_status, ""); 6498 job_info->status=nt_printj_status(queue->status); 6499 job_info->priority=queue->priority; 6500 job_info->position=position; 6501 job_info->totalpages=queue->page_count; 6502 job_info->pagesprinted=0; 6503 6504 make_systemtime(&job_info->submitted, t); 6505} 6506 6507/**************************************************************************** 6508****************************************************************************/ 6509 6510static BOOL fill_job_info_2(JOB_INFO_2 *job_info, const print_queue_struct *queue, 6511 int position, int snum, 6512 const NT_PRINTER_INFO_LEVEL *ntprinter, 6513 DEVICEMODE *devmode) 6514{ 6515 struct tm *t; 6516 6517 t=gmtime(&queue->time); 6518 6519 job_info->jobid=queue->job; 6520 6521 init_unistr(&job_info->printername, ntprinter->info_2->printername); 6522 6523 init_unistr(&job_info->machinename, ntprinter->info_2->servername); 6524 init_unistr(&job_info->username, queue->fs_user); 6525 init_unistr(&job_info->document, queue->fs_file); 6526 init_unistr(&job_info->notifyname, queue->fs_user); 6527 init_unistr(&job_info->datatype, "RAW"); 6528 init_unistr(&job_info->printprocessor, "winprint"); 6529 init_unistr(&job_info->parameters, ""); 6530 init_unistr(&job_info->drivername, ntprinter->info_2->drivername); 6531 init_unistr(&job_info->text_status, ""); 6532 6533/* and here the security descriptor */ 6534 6535 job_info->status=nt_printj_status(queue->status); 6536 job_info->priority=queue->priority; 6537 job_info->position=position; 6538 job_info->starttime=0; 6539 job_info->untiltime=0; 6540 job_info->totalpages=queue->page_count; 6541 job_info->size=queue->size; 6542 make_systemtime(&(job_info->submitted), t); 6543 job_info->timeelapsed=0; 6544 job_info->pagesprinted=0; 6545 6546 job_info->devmode = devmode; 6547 6548 return (True); 6549} 6550 6551/**************************************************************************** 6552 Enumjobs at level 1. 6553****************************************************************************/ 6554 6555static WERROR enumjobs_level1(const print_queue_struct *queue, int snum, 6556 const NT_PRINTER_INFO_LEVEL *ntprinter, 6557 RPC_BUFFER *buffer, uint32 offered, 6558 uint32 *needed, uint32 *returned) 6559{ 6560 JOB_INFO_1 *info; 6561 int i; 6562 WERROR result = WERR_OK; 6563 6564 info=SMB_MALLOC_ARRAY(JOB_INFO_1,*returned); 6565 if (info==NULL) { 6566 *returned=0; 6567 return WERR_NOMEM; 6568 } 6569 6570 for (i=0; i<*returned; i++) 6571 fill_job_info_1( &info[i], &queue[i], i, snum, ntprinter ); 6572 6573 /* check the required size. */ 6574 for (i=0; i<*returned; i++) 6575 (*needed) += spoolss_size_job_info_1(&info[i]); 6576 6577 if (*needed > offered) { 6578 result = WERR_INSUFFICIENT_BUFFER; 6579 goto out; 6580 } 6581 6582 if (!rpcbuf_alloc_size(buffer, *needed)) { 6583 result = WERR_NOMEM; 6584 goto out; 6585 } 6586 6587 /* fill the buffer with the structures */ 6588 for (i=0; i<*returned; i++) 6589 smb_io_job_info_1("", buffer, &info[i], 0); 6590 6591out: 6592 /* clear memory */ 6593 SAFE_FREE(info); 6594 6595 if ( !W_ERROR_IS_OK(result) ) 6596 *returned = 0; 6597 6598 return result; 6599} 6600 6601/**************************************************************************** 6602 Enumjobs at level 2. 6603****************************************************************************/ 6604 6605static WERROR enumjobs_level2(const print_queue_struct *queue, int snum, 6606 const NT_PRINTER_INFO_LEVEL *ntprinter, 6607 RPC_BUFFER *buffer, uint32 offered, 6608 uint32 *needed, uint32 *returned) 6609{ 6610 JOB_INFO_2 *info = NULL; 6611 int i; 6612 WERROR result = WERR_OK; 6613 DEVICEMODE *devmode = NULL; 6614 6615 if ( !(info = SMB_MALLOC_ARRAY(JOB_INFO_2,*returned)) ) { 6616 *returned=0; 6617 return WERR_NOMEM; 6618 } 6619 6620 /* this should not be a failure condition if the devmode is NULL */ 6621 6622 devmode = construct_dev_mode(lp_const_servicename(snum)); 6623 6624 for (i=0; i<*returned; i++) 6625 fill_job_info_2(&(info[i]), &queue[i], i, snum, ntprinter, devmode); 6626 6627 /* check the required size. */ 6628 for (i=0; i<*returned; i++) 6629 (*needed) += spoolss_size_job_info_2(&info[i]); 6630 6631 if (*needed > offered) { 6632 result = WERR_INSUFFICIENT_BUFFER; 6633 goto out; 6634 } 6635 6636 if (!rpcbuf_alloc_size(buffer, *needed)) { 6637 result = WERR_NOMEM; 6638 goto out; 6639 } 6640 6641 /* fill the buffer with the structures */ 6642 for (i=0; i<*returned; i++) 6643 smb_io_job_info_2("", buffer, &info[i], 0); 6644 6645out: 6646 free_devmode(devmode); 6647 SAFE_FREE(info); 6648 6649 if ( !W_ERROR_IS_OK(result) ) 6650 *returned = 0; 6651 6652 return result; 6653 6654} 6655 6656/**************************************************************************** 6657 Enumjobs. 6658****************************************************************************/ 6659 6660WERROR _spoolss_enumjobs( pipes_struct *p, SPOOL_Q_ENUMJOBS *q_u, SPOOL_R_ENUMJOBS *r_u) 6661{ 6662 POLICY_HND *handle = &q_u->handle; 6663 uint32 level = q_u->level; 6664 RPC_BUFFER *buffer = NULL; 6665 uint32 offered = q_u->offered; 6666 uint32 *needed = &r_u->needed; 6667 uint32 *returned = &r_u->returned; 6668 WERROR wret; 6669 NT_PRINTER_INFO_LEVEL *ntprinter = NULL; 6670 int snum; 6671 print_status_struct prt_status; 6672 print_queue_struct *queue=NULL; 6673 6674 /* that's an [in out] buffer */ 6675 6676 if (!q_u->buffer && (offered!=0)) { 6677 return WERR_INVALID_PARAM; 6678 } 6679 6680 rpcbuf_move(q_u->buffer, &r_u->buffer); 6681 buffer = r_u->buffer; 6682 6683 DEBUG(4,("_spoolss_enumjobs\n")); 6684 6685 *needed=0; 6686 *returned=0; 6687 6688 /* lookup the printer snum and tdb entry */ 6689 6690 if (!get_printer_snum(p, handle, &snum)) 6691 return WERR_BADFID; 6692 6693 wret = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); 6694 if ( !W_ERROR_IS_OK(wret) ) 6695 return wret; 6696 6697 *returned = print_queue_status(snum, &queue, &prt_status); 6698 DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message)); 6699 6700 if (*returned == 0) { 6701 SAFE_FREE(queue); 6702 free_a_printer(&ntprinter, 2); 6703 return WERR_OK; 6704 } 6705 6706 switch (level) { 6707 case 1: 6708 wret = enumjobs_level1(queue, snum, ntprinter, buffer, offered, needed, returned); 6709 break; 6710 case 2: 6711 wret = enumjobs_level2(queue, snum, ntprinter, buffer, offered, needed, returned); 6712 break; 6713 default: 6714 *returned=0; 6715 wret = WERR_UNKNOWN_LEVEL; 6716 break; 6717 } 6718 6719 SAFE_FREE(queue); 6720 free_a_printer( &ntprinter, 2 ); 6721 return wret; 6722} 6723 6724/**************************************************************************** 6725****************************************************************************/ 6726 6727WERROR _spoolss_schedulejob( pipes_struct *p, SPOOL_Q_SCHEDULEJOB *q_u, SPOOL_R_SCHEDULEJOB *r_u) 6728{ 6729 return WERR_OK; 6730} 6731 6732/**************************************************************************** 6733****************************************************************************/ 6734 6735WERROR _spoolss_setjob(pipes_struct *p, SPOOL_Q_SETJOB *q_u, SPOOL_R_SETJOB *r_u) 6736{ 6737 POLICY_HND *handle = &q_u->handle; 6738 uint32 jobid = q_u->jobid; 6739 uint32 command = q_u->command; 6740 6741 struct current_user user; 6742 int snum; 6743 WERROR errcode = WERR_BADFUNC; 6744 6745 if (!get_printer_snum(p, handle, &snum)) { 6746 return WERR_BADFID; 6747 } 6748 6749 if (!print_job_exists(lp_const_servicename(snum), jobid)) { 6750 return WERR_INVALID_PRINTER_NAME; 6751 } 6752 6753 get_current_user(&user, p); 6754 6755 switch (command) { 6756 case JOB_CONTROL_CANCEL: 6757 case JOB_CONTROL_DELETE: 6758 if (print_job_delete(&user, snum, jobid, &errcode)) { 6759 errcode = WERR_OK; 6760 } 6761 break; 6762 case JOB_CONTROL_PAUSE: 6763 if (print_job_pause(&user, snum, jobid, &errcode)) { 6764 errcode = WERR_OK; 6765 } 6766 break; 6767 case JOB_CONTROL_RESTART: 6768 case JOB_CONTROL_RESUME: 6769 if (print_job_resume(&user, snum, jobid, &errcode)) { 6770 errcode = WERR_OK; 6771 } 6772 break; 6773 default: 6774 return WERR_UNKNOWN_LEVEL; 6775 } 6776 6777 return errcode; 6778} 6779 6780/**************************************************************************** 6781 Enumerates all printer drivers at level 1. 6782****************************************************************************/ 6783 6784static WERROR enumprinterdrivers_level1(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 6785{ 6786 int i; 6787 int ndrivers; 6788 uint32 version; 6789 fstring *list = NULL; 6790 NT_PRINTER_DRIVER_INFO_LEVEL driver; 6791 DRIVER_INFO_1 *driver_info_1=NULL; 6792 WERROR result = WERR_OK; 6793 6794 *returned=0; 6795 6796 for (version=0; version<DRIVER_MAX_VERSION; version++) { 6797 list=NULL; 6798 ndrivers=get_ntdrivers(&list, architecture, version); 6799 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); 6800 6801 if(ndrivers == -1) { 6802 SAFE_FREE(driver_info_1); 6803 return WERR_NOMEM; 6804 } 6805 6806 if(ndrivers != 0) { 6807 if((driver_info_1=SMB_REALLOC_ARRAY(driver_info_1, DRIVER_INFO_1, *returned+ndrivers )) == NULL) { 6808 DEBUG(0,("enumprinterdrivers_level1: failed to enlarge driver info buffer!\n")); 6809 SAFE_FREE(list); 6810 return WERR_NOMEM; 6811 } 6812 } 6813 6814 for (i=0; i<ndrivers; i++) { 6815 WERROR status; 6816 DEBUGADD(5,("\tdriver: [%s]\n", list[i])); 6817 ZERO_STRUCT(driver); 6818 status = get_a_printer_driver(&driver, 3, list[i], 6819 architecture, version); 6820 if (!W_ERROR_IS_OK(status)) { 6821 SAFE_FREE(list); 6822 SAFE_FREE(driver_info_1); 6823 return status; 6824 } 6825 fill_printer_driver_info_1(&driver_info_1[*returned+i], driver, servername, architecture ); 6826 free_a_printer_driver(driver, 3); 6827 } 6828 6829 *returned+=ndrivers; 6830 SAFE_FREE(list); 6831 } 6832 6833 /* check the required size. */ 6834 for (i=0; i<*returned; i++) { 6835 DEBUGADD(6,("adding driver [%d]'s size\n",i)); 6836 *needed += spoolss_size_printer_driver_info_1(&driver_info_1[i]); 6837 } 6838 6839 if (*needed > offered) { 6840 result = WERR_INSUFFICIENT_BUFFER; 6841 goto out; 6842 } 6843 6844 if (!rpcbuf_alloc_size(buffer, *needed)) { 6845 result = WERR_NOMEM; 6846 goto out; 6847 } 6848 6849 /* fill the buffer with the driver structures */ 6850 for (i=0; i<*returned; i++) { 6851 DEBUGADD(6,("adding driver [%d] to buffer\n",i)); 6852 smb_io_printer_driver_info_1("", buffer, &driver_info_1[i], 0); 6853 } 6854 6855out: 6856 SAFE_FREE(driver_info_1); 6857 6858 if ( !W_ERROR_IS_OK(result) ) 6859 *returned = 0; 6860 6861 return result; 6862} 6863 6864/**************************************************************************** 6865 Enumerates all printer drivers at level 2. 6866****************************************************************************/ 6867 6868static WERROR enumprinterdrivers_level2(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 6869{ 6870 int i; 6871 int ndrivers; 6872 uint32 version; 6873 fstring *list = NULL; 6874 NT_PRINTER_DRIVER_INFO_LEVEL driver; 6875 DRIVER_INFO_2 *driver_info_2=NULL; 6876 WERROR result = WERR_OK; 6877 6878 *returned=0; 6879 6880 for (version=0; version<DRIVER_MAX_VERSION; version++) { 6881 list=NULL; 6882 ndrivers=get_ntdrivers(&list, architecture, version); 6883 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); 6884 6885 if(ndrivers == -1) { 6886 SAFE_FREE(driver_info_2); 6887 return WERR_NOMEM; 6888 } 6889 6890 if(ndrivers != 0) { 6891 if((driver_info_2=SMB_REALLOC_ARRAY(driver_info_2, DRIVER_INFO_2, *returned+ndrivers )) == NULL) { 6892 DEBUG(0,("enumprinterdrivers_level2: failed to enlarge driver info buffer!\n")); 6893 SAFE_FREE(list); 6894 return WERR_NOMEM; 6895 } 6896 } 6897 6898 for (i=0; i<ndrivers; i++) { 6899 WERROR status; 6900 6901 DEBUGADD(5,("\tdriver: [%s]\n", list[i])); 6902 ZERO_STRUCT(driver); 6903 status = get_a_printer_driver(&driver, 3, list[i], 6904 architecture, version); 6905 if (!W_ERROR_IS_OK(status)) { 6906 SAFE_FREE(list); 6907 SAFE_FREE(driver_info_2); 6908 return status; 6909 } 6910 fill_printer_driver_info_2(&driver_info_2[*returned+i], driver, servername); 6911 free_a_printer_driver(driver, 3); 6912 } 6913 6914 *returned+=ndrivers; 6915 SAFE_FREE(list); 6916 } 6917 6918 /* check the required size. */ 6919 for (i=0; i<*returned; i++) { 6920 DEBUGADD(6,("adding driver [%d]'s size\n",i)); 6921 *needed += spoolss_size_printer_driver_info_2(&(driver_info_2[i])); 6922 } 6923 6924 if (*needed > offered) { 6925 result = WERR_INSUFFICIENT_BUFFER; 6926 goto out; 6927 } 6928 6929 if (!rpcbuf_alloc_size(buffer, *needed)) { 6930 result = WERR_NOMEM; 6931 goto out; 6932 } 6933 6934 /* fill the buffer with the form structures */ 6935 for (i=0; i<*returned; i++) { 6936 DEBUGADD(6,("adding driver [%d] to buffer\n",i)); 6937 smb_io_printer_driver_info_2("", buffer, &(driver_info_2[i]), 0); 6938 } 6939 6940out: 6941 SAFE_FREE(driver_info_2); 6942 6943 if ( !W_ERROR_IS_OK(result) ) 6944 *returned = 0; 6945 6946 return result; 6947} 6948 6949/**************************************************************************** 6950 Enumerates all printer drivers at level 3. 6951****************************************************************************/ 6952 6953static WERROR enumprinterdrivers_level3(fstring servername, fstring architecture, RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 6954{ 6955 int i; 6956 int ndrivers; 6957 uint32 version; 6958 fstring *list = NULL; 6959 DRIVER_INFO_3 *driver_info_3=NULL; 6960 NT_PRINTER_DRIVER_INFO_LEVEL driver; 6961 WERROR result = WERR_OK; 6962 6963 *returned=0; 6964 6965 for (version=0; version<DRIVER_MAX_VERSION; version++) { 6966 list=NULL; 6967 ndrivers=get_ntdrivers(&list, architecture, version); 6968 DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version)); 6969 6970 if(ndrivers == -1) { 6971 SAFE_FREE(driver_info_3); 6972 return WERR_NOMEM; 6973 } 6974 6975 if(ndrivers != 0) { 6976 if((driver_info_3=SMB_REALLOC_ARRAY(driver_info_3, DRIVER_INFO_3, *returned+ndrivers )) == NULL) { 6977 DEBUG(0,("enumprinterdrivers_level3: failed to enlarge driver info buffer!\n")); 6978 SAFE_FREE(list); 6979 return WERR_NOMEM; 6980 } 6981 } 6982 6983 for (i=0; i<ndrivers; i++) { 6984 WERROR status; 6985 6986 DEBUGADD(5,("\tdriver: [%s]\n", list[i])); 6987 ZERO_STRUCT(driver); 6988 status = get_a_printer_driver(&driver, 3, list[i], 6989 architecture, version); 6990 if (!W_ERROR_IS_OK(status)) { 6991 SAFE_FREE(list); 6992 SAFE_FREE(driver_info_3); 6993 return status; 6994 } 6995 fill_printer_driver_info_3(&driver_info_3[*returned+i], driver, servername); 6996 free_a_printer_driver(driver, 3); 6997 } 6998 6999 *returned+=ndrivers; 7000 SAFE_FREE(list); 7001 } 7002 7003 /* check the required size. */ 7004 for (i=0; i<*returned; i++) { 7005 DEBUGADD(6,("adding driver [%d]'s size\n",i)); 7006 *needed += spoolss_size_printer_driver_info_3(&driver_info_3[i]); 7007 } 7008 7009 if (*needed > offered) { 7010 result = WERR_INSUFFICIENT_BUFFER; 7011 goto out; 7012 } 7013 7014 if (!rpcbuf_alloc_size(buffer, *needed)) { 7015 result = WERR_NOMEM; 7016 goto out; 7017 } 7018 7019 /* fill the buffer with the driver structures */ 7020 for (i=0; i<*returned; i++) { 7021 DEBUGADD(6,("adding driver [%d] to buffer\n",i)); 7022 smb_io_printer_driver_info_3("", buffer, &driver_info_3[i], 0); 7023 } 7024 7025out: 7026 for (i=0; i<*returned; i++) { 7027 SAFE_FREE(driver_info_3[i].dependentfiles); 7028 } 7029 7030 SAFE_FREE(driver_info_3); 7031 7032 if ( !W_ERROR_IS_OK(result) ) 7033 *returned = 0; 7034 7035 return result; 7036} 7037 7038/**************************************************************************** 7039 Enumerates all printer drivers. 7040****************************************************************************/ 7041 7042WERROR _spoolss_enumprinterdrivers( pipes_struct *p, SPOOL_Q_ENUMPRINTERDRIVERS *q_u, SPOOL_R_ENUMPRINTERDRIVERS *r_u) 7043{ 7044 uint32 level = q_u->level; 7045 RPC_BUFFER *buffer = NULL; 7046 uint32 offered = q_u->offered; 7047 uint32 *needed = &r_u->needed; 7048 uint32 *returned = &r_u->returned; 7049 7050 fstring servername; 7051 fstring architecture; 7052 7053 /* that's an [in out] buffer */ 7054 7055 if (!q_u->buffer && (offered!=0)) { 7056 return WERR_INVALID_PARAM; 7057 } 7058 7059 rpcbuf_move(q_u->buffer, &r_u->buffer); 7060 buffer = r_u->buffer; 7061 7062 DEBUG(4,("_spoolss_enumprinterdrivers\n")); 7063 7064 *needed = 0; 7065 *returned = 0; 7066 7067 unistr2_to_ascii(architecture, &q_u->environment, sizeof(architecture)-1); 7068 unistr2_to_ascii(servername, &q_u->name, sizeof(servername)-1); 7069 7070 if ( !is_myname_or_ipaddr( servername ) ) 7071 return WERR_UNKNOWN_PRINTER_DRIVER; 7072 7073 switch (level) { 7074 case 1: 7075 return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned); 7076 case 2: 7077 return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned); 7078 case 3: 7079 return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned); 7080 default: 7081 return WERR_UNKNOWN_LEVEL; 7082 } 7083} 7084 7085/**************************************************************************** 7086****************************************************************************/ 7087 7088static void fill_form_1(FORM_1 *form, nt_forms_struct *list) 7089{ 7090 form->flag=list->flag; 7091 init_unistr(&form->name, list->name); 7092 form->width=list->width; 7093 form->length=list->length; 7094 form->left=list->left; 7095 form->top=list->top; 7096 form->right=list->right; 7097 form->bottom=list->bottom; 7098} 7099 7100/**************************************************************************** 7101****************************************************************************/ 7102 7103WERROR _spoolss_enumforms(pipes_struct *p, SPOOL_Q_ENUMFORMS *q_u, SPOOL_R_ENUMFORMS *r_u) 7104{ 7105 uint32 level = q_u->level; 7106 RPC_BUFFER *buffer = NULL; 7107 uint32 offered = q_u->offered; 7108 uint32 *needed = &r_u->needed; 7109 uint32 *numofforms = &r_u->numofforms; 7110 uint32 numbuiltinforms; 7111 7112 nt_forms_struct *list=NULL; 7113 nt_forms_struct *builtinlist=NULL; 7114 FORM_1 *forms_1; 7115 int buffer_size=0; 7116 int i; 7117 7118 /* that's an [in out] buffer */ 7119 7120 if (!q_u->buffer && (offered!=0) ) { 7121 return WERR_INVALID_PARAM; 7122 } 7123 7124 rpcbuf_move(q_u->buffer, &r_u->buffer); 7125 buffer = r_u->buffer; 7126 7127 DEBUG(4,("_spoolss_enumforms\n")); 7128 DEBUGADD(5,("Offered buffer size [%d]\n", offered)); 7129 DEBUGADD(5,("Info level [%d]\n", level)); 7130 7131 numbuiltinforms = get_builtin_ntforms(&builtinlist); 7132 DEBUGADD(5,("Number of builtin forms [%d]\n", numbuiltinforms)); 7133 *numofforms = get_ntforms(&list); 7134 DEBUGADD(5,("Number of user forms [%d]\n", *numofforms)); 7135 *numofforms += numbuiltinforms; 7136 7137 if (*numofforms == 0) { 7138 SAFE_FREE(builtinlist); 7139 SAFE_FREE(list); 7140 return WERR_NO_MORE_ITEMS; 7141 } 7142 7143 switch (level) { 7144 case 1: 7145 if ((forms_1=SMB_MALLOC_ARRAY(FORM_1, *numofforms)) == NULL) { 7146 SAFE_FREE(builtinlist); 7147 SAFE_FREE(list); 7148 *numofforms=0; 7149 return WERR_NOMEM; 7150 } 7151 7152 /* construct the list of form structures */ 7153 for (i=0; i<numbuiltinforms; i++) { 7154 DEBUGADD(6,("Filling form number [%d]\n",i)); 7155 fill_form_1(&forms_1[i], &builtinlist[i]); 7156 } 7157 7158 SAFE_FREE(builtinlist); 7159 7160 for (; i<*numofforms; i++) { 7161 DEBUGADD(6,("Filling form number [%d]\n",i)); 7162 fill_form_1(&forms_1[i], &list[i-numbuiltinforms]); 7163 } 7164 7165 SAFE_FREE(list); 7166 7167 /* check the required size. */ 7168 for (i=0; i<numbuiltinforms; i++) { 7169 DEBUGADD(6,("adding form [%d]'s size\n",i)); 7170 buffer_size += spoolss_size_form_1(&forms_1[i]); 7171 } 7172 for (; i<*numofforms; i++) { 7173 DEBUGADD(6,("adding form [%d]'s size\n",i)); 7174 buffer_size += spoolss_size_form_1(&forms_1[i]); 7175 } 7176 7177 *needed=buffer_size; 7178 7179 if (*needed > offered) { 7180 SAFE_FREE(forms_1); 7181 *numofforms=0; 7182 return WERR_INSUFFICIENT_BUFFER; 7183 } 7184 7185 if (!rpcbuf_alloc_size(buffer, buffer_size)){ 7186 SAFE_FREE(forms_1); 7187 *numofforms=0; 7188 return WERR_NOMEM; 7189 } 7190 7191 /* fill the buffer with the form structures */ 7192 for (i=0; i<numbuiltinforms; i++) { 7193 DEBUGADD(6,("adding form [%d] to buffer\n",i)); 7194 smb_io_form_1("", buffer, &forms_1[i], 0); 7195 } 7196 for (; i<*numofforms; i++) { 7197 DEBUGADD(6,("adding form [%d] to buffer\n",i)); 7198 smb_io_form_1("", buffer, &forms_1[i], 0); 7199 } 7200 7201 SAFE_FREE(forms_1); 7202 7203 return WERR_OK; 7204 7205 default: 7206 SAFE_FREE(list); 7207 SAFE_FREE(builtinlist); 7208 return WERR_UNKNOWN_LEVEL; 7209 } 7210} 7211 7212/**************************************************************************** 7213****************************************************************************/ 7214 7215WERROR _spoolss_getform(pipes_struct *p, SPOOL_Q_GETFORM *q_u, SPOOL_R_GETFORM *r_u) 7216{ 7217 uint32 level = q_u->level; 7218 UNISTR2 *uni_formname = &q_u->formname; 7219 RPC_BUFFER *buffer = NULL; 7220 uint32 offered = q_u->offered; 7221 uint32 *needed = &r_u->needed; 7222 7223 nt_forms_struct *list=NULL; 7224 nt_forms_struct builtin_form; 7225 BOOL foundBuiltin; 7226 FORM_1 form_1; 7227 fstring form_name; 7228 int buffer_size=0; 7229 int numofforms=0, i=0; 7230 7231 /* that's an [in out] buffer */ 7232 7233 if (!q_u->buffer && (offered!=0)) { 7234 return WERR_INVALID_PARAM; 7235 } 7236 7237 rpcbuf_move(q_u->buffer, &r_u->buffer); 7238 buffer = r_u->buffer; 7239 7240 unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1); 7241 7242 DEBUG(4,("_spoolss_getform\n")); 7243 DEBUGADD(5,("Offered buffer size [%d]\n", offered)); 7244 DEBUGADD(5,("Info level [%d]\n", level)); 7245 7246 foundBuiltin = get_a_builtin_ntform(uni_formname,&builtin_form); 7247 if (!foundBuiltin) { 7248 numofforms = get_ntforms(&list); 7249 DEBUGADD(5,("Number of forms [%d]\n", numofforms)); 7250 7251 if (numofforms == 0) 7252 return WERR_BADFID; 7253 } 7254 7255 switch (level) { 7256 case 1: 7257 if (foundBuiltin) { 7258 fill_form_1(&form_1, &builtin_form); 7259 } else { 7260 7261 /* Check if the requested name is in the list of form structures */ 7262 for (i=0; i<numofforms; i++) { 7263 7264 DEBUG(4,("_spoolss_getform: checking form %s (want %s)\n", list[i].name, form_name)); 7265 7266 if (strequal(form_name, list[i].name)) { 7267 DEBUGADD(6,("Found form %s number [%d]\n", form_name, i)); 7268 fill_form_1(&form_1, &list[i]); 7269 break; 7270 } 7271 } 7272 7273 SAFE_FREE(list); 7274 if (i == numofforms) { 7275 return WERR_BADFID; 7276 } 7277 } 7278 /* check the required size. */ 7279 7280 *needed=spoolss_size_form_1(&form_1); 7281 7282 if (*needed > offered) 7283 return WERR_INSUFFICIENT_BUFFER; 7284 7285 if (!rpcbuf_alloc_size(buffer, buffer_size)) 7286 return WERR_NOMEM; 7287 7288 /* fill the buffer with the form structures */ 7289 DEBUGADD(6,("adding form %s [%d] to buffer\n", form_name, i)); 7290 smb_io_form_1("", buffer, &form_1, 0); 7291 7292 return WERR_OK; 7293 7294 default: 7295 SAFE_FREE(list); 7296 return WERR_UNKNOWN_LEVEL; 7297 } 7298} 7299 7300/**************************************************************************** 7301****************************************************************************/ 7302 7303static void fill_port_1(PORT_INFO_1 *port, const char *name) 7304{ 7305 init_unistr(&port->port_name, name); 7306} 7307 7308/**************************************************************************** 7309 TODO: This probably needs distinguish between TCP/IP and Local ports 7310 somehow. 7311****************************************************************************/ 7312 7313static void fill_port_2(PORT_INFO_2 *port, const char *name) 7314{ 7315 init_unistr(&port->port_name, name); 7316 init_unistr(&port->monitor_name, "Local Monitor"); 7317 init_unistr(&port->description, SPL_LOCAL_PORT ); 7318 port->port_type=PORT_TYPE_WRITE; 7319 port->reserved=0x0; 7320} 7321 7322 7323/**************************************************************************** 7324 wrapper around the enumer ports command 7325****************************************************************************/ 7326 7327WERROR enumports_hook( int *count, char ***lines ) 7328{ 7329 char *cmd = lp_enumports_cmd(); 7330 char **qlines; 7331 pstring command; 7332 int numlines; 7333 int ret; 7334 int fd; 7335 7336 *count = 0; 7337 *lines = NULL; 7338 7339 /* if no hook then just fill in the default port */ 7340 7341 if ( !*cmd ) { 7342 qlines = SMB_MALLOC_ARRAY( char*, 2 ); 7343 qlines[0] = SMB_STRDUP( SAMBA_PRINTER_PORT_NAME ); 7344 qlines[1] = NULL; 7345 numlines = 1; 7346 } 7347 else { 7348 /* we have a valid enumport command */ 7349 7350 slprintf(command, sizeof(command)-1, "%s \"%d\"", cmd, 1); 7351 7352 DEBUG(10,("Running [%s]\n", command)); 7353 ret = smbrun(command, &fd); 7354 DEBUG(10,("Returned [%d]\n", ret)); 7355 if (ret != 0) { 7356 if (fd != -1) { 7357 close(fd); 7358 } 7359 return WERR_ACCESS_DENIED; 7360 } 7361 7362 numlines = 0; 7363 qlines = fd_lines_load(fd, &numlines, 0); 7364 DEBUGADD(10,("Lines returned = [%d]\n", numlines)); 7365 close(fd); 7366 } 7367 7368 *count = numlines; 7369 *lines = qlines; 7370 7371 return WERR_OK; 7372} 7373 7374/**************************************************************************** 7375 enumports level 1. 7376****************************************************************************/ 7377 7378static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 7379{ 7380 PORT_INFO_1 *ports=NULL; 7381 int i=0; 7382 WERROR result = WERR_OK; 7383 char **qlines = NULL; 7384 int numlines = 0; 7385 7386 result = enumports_hook( &numlines, &qlines ); 7387 if (!W_ERROR_IS_OK(result)) { 7388 file_lines_free(qlines); 7389 return result; 7390 } 7391 7392 if(numlines) { 7393 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) { 7394 DEBUG(10,("Returning WERR_NOMEM [%s]\n", 7395 dos_errstr(WERR_NOMEM))); 7396 file_lines_free(qlines); 7397 return WERR_NOMEM; 7398 } 7399 7400 for (i=0; i<numlines; i++) { 7401 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i])); 7402 fill_port_1(&ports[i], qlines[i]); 7403 } 7404 } 7405 file_lines_free(qlines); 7406 7407 *returned = numlines; 7408 7409 /* check the required size. */ 7410 for (i=0; i<*returned; i++) { 7411 DEBUGADD(6,("adding port [%d]'s size\n", i)); 7412 *needed += spoolss_size_port_info_1(&ports[i]); 7413 } 7414 7415 if (*needed > offered) { 7416 result = WERR_INSUFFICIENT_BUFFER; 7417 goto out; 7418 } 7419 7420 if (!rpcbuf_alloc_size(buffer, *needed)) { 7421 result = WERR_NOMEM; 7422 goto out; 7423 } 7424 7425 /* fill the buffer with the ports structures */ 7426 for (i=0; i<*returned; i++) { 7427 DEBUGADD(6,("adding port [%d] to buffer\n", i)); 7428 smb_io_port_1("", buffer, &ports[i], 0); 7429 } 7430 7431out: 7432 SAFE_FREE(ports); 7433 7434 if ( !W_ERROR_IS_OK(result) ) 7435 *returned = 0; 7436 7437 return result; 7438} 7439 7440/**************************************************************************** 7441 enumports level 2. 7442****************************************************************************/ 7443 7444static WERROR enumports_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 7445{ 7446 PORT_INFO_2 *ports=NULL; 7447 int i=0; 7448 WERROR result = WERR_OK; 7449 char **qlines = NULL; 7450 int numlines = 0; 7451 7452 result = enumports_hook( &numlines, &qlines ); 7453 if ( !W_ERROR_IS_OK(result)) { 7454 file_lines_free(qlines); 7455 return result; 7456 } 7457 7458 if(numlines) { 7459 if((ports=SMB_MALLOC_ARRAY( PORT_INFO_2, numlines)) == NULL) { 7460 file_lines_free(qlines); 7461 return WERR_NOMEM; 7462 } 7463 7464 for (i=0; i<numlines; i++) { 7465 DEBUG(6,("Filling port number [%d] with port [%s]\n", i, qlines[i])); 7466 fill_port_2(&(ports[i]), qlines[i]); 7467 } 7468 } 7469 7470 file_lines_free(qlines); 7471 7472 *returned = numlines; 7473 7474 /* check the required size. */ 7475 for (i=0; i<*returned; i++) { 7476 DEBUGADD(6,("adding port [%d]'s size\n", i)); 7477 *needed += spoolss_size_port_info_2(&ports[i]); 7478 } 7479 7480 if (*needed > offered) { 7481 result = WERR_INSUFFICIENT_BUFFER; 7482 goto out; 7483 } 7484 7485 if (!rpcbuf_alloc_size(buffer, *needed)) { 7486 result = WERR_NOMEM; 7487 goto out; 7488 } 7489 7490 /* fill the buffer with the ports structures */ 7491 for (i=0; i<*returned; i++) { 7492 DEBUGADD(6,("adding port [%d] to buffer\n", i)); 7493 smb_io_port_2("", buffer, &ports[i], 0); 7494 } 7495 7496out: 7497 SAFE_FREE(ports); 7498 7499 if ( !W_ERROR_IS_OK(result) ) 7500 *returned = 0; 7501 7502 return result; 7503} 7504 7505/**************************************************************************** 7506 enumports. 7507****************************************************************************/ 7508 7509WERROR _spoolss_enumports( pipes_struct *p, SPOOL_Q_ENUMPORTS *q_u, SPOOL_R_ENUMPORTS *r_u) 7510{ 7511 uint32 level = q_u->level; 7512 RPC_BUFFER *buffer = NULL; 7513 uint32 offered = q_u->offered; 7514 uint32 *needed = &r_u->needed; 7515 uint32 *returned = &r_u->returned; 7516 7517 /* that's an [in out] buffer */ 7518 7519 if (!q_u->buffer && (offered!=0)) { 7520 return WERR_INVALID_PARAM; 7521 } 7522 7523 rpcbuf_move(q_u->buffer, &r_u->buffer); 7524 buffer = r_u->buffer; 7525 7526 DEBUG(4,("_spoolss_enumports\n")); 7527 7528 *returned=0; 7529 *needed=0; 7530 7531 switch (level) { 7532 case 1: 7533 return enumports_level_1(buffer, offered, needed, returned); 7534 case 2: 7535 return enumports_level_2(buffer, offered, needed, returned); 7536 default: 7537 return WERR_UNKNOWN_LEVEL; 7538 } 7539} 7540 7541/**************************************************************************** 7542****************************************************************************/ 7543 7544static WERROR spoolss_addprinterex_level_2( pipes_struct *p, const UNISTR2 *uni_srv_name, 7545 const SPOOL_PRINTER_INFO_LEVEL *info, 7546 DEVICEMODE *devmode, SEC_DESC_BUF *sec_desc_buf, 7547 uint32 user_switch, const SPOOL_USER_CTR *user, 7548 POLICY_HND *handle) 7549{ 7550 NT_PRINTER_INFO_LEVEL *printer = NULL; 7551 fstring name; 7552 int snum; 7553 WERROR err = WERR_OK; 7554 7555 if ( !(printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) { 7556 DEBUG(0,("spoolss_addprinterex_level_2: malloc fail.\n")); 7557 return WERR_NOMEM; 7558 } 7559 7560 /* convert from UNICODE to ASCII - this allocates the info_2 struct inside *printer.*/ 7561 if (!convert_printer_info(info, printer, 2)) { 7562 free_a_printer(&printer, 2); 7563 return WERR_NOMEM; 7564 } 7565 7566 /* check to see if the printer already exists */ 7567 7568 if ((snum = print_queue_snum(printer->info_2->sharename)) != -1) { 7569 DEBUG(5, ("spoolss_addprinterex_level_2: Attempted to add a printer named [%s] when one already existed!\n", 7570 printer->info_2->sharename)); 7571 free_a_printer(&printer, 2); 7572 return WERR_PRINTER_ALREADY_EXISTS; 7573 } 7574 7575 /* FIXME!!! smbd should check to see if the driver is installed before 7576 trying to add a printer like this --jerry */ 7577 7578 if (*lp_addprinter_cmd() ) { 7579 if ( !add_printer_hook(p->pipe_user.nt_user_token, printer) ) { 7580 free_a_printer(&printer,2); 7581 return WERR_ACCESS_DENIED; 7582 } 7583 } else { 7584 DEBUG(0,("spoolss_addprinterex_level_2: add printer for printer %s called and no" 7585 "smb.conf parameter \"addprinter command\" is defined. This" 7586 "parameter must exist for this call to succeed\n", 7587 printer->info_2->sharename )); 7588 } 7589 7590 /* use our primary netbios name since get_a_printer() will convert 7591 it to what the client expects on a case by case basis */ 7592 7593 slprintf(name, sizeof(name)-1, "\\\\%s\\%s", global_myname(), 7594 printer->info_2->sharename); 7595 7596 7597 if ((snum = print_queue_snum(printer->info_2->sharename)) == -1) { 7598 free_a_printer(&printer,2); 7599 return WERR_ACCESS_DENIED; 7600 } 7601 7602 /* you must be a printer admin to add a new printer */ 7603 if (!print_access_check(NULL, snum, PRINTER_ACCESS_ADMINISTER)) { 7604 free_a_printer(&printer,2); 7605 return WERR_ACCESS_DENIED; 7606 } 7607 7608 /* 7609 * Do sanity check on the requested changes for Samba. 7610 */ 7611 7612 if (!check_printer_ok(printer->info_2, snum)) { 7613 free_a_printer(&printer,2); 7614 return WERR_INVALID_PARAM; 7615 } 7616 7617 /* 7618 * When a printer is created, the drivername bound to the printer is used 7619 * to lookup previously saved driver initialization info, which is then 7620 * bound to the new printer, simulating what happens in the Windows arch. 7621 */ 7622 7623 if (!devmode) 7624 { 7625 set_driver_init(printer, 2); 7626 } 7627 else 7628 { 7629 /* A valid devmode was included, convert and link it 7630 */ 7631 DEBUGADD(10, ("spoolss_addprinterex_level_2: devmode included, converting\n")); 7632 7633 if (!convert_devicemode(printer->info_2->printername, devmode, 7634 &printer->info_2->devmode)) 7635 return WERR_NOMEM; 7636 } 7637 7638 /* write the ASCII on disk */ 7639 err = mod_a_printer(printer, 2); 7640 if (!W_ERROR_IS_OK(err)) { 7641 free_a_printer(&printer,2); 7642 return err; 7643 } 7644 7645 if (!open_printer_hnd(p, handle, name, PRINTER_ACCESS_ADMINISTER)) { 7646 /* Handle open failed - remove addition. */ 7647 del_a_printer(printer->info_2->sharename); 7648 free_a_printer(&printer,2); 7649 return WERR_ACCESS_DENIED; 7650 } 7651 7652 update_c_setprinter(False); 7653 free_a_printer(&printer,2); 7654 7655 return WERR_OK; 7656} 7657 7658/**************************************************************************** 7659****************************************************************************/ 7660 7661WERROR _spoolss_addprinterex( pipes_struct *p, SPOOL_Q_ADDPRINTEREX *q_u, SPOOL_R_ADDPRINTEREX *r_u) 7662{ 7663 UNISTR2 *uni_srv_name = q_u->server_name; 7664 uint32 level = q_u->level; 7665 SPOOL_PRINTER_INFO_LEVEL *info = &q_u->info; 7666 DEVICEMODE *devmode = q_u->devmode_ctr.devmode; 7667 SEC_DESC_BUF *sdb = q_u->secdesc_ctr; 7668 uint32 user_switch = q_u->user_switch; 7669 SPOOL_USER_CTR *user = &q_u->user_ctr; 7670 POLICY_HND *handle = &r_u->handle; 7671 7672 switch (level) { 7673 case 1: 7674 /* we don't handle yet */ 7675 /* but I know what to do ... */ 7676 return WERR_UNKNOWN_LEVEL; 7677 case 2: 7678 return spoolss_addprinterex_level_2(p, uni_srv_name, info, 7679 devmode, sdb, 7680 user_switch, user, handle); 7681 default: 7682 return WERR_UNKNOWN_LEVEL; 7683 } 7684} 7685 7686/**************************************************************************** 7687****************************************************************************/ 7688 7689WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u, SPOOL_R_ADDPRINTERDRIVER *r_u) 7690{ 7691 uint32 level = q_u->level; 7692 SPOOL_PRINTER_DRIVER_INFO_LEVEL *info = &q_u->info; 7693 WERROR err = WERR_OK; 7694 NT_PRINTER_DRIVER_INFO_LEVEL driver; 7695 struct current_user user; 7696 fstring driver_name; 7697 uint32 version; 7698 7699 ZERO_STRUCT(driver); 7700 7701 get_current_user(&user, p); 7702 7703 if (!convert_printer_driver_info(info, &driver, level)) { 7704 err = WERR_NOMEM; 7705 goto done; 7706 } 7707 7708 DEBUG(5,("Cleaning driver's information\n")); 7709 err = clean_up_driver_struct(driver, level, &user); 7710 if (!W_ERROR_IS_OK(err)) 7711 goto done; 7712 7713 DEBUG(5,("Moving driver to final destination\n")); 7714 if( !W_ERROR_IS_OK(err = move_driver_to_download_area(driver, level, &user, &err)) ) { 7715 goto done; 7716 } 7717 7718 if (add_a_printer_driver(driver, level)!=0) { 7719 err = WERR_ACCESS_DENIED; 7720 goto done; 7721 } 7722 7723 /* 7724 * I think this is where he DrvUpgradePrinter() hook would be 7725 * be called in a driver's interface DLL on a Windows NT 4.0/2k 7726 * server. Right now, we just need to send ourselves a message 7727 * to update each printer bound to this driver. --jerry 7728 */ 7729 7730 if (!srv_spoolss_drv_upgrade_printer(driver_name)) { 7731 DEBUG(0,("_spoolss_addprinterdriver: Failed to send message about upgrading driver [%s]!\n", 7732 driver_name)); 7733 } 7734 7735 /* 7736 * Based on the version (e.g. driver destination dir: 0=9x,2=Nt/2k,3=2k/Xp), 7737 * decide if the driver init data should be deleted. The rules are: 7738 * 1) never delete init data if it is a 9x driver, they don't use it anyway 7739 * 2) delete init data only if there is no 2k/Xp driver 7740 * 3) always delete init data 7741 * The generalized rule is always use init data from the highest order driver. 7742 * It is necessary to follow the driver install by an initialization step to 7743 * finish off this process. 7744 */ 7745 if (level == 3) 7746 version = driver.info_3->cversion; 7747 else if (level == 6) 7748 version = driver.info_6->version; 7749 else 7750 version = -1; 7751 switch (version) { 7752 /* 7753 * 9x printer driver - never delete init data 7754 */ 7755 case 0: 7756 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for 9x driver [%s]\n", 7757 driver_name)); 7758 break; 7759 7760 /* 7761 * Nt or 2k (compatiblity mode) printer driver - only delete init data if 7762 * there is no 2k/Xp driver init data for this driver name. 7763 */ 7764 case 2: 7765 { 7766 NT_PRINTER_DRIVER_INFO_LEVEL driver1; 7767 7768 if (!W_ERROR_IS_OK(get_a_printer_driver(&driver1, 3, driver_name, "Windows NT x86", 3))) { 7769 /* 7770 * No 2k/Xp driver found, delete init data (if any) for the new Nt driver. 7771 */ 7772 if (!del_driver_init(driver_name)) 7773 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) Nt failed!\n", driver_name)); 7774 } else { 7775 /* 7776 * a 2k/Xp driver was found, don't delete init data because Nt driver will use it. 7777 */ 7778 free_a_printer_driver(driver1,3); 7779 DEBUG(10,("_spoolss_addprinterdriver: init data not deleted for Nt driver [%s]\n", 7780 driver_name)); 7781 } 7782 } 7783 break; 7784 7785 /* 7786 * 2k or Xp printer driver - always delete init data 7787 */ 7788 case 3: 7789 if (!del_driver_init(driver_name)) 7790 DEBUG(6,("_spoolss_addprinterdriver: del_driver_init(%s) 2k/Xp failed!\n", driver_name)); 7791 break; 7792 7793 default: 7794 DEBUG(0,("_spoolss_addprinterdriver: invalid level=%d\n", level)); 7795 break; 7796 } 7797 7798 7799done: 7800 free_a_printer_driver(driver, level); 7801 return err; 7802} 7803 7804/******************************************************************** 7805 * spoolss_addprinterdriverex 7806 ********************************************************************/ 7807 7808WERROR _spoolss_addprinterdriverex(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVEREX *q_u, SPOOL_R_ADDPRINTERDRIVEREX *r_u) 7809{ 7810 SPOOL_Q_ADDPRINTERDRIVER q_u_local; 7811 SPOOL_R_ADDPRINTERDRIVER r_u_local; 7812 7813 /* 7814 * we only support the semantics of AddPrinterDriver() 7815 * i.e. only copy files that are newer than existing ones 7816 */ 7817 7818 if ( q_u->copy_flags != APD_COPY_NEW_FILES ) 7819 return WERR_ACCESS_DENIED; 7820 7821 ZERO_STRUCT(q_u_local); 7822 ZERO_STRUCT(r_u_local); 7823 7824 /* just pass the information off to _spoolss_addprinterdriver() */ 7825 q_u_local.server_name_ptr = q_u->server_name_ptr; 7826 copy_unistr2(&q_u_local.server_name, &q_u->server_name); 7827 q_u_local.level = q_u->level; 7828 memcpy( &q_u_local.info, &q_u->info, sizeof(SPOOL_PRINTER_DRIVER_INFO_LEVEL) ); 7829 7830 return _spoolss_addprinterdriver( p, &q_u_local, &r_u_local ); 7831} 7832 7833/**************************************************************************** 7834****************************************************************************/ 7835 7836static void fill_driverdir_1(DRIVER_DIRECTORY_1 *info, char *name) 7837{ 7838 init_unistr(&info->name, name); 7839} 7840 7841/**************************************************************************** 7842****************************************************************************/ 7843 7844static WERROR getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environment, RPC_BUFFER *buffer, uint32 offered, uint32 *needed) 7845{ 7846 pstring path; 7847 pstring long_archi; 7848 fstring servername; 7849 char *pservername; 7850 const char *short_archi; 7851 DRIVER_DIRECTORY_1 *info=NULL; 7852 WERROR result = WERR_OK; 7853 7854 unistr2_to_ascii(servername, name, sizeof(servername)-1); 7855 unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1); 7856 7857 /* check for beginning double '\'s and that the server 7858 long enough */ 7859 7860 pservername = servername; 7861 if ( *pservername == '\\' && strlen(servername)>2 ) { 7862 pservername += 2; 7863 } 7864 7865 if ( !is_myname_or_ipaddr( pservername ) ) 7866 return WERR_INVALID_PARAM; 7867 7868 if (!(short_archi = get_short_archi(long_archi))) 7869 return WERR_INVALID_ENVIRONMENT; 7870 7871 if((info=SMB_MALLOC_P(DRIVER_DIRECTORY_1)) == NULL) 7872 return WERR_NOMEM; 7873 7874 slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", pservername, short_archi); 7875 7876 DEBUG(4,("printer driver directory: [%s]\n", path)); 7877 7878 fill_driverdir_1(info, path); 7879 7880 *needed += spoolss_size_driverdir_info_1(info); 7881 7882 if (*needed > offered) { 7883 result = WERR_INSUFFICIENT_BUFFER; 7884 goto out; 7885 } 7886 7887 if (!rpcbuf_alloc_size(buffer, *needed)) { 7888 result = WERR_NOMEM; 7889 goto out; 7890 } 7891 7892 smb_io_driverdir_1("", buffer, info, 0); 7893 7894out: 7895 SAFE_FREE(info); 7896 7897 return result; 7898} 7899 7900/**************************************************************************** 7901****************************************************************************/ 7902 7903WERROR _spoolss_getprinterdriverdirectory(pipes_struct *p, SPOOL_Q_GETPRINTERDRIVERDIR *q_u, SPOOL_R_GETPRINTERDRIVERDIR *r_u) 7904{ 7905 UNISTR2 *name = &q_u->name; 7906 UNISTR2 *uni_environment = &q_u->environment; 7907 uint32 level = q_u->level; 7908 RPC_BUFFER *buffer = NULL; 7909 uint32 offered = q_u->offered; 7910 uint32 *needed = &r_u->needed; 7911 7912 /* that's an [in out] buffer */ 7913 7914 if (!q_u->buffer && (offered!=0)) { 7915 return WERR_INVALID_PARAM; 7916 } 7917 7918 rpcbuf_move(q_u->buffer, &r_u->buffer); 7919 buffer = r_u->buffer; 7920 7921 DEBUG(4,("_spoolss_getprinterdriverdirectory\n")); 7922 7923 *needed=0; 7924 7925 switch(level) { 7926 case 1: 7927 return getprinterdriverdir_level_1(name, uni_environment, buffer, offered, needed); 7928 default: 7929 return WERR_UNKNOWN_LEVEL; 7930 } 7931} 7932 7933/**************************************************************************** 7934****************************************************************************/ 7935 7936WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, SPOOL_R_ENUMPRINTERDATA *r_u) 7937{ 7938 POLICY_HND *handle = &q_u->handle; 7939 uint32 idx = q_u->index; 7940 uint32 in_value_len = q_u->valuesize; 7941 uint32 in_data_len = q_u->datasize; 7942 uint32 *out_max_value_len = &r_u->valuesize; 7943 uint16 **out_value = &r_u->value; 7944 uint32 *out_value_len = &r_u->realvaluesize; 7945 uint32 *out_type = &r_u->type; 7946 uint32 *out_max_data_len = &r_u->datasize; 7947 uint8 **data_out = &r_u->data; 7948 uint32 *out_data_len = &r_u->realdatasize; 7949 7950 NT_PRINTER_INFO_LEVEL *printer = NULL; 7951 7952 uint32 biggest_valuesize; 7953 uint32 biggest_datasize; 7954 uint32 data_len; 7955 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 7956 int snum; 7957 WERROR result; 7958 REGISTRY_VALUE *val = NULL; 7959 NT_PRINTER_DATA *p_data; 7960 int i, key_index, num_values; 7961 int name_length; 7962 7963 *out_type = 0; 7964 7965 *out_max_data_len = 0; 7966 *data_out = NULL; 7967 *out_data_len = 0; 7968 7969 DEBUG(5,("spoolss_enumprinterdata\n")); 7970 7971 if (!Printer) { 7972 DEBUG(2,("_spoolss_enumprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 7973 return WERR_BADFID; 7974 } 7975 7976 if (!get_printer_snum(p,handle, &snum)) 7977 return WERR_BADFID; 7978 7979 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 7980 if (!W_ERROR_IS_OK(result)) 7981 return result; 7982 7983 p_data = printer->info_2->data; 7984 key_index = lookup_printerkey( p_data, SPOOL_PRINTERDATA_KEY ); 7985 7986 result = WERR_OK; 7987 7988 /* 7989 * The NT machine wants to know the biggest size of value and data 7990 * 7991 * cf: MSDN EnumPrinterData remark section 7992 */ 7993 7994 if ( !in_value_len && !in_data_len && (key_index != -1) ) 7995 { 7996 DEBUGADD(6,("Activating NT mega-hack to find sizes\n")); 7997 7998 biggest_valuesize = 0; 7999 biggest_datasize = 0; 8000 8001 num_values = regval_ctr_numvals( p_data->keys[key_index].values ); 8002 8003 for ( i=0; i<num_values; i++ ) 8004 { 8005 val = regval_ctr_specific_value( p_data->keys[key_index].values, i ); 8006 8007 name_length = strlen(val->valuename); 8008 if ( strlen(val->valuename) > biggest_valuesize ) 8009 biggest_valuesize = name_length; 8010 8011 if ( val->size > biggest_datasize ) 8012 biggest_datasize = val->size; 8013 8014 DEBUG(6,("current values: [%d], [%d]\n", biggest_valuesize, 8015 biggest_datasize)); 8016 } 8017 8018 /* the value is an UNICODE string but real_value_size is the length 8019 in bytes including the trailing 0 */ 8020 8021 *out_value_len = 2 * (1+biggest_valuesize); 8022 *out_data_len = biggest_datasize; 8023 8024 DEBUG(6,("final values: [%d], [%d]\n", *out_value_len, *out_data_len)); 8025 8026 goto done; 8027 } 8028 8029 /* 8030 * the value len is wrong in NT sp3 8031 * that's the number of bytes not the number of unicode chars 8032 */ 8033 8034 if ( key_index != -1 ) 8035 val = regval_ctr_specific_value( p_data->keys[key_index].values, idx ); 8036 8037 if ( !val ) 8038 { 8039 8040 /* out_value should default to "" or else NT4 has 8041 problems unmarshalling the response */ 8042 8043 *out_max_value_len=(in_value_len/sizeof(uint16)); 8044 8045 if (in_value_len) { 8046 if((*out_value=(uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL) 8047 { 8048 result = WERR_NOMEM; 8049 goto done; 8050 } 8051 *out_value_len = (uint32)rpcstr_push((char *)*out_value, "", in_value_len, 0); 8052 } else { 8053 *out_value=NULL; 8054 *out_value_len = 0; 8055 } 8056 8057 /* the data is counted in bytes */ 8058 8059 *out_max_data_len = in_data_len; 8060 *out_data_len = in_data_len; 8061 8062 /* only allocate when given a non-zero data_len */ 8063 8064 if ( in_data_len && ((*data_out=(uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) ) 8065 { 8066 result = WERR_NOMEM; 8067 goto done; 8068 } 8069 8070 result = WERR_NO_MORE_ITEMS; 8071 } 8072 else 8073 { 8074 /* 8075 * the value is: 8076 * - counted in bytes in the request 8077 * - counted in UNICODE chars in the max reply 8078 * - counted in bytes in the real size 8079 * 8080 * take a pause *before* coding not *during* coding 8081 */ 8082 8083 /* name */ 8084 *out_max_value_len=(in_value_len/sizeof(uint16)); 8085 if (in_value_len) { 8086 if ( (*out_value = (uint16 *)TALLOC_ZERO(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL ) 8087 { 8088 result = WERR_NOMEM; 8089 goto done; 8090 } 8091 8092 *out_value_len = (uint32)rpcstr_push((char *)*out_value, regval_name(val), (size_t)in_value_len, 0); 8093 } else { 8094 *out_value = NULL; 8095 *out_value_len = 0; 8096 } 8097 8098 /* type */ 8099 8100 *out_type = regval_type( val ); 8101 8102 /* data - counted in bytes */ 8103 8104 *out_max_data_len = in_data_len; 8105 if ( in_data_len && (*data_out = (uint8 *)TALLOC_ZERO(p->mem_ctx, in_data_len*sizeof(uint8))) == NULL) 8106 { 8107 result = WERR_NOMEM; 8108 goto done; 8109 } 8110 data_len = regval_size(val); 8111 if ( *data_out && data_len ) 8112 memcpy( *data_out, regval_data_p(val), data_len ); 8113 *out_data_len = data_len; 8114 } 8115 8116done: 8117 free_a_printer(&printer, 2); 8118 return result; 8119} 8120 8121/**************************************************************************** 8122****************************************************************************/ 8123 8124WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SPOOL_R_SETPRINTERDATA *r_u) 8125{ 8126 POLICY_HND *handle = &q_u->handle; 8127 UNISTR2 *value = &q_u->value; 8128 uint32 type = q_u->type; 8129 uint8 *data = q_u->data; 8130 uint32 real_len = q_u->real_len; 8131 8132 NT_PRINTER_INFO_LEVEL *printer = NULL; 8133 int snum=0; 8134 WERROR status = WERR_OK; 8135 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 8136 fstring valuename; 8137 8138 DEBUG(5,("spoolss_setprinterdata\n")); 8139 8140 if (!Printer) { 8141 DEBUG(2,("_spoolss_setprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 8142 return WERR_BADFID; 8143 } 8144 8145 if ( Printer->printer_type == SPLHND_SERVER ) { 8146 DEBUG(10,("_spoolss_setprinterdata: Not implemented for server handles yet\n")); 8147 return WERR_INVALID_PARAM; 8148 } 8149 8150 if (!get_printer_snum(p,handle, &snum)) 8151 return WERR_BADFID; 8152 8153 /* 8154 * Access check : NT returns "access denied" if you make a 8155 * SetPrinterData call without the necessary privildge. 8156 * we were originally returning OK if nothing changed 8157 * which made Win2k issue **a lot** of SetPrinterData 8158 * when connecting to a printer --jerry 8159 */ 8160 8161 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) 8162 { 8163 DEBUG(3, ("_spoolss_setprinterdata: change denied by handle access permissions\n")); 8164 status = WERR_ACCESS_DENIED; 8165 goto done; 8166 } 8167 8168 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 8169 if (!W_ERROR_IS_OK(status)) 8170 return status; 8171 8172 unistr2_to_ascii( valuename, value, sizeof(valuename)-1 ); 8173 8174 /* 8175 * When client side code sets a magic printer data key, detect it and save 8176 * the current printer data and the magic key's data (its the DEVMODE) for 8177 * future printer/driver initializations. 8178 */ 8179 if ( (type == REG_BINARY) && strequal( valuename, PHANTOM_DEVMODE_KEY)) 8180 { 8181 /* Set devmode and printer initialization info */ 8182 status = save_driver_init( printer, 2, data, real_len ); 8183 8184 srv_spoolss_reset_printerdata( printer->info_2->drivername ); 8185 } 8186 else 8187 { 8188 status = set_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename, 8189 type, data, real_len ); 8190 if ( W_ERROR_IS_OK(status) ) 8191 status = mod_a_printer(printer, 2); 8192 } 8193 8194done: 8195 free_a_printer(&printer, 2); 8196 8197 return status; 8198} 8199 8200/**************************************************************************** 8201****************************************************************************/ 8202 8203WERROR _spoolss_resetprinter(pipes_struct *p, SPOOL_Q_RESETPRINTER *q_u, SPOOL_R_RESETPRINTER *r_u) 8204{ 8205 POLICY_HND *handle = &q_u->handle; 8206 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 8207 int snum; 8208 8209 DEBUG(5,("_spoolss_resetprinter\n")); 8210 8211 /* 8212 * All we do is to check to see if the handle and queue is valid. 8213 * This call really doesn't mean anything to us because we only 8214 * support RAW printing. --jerry 8215 */ 8216 8217 if (!Printer) { 8218 DEBUG(2,("_spoolss_resetprinter: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 8219 return WERR_BADFID; 8220 } 8221 8222 if (!get_printer_snum(p,handle, &snum)) 8223 return WERR_BADFID; 8224 8225 8226 /* blindly return success */ 8227 return WERR_OK; 8228} 8229 8230 8231/**************************************************************************** 8232****************************************************************************/ 8233 8234WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_u, SPOOL_R_DELETEPRINTERDATA *r_u) 8235{ 8236 POLICY_HND *handle = &q_u->handle; 8237 UNISTR2 *value = &q_u->valuename; 8238 8239 NT_PRINTER_INFO_LEVEL *printer = NULL; 8240 int snum=0; 8241 WERROR status = WERR_OK; 8242 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 8243 pstring valuename; 8244 8245 DEBUG(5,("spoolss_deleteprinterdata\n")); 8246 8247 if (!Printer) { 8248 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 8249 return WERR_BADFID; 8250 } 8251 8252 if (!get_printer_snum(p, handle, &snum)) 8253 return WERR_BADFID; 8254 8255 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { 8256 DEBUG(3, ("_spoolss_deleteprinterdata: printer properties change denied by handle\n")); 8257 return WERR_ACCESS_DENIED; 8258 } 8259 8260 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 8261 if (!W_ERROR_IS_OK(status)) 8262 return status; 8263 8264 unistr2_to_ascii( valuename, value, sizeof(valuename)-1 ); 8265 8266 status = delete_printer_dataex( printer, SPOOL_PRINTERDATA_KEY, valuename ); 8267 8268 if ( W_ERROR_IS_OK(status) ) 8269 mod_a_printer( printer, 2 ); 8270 8271 free_a_printer(&printer, 2); 8272 8273 return status; 8274} 8275 8276/**************************************************************************** 8277****************************************************************************/ 8278 8279WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM *r_u) 8280{ 8281 POLICY_HND *handle = &q_u->handle; 8282 FORM *form = &q_u->form; 8283 nt_forms_struct tmpForm; 8284 int snum; 8285 WERROR status = WERR_OK; 8286 NT_PRINTER_INFO_LEVEL *printer = NULL; 8287 8288 int count=0; 8289 nt_forms_struct *list=NULL; 8290 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 8291 8292 DEBUG(5,("spoolss_addform\n")); 8293 8294 if (!Printer) { 8295 DEBUG(2,("_spoolss_addform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 8296 return WERR_BADFID; 8297 } 8298 8299 8300 /* forms can be added on printer of on the print server handle */ 8301 8302 if ( Printer->printer_type == SPLHND_PRINTER ) 8303 { 8304 if (!get_printer_snum(p,handle, &snum)) 8305 return WERR_BADFID; 8306 8307 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 8308 if (!W_ERROR_IS_OK(status)) 8309 goto done; 8310 } 8311 8312 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) { 8313 DEBUG(2,("_spoolss_addform: denied by handle permissions.\n")); 8314 status = WERR_ACCESS_DENIED; 8315 goto done; 8316 } 8317 8318 /* can't add if builtin */ 8319 8320 if (get_a_builtin_ntform(&form->name,&tmpForm)) { 8321 status = WERR_ALREADY_EXISTS; 8322 goto done; 8323 } 8324 8325 count = get_ntforms(&list); 8326 8327 if(!add_a_form(&list, form, &count)) { 8328 status = WERR_NOMEM; 8329 goto done; 8330 } 8331 8332 write_ntforms(&list, count); 8333 8334 /* 8335 * ChangeID must always be set if this is a printer 8336 */ 8337 8338 if ( Printer->printer_type == SPLHND_PRINTER ) 8339 status = mod_a_printer(printer, 2); 8340 8341done: 8342 if ( printer ) 8343 free_a_printer(&printer, 2); 8344 SAFE_FREE(list); 8345 8346 return status; 8347} 8348 8349/**************************************************************************** 8350****************************************************************************/ 8351 8352WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DELETEFORM *r_u) 8353{ 8354 POLICY_HND *handle = &q_u->handle; 8355 UNISTR2 *form_name = &q_u->name; 8356 nt_forms_struct tmpForm; 8357 int count=0; 8358 nt_forms_struct *list=NULL; 8359 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 8360 int snum; 8361 WERROR status = WERR_OK; 8362 NT_PRINTER_INFO_LEVEL *printer = NULL; 8363 8364 DEBUG(5,("spoolss_deleteform\n")); 8365 8366 if (!Printer) { 8367 DEBUG(2,("_spoolss_deleteform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 8368 return WERR_BADFID; 8369 } 8370 8371 /* forms can be deleted on printer of on the print server handle */ 8372 8373 if ( Printer->printer_type == SPLHND_PRINTER ) 8374 { 8375 if (!get_printer_snum(p,handle, &snum)) 8376 return WERR_BADFID; 8377 8378 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 8379 if (!W_ERROR_IS_OK(status)) 8380 goto done; 8381 } 8382 8383 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) { 8384 DEBUG(2,("_spoolss_deleteform: denied by handle permissions.\n")); 8385 status = WERR_ACCESS_DENIED; 8386 goto done; 8387 } 8388 8389 /* can't delete if builtin */ 8390 8391 if (get_a_builtin_ntform(form_name,&tmpForm)) { 8392 status = WERR_INVALID_PARAM; 8393 goto done; 8394 } 8395 8396 count = get_ntforms(&list); 8397 8398 if ( !delete_a_form(&list, form_name, &count, &status )) 8399 goto done; 8400 8401 /* 8402 * ChangeID must always be set if this is a printer 8403 */ 8404 8405 if ( Printer->printer_type == SPLHND_PRINTER ) 8406 status = mod_a_printer(printer, 2); 8407 8408done: 8409 if ( printer ) 8410 free_a_printer(&printer, 2); 8411 SAFE_FREE(list); 8412 8413 return status; 8414} 8415 8416/**************************************************************************** 8417****************************************************************************/ 8418 8419WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM *r_u) 8420{ 8421 POLICY_HND *handle = &q_u->handle; 8422 FORM *form = &q_u->form; 8423 nt_forms_struct tmpForm; 8424 int snum; 8425 WERROR status = WERR_OK; 8426 NT_PRINTER_INFO_LEVEL *printer = NULL; 8427 8428 int count=0; 8429 nt_forms_struct *list=NULL; 8430 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 8431 8432 DEBUG(5,("spoolss_setform\n")); 8433 8434 if (!Printer) { 8435 DEBUG(2,("_spoolss_setform: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 8436 return WERR_BADFID; 8437 } 8438 8439 /* forms can be modified on printer of on the print server handle */ 8440 8441 if ( Printer->printer_type == SPLHND_PRINTER ) 8442 { 8443 if (!get_printer_snum(p,handle, &snum)) 8444 return WERR_BADFID; 8445 8446 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 8447 if (!W_ERROR_IS_OK(status)) 8448 goto done; 8449 } 8450 8451 if ( !(Printer->access_granted & (PRINTER_ACCESS_ADMINISTER|SERVER_ACCESS_ADMINISTER)) ) { 8452 DEBUG(2,("_spoolss_setform: denied by handle permissions\n")); 8453 status = WERR_ACCESS_DENIED; 8454 goto done; 8455 } 8456 8457 /* can't set if builtin */ 8458 if (get_a_builtin_ntform(&form->name,&tmpForm)) { 8459 status = WERR_INVALID_PARAM; 8460 goto done; 8461 } 8462 8463 count = get_ntforms(&list); 8464 update_a_form(&list, form, count); 8465 write_ntforms(&list, count); 8466 8467 /* 8468 * ChangeID must always be set if this is a printer 8469 */ 8470 8471 if ( Printer->printer_type == SPLHND_PRINTER ) 8472 status = mod_a_printer(printer, 2); 8473 8474 8475done: 8476 if ( printer ) 8477 free_a_printer(&printer, 2); 8478 SAFE_FREE(list); 8479 8480 return status; 8481} 8482 8483/**************************************************************************** 8484 enumprintprocessors level 1. 8485****************************************************************************/ 8486 8487static WERROR enumprintprocessors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 8488{ 8489 PRINTPROCESSOR_1 *info_1=NULL; 8490 WERROR result = WERR_OK; 8491 8492 if((info_1 = SMB_MALLOC_P(PRINTPROCESSOR_1)) == NULL) 8493 return WERR_NOMEM; 8494 8495 (*returned) = 0x1; 8496 8497 init_unistr(&info_1->name, "winprint"); 8498 8499 *needed += spoolss_size_printprocessor_info_1(info_1); 8500 8501 if (*needed > offered) { 8502 result = WERR_INSUFFICIENT_BUFFER; 8503 goto out; 8504 } 8505 8506 if (!rpcbuf_alloc_size(buffer, *needed)) { 8507 result = WERR_NOMEM; 8508 goto out; 8509 } 8510 8511 smb_io_printprocessor_info_1("", buffer, info_1, 0); 8512 8513out: 8514 SAFE_FREE(info_1); 8515 8516 if ( !W_ERROR_IS_OK(result) ) 8517 *returned = 0; 8518 8519 return result; 8520} 8521 8522/**************************************************************************** 8523****************************************************************************/ 8524 8525WERROR _spoolss_enumprintprocessors(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCESSORS *q_u, SPOOL_R_ENUMPRINTPROCESSORS *r_u) 8526{ 8527 uint32 level = q_u->level; 8528 RPC_BUFFER *buffer = NULL; 8529 uint32 offered = q_u->offered; 8530 uint32 *needed = &r_u->needed; 8531 uint32 *returned = &r_u->returned; 8532 8533 /* that's an [in out] buffer */ 8534 8535 if (!q_u->buffer && (offered!=0)) { 8536 return WERR_INVALID_PARAM; 8537 } 8538 8539 rpcbuf_move(q_u->buffer, &r_u->buffer); 8540 buffer = r_u->buffer; 8541 8542 DEBUG(5,("spoolss_enumprintprocessors\n")); 8543 8544 /* 8545 * Enumerate the print processors ... 8546 * 8547 * Just reply with "winprint", to keep NT happy 8548 * and I can use my nice printer checker. 8549 */ 8550 8551 *returned=0; 8552 *needed=0; 8553 8554 switch (level) { 8555 case 1: 8556 return enumprintprocessors_level_1(buffer, offered, needed, returned); 8557 default: 8558 return WERR_UNKNOWN_LEVEL; 8559 } 8560} 8561 8562/**************************************************************************** 8563 enumprintprocdatatypes level 1. 8564****************************************************************************/ 8565 8566static WERROR enumprintprocdatatypes_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 8567{ 8568 PRINTPROCDATATYPE_1 *info_1=NULL; 8569 WERROR result = WERR_OK; 8570 8571 if((info_1 = SMB_MALLOC_P(PRINTPROCDATATYPE_1)) == NULL) 8572 return WERR_NOMEM; 8573 8574 (*returned) = 0x1; 8575 8576 init_unistr(&info_1->name, "RAW"); 8577 8578 *needed += spoolss_size_printprocdatatype_info_1(info_1); 8579 8580 if (*needed > offered) { 8581 result = WERR_INSUFFICIENT_BUFFER; 8582 goto out; 8583 } 8584 8585 if (!rpcbuf_alloc_size(buffer, *needed)) { 8586 result = WERR_NOMEM; 8587 goto out; 8588 } 8589 8590 smb_io_printprocdatatype_info_1("", buffer, info_1, 0); 8591 8592out: 8593 SAFE_FREE(info_1); 8594 8595 if ( !W_ERROR_IS_OK(result) ) 8596 *returned = 0; 8597 8598 return result; 8599} 8600 8601/**************************************************************************** 8602****************************************************************************/ 8603 8604WERROR _spoolss_enumprintprocdatatypes(pipes_struct *p, SPOOL_Q_ENUMPRINTPROCDATATYPES *q_u, SPOOL_R_ENUMPRINTPROCDATATYPES *r_u) 8605{ 8606 uint32 level = q_u->level; 8607 RPC_BUFFER *buffer = NULL; 8608 uint32 offered = q_u->offered; 8609 uint32 *needed = &r_u->needed; 8610 uint32 *returned = &r_u->returned; 8611 8612 /* that's an [in out] buffer */ 8613 8614 if (!q_u->buffer && (offered!=0)) { 8615 return WERR_INVALID_PARAM; 8616 } 8617 8618 rpcbuf_move(q_u->buffer, &r_u->buffer); 8619 buffer = r_u->buffer; 8620 8621 DEBUG(5,("_spoolss_enumprintprocdatatypes\n")); 8622 8623 *returned=0; 8624 *needed=0; 8625 8626 switch (level) { 8627 case 1: 8628 return enumprintprocdatatypes_level_1(buffer, offered, needed, returned); 8629 default: 8630 return WERR_UNKNOWN_LEVEL; 8631 } 8632} 8633 8634/**************************************************************************** 8635 enumprintmonitors level 1. 8636****************************************************************************/ 8637 8638static WERROR enumprintmonitors_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 8639{ 8640 PRINTMONITOR_1 *info_1; 8641 WERROR result = WERR_OK; 8642 int i; 8643 8644 if((info_1 = SMB_MALLOC_ARRAY(PRINTMONITOR_1, 2)) == NULL) 8645 return WERR_NOMEM; 8646 8647 *returned = 2; 8648 8649 init_unistr(&(info_1[0].name), SPL_LOCAL_PORT ); 8650 init_unistr(&(info_1[1].name), SPL_TCPIP_PORT ); 8651 8652 for ( i=0; i<*returned; i++ ) { 8653 *needed += spoolss_size_printmonitor_info_1(&info_1[i]); 8654 } 8655 8656 if (*needed > offered) { 8657 result = WERR_INSUFFICIENT_BUFFER; 8658 goto out; 8659 } 8660 8661 if (!rpcbuf_alloc_size(buffer, *needed)) { 8662 result = WERR_NOMEM; 8663 goto out; 8664 } 8665 8666 for ( i=0; i<*returned; i++ ) { 8667 smb_io_printmonitor_info_1("", buffer, &info_1[i], 0); 8668 } 8669 8670out: 8671 SAFE_FREE(info_1); 8672 8673 if ( !W_ERROR_IS_OK(result) ) 8674 *returned = 0; 8675 8676 return result; 8677} 8678 8679/**************************************************************************** 8680 enumprintmonitors level 2. 8681****************************************************************************/ 8682 8683static WERROR enumprintmonitors_level_2(RPC_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned) 8684{ 8685 PRINTMONITOR_2 *info_2; 8686 WERROR result = WERR_OK; 8687 int i; 8688 8689 if((info_2 = SMB_MALLOC_ARRAY(PRINTMONITOR_2, 2)) == NULL) 8690 return WERR_NOMEM; 8691 8692 *returned = 2; 8693 8694 init_unistr( &(info_2[0].name), SPL_LOCAL_PORT ); 8695 init_unistr( &(info_2[0].environment), "Windows NT X86" ); 8696 init_unistr( &(info_2[0].dll_name), "localmon.dll" ); 8697 8698 init_unistr( &(info_2[1].name), SPL_TCPIP_PORT ); 8699 init_unistr( &(info_2[1].environment), "Windows NT X86" ); 8700 init_unistr( &(info_2[1].dll_name), "tcpmon.dll" ); 8701 8702 for ( i=0; i<*returned; i++ ) { 8703 *needed += spoolss_size_printmonitor_info_2(&info_2[i]); 8704 } 8705 8706 if (*needed > offered) { 8707 result = WERR_INSUFFICIENT_BUFFER; 8708 goto out; 8709 } 8710 8711 if (!rpcbuf_alloc_size(buffer, *needed)) { 8712 result = WERR_NOMEM; 8713 goto out; 8714 } 8715 8716 for ( i=0; i<*returned; i++ ) { 8717 smb_io_printmonitor_info_2("", buffer, &info_2[i], 0); 8718 } 8719 8720out: 8721 SAFE_FREE(info_2); 8722 8723 if ( !W_ERROR_IS_OK(result) ) 8724 *returned = 0; 8725 8726 return result; 8727} 8728 8729/**************************************************************************** 8730****************************************************************************/ 8731 8732WERROR _spoolss_enumprintmonitors(pipes_struct *p, SPOOL_Q_ENUMPRINTMONITORS *q_u, SPOOL_R_ENUMPRINTMONITORS *r_u) 8733{ 8734 uint32 level = q_u->level; 8735 RPC_BUFFER *buffer = NULL; 8736 uint32 offered = q_u->offered; 8737 uint32 *needed = &r_u->needed; 8738 uint32 *returned = &r_u->returned; 8739 8740 /* that's an [in out] buffer */ 8741 8742 if (!q_u->buffer && (offered!=0)) { 8743 return WERR_INVALID_PARAM; 8744 } 8745 8746 rpcbuf_move(q_u->buffer, &r_u->buffer); 8747 buffer = r_u->buffer; 8748 8749 DEBUG(5,("spoolss_enumprintmonitors\n")); 8750 8751 /* 8752 * Enumerate the print monitors ... 8753 * 8754 * Just reply with "Local Port", to keep NT happy 8755 * and I can use my nice printer checker. 8756 */ 8757 8758 *returned=0; 8759 *needed=0; 8760 8761 switch (level) { 8762 case 1: 8763 return enumprintmonitors_level_1(buffer, offered, needed, returned); 8764 case 2: 8765 return enumprintmonitors_level_2(buffer, offered, needed, returned); 8766 default: 8767 return WERR_UNKNOWN_LEVEL; 8768 } 8769} 8770 8771/**************************************************************************** 8772****************************************************************************/ 8773 8774static WERROR getjob_level_1(print_queue_struct **queue, int count, int snum, 8775 NT_PRINTER_INFO_LEVEL *ntprinter, 8776 uint32 jobid, RPC_BUFFER *buffer, uint32 offered, 8777 uint32 *needed) 8778{ 8779 int i=0; 8780 BOOL found=False; 8781 JOB_INFO_1 *info_1=NULL; 8782 WERROR result = WERR_OK; 8783 8784 info_1=SMB_MALLOC_P(JOB_INFO_1); 8785 8786 if (info_1 == NULL) { 8787 return WERR_NOMEM; 8788 } 8789 8790 for (i=0; i<count && found==False; i++) { 8791 if ((*queue)[i].job==(int)jobid) 8792 found=True; 8793 } 8794 8795 if (found==False) { 8796 SAFE_FREE(info_1); 8797 /* NT treats not found as bad param... yet another bad choice */ 8798 return WERR_INVALID_PARAM; 8799 } 8800 8801 fill_job_info_1( info_1, &((*queue)[i-1]), i, snum, ntprinter ); 8802 8803 *needed += spoolss_size_job_info_1(info_1); 8804 8805 if (*needed > offered) { 8806 result = WERR_INSUFFICIENT_BUFFER; 8807 goto out; 8808 } 8809 8810 if (!rpcbuf_alloc_size(buffer, *needed)) { 8811 result = WERR_NOMEM; 8812 goto out; 8813 } 8814 8815 smb_io_job_info_1("", buffer, info_1, 0); 8816 8817out: 8818 SAFE_FREE(info_1); 8819 8820 return result; 8821} 8822 8823/**************************************************************************** 8824****************************************************************************/ 8825 8826static WERROR getjob_level_2(print_queue_struct **queue, int count, int snum, 8827 NT_PRINTER_INFO_LEVEL *ntprinter, 8828 uint32 jobid, RPC_BUFFER *buffer, uint32 offered, 8829 uint32 *needed) 8830{ 8831 int i = 0; 8832 BOOL found = False; 8833 JOB_INFO_2 *info_2; 8834 WERROR result; 8835 DEVICEMODE *devmode = NULL; 8836 NT_DEVICEMODE *nt_devmode = NULL; 8837 8838 if ( !(info_2=SMB_MALLOC_P(JOB_INFO_2)) ) 8839 return WERR_NOMEM; 8840 8841 ZERO_STRUCTP(info_2); 8842 8843 for ( i=0; i<count && found==False; i++ ) 8844 { 8845 if ((*queue)[i].job == (int)jobid) 8846 found = True; 8847 } 8848 8849 if ( !found ) { 8850 /* NT treats not found as bad param... yet another bad 8851 choice */ 8852 result = WERR_INVALID_PARAM; 8853 goto done; 8854 } 8855 8856 /* 8857 * if the print job does not have a DEVMODE associated with it, 8858 * just use the one for the printer. A NULL devicemode is not 8859 * a failure condition 8860 */ 8861 8862 if ( !(nt_devmode=print_job_devmode( lp_const_servicename(snum), jobid )) ) 8863 devmode = construct_dev_mode(lp_const_servicename(snum)); 8864 else { 8865 if ((devmode = SMB_MALLOC_P(DEVICEMODE)) != NULL) { 8866 ZERO_STRUCTP( devmode ); 8867 convert_nt_devicemode( devmode, nt_devmode ); 8868 } 8869 } 8870 8871 fill_job_info_2(info_2, &((*queue)[i-1]), i, snum, ntprinter, devmode); 8872 8873 *needed += spoolss_size_job_info_2(info_2); 8874 8875 if (*needed > offered) { 8876 result = WERR_INSUFFICIENT_BUFFER; 8877 goto done; 8878 } 8879 8880 if (!rpcbuf_alloc_size(buffer, *needed)) { 8881 result = WERR_NOMEM; 8882 goto done; 8883 } 8884 8885 smb_io_job_info_2("", buffer, info_2, 0); 8886 8887 result = WERR_OK; 8888 8889 done: 8890 /* Cleanup allocated memory */ 8891 8892 free_job_info_2(info_2); /* Also frees devmode */ 8893 SAFE_FREE(info_2); 8894 8895 return result; 8896} 8897 8898/**************************************************************************** 8899****************************************************************************/ 8900 8901WERROR _spoolss_getjob( pipes_struct *p, SPOOL_Q_GETJOB *q_u, SPOOL_R_GETJOB *r_u) 8902{ 8903 POLICY_HND *handle = &q_u->handle; 8904 uint32 jobid = q_u->jobid; 8905 uint32 level = q_u->level; 8906 RPC_BUFFER *buffer = NULL; 8907 uint32 offered = q_u->offered; 8908 uint32 *needed = &r_u->needed; 8909 WERROR wstatus = WERR_OK; 8910 NT_PRINTER_INFO_LEVEL *ntprinter = NULL; 8911 int snum; 8912 int count; 8913 print_queue_struct *queue = NULL; 8914 print_status_struct prt_status; 8915 8916 /* that's an [in out] buffer */ 8917 8918 if (!q_u->buffer && (offered!=0)) { 8919 return WERR_INVALID_PARAM; 8920 } 8921 8922 rpcbuf_move(q_u->buffer, &r_u->buffer); 8923 buffer = r_u->buffer; 8924 8925 DEBUG(5,("spoolss_getjob\n")); 8926 8927 *needed = 0; 8928 8929 if (!get_printer_snum(p, handle, &snum)) 8930 return WERR_BADFID; 8931 8932 wstatus = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); 8933 if ( !W_ERROR_IS_OK(wstatus) ) 8934 return wstatus; 8935 8936 count = print_queue_status(snum, &queue, &prt_status); 8937 8938 DEBUGADD(4,("count:[%d], prt_status:[%d], [%s]\n", 8939 count, prt_status.status, prt_status.message)); 8940 8941 switch ( level ) { 8942 case 1: 8943 wstatus = getjob_level_1(&queue, count, snum, ntprinter, jobid, 8944 buffer, offered, needed); 8945 break; 8946 case 2: 8947 wstatus = getjob_level_2(&queue, count, snum, ntprinter, jobid, 8948 buffer, offered, needed); 8949 break; 8950 default: 8951 wstatus = WERR_UNKNOWN_LEVEL; 8952 break; 8953 } 8954 8955 SAFE_FREE(queue); 8956 free_a_printer( &ntprinter, 2 ); 8957 8958 return wstatus; 8959} 8960 8961/******************************************************************** 8962 spoolss_getprinterdataex 8963 8964 From MSDN documentation of GetPrinterDataEx: pass request 8965 to GetPrinterData if key is "PrinterDriverData". 8966 ********************************************************************/ 8967 8968WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, SPOOL_R_GETPRINTERDATAEX *r_u) 8969{ 8970 POLICY_HND *handle = &q_u->handle; 8971 uint32 in_size = q_u->size; 8972 uint32 *type = &r_u->type; 8973 uint32 *out_size = &r_u->size; 8974 uint8 **data = &r_u->data; 8975 uint32 *needed = &r_u->needed; 8976 fstring keyname, valuename; 8977 8978 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 8979 8980 NT_PRINTER_INFO_LEVEL *printer = NULL; 8981 int snum = 0; 8982 WERROR status = WERR_OK; 8983 8984 DEBUG(4,("_spoolss_getprinterdataex\n")); 8985 8986 unistr2_to_ascii(keyname, &q_u->keyname, sizeof(keyname) - 1); 8987 unistr2_to_ascii(valuename, &q_u->valuename, sizeof(valuename) - 1); 8988 8989 DEBUG(10, ("_spoolss_getprinterdataex: key => [%s], value => [%s]\n", 8990 keyname, valuename)); 8991 8992 /* in case of problem, return some default values */ 8993 8994 *needed = 0; 8995 *type = 0; 8996 *out_size = in_size; 8997 8998 if (!Printer) { 8999 DEBUG(2,("_spoolss_getprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 9000 status = WERR_BADFID; 9001 goto done; 9002 } 9003 9004 /* Is the handle to a printer or to the server? */ 9005 9006 if (Printer->printer_type == SPLHND_SERVER) { 9007 DEBUG(10,("_spoolss_getprinterdataex: Not implemented for server handles yet\n")); 9008 status = WERR_INVALID_PARAM; 9009 goto done; 9010 } 9011 9012 if ( !get_printer_snum(p,handle, &snum) ) 9013 return WERR_BADFID; 9014 9015 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); 9016 if ( !W_ERROR_IS_OK(status) ) 9017 goto done; 9018 9019 /* check to see if the keyname is valid */ 9020 if ( !strlen(keyname) ) { 9021 status = WERR_INVALID_PARAM; 9022 goto done; 9023 } 9024 9025 if ( lookup_printerkey( printer->info_2->data, keyname ) == -1 ) { 9026 DEBUG(4,("_spoolss_getprinterdataex: Invalid keyname [%s]\n", keyname )); 9027 free_a_printer( &printer, 2 ); 9028 status = WERR_BADFILE; 9029 goto done; 9030 } 9031 9032 /* When given a new keyname, we should just create it */ 9033 9034 status = get_printer_dataex( p->mem_ctx, printer, keyname, valuename, type, data, needed, in_size ); 9035 9036 if (*needed > *out_size) 9037 status = WERR_MORE_DATA; 9038 9039done: 9040 if ( !W_ERROR_IS_OK(status) ) 9041 { 9042 DEBUG(5, ("error: allocating %d\n", *out_size)); 9043 9044 /* reply this param doesn't exist */ 9045 9046 if ( *out_size ) 9047 { 9048 if( (*data=(uint8 *)TALLOC_ZERO(p->mem_ctx, *out_size*sizeof(uint8))) == NULL ) { 9049 status = WERR_NOMEM; 9050 goto done; 9051 } 9052 } else { 9053 *data = NULL; 9054 } 9055 } 9056 9057 if ( printer ) 9058 free_a_printer( &printer, 2 ); 9059 9060 return status; 9061} 9062 9063/******************************************************************** 9064 * spoolss_setprinterdataex 9065 ********************************************************************/ 9066 9067WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, SPOOL_R_SETPRINTERDATAEX *r_u) 9068{ 9069 POLICY_HND *handle = &q_u->handle; 9070 uint32 type = q_u->type; 9071 uint8 *data = q_u->data; 9072 uint32 real_len = q_u->real_len; 9073 9074 NT_PRINTER_INFO_LEVEL *printer = NULL; 9075 int snum = 0; 9076 WERROR status = WERR_OK; 9077 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 9078 fstring valuename; 9079 fstring keyname; 9080 char *oid_string; 9081 9082 DEBUG(4,("_spoolss_setprinterdataex\n")); 9083 9084 /* From MSDN documentation of SetPrinterDataEx: pass request to 9085 SetPrinterData if key is "PrinterDriverData" */ 9086 9087 if (!Printer) { 9088 DEBUG(2,("_spoolss_setprinterdataex: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 9089 return WERR_BADFID; 9090 } 9091 9092 if ( Printer->printer_type == SPLHND_SERVER ) { 9093 DEBUG(10,("_spoolss_setprinterdataex: Not implemented for server handles yet\n")); 9094 return WERR_INVALID_PARAM; 9095 } 9096 9097 if ( !get_printer_snum(p,handle, &snum) ) 9098 return WERR_BADFID; 9099 9100 /* 9101 * Access check : NT returns "access denied" if you make a 9102 * SetPrinterData call without the necessary privildge. 9103 * we were originally returning OK if nothing changed 9104 * which made Win2k issue **a lot** of SetPrinterData 9105 * when connecting to a printer --jerry 9106 */ 9107 9108 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) 9109 { 9110 DEBUG(3, ("_spoolss_setprinterdataex: change denied by handle access permissions\n")); 9111 return WERR_ACCESS_DENIED; 9112 } 9113 9114 status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); 9115 if (!W_ERROR_IS_OK(status)) 9116 return status; 9117 9118 unistr2_to_ascii( valuename, &q_u->value, sizeof(valuename) - 1); 9119 unistr2_to_ascii( keyname, &q_u->key, sizeof(keyname) - 1); 9120 9121 /* check for OID in valuename */ 9122 9123 if ( (oid_string = strchr( valuename, ',' )) != NULL ) 9124 { 9125 *oid_string = '\0'; 9126 oid_string++; 9127 } 9128 9129 /* save the registry data */ 9130 9131 status = set_printer_dataex( printer, keyname, valuename, type, data, real_len ); 9132 9133 if ( W_ERROR_IS_OK(status) ) 9134 { 9135 /* save the OID if one was specified */ 9136 if ( oid_string ) { 9137 fstrcat( keyname, "\\" ); 9138 fstrcat( keyname, SPOOL_OID_KEY ); 9139 9140 /* 9141 * I'm not checking the status here on purpose. Don't know 9142 * if this is right, but I'm returning the status from the 9143 * previous set_printer_dataex() call. I have no idea if 9144 * this is right. --jerry 9145 */ 9146 9147 set_printer_dataex( printer, keyname, valuename, 9148 REG_SZ, (void*)oid_string, strlen(oid_string)+1 ); 9149 } 9150 9151 status = mod_a_printer(printer, 2); 9152 } 9153 9154 free_a_printer(&printer, 2); 9155 9156 return status; 9157} 9158 9159 9160/******************************************************************** 9161 * spoolss_deleteprinterdataex 9162 ********************************************************************/ 9163 9164WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX *q_u, SPOOL_R_DELETEPRINTERDATAEX *r_u) 9165{ 9166 POLICY_HND *handle = &q_u->handle; 9167 UNISTR2 *value = &q_u->valuename; 9168 UNISTR2 *key = &q_u->keyname; 9169 9170 NT_PRINTER_INFO_LEVEL *printer = NULL; 9171 int snum=0; 9172 WERROR status = WERR_OK; 9173 Printer_entry *Printer=find_printer_index_by_hnd(p, handle); 9174 pstring valuename, keyname; 9175 9176 DEBUG(5,("spoolss_deleteprinterdataex\n")); 9177 9178 if (!Printer) { 9179 DEBUG(2,("_spoolss_deleteprinterdata: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 9180 return WERR_BADFID; 9181 } 9182 9183 if (!get_printer_snum(p, handle, &snum)) 9184 return WERR_BADFID; 9185 9186 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { 9187 DEBUG(3, ("_spoolss_deleteprinterdataex: printer properties change denied by handle\n")); 9188 return WERR_ACCESS_DENIED; 9189 } 9190 9191 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 9192 if (!W_ERROR_IS_OK(status)) 9193 return status; 9194 9195 unistr2_to_ascii( valuename, value, sizeof(valuename)-1 ); 9196 unistr2_to_ascii( keyname, key, sizeof(keyname)-1 ); 9197 9198 status = delete_printer_dataex( printer, keyname, valuename ); 9199 9200 if ( W_ERROR_IS_OK(status) ) 9201 mod_a_printer( printer, 2 ); 9202 9203 free_a_printer(&printer, 2); 9204 9205 return status; 9206} 9207 9208/******************************************************************** 9209 * spoolss_enumprinterkey 9210 ********************************************************************/ 9211 9212 9213WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPOOL_R_ENUMPRINTERKEY *r_u) 9214{ 9215 fstring key; 9216 fstring *keynames = NULL; 9217 uint16 *enumkeys = NULL; 9218 int num_keys; 9219 int printerkey_len; 9220 POLICY_HND *handle = &q_u->handle; 9221 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 9222 NT_PRINTER_DATA *data; 9223 NT_PRINTER_INFO_LEVEL *printer = NULL; 9224 int snum = 0; 9225 WERROR status = WERR_BADFILE; 9226 9227 9228 DEBUG(4,("_spoolss_enumprinterkey\n")); 9229 9230 if (!Printer) { 9231 DEBUG(2,("_spoolss_enumprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 9232 return WERR_BADFID; 9233 } 9234 9235 if ( !get_printer_snum(p,handle, &snum) ) 9236 return WERR_BADFID; 9237 9238 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 9239 if (!W_ERROR_IS_OK(status)) 9240 return status; 9241 9242 /* get the list of subkey names */ 9243 9244 unistr2_to_ascii( key, &q_u->key, sizeof(key)-1 ); 9245 data = printer->info_2->data; 9246 9247 num_keys = get_printer_subkeys( data, key, &keynames ); 9248 9249 if ( num_keys == -1 ) { 9250 status = WERR_BADFILE; 9251 goto done; 9252 } 9253 9254 printerkey_len = init_unistr_array( &enumkeys, keynames, NULL ); 9255 9256 r_u->needed = printerkey_len*2; 9257 9258 if ( q_u->size < r_u->needed ) { 9259 status = WERR_MORE_DATA; 9260 goto done; 9261 } 9262 9263 if (!make_spoolss_buffer5(p->mem_ctx, &r_u->keys, printerkey_len, enumkeys)) { 9264 status = WERR_NOMEM; 9265 goto done; 9266 } 9267 9268 status = WERR_OK; 9269 9270 if ( q_u->size < r_u->needed ) 9271 status = WERR_MORE_DATA; 9272 9273done: 9274 free_a_printer( &printer, 2 ); 9275 SAFE_FREE( keynames ); 9276 9277 return status; 9278} 9279 9280/******************************************************************** 9281 * spoolss_deleteprinterkey 9282 ********************************************************************/ 9283 9284WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u, SPOOL_R_DELETEPRINTERKEY *r_u) 9285{ 9286 POLICY_HND *handle = &q_u->handle; 9287 Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle); 9288 fstring key; 9289 NT_PRINTER_INFO_LEVEL *printer = NULL; 9290 int snum=0; 9291 WERROR status; 9292 9293 DEBUG(5,("spoolss_deleteprinterkey\n")); 9294 9295 if (!Printer) { 9296 DEBUG(2,("_spoolss_deleteprinterkey: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(handle))); 9297 return WERR_BADFID; 9298 } 9299 9300 /* if keyname == NULL, return error */ 9301 9302 if ( !q_u->keyname.buffer ) 9303 return WERR_INVALID_PARAM; 9304 9305 if (!get_printer_snum(p, handle, &snum)) 9306 return WERR_BADFID; 9307 9308 if (Printer->access_granted != PRINTER_ACCESS_ADMINISTER) { 9309 DEBUG(3, ("_spoolss_deleteprinterkey: printer properties change denied by handle\n")); 9310 return WERR_ACCESS_DENIED; 9311 } 9312 9313 status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 9314 if (!W_ERROR_IS_OK(status)) 9315 return status; 9316 9317 /* delete the key and all subneys */ 9318 9319 unistr2_to_ascii(key, &q_u->keyname, sizeof(key) - 1); 9320 9321 status = delete_all_printer_data( printer->info_2, key ); 9322 9323 if ( W_ERROR_IS_OK(status) ) 9324 status = mod_a_printer(printer, 2); 9325 9326 free_a_printer( &printer, 2 ); 9327 9328 return status; 9329} 9330 9331 9332/******************************************************************** 9333 * spoolss_enumprinterdataex 9334 ********************************************************************/ 9335 9336WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_u, SPOOL_R_ENUMPRINTERDATAEX *r_u) 9337{ 9338 POLICY_HND *handle = &q_u->handle; 9339 uint32 in_size = q_u->size; 9340 uint32 num_entries, 9341 needed; 9342 NT_PRINTER_INFO_LEVEL *printer = NULL; 9343 PRINTER_ENUM_VALUES *enum_values = NULL; 9344 NT_PRINTER_DATA *p_data; 9345 fstring key; 9346 Printer_entry *Printer = find_printer_index_by_hnd(p, handle); 9347 int snum; 9348 WERROR result; 9349 int key_index; 9350 int i; 9351 REGISTRY_VALUE *val; 9352 char *value_name; 9353 uint32 data_len; 9354 9355 9356 DEBUG(4,("_spoolss_enumprinterdataex\n")); 9357 9358 if (!Printer) { 9359 DEBUG(2,("_spoolss_enumprinterdataex: Invalid handle (%s:%u:%u1<).\n", OUR_HANDLE(handle))); 9360 return WERR_BADFID; 9361 } 9362 9363 /* 9364 * first check for a keyname of NULL or "". Win2k seems to send 9365 * this a lot and we should send back WERR_INVALID_PARAM 9366 * no need to spend time looking up the printer in this case. 9367 * --jerry 9368 */ 9369 9370 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1); 9371 if ( !strlen(key) ) { 9372 result = WERR_INVALID_PARAM; 9373 goto done; 9374 } 9375 9376 /* get the printer off of disk */ 9377 9378 if (!get_printer_snum(p,handle, &snum)) 9379 return WERR_BADFID; 9380 9381 ZERO_STRUCT(printer); 9382 result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); 9383 if (!W_ERROR_IS_OK(result)) 9384 return result; 9385 9386 /* now look for a match on the key name */ 9387 9388 p_data = printer->info_2->data; 9389 9390 unistr2_to_ascii(key, &q_u->key, sizeof(key) - 1); 9391 if ( (key_index = lookup_printerkey( p_data, key)) == -1 ) 9392 { 9393 DEBUG(10,("_spoolss_enumprinterdataex: Unknown keyname [%s]\n", key)); 9394 result = WERR_INVALID_PARAM; 9395 goto done; 9396 } 9397 9398 result = WERR_OK; 9399 needed = 0; 9400 9401 /* allocate the memory for the array of pointers -- if necessary */ 9402 9403 num_entries = regval_ctr_numvals( p_data->keys[key_index].values ); 9404 if ( num_entries ) 9405 { 9406 if ( (enum_values=TALLOC_ARRAY(p->mem_ctx, PRINTER_ENUM_VALUES, num_entries)) == NULL ) 9407 { 9408 DEBUG(0,("_spoolss_enumprinterdataex: talloc() failed to allocate memory for [%lu] bytes!\n", 9409 (unsigned long)num_entries*sizeof(PRINTER_ENUM_VALUES))); 9410 result = WERR_NOMEM; 9411 goto done; 9412 } 9413 9414 memset( enum_values, 0x0, num_entries*sizeof(PRINTER_ENUM_VALUES) ); 9415 } 9416 9417 /* 9418 * loop through all params and build the array to pass 9419 * back to the client 9420 */ 9421 9422 for ( i=0; i<num_entries; i++ ) 9423 { 9424 /* lookup the registry value */ 9425 9426 val = regval_ctr_specific_value( p_data->keys[key_index].values, i ); 9427 DEBUG(10,("retrieved value number [%d] [%s]\n", i, regval_name(val) )); 9428 9429 /* copy the data */ 9430 9431 value_name = regval_name( val ); 9432 init_unistr( &enum_values[i].valuename, value_name ); 9433 enum_values[i].value_len = (strlen(value_name)+1) * 2; 9434 enum_values[i].type = regval_type( val ); 9435 9436 data_len = regval_size( val ); 9437 if ( data_len ) { 9438 if ( !(enum_values[i].data = TALLOC_MEMDUP(p->mem_ctx, regval_data_p(val), data_len)) ) 9439 { 9440 DEBUG(0,("TALLOC_MEMDUP failed to allocate memory [data_len=%d] for data!\n", 9441 data_len )); 9442 result = WERR_NOMEM; 9443 goto done; 9444 } 9445 } 9446 enum_values[i].data_len = data_len; 9447 9448 /* keep track of the size of the array in bytes */ 9449 9450 needed += spoolss_size_printer_enum_values(&enum_values[i]); 9451 } 9452 9453 /* housekeeping information in the reply */ 9454 9455 /* Fix from Martin Zielinski <mz@seh.de> - ensure 9456 * the hand marshalled container size is a multiple 9457 * of 4 bytes for RPC alignment. 9458 */ 9459 9460 if (needed % 4) { 9461 needed += 4-(needed % 4); 9462 } 9463 9464 r_u->needed = needed; 9465 r_u->returned = num_entries; 9466 9467 if (needed > in_size) { 9468 result = WERR_MORE_DATA; 9469 goto done; 9470 } 9471 9472 /* copy data into the reply */ 9473 9474 r_u->ctr.size = r_u->needed; 9475 9476 r_u->ctr.size_of_array = r_u->returned; 9477 r_u->ctr.values = enum_values; 9478 9479 9480 9481done: 9482 if ( printer ) 9483 free_a_printer(&printer, 2); 9484 9485 return result; 9486} 9487 9488/**************************************************************************** 9489****************************************************************************/ 9490 9491static void fill_printprocessordirectory_1(PRINTPROCESSOR_DIRECTORY_1 *info, char *name) 9492{ 9493 init_unistr(&info->name, name); 9494} 9495 9496static WERROR getprintprocessordirectory_level_1(UNISTR2 *name, 9497 UNISTR2 *environment, 9498 RPC_BUFFER *buffer, 9499 uint32 offered, 9500 uint32 *needed) 9501{ 9502 pstring path; 9503 pstring long_archi; 9504 PRINTPROCESSOR_DIRECTORY_1 *info=NULL; 9505 WERROR result = WERR_OK; 9506 9507 unistr2_to_ascii(long_archi, environment, sizeof(long_archi)-1); 9508 9509 if (!get_short_archi(long_archi)) 9510 return WERR_INVALID_ENVIRONMENT; 9511 9512 if((info=SMB_MALLOC_P(PRINTPROCESSOR_DIRECTORY_1)) == NULL) 9513 return WERR_NOMEM; 9514 9515 pstrcpy(path, "C:\\WINNT\\System32\\spool\\PRTPROCS\\W32X86"); 9516 9517 fill_printprocessordirectory_1(info, path); 9518 9519 *needed += spoolss_size_printprocessordirectory_info_1(info); 9520 9521 if (*needed > offered) { 9522 result = WERR_INSUFFICIENT_BUFFER; 9523 goto out; 9524 } 9525 9526 if (!rpcbuf_alloc_size(buffer, *needed)) { 9527 result = WERR_INSUFFICIENT_BUFFER; 9528 goto out; 9529 } 9530 9531 smb_io_printprocessordirectory_1("", buffer, info, 0); 9532 9533out: 9534 SAFE_FREE(info); 9535 9536 return result; 9537} 9538 9539WERROR _spoolss_getprintprocessordirectory(pipes_struct *p, SPOOL_Q_GETPRINTPROCESSORDIRECTORY *q_u, SPOOL_R_GETPRINTPROCESSORDIRECTORY *r_u) 9540{ 9541 uint32 level = q_u->level; 9542 RPC_BUFFER *buffer = NULL; 9543 uint32 offered = q_u->offered; 9544 uint32 *needed = &r_u->needed; 9545 WERROR result; 9546 9547 /* that's an [in out] buffer */ 9548 9549 if (!q_u->buffer && (offered!=0)) { 9550 return WERR_INVALID_PARAM; 9551 } 9552 9553 rpcbuf_move(q_u->buffer, &r_u->buffer); 9554 buffer = r_u->buffer; 9555 9556 DEBUG(5,("_spoolss_getprintprocessordirectory\n")); 9557 9558 *needed=0; 9559 9560 switch(level) { 9561 case 1: 9562 result = getprintprocessordirectory_level_1 9563 (&q_u->name, &q_u->environment, buffer, offered, needed); 9564 break; 9565 default: 9566 result = WERR_UNKNOWN_LEVEL; 9567 } 9568 9569 return result; 9570} 9571 9572/******************************************************************* 9573 Streams the monitor UI DLL name in UNICODE 9574*******************************************************************/ 9575 9576static WERROR xcvtcp_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in, 9577 RPC_BUFFER *out, uint32 *needed ) 9578{ 9579 const char *dllname = "tcpmonui.dll"; 9580 9581 *needed = (strlen(dllname)+1) * 2; 9582 9583 if ( rpcbuf_get_size(out) < *needed ) { 9584 return WERR_INSUFFICIENT_BUFFER; 9585 } 9586 9587 if ( !make_monitorui_buf( out, dllname ) ) { 9588 return WERR_NOMEM; 9589 } 9590 9591 return WERR_OK; 9592} 9593 9594/******************************************************************* 9595 Create a new TCP/IP port 9596*******************************************************************/ 9597 9598static WERROR xcvtcp_addport( NT_USER_TOKEN *token, RPC_BUFFER *in, 9599 RPC_BUFFER *out, uint32 *needed ) 9600{ 9601 NT_PORT_DATA_1 port1; 9602 pstring device_uri; 9603 9604 ZERO_STRUCT( port1 ); 9605 9606 /* convert to our internal port data structure */ 9607 9608 if ( !convert_port_data_1( &port1, in ) ) { 9609 return WERR_NOMEM; 9610 } 9611 9612 /* create the device URI and call the add_port_hook() */ 9613 9614 switch ( port1.protocol ) { 9615 case PORT_PROTOCOL_DIRECT: 9616 pstr_sprintf( device_uri, "socket://%s:%d/", port1.hostaddr, port1.port ); 9617 break; 9618 9619 case PORT_PROTOCOL_LPR: 9620 pstr_sprintf( device_uri, "lpr://%s/%s", port1.hostaddr, port1.queue ); 9621 break; 9622 9623 default: 9624 return WERR_UNKNOWN_PORT; 9625 } 9626 9627 return add_port_hook( token, port1.name, device_uri ); 9628} 9629 9630/******************************************************************* 9631*******************************************************************/ 9632 9633struct xcv_api_table xcvtcp_cmds[] = { 9634 { "MonitorUI", xcvtcp_monitorui }, 9635 { "AddPort", xcvtcp_addport}, 9636 { NULL, NULL } 9637}; 9638 9639static WERROR process_xcvtcp_command( NT_USER_TOKEN *token, const char *command, 9640 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf, 9641 uint32 *needed ) 9642{ 9643 int i; 9644 9645 DEBUG(10,("process_xcvtcp_command: Received command \"%s\"\n", command)); 9646 9647 for ( i=0; xcvtcp_cmds[i].name; i++ ) { 9648 if ( strcmp( command, xcvtcp_cmds[i].name ) == 0 ) 9649 return xcvtcp_cmds[i].fn( token, inbuf, outbuf, needed ); 9650 } 9651 9652 return WERR_BADFUNC; 9653} 9654 9655/******************************************************************* 9656*******************************************************************/ 9657#if 0 /* don't support management using the "Local Port" monitor */ 9658 9659static WERROR xcvlocal_monitorui( NT_USER_TOKEN *token, RPC_BUFFER *in, 9660 RPC_BUFFER *out, uint32 *needed ) 9661{ 9662 const char *dllname = "localui.dll"; 9663 9664 *needed = (strlen(dllname)+1) * 2; 9665 9666 if ( rpcbuf_get_size(out) < *needed ) { 9667 return WERR_INSUFFICIENT_BUFFER; 9668 } 9669 9670 if ( !make_monitorui_buf( out, dllname )) { 9671 return WERR_NOMEM; 9672 } 9673 9674 return WERR_OK; 9675} 9676 9677/******************************************************************* 9678*******************************************************************/ 9679 9680struct xcv_api_table xcvlocal_cmds[] = { 9681 { "MonitorUI", xcvlocal_monitorui }, 9682 { NULL, NULL } 9683}; 9684#else 9685struct xcv_api_table xcvlocal_cmds[] = { 9686 { NULL, NULL } 9687}; 9688#endif 9689 9690 9691 9692/******************************************************************* 9693*******************************************************************/ 9694 9695static WERROR process_xcvlocal_command( NT_USER_TOKEN *token, const char *command, 9696 RPC_BUFFER *inbuf, RPC_BUFFER *outbuf, 9697 uint32 *needed ) 9698{ 9699 int i; 9700 9701 DEBUG(10,("process_xcvlocal_command: Received command \"%s\"\n", command)); 9702 9703 for ( i=0; xcvlocal_cmds[i].name; i++ ) { 9704 if ( strcmp( command, xcvlocal_cmds[i].name ) == 0 ) 9705 return xcvlocal_cmds[i].fn( token, inbuf, outbuf , needed ); 9706 } 9707 return WERR_BADFUNC; 9708} 9709 9710/******************************************************************* 9711*******************************************************************/ 9712 9713WERROR _spoolss_xcvdataport(pipes_struct *p, SPOOL_Q_XCVDATAPORT *q_u, SPOOL_R_XCVDATAPORT *r_u) 9714{ 9715 Printer_entry *Printer = find_printer_index_by_hnd(p, &q_u->handle); 9716 fstring command; 9717 9718 if (!Printer) { 9719 DEBUG(2,("_spoolss_xcvdataport: Invalid handle (%s:%u:%u).\n", OUR_HANDLE(&q_u->handle))); 9720 return WERR_BADFID; 9721 } 9722 9723 /* Has to be a handle to the TCP/IP port monitor */ 9724 9725 if ( !(Printer->printer_type & (SPLHND_PORTMON_LOCAL|SPLHND_PORTMON_TCP)) ) { 9726 DEBUG(2,("_spoolss_xcvdataport: Call only valid for Port Monitors\n")); 9727 return WERR_BADFID; 9728 } 9729 9730 /* requires administrative access to the server */ 9731 9732 if ( !(Printer->access_granted & SERVER_ACCESS_ADMINISTER) ) { 9733 DEBUG(2,("_spoolss_xcvdataport: denied by handle permissions.\n")); 9734 return WERR_ACCESS_DENIED; 9735 } 9736 9737 /* Get the command name. There's numerous commands supported by the 9738 TCPMON interface. */ 9739 9740 rpcstr_pull(command, q_u->dataname.buffer, sizeof(command), 9741 q_u->dataname.uni_str_len*2, 0); 9742 9743 /* Allocate the outgoing buffer */ 9744 9745 rpcbuf_init( &r_u->outdata, q_u->offered, p->mem_ctx ); 9746 9747 switch ( Printer->printer_type ) { 9748 case SPLHND_PORTMON_TCP: 9749 return process_xcvtcp_command( p->pipe_user.nt_user_token, command, 9750 &q_u->indata, &r_u->outdata, &r_u->needed ); 9751 case SPLHND_PORTMON_LOCAL: 9752 return process_xcvlocal_command( p->pipe_user.nt_user_token, command, 9753 &q_u->indata, &r_u->outdata, &r_u->needed ); 9754 } 9755 9756 return WERR_INVALID_PRINT_MONITOR; 9757} 9758 9759 9760