*
* 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
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include "includes.h"
/* Map generic permissions to printer object specific permissions */
-GENERIC_MAPPING printer_generic_mapping = {
+const struct generic_mapping printer_generic_mapping = {
PRINTER_READ,
PRINTER_WRITE,
PRINTER_EXECUTE,
PRINTER_ALL_ACCESS
};
-STANDARD_MAPPING printer_std_mapping = {
+const struct standard_mapping printer_std_mapping = {
PRINTER_READ,
PRINTER_WRITE,
PRINTER_EXECUTE,
/* Map generic permissions to print server object specific permissions */
-GENERIC_MAPPING printserver_generic_mapping = {
+const struct generic_mapping printserver_generic_mapping = {
SERVER_READ,
SERVER_WRITE,
SERVER_EXECUTE,
SERVER_ALL_ACCESS
};
-STANDARD_MAPPING printserver_std_mapping = {
+const struct generic_mapping printserver_std_mapping = {
SERVER_READ,
SERVER_WRITE,
SERVER_EXECUTE,
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.dptr = keystr;
- key.dsize = strlen(keystr)+1;
+
+ fstrcpy(share, sharename);
+ strlower_m(share);
+
+ keystr = talloc_asprintf(ctx, "%s%s", PRINTERS_PREFIX, share);
+ key = string_term_tdb_data(keystr ? keystr : "");
return key;
}
generate a new TDB_DATA key for storing a printer security descriptor
****************************************************************************/
-static char* 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;
-
- fstrcpy( share, sharename );
- strlower_m( share );
-
- pstr_sprintf( keystr, "%s%s", SECDESC_PREFIX, share );
+ char *keystr = NULL;
+ TDB_DATA key;
- return keystr;
+ fstrcpy(share, sharename );
+ strlower_m(share);
+
+ keystr = talloc_asprintf(ctx, "%s%s", SECDESC_PREFIX, share);
+ key = string_term_tdb_data(keystr ? keystr : "");
+
+ return key;
}
/****************************************************************************
****************************************************************************/
-static BOOL upgrade_to_version_3(void)
+static bool upgrade_to_version_3(void)
{
TDB_DATA kbuf, newkey, dbuf;
dbuf = tdb_fetch(tdb_drivers, kbuf);
- if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
+ if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) == 0) {
DEBUG(0,("upgrade_to_version_3:moving form\n"));
if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) {
SAFE_FREE(dbuf.dptr);
}
}
- if (strncmp(kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
+ if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
DEBUG(0,("upgrade_to_version_3:moving printer\n"));
if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
SAFE_FREE(dbuf.dptr);
}
}
- if (strncmp(kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
+ if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
SAFE_FREE(dbuf.dptr);
size_t size_new_sec;
DOM_SID sid;
- if (!data.dptr || data.dsize == 0)
+ if (!data.dptr || data.dsize == 0) {
return 0;
+ }
- if ( strncmp( key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 )
+ if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) != 0 ) {
return 0;
+ }
/* upgrade the security descriptor */
ZERO_STRUCT( ps );
prs_init( &ps, 0, ctx, UNMARSHALL );
- prs_give_memory( &ps, data.dptr, data.dsize, True );
+ prs_give_memory( &ps, (char *)data.dptr, data.dsize, False );
if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_orig, &ps, 1 ) ) {
/* delete bad entries */
- DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si. Deleting....\n", key.dptr ));
+ DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si. Deleting....\n",
+ (const char *)key.dptr ));
tdb_delete( tdb_printers, key );
+ prs_mem_free( &ps );
return 0;
}
- sec = sd_orig->sec;
+ if (!sd_orig) {
+ prs_mem_free( &ps );
+ return 0;
+ }
+ sec = sd_orig->sd;
/* is this even valid? */
- if ( !sec->dacl )
+ if ( !sec->dacl ) {
+ prs_mem_free( &ps );
return 0;
+ }
/* update access masks */
for ( i=0; i<sec->dacl->num_aces; i++ ) {
- switch ( sec->dacl->ace[i].info.mask ) {
+ switch ( sec->dacl->aces[i].access_mask ) {
case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):
- sec->dacl->ace[i].info.mask = PRINTER_ACE_PRINT;
+ sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;
break;
case GENERIC_ALL_ACCESS:
- sec->dacl->ace[i].info.mask = PRINTER_ACE_FULL_CONTROL;
+ sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;
break;
case READ_CONTROL_ACCESS:
- sec->dacl->ace[i].info.mask = PRINTER_ACE_MANAGE_DOCUMENTS;
+ sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
default: /* no change */
break;
new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
&sid, &sid,
NULL, NULL, &size_new_sec );
+ if (!new_sec) {
+ prs_mem_free( &ps );
+ return 0;
+ }
sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
+ if (!sd_new) {
+ prs_mem_free( &ps );
+ return 0;
+ }
if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {
DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
+ prs_mem_free( &ps );
return 0;
}
+ prs_mem_free( &ps );
+
/* store it back */
- sd_size = sec_desc_size(sd_store->sec) + sizeof(SEC_DESC_BUF);
+ sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
+ + sizeof(SEC_DESC_BUF);
prs_init(&ps, sd_size, ctx, MARSHALL);
if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_store, &ps, 1 ) ) {
DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
+ prs_mem_free( &ps );
return 0;
}
- data.dptr = prs_data_p( &ps );
+ data.dptr = (uint8 *)prs_data_p( &ps );
data.dsize = sd_size;
result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
/*******************************************************************
*******************************************************************/
-static BOOL upgrade_to_version_4(void)
+static bool upgrade_to_version_4(void)
{
TALLOC_CTX *ctx;
int result;
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( key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
- new_key = make_printer_tdbkey( key.dptr+strlen(PRINTERS_PREFIX) );
+
+ if ( strncmp((const char *) key.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX) ) == 0 ) {
+ new_key = make_printer_tdbkey(ctx, (const char *)key.dptr+strlen(PRINTERS_PREFIX) );
}
- else if ( strncmp( key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
- new_key.dptr = make_printers_secdesc_tdbkey( key.dptr+strlen(SECDESC_PREFIX) );
- new_key.dsize = strlen( new_key.dptr ) + 1;
+ else if ( strncmp((const char *) key.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX) ) == 0 ) {
+ 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;
}
/*******************************************************************
*******************************************************************/
-static BOOL upgrade_to_version_5(void)
+static bool upgrade_to_version_5(void)
{
TALLOC_CTX *ctx;
int result;
Open the NT printing tdbs. Done once before fork().
****************************************************************************/
-BOOL nt_printing_init(void)
+bool nt_printing_init(struct messaging_context *msg_ctx)
{
const char *vstring = "INFO/version";
WERROR win_rc;
if (tdb_drivers)
tdb_close(tdb_drivers);
- tdb_drivers = tdb_open_log(lock_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_drivers) {
DEBUG(0,("nt_printing_init: Failed to open nt drivers database %s (%s)\n",
- lock_path("ntdrivers.tdb"), strerror(errno) ));
+ state_path("ntdrivers.tdb"), strerror(errno) ));
return False;
}
if (tdb_printers)
tdb_close(tdb_printers);
- tdb_printers = tdb_open_log(lock_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_printers) {
DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
- lock_path("ntprinters.tdb"), strerror(errno) ));
+ state_path("ntprinters.tdb"), strerror(errno) ));
return False;
}
if (tdb_forms)
tdb_close(tdb_forms);
- tdb_forms = tdb_open_log(lock_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+ tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
if (!tdb_forms) {
DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
- lock_path("ntforms.tdb"), strerror(errno) ));
+ state_path("ntforms.tdb"), strerror(errno) ));
return False;
}
* drivers are installed
*/
- message_register( MSG_PRINTER_DRVUPGRADE, do_drv_upgrade_printer );
+ messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
+ do_drv_upgrade_printer);
/*
* register callback to handle updating printer data
* when a driver is initialized
*/
- message_register( MSG_PRINTERDATA_INIT_RESET, reset_all_printerdata );
+ messaging_register(msg_ctx, NULL, MSG_PRINTERDATA_INIT_RESET,
+ reset_all_printerdata);
/* of course, none of the message callbacks matter if you don't
tell messages.c that you interested in receiving PRINT_GENERAL
Function to allow filename parsing "the old way".
********************************************************************/
-static BOOL driver_unix_convert(char *name,connection_struct *conn,
- char *saved_last_component, BOOL *bad_path, SMB_STRUCT_STAT *pst)
+static char *driver_unix_convert(connection_struct *conn,
+ const char *old_name,
+ SMB_STRUCT_STAT *pst)
{
+ TALLOC_CTX *ctx = talloc_tos();
+ char *name = talloc_strdup(ctx, old_name);
+ char *new_name = NULL;
+
+ if (!name) {
+ return NULL;
+ }
unix_format(name);
- unix_clean_name(name);
+ name = unix_clean_name(ctx, name);
+ if (!name) {
+ return NULL;
+ }
trim_string(name,"/","/");
- return unix_convert(name, conn, saved_last_component, bad_path, pst);
+ unix_convert(ctx,conn, name, false, &new_name, NULL, pst);
+ return new_name;
}
/*******************************************************************
each add or delete printer RPC. Only Microsoft knows why... JRR020119
********************************************************************/
-uint32 update_c_setprinter(BOOL initialize)
+uint32 update_c_setprinter(bool initialize)
{
int32 c_setprinter;
int32 printer_count = 0;
- tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER, 0);
+ tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
/* Traverse the tdb, counting the printers */
tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
int get_builtin_ntforms(nt_forms_struct **list)
{
*list = (nt_forms_struct *)memdup(&default_forms[0], sizeof(default_forms));
+ if (!*list) {
+ return 0;
+ }
return sizeof(default_forms) / sizeof(default_forms[0]);
}
get a builtin form struct
****************************************************************************/
-BOOL get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
+bool get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
{
int i,count;
fstring form_name;
- unistr2_to_ascii(form_name, uni_formname, sizeof(form_name)-1);
+ unistr2_to_ascii(form_name, uni_formname, sizeof(form_name));
DEBUGADD(6,("Looking for builtin form %s \n", form_name));
count = sizeof(default_forms) / sizeof(default_forms[0]);
for (i=0;i<count;i++) {
}
/****************************************************************************
-get a form struct list
+ get a form struct list.
****************************************************************************/
+
int get_ntforms(nt_forms_struct **list)
{
TDB_DATA kbuf, newkey, dbuf;
- nt_forms_struct *tl;
nt_forms_struct form;
int ret;
int i;
int n = 0;
+ *list = NULL;
+
for (kbuf = tdb_firstkey(tdb_forms);
kbuf.dptr;
newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey)
{
- if (strncmp(kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
+ if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
continue;
dbuf = tdb_fetch(tdb_forms, kbuf);
if (!dbuf.dptr)
continue;
- fstrcpy(form.name, kbuf.dptr+strlen(FORMS_PREFIX));
+ fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));
ret = tdb_unpack(dbuf.dptr, dbuf.dsize, "dddddddd",
&i, &form.flag, &form.width, &form.length, &form.left,
&form.top, &form.right, &form.bottom);
if (ret != dbuf.dsize)
continue;
- tl = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
- if (!tl) {
+ *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
+ if (!*list) {
DEBUG(0,("get_ntforms: Realloc fail.\n"));
return 0;
}
- *list = tl;
(*list)[n] = form;
n++;
}
/****************************************************************************
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 kbuf,dbuf;
+ TDB_DATA dbuf;
int i;
for (i=0;i<number;i++) {
/* save index, so list is rebuilt in correct order */
- len = tdb_pack(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);
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
+ 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 = buf;
- if (tdb_store(tdb_forms, kbuf, dbuf, TDB_REPLACE) != 0) break;
+ dbuf.dptr = (uint8 *)buf;
+ 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;
/****************************************************************************
add a form struct at the end of the list
****************************************************************************/
-BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count)
+bool add_a_form(nt_forms_struct **list, const FORM *form, int *count)
{
int n=0;
- BOOL update;
+ bool update;
fstring form_name;
- nt_forms_struct *tl;
/*
* NT tries to add forms even when
update=False;
- unistr2_to_ascii(form_name, &form->name, sizeof(form_name)-1);
+ unistr2_to_ascii(form_name, &form->name, sizeof(form_name));
for (n=0; n<*count; n++) {
if ( strequal((*list)[n].name, form_name) ) {
update=True;
}
if (update==False) {
- if((tl=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {
+ if((*list=SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1)) == NULL) {
DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
return False;
}
- *list = tl;
- unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name)-1);
+ unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name));
(*count)++;
}
Delete a named form struct.
****************************************************************************/
-BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
+bool delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
{
- pstring key;
- TDB_DATA kbuf;
+ char *key = NULL;
int n=0;
fstring form_name;
*ret = WERR_OK;
- unistr2_to_ascii(form_name, del_name, sizeof(form_name)-1);
+ unistr2_to_ascii(form_name, del_name, sizeof(form_name));
for (n=0; n<*count; n++) {
if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
return False;
}
- slprintf(key, sizeof(key)-1, "%s%s", FORMS_PREFIX, (*list)[n].name);
- kbuf.dsize = strlen(key)+1;
- kbuf.dptr = key;
- if (tdb_delete(tdb_forms, kbuf) != 0) {
+ 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;
}
/****************************************************************************
{
int n=0;
fstring form_name;
- unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
+ unistr2_to_ascii(form_name, &(form->name), sizeof(form_name));
DEBUG(106, ("[%s]\n", form_name));
for (n=0; n<count; n++) {
{
int total=0;
const char *short_archi;
- fstring *fl;
- pstring key;
+ char *key = NULL;
TDB_DATA kbuf, newkey;
short_archi = get_short_archi(architecture);
- slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
+ if (!short_archi) {
+ return 0;
+ }
+
+ if (asprintf(&key, "%s%s/%d/", DRIVERS_PREFIX,
+ short_archi, version) < 0) {
+ return 0;
+ }
for (kbuf = tdb_firstkey(tdb_drivers);
kbuf.dptr;
newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
- if (strncmp(kbuf.dptr, key, strlen(key)) != 0)
+ if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0)
continue;
-
- if((fl = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {
+
+ if((*list = SMB_REALLOC_ARRAY(*list, fstring, total+1)) == NULL) {
DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
+ SAFE_FREE(key);
return -1;
}
- else *list = fl;
- fstrcpy((*list)[total], kbuf.dptr+strlen(key));
+ fstrcpy((*list)[total], (const char *)kbuf.dptr+strlen(key));
total++;
}
+ SAFE_FREE(key);
return(total);
}
/****************************************************************************
-function to do the mapping between the long architecture name and
-the short one.
+ Function to do the mapping between the long architecture name and
+ the short one.
****************************************************************************/
+
const char *get_short_archi(const char *long_archi)
{
int i=-1;
/* this might be client code - but shouldn't this be an fstrcpy etc? */
-
DEBUGADD(108,("index: [%d]\n", i));
DEBUGADD(108,("long architecture: [%s]\n", archi_table[i].long_archi));
DEBUGADD(108,("short architecture: [%s]\n", archi_table[i].short_archi));
char *buf = NULL;
ssize_t byte_count;
- if ((buf=SMB_MALLOC(PE_HEADER_SIZE)) == NULL) {
- DEBUG(0,("get_file_version: PE file [%s] PE Header malloc failed bytes = %d\n",
- fname, PE_HEADER_SIZE));
+ if ((buf=(char *)SMB_MALLOC(DOS_HEADER_SIZE)) == NULL) {
+ DEBUG(0,("get_file_version: PE file [%s] DOS Header malloc failed bytes = %d\n",
+ fname, DOS_HEADER_SIZE));
goto error_exit;
}
- /* Note: DOS_HEADER_SIZE < malloc'ed PE_HEADER_SIZE */
if ((byte_count = vfs_read_data(fsp, buf, DOS_HEADER_SIZE)) < DOS_HEADER_SIZE) {
DEBUG(3,("get_file_version: File [%s] DOS header too short, bytes read = %lu\n",
fname, (unsigned long)byte_count));
}
/* Skip OEM header (if any) and the DOS stub to start of Windows header */
- if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
+ if (SMB_VFS_LSEEK(fsp, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
DEBUG(3,("get_file_version: File [%s] too short, errno = %d\n",
fname, errno));
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
goto no_version_info;
}
- if ((byte_count = vfs_read_data(fsp, buf, PE_HEADER_SIZE)) < PE_HEADER_SIZE) {
+ /* Note: DOS_HEADER_SIZE and NE_HEADER_SIZE are incidentally same */
+ if ((byte_count = vfs_read_data(fsp, buf, NE_HEADER_SIZE)) < NE_HEADER_SIZE) {
DEBUG(3,("get_file_version: File [%s] Windows header too short, bytes read = %lu\n",
fname, (unsigned long)byte_count));
/* Assume this isn't an error... the file just looks sort of like a PE/NE file */
if (IVAL(buf,PE_HEADER_SIGNATURE_OFFSET) == PE_HEADER_SIGNATURE) {
unsigned int num_sections;
unsigned int section_table_bytes;
-
- if (SVAL(buf,PE_HEADER_MACHINE_OFFSET) != PE_HEADER_MACHINE_I386) {
- DEBUG(3,("get_file_version: PE file [%s] wrong machine = 0x%x\n",
- fname, SVAL(buf,PE_HEADER_MACHINE_OFFSET)));
- /* At this point, we assume the file is in error. It still could be somthing
- * else besides a PE file, but it unlikely at this point.
- */
+
+ /* Just skip over optional header to get to section table */
+ if (SMB_VFS_LSEEK(fsp,
+ SVAL(buf,PE_HEADER_OPTIONAL_HEADER_SIZE)-(NE_HEADER_SIZE-PE_HEADER_SIZE),
+ SEEK_CUR) == (SMB_OFF_T)-1) {
+ DEBUG(3,("get_file_version: File [%s] Windows optional header too short, errno = %d\n",
+ fname, errno));
goto error_exit;
}
goto error_exit;
SAFE_FREE(buf);
- if ((buf=SMB_MALLOC(section_table_bytes)) == NULL) {
+ if ((buf=(char *)SMB_MALLOC(section_table_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] section table malloc failed bytes = %d\n",
fname, section_table_bytes));
goto error_exit;
goto error_exit;
SAFE_FREE(buf);
- if ((buf=SMB_MALLOC(section_bytes)) == NULL) {
+ if ((buf=(char *)SMB_MALLOC(section_bytes)) == NULL) {
DEBUG(0,("get_file_version: PE file [%s] version malloc failed bytes = %d\n",
fname, section_bytes));
goto error_exit;
}
/* Seek to the start of the .rsrc section info */
- if (SMB_VFS_LSEEK(fsp, fsp->fh->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
+ if (SMB_VFS_LSEEK(fsp, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
DEBUG(3,("get_file_version: PE file [%s] too short for section info, errno = %d\n",
fname, errno));
goto error_exit;
if (IVAL(buf,pos) == VS_MAGIC_VALUE) {
*major = IVAL(buf,pos+VS_MAJOR_OFFSET);
*minor = IVAL(buf,pos+VS_MINOR_OFFSET);
-
+
DEBUG(6,("get_file_version: PE file [%s] Version = %08x:%08x (%d.%d.%d.%d)\n",
fname, *major, *minor,
(*major>>16)&0xffff, *major&0xffff,
/* Allocate a bit more space to speed up things */
SAFE_FREE(buf);
- if ((buf=SMB_MALLOC(VS_NE_BUF_SIZE)) == NULL) {
+ if ((buf=(char *)SMB_MALLOC(VS_NE_BUF_SIZE)) == NULL) {
DEBUG(0,("get_file_version: NE file [%s] malloc failed bytes = %d\n",
fname, PE_HEADER_SIZE));
goto error_exit;
* twice, as it is simpler to read the code. */
if (strcmp(&buf[i], VS_SIGNATURE) == 0) {
/* Compute skip alignment to next long address */
- int skip = -(SMB_VFS_LSEEK(fsp, fsp->fh->fd, 0, SEEK_CUR) - (byte_count - i) +
+ int skip = -(SMB_VFS_LSEEK(fsp, 0, SEEK_CUR) - (byte_count - i) +
sizeof(VS_SIGNATURE)) & 3;
if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
{
- BOOL use_version = True;
- pstring filepath;
+ bool use_version = true;
+ char *filepath = NULL;
uint32 new_major;
uint32 new_minor;
files_struct *fsp = NULL;
SMB_STRUCT_STAT st;
SMB_STRUCT_STAT stat_buf;
- BOOL bad_path;
+
+ NTSTATUS status;
SET_STAT_INVALID(st);
SET_STAT_INVALID(stat_buf);
old_create_time = (time_t)0;
/* Get file version info (if available) for previous file (if it exists) */
- pstrcpy(filepath, old_file);
-
- driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
+ filepath = driver_unix_convert(conn,old_file,&stat_buf);
+ if (!filepath) {
+ goto error_exit;
+ }
- fsp = open_file_ntcreate(conn, filepath, &stat_buf,
+ status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
INTERNAL_OPEN_ONLY,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
/* Old file not found, so by definition new file is in fact newer */
DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
filepath, errno));
- return True;
+ return 1;
} else {
int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
if (!ret) {
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
old_file));
- use_version = False;
- if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) goto error_exit;
+ use_version = false;
+ if (SMB_VFS_FSTAT(fsp, &st) == -1) {
+ goto error_exit;
+ }
old_create_time = st.st_mtime;
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
}
}
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
/* Get file version info (if available) for new file */
- pstrcpy(filepath, new_file);
- driver_unix_convert(filepath,conn,NULL,&bad_path,&stat_buf);
+ filepath = driver_unix_convert(conn,new_file,&stat_buf);
+ if (!filepath) {
+ goto error_exit;
+ }
- fsp = open_file_ntcreate(conn, filepath, &stat_buf,
+ status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
INTERNAL_OPEN_ONLY,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
/* New file not found, this shouldn't occur if the caller did its job */
DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
filepath, errno));
if (!ret) {
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
new_file));
- use_version = False;
- if (SMB_VFS_FSTAT(fsp, fsp->fh->fd, &st) == -1) goto error_exit;
+ use_version = false;
+ if (SMB_VFS_FSTAT(fsp, &st) == -1) {
+ goto error_exit;
+ }
new_create_time = st.st_mtime;
DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
}
}
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
if (use_version && (new_major != old_major || new_minor != old_minor)) {
/* Compare versions and choose the larger version number */
if (new_major > old_major ||
(new_major == old_major && new_minor > old_minor)) {
-
+
DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
- return True;
+ return 1;
}
else {
DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
- return False;
+ return 0;
}
} else {
/* Compare modification time/dates and choose the newest time/date */
if (new_create_time > old_create_time) {
DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
- return True;
+ return 1;
}
else {
DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
- return False;
+ return 0;
}
}
error_exit:
if(fsp)
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
return -1;
}
{
int cversion;
NTSTATUS nt_status;
- pstring driverpath;
+ char *driverpath = NULL;
DATA_BLOB null_pw;
fstring res_type;
files_struct *fsp = NULL;
- BOOL bad_path;
SMB_STRUCT_STAT st;
connection_struct *conn;
+ NTSTATUS status;
SET_STAT_INVALID(st);
*/
/* Null password is ok - we are already an authenticated user... */
- null_pw = data_blob(NULL, 0);
+ 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);
/* Open the driver file (Portable Executable format) and determine the
* deriver the cversion. */
- slprintf(driverpath, sizeof(driverpath)-1, "%s/%s", architecture, driverpath_in);
+ driverpath = talloc_asprintf(talloc_tos(),
+ "%s/%s",
+ architecture,
+ driverpath_in);
+ if (!driverpath) {
+ *perr = WERR_NOMEM;
+ goto error_exit;
+ }
- driver_unix_convert(driverpath,conn,NULL,&bad_path,&st);
+ driverpath = driver_unix_convert(conn,driverpath,&st);
+ if (!driverpath) {
+ *perr = WERR_NOMEM;
+ goto error_exit;
+ }
- if ( !vfs_file_exist( conn, driverpath, &st ) ) {
+ if (!vfs_file_exist(conn, driverpath, &st)) {
*perr = WERR_BADFILE;
goto error_exit;
}
- fsp = open_file_ntcreate(conn, driverpath, &st,
+ status = open_file_ntcreate(conn, NULL, driverpath, &st,
FILE_GENERIC_READ,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN,
0,
FILE_ATTRIBUTE_NORMAL,
INTERNAL_OPEN_ONLY,
- NULL);
+ NULL, &fsp);
- if (!fsp) {
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
driverpath, errno));
*perr = WERR_ACCESS_DENIED;
DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
driverpath, cversion));
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
close_cnum(conn, user->vuid);
unbecome_user();
*perr = WERR_OK;
error_exit:
if(fsp)
- close_file(fsp, True);
+ close_file(fsp, NORMAL_CLOSE);
close_cnum(conn, user->vuid);
unbecome_user();
}
architecture = get_short_archi(driver->environment);
+ if (!architecture) {
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
/* jfm:7/16/2000 the client always sends the cversion=0.
* The server should check which version the driver is by reading
* NT2K: cversion=3
*/
if ((driver->cversion = get_correct_cversion( architecture, driver->driverpath, user, &err)) == -1)
- return err;
+ return err;
return WERR_OK;
}
}
architecture = get_short_archi(driver->environment);
+ if (!architecture) {
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
/* jfm:7/16/2000 the client always sends the cversion=0.
* The server should check which version the driver is by reading
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
const char *architecture;
- pstring new_dir;
- pstring old_name;
- pstring new_name;
+ char *new_dir = NULL;
+ char *old_name = NULL;
+ char *new_name = NULL;
DATA_BLOB null_pw;
connection_struct *conn;
NTSTATUS nt_status;
- pstring inbuf;
- pstring outbuf;
fstring res_type;
- BOOL bad_path;
SMB_STRUCT_STAT st;
- int ver = 0;
int i;
- int err;
+ TALLOC_CTX *ctx = talloc_tos();
+ int ver = 0;
- memset(inbuf, '\0', sizeof(inbuf));
- memset(outbuf, '\0', sizeof(outbuf));
*perr = WERR_OK;
if (level==3)
}
architecture = get_short_archi(driver->environment);
+ if (!architecture) {
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
/*
* 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, 0);
+ 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);
return WERR_ACCESS_DENIED;
}
+ /* WE ARE NOW RUNNING AS USER conn->vuid !!!!! */
+
/*
* make the directories version and version\driver_name
* under the architecture directory.
*/
DEBUG(5,("Creating first directory\n"));
- slprintf(new_dir, sizeof(new_dir)-1, "%s/%d", architecture, driver->cversion);
- driver_unix_convert(new_dir, conn, NULL, &bad_path, &st);
- mkdir_internal(conn, new_dir, bad_path);
+ new_dir = talloc_asprintf(ctx,
+ "%s/%d",
+ architecture,
+ driver->cversion);
+ if (!new_dir) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ new_dir = driver_unix_convert(conn,new_dir,&st);
+ if (!new_dir) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+
+ create_directory(conn, NULL, new_dir);
/* For each driver file, archi\filexxx.yyy, if there is a duplicate file
* listed for this driver which has already been moved, skip it (note:
DEBUG(5,("Moving files now !\n"));
if (driver->driverpath && strlen(driver->driverpath)) {
- slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);
- slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);
+ new_name = talloc_asprintf(ctx,
+ "%s/%s",
+ architecture,
+ driver->driverpath);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ old_name = talloc_asprintf(ctx,
+ "%s/%s",
+ new_dir,
+ driver->driverpath);
+ if (!old_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
+ new_name = driver_unix_convert(conn,new_name,&st);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
+ OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
*perr = WERR_ACCESS_DENIED;
ver = -1;
}
- }
+ }
}
if (driver->datafile && strlen(driver->datafile)) {
if (!strequal(driver->datafile, driver->driverpath)) {
- slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);
- slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);
+ new_name = talloc_asprintf(ctx,
+ "%s/%s",
+ architecture,
+ driver->datafile);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ old_name = talloc_asprintf(ctx,
+ "%s/%s",
+ new_dir,
+ driver->datafile);
+ if (!old_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
+ new_name = driver_unix_convert(conn,new_name,&st);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
+ OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
*perr = WERR_ACCESS_DENIED;
if (driver->configfile && strlen(driver->configfile)) {
if (!strequal(driver->configfile, driver->driverpath) &&
!strequal(driver->configfile, driver->datafile)) {
- slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);
- slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);
+ new_name = talloc_asprintf(ctx,
+ "%s/%s",
+ architecture,
+ driver->configfile);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ old_name = talloc_asprintf(ctx,
+ "%s/%s",
+ new_dir,
+ driver->configfile);
+ if (!old_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
+ new_name = driver_unix_convert(conn,new_name,&st);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
+ OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
*perr = WERR_ACCESS_DENIED;
if (!strequal(driver->helpfile, driver->driverpath) &&
!strequal(driver->helpfile, driver->datafile) &&
!strequal(driver->helpfile, driver->configfile)) {
- slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);
- slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);
+ new_name = talloc_asprintf(ctx,
+ "%s/%s",
+ architecture,
+ driver->helpfile);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ old_name = talloc_asprintf(ctx,
+ "%s/%s",
+ new_dir,
+ driver->helpfile);
+ if (!old_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- if ( !copy_file(new_name, old_name, conn, OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
+ new_name = driver_unix_convert(conn,new_name,&st);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
+ OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
*perr = WERR_ACCESS_DENIED;
}
}
- slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);
- slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);
+ new_name = talloc_asprintf(ctx,
+ "%s/%s",
+ architecture,
+ driver->dependentfiles[i]);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ old_name = talloc_asprintf(ctx,
+ "%s/%s",
+ new_dir,
+ driver->dependentfiles[i]);
+ if (!old_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
- driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
- if ( !copy_file(new_name, old_name, conn,
+ new_name = driver_unix_convert(conn,new_name,&st);
+ if (!new_name) {
+ *perr = WERR_NOMEM;
+ goto err_exit;
+ }
+ if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name,
OPENX_FILE_EXISTS_TRUNCATE|
- OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
+ OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
new_name, old_name));
*perr = WERR_ACCESS_DENIED;
}
}
+ err_exit:
+
close_cnum(conn, user->vuid);
unbecome_user();
- return ver != -1 ? WERR_OK : WERR_UNKNOWN_PRINTER_DRIVER;
+ if (W_ERROR_EQUAL(*perr, WERR_OK)) {
+ return WERR_OK;
+ }
+ if (ver == -1) {
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
+ return (*perr);
}
/****************************************************************************
****************************************************************************/
+
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 *buf;
+ char *key = NULL;
+ uint8 *buf;
int i, ret;
- TDB_DATA kbuf, dbuf;
+ TDB_DATA dbuf;
architecture = get_short_archi(driver->environment);
+ if (!architecture) {
+ return (uint32)-1;
+ }
/* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
* \\server is added in the rpc server layer.
* 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:
}
}
- 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 ));
}
if (len != buflen) {
- char *tb;
-
- tb = (char *)SMB_REALLOC(buf, len);
- if (!tb) {
+ buf = (uint8 *)SMB_REALLOC(buf, len);
+ if (!buf) {
DEBUG(0,("add_a_printer_driver_3: failed to enlarge buffer\n!"));
ret = -1;
goto done;
}
- else buf = tb;
buflen = len;
goto again;
}
-
- kbuf.dptr = key;
- kbuf.dsize = strlen(key)+1;
dbuf.dptr = buf;
dbuf.dsize = len;
-
- ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
+
+ ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE);
done:
if (ret)
memset(info.dependentfiles, '\0', 2*sizeof(fstring));
fstrcpy(info.dependentfiles[0], "");
- *info_ptr = memdup(&info, sizeof(info));
+ *info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&info, sizeof(info));
+ if (!*info_ptr) {
+ SAFE_FREE(info.dependentfiles);
+ return WERR_NOMEM;
+ }
return WERR_OK;
}
static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, const char *arch, uint32 version)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
- TDB_DATA kbuf, dbuf;
+ TDB_DATA dbuf;
const char *architecture;
int len = 0;
int i;
- pstring key;
+ char *key = NULL;
ZERO_STRUCT(driver);
architecture = get_short_archi(arch);
-
- if ( !architecture )
+ 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;
+ }
- kbuf.dptr = key;
- kbuf.dsize = strlen(key)+1;
-
- dbuf = tdb_fetch(tdb_drivers, kbuf);
- if (!dbuf.dptr)
+ dbuf = tdb_fetch_bystring(tdb_drivers, key);
+ if (!dbuf.dptr) {
+ SAFE_FREE(key);
return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
&driver.cversion,
i=0;
while (len < dbuf.dsize) {
- fstring *tddfs;
-
- tddfs = SMB_REALLOC_ARRAY(driver.dependentfiles, fstring, i+2);
- if ( !tddfs ) {
+ driver.dependentfiles = SMB_REALLOC_ARRAY(driver.dependentfiles, fstring, i+2);
+ if ( !driver.dependentfiles ) {
DEBUG(0,("get_a_printer_driver_3: failed to enlarge buffer!\n"));
break;
}
- else
- driver.dependentfiles = tddfs;
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "f",
&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);
}
*info_ptr = (NT_PRINTER_DRIVER_INFO_LEVEL_3 *)memdup(&driver, sizeof(driver));
+ if (!*info_ptr) {
+ SAFE_FREE(driver.dependentfiles);
+ return WERR_NOMEM;
+ }
return WERR_OK;
}
/****************************************************************************
****************************************************************************/
-int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
+int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen)
{
int len = 0;
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,
/****************************************************************************
Pack all values in all printer keys
***************************************************************************/
-
-static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
+
+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,
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;
uint32 del_a_printer(const char *sharename)
{
- pstring key;
TDB_DATA kbuf;
- pstring printdb_path;
+ char *printdb_path = NULL;
+ TALLOC_CTX *ctx = talloc_tos();
- slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
- kbuf.dptr=key;
- kbuf.dsize=strlen(key)+1;
+ kbuf = make_printer_tdbkey(ctx, sharename);
tdb_delete(tdb_printers, kbuf);
- slprintf(key, sizeof(key)-1, "%s%s", SECDESC_PREFIX, sharename);
- kbuf.dptr=key;
- kbuf.dsize=strlen(key)+1;
+ 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;
****************************************************************************/
static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
{
- char *buf;
+ uint8 *buf;
int buflen, len;
+ int retlen;
WERROR ret;
TDB_DATA kbuf, dbuf;
buf = NULL;
buflen = 0;
- again:
+ again:
len = 0;
len += tdb_pack(buf+len, buflen-len, "dddddddddddfffffPfffff",
info->attributes,
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) {
- char *tb;
-
- tb = (char *)SMB_REALLOC(buf, len);
- if (!tb) {
+ buf = (uint8 *)SMB_REALLOC(buf, len);
+ if (!buf) {
DEBUG(0,("update_a_printer_2: failed to enlarge buffer!\n"));
ret = WERR_NOMEM;
goto done;
}
- else buf = tb;
buflen = len;
goto again;
}
-
- kbuf = make_printer_tdbkey( info->sharename );
+ kbuf = make_printer_tdbkey(talloc_tos(), info->sharename );
dbuf.dptr = buf;
dbuf.dsize = len;
new_nt_devicemode->nt_dev_private = NULL;
if (nt_devicemode->nt_dev_private != NULL) {
- if ((new_nt_devicemode->nt_dev_private = memdup(nt_devicemode->nt_dev_private, nt_devicemode->driverextra)) == NULL) {
+ if ((new_nt_devicemode->nt_dev_private = (uint8 *)memdup(nt_devicemode->nt_dev_private, nt_devicemode->driverextra)) == NULL) {
SAFE_FREE(new_nt_devicemode);
DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
return NULL;
/****************************************************************************
****************************************************************************/
-int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
+int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
{
int len = 0;
int extra_len = 0;
}
*nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
+ if (!*nt_devmode) {
+ SAFE_FREE(devmode.nt_dev_private);
+ return -1;
+ }
DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
if (devmode.nt_dev_private)
int key_len;
int num_subkeys = 0;
char *p;
- fstring *ptr, *subkeys_ptr = NULL;
+ fstring *subkeys_ptr = NULL;
fstring subkeyname;
+ *subkeys = NULL;
+
if ( !data )
return 0;
/* found a match, so allocate space and copy the name */
- if ( !(ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
+ if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
num_subkeys+1));
- SAFE_FREE( subkeys );
return -1;
}
- subkeys_ptr = ptr;
fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
num_subkeys++;
}
/* found a match, so allocate space and copy the name */
- if ( !(ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
+ if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
num_subkeys+1));
- SAFE_FREE( subkeys );
return 0;
}
- subkeys_ptr = ptr;
fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
num_subkeys++;
}
/* return error if the key was not found */
- if ( i == data->num_keys )
+ if ( i == data->num_keys ) {
+ SAFE_FREE(subkeys_ptr);
return -1;
+ }
done:
/* tag off the end */
}
static void map_bool_into_ctr(REGVAL_CTR *ctr, const char *val_name,
- BOOL b)
+ bool b)
{
uint8 bin_bool = (b ? 1 : 0);
regval_ctr_delvalue(ctr, val_name);
* Map the NT_PRINTER_INFO_LEVEL_2 data into DsSpooler keys for publishing.
*
* @param info2 NT_PRINTER_INFO_LEVEL_2 describing printer - gets modified
- * @return BOOL indicating success or failure
+ * @return bool indicating success or failure
***************************************************************************/
-static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
+static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
{
REGVAL_CTR *ctr = NULL;
fstring longname;
- fstring dnssuffix;
+ const char *dnssuffix;
char *allocated_string = NULL;
const char *ascii_str;
int i;
map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
- /* we make the assumption that the netbios name is the same
- as the DNS name sinc ethe former will be what we used to
+ /* we make the assumption that the netbios name is the same
+ as the DNS name sinc ethe former will be what we used to
join the domain */
- if ( get_mydnsdomname( dnssuffix ) )
+ dnssuffix = get_mydnsdomname(talloc_tos());
+ if (dnssuffix && *dnssuffix) {
fstr_sprintf( longname, "%s.%s", global_myname(), dnssuffix );
- else
+ } else {
fstrcpy( longname, global_myname() );
-
+ }
+
map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename);
return True;
}
+/*****************************************************************
+ ****************************************************************/
+
static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
- struct uuid guid)
+ struct GUID guid)
{
int i;
REGVAL_CTR *ctr=NULL;
+ UNISTR2 unistr_guid;
/* find the DsSpooler key */
if ((i = lookup_printerkey(info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
ctr = info2->data->keys[i].values;
regval_ctr_delvalue(ctr, "objectGUID");
- regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY,
- (char *) &guid, sizeof(struct uuid));
+
+ /* We used to store this as a REG_BINARY but that causes
+ Vista to whine */
+
+ ZERO_STRUCT( unistr_guid );
+
+ init_unistr2( &unistr_guid, smb_uuid_string(talloc_tos(), guid),
+ UNI_STR_TERMINATE );
+
+ regval_ctr_addvalue(ctr, "objectGUID", REG_SZ,
+ (char *)unistr_guid.buffer,
+ unistr_guid.uni_max_len*2);
+
}
static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
NT_PRINTER_INFO_LEVEL *printer)
{
ADS_STATUS ads_rc;
- void *res;
- char *prt_dn = NULL, *srv_dn, *srv_cn_0;
+ LDAPMessage *res;
+ char *prt_dn = NULL, *srv_dn, *srv_cn_0, *srv_cn_escaped, *sharename_escaped;
char *srv_dn_utf8, **srv_cn_utf8;
TALLOC_CTX *ctx;
ADS_MODLIST mods;
const char *attrs[] = {"objectGUID", NULL};
- struct uuid guid;
+ struct GUID guid;
WERROR win_rc = WERR_OK;
DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
/* We use ldap_get_dn here as we need the answer
* in utf8 to call ldap_explode_dn(). JRA. */
- srv_dn_utf8 = ldap_get_dn(ads->ld, res);
+ srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
if (!srv_dn_utf8) {
ads_destroy(&ads);
return WERR_SERVER_UNAVAILABLE;
ldap_memfree(srv_dn_utf8);
ldap_memfree(srv_cn_utf8);
- asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn_0,
- printer->info_2->sharename, srv_dn);
+ srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
+ if (!srv_cn_escaped) {
+ SAFE_FREE(srv_cn_0);
+ ldap_memfree(srv_dn_utf8);
+ ads_destroy(&ads);
+ return WERR_SERVER_UNAVAILABLE;
+ }
+ sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename);
+ if (!sharename_escaped) {
+ SAFE_FREE(srv_cn_escaped);
+ SAFE_FREE(srv_cn_0);
+ ldap_memfree(srv_dn_utf8);
+ ads_destroy(&ads);
+ return WERR_SERVER_UNAVAILABLE;
+ }
+
+
+ asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
SAFE_FREE(srv_dn);
SAFE_FREE(srv_cn_0);
+ SAFE_FREE(srv_cn_escaped);
+ SAFE_FREE(sharename_escaped);
/* build the ads mods */
ctx = talloc_init("nt_printer_publish_ads");
+ if (ctx == NULL) {
+ SAFE_FREE(prt_dn);
+ return WERR_NOMEM;
+ }
+
mods = ads_init_mods(ctx);
+ if (mods == NULL) {
+ SAFE_FREE(prt_dn);
+ talloc_destroy(ctx);
+ return WERR_NOMEM;
+ }
+
get_local_printer_publishing_data(ctx, &mods, printer->info_2->data);
ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
printer->info_2->sharename);
NT_PRINTER_INFO_LEVEL *printer)
{
ADS_STATUS ads_rc;
- void *res;
+ LDAPMessage *res;
char *prt_dn = NULL;
DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername));
if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
prt_dn = ads_get_dn(ads, res);
+ if (!prt_dn) {
+ ads_msgfree(ads, res);
+ return WERR_NOMEM;
+ }
ads_rc = ads_del_dn(ads, prt_dn);
ads_memfree(ads, prt_dn);
}
goto done;
}
- ads = ads_init(NULL, NULL, NULL);
+ ads = ads_init(lp_realm(), lp_workgroup(), NULL);
if (!ads) {
DEBUG(3, ("ads_init() failed\n"));
win_rc = WERR_SERVER_UNAVAILABLE;
int n_services = lp_numservices();
NT_PRINTER_INFO_LEVEL *printer = NULL;
- ads = ads_init(NULL, NULL, NULL);
+ ads = ads_init(lp_realm(), lp_workgroup(), NULL);
if (!ads) {
DEBUG(3, ("ads_init() failed\n"));
return WERR_SERVER_UNAVAILABLE;
if (!ADS_ERR_OK(ads_rc)) {
DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
ads_destroy(&ads);
+ ads_kdestroy("MEMORY:prtpub_cache");
return WERR_ACCESS_DENIED;
}
}
ads_destroy(&ads);
+ ads_kdestroy("MEMORY:prtpub_cache");
return WERR_OK;
}
-BOOL is_printer_published(Printer_entry *print_hnd, int snum,
- struct uuid *guid)
+bool is_printer_published(Printer_entry *print_hnd, int snum,
+ struct GUID *guid)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
REGVAL_CTR *ctr;
REGISTRY_VALUE *guid_val;
WERROR win_rc;
int i;
+ bool ret = False;
win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
return False;
}
- /* fetching printer guids really ought to be a separate function.. */
- if (guid && regval_size(guid_val) == sizeof(struct uuid))
- memcpy(guid, regval_data_p(guid_val), sizeof(struct uuid));
+ /* fetching printer guids really ought to be a separate function. */
+
+ if ( guid ) {
+ fstring guid_str;
+
+ /* We used to store the guid as REG_BINARY, then swapped
+ to REG_SZ for Vista compatibility so check for both */
+
+ switch ( regval_type(guid_val) ){
+ case REG_SZ:
+ rpcstr_pull( guid_str, regval_data_p(guid_val),
+ sizeof(guid_str)-1, -1, STR_TERMINATE );
+ ret = smb_string_to_uuid( guid_str, guid );
+ break;
+ case REG_BINARY:
+ if ( regval_size(guid_val) != sizeof(struct GUID) ) {
+ ret = False;
+ break;
+ }
+ memcpy(guid, regval_data_p(guid_val), sizeof(struct GUID));
+ break;
+ default:
+ DEBUG(0,("is_printer_published: GUID value stored as "
+ "invaluid type (%d)\n", regval_type(guid_val) ));
+ break;
+ }
+ }
free_a_printer(&printer, 2);
- return True;
+ return ret;
}
#else
WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
return WERR_OK;
}
-BOOL is_printer_published(Printer_entry *print_hnd, int snum,
- struct uuid *guid)
+bool is_printer_published(Printer_entry *print_hnd, int snum,
+ struct GUID *guid)
{
return False;
}
TALLOC_FREE( data );
+ p2->data = NULL;
+
DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
p2->printername ));
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;
/****************************************************************************
Unpack a list of registry values frem the TDB
***************************************************************************/
-
-static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
+
+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;
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", ®val_p);
- if ( !regval_p )
+ len += tdb_unpack(buf+len, buflen-len, "p", ®val_p);
+ if ( !regval_p )
break;
/* unpack the next regval */
-
+
len += tdb_unpack(buf+len, buflen-len, "fdB",
string,
&type,
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;
}
-
- /* add the new value */
-
- regval_ctr_addvalue( printer_data->keys[key_index].values, valuename, type, (const char *)data_p, size );
+
+ DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
+
+ /* 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" ) )
+ {
+ 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(talloc_tos(), guid),
+ UNI_STR_TERMINATE );
+
+ regval_ctr_addvalue( printer_data->keys[key_index].values,
+ valuename, REG_SZ,
+ (const char *)unistr_guid.buffer,
+ unistr_guid.uni_str_len*2 );
+
+ } else {
+ /* add the value */
+
+ regval_ctr_addvalue( printer_data->keys[key_index].values,
+ valuename, type, (const char *)data_p,
+ size );
+ }
SAFE_FREE(data_p); /* 'B' option to tdbpack does a malloc() */
- DEBUG(8,("specific: [%s:%s], len: %d\n", keyname, valuename, size));
}
return len;
/****************************************************************************
***************************************************************************/
+static char *last_from;
+static char *last_to;
+
+static const char *get_last_from(void)
+{
+ if (!last_from) {
+ return "";
+ }
+ return last_from;
+}
+
+static const char *get_last_to(void)
+{
+ if (!last_to) {
+ return "";
+ }
+ return last_to;
+}
+
+static bool set_last_from_to(const char *from, const char *to)
+{
+ char *orig_from = last_from;
+ char *orig_to = last_to;
+
+ last_from = SMB_STRDUP(from);
+ last_to = SMB_STRDUP(to);
+
+ SAFE_FREE(orig_from);
+ SAFE_FREE(orig_to);
+
+ if (!last_from || !last_to) {
+ SAFE_FREE(last_from);
+ SAFE_FREE(last_to);
+ return false;
+ }
+ return true;
+}
+
static void map_to_os2_driver(fstring drivername)
{
- static BOOL initialised=False;
- static fstring last_from,last_to;
char *mapfile = lp_os2_driver_map();
char **lines = NULL;
int numlines = 0;
if (!*mapfile)
return;
- if (!initialised) {
- *last_from = *last_to = 0;
- initialised = True;
- }
-
- if (strequal(drivername,last_from)) {
- DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,last_to));
- fstrcpy(drivername,last_to);
+ if (strequal(drivername,get_last_from())) {
+ DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
+ drivername,get_last_to()));
+ fstrcpy(drivername,get_last_to());
return;
}
- lines = file_lines_load(mapfile, &numlines);
- if (numlines == 0) {
+ lines = file_lines_load(mapfile, &numlines,0);
+ if (numlines == 0 || lines == NULL) {
DEBUG(0,("No entries in OS/2 driver map %s\n",mapfile));
+ SAFE_FREE(lines);
return;
}
if (strequal(nt_name,drivername)) {
DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
- fstrcpy(last_from,drivername);
- fstrcpy(last_to,os2_name);
+ set_last_from_to(drivername,os2_name);
fstrcpy(drivername,os2_name);
file_lines_free(lines);
return;
****************************************************************************/
static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info, const char *servername, const char* sharename)
{
- int snum;
-
- snum = lp_servicenumber(sharename);
+ int snum = lp_servicenumber(sharename);
slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
DEBUG(10,("get_a_printer_2_default: driver name set to [%s]\n", info->drivername));
- pstrcpy(info->comment, "");
+ strlcpy(info->comment, "", sizeof(info->comment));
fstrcpy(info->printprocessor, "winprint");
fstrcpy(info->datatype, "RAW");
+#ifdef HAVE_CUPS
+ if ( (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
+ /* Pull the location and comment strings from cups if we don't
+ already have one */
+ if ( !strlen(info->location) || !strlen(info->comment) )
+ cups_pull_comment_location( info );
+ }
+#endif
+
info->attributes = PRINTER_ATTRIBUTE_SAMBA;
info->starttime = 0; /* Minutes since 12:00am GMT */
*/
if (lp_default_devmode(snum)) {
- if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL)
+ if ((info->devmode = construct_nt_devicemode(info->printername)) == NULL) {
goto fail;
- }
- else {
+ }
+ } else {
info->devmode = NULL;
}
- if (!nt_printing_getsec(info, sharename, &info->secdesc_buf))
+ if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
goto fail;
+ }
return WERR_OK;
TDB_DATA kbuf, dbuf;
fstring printername;
char adevice[MAXDEVICENAME];
-
- kbuf = make_printer_tdbkey( sharename );
+ char *comment = NULL;
+
+ kbuf = make_printer_tdbkey(talloc_tos(), sharename);
dbuf = tdb_fetch(tdb_printers, kbuf);
- if (!dbuf.dptr)
+ if (!dbuf.dptr) {
return get_a_printer_2_default(info, servername, sharename);
+ }
len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
&info->attributes,
info->sharename,
info->portname,
info->drivername,
- info->comment,
+ &comment,
info->location,
info->sepfile,
info->printprocessor,
info->datatype,
info->parameters);
+ if (comment) {
+ strlcpy(info->comment, comment, sizeof(info->comment));
+ SAFE_FREE(comment);
+ }
+
/* Samba has to have shared raw drivers. */
info->attributes |= PRINTER_ATTRIBUTE_SAMBA;
info->attributes &= ~PRINTER_ATTRIBUTE_NOT_SAMBA;
/* Restore the stripped strings. */
slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
- if ( lp_force_printername(snum) )
+ if ( lp_force_printername(snum) ) {
slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
- else
+ } else {
slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info->printername);
+ }
fstrcpy(info->printername, printername);
+#ifdef HAVE_CUPS
+ if ( (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
+ /* Pull the location and comment strings from cups if we don't
+ already have one */
+ if ( !strlen(info->location) || !strlen(info->comment) )
+ cups_pull_comment_location( info );
+ }
+#endif
+
len += unpack_devicemode(&info->devmode,dbuf.dptr+len, dbuf.dsize-len);
/*
if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
DEBUG(0,("unpack_values: talloc() failed!\n"));
+ SAFE_FREE(dbuf.dptr);
return WERR_NOMEM;
}
len += unpack_values( info->data, dbuf.dptr+len, dbuf.dsize-len );
/* This will get the current RPC talloc context, but we should be
passing this as a parameter... fixme... JRA ! */
- nt_printing_getsec(info, sharename, &info->secdesc_buf);
+ if (!nt_printing_getsec(info, sharename, &info->secdesc_buf)) {
+ SAFE_FREE(dbuf.dptr);
+ return WERR_NOMEM;
+ }
/* Fix for OS/2 drivers. */
- if (get_remote_arch() == RA_OS2)
+ if (get_remote_arch() == RA_OS2) {
map_to_os2_driver(info->drivername);
+ }
SAFE_FREE(dbuf.dptr);
*/
result=update_a_printer_2(printer->info_2);
-
break;
}
default:
result=WERR_UNKNOWN_LEVEL;
break;
}
-
+
return result;
}
Initialize printer devmode & data with previously saved driver init values.
****************************************************************************/
-static BOOL set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
+static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
{
int len = 0;
- pstring key;
- TDB_DATA kbuf, dbuf;
+ char *key = NULL;
+ TDB_DATA dbuf;
NT_PRINTER_INFO_LEVEL_2 info;
* 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);
- kbuf.dptr = key;
- kbuf.dsize = strlen(key)+1;
+ if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX,
+ info_ptr->drivername) < 0) {
+ return false;
+ }
- dbuf = tdb_fetch(tdb_drivers, kbuf);
+ dbuf = tdb_fetch_bystring(tdb_drivers, key);
if (!dbuf.dptr) {
/*
* When changing to a driver that has no init info in the tdb, remove
* 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);
/*
* 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;
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;
}
/****************************************************************************
is bound to the new printer.
****************************************************************************/
-BOOL set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
+bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
{
- BOOL result = False;
-
+ 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;
}
Delete driver init data stored for a specified driver
****************************************************************************/
-BOOL del_driver_init(char *drivername)
+bool del_driver_init(char *drivername)
{
- pstring key;
- TDB_DATA kbuf;
+ 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);
-
- kbuf.dptr = key;
- kbuf.dsize = strlen(key)+1;
+ 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(tdb_drivers, kbuf) == 0);
+ ret = (tdb_delete_bystring(tdb_drivers, key) == 0);
+ SAFE_FREE(key);
+ return ret;
}
/****************************************************************************
static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
{
- pstring key;
- char *buf;
+ char *key = NULL;
+ uint8 *buf;
int buflen, len, ret;
- TDB_DATA kbuf, dbuf;
+ 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) {
- char *tb;
-
- tb = (char *)SMB_REALLOC(buf, len);
- if (!tb) {
+ buf = (uint8 *)SMB_REALLOC(buf, len);
+ if (!buf) {
DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
ret = -1;
goto done;
}
- else
- buf = tb;
buflen = len;
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;
+ }
- kbuf.dptr = key;
- kbuf.dsize = strlen(key)+1;
dbuf.dptr = buf;
dbuf.dsize = len;
- ret = tdb_store(tdb_drivers, kbuf, dbuf, TDB_REPLACE);
+ ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE);
done:
if (ret == -1)
got to keep the endians happy :).
****************************************************************************/
-static BOOL convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len )
+static bool convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len )
{
- BOOL result = False;
+ bool result = False;
prs_struct ps;
DEVICEMODE devmode;
fstrcpy( servername, print_hnd->servername );
else {
fstrcpy( servername, "%L" );
- standard_sub_basic( "", servername, sizeof(servername)-1 );
+ standard_sub_basic( "", "", servername,
+ sizeof(servername)-1 );
}
result = get_a_printer_2( (*pp_printer)->info_2, servername, sharename );
to a printer
****************************************************************************/
-BOOL printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
+bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
{
int snum;
int n_services = lp_numservices();
NT_PRINTER_INFO_LEVEL *printer = NULL;
- BOOL in_use = False;
+ bool in_use = False;
if ( !info_3 )
return False;
Check to see if a ogiven file is in use by *info
*********************************************************************/
-static BOOL drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
+static bool drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
{
int i = 0;
Check if any of the files used by src are also used by drv
*********************************************************************/
-static BOOL trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
+static bool trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
{
- BOOL in_use = False;
+ bool in_use = False;
int i = 0;
if ( !src || !drv )
which are not in use
****************************************************************************/
-BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
+bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
{
int i;
int ndrivers;
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.
****************************************************************************/
-static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
+static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
{
int i = 0;
char *s;
- pstring file;
+ const char *file;
connection_struct *conn;
DATA_BLOB null_pw;
NTSTATUS nt_status;
fstring res_type;
- BOOL bad_path;
SMB_STRUCT_STAT st;
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, 0 );
+
+ 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;
}
+ if ( !CAN_WRITE(conn) ) {
+ DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
+ return False;
+ }
+
/* Save who we are - we are temporarily becoming the connection user. */
if ( !become_user(conn, conn->vuid) ) {
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 );
- driver_unix_convert(file, conn, NULL, &bad_path, &st);
+ file = s;
+ driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting driverfile [%s]\n", s));
- unlink_internals(conn, 0, file);
+ unlink_internals(conn, NULL, 0, file, False);
}
}
-
+
if ( *info_3->configfile ) {
if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
- pstrcpy( file, s );
- driver_unix_convert(file, conn, NULL, &bad_path, &st);
+ file = s;
+ driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting configfile [%s]\n", s));
- unlink_internals(conn, 0, file);
+ unlink_internals(conn, NULL, 0, file, False);
}
}
-
+
if ( *info_3->datafile ) {
if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
- pstrcpy( file, s );
- driver_unix_convert(file, conn, NULL, &bad_path, &st);
+ file = s;
+ driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting datafile [%s]\n", s));
- unlink_internals(conn, 0, file);
+ unlink_internals(conn, NULL, 0, file, False);
}
}
-
+
if ( *info_3->helpfile ) {
if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
- pstrcpy( file, s );
- driver_unix_convert(file, conn, NULL, &bad_path, &st);
+ file = s;
+ driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting helpfile [%s]\n", s));
- unlink_internals(conn, 0, file);
+ 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 );
- driver_unix_convert(file, conn, NULL, &bad_path, &st);
+ file = p;
+ driver_unix_convert(conn,file,&st);
DEBUG(10,("deleting dependent file [%s]\n", file));
- unlink_internals(conn, 0, file );
+ unlink_internals(conn, NULL, 0, file, False);
}
-
+
i++;
}
}
unbecome_user();
-
- return True;
+
+ return true;
}
/****************************************************************************
***************************************************************************/
WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
- uint32 version, BOOL delete_files )
+ uint32 version, bool delete_files )
{
- pstring key;
+ char *key = NULL;
const char *arch;
- TDB_DATA kbuf, dbuf;
+ TDB_DATA dbuf;
NT_PRINTER_DRIVER_INFO_LEVEL ctr;
/* delete the tdb data first */
arch = get_short_archi(info_3->environment);
- slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
- arch, version, info_3->name);
+ if (!arch) {
+ return WERR_UNKNOWN_PRINTER_DRIVER;
+ }
+ 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" ));
ctr.info_3 = info_3;
dump_a_printer_driver( ctr, 3 );
- kbuf.dptr=key;
- kbuf.dsize=strlen(key)+1;
-
/* check if the driver actually exists for this environment */
-
- dbuf = tdb_fetch( tdb_drivers, kbuf );
+
+ 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(tdb_drivers, kbuf) == -1) {
+
+ 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;
}
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.
****************************************************************************/
SEC_DESC_BUF *old_secdesc_ctr = NULL;
prs_struct ps;
TALLOC_CTX *mem_ctx = NULL;
- char *key;
+ TDB_DATA kbuf;
WERROR status;
mem_ctx = talloc_init("nt_printing_setsec");
permissions through NT. If they are NULL in the new security
descriptor then copy them over from the old one. */
- if (!secdesc_ctr->sec->owner_sid || !secdesc_ctr->sec->grp_sid) {
+ if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {
DOM_SID *owner_sid, *group_sid;
SEC_ACL *dacl, *sacl;
SEC_DESC *psd = NULL;
size_t size;
- nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr);
+ if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
+ status = WERR_NOMEM;
+ goto out;
+ }
/* Pick out correct owner and group sids */
- owner_sid = secdesc_ctr->sec->owner_sid ?
- secdesc_ctr->sec->owner_sid :
- old_secdesc_ctr->sec->owner_sid;
+ owner_sid = secdesc_ctr->sd->owner_sid ?
+ secdesc_ctr->sd->owner_sid :
+ old_secdesc_ctr->sd->owner_sid;
- group_sid = secdesc_ctr->sec->grp_sid ?
- secdesc_ctr->sec->grp_sid :
- old_secdesc_ctr->sec->grp_sid;
+ group_sid = secdesc_ctr->sd->group_sid ?
+ secdesc_ctr->sd->group_sid :
+ old_secdesc_ctr->sd->group_sid;
- dacl = secdesc_ctr->sec->dacl ?
- secdesc_ctr->sec->dacl :
- old_secdesc_ctr->sec->dacl;
+ dacl = secdesc_ctr->sd->dacl ?
+ secdesc_ctr->sd->dacl :
+ old_secdesc_ctr->sd->dacl;
- sacl = secdesc_ctr->sec->sacl ?
- secdesc_ctr->sec->sacl :
- old_secdesc_ctr->sec->sacl;
+ sacl = secdesc_ctr->sd->sacl ?
+ secdesc_ctr->sd->sacl :
+ old_secdesc_ctr->sd->sacl;
/* Make a deep copy of the security descriptor */
- psd = make_sec_desc(mem_ctx, secdesc_ctr->sec->revision, secdesc_ctr->sec->type,
+ psd = make_sec_desc(mem_ctx, secdesc_ctr->sd->revision, secdesc_ctr->sd->type,
owner_sid, group_sid,
sacl,
dacl,
&size);
+ if (!psd) {
+ status = WERR_NOMEM;
+ goto out;
+ }
+
new_secdesc_ctr = make_sec_desc_buf(mem_ctx, size, psd);
}
/* Store the security descriptor in a tdb */
- prs_init(&ps, (uint32)sec_desc_size(new_secdesc_ctr->sec) +
- sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
+ prs_init(&ps,
+ (uint32)ndr_size_security_descriptor(new_secdesc_ctr->sd, 0)
+ + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL);
if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
&ps, 1)) {
goto out;
}
- key = make_printers_secdesc_tdbkey( sharename );
+ kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
- if (tdb_prs_store(tdb_printers, key, &ps)==0) {
+ if (tdb_prs_store(tdb_printers, kbuf, &ps)==0) {
status = WERR_OK;
} else {
DEBUG(1,("Failed to store secdesc for %s\n", sharename));
Get a security desc for a printer.
****************************************************************************/
-BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
+bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
{
prs_struct ps;
- char *key;
+ TDB_DATA kbuf;
char *temp;
if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
sharename = temp + 1;
}
+ ZERO_STRUCT(ps);
+
/* Fetch security descriptor from tdb */
- key = make_printers_secdesc_tdbkey( sharename );
+ kbuf = make_printers_secdesc_tdbkey(ctx, sharename );
- if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
+ if (tdb_prs_fetch(tdb_printers, kbuf, &ps, ctx)!=0 ||
!sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
+ prs_mem_free(&ps);
+
DEBUG(4,("using default secdesc for %s\n", sharename));
if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
/* Save default security descriptor for later */
- prs_init(&ps, (uint32)sec_desc_size((*secdesc_ctr)->sec) +
+ prs_init(&ps, (uint32)ndr_size_security_descriptor((*secdesc_ctr)->sd, 0) +
sizeof(SEC_DESC_BUF), ctx, MARSHALL);
- if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1))
- tdb_prs_store(tdb_printers, key, &ps);
+ if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
+ tdb_prs_store(tdb_printers, kbuf, &ps);
+ }
prs_mem_free(&ps);
return True;
}
+ prs_mem_free(&ps);
+
/* If security descriptor is owned by S-1-1-0 and winbindd is up,
this security descriptor has been created when winbindd was
down. Take ownership of security descriptor. */
- if (sid_equal((*secdesc_ctr)->sec->owner_sid, &global_sid_World)) {
+ if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {
DOM_SID owner_sid;
/* Change sd owner to workgroup administrator */
sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
- psd = make_sec_desc(ctx, (*secdesc_ctr)->sec->revision, (*secdesc_ctr)->sec->type,
+ psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
&owner_sid,
- (*secdesc_ctr)->sec->grp_sid,
- (*secdesc_ctr)->sec->sacl,
- (*secdesc_ctr)->sec->dacl,
+ (*secdesc_ctr)->sd->group_sid,
+ (*secdesc_ctr)->sd->sacl,
+ (*secdesc_ctr)->sd->dacl,
&size);
+ if (!psd) {
+ return False;
+ }
+
new_secdesc_ctr = make_sec_desc_buf(ctx, size, psd);
+ if (!new_secdesc_ctr) {
+ return False;
+ }
/* Swap with other one */
}
if (DEBUGLEVEL >= 10) {
- SEC_ACL *the_acl = (*secdesc_ctr)->sec->dacl;
+ SEC_ACL *the_acl = (*secdesc_ctr)->sd->dacl;
int i;
DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
sharename, the_acl->num_aces));
for (i = 0; i < the_acl->num_aces; i++) {
- fstring sid_str;
-
- sid_to_string(sid_str, &the_acl->ace[i].trustee);
-
- DEBUG(10, ("%s %d %d 0x%08x\n", sid_str,
- the_acl->ace[i].type, the_acl->ace[i].flags,
- the_acl->ace[i].info.mask));
+ DEBUG(10, ("%s %d %d 0x%08x\n",
+ sid_string_dbg(&the_acl->aces[i].trustee),
+ the_acl->aces[i].type, the_acl->aces[i].flags,
+ the_acl->aces[i].access_mask));
}
}
- prs_mem_free(&ps);
return True;
}
int i;
for (i = 0; sd->dacl && i < sd->dacl->num_aces; i++) {
- se_map_generic(&sd->dacl->ace[i].info.mask,
+ se_map_generic(&sd->dacl->aces[i].access_mask,
&printer_generic_mapping);
}
}
3) "printer admins" (may result in numerous calls to winbind)
****************************************************************************/
-BOOL print_access_check(struct current_user *user, int snum, int access_type)
+bool print_access_check(struct current_user *user, int snum, int access_type)
{
SEC_DESC_BUF *secdesc = NULL;
uint32 access_granted;
NTSTATUS status;
- BOOL result;
+ bool result;
const char *pname;
TALLOC_CTX *mem_ctx = NULL;
SE_PRIV se_printop = SE_PRINT_OPERATOR;
/* Always allow root or SE_PRINT_OPERATROR to do anything */
- if ( user->uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
+ if ( user->ut.uid == 0 || user_has_privileges(user->nt_user_token, &se_printop ) ) {
return True;
}
return False;
}
- nt_printing_getsec(mem_ctx, pname, &secdesc);
+ if (!nt_printing_getsec(mem_ctx, pname, &secdesc)) {
+ talloc_destroy(mem_ctx);
+ errno = ENOMEM;
+ return False;
+ }
if (access_type == JOB_ACCESS_ADMINISTER) {
SEC_DESC_BUF *parent_secdesc = secdesc;
against. This is because print jobs are child objects
objects of a printer. */
- secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sec, False);
+ secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sd, False);
+
+ if (!secdesc) {
+ talloc_destroy(mem_ctx);
+ errno = ENOMEM;
+ return False;
+ }
/* Now this is the bit that really confuses me. The access
type needs to be changed from JOB_ACCESS_ADMINISTER to
/* Check access */
- map_printer_permissions(secdesc->sec);
+ map_printer_permissions(secdesc->sd);
- result = se_access_check(secdesc->sec, user->nt_user_token, access_type,
+ result = se_access_check(secdesc->sd, user->nt_user_token, access_type,
&access_granted, &status);
DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
/* see if we need to try the printer admin list */
- if ( access_granted == 0 ) {
- if ( user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups) )
- return True;
+ if ((access_granted == 0) &&
+ (token_contains_name_in_list(uidtoname(user->ut.uid), NULL,
+ user->nt_user_token,
+ lp_printer_admin(snum)))) {
+ talloc_destroy(mem_ctx);
+ return True;
}
talloc_destroy(mem_ctx);
- if (!result)
+ if (!result) {
errno = EACCES;
+ }
return result;
}
Check the time parameters allow a print operation.
*****************************************************************************/
-BOOL print_time_access_check(int snum)
+bool print_time_access_check(const char *servicename)
{
NT_PRINTER_INFO_LEVEL *printer = NULL;
- BOOL ok = False;
+ bool ok = False;
time_t now = time(NULL);
struct tm *t;
uint32 mins;
- if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, servicename)))
return False;
if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)