Merge branch 'master' of ssh://git.samba.org/data/git/abartlet/samba into extended...
[abartlet/samba.git/.git] / source3 / printing / nt_printing.c
index 11370272a24eb86014f7b8725b80a33215c71245..ba1fb4352c332455d07ce7f326b36b24252bd77d 100644 (file)
@@ -1344,14 +1344,24 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                goto error_exit;
        }
 
-       status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
-                               FILE_GENERIC_READ,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE,
-                               FILE_OPEN,
-                               0,
-                               FILE_ATTRIBUTE_NORMAL,
-                               INTERNAL_OPEN_ONLY,
-                               NULL, &fsp);
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               NULL,                                   /* req */
+               0,                                      /* root_dir_fid */
+               filepath,                               /* fname */
+               0,                                      /* create_file_flags */
+               FILE_GENERIC_READ,                      /* access_mask */
+               FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               NULL,                                   /* pinfo */
+               &stat_buf);                             /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                /* Old file not found, so by definition new file is in fact newer */
@@ -1385,14 +1395,24 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                goto error_exit;
        }
 
-       status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
-                               FILE_GENERIC_READ,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE,
-                               FILE_OPEN,
-                               0,
-                               FILE_ATTRIBUTE_NORMAL,
-                               INTERNAL_OPEN_ONLY,
-                               NULL, &fsp);
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               NULL,                                   /* req */
+               0,                                      /* root_dir_fid */
+               filepath,                               /* fname */
+               0,                                      /* create_file_flags */
+               FILE_GENERIC_READ,                      /* access_mask */
+               FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               NULL,                                   /* pinfo */
+               &stat_buf);                             /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                /* New file not found, this shouldn't occur if the caller did its job */
@@ -1454,18 +1474,21 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
 /****************************************************************************
 Determine the correct cVersion associated with an architecture and driver
 ****************************************************************************/
-static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in,
-                                  struct current_user *user, WERROR *perr)
+static uint32 get_correct_cversion(struct pipes_struct *p,
+                                  const char *architecture,
+                                  fstring driverpath_in,
+                                  WERROR *perr)
 {
        int               cversion;
        NTSTATUS          nt_status;
        char *driverpath = NULL;
-       DATA_BLOB         null_pw;
-       fstring           res_type;
        files_struct      *fsp = NULL;
        SMB_STRUCT_STAT   st;
-       connection_struct *conn;
+       connection_struct *conn = NULL;
        NTSTATUS status;
+       char *oldcwd;
+       fstring printdollar;
+       int printdollar_snum;
 
        SET_STAT_INVALID(st);
 
@@ -1485,28 +1508,21 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
                return 3;
        }
 
-       /*
-        * Connect to the print$ share under the same account as the user connected
-        * to the rpc pipe. Note we must still be root to do this.
-        */
-
-       /* Null password is ok - we are already an authenticated user... */
-       null_pw = data_blob_null;
-       fstrcpy(res_type, "A:");
-       become_root();
-       conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
-       unbecome_root();
+       fstrcpy(printdollar, "print$");
 
-       if (conn == NULL) {
-               DEBUG(0,("get_correct_cversion: Unable to connect\n"));
-               *perr = ntstatus_to_werror(nt_status);
+       printdollar_snum = find_service(printdollar);
+       if (printdollar_snum == -1) {
+               *perr = WERR_NO_SUCH_SHARE;
                return -1;
        }
 
-       /* We are temporarily becoming the connection user. */
-       if (!become_user(conn, user->vuid)) {
-               DEBUG(0,("get_correct_cversion: Can't become user!\n"));
-               *perr = WERR_ACCESS_DENIED;
+       nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+                                      lp_pathname(printdollar_snum),
+                                      p->server_info, &oldcwd);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(0,("get_correct_cversion: create_conn_struct "
+                        "returned %s\n", nt_errstr(nt_status)));
+               *perr = ntstatus_to_werror(nt_status);
                return -1;
        }
 
@@ -1532,14 +1548,24 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
                goto error_exit;
        }
 
-       status = open_file_ntcreate(conn, NULL, driverpath, &st,
-                               FILE_GENERIC_READ,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE,
-                               FILE_OPEN,
-                               0,
-                               FILE_ATTRIBUTE_NORMAL,
-                               INTERNAL_OPEN_ONLY,
-                               NULL, &fsp);
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               NULL,                                   /* req */
+               0,                                      /* root_dir_fid */
+               driverpath,                             /* fname */
+               0,                                      /* create_file_flags */
+               FILE_GENERIC_READ,                      /* access_mask */
+               FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               NULL,                                   /* pinfo */
+               &st);                                   /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
@@ -1583,27 +1609,28 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
        DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
                driverpath, cversion));
 
-       close_file(NULL, fsp, NORMAL_CLOSE);
-       close_cnum(conn, user->vuid);
-       unbecome_user();
-       *perr = WERR_OK;
-       return cversion;
-
-
-  error_exit:
+       goto done;
 
-       if(fsp)
+ error_exit:
+       cversion = -1;
+ done:
+       if (fsp != NULL) {
                close_file(NULL, fsp, NORMAL_CLOSE);
-
-       close_cnum(conn, user->vuid);
-       unbecome_user();
-       return -1;
+       }
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free_internal(conn);
+       }
+       if (cversion != -1) {
+               *perr = WERR_OK;
+       }
+       return cversion;
 }
 
 /****************************************************************************
 ****************************************************************************/
-static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
-                                                                                        struct current_user *user)
+static WERROR clean_up_driver_struct_level_3(struct pipes_struct *rpc_pipe,
+                                            NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
 {
        const char *architecture;
        fstring new_name;
@@ -1661,7 +1688,9 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
         *      NT 4: cversion=2
         *      NT2K: cversion=3
         */
-       if ((driver->cversion = get_correct_cversion( architecture, driver->driverpath, user, &err)) == -1)
+       if ((driver->cversion = get_correct_cversion(rpc_pipe, architecture,
+                                                    driver->driverpath,
+                                                    &err)) == -1)
                return err;
 
        return WERR_OK;
@@ -1669,7 +1698,8 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
        
 /****************************************************************************
 ****************************************************************************/
-static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
+static WERROR clean_up_driver_struct_level_6(struct pipes_struct *rpc_pipe,
+                                            NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
 {
        const char *architecture;
        fstring new_name;
@@ -1728,7 +1758,9 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
         *      NT2K: cversion=3
         */
 
-       if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
+       if ((driver->version = get_correct_cversion(rpc_pipe, architecture,
+                                                   driver->driverpath,
+                                                   &err)) == -1)
                        return err;
 
        return WERR_OK;
@@ -1736,21 +1768,24 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
 
 /****************************************************************************
 ****************************************************************************/
-WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
-                                                         uint32 level, struct current_user *user)
+WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
+                             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;
-                       return clean_up_driver_struct_level_3(driver, user);
+                       return clean_up_driver_struct_level_3(rpc_pipe,
+                                                             driver);
                }
                case 6:
                {
                        NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
                        driver=driver_abstract.info_6;
-                       return clean_up_driver_struct_level_6(driver, user);
+                       return clean_up_driver_struct_level_6(rpc_pipe,
+                                                             driver);
                }
                default:
                        return WERR_INVALID_PARAM;
@@ -1796,8 +1831,9 @@ static char* ffmt(unsigned char *c){
 
 /****************************************************************************
 ****************************************************************************/
-WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
-                                 struct current_user *user, WERROR *perr)
+WERROR move_driver_to_download_area(struct pipes_struct *p,
+                                   NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+                                   uint32 level, WERROR *perr)
 {
        NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
        NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
@@ -1805,14 +1841,15 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
        char *new_dir = NULL;
        char *old_name = NULL;
        char *new_name = NULL;
-       DATA_BLOB null_pw;
-       connection_struct *conn;
+       connection_struct *conn = NULL;
        NTSTATUS nt_status;
-       fstring res_type;
        SMB_STRUCT_STAT st;
        int i;
        TALLOC_CTX *ctx = talloc_tos();
        int ver = 0;
+       char *oldcwd;
+       fstring printdollar;
+       int printdollar_snum;
 
        *perr = WERR_OK;
 
@@ -1831,38 +1868,24 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
                return WERR_UNKNOWN_PRINTER_DRIVER;
        }
 
-       /*
-        * 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.
-        */
-
-       null_pw = data_blob_null;
-       fstrcpy(res_type, "A:");
-       become_root();
-       conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
-       unbecome_root();
+       fstrcpy(printdollar, "print$");
 
-       if (conn == NULL) {
-               DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
-               *perr = ntstatus_to_werror(nt_status);
+       printdollar_snum = find_service(printdollar);
+       if (printdollar_snum == -1) {
+               *perr = WERR_NO_SUCH_SHARE;
                return WERR_NO_SUCH_SHARE;
        }
 
-       /*
-        * Save who we are - we are temporarily becoming the connection user.
-        */
-
-       if (!become_user(conn, conn->vuid)) {
-               DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
-               return WERR_ACCESS_DENIED;
+       nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+                                      lp_pathname(printdollar_snum),
+                                      p->server_info, &oldcwd);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(0,("move_driver_to_download_area: create_conn_struct "
+                        "returned %s\n", nt_errstr(nt_status)));
+               *perr = ntstatus_to_werror(nt_status);
+               return *perr;
        }
 
-       /* WE ARE NOW RUNNING AS USER conn->vuid !!!!! */
-
-       /*
-        * make the directories version and version\driver_name
-        * under the architecture directory.
-        */
        DEBUG(5,("Creating first directory\n"));
        new_dir = talloc_asprintf(ctx,
                                "%s/%d",
@@ -2092,8 +2115,10 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
 
   err_exit:
 
-       close_cnum(conn, user->vuid);
-       unbecome_user();
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free_internal(conn);
+       }
 
        if (W_ERROR_EQUAL(*perr, WERR_OK)) {
                return WERR_OK;
@@ -5201,49 +5226,44 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
   this.
 ****************************************************************************/
 
-static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
+static bool delete_driver_files(struct pipes_struct *rpc_pipe,
+                               NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3)
 {
        int i = 0;
        char *s;
        const char *file;
        connection_struct *conn;
-       DATA_BLOB null_pw;
        NTSTATUS nt_status;
-       fstring res_type;
        SMB_STRUCT_STAT  st;
+       char *oldcwd;
+       fstring printdollar;
+       int printdollar_snum;
+       bool ret = false;
 
        if ( !info_3 )
                return False;
 
        DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->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.
-        */
+       fstrcpy(printdollar, "print$");
 
-       null_pw = data_blob_null;
-       fstrcpy(res_type, "A:");
-       become_root();
-        conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status );
-       unbecome_root();
+       printdollar_snum = find_service(printdollar);
+       if (printdollar_snum == -1) {
+               return false;
+       }
 
-       if ( !conn ) {
-               DEBUG(0,("delete_driver_files: Unable to connect\n"));
-               return False;
+       nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+                                      lp_pathname(printdollar_snum),
+                                      rpc_pipe->server_info, &oldcwd);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(0,("delete_driver_files: create_conn_struct "
+                        "returned %s\n", nt_errstr(nt_status)));
+               return false;
        }
 
        if ( !CAN_WRITE(conn) ) {
                DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\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;
+               goto fail;
        }
 
        /* now delete the files; must strip the '\print$' string from
@@ -5304,9 +5324,15 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
                }
        }
 
-       unbecome_user();
-
-       return true;
+       goto done;
+ fail:
+       ret = false;
+ done:
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free_internal(conn);
+       }
+       return ret;
 }
 
 /****************************************************************************
@@ -5314,8 +5340,9 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
  previously looked up.
  ***************************************************************************/
 
-WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
-                              uint32 version, bool delete_files )
+WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
+                            NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3,
+                            uint32 version, bool delete_files )
 {
        char *key = NULL;
        const char     *arch;
@@ -5365,7 +5392,7 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
         */
 
        if ( delete_files )
-               delete_driver_files( info_3, user );
+               delete_driver_files(rpc_pipe, info_3);
 
        DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
        SAFE_FREE(key);