From 7c7d796b6d292a7c98b099ad1e1adbc4f2363512 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 25 Feb 2003 20:51:23 +0000 Subject: Progress on CR 601 cache the printer_info_2 with the open printer handle. cache is invalidated on a mod_a_printer() call **on that smbd**. Yes, this means that the window for admins to step on each other from different clients just got larger, but since handles a generally short lived this is probably ok. (This used to be commit 33c7b7522504fb15989f32add8e9a087c8d9d0fa) --- source3/include/nt_printing.h | 45 +++++ source3/printing/nt_printing.c | 366 +++++++++++++++++++++--------------- source3/registry/reg_printing.c | 7 +- source3/rpc_parse/parse_spoolss.c | 2 +- source3/rpc_server/srv_spoolss_nt.c | 277 ++++++++++++--------------- source3/smbd/lanman.c | 6 +- 6 files changed, 388 insertions(+), 315 deletions(-) diff --git a/source3/include/nt_printing.h b/source3/include/nt_printing.h index 6d952a89a5..ca65a40d48 100644 --- a/source3/include/nt_printing.h +++ b/source3/include/nt_printing.h @@ -434,4 +434,49 @@ typedef struct { SPOOLSS_NOTIFY_MSG_GROUP *msg_groups; } SPOOLSS_NOTIFY_MSG_CTR; +#define PRINTER_HANDLE_IS_PRINTER 0 +#define PRINTER_HANDLE_IS_PRINTSERVER 1 + +/* structure to store the printer handles */ +/* and a reference to what it's pointing to */ +/* and the notify info asked about */ +/* that's the central struct */ +typedef struct _Printer{ + struct _Printer *prev, *next; + BOOL document_started; + BOOL page_started; + uint32 jobid; /* jobid in printing backend */ + BOOL printer_type; + TALLOC_CTX *ctx; + union { + fstring handlename; + fstring printerservername; + } dev; + uint32 type; + uint32 access_granted; + struct { + uint32 flags; + uint32 options; + fstring localmachine; + uint32 printerlocal; + SPOOL_NOTIFY_OPTION *option; + POLICY_HND client_hnd; + BOOL client_connected; + uint32 change; + /* are we in a FindNextPrinterChangeNotify() call? */ + BOOL fnpcn; + } notify; + struct { + fstring machine; + fstring user; + } client; + + /* devmode sent in the OpenPrinter() call */ + NT_DEVICEMODE *nt_devmode; + + /* cache the printer info */ + NT_PRINTER_INFO_LEVEL *printer_info; + +} Printer_entry; + #endif /* NT_PRINTING_H_ */ diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 836324ecc9..0f5067c5a0 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -3,7 +3,7 @@ * RPC Pipe client / server routines * Copyright (C) Andrew Tridgell 1992-2000, * Copyright (C) Jean François Micouleau 1998-2000. - * Copyright (C) Gerald Carter 2002. + * Copyright (C) Gerald Carter 2002-2003. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -565,8 +565,9 @@ BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count) } /**************************************************************************** - delete a named form struct + Delete a named form struct. ****************************************************************************/ + BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret) { pstring key; @@ -603,8 +604,9 @@ BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR } /**************************************************************************** -update a form struct + Update a form struct. ****************************************************************************/ + void update_a_form(nt_forms_struct **list, const FORM *form, int count) { int n=0; @@ -612,8 +614,7 @@ void update_a_form(nt_forms_struct **list, const FORM *form, int count) unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1); DEBUG(106, ("[%s]\n", form_name)); - for (n=0; ndevicename, @@ -1937,15 +1940,13 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen) /* loop over all keys */ - for ( i=0; inum_keys; i++ ) - { + for ( i=0; inum_keys; i++ ) { val_ctr = &data->keys[i].values; num_values = regval_ctr_numvals( val_ctr ); /* loop over all values */ - for ( j=0; j\ */ val = regval_ctr_specific_value( val_ctr, j ); @@ -1991,7 +1992,7 @@ uint32 del_a_printer(char *sharename) } /* FIXME!!! Reorder so this forward declaration is not necessary --jerry */ -static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring); +static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, const char* sharename); static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **); /**************************************************************************** ****************************************************************************/ @@ -2169,6 +2170,9 @@ NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode) { NT_DEVICEMODE *new_nt_devicemode = NULL; + if ( !nt_devicemode ) + return NULL; + if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) { DEBUG(0,("dup_nt_devicemode: malloc fail.\n")); return NULL; @@ -2222,8 +2226,7 @@ static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr) /* clean up all registry keys */ data = &info->data; - for ( i=0; inum_keys; i++ ) - { + for ( i=0; inum_keys; i++ ) { SAFE_FREE( data->keys[i].name ); regval_ctr_destroy( &data->keys[i].values ); } @@ -2311,8 +2314,8 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen) } /**************************************************************************** - allocate and initialize a new slot in - ***************************************************************************/ + Allocate and initialize a new slot. +***************************************************************************/ static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name ) { @@ -2360,8 +2363,7 @@ int lookup_printerkey( NT_PRINTER_DATA *data, const char *name ) /* loop over all existing keys */ - for ( i=0; inum_keys; i++ ) - { + for ( i=0; inum_keys; i++ ) { if ( strequal(data->keys[i].name, name) ) { DEBUG(12,("lookup_printerkey: Found [%s]!\n", name)); key_index = i; @@ -2388,10 +2390,8 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su if ( !data ) return 0; - for ( i=0; inum_keys; i++ ) - { - if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) - { + for ( i=0; inum_keys; i++ ) { + if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) { /* match sure it is a subkey and not the key itself */ key_len = strlen( key ); @@ -2436,7 +2436,7 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su /* tag of the end */ if (num_subkeys) - fstrcpy( subkeys_ptr[num_subkeys], "" ); + fstrcpy(subkeys_ptr[num_subkeys], "" ); *subkeys = subkeys_ptr; @@ -2692,12 +2692,12 @@ WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer) * @return WERROR indicating status of publishing ***************************************************************************/ -WERROR nt_printer_publish(int snum, int action) +WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) { NT_PRINTER_INFO_LEVEL *printer = NULL; WERROR win_rc; - win_rc = get_a_printer(&printer, 2, lp_servicename(snum)); + win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); if (!W_ERROR_IS_OK(win_rc)) return win_rc; @@ -2718,7 +2718,7 @@ WERROR nt_printer_publish(int snum, int action) return win_rc; } -BOOL is_printer_published(int snum, GUID *guid) +BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid) { NT_PRINTER_INFO_LEVEL *printer = NULL; REGVAL_CTR *ctr; @@ -2727,7 +2727,7 @@ BOOL is_printer_published(int snum, GUID *guid) int i; - win_rc = get_a_printer(&printer, 2, lp_servicename(snum)); + win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum)); if (!W_ERROR_IS_OK(win_rc)) return False; @@ -2753,11 +2753,11 @@ BOOL is_printer_published(int snum, GUID *guid) } #else -WERROR nt_printer_publish(int snum, int action) +WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action) { return WERR_OK; } -BOOL is_printer_published(int snum, GUID *guid) +BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid) { return False; } @@ -2780,10 +2780,8 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key ) /* remove all keys */ - if ( !strlen(key) ) - { - for ( i=0; inum_keys; i++ ) - { + if ( !strlen(key) ) { + for ( i=0; inum_keys; i++ ) { DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n", data->keys[i].name)); @@ -2802,10 +2800,8 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key ) /* remove a specific key (and all subkeys) */ - for ( i=0; inum_keys; i++ ) - { - if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) - { + for ( i=0; inum_keys; i++ ) { + if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) { DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n", data->keys[i].name)); @@ -2849,8 +2845,7 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key ) /* sanity check to see if anything is left */ - if ( !data->num_keys ) - { + if ( !data->num_keys ) { DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername )); SAFE_FREE( data->keys ); @@ -2956,8 +2951,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen) /* loop and unpack the rest of the registry values */ - while ( True ) - { + while ( True ) { /* check to see if there are any more registry values */ @@ -3007,7 +3001,8 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen) regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, data_p, size ); - SAFE_FREE(data_p); /* 'B' option to tdb_unpack does a malloc() */ + SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */ + DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size)); } @@ -3099,9 +3094,9 @@ static void map_to_os2_driver(fstring drivername) } /**************************************************************************** -get a default printer info 2 struct + Get a default printer info 2 struct. ****************************************************************************/ -static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename) +static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename) { int snum; NT_PRINTER_INFO_LEVEL_2 info; @@ -3180,7 +3175,7 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin /**************************************************************************** ****************************************************************************/ -static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename) +static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename) { pstring key; NT_PRINTER_INFO_LEVEL_2 info; @@ -3270,7 +3265,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen } /**************************************************************************** -debugging function, dump at level 6 the struct in the logs + Debugging function, dump at level 6 the struct in the logs. ****************************************************************************/ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) { @@ -3279,8 +3274,7 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) DEBUG(106,("Dumping printer at level [%d]\n", level)); - switch (level) - { + switch (level) { case 2: { if (printer.info_2 == NULL) @@ -3325,26 +3319,6 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) return result; } -/**************************************************************************** - Get the parameters we can substitute in an NT print job. -****************************************************************************/ - -void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname) -{ - NT_PRINTER_INFO_LEVEL *printer = NULL; - - **printername = **sharename = **portname = '\0'; - - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum)))) - return; - - fstrcpy(*printername, printer->info_2->printername); - fstrcpy(*sharename, printer->info_2->sharename); - fstrcpy(*portname, printer->info_2->portname); - - free_a_printer(&printer, 2); -} - /**************************************************************************** Update the changeid time. This is SO NASTY as some drivers need this to change, others need it @@ -3388,8 +3362,15 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) dump_a_printer(printer, level); - switch (level) - { + /* + * invalidate cache for all open handles to this printer. + * cache for a given handle will be updated on the next + * get_a_printer() + */ + + invalidate_printer_hnd_cache( printer.info_2->sharename ); + + switch (level) { case 2: { /* @@ -3424,6 +3405,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level) */ result=update_a_printer_2(printer.info_2); + break; } default: @@ -3528,8 +3510,7 @@ BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) { BOOL result = False; - switch (level) - { + switch (level) { case 2: result = set_driver_init_2(printer->info_2); break; @@ -3600,7 +3581,8 @@ static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info) ret = -1; goto done; } - else buf = tb; + else + buf = tb; buflen = len; goto again; } @@ -3636,13 +3618,10 @@ uint32 update_driver_init(NT_PRINTER_INFO_LEVEL printer, uint32 level) dump_a_printer(printer, level); - switch (level) - { + switch (level) { case 2: - { result = update_driver_init_2(printer.info_2); break; - } default: result = 1; break; @@ -3711,8 +3690,7 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui */ DEBUG(8,("save_driver_init_2: Enter...\n")); - if ( !printer->info_2->devmode && data_len ) - { + if ( !printer->info_2->devmode && data_len ) { /* * Set devmode on printer info, so entire printer initialization can be * saved to tdb. @@ -3781,13 +3759,10 @@ WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *dat { WERROR status = WERR_OK; - switch (level) - { + switch (level) { case 2: - { status = save_driver_init_2( printer, data, data_len ); break; - } default: status = WERR_UNKNOWN_LEVEL; break; @@ -3796,11 +3771,80 @@ WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *dat return status; } +/**************************************************************************** + Deep copy a NT_PRINTER_DATA +****************************************************************************/ + +static NTSTATUS copy_printer_data( NT_PRINTER_DATA *dst, NT_PRINTER_DATA *src ) +{ + int i, j, num_vals, new_key_index; + REGVAL_CTR *src_key, *dst_key; + + if ( !dst || !src ) + return NT_STATUS_NO_MEMORY; + + for ( i=0; inum_keys; i++ ) { + + /* create a new instance of the printerkey in the destination + printer_data object */ + + new_key_index = add_new_printer_key( dst, src->keys[i].name ); + dst_key = &dst->keys[new_key_index].values; + + src_key = &src->keys[i].values; + num_vals = regval_ctr_numvals( src_key ); + + /* dup the printer entire printer key */ + + for ( j=0; jdevmode = dup_nt_devicemode( printer->devmode ); + + ZERO_STRUCT( copy->data ); + copy_printer_data( ©->data, &printer->data ); + + /* this is talloc()'d; very ugly that we have a structure that + is half malloc()'d and half talloc()'d but that is the way + that the PRINTER_INFO stuff is written right now. --jerry */ + + copy->secdesc_buf = dup_sec_desc_buf( ctx, printer->secdesc_buf ); + + return copy; +} + /**************************************************************************** Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory. ****************************************************************************/ -WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename) +#define ENABLE_PRINT_HND_CACHE 1 + +WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, + const char *sharename) { WERROR result; NT_PRINTER_INFO_LEVEL *printer = NULL; @@ -3809,24 +3853,70 @@ WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring s DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level)); - switch (level) - { + switch (level) { case 2: - { if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) { DEBUG(0,("get_a_printer: malloc fail.\n")); return WERR_NOMEM; } ZERO_STRUCTP(printer); + + /* + * check for cache first. A Printer handle cannot changed + * to another printer object so we only check that the printer + * is actually for a printer and that the printer_info pointer + * is valid + */ +#ifdef ENABLE_PRINT_HND_CACHE /* JERRY */ + if ( print_hnd + && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER) + && print_hnd->printer_info ) + { + if ( !(printer->info_2 = dup_printer_2(print_hnd->ctx, print_hnd->printer_info->info_2)) ) { + DEBUG(0,("get_a_printer: unable to copy cached printer info!\n")); + + SAFE_FREE(printer); + return WERR_NOMEM; + } + + DEBUG(10,("get_a_printer: using cached copy of printer_info_2\n")); + + *pp_printer = printer; + result = WERR_OK; + + break; + } +#endif + + /* no cache; look it up on disk */ + result=get_a_printer_2(&printer->info_2, sharename); if (W_ERROR_IS_OK(result)) { dump_a_printer(*printer, level); + +#if ENABLE_PRINT_HND_CACHE /* JERRY */ + /* save a copy in cache */ + if ( print_hnd && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)) { + if ( !print_hnd->printer_info ) + print_hnd->printer_info = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL)); + + if ( print_hnd->printer_info ) { + print_hnd->printer_info->info_2 = dup_printer_2(print_hnd->ctx, printer->info_2); + + /* don't fail the lookup just because the cache update failed */ + if ( !print_hnd->printer_info->info_2 ) + DEBUG(0,("get_a_printer: unable to copy new printer info!\n")); + } + + } +#endif *pp_printer = printer; - } else { - SAFE_FREE(printer); } + else + SAFE_FREE(printer); + + break; - } default: result=WERR_UNKNOWN_LEVEL; break; @@ -3851,21 +3941,15 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level) if (printer == NULL) return 0; - switch (level) - { + switch (level) { case 2: - { - if (printer->info_2 != NULL) - { + if (printer->info_2 != NULL) { free_nt_printer_info_level_2(&printer->info_2); result=0; - } - else - { + } else result=4; - } break; - } + default: result=1; break; @@ -3883,19 +3967,15 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) DEBUG(104,("adding a printer at level [%d]\n", level)); dump_a_printer_driver(driver, level); - switch (level) - { + switch (level) { case 3: - { result=add_a_printer_driver_3(driver.info_3); break; - } case 6: - { result=add_a_printer_driver_6(driver.info_6); break; - } + default: result=1; break; @@ -3905,13 +3985,13 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) } /**************************************************************************** ****************************************************************************/ + WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, fstring drivername, const char *architecture, uint32 version) { WERROR result; - switch (level) - { + switch (level) { case 3: /* Sometime we just want any version of the driver */ @@ -3924,8 +4004,7 @@ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, result = get_a_printer_driver_3( &driver->info_3, drivername, architecture, 2 ); } - } - else { + } else { result = get_a_printer_driver_3(&driver->info_3, drivername, architecture, version); } @@ -3948,8 +4027,7 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) { uint32 result; - switch (level) - { + switch (level) { case 3: { NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3; @@ -3960,9 +4038,7 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) ZERO_STRUCTP(info3); SAFE_FREE(info3); result=0; - } - else - { + } else { result=4; } break; @@ -3970,17 +4046,14 @@ uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) case 6: { NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6; - if (driver.info_6 != NULL) - { + if (driver.info_6 != NULL) { info6=driver.info_6; SAFE_FREE(info6->dependentfiles); SAFE_FREE(info6->previousnames); ZERO_STRUCTP(info6); SAFE_FREE(info6); result=0; - } - else - { + } else { result=4; } break; @@ -4011,12 +4084,11 @@ BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 ) /* loop through the printers.tdb and check for the drivername */ - for (snum=0; snumname, printer->info_2->drivername) ) { @@ -4063,11 +4135,9 @@ static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) if ( !info->dependentfiles ) return False; - while ( *info->dependentfiles[i] ) - { + while ( *info->dependentfiles[i] ) { if ( strequal(file, info->dependentfiles[i]) ) return True; - i++; } @@ -4085,8 +4155,7 @@ static void trim_dependent_file( fstring files[], int idx ) /* bump everything down a slot */ - while( *files[idx+1] ) - { + while( *files[idx+1] ) { fstrcpy( files[idx], files[idx+1] ); idx++; } @@ -4140,14 +4209,12 @@ static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, if ( !src->dependentfiles ) return in_use; - while ( *src->dependentfiles[i] ) - { + while ( *src->dependentfiles[i] ) { if ( drv_file_in_use(src->dependentfiles[i], drv) ) { in_use = True; DEBUG(10,("Removing [%s] from dependent file list\n", src->dependentfiles[i])); trim_dependent_file( src->dependentfiles, i ); - } - else + } else i++; } @@ -4192,15 +4259,12 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) /* check each driver for overlap in files */ - for (i=0; ienvironment, version)) ) - { + if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], info->environment, version)) ) { SAFE_FREE(list); return True; } @@ -4208,8 +4272,7 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ) /* check if d2 uses any files from d1 */ /* only if this is a different driver than the one being deleted */ - if ( !strequal(info->name, driver.info_3->name) ) - { + if ( !strequal(info->name, driver.info_3->name) ) { if ( trim_overlap_drv_files(info, driver.info_3) ) { free_a_printer_driver(driver, 3); SAFE_FREE( list ); @@ -4307,15 +4370,13 @@ static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct /* check if we are done removing files */ - if ( info_3->dependentfiles ) - { + if ( info_3->dependentfiles ) { while ( *info_3->dependentfiles[i] ) { char *file; /* bypass the "\print$" portion of the path */ - if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) - { + if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) { DEBUG(10,("deleting dependent file [%s]\n", file)); unlink_internals(conn, 0, file ); } @@ -4560,8 +4621,9 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF * fstring key; char *temp; - if (strlen(printername) > 2 && (temp = strchr(printername + 2, '\\'))) + if (strlen(printername) > 2 && (temp = strchr(printername + 2, '\\'))) { printername = temp + 1; + } /* Fetch security descriptor from tdb */ @@ -4803,7 +4865,7 @@ BOOL print_time_access_check(int snum) struct tm *t; uint32 mins; - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum)))) return False; if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0) diff --git a/source3/registry/reg_printing.c b/source3/registry/reg_printing.c index 4b8eaa658e..619ffc7ee7 100644 --- a/source3/registry/reg_printing.c +++ b/source3/registry/reg_printing.c @@ -497,7 +497,7 @@ static int print_subpath_printers( char *key, REGSUBKEY_CTR *subkeys ) keystr = key2; reg_split_path( keystr, &base, &new_path ); - if ( !W_ERROR_IS_OK( get_a_printer(&printer, 2, base) ) ) + if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, base) ) ) goto done; num_subkeys = get_printer_subkeys( &printer->info_2->data, new_path?new_path:"", &subkey_names ); @@ -557,7 +557,7 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val ) { /* we are dealing with the printer itself */ - if ( !W_ERROR_IS_OK( get_a_printer(&printer, 2, printername) ) ) + if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) goto done; info2 = printer->info_2; @@ -628,7 +628,6 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val ) } } - prs_mem_free( &prs ); num_values = regval_ctr_numvals( val ); @@ -639,7 +638,7 @@ static int print_subpath_values_printers( char *key, REGVAL_CTR *val ) /* now enumerate the key */ - if ( !W_ERROR_IS_OK( get_a_printer(&printer, 2, printername) ) ) + if ( !W_ERROR_IS_OK( get_a_printer(NULL, &printer, 2, printername) ) ) goto done; /* iterate over all printer data and fill the regval container */ diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c index fb2aaf71ec..a34740f9ff 100644 --- a/source3/rpc_parse/parse_spoolss.c +++ b/source3/rpc_parse/parse_spoolss.c @@ -1372,7 +1372,7 @@ BOOL spoolss_io_r_getprinterdata(const char *desc, SPOOL_R_GETPRINTERDATA *r_u, return False; } - if (!prs_uint8s( r_u->type&(REG_SZ|REG_MULTI_SZ), "data", ps, depth, r_u->data, r_u->size )) + if (!prs_uint8s( False, "data", ps, depth, r_u->data, r_u->size )) return False; if (!prs_align(ps)) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 93566c2bb7..fa9b8eaeff 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -5,7 +5,7 @@ * Copyright (C) Luke Kenneth Casson Leighton 1996-2000, * Copyright (C) Jean François Micouleau 1998-2000, * Copyright (C) Jeremy Allison 2001-2002, - * Copyright (C) Gerald Carter 2000-2002, + * Copyright (C) Gerald Carter 2000-2003, * Copyright (C) Tim Potter 2001-2002. * * This program is free software; you can redistribute it and/or modify @@ -37,8 +37,7 @@ #define MAGIC_DISPLAY_FREQUENCY 0xfade2bad #define PHANTOM_DEVMODE_KEY "_p_f_a_n_t_0_m_" -#define PRINTER_HANDLE_IS_PRINTER 0 -#define PRINTER_HANDLE_IS_PRINTSERVER 1 + /* Table to map the driver version */ /* to OS */ @@ -55,46 +54,6 @@ struct table_node { int version; }; - -/* structure to store the printer handles */ -/* and a reference to what it's pointing to */ -/* and the notify info asked about */ -/* that's the central struct */ -typedef struct _Printer{ - struct _Printer *prev, *next; - BOOL document_started; - BOOL page_started; - uint32 jobid; /* jobid in printing backend */ - BOOL printer_type; - union { - fstring handlename; - fstring printerservername; - } dev; - uint32 type; - uint32 access_granted; - struct { - uint32 flags; - uint32 options; - fstring localmachine; - uint32 printerlocal; - SPOOL_NOTIFY_OPTION *option; - POLICY_HND client_hnd; - BOOL client_connected; - uint32 change; - /* are we in a FindNextPrinterChangeNotify() call? */ - BOOL fnpcn; - } notify; - struct { - fstring machine; - fstring user; - } client; - - /* devmode sent in the OpenPrinter() call */ - NT_DEVICEMODE *nt_devmode; - - -} Printer_entry; - static Printer_entry *printers_list; typedef struct _counter_printer_0 { @@ -251,6 +210,9 @@ static void free_printer_entry(void *ptr) Printer->notify.client_connected=False; free_nt_devicemode( &Printer->nt_devmode ); + free_a_printer( &Printer->printer_info, 2 ); + + talloc_destroy( Printer->ctx ); /* Remove from the internal list. */ DLIST_REMOVE(printers_list, Printer); @@ -303,6 +265,29 @@ static Printer_entry *find_printer_index_by_hnd(pipes_struct *p, POLICY_HND *hnd return find_printer; } +/**************************************************************************** + find printer index by handle +****************************************************************************/ + +void invalidate_printer_hnd_cache( char *printername ) +{ + Printer_entry *p; + + DEBUG(10,("invalidate_printer_hnd_cache: printer [%s]\n", printername)); + + for ( p=printers_list; p; p=p->next ) + { + if ( p->printer_type==PRINTER_HANDLE_IS_PRINTER + && StrCaseCmp(p->dev.handlename, printername)==0) + { + DEBUG(10,("invalidating printer_info cache for handl:\n")); + free_a_printer( &p->printer_info, 2 ); + p->printer_info = NULL; + } + } + + return; +} /**************************************************************************** Close printer index by handle. ****************************************************************************/ @@ -534,6 +519,11 @@ static BOOL open_printer_hnd(pipes_struct *p, POLICY_HND *hnd, char *name, uint3 ZERO_STRUCTP(new_printer); + if ( !(new_printer->ctx = talloc_init("Printer Entry [0x%x]", (uint32)hnd)) ) { + DEBUG(0,("open_printer_hnd: talloc_init() failed!\n")); + return False; + } + new_printer->notify.option=NULL; /* Add to the internal list. */ @@ -861,8 +851,7 @@ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MS /* add a new group? */ - if ( i == ctr->num_groups ) - { + if ( i == ctr->num_groups ) { ctr->num_groups++; if ( !(groups = talloc_realloc( ctr->ctx, ctr->msg_groups, sizeof(SPOOLSS_NOTIFY_MSG_GROUP)*ctr->num_groups)) ) { @@ -929,8 +918,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) /* loop over all printers */ - for (p = printers_list; p; p = p->next) - { + for (p = printers_list; p; p = p->next) { SPOOL_NOTIFY_INFO_DATA *data; uint32 data_len = 0; uint32 id; @@ -961,8 +949,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) /* build the array of change notifications */ - for ( i=0; inum_msgs; i++ ) - { + for ( i=0; inum_msgs; i++ ) { SPOOLSS_NOTIFY_MSG *msg = &messages[i]; /* Are we monitoring this event? */ @@ -995,8 +982,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) /* Convert unix jobid to smb jobid */ - if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) - { + if (msg->flags & SPOOLSS_NOTIFY_MSG_UNIX_JOBID) { id = sysjob_to_jobid(msg->id); if (id == -1) { @@ -1204,7 +1190,7 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len) WERROR result; NT_PRINTER_INFO_LEVEL *printer = NULL; - result = get_a_printer(&printer, 2, lp_servicename(snum)); + result = get_a_printer(NULL, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(result)) continue; @@ -1300,7 +1286,7 @@ void reset_all_printerdata(int msg_type, pid_t src, void *buf, size_t len) WERROR result; NT_PRINTER_INFO_LEVEL *printer = NULL; - result = get_a_printer( &printer, 2, lp_servicename(snum) ); + result = get_a_printer( NULL, &printer, 2, lp_const_servicename(snum) ); if ( !W_ERROR_IS_OK(result) ) continue; @@ -2157,9 +2143,7 @@ static WERROR get_printer_dataex( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL *printe static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value ) { - delete_printer_data( printer->info_2, key, value ); - - return mod_a_printer(*printer, 2); + return delete_printer_data( printer->info_2, key, value ); } /**************************************************************************** @@ -2171,9 +2155,7 @@ static WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *ke { delete_printer_data( printer->info_2, key, value ); - add_printer_data( printer->info_2, key, value, type, data, real_len ); - - return mod_a_printer(*printer, 2); + return add_printer_data( printer->info_2, key, value, type, data, real_len ); } /******************************************************************** @@ -2349,7 +2331,7 @@ WERROR _spoolss_getprinterdata(pipes_struct *p, SPOOL_Q_GETPRINTERDATA *q_u, SPO goto done; } - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); if ( !W_ERROR_IS_OK(status) ) goto done; @@ -3443,7 +3425,7 @@ void construct_info_data(SPOOL_NOTIFY_INFO_DATA *info_data, uint16 type, uint16 * ********************************************************************/ -static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int +static BOOL construct_notify_printer_info(Printer_entry *print_hnd, SPOOL_NOTIFY_INFO *info, int snum, SPOOL_NOTIFY_OPTION_TYPE *option_type, uint32 id, TALLOC_CTX *mem_ctx) @@ -3462,11 +3444,10 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int (option_type->type==PRINTER_NOTIFY_TYPE?"PRINTER_NOTIFY_TYPE":"JOB_NOTIFY_TYPE"), option_type->count, lp_servicename(snum))); - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum)))) return False; - for(field_num=0; field_numcount; field_num++) - { + for(field_num=0; field_numcount; field_num++) { field = option_type->fields[field_num]; DEBUG(4,("construct_notify_printer_info: notify [%d]: type [%x], field [%x]\n", field_num, type, field)); @@ -3474,12 +3455,10 @@ static BOOL construct_notify_printer_info(SPOOL_NOTIFY_INFO *info, int if (!search_notify(type, field, &j) ) continue; - if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) - { + if((tid=(SPOOL_NOTIFY_INFO_DATA *)Realloc(info->data, (info->count+1)*sizeof(SPOOL_NOTIFY_INFO_DATA))) == NULL) { DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n")); return False; - } - else + } else info->data = tid; current_data = &info->data[info->count]; @@ -3611,7 +3590,7 @@ static WERROR printserver_notify_info(pipes_struct *p, POLICY_HND *hnd, for (snum=0; snumtype ) { case PRINTER_NOTIFY_TYPE: - if(construct_notify_printer_info(info, snum, + if(construct_notify_printer_info(Printer, info, snum, option_type, id, mem_ctx)) id--; @@ -3682,8 +3661,7 @@ static WERROR printer_notify_info(pipes_struct *p, POLICY_HND *hnd, SPOOL_NOTIFY count = print_queue_status(snum, &queue, &status); - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, - lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)))) goto done; for (j=0; jflags=flags; @@ -3997,7 +3975,7 @@ DEVICEMODE *construct_dev_mode(int snum) DEBUGADD(8,("getting printer characteristics\n")); - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum)))) return NULL; if ( !printer->info_2->devmode ) { @@ -4030,14 +4008,14 @@ done: * fill a printer_info_2 struct ********************************************************************/ -static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum) +static BOOL construct_printer_info_2(Printer_entry *print_hnd, PRINTER_INFO_2 *printer, int snum) { int count; NT_PRINTER_INFO_LEVEL *ntprinter = NULL; print_status_struct status; - if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; count = print_queue_length(snum, &status); @@ -4093,12 +4071,12 @@ static BOOL construct_printer_info_2(PRINTER_INFO_2 *printer, int snum) * fill a printer_info_3 struct ********************************************************************/ -static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum) +static BOOL construct_printer_info_3(Printer_entry *print_hnd, PRINTER_INFO_3 **pp_printer, int snum) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; PRINTER_INFO_3 *printer = NULL; - if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; *pp_printer = NULL; @@ -4148,11 +4126,11 @@ static BOOL construct_printer_info_3(PRINTER_INFO_3 **pp_printer, int snum) * fill a printer_info_4 struct ********************************************************************/ -static BOOL construct_printer_info_4(PRINTER_INFO_4 *printer, int snum) +static BOOL construct_printer_info_4(Printer_entry *print_hnd, PRINTER_INFO_4 *printer, int snum) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; init_unistr(&printer->printername, ntprinter->info_2->printername); /* printername*/ @@ -4168,11 +4146,11 @@ static BOOL construct_printer_info_4(PRINTER_INFO_4 *printer, int snum) * fill a printer_info_5 struct ********************************************************************/ -static BOOL construct_printer_info_5(PRINTER_INFO_5 *printer, int snum) +static BOOL construct_printer_info_5(Printer_entry *print_hnd, PRINTER_INFO_5 *printer, int snum) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - if (!W_ERROR_IS_OK(get_a_printer(&ntprinter, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &ntprinter, 2, lp_const_servicename(snum)))) return False; init_unistr(&printer->printername, ntprinter->info_2->printername); @@ -4194,12 +4172,12 @@ static BOOL construct_printer_info_5(PRINTER_INFO_5 *printer, int snum) * fill a printer_info_7 struct ********************************************************************/ -static BOOL construct_printer_info_7(PRINTER_INFO_7 *printer, int snum) +static BOOL construct_printer_info_7(Printer_entry *print_hnd, PRINTER_INFO_7 *printer, int snum) { char *guid_str = NULL; GUID guid; - if (is_printer_published(snum, &guid)) { + if (is_printer_published(print_hnd, snum, &guid)) { asprintf(&guid_str, "{%s}", uuid_string_static(guid)); strupper(guid_str); init_unistr(&printer->guid, guid_str); @@ -4230,7 +4208,7 @@ static WERROR enum_all_printers_info_1(uint32 flags, NEW_BUFFER *buffer, uint32 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - if (construct_printer_info_1(flags, ¤t_prt, snum)) { + if (construct_printer_info_1(NULL, flags, ¤t_prt, snum)) { if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_1))) == NULL) { DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n")); SAFE_FREE(printers); @@ -4399,7 +4377,7 @@ static WERROR enum_all_printers_info_2(NEW_BUFFER *buffer, uint32 offered, uint3 if (lp_browseable(snum) && lp_snum_ok(snum) && lp_print_ok(snum) ) { DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - if (construct_printer_info_2(¤t_prt, snum)) { + if (construct_printer_info_2(NULL, ¤t_prt, snum)) { if((tp=Realloc(printers, (*returned +1)*sizeof(PRINTER_INFO_2))) == NULL) { DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n")); SAFE_FREE(printers); @@ -4570,14 +4548,14 @@ WERROR _spoolss_enumprinters( pipes_struct *p, SPOOL_Q_ENUMPRINTERS *q_u, SPOOL_ /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_0(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_0 *printer=NULL; if((printer=(PRINTER_INFO_0*)malloc(sizeof(PRINTER_INFO_0))) == NULL) return WERR_NOMEM; - construct_printer_info_0(printer, snum); + construct_printer_info_0(print_hnd, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_0(printer); @@ -4603,14 +4581,14 @@ static WERROR getprinter_level_0(int snum, NEW_BUFFER *buffer, uint32 offered, u /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_1(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_1 *printer=NULL; if((printer=(PRINTER_INFO_1*)malloc(sizeof(PRINTER_INFO_1))) == NULL) return WERR_NOMEM; - construct_printer_info_1(PRINTER_ENUM_ICON8, printer, snum); + construct_printer_info_1(print_hnd, PRINTER_ENUM_ICON8, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_1(printer); @@ -4636,14 +4614,14 @@ static WERROR getprinter_level_1(int snum, NEW_BUFFER *buffer, uint32 offered, u /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_2(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_2 *printer=NULL; if((printer=(PRINTER_INFO_2*)malloc(sizeof(PRINTER_INFO_2)))==NULL) return WERR_NOMEM; - construct_printer_info_2(printer, snum); + construct_printer_info_2(print_hnd, printer, snum); /* check the required size. */ *needed += spoolss_size_printer_info_2(printer); @@ -4672,11 +4650,11 @@ static WERROR getprinter_level_2(int snum, NEW_BUFFER *buffer, uint32 offered, u /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_3(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_3 *printer=NULL; - if (!construct_printer_info_3(&printer, snum)) + if (!construct_printer_info_3(print_hnd, &printer, snum)) return WERR_NOMEM; /* check the required size. */ @@ -4703,14 +4681,14 @@ static WERROR getprinter_level_3(int snum, NEW_BUFFER *buffer, uint32 offered, u /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_4(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_4(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_4 *printer=NULL; if((printer=(PRINTER_INFO_4*)malloc(sizeof(PRINTER_INFO_4)))==NULL) return WERR_NOMEM; - if (!construct_printer_info_4(printer, snum)) + if (!construct_printer_info_4(print_hnd, printer, snum)) return WERR_NOMEM; /* check the required size. */ @@ -4737,14 +4715,14 @@ static WERROR getprinter_level_4(int snum, NEW_BUFFER *buffer, uint32 offered, u /**************************************************************************** ****************************************************************************/ -static WERROR getprinter_level_5(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_5(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_5 *printer=NULL; if((printer=(PRINTER_INFO_5*)malloc(sizeof(PRINTER_INFO_5)))==NULL) return WERR_NOMEM; - if (!construct_printer_info_5(printer, snum)) + if (!construct_printer_info_5(print_hnd, printer, snum)) return WERR_NOMEM; /* check the required size. */ @@ -4768,14 +4746,14 @@ static WERROR getprinter_level_5(int snum, NEW_BUFFER *buffer, uint32 offered, u return WERR_OK; } -static WERROR getprinter_level_7(int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) +static WERROR getprinter_level_7(Printer_entry *print_hnd, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed) { PRINTER_INFO_7 *printer=NULL; if((printer=(PRINTER_INFO_7*)malloc(sizeof(PRINTER_INFO_7)))==NULL) return WERR_NOMEM; - if (!construct_printer_info_7(printer, snum)) + if (!construct_printer_info_7(print_hnd, printer, snum)) return WERR_NOMEM; /* check the required size. */ @@ -4809,6 +4787,7 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET NEW_BUFFER *buffer = NULL; uint32 offered = q_u->offered; uint32 *needed = &r_u->needed; + Printer_entry *Printer=find_printer_index_by_hnd(p, handle); int snum; @@ -4823,19 +4802,19 @@ WERROR _spoolss_getprinter(pipes_struct *p, SPOOL_Q_GETPRINTER *q_u, SPOOL_R_GET switch (level) { case 0: - return getprinter_level_0(snum, buffer, offered, needed); + return getprinter_level_0(Printer, snum, buffer, offered, needed); case 1: - return getprinter_level_1(snum, buffer, offered, needed); + return getprinter_level_1(Printer, snum, buffer, offered, needed); case 2: - return getprinter_level_2(snum, buffer, offered, needed); + return getprinter_level_2(Printer, snum, buffer, offered, needed); case 3: - return getprinter_level_3(snum, buffer, offered, needed); + return getprinter_level_3(Printer, snum, buffer, offered, needed); case 4: - return getprinter_level_4(snum, buffer, offered, needed); + return getprinter_level_4(Printer, snum, buffer, offered, needed); case 5: - return getprinter_level_5(snum, buffer, offered, needed); + return getprinter_level_5(Printer, snum, buffer, offered, needed); case 7: - return getprinter_level_7(snum, buffer, offered, needed); + return getprinter_level_7(Printer, snum, buffer, offered, needed); } return WERR_UNKNOWN_LEVEL; } @@ -4860,7 +4839,7 @@ static WERROR construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fst ZERO_STRUCT(driver); - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum)))) return WERR_INVALID_PRINTER_NAME; if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) @@ -4920,7 +4899,7 @@ static WERROR construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fst ZERO_STRUCT(printer); ZERO_STRUCT(driver); - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum)))) + if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_const_servicename(snum)))) return WERR_INVALID_PRINTER_NAME; if (!W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version))) @@ -5059,7 +5038,7 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fst WERROR status; ZERO_STRUCT(driver); - status=get_a_printer(&printer, 2, lp_servicename(snum) ); + status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) ); DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); if (!W_ERROR_IS_OK(status)) return WERR_INVALID_PRINTER_NAME; @@ -5184,7 +5163,7 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, ZERO_STRUCT(driver); - status=get_a_printer(&printer, 2, lp_servicename(snum) ); + status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) ); DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); @@ -5853,13 +5832,6 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, result = WERR_OK; - if (level!=2) { - DEBUG(0,("update_printer: Send a mail to samba@samba.org\n")); - DEBUGADD(0,("with the following message: update_printer: level!=2\n")); - result = WERR_UNKNOWN_LEVEL; - goto done; - } - if (!Printer) { result = WERR_BADFID; goto done; @@ -5870,8 +5842,8 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, goto done; } - if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) || - (!W_ERROR_IS_OK(get_a_printer(&old_printer, 2, lp_servicename(snum))))) { + if (!W_ERROR_IS_OK(get_a_printer(Printer, &printer, 2, lp_const_servicename(snum))) || + (!W_ERROR_IS_OK(get_a_printer(Printer, &old_printer, 2, lp_const_servicename(snum))))) { result = WERR_BADFID; goto done; } @@ -5899,13 +5871,6 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, result = WERR_NOMEM; goto done; } - - /* - * make sure we actually reload the services after - * this as smb.conf could have a new section in it - * .... shouldn't .... but could - */ - reload_services(False); } /* Do sanity check on the requested changes for Samba */ @@ -5964,9 +5929,6 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, notify_printer_driver(snum, printer->info_2->drivername); } - /* Update printer info */ - result = mod_a_printer(*printer, 2); - /* * flag which changes actually occured. This is a small subset of * all the possible changes. We also have to update things in the @@ -6022,6 +5984,9 @@ static WERROR update_printer(pipes_struct *p, POLICY_HND *handle, uint32 level, set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName", REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + /* Update printer info */ + result = mod_a_printer(*printer, 2); + done: free_a_printer(&printer, 2); free_a_printer(&old_printer, 2); @@ -6051,7 +6016,7 @@ static WERROR publish_or_unpublish_printer(pipes_struct *p, POLICY_HND *handle, if (!get_printer_snum(p, handle, &snum)) return WERR_BADFID; - nt_printer_publish(snum, info7->action); + nt_printer_publish(Printer, snum, info7->action); return WERR_OK; #else @@ -6287,7 +6252,7 @@ static WERROR enumjobs_level2(print_queue_struct *queue, int snum, goto done; } - result = get_a_printer(&ntprinter, 2, lp_servicename(snum)); + result = get_a_printer(NULL, &ntprinter, 2, lp_servicename(snum)); if (!W_ERROR_IS_OK(result)) { *returned = 0; goto done; @@ -7591,7 +7556,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S if (!get_printer_snum(p,handle, &snum)) return WERR_BADFID; - result = get_a_printer(&printer, 2, lp_servicename(snum)); + result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(result)) return result; @@ -7655,9 +7620,9 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S /* out_value should default to "" or else NT4 has problems unmarshalling the response */ - *out_max_value_len = (in_value_len/sizeof(uint16)); + *out_max_value_len=(in_value_len/sizeof(uint16)); - if ( (*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL ) + if((*out_value=(uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL) { result = WERR_NOMEM; goto done; @@ -7692,7 +7657,7 @@ WERROR _spoolss_enumprinterdata(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATA *q_u, S */ /* name */ - *out_max_value_len = ( in_value_len / sizeof(uint16) ); + *out_max_value_len=(in_value_len/sizeof(uint16)); if ( (*out_value = (uint16 *)talloc_zero(p->mem_ctx, in_value_len*sizeof(uint8))) == NULL ) { result = WERR_NOMEM; @@ -7765,7 +7730,7 @@ WERROR _spoolss_setprinterdata( pipes_struct *p, SPOOL_Q_SETPRINTERDATA *q_u, SP goto done; } - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) return status; @@ -7857,7 +7822,7 @@ WERROR _spoolss_deleteprinterdata(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATA *q_ return WERR_ACCESS_DENIED; } - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) return status; @@ -7901,7 +7866,7 @@ WERROR _spoolss_addform( pipes_struct *p, SPOOL_Q_ADDFORM *q_u, SPOOL_R_ADDFORM if (!get_printer_snum(p,handle, &snum)) return WERR_BADFID; - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) goto done; } @@ -7972,7 +7937,7 @@ WERROR _spoolss_deleteform( pipes_struct *p, SPOOL_Q_DELETEFORM *q_u, SPOOL_R_DE if (!get_printer_snum(p,handle, &snum)) return WERR_BADFID; - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) goto done; } @@ -8040,7 +8005,7 @@ WERROR _spoolss_setform(pipes_struct *p, SPOOL_Q_SETFORM *q_u, SPOOL_R_SETFORM * if (!get_printer_snum(p,handle, &snum)) return WERR_BADFID; - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) goto done; } @@ -8390,7 +8355,7 @@ static WERROR getjob_level_2(print_queue_struct *queue, int count, int snum, uin goto done; } - ret = get_a_printer(&ntprinter, 2, lp_servicename(snum)); + ret = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(ret)) goto done; @@ -8543,7 +8508,7 @@ WERROR _spoolss_getprinterdataex(pipes_struct *p, SPOOL_Q_GETPRINTERDATAEX *q_u, if ( !get_printer_snum(p,handle, &snum) ) return WERR_BADFID; - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); if ( !W_ERROR_IS_OK(status) ) goto done; @@ -8638,7 +8603,7 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, return WERR_ACCESS_DENIED; } - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_servicename(snum)); if (!W_ERROR_IS_OK(status)) return status; @@ -8657,11 +8622,10 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, status = set_printer_dataex( printer, keyname, valuename, type, data, real_len ); - /* save the OID if one was specified and the previous set call succeeded */ - - if ( W_ERROR_IS_OK(status) && oid_string ) + if ( W_ERROR_IS_OK(status) ) { - + /* save the OID if one was specified */ + if ( oid_string ) { fstrcat( keyname, "\\" ); fstrcat( keyname, SPOOL_OID_KEY ); @@ -8676,6 +8640,9 @@ WERROR _spoolss_setprinterdataex(pipes_struct *p, SPOOL_Q_SETPRINTERDATAEX *q_u, REG_SZ, (void*)oid_string, strlen(oid_string)+1 ); } + status = mod_a_printer(*printer, 2); + } + free_a_printer(&printer, 2); return status; @@ -8713,7 +8680,7 @@ WERROR _spoolss_deleteprinterdataex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDATAEX return WERR_ACCESS_DENIED; } - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) return status; @@ -8757,7 +8724,7 @@ WERROR _spoolss_enumprinterkey(pipes_struct *p, SPOOL_Q_ENUMPRINTERKEY *q_u, SPO if ( !get_printer_snum(p,handle, &snum) ) return WERR_BADFID; - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) return status; @@ -8832,7 +8799,7 @@ WERROR _spoolss_deleteprinterkey(pipes_struct *p, SPOOL_Q_DELETEPRINTERKEY *q_u, return WERR_ACCESS_DENIED; } - status = get_a_printer(&printer, 2, lp_servicename(snum)); + status = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(status)) return status; @@ -8901,7 +8868,7 @@ WERROR _spoolss_enumprinterdataex(pipes_struct *p, SPOOL_Q_ENUMPRINTERDATAEX *q_ return WERR_BADFID; ZERO_STRUCT(printer); - result = get_a_printer(&printer, 2, lp_servicename(snum)); + result = get_a_printer(Printer, &printer, 2, lp_const_servicename(snum)); if (!W_ERROR_IS_OK(result)) return result; diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 25f390be55..98857c6d32 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -500,7 +500,7 @@ static BOOL get_driver_name(int snum, pstring drivername) NT_PRINTER_INFO_LEVEL *info = NULL; BOOL in_tdb = False; - get_a_printer (&info, 2, lp_servicename(snum)); + get_a_printer (NULL, &info, 2, lp_servicename(snum)); if (info != NULL) { pstrcpy( drivername, info->info_2->drivername); in_tdb = True; @@ -522,7 +522,7 @@ static void fill_printq_info_52(connection_struct *conn, int snum, NT_PRINTER_DRIVER_INFO_LEVEL driver; NT_PRINTER_INFO_LEVEL *printer = NULL; - if ( !W_ERROR_IS_OK(get_a_printer( &printer, 2, lp_servicename(snum))) ) { + if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) { DEBUG(3,("fill_printq_info_52: Failed to lookup printer [%s]\n", lp_servicename(snum))); goto err; @@ -679,7 +679,7 @@ static int get_printerdrivernumber(int snum) NT_PRINTER_DRIVER_INFO_LEVEL driver; NT_PRINTER_INFO_LEVEL *printer = NULL; - if ( !W_ERROR_IS_OK(get_a_printer( &printer, 2, lp_servicename(snum))) ) { + if ( !W_ERROR_IS_OK(get_a_printer( NULL, &printer, 2, lp_servicename(snum))) ) { DEBUG(3,("get_printerdrivernumber: Failed to lookup printer [%s]\n", lp_servicename(snum))); goto done; -- cgit