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