mirror of
https://github.com/samba-team/samba.git
synced 2025-01-24 02:04:21 +03:00
A rather big change set ! (listed in no particular order)
- changed the default forms flag to 2 - all short architecture name are uppercased - get_short_archi() is now case unsensitive - the drivers TDB is indexed by archi/version/name - implemented code to move drivers from the upload area to the download area. Someone else need to look at that code. - don't return anymore a default driver if it doesn't exist in the TDB. Instead return an error. - cleaned prs_unistr. - #ifdef out jeremy's new SD parsing in printer_info_2 - removed the unused MANGLE_CODE - #ifdef out the security checking in update_printer() as it doesn't work for me. Zap your ntdrivers.tdb, it won't work anymore. J.F.
This commit is contained in:
parent
dcf3249bb9
commit
ac0a145acc
@ -1668,8 +1668,10 @@ int get_ntforms(nt_forms_struct **list);
|
||||
int write_ntforms(nt_forms_struct **list, int number);
|
||||
BOOL add_a_form(nt_forms_struct **list, const FORM *form, int *count);
|
||||
void update_a_form(nt_forms_struct **list, const FORM *form, int count);
|
||||
int get_ntdrivers(fstring **list, char *architecture);
|
||||
void get_short_archi(char *short_archi, char *long_archi);
|
||||
int get_ntdrivers(fstring **list, char *architecture, uint32 version);
|
||||
BOOL get_short_archi(char *short_archi, char *long_archi);
|
||||
uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level);
|
||||
uint32 move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user);
|
||||
uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model);
|
||||
uint32 del_a_printer(char *sharename);
|
||||
BOOL add_a_specific_param(NT_PRINTER_INFO_LEVEL_2 *info_2, NT_PRINTER_PARAM *param);
|
||||
@ -1682,7 +1684,7 @@ uint32 get_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, fstring s
|
||||
uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level);
|
||||
uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
|
||||
uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
|
||||
fstring printername, fstring architecture);
|
||||
fstring printername, fstring architecture, uint32 version);
|
||||
uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level);
|
||||
BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
|
||||
fstring value, uint8 **data, uint32 *type, uint32 *len);
|
||||
@ -2319,7 +2321,6 @@ BOOL prs_string2(BOOL charmode, char *name, prs_struct *ps, int depth, STRING2 *
|
||||
BOOL prs_unistr2(BOOL charmode, char *name, prs_struct *ps, int depth, UNISTR2 *str);
|
||||
BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int depth);
|
||||
BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
|
||||
BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str);
|
||||
BOOL prs_string(char *name, prs_struct *ps, int depth, char *str, int len, int max_buf_size);
|
||||
BOOL prs_uint16_pre(char *name, prs_struct *ps, int depth, uint16 *data16, uint32 *offset);
|
||||
BOOL prs_uint16_post(char *name, prs_struct *ps, int depth, uint16 *data16,
|
||||
@ -3112,9 +3113,8 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
|
||||
uint32 unk0, uint32 unk1, uint32 unk2, uint32 unk3,
|
||||
uint32 user_switch, const SPOOL_USER_CTR *user,
|
||||
POLICY_HND *handle);
|
||||
uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
|
||||
uint32 level,
|
||||
const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info);
|
||||
uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
|
||||
uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info);
|
||||
uint32 _spoolss_getprinterdriverdirectory(UNISTR2 *name, UNISTR2 *uni_environment, uint32 level,
|
||||
NEW_BUFFER *buffer, uint32 offered,
|
||||
uint32 *needed);
|
||||
@ -3625,6 +3625,7 @@ int reply_printclose(connection_struct *conn,
|
||||
int reply_printqueue(connection_struct *conn,
|
||||
char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
|
||||
int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
|
||||
int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory);
|
||||
int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
|
||||
BOOL rmdir_internals(connection_struct *conn, char *directory);
|
||||
int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize);
|
||||
|
@ -184,8 +184,10 @@ implemented */
|
||||
#define ERROR_EAS_DIDNT_FIT (275) /* Extended attributes didn't fit */
|
||||
#define ERROR_EAS_NOT_SUPPORTED (282) /* Extended attributes not supported */
|
||||
#define ERROR_NOTIFY_ENUM_DIR (1022) /* Buffer too small to return change notify. */
|
||||
#define ERROR_UNKNOWN_PRINTER_DRIVER (1797)
|
||||
#define ERROR_INVALID_PRINTER_NAME (1801)
|
||||
#define ERROR_INVALID_DATATYPE (1804)
|
||||
#define ERROR_INVALID_ENVIRONMENT (1805)
|
||||
|
||||
/* here's a special one from observing NT */
|
||||
#define ERRnoipc 66 /* don't support ipc */
|
||||
|
@ -37,8 +37,8 @@ static TDB_CONTEXT *tdb; /* used for driver files */
|
||||
/* we need to have a small set of default forms to support our
|
||||
default printer */
|
||||
static nt_forms_struct default_forms[] = {
|
||||
{"Letter", 0x20, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
|
||||
{"A4", 0xb0, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
|
||||
{"Letter", 0x2, 0x34b5b, 0x44367, 0x0, 0x0, 0x34b5b, 0x44367},
|
||||
{"A4", 0x2, 0x3354f, 0x4884e, 0x0, 0x0, 0x3354f, 0x4884e}
|
||||
};
|
||||
|
||||
|
||||
@ -216,7 +216,7 @@ get the nt drivers list
|
||||
|
||||
traverse the database and look-up the matching names
|
||||
****************************************************************************/
|
||||
int get_ntdrivers(fstring **list, char *architecture)
|
||||
int get_ntdrivers(fstring **list, char *architecture, uint32 version)
|
||||
{
|
||||
int total=0;
|
||||
fstring short_archi;
|
||||
@ -224,7 +224,7 @@ int get_ntdrivers(fstring **list, char *architecture)
|
||||
TDB_DATA kbuf, newkey;
|
||||
|
||||
get_short_archi(short_archi, architecture);
|
||||
slprintf(key, sizeof(key), "%s%s/", DRIVERS_PREFIX, short_archi);
|
||||
slprintf(key, sizeof(key), "%s%s/%d/", DRIVERS_PREFIX, short_archi, version);
|
||||
|
||||
for (kbuf = tdb_firstkey(tdb);
|
||||
kbuf.dptr;
|
||||
@ -245,7 +245,7 @@ int get_ntdrivers(fstring **list, char *architecture)
|
||||
function to do the mapping between the long architecture name and
|
||||
the short one.
|
||||
****************************************************************************/
|
||||
void get_short_archi(char *short_archi, char *long_archi)
|
||||
BOOL get_short_archi(char *short_archi, char *long_archi)
|
||||
{
|
||||
struct table {
|
||||
char *long_archi;
|
||||
@ -256,9 +256,9 @@ void get_short_archi(char *short_archi, char *long_archi)
|
||||
{
|
||||
{"Windows 4.0", "WIN40" },
|
||||
{"Windows NT x86", "W32X86" },
|
||||
{"Windows NT R4000", "W32mips" },
|
||||
{"Windows NT Alpha_AXP", "W32alpha" },
|
||||
{"Windows NT PowerPC", "W32ppc" },
|
||||
{"Windows NT R4000", "W32MIPS" },
|
||||
{"Windows NT Alpha_AXP", "W32ALPHA" },
|
||||
{"Windows NT PowerPC", "W32PPC" },
|
||||
{NULL, "" }
|
||||
};
|
||||
|
||||
@ -267,17 +267,192 @@ void get_short_archi(char *short_archi, char *long_archi)
|
||||
DEBUG(107,("Getting architecture dependant directory\n"));
|
||||
do {
|
||||
i++;
|
||||
} while ( (archi_table[i].long_archi!=NULL ) && strncmp(long_archi, archi_table[i].long_archi, strlen(long_archi)) );
|
||||
} while ( (archi_table[i].long_archi!=NULL ) &&
|
||||
StrCaseCmp(long_archi, archi_table[i].long_archi) );
|
||||
|
||||
if (archi_table[i].long_archi==NULL)
|
||||
{
|
||||
if (archi_table[i].long_archi==NULL) {
|
||||
DEBUGADD(107,("Unknown architecture [%s] !\n", long_archi));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
StrnCpy (short_archi, archi_table[i].short_archi, strlen(archi_table[i].short_archi));
|
||||
|
||||
DEBUGADD(108,("index: [%d]\n", i));
|
||||
DEBUGADD(108,("long architecture: [%s]\n", long_archi));
|
||||
DEBUGADD(108,("short architecture: [%s]\n", short_archi));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
static uint32 clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
|
||||
{
|
||||
fstring architecture;
|
||||
fstring new_name;
|
||||
char *p;
|
||||
int i;
|
||||
|
||||
/* jfm:7/16/2000 the client always sends the cversion=0.
|
||||
* The server should check which version the driver is by reading the PE header
|
||||
* of driver->driverpath.
|
||||
*
|
||||
* For Windows 95/98 the version is 0 (so the value sent is correct)
|
||||
* For Windows NT (the architecture doesn't matter)
|
||||
* NT 3.1: cversion=0
|
||||
* NT 3.5/3.51: cversion=1
|
||||
* NT 4: cversion=2
|
||||
* NT2K: cversion=3
|
||||
*/
|
||||
|
||||
get_short_archi(architecture, driver->environment);
|
||||
|
||||
/* if it's Windows 95/98, we keep the version at 0
|
||||
* jfmxxx: I need to redo that more correctly for NT2K.
|
||||
*/
|
||||
|
||||
if (StrCaseCmp(driver->environment, "Windows 4.0")==0)
|
||||
driver->cversion=0;
|
||||
else
|
||||
driver->cversion=2;
|
||||
|
||||
/* clean up the driver name.
|
||||
* we can get .\driver.dll
|
||||
* or worse c:\windows\system\driver.dll !
|
||||
*/
|
||||
/* using an intermediate string to not have overlaping memcpy()'s */
|
||||
if ((p = strrchr(driver->driverpath,'\\')) != NULL) {
|
||||
fstrcpy(new_name, p+1);
|
||||
fstrcpy(driver->driverpath, new_name);
|
||||
}
|
||||
|
||||
if ((p = strrchr(driver->datafile,'\\')) != NULL) {
|
||||
fstrcpy(new_name, p+1);
|
||||
fstrcpy(driver->datafile, new_name);
|
||||
}
|
||||
|
||||
if ((p = strrchr(driver->configfile,'\\')) != NULL) {
|
||||
fstrcpy(new_name, p+1);
|
||||
fstrcpy(driver->configfile, new_name);
|
||||
}
|
||||
|
||||
if ((p = strrchr(driver->helpfile,'\\')) != NULL) {
|
||||
fstrcpy(new_name, p+1);
|
||||
fstrcpy(driver->helpfile, new_name);
|
||||
}
|
||||
|
||||
if (driver->dependentfiles) {
|
||||
for (i=0; *driver->dependentfiles[i]; i++) {
|
||||
if ((p = strrchr(driver->dependentfiles[i],'\\')) != NULL) {
|
||||
fstrcpy(new_name, p+1);
|
||||
fstrcpy(driver->dependentfiles[i], new_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
static uint32 clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
uint32 clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level)
|
||||
{
|
||||
switch (level) {
|
||||
case 3:
|
||||
{
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
|
||||
driver=driver_abstract.info_3;
|
||||
clean_up_driver_struct_level_3(driver);
|
||||
break;
|
||||
}
|
||||
case 6:
|
||||
{
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
|
||||
driver=driver_abstract.info_6;
|
||||
clean_up_driver_struct_level_6(driver);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
uint32 move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, struct current_user *user)
|
||||
{
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
|
||||
fstring architecture;
|
||||
fstring clean_driver_name;
|
||||
pstring new_dir;
|
||||
pstring old_name;
|
||||
pstring new_name;
|
||||
connection_struct *conn;
|
||||
fstring inbuf;
|
||||
fstring outbuf;
|
||||
struct smb_passwd *smb_pass;
|
||||
int ecode;
|
||||
int outsize = 0;
|
||||
int i;
|
||||
|
||||
if (level==3)
|
||||
driver=driver_abstract.info_3;
|
||||
|
||||
get_short_archi(architecture, driver->environment);
|
||||
|
||||
/* clean up the driver's name */
|
||||
fstrcpy(clean_driver_name, driver->name);
|
||||
all_string_sub(clean_driver_name, "/", "#", 0);
|
||||
|
||||
/* connect to the print$ share under the same account as the user connected to the rpc pipe */
|
||||
smb_pass = getsmbpwnam(uidtoname(user->uid));
|
||||
conn = make_connection("print$", uidtoname(user->uid), smb_pass->smb_nt_passwd, 24, "A:", user->vuid, &ecode);
|
||||
|
||||
/*
|
||||
* make the directories version and version\driver_name
|
||||
* under the architecture directory.
|
||||
*/
|
||||
DEBUG(5,("Creating first directory\n"));
|
||||
slprintf(new_dir, sizeof(new_dir), "%s\\%d", architecture, driver->cversion);
|
||||
mkdir_internal(conn, inbuf, outbuf, new_dir);
|
||||
|
||||
slprintf(new_dir, sizeof(new_dir), "%s\\%d\\%s", architecture, driver->cversion, clean_driver_name);
|
||||
mkdir_internal(conn, inbuf, outbuf, new_dir);
|
||||
|
||||
/* move all the files, one by one,
|
||||
* from archi\filexxx.yyy to
|
||||
* archi\version\driver name\filexxx.yyy
|
||||
*/
|
||||
|
||||
DEBUG(5,("Moving file now !\n"));
|
||||
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->driverpath);
|
||||
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->driverpath);
|
||||
outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False);
|
||||
|
||||
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->datafile);
|
||||
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->datafile);
|
||||
outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False);
|
||||
|
||||
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->configfile);
|
||||
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->configfile);
|
||||
outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False);
|
||||
|
||||
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->helpfile);
|
||||
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->helpfile);
|
||||
outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False);
|
||||
|
||||
if (driver->dependentfiles) {
|
||||
for (i=0; *driver->dependentfiles[i]; i++) {
|
||||
slprintf(old_name, sizeof(old_name), "%s\\%s", architecture, driver->dependentfiles[i]);
|
||||
slprintf(new_name, sizeof(new_name), "%s\\%s", new_dir, driver->dependentfiles[i]);
|
||||
outsize = rename_internals(conn, inbuf, outbuf, old_name, new_name, False);
|
||||
}
|
||||
}
|
||||
|
||||
close_cnum(conn, user->vuid);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -286,24 +461,49 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
|
||||
{
|
||||
int len, buflen;
|
||||
fstring architecture;
|
||||
pstring directory;
|
||||
fstring clean_driver_name;
|
||||
pstring temp_name;
|
||||
pstring key;
|
||||
char *buf;
|
||||
int i, ret;
|
||||
TDB_DATA kbuf, dbuf;
|
||||
|
||||
get_short_archi(architecture, driver->environment);
|
||||
slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, driver->name);
|
||||
|
||||
/*
|
||||
* cversion must be 2.
|
||||
* when adding a printer ON the SERVER
|
||||
* rpcAddPrinterDriver defines it to zero
|
||||
* which is wrong !!!
|
||||
*
|
||||
* JFM, 4/14/99
|
||||
/* The names are relative. We store them in the form: \print$\arch\version\printer-name\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.
|
||||
*/
|
||||
driver->cversion=2;
|
||||
|
||||
/* clean up the driver's name */
|
||||
fstrcpy(clean_driver_name, driver->name);
|
||||
all_string_sub(clean_driver_name, "/", "#", 0);
|
||||
|
||||
slprintf(directory, sizeof(directory), "\\print$\\%s\\%d\\%s\\", architecture, driver->cversion, clean_driver_name);
|
||||
|
||||
|
||||
fstrcpy(temp_name, driver->driverpath);
|
||||
slprintf(driver->driverpath, sizeof(driver->driverpath), "%s%s", directory, temp_name);
|
||||
|
||||
fstrcpy(temp_name, driver->datafile);
|
||||
slprintf(driver->datafile, sizeof(driver->datafile), "%s%s", directory, temp_name);
|
||||
|
||||
fstrcpy(temp_name, driver->configfile);
|
||||
slprintf(driver->configfile, sizeof(driver->configfile), "%s%s", directory, temp_name);
|
||||
|
||||
fstrcpy(temp_name, driver->helpfile);
|
||||
slprintf(driver->helpfile, sizeof(driver->helpfile), "%s%s", directory, temp_name);
|
||||
|
||||
if (driver->dependentfiles) {
|
||||
for (i=0; *driver->dependentfiles[i]; i++) {
|
||||
fstrcpy(temp_name, driver->dependentfiles[i]);
|
||||
slprintf(driver->dependentfiles[i], sizeof(driver->dependentfiles[i]), "%s%s", directory, temp_name);
|
||||
}
|
||||
}
|
||||
|
||||
slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, driver->cversion, driver->name);
|
||||
|
||||
buf = NULL;
|
||||
len = buflen = 0;
|
||||
|
||||
@ -319,7 +519,7 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
|
||||
driver->helpfile,
|
||||
driver->monitorname,
|
||||
driver->defaultdatatype);
|
||||
|
||||
|
||||
if (driver->dependentfiles) {
|
||||
for (i=0; *driver->dependentfiles[i]; i++) {
|
||||
len += tdb_pack(buf+len, buflen-len, "f",
|
||||
@ -395,7 +595,7 @@ static uint32 get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch)
|
||||
static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring in_prt, fstring in_arch, uint32 version)
|
||||
{
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
|
||||
TDB_DATA kbuf, dbuf;
|
||||
@ -407,14 +607,20 @@ static uint32 get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
|
||||
ZERO_STRUCT(driver);
|
||||
|
||||
get_short_archi(architecture, in_arch);
|
||||
slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, architecture, in_prt);
|
||||
|
||||
DEBUG(8,("get_a_printer_driver_3: [%s%s/%d/%s]\n", DRIVERS_PREFIX, architecture, version, in_prt));
|
||||
|
||||
slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, architecture, version, in_prt);
|
||||
|
||||
kbuf.dptr = key;
|
||||
kbuf.dsize = strlen(key)+1;
|
||||
|
||||
dbuf = tdb_fetch(tdb, kbuf);
|
||||
#if 0
|
||||
if (!dbuf.dptr) return get_a_printer_driver_3_default(info_ptr, in_prt, in_arch);
|
||||
|
||||
#else
|
||||
if (!dbuf.dptr) return 5;
|
||||
#endif
|
||||
len += tdb_unpack(dbuf.dptr, dbuf.dsize, "dffffffff",
|
||||
&driver.cversion,
|
||||
driver.name,
|
||||
@ -464,7 +670,7 @@ uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
|
||||
int i;
|
||||
line[0] = '\0';
|
||||
|
||||
slprintf(key, sizeof(key), "%s%s/%s", DRIVERS_PREFIX, "WIN40", model);
|
||||
slprintf(key, sizeof(key), "%s%s/%d/%s", DRIVERS_PREFIX, "WIN40", 0, model);
|
||||
DEBUG(10,("driver key: [%s]\n", key));
|
||||
|
||||
kbuf.dptr = key;
|
||||
@ -472,7 +678,7 @@ uint32 get_a_printer_driver_9x_compatible(pstring line, fstring model)
|
||||
if (!tdb_exists(tdb, kbuf)) return False;
|
||||
|
||||
ZERO_STRUCT(info3);
|
||||
get_a_printer_driver_3(&info3, model, "Windows 4.0");
|
||||
get_a_printer_driver_3(&info3, model, "Windows 4.0", 0);
|
||||
|
||||
DEBUGADD(10,("info3->name [%s]\n", info3->name));
|
||||
DEBUGADD(10,("info3->datafile [%s]\n", info3->datafile));
|
||||
@ -754,7 +960,7 @@ static uint32 add_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
|
||||
safe_free(buf);
|
||||
|
||||
DEBUG(8,("packed printer [%s] with driver [%s] portname=[%s] len=%d\n",
|
||||
info->portname, info->drivername, info->portname, len));
|
||||
info->sharename, info->drivername, info->portname, len));
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1071,6 +1277,8 @@ static int unpack_specifics(NT_PRINTER_PARAM **list, char *buf, int buflen)
|
||||
¶m.data);
|
||||
param.next = *list;
|
||||
*list = memdup(¶m, sizeof(param));
|
||||
|
||||
DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
|
||||
}
|
||||
|
||||
return len;
|
||||
@ -1110,8 +1318,10 @@ static uint32 get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstrin
|
||||
if ((info.devmode = construct_nt_devicemode(info.printername)) == NULL)
|
||||
goto fail;
|
||||
|
||||
#if 1
|
||||
if (!nt_printing_getsec(sharename, &info.secdesc_buf))
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
*info_ptr = (NT_PRINTER_INFO_LEVEL_2 *)memdup(&info, sizeof(info));
|
||||
if (! *info_ptr) {
|
||||
@ -1141,8 +1351,7 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
|
||||
|
||||
ZERO_STRUCT(info);
|
||||
|
||||
slprintf(key, sizeof(key), "%s%s",
|
||||
PRINTERS_PREFIX, sharename);
|
||||
slprintf(key, sizeof(key), "%s%s", PRINTERS_PREFIX, sharename);
|
||||
|
||||
kbuf.dptr = key;
|
||||
kbuf.dsize = strlen(key)+1;
|
||||
@ -1184,7 +1393,9 @@ static uint32 get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, fstring sharen
|
||||
len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
|
||||
len += unpack_specifics(&info.specific,dbuf.dptr+len, dbuf.dsize-len);
|
||||
|
||||
#if 1 /* JRATEST */
|
||||
nt_printing_getsec(sharename, &info.secdesc_buf);
|
||||
#endif /* JRATEST */
|
||||
|
||||
safe_free(dbuf.dptr);
|
||||
*info_ptr=memdup(&info, sizeof(info));
|
||||
@ -1393,7 +1604,7 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
|
||||
fstring printername, fstring architecture)
|
||||
fstring printername, fstring architecture, uint32 version)
|
||||
{
|
||||
uint32 success;
|
||||
|
||||
@ -1403,7 +1614,7 @@ uint32 get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
|
||||
{
|
||||
success=get_a_printer_driver_3(&(driver->info_3),
|
||||
printername,
|
||||
architecture);
|
||||
architecture, version);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -1645,6 +1856,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(void)
|
||||
init_sec_ace(&ace, &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
|
||||
sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
|
||||
|
||||
|
||||
/* Make the security descriptor owned by the Administrators group
|
||||
on the PDC of the domain. */
|
||||
|
||||
|
@ -628,61 +628,6 @@ BOOL prs_unistr3(BOOL charmode, char *name, UNISTR3 *str, prs_struct *ps, int de
|
||||
in little-endian format then do it as a stream of bytes.
|
||||
********************************************************************/
|
||||
|
||||
#ifndef RPCCLIENT_TEST
|
||||
BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
|
||||
{
|
||||
int len = 0;
|
||||
unsigned char *p = (unsigned char *)str->buffer;
|
||||
uint8 *start;
|
||||
char *q;
|
||||
char zero=0;
|
||||
|
||||
for(len = 0; len < (sizeof(str->buffer) / sizeof(str->buffer[0])) &&
|
||||
str->buffer[len] != 0; len++)
|
||||
;
|
||||
|
||||
q = prs_mem_get(ps, (len+1)*2);
|
||||
if (q == NULL)
|
||||
return False;
|
||||
|
||||
start = (uint8*)q;
|
||||
|
||||
for(len = 0; len < (sizeof(str->buffer) / sizeof(str->buffer[0])) &&
|
||||
str->buffer[len] != 0; len++) {
|
||||
if(ps->bigendian_data) {
|
||||
RW_SVAL(ps->io, ps->bigendian_data, q, *p, 0);
|
||||
p += 2;
|
||||
q += 2;
|
||||
} else {
|
||||
RW_CVAL(ps->io, q, *p, 0);
|
||||
p++;
|
||||
q++;
|
||||
RW_CVAL(ps->io, q, *p, 0);
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* even if the string is 'empty' (only an \0 char)
|
||||
* at this point the leading \0 hasn't been parsed.
|
||||
* so parse it now
|
||||
*/
|
||||
|
||||
RW_CVAL(ps->io, q, zero, 0);
|
||||
q++;
|
||||
RW_CVAL(ps->io, q, zero, 0);
|
||||
q++;
|
||||
|
||||
len++;
|
||||
|
||||
ps->data_offset += len*2;
|
||||
|
||||
dump_data(5+depth, (char *)start, len * 2);
|
||||
|
||||
return True;
|
||||
}
|
||||
#else
|
||||
BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
|
||||
{
|
||||
int len = 0;
|
||||
@ -769,8 +714,6 @@ BOOL prs_unistr(char *name, prs_struct *ps, int depth, UNISTR *str)
|
||||
return True;
|
||||
}
|
||||
|
||||
#endif /* RPCCLIENT_TEST */
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
Stream a null-terminated string. len is strlen, and therefore does
|
||||
|
@ -1791,8 +1791,13 @@ BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *i
|
||||
if (!new_smb_io_relstr("parameters", buffer, depth, &info->parameters))
|
||||
return False;
|
||||
|
||||
if (!prs_uint32_pre("secdesc_ptr ", ps, depth, &i, &sec_offset))
|
||||
#if 0 /* JFMTEST */
|
||||
if (!prs_uint32_pre("secdesc_ptr ", ps, depth, NULL, &sec_offset))
|
||||
return False;
|
||||
#else
|
||||
if (!new_smb_io_relsecdesc("secdesc", buffer, depth, &info->secdesc))
|
||||
return False;
|
||||
#endif
|
||||
|
||||
if (!prs_uint32("attributes", ps, depth, &info->attributes))
|
||||
return False;
|
||||
@ -1811,12 +1816,13 @@ BOOL new_smb_io_printer_info_2(char *desc, NEW_BUFFER *buffer, PRINTER_INFO_2 *i
|
||||
if (!prs_uint32("averageppm", ps, depth, &info->averageppm))
|
||||
return False;
|
||||
|
||||
if (!prs_uint32_post("secdesc_ptr", ps, depth, &i, sec_offset, info->secdesc ? prs_offset(ps) : 0 ))
|
||||
#if 0 /* JFMTEST */
|
||||
if (!prs_uint32_post("secdesc_ptr", ps, depth, NULL, sec_offset, info->secdesc ? prs_offset(ps)-buffer->struct_start : 0 ))
|
||||
return False;
|
||||
|
||||
if (!sec_io_desc("secdesc", &info->secdesc, ps, depth))
|
||||
return False;
|
||||
|
||||
#endif
|
||||
return True;
|
||||
}
|
||||
|
||||
@ -4285,7 +4291,6 @@ BOOL make_spoolss_q_getprinterdriverdir(SPOOL_Q_GETPRINTERDRIVERDIR *q_u,
|
||||
NEW_BUFFER *buffer, uint32 offered)
|
||||
{
|
||||
init_buf_unistr2(&q_u->name, &q_u->name_ptr, servername);
|
||||
|
||||
init_buf_unistr2(&q_u->environment, &q_u->environment_ptr, env_name);
|
||||
|
||||
q_u->level=level;
|
||||
|
@ -880,7 +880,7 @@ static BOOL api_spoolss_addprinterdriver(pipes_struct *p)
|
||||
return False;
|
||||
}
|
||||
|
||||
r_u.status = _spoolss_addprinterdriver(&q_u.server_name, q_u.level, &q_u.info);
|
||||
r_u.status = _spoolss_addprinterdriver(p, &q_u.server_name, q_u.level, &q_u.info);
|
||||
|
||||
if(!spoolss_io_r_addprinterdriver("", &r_u, rdata, 0)) {
|
||||
DEBUG(0,("spoolss_io_r_addprinterdriver: unable to marshall SPOOL_R_ADDPRINTERDRIVER.\n"));
|
||||
|
@ -25,10 +25,6 @@
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifndef MANGLE_DRIVER_PATH
|
||||
#define MANGLE_DRIVER_PATH 0
|
||||
#endif
|
||||
|
||||
extern int DEBUGLEVEL;
|
||||
extern pstring global_myname;
|
||||
|
||||
@ -2479,73 +2475,66 @@ uint32 _spoolss_getprinter(POLICY_HND *handle, uint32 level,
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* construct_printer_driver_info_1
|
||||
* fill a construct_printer_driver_info_1 struct
|
||||
* fill a DRIVER_INFO_1 struct
|
||||
********************************************************************/
|
||||
static void fill_printer_driver_info_1(DRIVER_INFO_1 *info,
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver,
|
||||
fstring servername, fstring architecture)
|
||||
static void fill_printer_driver_info_1(DRIVER_INFO_1 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername, fstring architecture)
|
||||
{
|
||||
init_unistr( &(info->name), driver.info_3->name);
|
||||
}
|
||||
|
||||
static void construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum,
|
||||
fstring servername, fstring architecture)
|
||||
/********************************************************************
|
||||
* construct_printer_driver_info_1
|
||||
********************************************************************/
|
||||
static uint32 construct_printer_driver_info_1(DRIVER_INFO_1 *info, int snum, fstring servername, fstring architecture, uint32 version)
|
||||
{
|
||||
NT_PRINTER_INFO_LEVEL *printer = NULL;
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver;
|
||||
|
||||
ZERO_STRUCT(driver);
|
||||
|
||||
get_a_printer(&printer, 2, lp_servicename(snum) );
|
||||
get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture);
|
||||
|
||||
if (get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
|
||||
return ERROR_INVALID_PRINTER_NAME;
|
||||
|
||||
if (get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
|
||||
return ERROR_UNKNOWN_PRINTER_DRIVER;
|
||||
|
||||
fill_printer_driver_info_1(info, driver, servername, architecture);
|
||||
|
||||
free_a_printer(&printer,2);
|
||||
|
||||
return NT_STATUS_NO_PROBLEMO;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* construct_printer_driver_info_2
|
||||
* fill a printer_info_2 struct
|
||||
********************************************************************/
|
||||
static void fill_printer_driver_info_2(DRIVER_INFO_2 *info,
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver,
|
||||
fstring servername, fstring architecture)
|
||||
static void fill_printer_driver_info_2(DRIVER_INFO_2 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
|
||||
{
|
||||
pstring where;
|
||||
pstring temp_driverpath;
|
||||
pstring temp_datafile;
|
||||
pstring temp_configfile;
|
||||
fstring short_archi;
|
||||
|
||||
get_short_archi(short_archi,architecture);
|
||||
|
||||
snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi);
|
||||
|
||||
info->version=driver.info_3->cversion;
|
||||
|
||||
init_unistr( &info->name, driver.info_3->name );
|
||||
init_unistr( &info->architecture, architecture );
|
||||
|
||||
snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where,
|
||||
driver.info_3->driverpath);
|
||||
init_unistr( &info->driverpath, temp_driverpath );
|
||||
init_unistr( &info->name, driver.info_3->name );
|
||||
init_unistr( &info->architecture, driver.info_3->environment );
|
||||
|
||||
snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where,
|
||||
driver.info_3->datafile);
|
||||
init_unistr( &info->datafile, temp_datafile );
|
||||
snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
|
||||
init_unistr( &info->driverpath, temp_driverpath );
|
||||
|
||||
snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where,
|
||||
driver.info_3->configfile);
|
||||
init_unistr( &info->configfile, temp_configfile );
|
||||
snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
|
||||
init_unistr( &info->datafile, temp_datafile );
|
||||
|
||||
snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
|
||||
init_unistr( &info->configfile, temp_configfile );
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* construct_printer_driver_info_2
|
||||
* fill a printer_info_2 struct
|
||||
********************************************************************/
|
||||
static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture)
|
||||
static uint32 construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstring servername, fstring architecture, uint32 version)
|
||||
{
|
||||
NT_PRINTER_INFO_LEVEL *printer = NULL;
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver;
|
||||
@ -2553,12 +2542,17 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstri
|
||||
ZERO_STRUCT(printer);
|
||||
ZERO_STRUCT(driver);
|
||||
|
||||
get_a_printer(&printer, 2, lp_servicename(snum) );
|
||||
get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture);
|
||||
if (!get_a_printer(&printer, 2, lp_servicename(snum)) != 0)
|
||||
return ERROR_INVALID_PRINTER_NAME;
|
||||
|
||||
fill_printer_driver_info_2(info, driver, servername, architecture);
|
||||
if (!get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version) != 0)
|
||||
return ERROR_UNKNOWN_PRINTER_DRIVER;
|
||||
|
||||
fill_printer_driver_info_2(info, driver, servername);
|
||||
|
||||
free_a_printer(&printer,2);
|
||||
|
||||
return NT_STATUS_NO_PROBLEMO;
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
@ -2566,7 +2560,7 @@ static void construct_printer_driver_info_2(DRIVER_INFO_2 *info, int snum, fstri
|
||||
*
|
||||
* convert an array of ascii string to a UNICODE string
|
||||
********************************************************************/
|
||||
static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *where)
|
||||
static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *servername)
|
||||
{
|
||||
int i=0;
|
||||
int j=0;
|
||||
@ -2584,7 +2578,7 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *whe
|
||||
if (!v) v = ""; /* hack to handle null lists */
|
||||
}
|
||||
if (strlen(v) == 0) break;
|
||||
snprintf(line, sizeof(line)-1, "%s%s", where, v);
|
||||
snprintf(line, sizeof(line)-1, "\\\\%s%s", servername, v);
|
||||
DEBUGADD(6,("%d:%s:%d\n", i, line, strlen(line)));
|
||||
if((*uni_array=Realloc(*uni_array, (j+strlen(line)+2)*sizeof(uint16))) == NULL) {
|
||||
DEBUG(0,("init_unistr_array: Realloc error\n" ));
|
||||
@ -2605,67 +2599,63 @@ static void init_unistr_array(uint16 **uni_array, fstring *char_array, char *whe
|
||||
* construct_printer_info_3
|
||||
* fill a printer_info_3 struct
|
||||
********************************************************************/
|
||||
static void fill_printer_driver_info_3(DRIVER_INFO_3 *info,
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver,
|
||||
fstring servername, fstring architecture)
|
||||
static void fill_printer_driver_info_3(DRIVER_INFO_3 *info, NT_PRINTER_DRIVER_INFO_LEVEL driver, fstring servername)
|
||||
{
|
||||
pstring where;
|
||||
pstring temp_driverpath;
|
||||
pstring temp_datafile;
|
||||
pstring temp_configfile;
|
||||
pstring temp_helpfile;
|
||||
fstring short_archi;
|
||||
|
||||
get_short_archi(short_archi, architecture);
|
||||
|
||||
#if MANGLE_DRIVER_PATH
|
||||
snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\%s\\", servername, short_archi, driver.info_3->name);
|
||||
#else
|
||||
snprintf(where,sizeof(where)-1,"\\\\%s\\print$\\%s\\", servername, short_archi);
|
||||
#endif
|
||||
|
||||
info->version=driver.info_3->cversion;
|
||||
|
||||
init_unistr( &info->name, driver.info_3->name );
|
||||
init_unistr( &info->architecture, architecture );
|
||||
|
||||
snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "%s%s", where, driver.info_3->driverpath);
|
||||
init_unistr( &info->name, driver.info_3->name );
|
||||
init_unistr( &info->architecture, driver.info_3->environment );
|
||||
|
||||
snprintf(temp_driverpath, sizeof(temp_driverpath)-1, "\\\\%s%s", servername, driver.info_3->driverpath);
|
||||
init_unistr( &info->driverpath, temp_driverpath );
|
||||
|
||||
snprintf(temp_datafile, sizeof(temp_datafile)-1, "%s%s", where, driver.info_3->datafile);
|
||||
|
||||
snprintf(temp_datafile, sizeof(temp_datafile)-1, "\\\\%s%s", servername, driver.info_3->datafile);
|
||||
init_unistr( &info->datafile, temp_datafile );
|
||||
|
||||
snprintf(temp_configfile, sizeof(temp_configfile)-1, "%s%s", where, driver.info_3->configfile);
|
||||
|
||||
snprintf(temp_configfile, sizeof(temp_configfile)-1, "\\\\%s%s", servername, driver.info_3->configfile);
|
||||
init_unistr( &info->configfile, temp_configfile );
|
||||
|
||||
snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "%s%s", where, driver.info_3->helpfile);
|
||||
|
||||
snprintf(temp_helpfile, sizeof(temp_helpfile)-1, "\\\\%s%s", servername, driver.info_3->helpfile);
|
||||
init_unistr( &info->helpfile, temp_helpfile );
|
||||
|
||||
init_unistr( &info->monitorname, driver.info_3->monitorname );
|
||||
init_unistr( &info->defaultdatatype, driver.info_3->defaultdatatype );
|
||||
|
||||
info->dependentfiles=NULL;
|
||||
init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, where);
|
||||
init_unistr_array(&info->dependentfiles, driver.info_3->dependentfiles, servername);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
* construct_printer_info_3
|
||||
* fill a printer_info_3 struct
|
||||
********************************************************************/
|
||||
static void construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum,
|
||||
fstring servername, fstring architecture)
|
||||
static uint32 construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, fstring servername, fstring architecture, uint32 version)
|
||||
{
|
||||
NT_PRINTER_INFO_LEVEL *printer = NULL;
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver;
|
||||
|
||||
uint32 status=0;
|
||||
ZERO_STRUCT(driver);
|
||||
|
||||
get_a_printer(&printer, 2, lp_servicename(snum) );
|
||||
get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture);
|
||||
status=get_a_printer(&printer, 2, lp_servicename(snum) );
|
||||
DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
|
||||
if (status != 0)
|
||||
return ERROR_INVALID_PRINTER_NAME;
|
||||
|
||||
fill_printer_driver_info_3(info, driver, servername, architecture);
|
||||
status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version);
|
||||
DEBUG(8,("construct_printer_driver_info_3: status: %d\n", status));
|
||||
if (status != 0)
|
||||
return ERROR_UNKNOWN_PRINTER_DRIVER;
|
||||
|
||||
fill_printer_driver_info_3(info, driver, servername);
|
||||
|
||||
free_a_printer(&printer,2);
|
||||
|
||||
return NT_STATUS_NO_PROBLEMO;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -2678,14 +2668,19 @@ static void free_printer_driver_info_3(DRIVER_INFO_3 *info)
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
|
||||
static uint32 getprinterdriver2_level1(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
|
||||
{
|
||||
DRIVER_INFO_1 *info=NULL;
|
||||
uint32 status;
|
||||
|
||||
if((info=(DRIVER_INFO_1 *)malloc(sizeof(DRIVER_INFO_1))) == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
construct_printer_driver_info_1(info, snum, servername, architecture);
|
||||
status=construct_printer_driver_info_1(info, snum, servername, architecture, version);
|
||||
if (status != NT_STATUS_NO_PROBLEMO) {
|
||||
safe_free(info);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* check the required size. */
|
||||
*needed += spoolss_size_printer_driver_info_1(info);
|
||||
@ -2709,14 +2704,19 @@ static uint32 getprinterdriver2_level1(fstring servername, fstring architecture,
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
|
||||
static uint32 getprinterdriver2_level2(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
|
||||
{
|
||||
DRIVER_INFO_2 *info=NULL;
|
||||
uint32 status;
|
||||
|
||||
if((info=(DRIVER_INFO_2 *)malloc(sizeof(DRIVER_INFO_2))) == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
construct_printer_driver_info_2(info, snum, servername, architecture);
|
||||
status=construct_printer_driver_info_2(info, snum, servername, architecture, version);
|
||||
if (status != NT_STATUS_NO_PROBLEMO) {
|
||||
safe_free(info);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* check the required size. */
|
||||
*needed += spoolss_size_printer_driver_info_2(info);
|
||||
@ -2740,13 +2740,17 @@ static uint32 getprinterdriver2_level2(fstring servername, fstring architecture,
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
|
||||
static uint32 getprinterdriver2_level3(fstring servername, fstring architecture, uint32 version, int snum, NEW_BUFFER *buffer, uint32 offered, uint32 *needed)
|
||||
{
|
||||
DRIVER_INFO_3 info;
|
||||
uint32 status;
|
||||
|
||||
ZERO_STRUCT(info);
|
||||
|
||||
construct_printer_driver_info_3(&info, snum, servername, architecture);
|
||||
status=construct_printer_driver_info_3(&info, snum, servername, architecture, version);
|
||||
if (status != NT_STATUS_NO_PROBLEMO) {
|
||||
return status;
|
||||
}
|
||||
|
||||
/* check the required size. */
|
||||
*needed += spoolss_size_printer_driver_info_3(&info);
|
||||
@ -2792,13 +2796,13 @@ uint32 _spoolss_getprinterdriver2(POLICY_HND *handle, const UNISTR2 *uni_arch, u
|
||||
|
||||
switch (level) {
|
||||
case 1:
|
||||
return getprinterdriver2_level1(servername, architecture, snum, buffer, offered, needed);
|
||||
return getprinterdriver2_level1(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
|
||||
break;
|
||||
case 2:
|
||||
return getprinterdriver2_level2(servername, architecture, snum, buffer, offered, needed);
|
||||
return getprinterdriver2_level2(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
|
||||
break;
|
||||
case 3:
|
||||
return getprinterdriver2_level3(servername, architecture, snum, buffer, offered, needed);
|
||||
return getprinterdriver2_level3(servername, architecture, clientmajorversion, snum, buffer, offered, needed);
|
||||
break;
|
||||
default:
|
||||
return ERROR_INVALID_LEVEL;
|
||||
@ -3113,7 +3117,7 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
|
||||
|
||||
/* Check calling user has permission to update printer description */
|
||||
|
||||
#if 1 /* JFMTEST */
|
||||
#if 0 /* JFMTEST */
|
||||
if (!nt_printing_getsec(Printer->dev.handlename, &sd)) {
|
||||
DEBUG(3, ("Could not get security descriptor for printer %s",
|
||||
Printer->dev.handlename));
|
||||
@ -3543,24 +3547,46 @@ uint32 _spoolss_setjob( POLICY_HND *handle,
|
||||
/****************************************************************************
|
||||
Enumerates all printer drivers at level 1.
|
||||
****************************************************************************/
|
||||
static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
||||
static uint32 enumprinterdrivers_level1(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
||||
{
|
||||
int i;
|
||||
int ndrivers;
|
||||
uint32 version;
|
||||
fstring *list = NULL;
|
||||
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver;
|
||||
DRIVER_INFO_1 *driver_info_1=NULL;
|
||||
|
||||
ZERO_STRUCT(driver);
|
||||
*returned=0;
|
||||
|
||||
if((driver_info_1=(DRIVER_INFO_1 *)malloc(*returned * sizeof(DRIVER_INFO_1))) == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
#define MAX_VERSION 4
|
||||
|
||||
for (i=0; i<*returned; i++) {
|
||||
get_a_printer_driver(&driver, 3, list[i], architecture);
|
||||
fill_printer_driver_info_1(&(driver_info_1[i]), driver, servername, architecture );
|
||||
for (version=0; version<MAX_VERSION; version++) {
|
||||
list=NULL;
|
||||
ndrivers=get_ntdrivers(&list, architecture, version);
|
||||
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
|
||||
|
||||
if(ndrivers == -1)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
if(ndrivers != 0) {
|
||||
if((driver_info_1=(DRIVER_INFO_1 *)Realloc(driver_info_1, (*returned+ndrivers) * sizeof(DRIVER_INFO_1))) == NULL) {
|
||||
safe_free(list);
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<ndrivers; i++) {
|
||||
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
|
||||
ZERO_STRUCT(driver);
|
||||
get_a_printer_driver(&driver, 3, list[i], architecture, version);
|
||||
fill_printer_driver_info_1(&(driver_info_1[*returned+i]), driver, servername, architecture );
|
||||
}
|
||||
|
||||
*returned+=ndrivers;
|
||||
safe_free(list);
|
||||
}
|
||||
|
||||
safe_free(list);
|
||||
|
||||
/* check the required size. */
|
||||
for (i=0; i<*returned; i++) {
|
||||
DEBUGADD(6,("adding driver [%d]'s size\n",i));
|
||||
@ -3591,28 +3617,46 @@ static uint32 enumprinterdrivers_level1(fstring *list, fstring servername, fstri
|
||||
/****************************************************************************
|
||||
Enumerates all printer drivers at level 2.
|
||||
****************************************************************************/
|
||||
static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
||||
static uint32 enumprinterdrivers_level2(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
||||
{
|
||||
int i;
|
||||
int ndrivers;
|
||||
uint32 version;
|
||||
fstring *list = NULL;
|
||||
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver;
|
||||
DRIVER_INFO_2 *driver_info_2=NULL;
|
||||
|
||||
if (*returned > 0 &&
|
||||
!(driver_info_2=(DRIVER_INFO_2 *)malloc(*returned * sizeof(DRIVER_INFO_2))))
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
*returned=0;
|
||||
|
||||
for (i=0; i<*returned; i++) {
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver;
|
||||
ZERO_STRUCT(driver);
|
||||
if (get_a_printer_driver(&driver, 3, list[i], architecture)
|
||||
!= 0) {
|
||||
*returned = i;
|
||||
break;
|
||||
#define MAX_VERSION 4
|
||||
|
||||
for (version=0; version<MAX_VERSION; version++) {
|
||||
list=NULL;
|
||||
ndrivers=get_ntdrivers(&list, architecture, version);
|
||||
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
|
||||
|
||||
if(ndrivers == -1)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
if(ndrivers != 0) {
|
||||
if((driver_info_2=(DRIVER_INFO_2 *)Realloc(driver_info_2, (*returned+ndrivers) * sizeof(DRIVER_INFO_2))) == NULL) {
|
||||
safe_free(list);
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
}
|
||||
fill_printer_driver_info_2(&(driver_info_2[i]), driver, servername, architecture );
|
||||
|
||||
for (i=0; i<ndrivers; i++) {
|
||||
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
|
||||
ZERO_STRUCT(driver);
|
||||
get_a_printer_driver(&driver, 3, list[i], architecture, version);
|
||||
fill_printer_driver_info_2(&(driver_info_2[*returned+i]), driver, servername);
|
||||
}
|
||||
|
||||
*returned+=ndrivers;
|
||||
safe_free(list);
|
||||
}
|
||||
|
||||
safe_free(list);
|
||||
|
||||
/* check the required size. */
|
||||
for (i=0; i<*returned; i++) {
|
||||
DEBUGADD(6,("adding driver [%d]'s size\n",i));
|
||||
@ -3643,24 +3687,46 @@ static uint32 enumprinterdrivers_level2(fstring *list, fstring servername, fstri
|
||||
/****************************************************************************
|
||||
Enumerates all printer drivers at level 3.
|
||||
****************************************************************************/
|
||||
static uint32 enumprinterdrivers_level3(fstring *list, fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
||||
static uint32 enumprinterdrivers_level3(fstring servername, fstring architecture, NEW_BUFFER *buffer, uint32 offered, uint32 *needed, uint32 *returned)
|
||||
{
|
||||
int i;
|
||||
int ndrivers;
|
||||
uint32 version;
|
||||
fstring *list = NULL;
|
||||
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver;
|
||||
DRIVER_INFO_3 *driver_info_3=NULL;
|
||||
|
||||
ZERO_STRUCT(driver);
|
||||
*returned=0;
|
||||
|
||||
if((driver_info_3=(DRIVER_INFO_3 *)malloc((*returned)*sizeof(DRIVER_INFO_3))) == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
#define MAX_VERSION 4
|
||||
|
||||
for (i=0; i<*returned; i++) {
|
||||
get_a_printer_driver(&driver, 3, list[i], architecture);
|
||||
fill_printer_driver_info_3(&(driver_info_3[i]), driver, servername, architecture );
|
||||
for (version=0; version<MAX_VERSION; version++) {
|
||||
list=NULL;
|
||||
ndrivers=get_ntdrivers(&list, architecture, version);
|
||||
DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", ndrivers, architecture, version));
|
||||
|
||||
if(ndrivers == -1)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
if(ndrivers != 0) {
|
||||
if((driver_info_3=(DRIVER_INFO_3 *)Realloc(driver_info_3, (*returned+ndrivers) * sizeof(DRIVER_INFO_3))) == NULL) {
|
||||
safe_free(list);
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
for (i=0; i<ndrivers; i++) {
|
||||
DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
|
||||
ZERO_STRUCT(driver);
|
||||
get_a_printer_driver(&driver, 3, list[i], architecture, version);
|
||||
fill_printer_driver_info_3(&(driver_info_3[*returned+i]), driver, servername);
|
||||
}
|
||||
|
||||
*returned+=ndrivers;
|
||||
safe_free(list);
|
||||
}
|
||||
|
||||
safe_free(list);
|
||||
|
||||
|
||||
/* check the required size. */
|
||||
for (i=0; i<*returned; i++) {
|
||||
DEBUGADD(6,("adding driver [%d]'s size\n",i));
|
||||
@ -3709,27 +3775,20 @@ uint32 _spoolss_enumprinterdrivers( UNISTR2 *name, UNISTR2 *environment, uint32
|
||||
*returned=0;
|
||||
|
||||
unistr2_to_ascii(architecture, environment, sizeof(architecture)-1);
|
||||
*returned=get_ntdrivers(&list, architecture);
|
||||
|
||||
DEBUGADD(4,("we have: [%d] drivers in environment [%s]\n", *returned, architecture));
|
||||
if(*returned == -1)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
for (i=0; i<*returned; i++)
|
||||
DEBUGADD(5,("driver: [%s]\n", list[i]));
|
||||
|
||||
switch (level) {
|
||||
case 1:
|
||||
return enumprinterdrivers_level1(list, servername, architecture, buffer, offered, needed, returned);
|
||||
return enumprinterdrivers_level1(servername, architecture, buffer, offered, needed, returned);
|
||||
break;
|
||||
case 2:
|
||||
return enumprinterdrivers_level2(list, servername, architecture, buffer, offered, needed, returned);
|
||||
return enumprinterdrivers_level2(servername, architecture, buffer, offered, needed, returned);
|
||||
break;
|
||||
case 3:
|
||||
return enumprinterdrivers_level3(list, servername, architecture, buffer, offered, needed, returned);
|
||||
return enumprinterdrivers_level3(servername, architecture, buffer, offered, needed, returned);
|
||||
break;
|
||||
default:
|
||||
*returned=0;
|
||||
safe_free(list);
|
||||
return ERROR_INVALID_LEVEL;
|
||||
break;
|
||||
}
|
||||
@ -4094,77 +4153,34 @@ uint32 _spoolss_addprinterex( const UNISTR2 *uni_srv_name, uint32 level,
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Modify internal driver heirarchy.
|
||||
****************************************************************************/
|
||||
|
||||
#if MANGLE_DRIVER_PATH
|
||||
static uint32 modify_driver_heirarchy(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level)
|
||||
{
|
||||
pstring path_old;
|
||||
pstring path_new;
|
||||
pstring short_archi;
|
||||
pstring model_name;
|
||||
|
||||
/* find_service is an smbd-specific function call */
|
||||
int snum = find_service("print$");
|
||||
char *model = NULL;
|
||||
|
||||
*short_archi = '\0';
|
||||
switch (level) {
|
||||
case 3:
|
||||
get_short_archi(short_archi, driver->info_3->environment);
|
||||
model = driver->info_3->name;
|
||||
break;
|
||||
case 6:
|
||||
get_short_archi(short_archi, driver->info_6->environment);
|
||||
model = driver->info_6->name;
|
||||
break;
|
||||
default:
|
||||
DEBUG(0,("modify_driver_heirarchy: unknown info level (%d)\n", level));
|
||||
return ERROR_INVALID_LEVEL;
|
||||
break;
|
||||
}
|
||||
|
||||
slprintf(path_old, sizeof(path_old)-1, "%s/%s/TMP_%s", lp_pathname(snum), short_archi,
|
||||
client_addr());
|
||||
|
||||
/* Clean up any '/' and other characters in the model name. */
|
||||
alpha_strcpy(model_name, model, sizeof(pstring));
|
||||
|
||||
slprintf(path_new, sizeof(path_new)-1, "%s/%s/%s", lp_pathname(snum), short_archi, model_name);
|
||||
|
||||
DEBUG(10,("modify_driver_heirarchy: old_path=%s, new_path=%s\n",
|
||||
path_old, path_new ));
|
||||
if (dos_rename(path_old, path_new) == -1) {
|
||||
DEBUG(0,("modify_driver_heirarchy: rename from %s to %s failed (%s)\n",
|
||||
path_old, path_new, strerror(errno) ));
|
||||
/* We need to clean up here.... - how ? */
|
||||
return ERROR_ACCESS_DENIED; /* We need a generic mapping from NT errors here... */
|
||||
}
|
||||
|
||||
return NT_STATUS_NO_PROBLEMO;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
****************************************************************************/
|
||||
uint32 _spoolss_addprinterdriver( const UNISTR2 *server_name,
|
||||
uint32 level,
|
||||
const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
|
||||
uint32 _spoolss_addprinterdriver(pipes_struct *p, const UNISTR2 *server_name,
|
||||
uint32 level, const SPOOL_PRINTER_DRIVER_INFO_LEVEL *info)
|
||||
{
|
||||
uint32 err = NT_STATUS_NO_PROBLEMO;
|
||||
NT_PRINTER_DRIVER_INFO_LEVEL driver;
|
||||
struct current_user user;
|
||||
|
||||
ZERO_STRUCT(driver);
|
||||
|
||||
if (p->ntlmssp_auth_validated) {
|
||||
memcpy(&user, &p->pipe_user, sizeof(user));
|
||||
} else {
|
||||
extern struct current_user current_user;
|
||||
memcpy(&user, ¤t_user, sizeof(user));
|
||||
}
|
||||
|
||||
convert_printer_driver_info(info, &driver, level);
|
||||
|
||||
DEBUG(5,("Cleaning driver's information\n"));
|
||||
clean_up_driver_struct(driver, level);
|
||||
|
||||
DEBUG(5,("Moving driver to final destination\n"));
|
||||
move_driver_to_download_area(driver, level, &user);
|
||||
|
||||
if (add_a_printer_driver(driver, level)!=0)
|
||||
return ERROR_ACCESS_DENIED;
|
||||
|
||||
#if MANGLE_DRIVER_PATH
|
||||
err = modify_driver_heirarchy(&driver, level);
|
||||
#endif
|
||||
|
||||
free_a_printer_driver(driver, level);
|
||||
|
||||
return err;
|
||||
@ -4185,20 +4201,17 @@ static uint32 getprinterdriverdir_level_1(UNISTR2 *name, UNISTR2 *uni_environmen
|
||||
pstring long_archi;
|
||||
pstring short_archi;
|
||||
DRIVER_DIRECTORY_1 *info=NULL;
|
||||
|
||||
|
||||
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
|
||||
|
||||
if (get_short_archi(short_archi, long_archi)==FALSE)
|
||||
return ERROR_INVALID_ENVIRONMENT;
|
||||
|
||||
if((info=(DRIVER_DIRECTORY_1 *)malloc(sizeof(DRIVER_DIRECTORY_1))) == NULL)
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
|
||||
unistr2_to_ascii(long_archi, uni_environment, sizeof(long_archi)-1);
|
||||
get_short_archi(short_archi, long_archi);
|
||||
|
||||
#if MANGLE_DRIVER_PATH
|
||||
slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s\\TMP_%s", global_myname, short_archi,
|
||||
client_addr());
|
||||
#else
|
||||
slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s",
|
||||
global_myname, short_archi);
|
||||
#endif
|
||||
|
||||
slprintf(path, sizeof(path)-1, "\\\\%s\\print$\\%s", global_myname, short_archi);
|
||||
|
||||
DEBUG(4,("printer driver directory: [%s]\n", path));
|
||||
|
||||
fill_driverdir_1(info, path);
|
||||
|
@ -470,7 +470,7 @@ uint32 cmd_spoolss_getprinterdriverdir(struct client_info *info, int argc, char
|
||||
|
||||
fstrcpy(env, argv[1]);
|
||||
|
||||
for (i=2; i<argc; i++) {
|
||||
for (i=2; i<=argc; i++) {
|
||||
fstrcat(env, " ");
|
||||
fstrcat(env, argv[i]);
|
||||
}
|
||||
|
@ -3101,15 +3101,14 @@ int reply_printwrite(connection_struct *conn, char *inbuf,char *outbuf, int dum_
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
reply to a mkdir
|
||||
The guts of the mkdir command, split out so it may be called by the NT SMB
|
||||
code.
|
||||
****************************************************************************/
|
||||
int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
|
||||
int mkdir_internal(connection_struct *conn, char *inbuf, char *outbuf, pstring directory)
|
||||
{
|
||||
pstring directory;
|
||||
int outsize,ret= -1;
|
||||
BOOL bad_path = False;
|
||||
|
||||
pstrcpy(directory,smb_buf(inbuf) + 1);
|
||||
int ret= -1;
|
||||
|
||||
unix_convert(directory,conn,0,&bad_path,NULL);
|
||||
|
||||
if (check_name(directory, conn))
|
||||
@ -3125,10 +3124,23 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
|
||||
}
|
||||
return(UNIXERROR(ERRDOS,ERRnoaccess));
|
||||
}
|
||||
}
|
||||
|
||||
outsize = set_message(outbuf,0,0,True);
|
||||
/****************************************************************************
|
||||
reply to a mkdir
|
||||
****************************************************************************/
|
||||
int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
|
||||
{
|
||||
pstring directory;
|
||||
int outsize;
|
||||
|
||||
pstrcpy(directory,smb_buf(inbuf) + 1);
|
||||
|
||||
DEBUG( 3, ( "mkdir %s ret=%d\n", directory, ret ) );
|
||||
outsize=mkdir_internal(conn, inbuf, outbuf, directory);
|
||||
if(outsize == 0)
|
||||
outsize = set_message(outbuf,0,0,True);
|
||||
|
||||
DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
|
||||
|
||||
return(outsize);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user