A rather big change set ! (listed in no particular order)
authorJean-François Micouleau <jfm@samba.org>
Tue, 25 Jul 2000 13:15:16 +0000 (13:15 +0000)
committerJean-François Micouleau <jfm@samba.org>
Tue, 25 Jul 2000 13:15:16 +0000 (13:15 +0000)
- 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.

source/include/proto.h
source/include/smb.h
source/printing/nt_printing.c
source/rpc_parse/parse_prs.c
source/rpc_parse/parse_spoolss.c
source/rpc_server/srv_spoolss.c
source/rpc_server/srv_spoolss_nt.c
source/rpcclient/cmd_spoolss.c
source/smbd/reply.c

index 696ccf07c6ae0737d1c7151c1728971819b772d7..7a5250645164f854f63ff024bd18c34fe3a7fdae 100644 (file)
@@ -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);
index a49bbb9636efd2c51e04bf0582132e918deb7f67..bc9f17544c67b43e041a00139319e0b4b629ab8c 100644 (file)
@@ -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 */
index 9e7862eda04fba798a7b44532263ab572a4f46fa..76ec4d4ace7d7fd703e8b5709840750c904de5ba 100644 (file)
@@ -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)
                                  &param.data);
                param.next = *list;
                *list = memdup(&param, 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. */
 
index 5f43e5297507e9c9fea64c8643b16d092a65f56f..42a3410752ed358c02dc0edc68d7c765faec390e 100644 (file)
@@ -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
index fd120a57ec1d051a1f0284e32a53fb1d0ac53723..b0223d2803df88549149fb746483b6849b3d7496 100644 (file)
@@ -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;
index 3f72305465e7c98f50d6bf771af617628fef2414..8b431551b573144a1ea86eb16e1f49af985a31e4 100755 (executable)
@@ -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"));
index 7d5036c6d40a371d61918466d91df6ec17da681a..99ed18677ad1260262ba6ff6428609f2f4da21d9 100644 (file)
 
 #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;
+
+       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;
 }
 
 /********************************************************************
@@ -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;
+
+       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;
 }
 
 /****************************************************************************
@@ -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;
        }
@@ -4093,78 +4152,35 @@ 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, &current_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);
index 2f338cdb22dd0303f85bbf81a6458cf3e86aa074..3a80e5d0e7917eca00a92c190f3600a4f800f47e 100644 (file)
@@ -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]);
         }
index 00a0ce3c4a0fa0212416263184e3f5b96064379b..19af1fdc3d3bba500c59f5f8bfefa271803bfc0e 100644 (file)
@@ -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);
+
+  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, ret ) );
+  DEBUG( 3, ( "mkdir %s ret=%d\n", directory, outsize ) );
 
   return(outsize);
 }