last check in for tonight.
authorGerald Carter <jerry@samba.org>
Thu, 11 Jul 2002 04:53:39 +0000 (04:53 +0000)
committerGerald Carter <jerry@samba.org>
Thu, 11 Jul 2002 04:53:39 +0000 (04:53 +0000)
  * DeletePrinterDriverEx() now has the ability to delete
    driver files.  I need to do some more testing
    tro veriofy that we are in fact not deleting a file out from
    under another driver, but it looks ok so far.

  * DeletePrinterDriver() noiw deletes all versions of the
    specified driver (cversion == 0, 1, 2, 3)
(This used to be commit 17bb780e1327663fa2fcd6a3cb25dd461a29c537)

source3/printing/nt_printing.c
source3/rpc_server/srv_spoolss_nt.c
source3/smbd/service.c

index 17a16b84bcef6277427d8233d59f1a91b4d42baa..8e65f1d76a3175943c6dc863114d17988bbbf3df 100644 (file)
@@ -1859,19 +1859,19 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
                        else {
                                info3=driver.info_3;
                        
-                               DEBUGADD(106,("version:[%d]\n",         info3->cversion));
-                               DEBUGADD(106,("name:[%s]\n",            info3->name));
-                               DEBUGADD(106,("environment:[%s]\n",     info3->environment));
-                               DEBUGADD(106,("driverpath:[%s]\n",      info3->driverpath));
-                               DEBUGADD(106,("datafile:[%s]\n",        info3->datafile));
-                               DEBUGADD(106,("configfile:[%s]\n",      info3->configfile));
-                               DEBUGADD(106,("helpfile:[%s]\n",        info3->helpfile));
-                               DEBUGADD(106,("monitorname:[%s]\n",     info3->monitorname));
-                               DEBUGADD(106,("defaultdatatype:[%s]\n", info3->defaultdatatype));
+                               DEBUGADD(20,("version:[%d]\n",         info3->cversion));
+                               DEBUGADD(20,("name:[%s]\n",            info3->name));
+                               DEBUGADD(20,("environment:[%s]\n",     info3->environment));
+                               DEBUGADD(20,("driverpath:[%s]\n",      info3->driverpath));
+                               DEBUGADD(20,("datafile:[%s]\n",        info3->datafile));
+                               DEBUGADD(20,("configfile:[%s]\n",      info3->configfile));
+                               DEBUGADD(20,("helpfile:[%s]\n",        info3->helpfile));
+                               DEBUGADD(20,("monitorname:[%s]\n",     info3->monitorname));
+                               DEBUGADD(20,("defaultdatatype:[%s]\n", info3->defaultdatatype));
                                
                                for (i=0; info3->dependentfiles &&
                                          *info3->dependentfiles[i]; i++) {
-                                       DEBUGADD(106,("dependentfile:[%s]\n",
+                                       DEBUGADD(20,("dependentfile:[%s]\n",
                                                      info3->dependentfiles[i]));
                                }
                                result=0;
@@ -1879,7 +1879,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
                        break;
                }
                default:
-                       DEBUGADD(106,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
+                       DEBUGADD(20,("dump_a_printer_driver: Level %u not implemented\n", (unsigned int)level));
                        result=1;
                        break;
        }
@@ -3657,56 +3657,115 @@ BOOL printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
   this.
 ****************************************************************************/
 
-static NTSTATUS delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i )
+static BOOL delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user )
 {
        char *s;
+       connection_struct *conn;
+       DATA_BLOB null_pw;
+       NTSTATUS nt_status;
        
        if ( !i )
-               return NT_STATUS_ACCESS_DENIED;
+               return False;
                
        DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", i->name, i->cversion));
        
+       /*
+        * Connect to the print$ share under the same account as the 
+        * user connected to the rpc pipe. Note we must be root to 
+        * do this.
+        */
+        
+       become_root();
+       null_pw = data_blob( NULL, 0 );
+        conn = make_connection_with_chdir( "print$", null_pw, "A:", user->vuid, &nt_status );
+       unbecome_root();
        
-       if ( *i->driverpath )
-               DEBUG(10,("deleting [%s]\n", i->driverpath));
-       if ( *i->configfile )
-               DEBUG(10,("deleting [%s]\n", i->configfile));
-       if ( *i->datafile )
-               DEBUG(10,("deleting [%s]\n", i->datafile));
-       if ( *i->helpfile )
-               DEBUG(10,("deleting [%s]\n", i->helpfile));
+       if ( !conn ) {
+               DEBUG(0,("delete_driver_files: Unable to connect\n"));
+               return False;
+       }
+
+        /* Save who we are - we are temporarily becoming the connection user. */
+
+       if ( !become_user(conn, conn->vuid) ) {
+               DEBUG(0,("delete_driver_files: Can't become user!\n"));
+               return False;
+       }
+
+       /* now delete the files; must strip the '\print$' string from 
+          fron of path                                                */
+       
+       if ( *i->driverpath ) {
+               if ( (s = strchr( &i->driverpath[1], '\\' )) != NULL ) {
+                       DEBUG(10,("deleting driverfile [%s]\n", s));
+                       unlink_internals(conn, 0, s);
+               }
+       }
+               
+       if ( *i->configfile ) {
+               if ( (s = strchr( &i->configfile[1], '\\' )) != NULL ) {
+                       DEBUG(10,("deleting configfile [%s]\n", s));
+                       unlink_internals(conn, 0, s);
+               }
+       }
+       
+       if ( *i->datafile ) {
+               if ( (s = strchr( &i->datafile[1], '\\' )) != NULL ) {
+                       DEBUG(10,("deleting datafile [%s]\n", s));
+                       unlink_internals(conn, 0, s);
+               }
+       }
+       
+       if ( *i->helpfile ) {
+               if ( (s = strchr( &i->helpfile[1], '\\' )) != NULL ) {
+                       DEBUG(10,("deleting helpfile [%s]\n", s));
+                       unlink_internals(conn, 0, s);
+               }
+       }
        
        s = (char*)i->dependentfiles;
        
-       if ( s ) {
-               while ( *s ) {
-                       DEBUG(10,("deleting dependent file [%s]\n", s));
-                       s += strlen( s ) + 1;
+       while ( s && *s ) {
+               char *file;
+
+               if ( (file = strchr( s+1, '\\' )) != NULL )
+               {
+                       DEBUG(10,("deleting dependent file [%s]\n", file));
+                       unlink_internals(conn, 0, file );
+                       file += strlen( file ) + 1;
                }
+
+               s = file;
        }
 
-       return NT_STATUS_OK;
+       return True;
 }
 
 /****************************************************************************
  Remove a printer driver from the TDB.  This assumes that the the driver was
  previously looked up.
  ***************************************************************************/
-WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_files)
+
+static WERROR delete_printer_driver_internal( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user,
+                              uint32 version, BOOL delete_files )
 {
        pstring         key;
        fstring         arch;
        TDB_DATA        kbuf;
+       NT_PRINTER_DRIVER_INFO_LEVEL    ctr;
 
        /* delete the tdb data first */
-       
+
        get_short_archi(arch, i->environment);
        slprintf(key, sizeof(key)-1, "%s%s/%d/%s", DRIVERS_PREFIX,
-               arch, i->cversion, i->name); 
-               
-       DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n", 
+               arch, version, i->name);
+
+       DEBUG(5,("delete_printer_driver: key = [%s] delete_files = %s\n",
                key, delete_files ? "TRUE" : "FALSE" ));
 
+       ctr.info_3 = i;
+       dump_a_printer_driver( ctr, 3 );
+
        kbuf.dptr=key;
        kbuf.dsize=strlen(key)+1;
 
@@ -3714,27 +3773,56 @@ WERROR delete_printer_driver (NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, BOOL delete_fil
                DEBUG (0,("delete_printer_driver: fail to delete %s!\n", key));
                return WERR_ACCESS_DENIED;
        }
-       
-       /* 
+
+       /*
         * now delete any associated files if delete_files == True
-        * even if this part failes, we return succes because the 
-        * driver doesn not exist any more  
+        * even if this part failes, we return succes because the
+        * driver doesn not exist any more
         */
-        
+
        if ( delete_files )
-               delete_driver_files( i );
-               
+               delete_driver_files( i, user );
+
        DEBUG(5,("delete_printer_driver: [%s] driver delete successful.\n",
                i->name));
-               
+
+       return WERR_OK;
+}
+
+/****************************************************************************
+ Remove a printer driver from the TDB.  This assumes that the the driver was
+ previously looked up.
+ ***************************************************************************/
+
+WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *i, struct current_user *user,
+                              uint32 version, BOOL delete_files )
+{
+       int ver;
+       WERROR err;
+
+       /* see if we should delete all versions of this driver */
+
+       if ( version == DRIVER_ANY_VERSION ) {
+               for ( ver=0; ver<DRIVER_MAX_VERSION; ver++ ) {
+                       err = delete_printer_driver_internal(i, user, ver, delete_files );
+                       if ( !W_ERROR_IS_OK(err) )
+                               return err;
+               }
+       }
+       else
+               delete_printer_driver_internal(i, user, version, delete_files );
+
        return WERR_OK;
 }
+
+
 /****************************************************************************
 ****************************************************************************/
+
 BOOL get_specific_param_by_index(NT_PRINTER_INFO_LEVEL printer, uint32 level, uint32 param_index,
                                  fstring value, uint8 **data, uint32 *type, uint32 *len)
 {
-       /* right now that's enough ! */ 
+       /* right now that's enough ! */
        NT_PRINTER_PARAM *param;
        int i=0;
        
index a37d8e9c19b1e26dac68d713590d8b3c9aed2a53..f7f191522f9d8acd63194c5040db4ad20f24564d 100644 (file)
@@ -1534,17 +1534,6 @@ static int get_version_id (char * arch)
 
 /********************************************************************
  * _spoolss_deleteprinterdriver
- *
- * We currently delete the driver for the architecture only.
- * This can leave the driver for other archtectures.  However,
- * since every printer associates a "Windows NT x86" driver name
- * and we cannot delete that one while it is in use, **and** since
- * it is impossible to assign a driver to a Samba printer without
- * having the "Windows NT x86" driver installed,...
- * 
- * ....we should not get into trouble here.  
- *
- *                                                      --jerry
  ********************************************************************/
 
 WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER *q_u, SPOOL_R_DELETEPRINTERDRIVER *r_u)
@@ -1553,6 +1542,9 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
        fstring                         arch;
        NT_PRINTER_DRIVER_INFO_LEVEL    info;
        int                             version;
+       struct current_user             user;
+       
+       get_current_user(&user, p);
         
        unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
        unistr2_to_ascii(arch,   &q_u->arch,   sizeof(arch)-1   );
@@ -1576,7 +1568,7 @@ WERROR _spoolss_deleteprinterdriver(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIVER
        if (printer_driver_in_use(info.info_3))
                return WERR_PRINTER_DRIVER_IN_USE;
 
-       return delete_printer_driver(info.info_3, False);
+       return delete_printer_driver(info.info_3, &user, DRIVER_ANY_VERSION, False);
 }
 
 /********************************************************************
@@ -1591,6 +1583,9 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
        int                             version;
        uint32                          flags = q_u->delete_flags;
        BOOL                            delete_files;
+       struct current_user             user;
+       
+       get_current_user(&user, p);
        
        unistr2_to_ascii(driver, &q_u->driver, sizeof(driver)-1 );
        unistr2_to_ascii(arch,   &q_u->arch,   sizeof(arch)-1   );
@@ -1611,7 +1606,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
        
        if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) 
                return WERR_UNKNOWN_PRINTER_DRIVER;
-
+               
        if ( printer_driver_in_use(info.info_3) )
                return WERR_PRINTER_DRIVER_IN_USE;
        
@@ -1638,7 +1633,7 @@ WERROR _spoolss_deleteprinterdriverex(pipes_struct *p, SPOOL_Q_DELETEPRINTERDRIV
                        return WERR_ACCESS_DENIED;      
        }
 
-       return delete_printer_driver(info.info_3, delete_files);
+       return delete_printer_driver(info.info_3, &user, version, delete_files);
 }
 
 
@@ -6820,7 +6815,7 @@ WERROR _spoolss_addprinterdriver(pipes_struct *p, SPOOL_Q_ADDPRINTERDRIVER *q_u,
 
        ZERO_STRUCT(driver);
 
-       get_current_user(&user, p);     
+       get_current_user(&user, p);
        
        if (!convert_printer_driver_info(info, &driver, level)) {
                err = WERR_NOMEM;
index 19bdc0e4b0268d248ab24267e72ee1e4736197ea..df930575d300b8f3a57880ab45987dc6cd6ea3c6 100644 (file)
@@ -723,7 +723,7 @@ connection_struct *make_connection_with_chdir(const char *service_in, DATA_BLOB
         * so we have to do it as a separate step  --jerry
         */
         
-       if (vfs_ChDir(conn,conn->connectpath) != 0) {
+       if ( conn && vfs_ChDir(conn,conn->connectpath) != 0 ) {
                DEBUG(0,("move_driver_to_download_area: Can't change directory to %s for [print$] (%s)\n",
                         conn->connectpath,strerror(errno)));
                yield_connection(conn, lp_servicename(SNUM(conn)));