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