summaryrefslogtreecommitdiff
path: root/source3/printing
diff options
context:
space:
mode:
Diffstat (limited to 'source3/printing')
-rw-r--r--source3/printing/nt_printing.c456
-rw-r--r--source3/printing/pcap.c17
-rw-r--r--source3/printing/print_aix.c32
-rw-r--r--source3/printing/print_cups.c12
-rw-r--r--source3/printing/print_generic.c112
-rw-r--r--source3/printing/printing_db.c16
6 files changed, 396 insertions, 249 deletions
diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c
index 1d218bac3d..bbe312ca27 100644
--- a/source3/printing/nt_printing.c
+++ b/source3/printing/nt_printing.c
@@ -228,18 +228,17 @@ static const struct table_node archi_table[]= {
generate a new TDB_DATA key for storing a printer
****************************************************************************/
-static TDB_DATA make_printer_tdbkey( const char *sharename )
+static TDB_DATA make_printer_tdbkey(TALLOC_CTX *ctx, const char *sharename )
{
fstring share;
- static pstring keystr;
+ char *keystr = NULL;
TDB_DATA key;
-
- fstrcpy( share, sharename );
- strlower_m( share );
-
- pstr_sprintf( keystr, "%s%s", PRINTERS_PREFIX, share );
-
- key = string_term_tdb_data(keystr);
+
+ fstrcpy(share, sharename);
+ strlower_m(share);
+
+ keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);
+ key = string_term_tdb_data(keystr ? keystr : "");
return key;
}
@@ -248,18 +247,18 @@ static TDB_DATA make_printer_tdbkey( const char *sharename )
generate a new TDB_DATA key for storing a printer security descriptor
****************************************************************************/
-static TDB_DATA make_printers_secdesc_tdbkey( const char* sharename )
+static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
+ const char* sharename )
{
fstring share;
- static pstring keystr;
+ char *keystr = NULL;
TDB_DATA key;
- fstrcpy( share, sharename );
- strlower_m( share );
-
- pstr_sprintf( keystr, "%s%s", SECDESC_PREFIX, share );
+ fstrcpy(share, sharename );
+ strlower_m(share);
- key = string_term_tdb_data(keystr);
+ keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);
+ key = string_term_tdb_data(keystr ? keystr : "");
return key;
}
@@ -482,38 +481,39 @@ static bool upgrade_to_version_4(void)
static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
TDB_DATA data, void *state )
{
+ TALLOC_CTX *ctx = talloc_tos();
TDB_DATA new_key;
-
+
if (!data.dptr || data.dsize == 0)
return 0;
/* upgrade printer records and security descriptors */
-
+
if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
- new_key = make_printer_tdbkey( (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
+ new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
}
else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
- new_key = make_printers_secdesc_tdbkey( (const char *)key.dptr+strlen(SECDESC_PREFIX) );
+ new_key = make_printers_secdesc_tdbkey(ctx, (const char *)key.dptr+strlen(SECDESC_PREFIX) );
}
else {
/* ignore this record */
return 0;
}
-
+
/* delete the original record and store under the normalized key */
-
+
if ( tdb_delete( the_tdb, key ) != 0 ) {
DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
key.dptr));
return 1;
}
-
+
if ( tdb_store( the_tdb, new_key, data, TDB_REPLACE) != 0 ) {
DEBUG(0,("normalize_printers_fn: failed to store new record for [%s]!\n",
key.dptr));
return 1;
}
-
+
return 0;
}
@@ -830,24 +830,46 @@ int get_ntforms(nt_forms_struct **list)
/****************************************************************************
write a form struct list
****************************************************************************/
+
int write_ntforms(nt_forms_struct **list, int number)
{
- pstring buf, key;
+ TALLOC_CTX *ctx = talloc_tos();
+ char *buf = NULL;
+ char *key = NULL;
int len;
TDB_DATA dbuf;
int i;
for (i=0;i<number;i++) {
/* save index, so list is rebuilt in correct order */
- len = tdb_pack((uint8 *)buf, sizeof(buf), "dddddddd",
+ len = tdb_pack(NULL, 0, "dddddddd",
i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
(*list)[i].left, (*list)[i].top, (*list)[i].right,
(*list)[i].bottom);
- if (len > sizeof(buf)) break;
- slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[i].name);
+ if (!len) {
+ continue;
+ }
+ buf = TALLOC_ARRAY(ctx, char, len);
+ if (!buf) {
+ return 0;
+ }
+ len = tdb_pack((uint8 *)buf, len, "dddddddd",
+ i, (*list)[i].flag, (*list)[i].width, (*list)[i].length,
+ (*list)[i].left, (*list)[i].top, (*list)[i].right,
+ (*list)[i].bottom);
+ key = talloc_asprintf(ctx, "%s%s", FORMS_PREFIX, (*list)[i].name);
+ if (!key) {
+ return 0;
+ }
dbuf.dsize = len;
dbuf.dptr = (uint8 *)buf;
- if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) break;
+ if (tdb_store_bystring(tdb_forms, key, dbuf, TDB_REPLACE) != 0) {
+ TALLOC_FREE(key);
+ TALLOC_FREE(buf);
+ break;
+ }
+ TALLOC_FREE(key);
+ TALLOC_FREE(buf);
}
return i;
@@ -907,7 +929,7 @@ bool add_a_form(nt_forms_struct **list, const FORM *form, int *count)
bool delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
{
- pstring key;
+ char *key = NULL;
int n=0;
fstring form_name;
@@ -928,13 +950,17 @@ bool delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR
return False;
}
- slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
+ if (asprintf(&key, "%s%s", FORMS_PREFIX, (*list)[n].name) < 0) {
+ *ret = WERR_NOMEM;
+ return false;
+ }
if (tdb_delete_bystring(tdb_forms, key) != 0) {
+ SAFE_FREE(key);
*ret = WERR_NOMEM;
return False;
}
-
- return True;
+ SAFE_FREE(key);
+ return true;
}
/****************************************************************************
@@ -973,7 +999,7 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
{
int total=0;
const char *short_archi;
- pstring key;
+ char *key = NULL;
TDB_DATA kbuf, newkey;
short_archi = get_short_archi(architecture);
@@ -981,7 +1007,10 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
return 0;
}
- slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
+ if (asprintf(&key, "%s%s/%d/", DRIVERS_PREFIX,
+ short_archi, version) < 0) {
+ return 0;
+ }
for (kbuf = tdb_firstkey(tdb_drivers);
kbuf.dptr;
@@ -989,9 +1018,10 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0)
continue;
-
+
if((*list = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {
DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
+ SAFE_FREE(key);
return -1;
}
@@ -999,6 +1029,7 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
total++;
}
+ SAFE_FREE(key);
return(total);
}
@@ -2063,13 +2094,15 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
/****************************************************************************
****************************************************************************/
+
static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
{
+ TALLOC_CTX *ctx = talloc_tos();
int len, buflen;
const char *architecture;
- pstring directory;
+ char *directory = NULL;
fstring temp_name;
- pstring key;
+ char *key = NULL;
uint8 *buf;
int i, ret;
TDB_DATA dbuf;
@@ -2084,7 +2117,11 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
* It does make sense to NOT store the server's name in the printer TDB.
*/
- slprintf(directory, sizeof(directory)-1, "\\print$\\%s\\%d\\", architecture, driver->cversion);
+ directory = talloc_asprintf(ctx, "\\print$\\%s\\%d\\",
+ architecture, driver->cversion);
+ if (!directory) {
+ return (uint32)-1;
+ }
/* .inf files do not always list a file for each of the four standard files.
* Don't prepend a path to a null filename, or client claims:
@@ -2119,7 +2156,11 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
}
}
- slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
+ key = talloc_asprintf(ctx, "%s%s/%d/%s", DRIVERS_PREFIX,
+ architecture, driver->cversion, driver->name);
+ if (!key) {
+ return (uint32)-1;
+ }
DEBUG(5,("add_a_printer_driver_3: Adding driver with key %s\n", key ));
@@ -2159,7 +2200,7 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
dbuf.dptr = buf;
dbuf.dsize = len;
-
+
ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE);
done:
@@ -2232,7 +2273,7 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
const char *architecture;
int len = 0;
int i;
- pstring key;
+ char *key = NULL;
ZERO_STRUCT(driver);
@@ -2240,19 +2281,24 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
if ( !architecture ) {
return WERR_UNKNOWN_PRINTER_DRIVER;
}
-
+
/* Windows 4.0 (i.e. win9x) should always use a version of 0 */
-
+
if ( strcmp( architecture, SPL_ARCH_WIN40 ) == 0 )
version = 0;
DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
- slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, drivername);
-
+ if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,
+ architecture, version, drivername) < 0) {
+ return WERR_NOMEM;
+ }
+
dbuf = tdb_fetch_bystring(tdb_drivers, key);
- if (!dbuf.dptr)
+ if (!dbuf.dptr) {
+ SAFE_FREE(key);
return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
&driver.cversion,
@@ -2277,11 +2323,12 @@ static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
&driver.dependentfiles[i]);
i++;
}
-
+
if ( driver.dependentfiles )
fstrcpy( driver.dependentfiles[i], "" );
SAFE_FREE(dbuf.dptr);
+ SAFE_FREE(key);
if (len != dbuf.dsize) {
SAFE_FREE(driver.dependentfiles);
@@ -2397,7 +2444,6 @@ int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen)
nt_devmode->panningheight,
nt_devmode->nt_dev_private);
-
if (nt_devmode->nt_dev_private) {
len += tdb_pack(buf+len, buflen-len, "B",
nt_devmode->driverextra,
@@ -2412,44 +2458,46 @@ int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen)
/****************************************************************************
Pack all values in all printer keys
***************************************************************************/
-
+
static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen)
{
int len = 0;
int i, j;
REGISTRY_VALUE *val;
REGVAL_CTR *val_ctr;
- pstring path;
+ char *path = NULL;
int num_values;
if ( !data )
return 0;
/* loop over all keys */
-
- for ( i=0; i<data->num_keys; i++ ) {
+
+ for ( i=0; i<data->num_keys; i++ ) {
val_ctr = data->keys[i].values;
num_values = regval_ctr_numvals( val_ctr );
/* pack the keyname followed by a empty value */
- len += tdb_pack(buf+len, buflen-len, "pPdB",
+ len += tdb_pack(buf+len, buflen-len, "pPdB",
&data->keys[i].name,
- data->keys[i].name,
+ data->keys[i].name,
REG_NONE,
0,
NULL);
-
+
/* now loop over all values */
-
+
for ( j=0; j<num_values; j++ ) {
/* pathname should be stored as <key>\<value> */
-
+
val = regval_ctr_specific_value( val_ctr, j );
- pstrcpy( path, data->keys[i].name );
- pstrcat( path, "\\" );
- pstrcat( path, regval_name(val) );
-
+ if (asprintf(&path, "%s\\%s",
+ data->keys[i].name,
+ regval_name(val)) < 0) {
+ return -1;
+ }
+
len += tdb_pack(buf+len, buflen-len, "pPdB",
val,
path,
@@ -2458,12 +2506,13 @@ static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen)
regval_data_p(val) );
DEBUG(8,("specific: [%s], len: %d\n", regval_name(val), regval_size(val)));
+ SAFE_FREE(path);
}
-
+
}
/* terminator */
-
+
len += tdb_pack(buf+len, buflen-len, "p", NULL);
return len;
@@ -2478,22 +2527,25 @@ static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen)
uint32 del_a_printer(const char *sharename)
{
TDB_DATA kbuf;
- pstring printdb_path;
+ char *printdb_path = NULL;
+ TALLOC_CTX *ctx = talloc_tos();
- kbuf = make_printer_tdbkey( sharename );
+ kbuf = make_printer_tdbkey(ctx, sharename);
tdb_delete(tdb_printers, kbuf);
- kbuf= make_printers_secdesc_tdbkey( sharename );
+ kbuf= make_printers_secdesc_tdbkey(ctx, sharename);
tdb_delete(tdb_printers, kbuf);
close_all_print_db();
if (geteuid() == 0) {
- pstrcpy(printdb_path, lock_path("printing/"));
- pstrcat(printdb_path, sharename);
- pstrcat(printdb_path, ".tdb");
-
+ if (asprintf(&printdb_path, "%s%s.tdb",
+ lock_path("printing/"),
+ sharename) < 0) {
+ return (uint32)-1;
+ }
unlink(printdb_path);
+ SAFE_FREE(printdb_path);
}
return 0;
@@ -2505,6 +2557,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
{
uint8 *buf;
int buflen, len;
+ int retlen;
WERROR ret;
TDB_DATA kbuf, dbuf;
@@ -2539,7 +2592,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
buf = NULL;
buflen = 0;
- again:
+ again:
len = 0;
len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
info->attributes,
@@ -2566,8 +2619,12 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
info->parameters);
len += pack_devicemode(info->devmode, buf+len, buflen-len);
-
- len += pack_values( info->data, buf+len, buflen-len );
+ retlen = pack_values( info->data, buf+len, buflen-len );
+ if (retlen == -1) {
+ ret = WERR_NOMEM;
+ goto done;
+ }
+ len += retlen;
if (buflen != len) {
buf = (uint8 *)SMB_REALLOC(buf, len);
@@ -2579,9 +2636,8 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
buflen = len;
goto again;
}
-
- kbuf = make_printer_tdbkey( info->sharename );
+ kbuf = make_printer_tdbkey(talloc_tos(), info->sharename );
dbuf.dptr = buf;
dbuf.dsize = len;
@@ -3645,13 +3701,13 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha
DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
key, value, type, real_len ));
-
+
return result;
}
/****************************************************************************
***************************************************************************/
-
+
REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
{
int key_index;
@@ -3668,12 +3724,14 @@ REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key,
/****************************************************************************
Unpack a list of registry values frem the TDB
***************************************************************************/
-
+
static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int buflen)
{
int len = 0;
uint32 type;
- pstring string, valuename, keyname;
+ fstring string;
+ const char *valuename = NULL;
+ const char *keyname = NULL;
char *str;
int size;
uint8 *data_p;
@@ -3681,22 +3739,22 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
int key_index;
/* add the "PrinterDriverData" key first for performance reasons */
-
+
add_new_printer_key( printer_data, SPOOL_PRINTERDATA_KEY );
/* loop and unpack the rest of the registry values */
-
+
while ( True ) {
-
+
/* check to see if there are any more registry values */
-
+
regval_p = NULL;
- len += tdb_unpack(buf+len, buflen-len, "p", &regval_p);
- if ( !regval_p )
+ len += tdb_unpack(buf+len, buflen-len, "p", &regval_p);
+ if ( !regval_p )
break;
/* unpack the next regval */
-
+
len += tdb_unpack(buf+len, buflen-len, "fdB",
string,
&type,
@@ -3711,64 +3769,64 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
add_new_printer_key( printer_data, string );
continue;
}
-
+
/*
- * break of the keyname from the value name.
+ * break of the keyname from the value name.
* Valuenames can have embedded '\'s so be careful.
- * only support one level of keys. See the
+ * only support one level of keys. See the
* "Konica Fiery S300 50C-K v1.1. enu" 2k driver.
* -- jerry
- */
-
+ */
+
str = strchr_m( string, '\\');
-
+
/* Put in "PrinterDriverData" is no key specified */
-
+
if ( !str ) {
- pstrcpy( keyname, SPOOL_PRINTERDATA_KEY );
- pstrcpy( valuename, string );
+ keyname = SPOOL_PRINTERDATA_KEY;
+ valuename = string;
}
else {
*str = '\0';
- pstrcpy( keyname, string );
- pstrcpy( valuename, str+1 );
+ keyname = string;
+ valuename = str+1;
}
-
+
/* see if we need a new key */
-
+
if ( (key_index=lookup_printerkey( printer_data, keyname )) == -1 )
key_index = add_new_printer_key( printer_data, keyname );
-
+
if ( key_index == -1 ) {
DEBUG(0,("unpack_values: Failed to allocate a new key [%s]!\n",
keyname));
break;
}
-
+
DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
- /* Vista doesn't like unknown REG_BINARY values in DsSpooler.
+ /* Vista doesn't like unknown REG_BINARY values in DsSpooler.
Thanks to Martin Zielinski for the hint. */
- if ( type == REG_BINARY &&
- strequal( keyname, SPOOL_DSSPOOLER_KEY ) &&
- strequal( valuename, "objectGUID" ) )
+ if ( type == REG_BINARY &&
+ strequal( keyname, SPOOL_DSSPOOLER_KEY ) &&
+ strequal( valuename, "objectGUID" ) )
{
struct GUID guid;
UNISTR2 unistr_guid;
ZERO_STRUCT( unistr_guid );
-
+
/* convert the GUID to a UNICODE string */
-
+
memcpy( &guid, data_p, sizeof(struct GUID) );
-
+
init_unistr2( &unistr_guid, smb_uuid_string_static(guid),
UNI_STR_TERMINATE );
-
+
regval_ctr_addvalue( printer_data->keys[key_index].values,
- valuename, REG_SZ,
- (const char *)unistr_guid.buffer,
+ valuename, REG_SZ,
+ (const char *)unistr_guid.buffer,
unistr_guid.uni_str_len*2 );
} else {
@@ -3778,7 +3836,6 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
valuename, type, (const char *)data_p,
size );
}
-
SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
@@ -3958,8 +4015,8 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info, const char *servern
TDB_DATA kbuf, dbuf;
fstring printername;
char adevice[MAXDEVICENAME];
-
- kbuf = make_printer_tdbkey( sharename );
+
+ kbuf = make_printer_tdbkey(talloc_tos(), sharename);
dbuf = tdb_fetch(tdb_printers, kbuf);
if (!dbuf.dptr) {
@@ -4198,14 +4255,13 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
*/
result=update_a_printer_2(printer->info_2);
-
break;
}
default:
result=WERR_UNKNOWN_LEVEL;
break;
}
-
+
return result;
}
@@ -4216,7 +4272,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
{
int len = 0;
- pstring key;
+ char *key = NULL;
TDB_DATA dbuf;
NT_PRINTER_INFO_LEVEL_2 info;
@@ -4228,11 +4284,14 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
* replace, there will generally be some, but during an add printer, there
* should not be any (if there are delete them).
*/
-
+
if ( info_ptr->data )
delete_all_printer_data( info_ptr, "" );
-
- slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info_ptr->drivername);
+
+ if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX,
+ info_ptr->drivername) < 0) {
+ return false;
+ }
dbuf = tdb_fetch_bystring(tdb_drivers, key);
if (!dbuf.dptr) {
@@ -4241,20 +4300,22 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
* the previous drivers init info and leave the new on blank.
*/
free_nt_devicemode(&info_ptr->devmode);
- return False;
+ SAFE_FREE(key);
+ return false;
}
-
+
+ SAFE_FREE(key);
/*
* Get the saved DEVMODE..
*/
-
+
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
/*
* The saved DEVMODE contains the devicename from the printer used during
* the initialization save. Change it to reflect the new printer.
*/
-
+
if ( info.devmode ) {
ZERO_STRUCT(info.devmode->devicename);
fstrcpy(info.devmode->devicename, info_ptr->printername);
@@ -4262,18 +4323,18 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
/*
* NT/2k does not change out the entire DeviceMode of a printer
- * when changing the driver. Only the driverextra, private, &
+ * when changing the driver. Only the driverextra, private, &
* driverversion fields. --jerry (Thu Mar 14 08:58:43 CST 2002)
*
* Later examination revealed that Windows NT/2k does reset the
- * the printer's device mode, bit **only** when you change a
+ * the printer's device mode, bit **only** when you change a
* property of the device mode such as the page orientation.
* --jerry
*/
/* Bind the saved DEVMODE to the new the printer */
-
+
free_nt_devicemode(&info_ptr->devmode);
info_ptr->devmode = info.devmode;
@@ -4286,13 +4347,12 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
DEBUG(0,("set_driver_init_2: talloc() failed!\n"));
return False;
}
-
+
len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
-
SAFE_FREE(dbuf.dptr);
- return True;
+ return true;
}
/****************************************************************************
@@ -4305,18 +4365,18 @@ static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
bool result = False;
-
+
switch (level) {
case 2:
result = set_driver_init_2(printer->info_2);
break;
-
+
default:
DEBUG(0,("set_driver_init: Programmer's error! Unknown driver_init level [%d]\n",
level));
break;
}
-
+
return result;
}
@@ -4326,18 +4386,24 @@ bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
bool del_driver_init(char *drivername)
{
- pstring key;
+ char *key;
+ bool ret;
if (!drivername || !*drivername) {
DEBUG(3,("del_driver_init: No drivername specified!\n"));
- return False;
+ return false;
}
- slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, drivername);
+ if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, drivername) < 0) {
+ return false;
+ }
- DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n", drivername));
+ DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n",
+ drivername));
- return (tdb_delete_bystring(tdb_drivers, key) == 0);
+ ret = (tdb_delete_bystring(tdb_drivers, key) == 0);
+ SAFE_FREE(key);
+ return ret;
}
/****************************************************************************
@@ -4350,19 +4416,25 @@ bool del_driver_init(char *drivername)
static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
{
- pstring key;
+ char *key = NULL;
uint8 *buf;
int buflen, len, ret;
+ int retlen;
TDB_DATA dbuf;
buf = NULL;
buflen = 0;
- again:
+ again:
len = 0;
len += pack_devicemode(info->devmode, buf+len, buflen-len);
- len += pack_values( info->data, buf+len, buflen-len );
+ retlen = pack_values( info->data, buf+len, buflen-len );
+ if (retlen == -1) {
+ ret = -1;
+ goto done;
+ }
+ len += retlen;
if (buflen < len) {
buf = (uint8 *)SMB_REALLOC(buf, len);
@@ -4375,7 +4447,11 @@ static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
goto again;
}
- slprintf(key, sizeof(key)-1, "%s%s", DRIVER_INIT_PREFIX, info->drivername);
+ SAFE_FREE(key);
+ if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, info->drivername) < 0) {
+ ret = (uint32)-1;
+ goto done;
+ }
dbuf.dptr = buf;
dbuf.dsize = len;
@@ -5007,25 +5083,25 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
return True;
}
}
-
+
free_a_printer_driver(driver, 3);
- }
-
+ }
+
SAFE_FREE(list);
-
+
DEBUG(5,("printer_driver_files_in_use: Completed search through ntdrivers.tdb...\n"));
-
+
driver.info_3 = info;
-
+
if ( DEBUGLEVEL >= 20 )
dump_a_printer_driver( driver, 3 );
-
+
return False;
}
/****************************************************************************
- Actually delete the driver files. Make sure that
- printer_driver_files_in_use() return False before calling
+ Actually delete the driver files. Make sure that
+ printer_driver_files_in_use() return False before calling
this.
****************************************************************************/
@@ -5033,7 +5109,7 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
{
int i = 0;
char *s;
- pstring file;
+ const char *file;
connection_struct *conn;
DATA_BLOB null_pw;
NTSTATUS nt_status;
@@ -5042,21 +5118,21 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
if ( !info_3 )
return False;
-
+
DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion));
-
+
/*
- * Connect to the print$ share under the same account as the
- * user connected to the rpc pipe. Note we must be root to
+ * Connect to the print$ share under the same account as the
+ * user connected to the rpc pipe. Note we must be root to
* do this.
*/
-
+
null_pw = data_blob_null;
fstrcpy(res_type, "A:");
become_root();
conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status );
unbecome_root();
-
+
if ( !conn ) {
DEBUG(0,("delete_driver_files: Unable to connect\n"));
return False;
@@ -5074,67 +5150,67 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
return False;
}
- /* now delete the files; must strip the '\print$' string from
+ /* now delete the files; must strip the '\print$' string from
fron of path */
-
+
if ( *info_3->driverpath ) {
if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
- pstrcpy( file, s );
+ file = s;
driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting driverfile [%s]\n", s));
unlink_internals(conn, NULL, 0, file, False);
}
}
-
+
if ( *info_3->configfile ) {
if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
- pstrcpy( file, s );
+ file = s;
driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting configfile [%s]\n", s));
unlink_internals(conn, NULL, 0, file, False);
}
}
-
+
if ( *info_3->datafile ) {
if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
- pstrcpy( file, s );
+ file = s;
driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting datafile [%s]\n", s));
unlink_internals(conn, NULL, 0, file, False);
}
}
-
+
if ( *info_3->helpfile ) {
if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
- pstrcpy( file, s );
+ file = s;
driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting helpfile [%s]\n", s));
unlink_internals(conn, NULL, 0, file, False);
}
}
-
+
/* check if we are done removing files */
-
+
if ( info_3->dependentfiles ) {
while ( info_3->dependentfiles[i][0] ) {
char *p;
/* bypass the "\print$" portion of the path */
-
+
if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
- pstrcpy( file, p );
+ file = p;
driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting dependent file [%s]\n", file));
unlink_internals(conn, NULL, 0, file, False);
}
-
+
i++;
}
}
unbecome_user();
-
- return True;
+
+ return true;
}
/****************************************************************************
@@ -5145,7 +5221,7 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
uint32 version, bool delete_files )
{
- pstring key;
+ char *key = NULL;
const char *arch;
TDB_DATA dbuf;
NT_PRINTER_DRIVER_INFO_LEVEL ctr;
@@ -5156,8 +5232,10 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
if (!arch) {
return WERR_UNKNOWN_PRINTER_DRIVER;
}
- slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
- arch, version, info_3->name);
+ if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,
+ arch, version, info_3->name) < 0) {
+ return WERR_NOMEM;
+ }
DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
key, delete_files ? "TRUE" : "FALSE" ));
@@ -5166,19 +5244,21 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
dump_a_printer_driver( ctr, 3 );
/* check if the driver actually exists for this environment */
-
+
dbuf = tdb_fetch_bystring( tdb_drivers, key );
if ( !dbuf.dptr ) {
DEBUG(8,("delete_printer_driver: Driver unknown [%s]\n", key));
+ SAFE_FREE(key);
return WERR_UNKNOWN_PRINTER_DRIVER;
}
-
+
SAFE_FREE( dbuf.dptr );
-
+
/* ok... the driver exists so the delete should return success */
-
+
if (tdb_delete_bystring(tdb_drivers, key) == -1) {
DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
+ SAFE_FREE(key);
return WERR_ACCESS_DENIED;
}
@@ -5190,13 +5270,13 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
if ( delete_files )
delete_driver_files( info_3, user );
-
-
+
DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
+ SAFE_FREE(key);
return WERR_OK;
- }
-
+}
+
/****************************************************************************
Store a security desc for a printer.
****************************************************************************/
@@ -5279,7 +5359,7 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
goto out;
}
- kbuf = make_printers_secdesc_tdbkey( sharename );
+ kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
if (tdb_prs_store(tdb_printers, kbuf, &ps)==0) {
status = WERR_OK;
@@ -5400,7 +5480,7 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
/* Fetch security descriptor from tdb */
- kbuf = make_printers_secdesc_tdbkey( sharename );
+ kbuf = make_printers_secdesc_tdbkey(ctx, sharename );
if (tdb_prs_fetch(tdb_printers, kbuf, &ps, ctx)!=0 ||
!sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
diff --git a/source3/printing/pcap.c b/source3/printing/pcap.c
index aabdb73e2e..30cb254a29 100644
--- a/source3/printing/pcap.c
+++ b/source3/printing/pcap.c
@@ -159,8 +159,9 @@ void pcap_cache_reload(void)
goto done;
}
- for (; (pcap_line = fgets_slash(NULL, sizeof(pstring), pcap_file)) != NULL; safe_free(pcap_line)) {
- pstring name, comment;
+ for (; (pcap_line = fgets_slash(NULL, 1024, pcap_file)) != NULL; safe_free(pcap_line)) {
+ char name[MAXPRINTERLEN+1];
+ char comment[62];
char *p, *q;
if (*pcap_line == '#' || *pcap_line == 0)
@@ -186,22 +187,22 @@ void pcap_cache_reload(void)
strchr_m(p, ')'));
if (strlen(p) > strlen(comment) && has_punctuation) {
- pstrcpy(comment, p);
+ strlcpy(comment, p, sizeof(comment));
continue;
}
if (strlen(p) <= MAXPRINTERLEN &&
strlen(p) > strlen(name) && !has_punctuation) {
- if (!*comment)
- pstrcpy(comment, name);
-
- pstrcpy(name, p);
+ if (!*comment) {
+ strlcpy(comment, name, sizeof(comment));
+ }
+ strlcpy(name, p, sizeof(name));
continue;
}
if (!strchr_m(comment, ' ') &&
strlen(p) > strlen(comment)) {
- pstrcpy(comment, p);
+ strlcpy(comment, p, sizeof(comment));
continue;
}
}
diff --git a/source3/printing/print_aix.c b/source3/printing/print_aix.c
index 15d0740fd2..bb125530df 100644
--- a/source3/printing/print_aix.c
+++ b/source3/printing/print_aix.c
@@ -32,21 +32,26 @@ bool aix_cache_reload(void)
int iEtat;
XFILE *pfile;
char *line = NULL, *p;
- pstring name, comment;
+ char *name;
+ TALLOC_CTX *ctx = talloc_init("aix_cache_reload");
+
+ if (!ctx) {
+ return false;
+ }
*name = 0;
- *comment = 0;
DEBUG(5, ("reloading aix printcap cache\n"));
if ((pfile = x_fopen(lp_printcapname(), O_RDONLY, 0)) == NULL) {
DEBUG(0,( "Unable to open qconfig file %s for read!\n", lp_printcapname()));
- return False;
+ TALLOC_FREE(ctx);
+ return false;
}
iEtat = 0;
/* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL, sizeof(pstring), pfile)); safe_free(line)) {
+ for (;(line = fgets_slash(NULL, 1024, pfile)); safe_free(line)) {
if (*line == '*' || *line == 0)
continue;
@@ -59,7 +64,13 @@ bool aix_cache_reload(void)
*p = '\0';
p = strtok(line, ":");
if (strcmp(p, "bsh") != 0) {
- pstrcpy(name, p);
+ name = talloc_strdup(ctx, p);
+ if (!name) {
+ safe_free(line);
+ x_fclose(pfile);
+ TALLOC_FREE(ctx);
+ return false;
+ }
iEtat = 1;
continue;
}
@@ -77,11 +88,12 @@ bool aix_cache_reload(void)
if (!pcap_cache_add(name, NULL)) {
safe_free(line);
x_fclose(pfile);
- return False;
+ TALLOC_FREE(ctx);
+ return false;
}
continue;
}
-
+
if (strstr_m(line, "backend")) {
/* it's a device, not a virtual printer */
iEtat = 0;
@@ -91,7 +103,8 @@ bool aix_cache_reload(void)
if (!pcap_cache_add(name, NULL)) {
safe_free(line);
x_fclose(pfile);
- return False;
+ TALLOC_FREE(ctx);
+ return false;
}
continue;
}
@@ -100,7 +113,8 @@ bool aix_cache_reload(void)
}
x_fclose(pfile);
- return True;
+ TALLOC_FREE(ctx);
+ return true;
}
#else
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index 2ffd322b45..6e62306d67 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -564,8 +564,8 @@ static int cups_job_submit(int snum, struct printjob *pjob)
cups_lang_t *language = NULL; /* Default language */
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
const char *clientname = NULL; /* hostname of client for job-originating-host attribute */
- pstring new_jobname;
- int num_options = 0;
+ char *new_jobname = NULL;
+ int num_options = 0;
cups_option_t *options = NULL;
char addr[INET6_ADDRSTRLEN];
@@ -627,8 +627,10 @@ static int cups_job_submit(int snum, struct printjob *pjob)
"job-originating-host-name", NULL,
clientname);
- pstr_sprintf(new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX,
- (unsigned int)pjob->smbjob, pjob->jobname);
+ if (asprintf(&new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX,
+ (unsigned int)pjob->smbjob, pjob->jobname) < 0) {
+ goto out;
+ }
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
new_jobname);
@@ -676,6 +678,8 @@ static int cups_job_submit(int snum, struct printjob *pjob)
if (http)
httpClose(http);
+ SAFE_FREE(new_jobname);
+
return ret;
}
diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c
index 8525d6208b..cc4b744a11 100644
--- a/source3/printing/print_generic.c
+++ b/source3/printing/print_generic.c
@@ -24,45 +24,63 @@ extern struct current_user current_user;
extern userdom_struct current_user_info;
/****************************************************************************
-run a given print command
-a null terminated list of value/substitute pairs is provided
-for local substitution strings
+ Run a given print command
+ a null terminated list of value/substitute pairs is provided
+ for local substitution strings
****************************************************************************/
static int print_run_command(int snum, const char* printername, bool do_sub,
const char *command, int *outfd, ...)
{
- pstring syscmd;
+ char *syscmd;
char *arg;
int ret;
+ TALLOC_CTX *ctx = talloc_tos();
va_list ap;
va_start(ap, outfd);
/* check for a valid system printername and valid command to run */
- if ( !printername || !*printername )
+ if ( !printername || !*printername ) {
return -1;
+ }
- if (!command || !*command)
+ if (!command || !*command) {
return -1;
+ }
- pstrcpy(syscmd, command);
+ syscmd = talloc_strdup(ctx, command);
+ if (!syscmd) {
+ return -1;
+ }
while ((arg = va_arg(ap, char *))) {
char *value = va_arg(ap,char *);
- pstring_sub(syscmd, arg, value);
+ syscmd = talloc_string_sub(ctx, syscmd, arg, value);
+ if (!syscmd) {
+ return -1;
+ }
}
va_end(ap);
-
- pstring_sub( syscmd, "%p", printername );
-
- if ( do_sub && snum != -1 )
- standard_sub_advanced(lp_servicename(snum),
- current_user_info.unix_name, "",
- current_user.ut.gid,
- get_current_username(),
- current_user_info.domain,
- syscmd, sizeof(syscmd));
-
+
+ syscmd = talloc_string_sub(ctx, syscmd, "%p", printername);
+ if (!syscmd) {
+ return -1;
+ }
+
+ if (do_sub && snum != -1) {
+ syscmd = talloc_sub_advanced(ctx,
+ lp_servicename(snum),
+ current_user_info.unix_name,
+ "",
+ current_user.ut.gid,
+ get_current_username(),
+ current_user_info.domain,
+ syscmd);
+ if (!syscmd) {
+ return -1;
+ }
+ }
+
ret = smbrun_no_sanitize(syscmd,outfd);
DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
@@ -107,7 +125,7 @@ resume a job
static int generic_job_resume(int snum, struct printjob *pjob)
{
fstring jobstr;
-
+
/* need to pause the spooled entry */
slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
return print_run_command(snum, PRINTERNAME(snum), True,
@@ -122,30 +140,52 @@ static int generic_job_resume(int snum, struct printjob *pjob)
static int generic_job_submit(int snum, struct printjob *pjob)
{
- int ret;
- pstring current_directory;
- pstring print_directory;
- char *wd, *p;
- pstring jobname;
+ int ret = -1;
+ char *current_directory = NULL;
+ char *print_directory = NULL;
+ char *wd = NULL;
+ char *p = NULL;
+ char *jobname = NULL;
+ TALLOC_CTX *ctx = talloc_tos();
fstring job_page_count, job_size;
/* we print from the directory path to give the best chance of
parsing the lpq output */
+ current_directory = TALLOC_ARRAY(ctx,
+ char,
+ PATH_MAX+1);
+ if (!current_directory) {
+ return -1;
+ }
wd = sys_getwd(current_directory);
- if (!wd)
- return 0;
+ if (!wd) {
+ return -1;
+ }
- pstrcpy(print_directory, pjob->filename);
+ print_directory = talloc_strdup(ctx, pjob->filename);
+ if (!print_directory) {
+ return -1;
+ }
p = strrchr_m(print_directory,'/');
- if (!p)
- return 0;
+ if (!p) {
+ return -1;
+ }
*p++ = 0;
- if (chdir(print_directory) != 0)
- return 0;
+ if (chdir(print_directory) != 0) {
+ return -1;
+ }
- pstrcpy(jobname, pjob->jobname);
- pstring_sub(jobname, "'", "_");
+ jobname = talloc_strdup(ctx, pjob->jobname);
+ if (!jobname) {
+ ret = -1;
+ goto out;
+ }
+ jobname = talloc_string_sub(ctx, jobname, "'", "_");
+ if (!jobname) {
+ ret = -1;
+ goto out;
+ }
slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
@@ -159,8 +199,10 @@ static int generic_job_submit(int snum, struct printjob *pjob)
"%c", job_page_count,
NULL);
- chdir(wd);
+ out:
+ chdir(wd);
+ TALLOC_FREE(current_directory);
return ret;
}
diff --git a/source3/printing/printing_db.c b/source3/printing/printing_db.c
index db736765fc..94319f96d0 100644
--- a/source3/printing/printing_db.c
+++ b/source3/printing/printing_db.c
@@ -33,7 +33,7 @@ struct tdb_print_db *get_print_db_byname(const char *printername)
{
struct tdb_print_db *p = NULL, *last_entry = NULL;
int num_open = 0;
- pstring printdb_path;
+ char *printdb_path = NULL;
bool done_become_root = False;
SMB_ASSERT(printername != NULL);
@@ -78,7 +78,7 @@ struct tdb_print_db *get_print_db_byname(const char *printername)
p = print_db_head;
}
}
-
+
if (!p) {
/* Create one. */
p = SMB_MALLOC_P(struct tdb_print_db);
@@ -90,9 +90,13 @@ struct tdb_print_db *get_print_db_byname(const char *printername)
DLIST_ADD(print_db_head, p);
}
- pstrcpy(printdb_path, lock_path("printing/"));
- pstrcat(printdb_path, printername);
- pstrcat(printdb_path, ".tdb");
+ if (asprintf(&printdb_path, "%s%s.tdb",
+ lock_path("printing/"),
+ printername) < 0) {
+ DLIST_REMOVE(print_db_head, p);
+ SAFE_FREE(p);
+ return NULL;
+ }
if (geteuid() != 0) {
become_root();
@@ -109,9 +113,11 @@ struct tdb_print_db *get_print_db_byname(const char *printername)
DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
printdb_path ));
DLIST_REMOVE(print_db_head, p);
+ SAFE_FREE(printdb_path);
SAFE_FREE(p);
return NULL;
}
+ SAFE_FREE(printdb_path);
fstrcpy(p->printer_name, printername);
p->ref_count++;
return p;