/* 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}
};
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;
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;
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;
{
{"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, "" }
};
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);
}
/****************************************************************************
{
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;
driver->helpfile,
driver->monitorname,
driver->defaultdatatype);
-
+
if (driver->dependentfiles) {
for (i=0; *driver->dependentfiles[i]; i++) {
len += tdb_pack(buf+len, buflen-len, "f",
/****************************************************************************
****************************************************************************/
-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;
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,
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;
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));
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;
}
¶m.data);
param.next = *list;
*list = memdup(¶m, sizeof(param));
+
+ DEBUG(8,("specific: [%s], len: %d\n", param.value, param.data_len));
}
return len;
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) {
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;
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));
/****************************************************************************
****************************************************************************/
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;
{
success=get_a_printer_driver_3(&(driver->info_3),
printername,
- architecture);
+ architecture, version);
break;
}
default:
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. */
#include "includes.h"
-#ifndef MANGLE_DRIVER_PATH
-#define MANGLE_DRIVER_PATH 0
-#endif
-
extern int DEBUGLEVEL;
extern pstring global_myname;
}
/********************************************************************
- * 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;
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;
+
+ 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, architecture);
+ fill_printer_driver_info_2(info, driver, servername);
free_a_printer(&printer,2);
+
+ return NT_STATUS_NO_PROBLEMO;
}
/********************************************************************
*
* 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;
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" ));
* 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;
+
+ 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, architecture);
+ fill_printer_driver_info_3(info, driver, servername);
free_a_printer(&printer,2);
+
+ return NT_STATUS_NO_PROBLEMO;
}
/****************************************************************************
/****************************************************************************
****************************************************************************/
-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);
/****************************************************************************
****************************************************************************/
-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);
/****************************************************************************
****************************************************************************/
-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);
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;
/* 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));
/****************************************************************************
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));
/****************************************************************************
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));
/****************************************************************************
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));
*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;
}
}
}
-/****************************************************************************
- 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;
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);