HACK... https://bugzilla.samba.org/show_bug.cgi?id=12892
authorStefan Metzmacher <metze@samba.org>
Tue, 11 Jul 2017 16:05:14 +0000 (18:05 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 18 Feb 2019 11:47:21 +0000 (12:47 +0100)
selftest/target/Samba3.pm
source3/include/vfs.h
source3/libads/ads_proto.h
source3/printing/nt_printing_migrate.h
source3/printing/printspoolss.c
source3/printing/tests/vlp.c
source3/rpc_client/cli_lsarpc.h
source3/rpc_server/rpc_ncacn_np.h
source3/rpc_server/srv_pipe.c
source3/smbd/smb2_write.c
source3/utils/net.h

index f11bb9312df6cb05665ee2f34774e7c5dbf3496a..044e54a47384328d5370cc029e6a081b12651486 100755 (executable)
@@ -1694,7 +1694,7 @@ sub provision($$$$$$$$$)
                $max_uid = $unix_uid;
        }
 
-       $uid_root = $max_uid - 1;
+       $uid_root = 0; #$max_uid - 1;
        $uid_nobody = $max_uid - 2;
        $uid_pdbtest = $max_uid - 3;
        $uid_pdbtest2 = $max_uid - 4;
@@ -1716,7 +1716,7 @@ sub provision($$$$$$$$$)
 
        $gid_nobody = $max_gid - 1;
        $gid_nogroup = $max_gid - 2;
-       $gid_root = $max_gid - 3;
+       $gid_root = 0; #$max_gid - 3;
        $gid_domusers = $max_gid - 4;
        $gid_domadmins = $max_gid - 5;
        $gid_userdup = $max_gid - 6;
index 8c35fa5ecc7aa8cb0d3a22d54f5121208d0eddc1..1f5e1e547affd4f231ae5d9722560bf8a8a05c30 100644 (file)
@@ -481,9 +481,6 @@ typedef struct connection_struct {
        name_compare_entry *veto_oplock_list; /* Per-share list of files to refuse oplocks on. */       
        name_compare_entry *aio_write_behind_list; /* Per-share list of files to use aio write behind on. */       
        struct trans_state *pending_trans;
-
-       struct rpc_pipe_client *spoolss_pipe;
-
 } connection_struct;
 
 struct smbd_smb2_request;
index 154bf67f9641b5f05401e8f3622ce5c42de810f3..9c91d4e0f6011d9831c3c4f82139722e5e78949e 100644 (file)
@@ -32,6 +32,8 @@
 #ifndef _LIBADS_ADS_PROTO_H_
 #define _LIBADS_ADS_PROTO_H_
 
+struct rpc_pipe_client;
+
 /* The following definitions come from libads/ads_struct.c  */
 
 char *ads_build_path(const char *realm, const char *sep, const char *field, int reverse);
index 0c9800ddcd5ced3d3c1cff2a344fdb2ea31a58e8..72ad2805978ca0e14fac4ef170999ed7d124d16c 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef _NT_PRINTING_MIGRATE_H_
 #define _NT_PRINTING_MIGRATE_H_
 
+struct rpc_pipe_client;
+
 NTSTATUS printing_tdb_migrate_form(TALLOC_CTX *mem_ctx,
                                   struct rpc_pipe_client *winreg_pipe,
                                   const char *key_name,
index 9d565de120ad44ecdc37f0051017da6a1b928d07..c6815c2f89a2d313b0a6bcfc276b243f588ecf90 100644 (file)
@@ -30,6 +30,8 @@ struct print_file_data {
        char *svcname;
        char *docname;
        char *filename;
+       uint64_t offset;
+       struct rpc_pipe_client *spoolss_pipe;
        struct policy_handle handle;
        uint32_t jobid;
        uint16_t rap_jobid;
@@ -121,30 +123,31 @@ NTSTATUS print_spool_open(files_struct *fsp,
                                        lp_path(talloc_tos(),
                                                SNUM(fsp->conn)),
                                        PRINT_SPOOL_PREFIX);
+       pf->filename = talloc_asprintf(pf, "%s.raw", pf->docname);
        if (!pf->filename) {
                status = NT_STATUS_NO_MEMORY;
                goto done;
        }
        errno = 0;
        mask = umask(S_IRWXO | S_IRWXG);
-       fd = mkstemp(pf->filename);
+       fd = -1;// mkstemp(pf->filename);
        umask(mask);
-       if (fd == -1) {
-               if (errno == EACCES) {
-                       /* Common setup error, force a report. */
-                       DEBUG(0, ("Insufficient permissions "
-                                 "to open spool file %s.\n",
-                                 pf->filename));
-               } else {
-                       /* Normal case, report at level 3 and above. */
-                       DEBUG(3, ("can't open spool file %s,\n",
-                                 pf->filename));
-                       DEBUGADD(3, ("errno = %d (%s).\n",
-                                    errno, strerror(errno)));
-               }
-               status = map_nt_error_from_unix(errno);
-               goto done;
-       }
+       //if (fd == -1) {
+       //      if (errno == EACCES) {
+       //              /* Common setup error, force a report. */
+       //              DEBUG(0, ("Insufficient permissions "
+       //                        "to open spool file %s.\n",
+       //                        pf->filename));
+       //      } else {
+       //              /* Normal case, report at level 3 and above. */
+       //              DEBUG(3, ("can't open spool file %s,\n",
+       //                        pf->filename));
+       //              DEBUGADD(3, ("errno = %d (%s).\n",
+       //                           errno, strerror(errno)));
+       //      }
+       //      status = map_nt_error_from_unix(errno);
+       //      goto done;
+       //}
 
        /* now open a document over spoolss so that it does
         * all printer verification, and eventually assigns
@@ -156,11 +159,11 @@ NTSTATUS print_spool_open(files_struct *fsp,
                                         fsp->conn->sconn->remote_address,
                                         fsp->conn->sconn->local_address,
                                         fsp->conn->sconn->msg_ctx,
-                                        &fsp->conn->spoolss_pipe);
+                                        &pf->spoolss_pipe);
        if (!NT_STATUS_IS_OK(status)) {
                goto done;
        }
-       b = fsp->conn->spoolss_pipe->binding_handle;
+       b = pf->spoolss_pipe->binding_handle;
 
        ZERO_STRUCT(devmode_ctr);
 
@@ -216,13 +219,13 @@ NTSTATUS print_spool_open(files_struct *fsp,
                goto done;
        }
 
-       if (sys_fstat(fd, &fsp->fsp_name->st, false) != 0) {
-               status = map_nt_error_from_unix(errno);
-               goto done;
-       }
+       //if (sys_fstat(fd, &fsp->fsp_name->st, false) != 0) {
+       //      status = map_nt_error_from_unix(errno);
+       //      goto done;
+       //}
 
-       fsp->file_id = vfs_file_id_from_sbuf(fsp->conn, &fsp->fsp_name->st);
-       fsp->fh->fd = fd;
+       //fsp->file_id = vfs_file_id_from_sbuf(fsp->conn, &fsp->fsp_name->st);
+       //fsp->fh->fd = fd;
 
        fsp->vuid = current_vuid;
        fsp->can_lock = false;
@@ -249,6 +252,7 @@ done:
                if (pf && pf->jobid) {
                        print_spool_terminate(fsp->conn, pf);
                }
+               TALLOC_FREE(pf);
        }
        talloc_free(tmp_ctx);
        return status;
@@ -258,12 +262,79 @@ int print_spool_write(files_struct *fsp,
                      const char *data, uint32_t size,
                      off_t offset, uint32_t *written)
 {
+       struct print_file_data *pf = fsp->print_file;
+       NTSTATUS status;
+       TALLOC_CTX *tmp_ctx = talloc_tos();
+       struct dcerpc_binding_handle *b = NULL;
+       DATA_BLOB buffer;
+       //int fd = -1;
+       WERROR werr;
        SMB_STRUCT_STAT st;
        ssize_t n;
        int ret;
+       uint64_t remaining;
 
        *written = 0;
 
+       if (pf == NULL) {
+               return EBADF;
+       }
+       if (pf->spoolss_pipe == NULL) {
+               return EBADF;
+       }
+       b = pf->spoolss_pipe->binding_handle;
+
+       /* When print files go beyond 4GB, the 32-bit offset sent in
+        * old SMBwrite calls is relative to the current 4GB chunk
+        * we're writing to.
+        *    Discovered by Sebastian Kloska <oncaphillis@snafu.de>.
+        */
+       if (offset < 0xffffffff00000000LL) {
+               offset = (pf->offset & 0xffffffff00000000LL) + offset;
+       }
+
+       if ((uint64_t)offset != pf->offset) {
+               // TODO: check what windows does, with non sequential
+               // writes.
+               ret = EINVAL;
+               goto error;
+       }
+
+       remaining = UINT64_MAX - pf->offset;
+       if (size > remaining) {
+               ret = EINVAL;
+               goto error;
+       }
+
+       buffer = data_blob_const(data, size);
+
+       status = dcerpc_spoolss_WritePrinter(b, tmp_ctx,
+                                            &pf->handle,
+                                            buffer,
+                                            buffer.length,
+                                            written,
+                                            &werr);
+       if (!NT_STATUS_IS_OK(status)) {
+               ret = EINVAL;
+               goto error;
+       }
+       if (!W_ERROR_IS_OK(werr)) {
+               //status = werror_to_ntstatus(werr);
+               ret = EINVAL;
+               goto error;
+       }
+
+       if (*written > size) {
+               //status = NT_STATUS_INVALID_PARAMETER;
+               ret = EINVAL;
+               goto error;
+       }
+
+       pf->offset += *written;
+       return 0;
+error:
+       print_spool_terminate(fsp->conn, fsp->print_file);
+       return ret;
        /* first of all stat file to find out if it is still there.
         * spoolss may have deleted it to signal someone has killed
         * the job through it's interface */
@@ -305,6 +376,7 @@ int print_spool_write(files_struct *fsp,
 
 void print_spool_end(files_struct *fsp, enum file_close_type close_type)
 {
+       struct print_file_data *pf = fsp->print_file;
        NTSTATUS status;
        WERROR werr;
        struct dcerpc_binding_handle *b = NULL;
@@ -326,7 +398,10 @@ void print_spool_end(files_struct *fsp, enum file_close_type close_type)
                }
        }
 
-       b = fsp->conn->spoolss_pipe->binding_handle;
+       if (pf->spoolss_pipe == NULL) {
+               return;
+       }
+       b = pf->spoolss_pipe->binding_handle;
 
        switch (close_type) {
        case NORMAL_CLOSE:
@@ -345,6 +420,7 @@ void print_spool_end(files_struct *fsp, enum file_close_type close_type)
                print_spool_terminate(fsp->conn, fsp->print_file);
                break;
        }
+       TALLOC_FREE(fsp->print_file);
 }
 
 
@@ -357,29 +433,30 @@ void print_spool_terminate(struct connection_struct *conn,
 
        rap_jobid_delete(print_file->svcname, print_file->jobid);
 
-       status = rpc_pipe_open_interface(conn,
-                                        &ndr_table_spoolss,
-                                        conn->session_info,
-                                        conn->sconn->remote_address,
-                                        conn->sconn->local_address,
-                                        conn->sconn->msg_ctx,
-                                        &conn->spoolss_pipe);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, ("print_spool_terminate: "
-                         "Failed to get spoolss pipe [%s]\n",
-                         nt_errstr(status)));
+       //status = rpc_pipe_open_interface(conn,
+       //                               &ndr_table_spoolss,
+       //                               conn->session_info,
+       //                               conn->sconn->remote_address,
+       //                               conn->sconn->local_address,
+       //                               conn->sconn->msg_ctx,
+       //                               &conn->spoolss_pipe);
+       //if (!NT_STATUS_IS_OK(status)) {
+       //      DEBUG(0, ("print_spool_terminate: "
+       //                "Failed to get spoolss pipe [%s]\n",
+       //                nt_errstr(status)));
+       //      return;
+       //}
+       if (print_file->spoolss_pipe == NULL) {
                return;
        }
-       b = conn->spoolss_pipe->binding_handle;
+       b = print_file->spoolss_pipe->binding_handle;
 
-       status = dcerpc_spoolss_SetJob(b, print_file,
-                                       &print_file->handle,
-                                       print_file->jobid,
-                                       NULL, SPOOLSS_JOB_CONTROL_DELETE,
-                                       &werr);
+       status = dcerpc_spoolss_AbortPrinter(b, print_file,
+                                            &print_file->handle,
+                                            &werr);
        if (!NT_STATUS_IS_OK(status) ||
            !NT_STATUS_IS_OK(status = werror_to_ntstatus(werr))) {
-               DEBUG(3, ("Failed to delete job %d [%s]\n",
+               DEBUG(3, ("Failed to abort printer job %d [%s]\n",
                          print_file->jobid, nt_errstr(status)));
                return;
        }
index d596c3141abae153dc09be17906de7dbd9fcf00e..aaad6af4db3ebd32ca7ad871d66ba0891244ddbd 100644 (file)
@@ -221,6 +221,7 @@ static int print_command(int argc, char **argv)
        char *printer;
        fstring keystr;
        struct passwd *pw;
+       const char *user = NULL;
        TDB_DATA value, queue;
        struct vlp_job job;
 
@@ -238,11 +239,15 @@ static int print_command(int argc, char **argv)
        slprintf(job.jobname, sizeof(job.jobname) - 1, "%s", argv[2]);
 
        if (!(pw = getpwuid(geteuid()))) {
-               printf("getpwuid failed\n");
+               printf("getpwuid(%d) failed, nss_wrapper_enabled[%d]\n",
+                      geteuid(), nss_wrapper_enabled());
+               user = "ignore";
                return 1;
+       } else {
+               user = pw->pw_name;
        }
 
-       slprintf(job.owner, sizeof(job.owner) - 1, "%s", pw->pw_name);
+       slprintf(job.owner, sizeof(job.owner) - 1, "%s", user);
 
        job.jobid = next_jobnum(printer);
        job.size = 666;
index f716b049e1278a268ae4f2b70ec8c9ff361672ca..f01dcb906dfd0e52616e617d75e6f8c761a912b6 100644 (file)
@@ -29,6 +29,8 @@
 
 /* The following definitions come from rpc_client/cli_lsarpc.c  */
 
+struct rpc_pipe_client;
+
 /**
  * @brief Open a LSA policy.
  *
index 9ba58644ec0588343bf62a369fd46b67c321992a..50e7330fe23ce51ef3f596f04de5a2ef631ab6e6 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef _RPC_NCACN_NP_H_
 #define _RPC_NCACN_NP_H_
 
+struct rpc_pipe_client;
 struct dcerpc_binding_handle;
 struct ndr_interface_table;
 struct tsocket_address;
index 7a1c61594678e9814bd9bfe9d1e292a893ba6bc7..349458bff3db689d92dbbabd49b0dc65df20a1bc 100644 (file)
@@ -1578,10 +1578,10 @@ static bool api_rpcTNP(struct pipes_struct *p, struct ncacn_packet *pkt,
 
        /* Check for buffer underflow in rpc parsing */
        if ((DEBUGLEVEL >= 10) &&
-           (pkt->frag_length < p->in_data.data.length)) {
+           (pkt->frag_length < p->out_data.rdata.length)) {
                DEBUG(10, ("api_rpcTNP: rpc input buffer underflow (parse error?)\n"));
-               dump_data(10, p->in_data.data.data + pkt->frag_length,
-                             p->in_data.data.length - pkt->frag_length);
+               dump_data(10, p->out_data.rdata.data + pkt->frag_length,
+                             p->out_data.rdata.length - pkt->frag_length);
        }
 
        return True;
index ee95bd317aefff1ad614b446ec6e179ab4918f07..d14da5b3de924a4116809063d9a3d4487df609ec 100644 (file)
@@ -24,6 +24,7 @@
 #include "../libcli/smb/smb_common.h"
 #include "../lib/util/tevent_ntstatus.h"
 #include "rpc_server/srv_pipe_hnd.h"
+#include "printing.h"
 
 #undef DBGC_CLASS
 #define DBGC_CLASS DBGC_SMB2
@@ -321,6 +322,30 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
                return req;
        }
 
+       if (IS_PRINT(smbreq->conn)) {
+               uint32_t out_count = 0;
+               int ret;
+
+               if (fsp->print_file == NULL) {
+                       tevent_req_nterror(req, NT_STATUS_FILE_CLOSED);
+                       return tevent_req_post(req, ev);
+               }
+
+               ret = print_spool_write(fsp,
+                                       (const char *)in_data.data,
+                                       in_data.length,
+                                       in_offset,
+                                       &out_count);
+               if (ret) {
+                       status = map_nt_error_from_unix(ret);
+                       tevent_req_nterror(req, status);
+                       return tevent_req_post(req, ev);
+               }
+               state->out_count = out_count;
+               tevent_req_done(req);
+               return tevent_req_post(req, ev);
+       }
+
        if (!CHECK_WRITE(fsp)) {
                tevent_req_nterror(req, NT_STATUS_ACCESS_DENIED);
                return tevent_req_post(req, ev);
index 0d01ad450102e9be0d8f3d95013f6ab8977b9605..dc4b94f546a432f48dc74951374fb38f6efa868a 100644 (file)
@@ -23,6 +23,7 @@
  */
 
 struct cli_state;
+struct rpc_pipe_client;
 
 #include "../librpc/gen_ndr/lsa.h"