* RPC Pipe client / server routines
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Jean François Micouleau 1998-2000.
- * Copyright (C) Gerald Carter 2002.
+ * Copyright (C) Gerald Carter 2002-2003.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
forms it wants and in the ORDER it wants them (note: DEVMODE papersize is an
array index). Letter is always first, so (for the current code) additions
always put things in the correct order. */
-static nt_forms_struct default_forms[] = {
+static const nt_forms_struct default_forms[] = {
{"Letter",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
{"Letter Small",0x1,0x34b5c,0x44368,0x0,0x0,0x34b5c,0x44368},
{"Tabloid",0x1,0x44368,0x696b8,0x0,0x0,0x44368,0x696b8},
{"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
};
+struct table_node {
+ const char *long_archi;
+ const char *short_archi;
+ int version;
+};
+
+static const struct table_node archi_table[]= {
+
+ {"Windows 4.0", "WIN40", 0 },
+ {"Windows NT x86", "W32X86", 2 },
+ {"Windows NT R4000", "W32MIPS", 2 },
+ {"Windows NT Alpha_AXP", "W32ALPHA", 2 },
+ {"Windows NT PowerPC", "W32PPC", 2 },
+ {NULL, "", -1 }
+};
+
static BOOL upgrade_to_version_3(void)
{
TDB_DATA kbuf, newkey, dbuf;
if (strncmp(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);
DEBUG(0,("upgrade_to_version_3: failed to move form. Error (%s).\n", tdb_errorstr(tdb_forms)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
+ SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to delete form. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
if (strncmp(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);
DEBUG(0,("upgrade_to_version_3: failed to move printer. Error (%s)\n", tdb_errorstr(tdb_printers)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
+ SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to delete printer. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
if (strncmp(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);
DEBUG(0,("upgrade_to_version_3: failed to move secdesc. Error (%s)\n", tdb_errorstr(tdb_printers)));
return False;
}
if (tdb_delete(tdb_drivers, kbuf) != 0) {
+ SAFE_FREE(dbuf.dptr);
DEBUG(0,("upgrade_to_version_3: failed to delete secdesc. Error (%s)\n", tdb_errorstr(tdb_drivers)));
return False;
}
}
/****************************************************************************
- Open the NT printing tdb.
+ Open the NT printing tdbs. Done once before fork().
****************************************************************************/
BOOL nt_printing_init(void)
{
static pid_t local_pid;
- char *vstring = "INFO/version";
+ const char *vstring = "INFO/version";
if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
return True;
+ if (tdb_drivers)
+ tdb_close(tdb_drivers);
tdb_drivers = tdb_open_log(lock_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",
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);
if (!tdb_printers) {
DEBUG(0,("nt_printing_init: Failed to open nt printers database %s (%s)\n",
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);
if (!tdb_forms) {
DEBUG(0,("nt_printing_init: Failed to open nt forms database %s (%s)\n",
}
/****************************************************************************
- delete a named form struct
+ Delete a named form struct.
****************************************************************************/
+
BOOL delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
{
pstring key;
}
/****************************************************************************
-update a form struct
+ Update a form struct.
****************************************************************************/
+
void update_a_form(nt_forms_struct **list, const FORM *form, int count)
{
int n=0;
unistr2_to_ascii(form_name, &(form->name), sizeof(form_name)-1);
DEBUG(106, ("[%s]\n", form_name));
- for (n=0; n<count; n++)
- {
+ for (n=0; n<count; n++) {
DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
break;
}
/****************************************************************************
-get the nt drivers list
-
-traverse the database and look-up the matching names
+ Get the nt drivers list.
+ Traverse the database and look-up the matching names.
****************************************************************************/
-int get_ntdrivers(fstring **list, char *architecture, uint32 version)
+int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
{
int total=0;
- fstring short_archi;
+ const char *short_archi;
fstring *fl;
pstring key;
TDB_DATA kbuf, newkey;
- get_short_archi(short_archi, architecture);
+ short_archi = get_short_archi(architecture);
slprintf(key, sizeof(key)-1, "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
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) continue;
+
+ if (strncmp(kbuf.dptr, key, strlen(key)) != 0)
+ continue;
if((fl = Realloc(*list, sizeof(fstring)*(total+1))) == NULL) {
DEBUG(0,("get_ntdrivers: failed to enlarge list!\n"));
function to do the mapping between the long architecture name and
the short one.
****************************************************************************/
-BOOL get_short_archi(char *short_archi, char *long_archi)
+const char *get_short_archi(const char *long_archi)
{
- struct table {
- char *long_archi;
- char *short_archi;
- };
-
- struct table archi_table[]=
- {
- {"Windows 4.0", "WIN40" },
- {"Windows NT x86", "W32X86" },
- {"Windows NT R4000", "W32MIPS" },
- {"Windows NT Alpha_AXP", "W32ALPHA" },
- {"Windows NT PowerPC", "W32PPC" },
- {NULL, "" }
- };
-
- int i=-1;
-
- DEBUG(107,("Getting architecture dependant directory\n"));
- do {
- i++;
- } while ( (archi_table[i].long_archi!=NULL ) &&
- StrCaseCmp(long_archi, archi_table[i].long_archi) );
+ int i=-1;
- if (archi_table[i].long_archi==NULL) {
- DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
- return False;
- }
+ DEBUG(107,("Getting architecture dependant directory\n"));
+ do {
+ i++;
+ } while ( (archi_table[i].long_archi!=NULL ) &&
+ StrCaseCmp(long_archi, archi_table[i].long_archi) );
- StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
+ if (archi_table[i].long_archi==NULL) {
+ DEBUGADD(10,("Unknown architecture [%s] !\n", long_archi));
+ return NULL;
+ }
- DEBUGADD(108,("index: [%d]\n", i));
- DEBUGADD(108,("long architecture: [%s]\n", long_archi));
- DEBUGADD(108,("short architecture: [%s]\n", short_archi));
-
- return True;
+ /* 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));
+
+ return archi_table[i].short_archi;
}
/****************************************************************************
}
/* Skip OEM header (if any) and the DOS stub to start of Windows header */
- if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, SVAL(buf,DOS_HEADER_LFANEW_OFFSET), SEEK_SET) == (SMB_OFF_T)-1) {
+ if (SMB_VFS_LSEEK(fsp, fsp->fd, 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 */
}
/* Seek to the start of the .rsrc section info */
- if (fsp->conn->vfs_ops.lseek(fsp, fsp->fd, section_pos, SEEK_SET) == (SMB_OFF_T)-1) {
+ if (SMB_VFS_LSEEK(fsp, fsp->fd, 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;
* 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 = -(fsp->conn->vfs_ops.lseek(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
+ int skip = -(SMB_VFS_LSEEK(fsp, fsp->fd, 0, SEEK_CUR) - (byte_count - i) +
sizeof(VS_SIGNATURE)) & 3;
if (IVAL(buf,i+sizeof(VS_SIGNATURE)+skip) != 0xfeef04bd) continue;
missing the version info structure, compare the creation date (on Unix use
the modification date). Otherwise chose the numerically larger version number.
****************************************************************************/
-static int file_version_is_newer(connection_struct *conn, fstring new_file,
- fstring old_file)
+
+static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
{
BOOL use_version = True;
pstring filepath;
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
old_file));
use_version = False;
- if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
+ if (SMB_VFS_FSTAT(fsp, fsp->fd, &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));
}
DEBUG(6,("file_version_is_newer: Version info not found [%s], use mod time\n",
new_file));
use_version = False;
- if (fsp->conn->vfs_ops.fstat(fsp, fsp->fd, &st) == -1) goto error_exit;
+ if (SMB_VFS_FSTAT(fsp, fsp->fd, &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));
}
/****************************************************************************
Determine the correct cVersion associated with an architecture and driver
****************************************************************************/
-static uint32 get_correct_cversion(fstring architecture, fstring driverpath_in,
+static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in,
struct current_user *user, WERROR *perr)
{
int cversion;
NTSTATUS nt_status;
pstring driverpath;
DATA_BLOB null_pw;
+ fstring res_type;
files_struct *fsp = NULL;
BOOL bad_path;
SMB_STRUCT_STAT st;
/* Null password is ok - we are already an authenticated user... */
null_pw = data_blob(NULL, 0);
+ fstrcpy(res_type, "A:");
become_root();
- conn = make_connection_with_chdir("print$", null_pw, "A:", user->vuid, &nt_status);
+ conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
unbecome_root();
if (conn == NULL) {
}
/* We are temporarily becoming the connection user. */
- if (!become_user(conn, conn->vuid)) {
+ if (!become_user(conn, user->vuid)) {
DEBUG(0,("get_correct_cversion: Can't become user!\n"));
*perr = WERR_ACCESS_DENIED;
return -1;
static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
struct current_user *user)
{
- fstring architecture;
+ const char *architecture;
fstring new_name;
char *p;
int i;
}
}
- get_short_archi(architecture, driver->environment);
+ architecture = get_short_archi(driver->environment);
/* jfm:7/16/2000 the client always sends the cversion=0.
* The server should check which version the driver is by reading
****************************************************************************/
static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
{
- fstring architecture;
+ const char *architecture;
fstring new_name;
char *p;
int i;
}
}
- get_short_archi(architecture, driver->environment);
+ architecture = get_short_archi(driver->environment);
/* 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;
- fstring architecture;
+ const char *architecture;
pstring new_dir;
pstring old_name;
pstring new_name;
NTSTATUS nt_status;
pstring inbuf;
pstring outbuf;
+ fstring res_type;
int ver = 0;
int i;
return False;
}
- get_short_archi(architecture, driver->environment);
+ architecture = get_short_archi(driver->environment);
/*
* 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.
*/
- become_root();
null_pw = data_blob(NULL, 0);
- conn = make_connection_with_chdir("print$", null_pw, "A:", user->vuid, &nt_status);
+ fstrcpy(res_type, "A:");
+ become_root();
+ conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
unbecome_root();
if (conn == NULL) {
static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
{
int len, buflen;
- fstring architecture;
+ const char *architecture;
pstring directory;
- pstring temp_name;
+ fstring temp_name;
pstring key;
char *buf;
int i, ret;
TDB_DATA kbuf, dbuf;
- get_short_archi(architecture, driver->environment);
+ architecture = get_short_archi(driver->environment);
/* The names are relative. We store them in the form: \print$\arch\version\driver.xxx
* \\server is added in the rpc server layer.
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring driver, fstring arch)
+static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, const char *driver, const char *arch)
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 info;
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, fstring arch, uint32 version)
+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;
- fstring architecture;
+ const char *architecture;
int len = 0;
int i;
pstring key;
ZERO_STRUCT(driver);
- get_short_archi(architecture, arch);
+ architecture = get_short_archi(arch);
DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, drivername));
driver.defaultdatatype);
i=0;
- while (len < dbuf.dsize)
- {
+ while (len < dbuf.dsize) {
fstring *tddfs;
tddfs = (fstring *)Realloc(driver.dependentfiles,
SAFE_FREE(dbuf.dptr);
- if (len != dbuf.dsize)
- {
+ if (len != dbuf.dsize) {
SAFE_FREE(driver.dependentfiles);
return get_a_printer_driver_3_default(info_ptr, drivername, arch);
len += tdb_pack(buf+len, buflen-len, "p", nt_devmode);
- if (!nt_devmode) return len;
+ if (!nt_devmode)
+ return len;
len += tdb_pack(buf+len, buflen-len, "ffwwwwwwwwwwwwwwwwwwddddddddddddddp",
nt_devmode->devicename,
/* 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 );
/* loop over all values */
- for ( j=0; j<num_values; j++ )
- {
+ for ( j=0; j<num_values; j++ ) {
/* pathname should be stored as <key>\<value> */
val = regval_ctr_specific_value( val_ctr, j );
}
/* FIXME!!! Reorder so this forward declaration is not necessary --jerry */
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, fstring);
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **, const char* sharename);
static void free_nt_printer_info_level_2(NT_PRINTER_INFO_LEVEL_2 **);
/****************************************************************************
****************************************************************************/
NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
{
- char adevice[32];
+ char adevice[MAXDEVICENAME];
NT_DEVICEMODE *nt_devmode = (NT_DEVICEMODE *)malloc(sizeof(NT_DEVICEMODE));
if (nt_devmode == NULL) {
ZERO_STRUCTP(nt_devmode);
- safe_strcpy(adevice, default_devicename, sizeof(adevice));
+ safe_strcpy(adevice, default_devicename, sizeof(adevice)-1);
fstrcpy(nt_devmode->devicename, adevice);
fstrcpy(nt_devmode->formname, "Letter");
{
NT_DEVICEMODE *new_nt_devicemode = NULL;
+ if ( !nt_devicemode )
+ return NULL;
+
if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
return NULL;
/* clean up all registry keys */
data = &info->data;
- for ( i=0; i<data->num_keys; i++ )
- {
+ for ( i=0; i<data->num_keys; i++ ) {
SAFE_FREE( data->keys[i].name );
regval_ctr_destroy( &data->keys[i].values );
}
}
/****************************************************************************
- allocate and initialize a new slot in
- ***************************************************************************/
+ Allocate and initialize a new slot.
+***************************************************************************/
-static int add_new_printer_key( NT_PRINTER_DATA *data, char *name )
+static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
{
NT_PRINTER_KEY *d;
int key_index;
search for a registry key name in the existing printer data
***************************************************************************/
-int lookup_printerkey( NT_PRINTER_DATA *data, char *name )
+int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
{
int key_index = -1;
int i;
/* loop over all existing keys */
- for ( i=0; i<data->num_keys; i++ )
- {
+ for ( i=0; i<data->num_keys; i++ ) {
if ( strequal(data->keys[i].name, name) ) {
DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
key_index = i;
/****************************************************************************
***************************************************************************/
-uint32 get_printer_subkeys( NT_PRINTER_DATA *data, char* key, fstring **subkeys )
+uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
{
int i, j;
int key_len;
if ( !data )
return 0;
- for ( i=0; i<data->num_keys; i++ )
- {
- if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 )
- {
+ for ( i=0; i<data->num_keys; i++ ) {
+ if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
/* match sure it is a subkey and not the key itself */
key_len = strlen( key );
/* tag of the end */
- fstrcpy( subkeys_ptr[num_subkeys], "" );
+ if (num_subkeys)
+ fstrcpy(subkeys_ptr[num_subkeys], "" );
*subkeys = subkeys_ptr;
return num_subkeys;
}
-
+
+static void map_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+ const char *sz)
+{
+ smb_ucs2_t conv_str[1024];
+ size_t str_size;
+
+ regval_ctr_delvalue(ctr, val_name);
+ str_size = push_ucs2(NULL, conv_str, sz, sizeof(conv_str),
+ STR_TERMINATE | STR_NOALIGN);
+ regval_ctr_addvalue(ctr, val_name, REG_SZ,
+ (char *) conv_str, str_size);
+}
+
+static void map_dword_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+ uint32 dword)
+{
+ regval_ctr_delvalue(ctr, val_name);
+ regval_ctr_addvalue(ctr, val_name, REG_DWORD,
+ (char *) &dword, sizeof(dword));
+}
+
+static void map_bool_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+ BOOL bool)
+{
+ uint8 bin_bool = (bool ? 1 : 0);
+ regval_ctr_delvalue(ctr, val_name);
+ regval_ctr_addvalue(ctr, val_name, REG_BINARY,
+ (char *) &bin_bool, sizeof(bin_bool));
+}
+
+static void map_single_multi_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+ const char *multi_sz)
+{
+ smb_ucs2_t *conv_strs = NULL;
+ size_t str_size;
+
+ /* a multi-sz has to have a null string terminator, i.e., the last
+ string must be followed by two nulls */
+ str_size = (strlen(multi_sz) + 2) * sizeof(smb_ucs2_t);
+ conv_strs = calloc(str_size, 1);
+
+ push_ucs2(NULL, conv_strs, multi_sz, str_size,
+ STR_TERMINATE | STR_NOALIGN);
+
+ regval_ctr_delvalue(ctr, val_name);
+ regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ,
+ (char *) conv_strs, str_size);
+ safe_free(conv_strs);
+
+}
+
+/****************************************************************************
+ * 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
+ ***************************************************************************/
+
+static BOOL map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
+{
+ REGVAL_CTR *ctr = NULL;
+ fstring longname;
+ char *allocated_string = NULL;
+ const char *ascii_str;
+ int i;
+
+ if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
+ i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
+ ctr = &info2->data.keys[i].values;
+
+ map_sz_into_ctr(ctr, SPOOL_REG_PRINTERNAME, info2->sharename);
+ map_sz_into_ctr(ctr, SPOOL_REG_SHORTSERVERNAME, global_myname());
+
+ get_myfullname(longname);
+ map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
+
+ asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename);
+ map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
+ SAFE_FREE(allocated_string);
+
+ map_dword_into_ctr(ctr, SPOOL_REG_VERSIONNUMBER, 4);
+ map_sz_into_ctr(ctr, SPOOL_REG_DRIVERNAME, info2->drivername);
+ map_sz_into_ctr(ctr, SPOOL_REG_LOCATION, info2->location);
+ map_sz_into_ctr(ctr, SPOOL_REG_DESCRIPTION, info2->comment);
+ map_single_multi_sz_into_ctr(ctr, SPOOL_REG_PORTNAME, info2->portname);
+ map_sz_into_ctr(ctr, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);
+ map_dword_into_ctr(ctr, SPOOL_REG_PRINTSTARTTIME, info2->starttime);
+ map_dword_into_ctr(ctr, SPOOL_REG_PRINTENDTIME, info2->untiltime);
+ map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
+
+ map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
+ (info2->attributes &
+ PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
+
+ switch (info2->attributes & 0x3) {
+ case 0:
+ ascii_str = SPOOL_REGVAL_PRINTWHILESPOOLING;
+ break;
+ case 1:
+ ascii_str = SPOOL_REGVAL_PRINTAFTERSPOOLED;
+ break;
+ case 2:
+ ascii_str = SPOOL_REGVAL_PRINTDIRECT;
+ break;
+ default:
+ ascii_str = "unknown";
+ }
+ map_sz_into_ctr(ctr, SPOOL_REG_PRINTSPOOLING, ascii_str);
+
+ return True;
+}
+
+#ifdef HAVE_ADS
+static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, GUID guid)
+{
+ int i;
+ REGVAL_CTR *ctr=NULL;
+
+ /* find the DsSpooler key */
+ if ((i = lookup_printerkey(&info2->data, SPOOL_DSSPOOLER_KEY)) < 0)
+ i = add_new_printer_key(&info2->data, SPOOL_DSSPOOLER_KEY);
+ ctr = &info2->data.keys[i].values;
+
+ regval_ctr_delvalue(ctr, "objectGUID");
+ regval_ctr_addvalue(ctr, "objectGUID", REG_BINARY,
+ (char *) &guid, sizeof(GUID));
+}
+
+static WERROR publish_it(NT_PRINTER_INFO_LEVEL *printer)
+{
+ ADS_STATUS ads_rc;
+ TALLOC_CTX *ctx = talloc_init("publish_it");
+ ADS_MODLIST mods = ads_init_mods(ctx);
+ char *prt_dn = NULL, *srv_dn, **srv_cn;
+ void *res = NULL;
+ ADS_STRUCT *ads;
+ const char *attrs[] = {"objectGUID", NULL};
+ GUID guid;
+ WERROR win_rc = WERR_OK;
+
+ ZERO_STRUCT(guid);
+ /* set the DsSpooler info and attributes */
+ if (!(map_nt_printer_info2_to_dsspooler(printer->info_2)))
+ return WERR_NOMEM;
+ printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
+ win_rc = mod_a_printer(*printer, 2);
+ if (!W_ERROR_IS_OK(win_rc)) {
+ DEBUG(3, ("err %d saving data\n",
+ W_ERROR_V(win_rc)));
+ return win_rc;
+ }
+
+ /* Build the ads mods */
+ get_local_printer_publishing_data(ctx, &mods,
+ &printer->info_2->data);
+ ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
+ printer->info_2->sharename);
+
+ /* connect to the ADS server */
+ ads = ads_init(NULL, NULL, lp_ads_server());
+ if (!ads) {
+ DEBUG(3, ("ads_init() failed\n"));
+ return WERR_SERVER_UNAVAILABLE;
+ }
+ setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
+ SAFE_FREE(ads->auth.password);
+ ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
+ NULL, NULL);
+ ads_rc = ads_connect(ads);
+ if (!ADS_ERR_OK(ads_rc)) {
+ DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
+ ads_destroy(&ads);
+ return WERR_ACCESS_DENIED;
+ }
+
+ /* figure out where to publish */
+ ads_find_machine_acct(ads, &res, global_myname());
+ srv_dn = ldap_get_dn(ads->ld, res);
+ ads_msgfree(ads, res);
+ srv_cn = ldap_explode_dn(srv_dn, 1);
+ asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn[0],
+ printer->info_2->sharename, srv_dn);
+ ads_memfree(ads, srv_dn);
+
+ /* publish it */
+ ads_rc = ads_add_printer_entry(ads, prt_dn, ctx, &mods);
+ if (LDAP_ALREADY_EXISTS == ads_rc.err.rc)
+ ads_rc = ads_mod_printer_entry(ads, prt_dn, ctx,&mods);
+
+ /* retreive the guid and store it locally */
+ if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
+ ads_memfree(ads, prt_dn);
+ ads_pull_guid(ads, res, &guid);
+ ads_msgfree(ads, res);
+ store_printer_guid(printer->info_2, guid);
+ win_rc = mod_a_printer(*printer, 2);
+ }
+
+ safe_free(prt_dn);
+ ads_destroy(&ads);
+
+ return WERR_OK;
+}
+
+WERROR unpublish_it(NT_PRINTER_INFO_LEVEL *printer)
+{
+ ADS_STATUS ads_rc;
+ ADS_STRUCT *ads;
+ void *res;
+ char *prt_dn = NULL;
+ WERROR win_rc;
+
+ printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
+ win_rc = mod_a_printer(*printer, 2);
+ if (!W_ERROR_IS_OK(win_rc)) {
+ DEBUG(3, ("err %d saving data\n",
+ W_ERROR_V(win_rc)));
+ return win_rc;
+ }
+
+ ads = ads_init(NULL, NULL, lp_ads_server());
+ if (!ads) {
+ DEBUG(3, ("ads_init() failed\n"));
+ return WERR_SERVER_UNAVAILABLE;
+ }
+ setenv(KRB5_ENV_CCNAME, "MEMORY:prtpub_cache", 1);
+ SAFE_FREE(ads->auth.password);
+ ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
+ NULL, NULL);
+ ads_rc = ads_connect(ads);
+ if (!ADS_ERR_OK(ads_rc)) {
+ DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
+ ads_destroy(&ads);
+ return WERR_ACCESS_DENIED;
+ }
+
+ /* remove the printer from the directory */
+ ads_rc = ads_find_printer_on_server(ads, &res,
+ printer->info_2->sharename, global_myname());
+ if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
+ prt_dn = ads_get_dn(ads, res);
+ ads_msgfree(ads, res);
+ ads_rc = ads_del_dn(ads, prt_dn);
+ ads_memfree(ads, prt_dn);
+ }
+
+ ads_destroy(&ads);
+ return WERR_OK;
+}
+
+/****************************************************************************
+ * Publish a printer in the directory
+ *
+ * @param snum describing printer service
+ * @return WERROR indicating status of publishing
+ ***************************************************************************/
+
+WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ WERROR win_rc;
+
+ win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(win_rc))
+ return win_rc;
+
+ switch(action) {
+ case SPOOL_DS_PUBLISH:
+ case SPOOL_DS_UPDATE:
+ win_rc = publish_it(printer);
+ break;
+ case SPOOL_DS_UNPUBLISH:
+ win_rc = unpublish_it(printer);
+ break;
+ default:
+ win_rc = WERR_NOT_SUPPORTED;
+ }
+
+
+ free_a_printer(&printer, 2);
+ return win_rc;
+}
+
+BOOL is_printer_published(Printer_entry *print_hnd, int snum, GUID *guid)
+{
+ NT_PRINTER_INFO_LEVEL *printer = NULL;
+ REGVAL_CTR *ctr;
+ REGISTRY_VALUE *guid_val;
+ WERROR win_rc;
+ int i;
+
+
+ win_rc = get_a_printer(print_hnd, &printer, 2, lp_servicename(snum));
+ if (!W_ERROR_IS_OK(win_rc))
+ return False;
+
+ if (!(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED))
+ return False;
+
+ if ((i = lookup_printerkey(&printer->info_2->data,
+ SPOOL_DSSPOOLER_KEY)) < 0)
+ return False;
+
+ if (!(ctr = &printer->info_2->data.keys[i].values)) {
+ return False;
+ }
+
+ if (!(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) {
+ return False;
+ }
+
+ if (regval_size(guid_val) == sizeof(GUID))
+ memcpy(guid, regval_data_p(guid_val), sizeof(GUID));
+
+ return True;
+}
+
+#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, GUID *guid)
+{
+ return False;
+}
+#endif
/****************************************************************************
***************************************************************************/
-WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key )
+WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
{
NT_PRINTER_DATA *data;
int i;
/* remove all keys */
- if ( !strlen(key) )
- {
- for ( i=0; i<data->num_keys; i++ )
- {
+ if ( !strlen(key) ) {
+ for ( i=0; i<data->num_keys; i++ ) {
DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
data->keys[i].name));
/* remove a specific key (and all subkeys) */
- for ( i=0; i<data->num_keys; i++ )
- {
- if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 )
- {
+ for ( i=0; i<data->num_keys; i++ ) {
+ if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
data->keys[i].name));
/* sanity check to see if anything is left */
- if ( !data->num_keys )
- {
+ if ( !data->num_keys ) {
DEBUG(8,("delete_all_printer_data: No keys left for printer [%s]\n", p2->printername ));
SAFE_FREE( data->keys );
/****************************************************************************
***************************************************************************/
-WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value )
+WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
{
WERROR result = WERR_OK;
int key_index;
/****************************************************************************
***************************************************************************/
-WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value,
+WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
uint32 type, uint8 *data, int real_len )
{
WERROR result = WERR_OK;
/****************************************************************************
***************************************************************************/
-REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, char *key, char *value )
+REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
{
int key_index;
/* loop and unpack the rest of the registry values */
- while ( True )
- {
+ while ( True ) {
/* check to see if there are any more registry values */
regval_ctr_addvalue( &printer_data->keys[key_index].values, valuename, type, 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));
}
}
/****************************************************************************
-get a default printer info 2 struct
+ Get a default printer info 2 struct.
****************************************************************************/
-static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
+static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename)
{
int snum;
NT_PRINTER_INFO_LEVEL_2 info;
fstrcpy(info.printprocessor, "winprint");
fstrcpy(info.datatype, "RAW");
- info.attributes = PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK; /* attributes */
+ info.attributes = PRINTER_ATTRIBUTE_SAMBA;
info.starttime = 0; /* Minutes since 12:00am GMT */
info.untiltime = 0; /* Minutes since 12:00am GMT */
/****************************************************************************
****************************************************************************/
-static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharename)
+static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *sharename)
{
pstring key;
NT_PRINTER_INFO_LEVEL_2 info;
info.parameters);
/* Samba has to have shared raw drivers. */
- info.attributes |= (PRINTER_ATTRIBUTE_SHARED | PRINTER_ATTRIBUTE_NETWORK);
+ info.attributes |= PRINTER_ATTRIBUTE_SAMBA;
/* Restore the stripped strings. */
slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", get_called_name());
* See comments in get_a_printer_2_default()
*/
- if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode)
- {
+ if (lp_default_devmode(lp_servicenumber(sharename)) && !info.devmode) {
DEBUG(8,("get_a_printer_2: Constructing a default device mode for [%s]\n",
printername));
info.devmode = construct_nt_devicemode(printername);
}
/****************************************************************************
-debugging function, dump at level 6 the struct in the logs
+ Debugging function, dump at level 6 the struct in the logs.
****************************************************************************/
static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL printer, uint32 level)
{
DEBUG(106,("Dumping printer at level [%d]\n", level));
- switch (level)
- {
+ switch (level) {
case 2:
{
if (printer.info_2 == NULL)
return result;
}
-/****************************************************************************
- Get the parameters we can substitute in an NT print job.
-****************************************************************************/
-
-void get_printer_subst_params(int snum, fstring *printername, fstring *sharename, fstring *portname)
-{
- NT_PRINTER_INFO_LEVEL *printer = NULL;
-
- **printername = **sharename = **portname = '\0';
-
- if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
- return;
-
- fstrcpy(*printername, printer->info_2->printername);
- fstrcpy(*sharename, printer->info_2->sharename);
- fstrcpy(*portname, printer->info_2->portname);
-
- free_a_printer(&printer, 2);
-}
-
/****************************************************************************
Update the changeid time.
This is SO NASTY as some drivers need this to change, others need it
dump_a_printer(printer, level);
- switch (level)
- {
+ /*
+ * invalidate cache for all open handles to this printer.
+ * cache for a given handle will be updated on the next
+ * get_a_printer()
+ */
+
+ invalidate_printer_hnd_cache( printer.info_2->sharename );
+
+ switch (level) {
case 2:
{
/*
*/
result=update_a_printer_2(printer.info_2);
+
break;
}
default:
*/
if ( info.devmode ) {
- ZERO_STRUCT(info.devmode->devicename);
- fstrcpy(info.devmode->devicename, info_ptr->printername);
+ ZERO_STRUCT(info.devmode->devicename);
+ fstrcpy(info.devmode->devicename, info_ptr->printername);
}
/*
{
BOOL result = False;
- switch (level)
- {
+ switch (level) {
case 2:
result = set_driver_init_2(printer->info_2);
break;
ret = -1;
goto done;
}
- else buf = tb;
+ else
+ buf = tb;
buflen = len;
goto again;
}
dump_a_printer(printer, level);
- switch (level)
- {
+ switch (level) {
case 2:
- {
result = update_driver_init_2(printer.info_2);
break;
- }
default:
result = 1;
break;
*/
DEBUG(8,("save_driver_init_2: Enter...\n"));
- if ( !printer->info_2->devmode && data_len )
- {
+ if ( !printer->info_2->devmode && data_len ) {
/*
* Set devmode on printer info, so entire printer initialization can be
* saved to tdb.
*/
- if ((ctx = talloc_init()) == NULL)
+ if ((ctx = talloc_init("save_driver_init_2")) == NULL)
return WERR_NOMEM;
if ((nt_devmode = (NT_DEVICEMODE*)malloc(sizeof(NT_DEVICEMODE))) == NULL) {
{
WERROR status = WERR_OK;
- switch (level)
- {
+ switch (level) {
case 2:
- {
status = save_driver_init_2( printer, data, data_len );
break;
- }
default:
status = WERR_UNKNOWN_LEVEL;
break;
return status;
}
+/****************************************************************************
+ Deep copy a NT_PRINTER_DATA
+****************************************************************************/
+
+static NTSTATUS copy_printer_data( NT_PRINTER_DATA *dst, NT_PRINTER_DATA *src )
+{
+ int i, j, num_vals, new_key_index;
+ REGVAL_CTR *src_key, *dst_key;
+
+ if ( !dst || !src )
+ return NT_STATUS_NO_MEMORY;
+
+ for ( i=0; i<src->num_keys; i++ ) {
+
+ /* create a new instance of the printerkey in the destination
+ printer_data object */
+
+ new_key_index = add_new_printer_key( dst, src->keys[i].name );
+ dst_key = &dst->keys[new_key_index].values;
+
+ src_key = &src->keys[i].values;
+ num_vals = regval_ctr_numvals( src_key );
+
+ /* dup the printer entire printer key */
+
+ for ( j=0; j<num_vals; j++ ) {
+ regval_ctr_copyvalue( dst_key, regval_ctr_specific_value(src_key, j) );
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Deep copy a NT_PRINTER_INFO_LEVEL_2 structure using malloc()'d memeory
+ Caller must free.
+****************************************************************************/
+
+static NT_PRINTER_INFO_LEVEL_2* dup_printer_2( TALLOC_CTX *ctx, NT_PRINTER_INFO_LEVEL_2 *printer )
+{
+ NT_PRINTER_INFO_LEVEL_2 *copy;
+
+ if ( !printer )
+ return NULL;
+
+ if ( !(copy = (NT_PRINTER_INFO_LEVEL_2 *)malloc(sizeof(NT_PRINTER_INFO_LEVEL_2))) )
+ return NULL;
+
+ memcpy( copy, printer, sizeof(NT_PRINTER_INFO_LEVEL_2) );
+
+ /* malloc()'d members copied here */
+
+ copy->devmode = dup_nt_devicemode( printer->devmode );
+
+ ZERO_STRUCT( copy->data );
+ copy_printer_data( ©->data, &printer->data );
+
+ /* this is talloc()'d; very ugly that we have a structure that
+ is half malloc()'d and half talloc()'d but that is the way
+ that the PRINTER_INFO stuff is written right now. --jerry */
+
+ copy->secdesc_buf = dup_sec_desc_buf( ctx, printer->secdesc_buf );
+
+ return copy;
+}
+
/****************************************************************************
Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
****************************************************************************/
-WERROR get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring sharename)
+#define ENABLE_PRINT_HND_CACHE 1
+
+WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
+ const char *sharename)
{
WERROR result;
NT_PRINTER_INFO_LEVEL *printer = NULL;
DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
- switch (level)
- {
+ switch (level) {
case 2:
- {
if ((printer = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL))) == NULL) {
DEBUG(0,("get_a_printer: malloc fail.\n"));
return WERR_NOMEM;
}
ZERO_STRUCTP(printer);
+
+ /*
+ * check for cache first. A Printer handle cannot changed
+ * to another printer object so we only check that the printer
+ * is actually for a printer and that the printer_info pointer
+ * is valid
+ */
+#ifdef ENABLE_PRINT_HND_CACHE /* JERRY */
+ if ( print_hnd
+ && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)
+ && print_hnd->printer_info )
+ {
+ if ( !(printer->info_2 = dup_printer_2(print_hnd->ctx, print_hnd->printer_info->info_2)) ) {
+ DEBUG(0,("get_a_printer: unable to copy cached printer info!\n"));
+
+ SAFE_FREE(printer);
+ return WERR_NOMEM;
+ }
+
+ DEBUG(10,("get_a_printer: using cached copy of printer_info_2\n"));
+
+ *pp_printer = printer;
+ result = WERR_OK;
+
+ break;
+ }
+#endif
+
+ /* no cache; look it up on disk */
+
result=get_a_printer_2(&printer->info_2, sharename);
if (W_ERROR_IS_OK(result)) {
dump_a_printer(*printer, level);
+
+#if ENABLE_PRINT_HND_CACHE /* JERRY */
+ /* save a copy in cache */
+ if ( print_hnd && (print_hnd->printer_type==PRINTER_HANDLE_IS_PRINTER)) {
+ if ( !print_hnd->printer_info )
+ print_hnd->printer_info = (NT_PRINTER_INFO_LEVEL *)malloc(sizeof(NT_PRINTER_INFO_LEVEL));
+
+ if ( print_hnd->printer_info ) {
+ print_hnd->printer_info->info_2 = dup_printer_2(print_hnd->ctx, printer->info_2);
+
+ /* don't fail the lookup just because the cache update failed */
+ if ( !print_hnd->printer_info->info_2 )
+ DEBUG(0,("get_a_printer: unable to copy new printer info!\n"));
+ }
+
+ }
+#endif
*pp_printer = printer;
- } else {
- SAFE_FREE(printer);
}
+ else
+ SAFE_FREE(printer);
+
+
break;
- }
default:
result=WERR_UNKNOWN_LEVEL;
break;
if (printer == NULL)
return 0;
- switch (level)
- {
+ switch (level) {
case 2:
- {
- if (printer->info_2 != NULL)
- {
+ if (printer->info_2 != NULL) {
free_nt_printer_info_level_2(&printer->info_2);
result=0;
- }
- else
- {
+ } else
result=4;
- }
break;
- }
+
default:
result=1;
break;
DEBUG(104,("adding a printer at level [%d]\n", level));
dump_a_printer_driver(driver, level);
- switch (level)
- {
+ switch (level) {
case 3:
- {
result=add_a_printer_driver_3(driver.info_3);
break;
- }
case 6:
- {
result=add_a_printer_driver_6(driver.info_6);
break;
- }
+
default:
result=1;
break;
}
/****************************************************************************
****************************************************************************/
+
WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
- fstring drivername, fstring architecture, uint32 version)
+ fstring drivername, const char *architecture, uint32 version)
{
WERROR result;
- switch (level)
- {
+ switch (level) {
case 3:
/* Sometime we just want any version of the driver */
result = get_a_printer_driver_3( &driver->info_3,
drivername, architecture, 2 );
}
- }
- else {
+ } else {
result = get_a_printer_driver_3(&driver->info_3, drivername,
architecture, version);
}
{
uint32 result;
- switch (level)
- {
+ switch (level) {
case 3:
{
NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
ZERO_STRUCTP(info3);
SAFE_FREE(info3);
result=0;
- }
- else
- {
+ } else {
result=4;
}
break;
case 6:
{
NT_PRINTER_DRIVER_INFO_LEVEL_6 *info6;
- if (driver.info_6 != NULL)
- {
+ if (driver.info_6 != NULL) {
info6=driver.info_6;
SAFE_FREE(info6->dependentfiles);
SAFE_FREE(info6->previousnames);
ZERO_STRUCTP(info6);
SAFE_FREE(info6);
result=0;
- }
- else
- {
+ } else {
result=4;
}
break;
/* loop through the printers.tdb and check for the drivername */
- for (snum=0; snum<n_services; snum++)
- {
+ for (snum=0; snum<n_services; snum++) {
if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
continue;
- if ( !W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))) )
+ if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
continue;
if ( !StrCaseCmp(info_3->name, printer->info_2->drivername) ) {
if ( !info->dependentfiles )
return False;
- while ( *info->dependentfiles[i] )
- {
+ while ( *info->dependentfiles[i] ) {
if ( strequal(file, info->dependentfiles[i]) )
return True;
-
i++;
}
/* bump everything down a slot */
- while( *files[idx+1] )
- {
+ while( *files[idx+1] ) {
fstrcpy( files[idx], files[idx+1] );
idx++;
}
if ( !src->dependentfiles )
return in_use;
- while ( *src->dependentfiles[i] )
- {
+ while ( *src->dependentfiles[i] ) {
if ( drv_file_in_use(src->dependentfiles[i], drv) ) {
in_use = True;
DEBUG(10,("Removing [%s] from dependent file list\n", src->dependentfiles[i]));
trim_dependent_file( src->dependentfiles, i );
- }
- else
+ } else
i++;
}
/* check each driver for overlap in files */
- for (i=0; i<ndrivers; i++)
- {
+ for (i=0; i<ndrivers; i++) {
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
ZERO_STRUCT(driver);
- if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i],
- info->environment, version)) )
- {
+ if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], info->environment, version)) ) {
SAFE_FREE(list);
return True;
}
/* check if d2 uses any files from d1 */
/* only if this is a different driver than the one being deleted */
- if ( !strequal(info->name, driver.info_3->name) )
- {
+ if ( !strequal(info->name, driver.info_3->name) ) {
if ( trim_overlap_drv_files(info, driver.info_3) ) {
free_a_printer_driver(driver, 3);
SAFE_FREE( list );
connection_struct *conn;
DATA_BLOB null_pw;
NTSTATUS nt_status;
-
+ fstring res_type;
+
if ( !info_3 )
return False;
* do this.
*/
- become_root();
null_pw = data_blob( NULL, 0 );
- conn = make_connection_with_chdir( "print$", null_pw, "A:", user->vuid, &nt_status );
+ fstrcpy(res_type, "A:");
+ become_root();
+ conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status );
unbecome_root();
if ( !conn ) {
/* check if we are done removing files */
- if ( info_3->dependentfiles )
- {
+ if ( info_3->dependentfiles ) {
while ( *info_3->dependentfiles[i] ) {
char *file;
/* bypass the "\print$" portion of the path */
- if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL )
- {
+ if ( (file = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
DEBUG(10,("deleting dependent file [%s]\n", file));
unlink_internals(conn, 0, file );
}
uint32 version, BOOL delete_files )
{
pstring key;
- fstring arch;
+ const char *arch;
TDB_DATA kbuf, dbuf;
NT_PRINTER_DRIVER_INFO_LEVEL ctr;
/* delete the tdb data first */
- get_short_archi(arch, info_3->environment);
+ arch = get_short_archi(info_3->environment);
slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
arch, version, info_3->name);
fstring key;
WERROR status;
- mem_ctx = talloc_init();
+ mem_ctx = talloc_init("nt_printing_setsec");
if (mem_ctx == NULL)
return WERR_NOMEM;
fstring key;
char *temp;
- if ((temp = strchr(printername + 2, '\\'))) {
+ if (strlen(printername) > 2 && (temp = strchr(printername + 2, '\\'))) {
printername = temp + 1;
}
/* Always allow root or printer admins to do anything */
if (user->uid == 0 ||
- user_in_list(uidtoname(user->uid), lp_printer_admin(snum))) {
+ user_in_list(uidtoname(user->uid), lp_printer_admin(snum), user->groups, user->ngroups)) {
return True;
}
/* Get printer security descriptor */
- if(!(mem_ctx = talloc_init())) {
+ if(!(mem_ctx = talloc_init("print_access_check"))) {
errno = ENOMEM;
return False;
}
struct tm *t;
uint32 mins;
- if (!W_ERROR_IS_OK(get_a_printer(&printer, 2, lp_servicename(snum))))
+ if (!W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))))
return False;
if (printer->info_2->starttime == 0 && printer->info_2->untiltime == 0)