[PATCH] Fix for Denied access for all client printing operations against Windows 2016

Jeremy Allison jra at samba.org
Wed Sep 5 23:59:22 UTC 2018


On Wed, Sep 05, 2018 at 04:55:41PM -0400, Justin Stephenson via samba-technical wrote:
> Thank you for the review Jeremy.
> 
> Updated patches attached with the corrected version number in the .xml docs.
> 
> Kind regards,
> Justin Stephenson

OK Justin, LGTM. RB+ Jeremy Allison <jra at samba.org>.

Can I get a second Team reviewer (Guenther, looking at you :-).

Cheers,

	Jeremy.

> On Wed, Sep 5, 2018 at 4:18 PM, Jeremy Allison <jra at samba.org> wrote:
> 
> > On Tue, Sep 04, 2018 at 12:14:59PM -0400, Justin Stephenson via
> > samba-technical wrote:
> > > Hi,
> > >
> > > Please see attached patchset to fix Bug 13597
> > > https://bugzilla.samba.org/show_bug.cgi?id=13597
> > >
> > > The microsoft documentation team has confirmed this discovered behavior
> > and
> > > will be updating the protocol specification regarding the build number
> > > requirements.
> > >
> > > Thank you to Guenther Deschner for writing two of the commits in this
> > > patchset.
> > >
> > > Gitlab Merge request: https://gitlab.com/samba-team/
> > samba/merge_requests/66
> > >
> > > Thank you,
> > >
> > > Justin Stephenson
> >
> > Hi Justin,
> >
> > Thanks a *LOT* for this fix. The code changes LGTM (can I get
> > a second Team reviewer please ?).
> >
> > However, I don't understand the xml documentation patches here.
> >
> > You have:
> >
> >  +<samba:parameter name="spoolss_client: os_major"
> >  +                 context="G"
> >  +                 type="integer"
> >  +                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> >  +<description>
> >  +     <para>Windows might require a new os version number. This option
> > allows
> >  +             to modify the build number. The complete default version
> > number is:
> >  +             5.0.2195 (Windows 2000). The example is 6.1.7601 (Windows
> > 2008 R2).
> >  +     </para>
> >  +</description>
> >  +<value type="default">2</value>
> >  +<value type="example">3</value>
> >
> >  +<samba:parameter name="spoolss_client: os_minor"
> >  +              context="G"
> >  +              type="integer"
> >  +              xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> >  +<description>
> >  +     <para>Windows might require a new os version number. This option
> > allows
> >  +             to modify the build number. The complete default version
> > number is:
> >  +             5.0.2195 (Windows 2000). The example is 6.1.7601 (Windows
> > 2008 R2).
> >  +     </para>
> >  +</description>
> >  +<value type="default">0</value>
> >  +<value type="example">1</value>
> >
> >  +<samba:parameter name="spoolss_client: os_build"
> >  +              context="G"
> >  +              type="integer"
> >  +              xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> >  +<description>
> >  +     <para>Windows might require a new os version number. This option
> > allows
> >  +             to modify the build number. The complete default version
> > number is:
> >  +             5.0.2195 (Windows 2000). The example is 6.1.7601 (Windows
> > 2008 R2).
> >  +     </para>
> >  +</description>
> >  +<value type="default">1381</value>
> >  +<value type="example">6000</value>
> >
> > But in the code changes you end up with:
> >
> > +/* Windows 7 and Windows Server 2008 R2 */
> > +#define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 6
> > +#define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 1
> > +#define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 7007
> >
> > Can you fix up the .xml docs to match the code changes
> > you're making, otherwise it's hard for others to understand
> > what these parameters mean ?
> >
> > Thanks.
> >
> >         Jeremy.
> >
> >
> > > From 2475ac8dbfd83c06f4a12dac939aaf38bed81b51 Mon Sep 17 00:00:00 2001
> > > From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
> > > Date: Fri, 31 Aug 2018 17:36:19 +0200
> > > Subject: [PATCH 1/6] s3-spoolss: Make spoolss client os_major,os_minor
> > and
> > >  os_build configurable.
> > >
> > > Similar to spoolss server options, make the client advertised OS version
> > > values configurable to allow overriding the defaults provided to the
> > print server.
> > >
> > > BUG: https://bugzilla.samba.org/show_bug.cgi?id=13597
> > >
> > > Signed-off-by: Guenther Deschner <gd at samba.org>
> > > ---
> > >  .../smbdotconf/printing/spoolssosversion.xml  | 42 +++++++++++++++++++
> > >  source3/rpc_client/cli_spoolss.c              | 29 ++++++-------
> > >  source3/rpc_client/init_spoolss.c             | 30 +++++++++++++
> > >  source3/rpc_client/init_spoolss.h             |  3 ++
> > >  4 files changed, 88 insertions(+), 16 deletions(-)
> > >
> > > diff --git a/docs-xml/smbdotconf/printing/spoolssosversion.xml
> > b/docs-xml/smbdotconf/printing/spoolssosversion.xml
> > > index 0ef4489a657..5878a4b00cd 100644
> > > --- a/docs-xml/smbdotconf/printing/spoolssosversion.xml
> > > +++ b/docs-xml/smbdotconf/printing/spoolssosversion.xml
> > > @@ -39,3 +39,45 @@
> > >  <value type="default">2195</value>
> > >  <value type="example">7601</value>
> > >  </samba:parameter>
> > > +
> > > +<samba:parameter name="spoolss_client: os_major"
> > > +                 context="G"
> > > +                 type="integer"
> > > +                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc
> > ">
> > > +<description>
> > > +     <para>Windows might require a new os version number. This option
> > allows
> > > +             to modify the build number. The complete default version
> > number is:
> > > +             5.0.2195 (Windows 2000). The example is 6.1.7601 (Windows
> > 2008 R2).
> > > +     </para>
> > > +</description>
> > > +<value type="default">2</value>
> > > +<value type="example">3</value>
> > > +</samba:parameter>
> > > +
> > > +<samba:parameter name="spoolss_client: os_minor"
> > > +              context="G"
> > > +              type="integer"
> > > +              xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> > > +<description>
> > > +     <para>Windows might require a new os version number. This option
> > allows
> > > +             to modify the build number. The complete default version
> > number is:
> > > +             5.0.2195 (Windows 2000). The example is 6.1.7601 (Windows
> > 2008 R2).
> > > +     </para>
> > > +</description>
> > > +<value type="default">0</value>
> > > +<value type="example">1</value>
> > > +</samba:parameter>
> > > +
> > > +<samba:parameter name="spoolss_client: os_build"
> > > +              context="G"
> > > +              type="integer"
> > > +              xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> > > +<description>
> > > +     <para>Windows might require a new os version number. This option
> > allows
> > > +             to modify the build number. The complete default version
> > number is:
> > > +             5.0.2195 (Windows 2000). The example is 6.1.7601 (Windows
> > 2008 R2).
> > > +     </para>
> > > +</description>
> > > +<value type="default">1381</value>
> > > +<value type="example">6000</value>
> > > +</samba:parameter>
> > > diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_
> > spoolss.c
> > > index 7f6ed8e3c91..36ca806f531 100644
> > > --- a/source3/rpc_client/cli_spoolss.c
> > > +++ b/source3/rpc_client/cli_spoolss.c
> > > @@ -28,6 +28,7 @@
> > >  #include "rpc_client/cli_spoolss.h"
> > >  #include "auth/gensec/gensec.h"
> > >  #include "auth/credentials/credentials.h"
> > > +#include "rpc_client/init_spoolss.h"
> > >
> > >  /**********************************************************************
> > >   convencience wrapper around rpccli_spoolss_OpenPrinterEx
> > > @@ -49,14 +50,12 @@ WERROR rpccli_spoolss_openprinter_ex(struct
> > rpc_pipe_client *cli,
> > >
> > >       ZERO_STRUCT(devmode_ctr);
> > >
> > > -     level1.size     = 28;
> > > -     level1.client   = talloc_asprintf(mem_ctx, "\\\\%s",
> > lp_netbios_name());
> > > -     W_ERROR_HAVE_NO_MEMORY(level1.client);
> > > -     level1.user     = cli_credentials_get_username(creds);
> > > -     level1.build    = 1381;
> > > -     level1.major    = 2;
> > > -     level1.minor    = 0;
> > > -     level1.processor = 0;
> > > +     werror = spoolss_init_spoolss_UserLevel1(mem_ctx,
> > > +
> > cli_credentials_get_username(creds),
> > > +                                              &level1);
> > > +     if (!W_ERROR_IS_OK(werror)) {
> > > +             return werror;
> > > +     }
> > >
> > >       userlevel_ctr.level = 1;
> > >       userlevel_ctr.user_info.level1 = &level1;
> > > @@ -229,14 +228,12 @@ WERROR rpccli_spoolss_addprinterex(struct
> > rpc_pipe_client *cli,
> > >       ZERO_STRUCT(devmode_ctr);
> > >       ZERO_STRUCT(secdesc_ctr);
> > >
> > > -     level1.size             = 28;
> > > -     level1.build            = 1381;
> > > -     level1.major            = 2;
> > > -     level1.minor            = 0;
> > > -     level1.processor        = 0;
> > > -     level1.client           = talloc_asprintf(mem_ctx, "\\\\%s",
> > lp_netbios_name());
> > > -     W_ERROR_HAVE_NO_MEMORY(level1.client);
> > > -     level1.user             = cli_credentials_get_username(creds);
> > > +     result = spoolss_init_spoolss_UserLevel1(mem_ctx,
> > > +
> > cli_credentials_get_username(creds),
> > > +                                              &level1);
> > > +     if (!W_ERROR_IS_OK(result)) {
> > > +             return result;
> > > +     }
> > >
> > >       userlevel_ctr.level = 1;
> > >       userlevel_ctr.user_info.level1 = &level1;
> > > diff --git a/source3/rpc_client/init_spoolss.c
> > b/source3/rpc_client/init_spoolss.c
> > > index 9a4dab6d417..1996465ee9f 100644
> > > --- a/source3/rpc_client/init_spoolss.c
> > > +++ b/source3/rpc_client/init_spoolss.c
> > > @@ -446,3 +446,33 @@ const char *spoolss_get_short_filesys_environment(const
> > char *environment)
> > >               return NULL;
> > >       }
> > >  }
> > > +
> > > +#define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 2
> > > +#define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 0
> > > +#define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 1381
> > > +
> > > +WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
> > > +                                    const char *username,
> > > +                                    struct spoolss_UserLevel1 *r)
> > > +{
> > > +     ZERO_STRUCTP(r);
> > > +
> > > +     r->size         = 28;
> > > +     r->client       = talloc_asprintf(mem_ctx, "\\\\%s",
> > lp_netbios_name());
> > > +     W_ERROR_HAVE_NO_MEMORY(r->client);
> > > +     r->user         = talloc_strdup(mem_ctx, username);
> > > +     W_ERROR_HAVE_NO_MEMORY(r->user);
> > > +     r->processor    = 0;
> > > +
> > > +     r->major        = lp_parm_int(GLOBAL_SECTION_SNUM,
> > > +                                   "spoolss_client", "os_major",
> > > +                                   GLOBAL_SPOOLSS_CLIENT_OS_
> > MAJOR_DEFAULT);
> > > +     r->minor        = lp_parm_int(GLOBAL_SECTION_SNUM,
> > > +                                   "spoolss_client", "os_minor",
> > > +                                   GLOBAL_SPOOLSS_CLIENT_OS_
> > MINOR_DEFAULT);
> > > +     r->build        = lp_parm_int(GLOBAL_SECTION_SNUM,
> > > +                                   "spoolss_client", "os_build",
> > > +                                   GLOBAL_SPOOLSS_CLIENT_OS_
> > BUILD_DEFAULT);
> > > +
> > > +     return WERR_OK;
> > > +}
> > > diff --git a/source3/rpc_client/init_spoolss.h
> > b/source3/rpc_client/init_spoolss.h
> > > index 376eaefe914..062e37b97e4 100644
> > > --- a/source3/rpc_client/init_spoolss.h
> > > +++ b/source3/rpc_client/init_spoolss.h
> > > @@ -48,5 +48,8 @@ WERROR spoolss_create_default_devmode(TALLOC_CTX
> > *mem_ctx,
> > >  WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
> > >                                     struct spoolss_security_descriptor
> > **secdesc);
> > >  const char *spoolss_get_short_filesys_environment(const char
> > *environment);
> > > +WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
> > > +                                    const char *username,
> > > +                                    struct spoolss_UserLevel1 *r);
> > >
> > >  #endif /* _RPC_CLIENT_INIT_SPOOLSS_H_ */
> > > --
> > > 2.17.1
> > >
> > >
> > > From b76926934e379cc2f42733bed5594fc339d2f8da Mon Sep 17 00:00:00 2001
> > > From: Justin Stephenson <jstephen at redhat.com>
> > > Date: Fri, 31 Aug 2018 13:28:58 -0400
> > > Subject: [PATCH 2/6] s3-rpc_client: Advertise Windows 7 client info
> > >
> > > Client printing operations currently fail against Windows
> > > Server 2016 with Access Denied if a client os build number
> > > lower than 6000 is advertised. Increase the default build number,
> > > major, and minor versions to values associated with client
> > > OS versoins Windows 7 and Windows Server 2008 R2.
> > >
> > > The build number value specifically needs to be increased to
> > > allow these operations to succeed.
> > >
> > > BUG: https://bugzilla.samba.org/show_bug.cgi?id=13597
> > >
> > > Signed-off-by: Justin Stephenson <jstephen at redhat.com>
> > > ---
> > >  source3/rpc_client/init_spoolss.c | 7 ++++---
> > >  1 file changed, 4 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/source3/rpc_client/init_spoolss.c
> > b/source3/rpc_client/init_spoolss.c
> > > index 1996465ee9f..c341b82b6ee 100644
> > > --- a/source3/rpc_client/init_spoolss.c
> > > +++ b/source3/rpc_client/init_spoolss.c
> > > @@ -447,9 +447,10 @@ const char *spoolss_get_short_filesys_environment(const
> > char *environment)
> > >       }
> > >  }
> > >
> > > -#define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 2
> > > -#define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 0
> > > -#define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 1381
> > > +/* Windows 7 and Windows Server 2008 R2 */
> > > +#define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 6
> > > +#define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 1
> > > +#define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 7007
> > >
> > >  WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
> > >                                      const char *username,
> > > --
> > > 2.17.1
> > >
> > >
> > > From da7a67846dc2b52dd98d5868a3259c6954290027 Mon Sep 17 00:00:00 2001
> > > From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
> > > Date: Fri, 31 Aug 2018 18:22:04 +0200
> > > Subject: [PATCH 3/6] s3-rpcclient: Use spoolss_init_spoolss_UserLevel1
> > in
> > >  winspool cmds
> > >
> > > Use spoolss initialization function to set client version information for
> > > iremotewinspool printer operations
> > >
> > > Signed-off-by: Guenther Deschner <gd at samba.org>
> > > ---
> > >  source3/rpcclient/cmd_iremotewinspool.c | 16 +++++++++-------
> > >  1 file changed, 9 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/source3/rpcclient/cmd_iremotewinspool.c
> > b/source3/rpcclient/cmd_iremotewinspool.c
> > > index c6148ec02c7..7f0cecfaf01 100644
> > > --- a/source3/rpcclient/cmd_iremotewinspool.c
> > > +++ b/source3/rpcclient/cmd_iremotewinspool.c
> > > @@ -24,6 +24,7 @@
> > >  #include "libsmb/libsmb.h"
> > >  #include "auth/gensec/gensec.h"
> > >  #include "auth/credentials/credentials.h"
> > > +#include "rpc_client/init_spoolss.h"
> > >
> > >  /***********************************************************
> > *****************
> > >  ************************************************************
> > ****************/
> > > @@ -33,6 +34,7 @@ static WERROR cmd_iremotewinspool_async_open_printer(struct
> > rpc_pipe_client *cli
> > >                                                    int argc, const char
> > **argv)
> > >  {
> > >       NTSTATUS status;
> > > +     WERROR werror;
> > >       struct policy_handle hnd;
> > >       struct spoolss_DevmodeContainer devmode_ctr;
> > >       struct spoolss_UserLevelCtr client_info_ctr;
> > > @@ -59,13 +61,13 @@ static WERROR cmd_iremotewinspool_async_open_printer(struct
> > rpc_pipe_client *cli
> > >
> > >       ZERO_STRUCT(devmode_ctr);
> > >
> > > -     level1.size     = 40;
> > > -     level1.client   = talloc_asprintf(mem_ctx, "\\\\%s",
> > lp_netbios_name());
> > > -     W_ERROR_HAVE_NO_MEMORY(level1.client);
> > > -     level1.user     = cli_credentials_get_username(creds);
> > > -     level1.build    = 1381;
> > > -     level1.major    = 3;
> > > -     level1.minor    = 0;
> > > +        werror = spoolss_init_spoolss_UserLevel1(mem_ctx,
> > > +
> > cli_credentials_get_username(creds),
> > > +                                              &level1);
> > > +     if (!W_ERROR_IS_OK(werror)) {
> > > +             return werror;
> > > +     }
> > > +
> > >       level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
> > >
> > >       client_info_ctr.level = 1;
> > > --
> > > 2.17.1
> > >
> > >
> > > From ca9bce09f2c81f9fddb8f88ad7f11c746f5ac80b Mon Sep 17 00:00:00 2001
> > > From: Justin Stephenson <jstephen at redhat.com>
> > > Date: Wed, 15 Aug 2018 11:10:21 -0400
> > > Subject: [PATCH 4/6] iremotewinspool-tests: Allow modification of OS
> > client
> > >  version information
> > >
> > > Add test_get_client_info() function to set and, or modify the client OS
> > > version values advertised in the iremotewinspool torture tests.
> > >
> > > The OS build numbers are used from the table in:
> > >
> > >   [MS-RPRN] <168> Section 2.2.3.10.1
> > >
> > > Signed-off-by: Justin Stephenson <jstephen at redhat.com>
> > > ---
> > >  source4/torture/rpc/iremotewinspool.c | 86 ++++++++++++++++++++++-----
> > >  1 file changed, 72 insertions(+), 14 deletions(-)
> > >
> > > diff --git a/source4/torture/rpc/iremotewinspool.c
> > b/source4/torture/rpc/iremotewinspool.c
> > > index d419e9c082b..d80f2f74c65 100644
> > > --- a/source4/torture/rpc/iremotewinspool.c
> > > +++ b/source4/torture/rpc/iremotewinspool.c
> > > @@ -33,31 +33,77 @@ struct test_iremotewinspool_context {
> > >       const char *environment;
> > >  };
> > >
> > > +enum client_os_version
> > > +{
> > > +     WIN_2000,
> > > +     WIN_VISTA,
> > > +     WIN_SERVER_2008,
> > > +     WIN_7,
> > > +     WIN_SERVER_2008R2,
> > > +     WIN_8,
> > > +     WIN_SERVER_2012,
> > > +     WIN_10,
> > > +     WIN_SERVER_2016
> > > +};
> > > +
> > > +static struct spoolss_UserLevel1 test_get_client_info(struct
> > torture_context *tctx,
> > > +                                                   enum
> > client_os_version os,
> > > +                                                   enum
> > spoolss_MajorVersion major_number,
> > > +                                                   enum
> > spoolss_MinorVersion minor_number)
> > > +{
> > > +     struct spoolss_UserLevel1 level1;
> > > +
> > > +     level1.size     = 28;
> > > +     level1.client   = talloc_asprintf(tctx, "\\\\%s", "mthelena");
> > > +     level1.user     = "GD";
> > > +     level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
> > > +     level1.major    = major_number;
> > > +     level1.minor    = minor_number;
> > > +
> > > +     switch (os) {
> > > +             case WIN_SERVER_2016:
> > > +             case WIN_10:
> > > +                     level1.build = 10586;
> > > +                     break;
> > > +             case WIN_SERVER_2012:
> > > +             case WIN_8:
> > > +                     level1.build = 9200;
> > > +                     break;
> > > +             case WIN_SERVER_2008R2:
> > > +             case WIN_7:
> > > +                     level1.build = 7007;
> > > +                     break;
> > > +             case WIN_SERVER_2008:
> > > +             case WIN_VISTA:
> > > +                     level1.build = 6000;
> > > +                     break;
> > > +             case WIN_2000:
> > > +                     level1.build = 1382;
> > > +                     break;
> > > +             default:
> > > +                     level1.build = 7007;
> > > +     }
> > > +
> > > +     return level1;
> > > +}
> > > +
> > >  static bool test_AsyncOpenPrinter_byprinter(struct torture_context
> > *tctx,
> > >                                           struct
> > test_iremotewinspool_context *ctx,
> > >                                           struct dcerpc_pipe *p,
> > >                                           const char *printer_name,
> > > +                                         struct spoolss_UserLevel1
> > cinfo,
> > >                                           struct policy_handle *handle)
> > >  {
> > >       struct dcerpc_binding_handle *b = p->binding_handle;
> > >       struct spoolss_DevmodeContainer devmode_ctr;
> > >       struct spoolss_UserLevelCtr client_info_ctr;
> > > -     struct spoolss_UserLevel1 level1;
> > >       uint32_t access_mask = SERVER_ALL_ACCESS;
> > >       struct winspool_AsyncOpenPrinter r;
> > >
> > >       ZERO_STRUCT(devmode_ctr);
> > >
> > > -     level1.size     = 28;
> > > -     level1.client   = talloc_asprintf(tctx, "\\\\%s", "mthelena");
> > > -     level1.user     = "GD";
> > > -     level1.build    = 1381;
> > > -     level1.major    = 3;
> > > -     level1.minor    = 0;
> > > -     level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
> > > -
> > >       client_info_ctr.level = 1;
> > > -     client_info_ctr.user_info.level1 = &level1;
> > > +     client_info_ctr.user_info.level1 = &cinfo;
> > >
> > >       r.in.pPrinterName       = printer_name;
> > >       r.in.pDatatype          = NULL;
> > > @@ -196,6 +242,7 @@ static bool torture_rpc_iremotewinspool_setup_common(struct
> > torture_context *tct
> > >                                                    struct
> > test_iremotewinspool_context *t)
> > >  {
> > >       const char *printer_name;
> > > +     struct spoolss_UserLevel1 client_info;
> > >       struct dcerpc_binding *binding;
> > >
> > >       torture_assert_ntstatus_ok(tctx,
> > > @@ -216,10 +263,12 @@ static bool torture_rpc_iremotewinspool_setup_common(struct
> > torture_context *tct
> > >
> > >       printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(t->iremotewinspool_pipe));
> > >
> > > +     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +
> > >       torture_assert(tctx,
> > >               test_AsyncOpenPrinter_byprinter(tctx, t,
> > >                                               t->iremotewinspool_pipe,
> > printer_name,
> > > -                                             &t->server_handle),
> > > +                                             client_info,
> > &t->server_handle),
> > >                                               "failed to open
> > printserver");
> > >       torture_assert(tctx,
> > >               test_get_environment(tctx,
> > > @@ -269,12 +318,15 @@ static bool test_AsyncClosePrinter(struct
> > torture_context *tctx,
> > >
> > >       struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
> > >       const char *printer_name;
> > > +     struct spoolss_UserLevel1 client_info;
> > >       struct policy_handle handle;
> > >
> > >       printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(p));
> > >
> > > +     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +
> > >       torture_assert(tctx,
> > > -             test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, &handle),
> > > +             test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, client_info, &handle),
> > >               "failed to test AsyncOpenPrinter");
> > >
> > >       torture_assert(tctx,
> > > @@ -292,12 +344,15 @@ static bool test_AsyncOpenPrinter(struct
> > torture_context *tctx,
> > >
> > >       struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
> > >       const char *printer_name;
> > > +     struct spoolss_UserLevel1 client_info;
> > >       struct policy_handle handle;
> > >
> > >       printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(p));
> > >
> > > +     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +
> > >       torture_assert(tctx,
> > > -             test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, &handle),
> > > +             test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, client_info, &handle),
> > >               "failed to test AsyncOpenPrinter");
> > >
> > >       test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle);
> > > @@ -871,6 +926,7 @@ static bool test_OpenPrinter(struct torture_context
> > *tctx,
> > >       struct policy_handle handle;
> > >       struct dcerpc_pipe *s;
> > >       struct dcerpc_binding *binding;
> > > +     struct spoolss_UserLevel1 client_info;
> > >       struct spoolss_ClosePrinter r;
> > >
> > >       torture_assert_ntstatus_ok(tctx,
> > > @@ -891,8 +947,10 @@ static bool test_OpenPrinter(struct torture_context
> > *tctx,
> > >
> > >       printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(p));
> > >
> > > +     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +
> > >       torture_assert(tctx,
> > > -             test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, &handle),
> > > +             test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, client_info, &handle),
> > >               "failed to open printserver via winspool");
> > >
> > >
> > > --
> > > 2.17.1
> > >
> > >
> > > From 80ee68584befaaad8e2e55d950c04d5d1a6bc873 Mon Sep 17 00:00:00 2001
> > > From: Justin Stephenson <jstephen at redhat.com>
> > > Date: Wed, 22 Aug 2018 13:23:18 -0400
> > > Subject: [PATCH 5/6] iremotewinspool-tests: Add client os build number
> > >  validation test
> > >
> > > Add test validating the AsyncOpenPrinter result based on the provided
> > > client info build number
> > >
> > > Signed-off-by: Justin Stephenson <jstephen at redhat.com>
> > > ---
> > >  source4/torture/rpc/iremotewinspool.c | 65 +++++++++++++++++++++++++++
> > >  1 file changed, 65 insertions(+)
> > >
> > > diff --git a/source4/torture/rpc/iremotewinspool.c
> > b/source4/torture/rpc/iremotewinspool.c
> > > index d80f2f74c65..805f46c8b89 100644
> > > --- a/source4/torture/rpc/iremotewinspool.c
> > > +++ b/source4/torture/rpc/iremotewinspool.c
> > > @@ -360,6 +360,70 @@ static bool test_AsyncOpenPrinter(struct
> > torture_context *tctx,
> > >       return true;
> > >  }
> > >
> > > +/*
> > > + * Validate the result of AsyncOpenPrinter calls based on client info
> > > + * build number. Windows Server 2016 rejects an advertised build
> > > + * number less than 6000(Windows Vista and Windows Server 2008, or
> > older)
> > > + */
> > > +static bool test_AsyncOpenPrinterValidateBuildNumber(struct
> > torture_context *tctx,
> > > +                                                  void *private_data)
> > > +{
> > > +     struct test_iremotewinspool_context *ctx =
> > > +             talloc_get_type_abort(private_data, struct
> > test_iremotewinspool_context);
> > > +
> > > +     struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
> > > +     const char *printer_name;
> > > +     struct spoolss_UserLevel1 client_info;
> > > +     struct policy_handle handle;
> > > +     struct dcerpc_binding_handle *b = p->binding_handle;
> > > +     struct spoolss_DevmodeContainer devmode_ctr;
> > > +     struct spoolss_UserLevelCtr client_info_ctr = {
> > > +             .level = 1,
> > > +     };
> > > +     uint32_t access_mask = SERVER_ALL_ACCESS;
> > > +     struct winspool_AsyncOpenPrinter r;
> > > +     NTSTATUS status;
> > > +     bool ok = false;
> > > +
> > > +     printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(p));
> > > +     torture_assert_not_null(tctx, printer_name, "Cannot allocate
> > memory");
> > > +
> > > +     /* fail with Windows 2000 build number */
> > > +     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +
> > > +     ZERO_STRUCT(devmode_ctr);
> > > +
> > > +     client_info_ctr.user_info.level1 = &client_info;
> > > +
> > > +     r.in.pPrinterName       = printer_name;
> > > +     r.in.pDatatype          = NULL;
> > > +     r.in.pDevModeContainer  = &devmode_ctr;
> > > +     r.in.AccessRequired     = access_mask;
> > > +     r.in.pClientInfo        = &client_info_ctr;
> > > +     r.out.pHandle           = &handle;
> > > +
> > > +     status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
> > > +     torture_assert_ntstatus_ok(tctx, status, "AsyncOpenPrinter
> > failed");
> > > +     torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
> > > +             "AsyncOpenPrinter should have failed");
> > > +
> > > +     /* succeed with Windows 7 build number */
> > > +     client_info = test_get_client_info(tctx, WIN_7, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +     client_info_ctr.user_info.level1 = &client_info;
> > > +     r.in.pClientInfo        = &client_info_ctr;
> > > +
> > > +     status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
> > > +     torture_assert_ntstatus_ok(tctx, status, "AsyncOpenPrinter
> > failed");
> > > +     torture_assert_werr_ok(tctx, r.out.result,
> > > +             "AsyncOpenPrinter failed");
> > > +
> > > +     ok = test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle);
> > > +     torture_assert(tctx, ok, "failed to AsyncClosePrinter handle");
> > > +
> > > +     return true;
> > > +
> > > +}
> > > +
> > >  static struct spoolss_NotifyOption *setup_printserver_NotifyOption(struct
> > torture_context *tctx)
> > >  {
> > >       struct spoolss_NotifyOption *o;
> > > @@ -986,6 +1050,7 @@ struct torture_suite *torture_rpc_iremotewinspool(TALLOC_CTX
> > *mem_ctx)
> > >       torture_tcase_add_simple_test(tcase, "
> > AsyncCorePrinterDriverInstalled", test_AsyncCorePrinterDriverInstalled);
> > >       torture_tcase_add_simple_test(tcase, "
> > AsyncDeletePrintDriverPackage", test_AsyncDeletePrintDriverPackage);
> > >       torture_tcase_add_simple_test(tcase, "
> > AsyncGetPrinterDriverDirectory", test_AsyncGetPrinterDriverDirectory);
> > > +     torture_tcase_add_simple_test(tcase, "
> > AsyncOpenPrinterValidateBuildNumber", test_AsyncOpenPrinterValidateBuildN
> > umber);
> > >
> > >       tcase = torture_suite_add_tcase(suite, "handles");
> > >
> > > --
> > > 2.17.1
> > >
> > >
> > > From cb14b4cea01f7018de7440ff482e11834d35c85b Mon Sep 17 00:00:00 2001
> > > From: Justin Stephenson <jstephen at redhat.com>
> > > Date: Fri, 31 Aug 2018 15:28:36 -0400
> > > Subject: [PATCH 6/6] spoolss-iremotewinspool-tests: Use more recent
> > client OS
> > >  version
> > >
> > > Set torture test client info build, major, and minor
> > > version numbers to Windows 7 and Windows Server 2008 R2 values
> > >
> > >  buildnum: 7007
> > >  major: 6
> > >  minor: 1
> > >
> > > Build number taken from
> > >  [MS-RPRN] <168> Section 2.2.3.10.1
> > >
> > > Major/Minor numbers taken from
> > >  https://docs.microsoft.com/en-us/windows/desktop/sysinfo/
> > operating-system-version
> > >
> > > Signed-off-by: Justin Stephenson <jstephen at redhat.com>
> > > ---
> > >  source4/torture/rpc/iremotewinspool.c | 10 +++++-----
> > >  source4/torture/rpc/spoolss_access.c  |  7 ++++---
> > >  2 files changed, 9 insertions(+), 8 deletions(-)
> > >
> > > diff --git a/source4/torture/rpc/iremotewinspool.c
> > b/source4/torture/rpc/iremotewinspool.c
> > > index 805f46c8b89..b4dbe71160e 100644
> > > --- a/source4/torture/rpc/iremotewinspool.c
> > > +++ b/source4/torture/rpc/iremotewinspool.c
> > > @@ -263,7 +263,7 @@ static bool torture_rpc_iremotewinspool_setup_common(struct
> > torture_context *tct
> > >
> > >       printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(t->iremotewinspool_pipe));
> > >
> > > -     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +     client_info = test_get_client_info(tctx, WIN_7, 6, 1);
> > >
> > >       torture_assert(tctx,
> > >               test_AsyncOpenPrinter_byprinter(tctx, t,
> > > @@ -323,7 +323,7 @@ static bool test_AsyncClosePrinter(struct
> > torture_context *tctx,
> > >
> > >       printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(p));
> > >
> > > -     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +     client_info = test_get_client_info(tctx, WIN_7, 6, 1);
> > >
> > >       torture_assert(tctx,
> > >               test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, client_info, &handle),
> > > @@ -349,7 +349,7 @@ static bool test_AsyncOpenPrinter(struct
> > torture_context *tctx,
> > >
> > >       printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(p));
> > >
> > > -     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +     client_info = test_get_client_info(tctx, WIN_7, 6, 1);
> > >
> > >       torture_assert(tctx,
> > >               test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, client_info, &handle),
> > > @@ -408,7 +408,7 @@ static bool test_AsyncOpenPrinterValidateBuildNumber(struct
> > torture_context *tct
> > >               "AsyncOpenPrinter should have failed");
> > >
> > >       /* succeed with Windows 7 build number */
> > > -     client_info = test_get_client_info(tctx, WIN_7, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +     client_info = test_get_client_info(tctx, WIN_7, 6, 1);
> > >       client_info_ctr.user_info.level1 = &client_info;
> > >       r.in.pClientInfo        = &client_info_ctr;
> > >
> > > @@ -1011,7 +1011,7 @@ static bool test_OpenPrinter(struct
> > torture_context *tctx,
> > >
> > >       printer_name = talloc_asprintf(tctx, "\\\\%s",
> > dcerpc_server_name(p));
> > >
> > > -     client_info = test_get_client_info(tctx, WIN_2000, 3,
> > SPOOLSS_MINOR_VERSION_0);
> > > +     client_info = test_get_client_info(tctx, WIN_7, 6, 1);
> > >
> > >       torture_assert(tctx,
> > >               test_AsyncOpenPrinter_byprinter(tctx, ctx, p,
> > printer_name, client_info, &handle),
> > > diff --git a/source4/torture/rpc/spoolss_access.c
> > b/source4/torture/rpc/spoolss_access.c
> > > index 28cecf08b14..946b420b60a 100644
> > > --- a/source4/torture/rpc/spoolss_access.c
> > > +++ b/source4/torture/rpc/spoolss_access.c
> > > @@ -74,9 +74,10 @@ static bool test_openprinter_handle(struct
> > torture_context *tctx,
> > >       level1.size     = 28;
> > >       level1.client   = talloc_asprintf(tctx, "\\\\%s", "smbtorture");
> > >       level1.user     = username;
> > > -     level1.build    = 1381;
> > > -     level1.major    = 3;
> > > -     level1.minor    = 0;
> > > +     /* Windows 7 and Windows Server 2008 R2 */
> > > +     level1.build    = 7007;
> > > +     level1.major    = 6;
> > > +     level1.minor    = 1;
> > >       level1.processor= 0;
> > >
> > >       r.in.printername        = printername;
> > > --
> > > 2.17.1
> > >
> >
> >

> From c7b8d4888776c0fa2e017a2cbe119b157222d537 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
> Date: Fri, 31 Aug 2018 17:36:19 +0200
> Subject: [PATCH 1/6] s3-spoolss: Make spoolss client os_major,os_minor and
>  os_build configurable.
> 
> Similar to spoolss server options, make the client advertised OS version
> values configurable to allow overriding the defaults provided to the print server.
> 
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=13597
> 
> Signed-off-by: Guenther Deschner <gd at samba.org>
> ---
>  .../smbdotconf/printing/spoolssosversion.xml  | 39 +++++++++++++++++++
>  source3/rpc_client/cli_spoolss.c              | 29 +++++++-------
>  source3/rpc_client/init_spoolss.c             | 30 ++++++++++++++
>  source3/rpc_client/init_spoolss.h             |  3 ++
>  4 files changed, 85 insertions(+), 16 deletions(-)
> 
> diff --git a/docs-xml/smbdotconf/printing/spoolssosversion.xml b/docs-xml/smbdotconf/printing/spoolssosversion.xml
> index 0ef4489a657..1b57b692705 100644
> --- a/docs-xml/smbdotconf/printing/spoolssosversion.xml
> +++ b/docs-xml/smbdotconf/printing/spoolssosversion.xml
> @@ -39,3 +39,42 @@
>  <value type="default">2195</value>
>  <value type="example">7601</value>
>  </samba:parameter>
> +
> +<samba:parameter name="spoolss_client: os_major"
> +                 context="G"
> +                 type="integer"
> +                 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> +<description>
> +	<para>Windows might require a new os version number. This option allows
> +		to modify the build number. The complete default version number is:
> +		6.1.7007 (Windows 7 and Windows Server 2008 R2).
> +	</para>
> +</description>
> +<value type="default">6</value>
> +</samba:parameter>
> +
> +<samba:parameter name="spoolss_client: os_minor"
> +		 context="G"
> +		 type="integer"
> +		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> +<description>
> +	<para>Windows might require a new os version number. This option allows
> +		to modify the build number. The complete default version number is:
> +		6.1.7007 (Windows 7 and Windows Server 2008 R2).
> +	</para>
> +</description>
> +<value type="default">1</value>
> +</samba:parameter>
> +
> +<samba:parameter name="spoolss_client: os_build"
> +		 context="G"
> +		 type="integer"
> +		 xmlns:samba="http://www.samba.org/samba/DTD/samba-doc">
> +<description>
> +	<para>Windows might require a new os version number. This option allows
> +		to modify the build number. The complete default version number is:
> +		6.1.7007 (Windows 7 and Windows Server 2008 R2).
> +	</para>
> +</description>
> +<value type="default">7007</value>
> +</samba:parameter>
> diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c
> index 7f6ed8e3c91..36ca806f531 100644
> --- a/source3/rpc_client/cli_spoolss.c
> +++ b/source3/rpc_client/cli_spoolss.c
> @@ -28,6 +28,7 @@
>  #include "rpc_client/cli_spoolss.h"
>  #include "auth/gensec/gensec.h"
>  #include "auth/credentials/credentials.h"
> +#include "rpc_client/init_spoolss.h"
>  
>  /**********************************************************************
>   convencience wrapper around rpccli_spoolss_OpenPrinterEx
> @@ -49,14 +50,12 @@ WERROR rpccli_spoolss_openprinter_ex(struct rpc_pipe_client *cli,
>  
>  	ZERO_STRUCT(devmode_ctr);
>  
> -	level1.size	= 28;
> -	level1.client	= talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
> -	W_ERROR_HAVE_NO_MEMORY(level1.client);
> -	level1.user	= cli_credentials_get_username(creds);
> -	level1.build	= 1381;
> -	level1.major	= 2;
> -	level1.minor	= 0;
> -	level1.processor = 0;
> +	werror = spoolss_init_spoolss_UserLevel1(mem_ctx,
> +						 cli_credentials_get_username(creds),
> +						 &level1);
> +	if (!W_ERROR_IS_OK(werror)) {
> +		return werror;
> +	}
>  
>  	userlevel_ctr.level = 1;
>  	userlevel_ctr.user_info.level1 = &level1;
> @@ -229,14 +228,12 @@ WERROR rpccli_spoolss_addprinterex(struct rpc_pipe_client *cli,
>  	ZERO_STRUCT(devmode_ctr);
>  	ZERO_STRUCT(secdesc_ctr);
>  
> -	level1.size		= 28;
> -	level1.build		= 1381;
> -	level1.major		= 2;
> -	level1.minor		= 0;
> -	level1.processor	= 0;
> -	level1.client		= talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
> -	W_ERROR_HAVE_NO_MEMORY(level1.client);
> -	level1.user	        = cli_credentials_get_username(creds);
> +	result = spoolss_init_spoolss_UserLevel1(mem_ctx,
> +						 cli_credentials_get_username(creds),
> +						 &level1);
> +	if (!W_ERROR_IS_OK(result)) {
> +		return result;
> +	}
>  
>  	userlevel_ctr.level = 1;
>  	userlevel_ctr.user_info.level1 = &level1;
> diff --git a/source3/rpc_client/init_spoolss.c b/source3/rpc_client/init_spoolss.c
> index 9a4dab6d417..1996465ee9f 100644
> --- a/source3/rpc_client/init_spoolss.c
> +++ b/source3/rpc_client/init_spoolss.c
> @@ -446,3 +446,33 @@ const char *spoolss_get_short_filesys_environment(const char *environment)
>  		return NULL;
>  	}
>  }
> +
> +#define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 2
> +#define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 0
> +#define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 1381
> +
> +WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
> +				       const char *username,
> +				       struct spoolss_UserLevel1 *r)
> +{
> +	ZERO_STRUCTP(r);
> +
> +	r->size		= 28;
> +	r->client	= talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
> +	W_ERROR_HAVE_NO_MEMORY(r->client);
> +	r->user		= talloc_strdup(mem_ctx, username);
> +	W_ERROR_HAVE_NO_MEMORY(r->user);
> +	r->processor	= 0;
> +
> +	r->major	= lp_parm_int(GLOBAL_SECTION_SNUM,
> +				      "spoolss_client", "os_major",
> +				      GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT);
> +	r->minor	= lp_parm_int(GLOBAL_SECTION_SNUM,
> +				      "spoolss_client", "os_minor",
> +				      GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT);
> +	r->build	= lp_parm_int(GLOBAL_SECTION_SNUM,
> +				      "spoolss_client", "os_build",
> +				      GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT);
> +
> +	return WERR_OK;
> +}
> diff --git a/source3/rpc_client/init_spoolss.h b/source3/rpc_client/init_spoolss.h
> index 376eaefe914..062e37b97e4 100644
> --- a/source3/rpc_client/init_spoolss.h
> +++ b/source3/rpc_client/init_spoolss.h
> @@ -48,5 +48,8 @@ WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
>  WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
>  				      struct spoolss_security_descriptor **secdesc);
>  const char *spoolss_get_short_filesys_environment(const char *environment);
> +WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
> +				       const char *username,
> +				       struct spoolss_UserLevel1 *r);
>  
>  #endif /* _RPC_CLIENT_INIT_SPOOLSS_H_ */
> -- 
> 2.17.1
> 
> 
> From 17f07f368ae6ef759431c87aae0a50a610a29623 Mon Sep 17 00:00:00 2001
> From: Justin Stephenson <jstephen at redhat.com>
> Date: Fri, 31 Aug 2018 13:28:58 -0400
> Subject: [PATCH 2/6] s3-rpc_client: Advertise Windows 7 client info
> 
> Client printing operations currently fail against Windows
> Server 2016 with Access Denied if a client os build number
> lower than 6000 is advertised. Increase the default build number,
> major, and minor versions to values associated with client
> OS versoins Windows 7 and Windows Server 2008 R2.
> 
> The build number value specifically needs to be increased to
> allow these operations to succeed.
> 
> BUG: https://bugzilla.samba.org/show_bug.cgi?id=13597
> 
> Signed-off-by: Justin Stephenson <jstephen at redhat.com>
> ---
>  source3/rpc_client/init_spoolss.c | 7 ++++---
>  1 file changed, 4 insertions(+), 3 deletions(-)
> 
> diff --git a/source3/rpc_client/init_spoolss.c b/source3/rpc_client/init_spoolss.c
> index 1996465ee9f..c341b82b6ee 100644
> --- a/source3/rpc_client/init_spoolss.c
> +++ b/source3/rpc_client/init_spoolss.c
> @@ -447,9 +447,10 @@ const char *spoolss_get_short_filesys_environment(const char *environment)
>  	}
>  }
>  
> -#define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 2
> -#define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 0
> -#define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 1381
> +/* Windows 7 and Windows Server 2008 R2 */
> +#define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 6
> +#define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 1
> +#define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 7007
>  
>  WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
>  				       const char *username,
> -- 
> 2.17.1
> 
> 
> From 20cd8658a67d0de3cece4f2346dcccc747fe9c68 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?G=C3=BCnther=20Deschner?= <gd at samba.org>
> Date: Fri, 31 Aug 2018 18:22:04 +0200
> Subject: [PATCH 3/6] s3-rpcclient: Use spoolss_init_spoolss_UserLevel1 in
>  winspool cmds
> 
> Use spoolss initialization function to set client version information for
> iremotewinspool printer operations
> 
> Signed-off-by: Guenther Deschner <gd at samba.org>
> ---
>  source3/rpcclient/cmd_iremotewinspool.c | 16 +++++++++-------
>  1 file changed, 9 insertions(+), 7 deletions(-)
> 
> diff --git a/source3/rpcclient/cmd_iremotewinspool.c b/source3/rpcclient/cmd_iremotewinspool.c
> index c6148ec02c7..7f0cecfaf01 100644
> --- a/source3/rpcclient/cmd_iremotewinspool.c
> +++ b/source3/rpcclient/cmd_iremotewinspool.c
> @@ -24,6 +24,7 @@
>  #include "libsmb/libsmb.h"
>  #include "auth/gensec/gensec.h"
>  #include "auth/credentials/credentials.h"
> +#include "rpc_client/init_spoolss.h"
>  
>  /****************************************************************************
>  ****************************************************************************/
> @@ -33,6 +34,7 @@ static WERROR cmd_iremotewinspool_async_open_printer(struct rpc_pipe_client *cli
>  						     int argc, const char **argv)
>  {
>  	NTSTATUS status;
> +	WERROR werror;
>  	struct policy_handle hnd;
>  	struct spoolss_DevmodeContainer devmode_ctr;
>  	struct spoolss_UserLevelCtr client_info_ctr;
> @@ -59,13 +61,13 @@ static WERROR cmd_iremotewinspool_async_open_printer(struct rpc_pipe_client *cli
>  
>  	ZERO_STRUCT(devmode_ctr);
>  
> -	level1.size	= 40;
> -	level1.client	= talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
> -	W_ERROR_HAVE_NO_MEMORY(level1.client);
> -	level1.user	= cli_credentials_get_username(creds);
> -	level1.build	= 1381;
> -	level1.major	= 3;
> -	level1.minor	= 0;
> +        werror = spoolss_init_spoolss_UserLevel1(mem_ctx,
> +						 cli_credentials_get_username(creds),
> +						 &level1);
> +	if (!W_ERROR_IS_OK(werror)) {
> +		return werror;
> +	}
> +
>  	level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
>  
>  	client_info_ctr.level = 1;
> -- 
> 2.17.1
> 
> 
> From 287042d69db658c637de22050f79686184c8820d Mon Sep 17 00:00:00 2001
> From: Justin Stephenson <jstephen at redhat.com>
> Date: Wed, 15 Aug 2018 11:10:21 -0400
> Subject: [PATCH 4/6] iremotewinspool-tests: Allow modification of OS client
>  version information
> 
> Add test_get_client_info() function to set and, or modify the client OS
> version values advertised in the iremotewinspool torture tests.
> 
> The OS build numbers are used from the table in:
> 
>   [MS-RPRN] <168> Section 2.2.3.10.1
> 
> Signed-off-by: Justin Stephenson <jstephen at redhat.com>
> ---
>  source4/torture/rpc/iremotewinspool.c | 86 ++++++++++++++++++++++-----
>  1 file changed, 72 insertions(+), 14 deletions(-)
> 
> diff --git a/source4/torture/rpc/iremotewinspool.c b/source4/torture/rpc/iremotewinspool.c
> index d419e9c082b..d80f2f74c65 100644
> --- a/source4/torture/rpc/iremotewinspool.c
> +++ b/source4/torture/rpc/iremotewinspool.c
> @@ -33,31 +33,77 @@ struct test_iremotewinspool_context {
>  	const char *environment;
>  };
>  
> +enum client_os_version
> +{
> +	WIN_2000,
> +	WIN_VISTA,
> +	WIN_SERVER_2008,
> +	WIN_7,
> +	WIN_SERVER_2008R2,
> +	WIN_8,
> +	WIN_SERVER_2012,
> +	WIN_10,
> +	WIN_SERVER_2016
> +};
> +
> +static struct spoolss_UserLevel1 test_get_client_info(struct torture_context *tctx,
> +						      enum client_os_version os,
> +						      enum spoolss_MajorVersion major_number,
> +						      enum spoolss_MinorVersion minor_number)
> +{
> +	struct spoolss_UserLevel1 level1;
> +
> +	level1.size	= 28;
> +	level1.client	= talloc_asprintf(tctx, "\\\\%s", "mthelena");
> +	level1.user	= "GD";
> +	level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
> +	level1.major	= major_number;
> +	level1.minor	= minor_number;
> +
> +	switch (os) {
> +		case WIN_SERVER_2016:
> +		case WIN_10:
> +			level1.build = 10586;
> +			break;
> +		case WIN_SERVER_2012:
> +		case WIN_8:
> +			level1.build = 9200;
> +			break;
> +		case WIN_SERVER_2008R2:
> +		case WIN_7:
> +			level1.build = 7007;
> +			break;
> +		case WIN_SERVER_2008:
> +		case WIN_VISTA:
> +			level1.build = 6000;
> +			break;
> +		case WIN_2000:
> +			level1.build = 1382;
> +			break;
> +		default:
> +			level1.build = 7007;
> +	}
> +
> +	return level1;
> +}
> +
>  static bool test_AsyncOpenPrinter_byprinter(struct torture_context *tctx,
>  					    struct test_iremotewinspool_context *ctx,
>  					    struct dcerpc_pipe *p,
>  					    const char *printer_name,
> +					    struct spoolss_UserLevel1 cinfo,
>  					    struct policy_handle *handle)
>  {
>  	struct dcerpc_binding_handle *b = p->binding_handle;
>  	struct spoolss_DevmodeContainer devmode_ctr;
>  	struct spoolss_UserLevelCtr client_info_ctr;
> -	struct spoolss_UserLevel1 level1;
>  	uint32_t access_mask = SERVER_ALL_ACCESS;
>  	struct winspool_AsyncOpenPrinter r;
>  
>  	ZERO_STRUCT(devmode_ctr);
>  
> -	level1.size	= 28;
> -	level1.client	= talloc_asprintf(tctx, "\\\\%s", "mthelena");
> -	level1.user	= "GD";
> -	level1.build	= 1381;
> -	level1.major	= 3;
> -	level1.minor	= 0;
> -	level1.processor = PROCESSOR_ARCHITECTURE_AMD64;
> -
>  	client_info_ctr.level = 1;
> -	client_info_ctr.user_info.level1 = &level1;
> +	client_info_ctr.user_info.level1 = &cinfo;
>  
>  	r.in.pPrinterName	= printer_name;
>  	r.in.pDatatype		= NULL;
> @@ -196,6 +242,7 @@ static bool torture_rpc_iremotewinspool_setup_common(struct torture_context *tct
>  						     struct test_iremotewinspool_context *t)
>  {
>  	const char *printer_name;
> +	struct spoolss_UserLevel1 client_info;
>  	struct dcerpc_binding *binding;
>  
>  	torture_assert_ntstatus_ok(tctx,
> @@ -216,10 +263,12 @@ static bool torture_rpc_iremotewinspool_setup_common(struct torture_context *tct
>  
>  	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(t->iremotewinspool_pipe));
>  
> +	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +
>  	torture_assert(tctx,
>  		test_AsyncOpenPrinter_byprinter(tctx, t,
>  						t->iremotewinspool_pipe, printer_name,
> -						&t->server_handle),
> +						client_info, &t->server_handle),
>  						"failed to open printserver");
>  	torture_assert(tctx,
>  		test_get_environment(tctx,
> @@ -269,12 +318,15 @@ static bool test_AsyncClosePrinter(struct torture_context *tctx,
>  
>  	struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
>  	const char *printer_name;
> +	struct spoolss_UserLevel1 client_info;
>  	struct policy_handle handle;
>  
>  	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
>  
> +	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +
>  	torture_assert(tctx,
> -		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, &handle),
> +		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
>  		"failed to test AsyncOpenPrinter");
>  
>  	torture_assert(tctx,
> @@ -292,12 +344,15 @@ static bool test_AsyncOpenPrinter(struct torture_context *tctx,
>  
>  	struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
>  	const char *printer_name;
> +	struct spoolss_UserLevel1 client_info;
>  	struct policy_handle handle;
>  
>  	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
>  
> +	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +
>  	torture_assert(tctx,
> -		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, &handle),
> +		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
>  		"failed to test AsyncOpenPrinter");
>  
>  	test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle);
> @@ -871,6 +926,7 @@ static bool test_OpenPrinter(struct torture_context *tctx,
>  	struct policy_handle handle;
>  	struct dcerpc_pipe *s;
>  	struct dcerpc_binding *binding;
> +	struct spoolss_UserLevel1 client_info;
>  	struct spoolss_ClosePrinter r;
>  
>  	torture_assert_ntstatus_ok(tctx,
> @@ -891,8 +947,10 @@ static bool test_OpenPrinter(struct torture_context *tctx,
>  
>  	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
>  
> +	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +
>  	torture_assert(tctx,
> -		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, &handle),
> +		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
>  		"failed to open printserver via winspool");
>  
>  
> -- 
> 2.17.1
> 
> 
> From 1c5cc7a4f98e6833a2d293fa40480751a1f72dfa Mon Sep 17 00:00:00 2001
> From: Justin Stephenson <jstephen at redhat.com>
> Date: Wed, 22 Aug 2018 13:23:18 -0400
> Subject: [PATCH 5/6] iremotewinspool-tests: Add client os build number
>  validation test
> 
> Add test validating the AsyncOpenPrinter result based on the provided
> client info build number
> 
> Signed-off-by: Justin Stephenson <jstephen at redhat.com>
> ---
>  source4/torture/rpc/iremotewinspool.c | 65 +++++++++++++++++++++++++++
>  1 file changed, 65 insertions(+)
> 
> diff --git a/source4/torture/rpc/iremotewinspool.c b/source4/torture/rpc/iremotewinspool.c
> index d80f2f74c65..805f46c8b89 100644
> --- a/source4/torture/rpc/iremotewinspool.c
> +++ b/source4/torture/rpc/iremotewinspool.c
> @@ -360,6 +360,70 @@ static bool test_AsyncOpenPrinter(struct torture_context *tctx,
>  	return true;
>  }
>  
> +/*
> + * Validate the result of AsyncOpenPrinter calls based on client info
> + * build number. Windows Server 2016 rejects an advertised build
> + * number less than 6000(Windows Vista and Windows Server 2008, or older)
> + */
> +static bool test_AsyncOpenPrinterValidateBuildNumber(struct torture_context *tctx,
> +						     void *private_data)
> +{
> +	struct test_iremotewinspool_context *ctx =
> +		talloc_get_type_abort(private_data, struct test_iremotewinspool_context);
> +
> +	struct dcerpc_pipe *p = ctx->iremotewinspool_pipe;
> +	const char *printer_name;
> +	struct spoolss_UserLevel1 client_info;
> +	struct policy_handle handle;
> +	struct dcerpc_binding_handle *b = p->binding_handle;
> +	struct spoolss_DevmodeContainer devmode_ctr;
> +	struct spoolss_UserLevelCtr client_info_ctr = {
> +		.level = 1,
> +	};
> +	uint32_t access_mask = SERVER_ALL_ACCESS;
> +	struct winspool_AsyncOpenPrinter r;
> +	NTSTATUS status;
> +	bool ok = false;
> +
> +	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
> +	torture_assert_not_null(tctx, printer_name, "Cannot allocate memory");
> +
> +	/* fail with Windows 2000 build number */
> +	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +
> +	ZERO_STRUCT(devmode_ctr);
> +
> +	client_info_ctr.user_info.level1 = &client_info;
> +
> +	r.in.pPrinterName	= printer_name;
> +	r.in.pDatatype		= NULL;
> +	r.in.pDevModeContainer	= &devmode_ctr;
> +	r.in.AccessRequired	= access_mask;
> +	r.in.pClientInfo	= &client_info_ctr;
> +	r.out.pHandle		= &handle;
> +
> +	status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
> +	torture_assert_ntstatus_ok(tctx, status, "AsyncOpenPrinter failed");
> +	torture_assert_werr_equal(tctx, r.out.result, WERR_ACCESS_DENIED,
> +		"AsyncOpenPrinter should have failed");
> +
> +	/* succeed with Windows 7 build number */
> +	client_info = test_get_client_info(tctx, WIN_7, 3, SPOOLSS_MINOR_VERSION_0);
> +	client_info_ctr.user_info.level1 = &client_info;
> +	r.in.pClientInfo	= &client_info_ctr;
> +
> +	status = dcerpc_winspool_AsyncOpenPrinter_r(b, tctx, &r);
> +	torture_assert_ntstatus_ok(tctx, status, "AsyncOpenPrinter failed");
> +	torture_assert_werr_ok(tctx, r.out.result,
> +		"AsyncOpenPrinter failed");
> +
> +	ok = test_AsyncClosePrinter_byhandle(tctx, ctx, p, &handle);
> +	torture_assert(tctx, ok, "failed to AsyncClosePrinter handle");
> +
> +	return true;
> +
> +}
> +
>  static struct spoolss_NotifyOption *setup_printserver_NotifyOption(struct torture_context *tctx)
>  {
>  	struct spoolss_NotifyOption *o;
> @@ -986,6 +1050,7 @@ struct torture_suite *torture_rpc_iremotewinspool(TALLOC_CTX *mem_ctx)
>  	torture_tcase_add_simple_test(tcase, "AsyncCorePrinterDriverInstalled", test_AsyncCorePrinterDriverInstalled);
>  	torture_tcase_add_simple_test(tcase, "AsyncDeletePrintDriverPackage", test_AsyncDeletePrintDriverPackage);
>  	torture_tcase_add_simple_test(tcase, "AsyncGetPrinterDriverDirectory", test_AsyncGetPrinterDriverDirectory);
> +	torture_tcase_add_simple_test(tcase, "AsyncOpenPrinterValidateBuildNumber", test_AsyncOpenPrinterValidateBuildNumber);
>  
>  	tcase = torture_suite_add_tcase(suite, "handles");
>  
> -- 
> 2.17.1
> 
> 
> From be282e2eba607f56149f445de48e142c5b137013 Mon Sep 17 00:00:00 2001
> From: Justin Stephenson <jstephen at redhat.com>
> Date: Fri, 31 Aug 2018 15:28:36 -0400
> Subject: [PATCH 6/6] spoolss-iremotewinspool-tests: Use more recent client OS
>  version
> 
> Set torture test client info build, major, and minor
> version numbers to Windows 7 and Windows Server 2008 R2 values
> 
>  buildnum: 7007
>  major: 6
>  minor: 1
> 
> Build number taken from
>  [MS-RPRN] <168> Section 2.2.3.10.1
> 
> Major/Minor numbers taken from
>  https://docs.microsoft.com/en-us/windows/desktop/sysinfo/operating-system-version
> 
> Signed-off-by: Justin Stephenson <jstephen at redhat.com>
> ---
>  source4/torture/rpc/iremotewinspool.c | 10 +++++-----
>  source4/torture/rpc/spoolss_access.c  |  7 ++++---
>  2 files changed, 9 insertions(+), 8 deletions(-)
> 
> diff --git a/source4/torture/rpc/iremotewinspool.c b/source4/torture/rpc/iremotewinspool.c
> index 805f46c8b89..b4dbe71160e 100644
> --- a/source4/torture/rpc/iremotewinspool.c
> +++ b/source4/torture/rpc/iremotewinspool.c
> @@ -263,7 +263,7 @@ static bool torture_rpc_iremotewinspool_setup_common(struct torture_context *tct
>  
>  	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(t->iremotewinspool_pipe));
>  
> -	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +	client_info = test_get_client_info(tctx, WIN_7, 6, 1);
>  
>  	torture_assert(tctx,
>  		test_AsyncOpenPrinter_byprinter(tctx, t,
> @@ -323,7 +323,7 @@ static bool test_AsyncClosePrinter(struct torture_context *tctx,
>  
>  	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
>  
> -	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +	client_info = test_get_client_info(tctx, WIN_7, 6, 1);
>  
>  	torture_assert(tctx,
>  		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
> @@ -349,7 +349,7 @@ static bool test_AsyncOpenPrinter(struct torture_context *tctx,
>  
>  	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
>  
> -	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +	client_info = test_get_client_info(tctx, WIN_7, 6, 1);
>  
>  	torture_assert(tctx,
>  		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
> @@ -408,7 +408,7 @@ static bool test_AsyncOpenPrinterValidateBuildNumber(struct torture_context *tct
>  		"AsyncOpenPrinter should have failed");
>  
>  	/* succeed with Windows 7 build number */
> -	client_info = test_get_client_info(tctx, WIN_7, 3, SPOOLSS_MINOR_VERSION_0);
> +	client_info = test_get_client_info(tctx, WIN_7, 6, 1);
>  	client_info_ctr.user_info.level1 = &client_info;
>  	r.in.pClientInfo	= &client_info_ctr;
>  
> @@ -1011,7 +1011,7 @@ static bool test_OpenPrinter(struct torture_context *tctx,
>  
>  	printer_name = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p));
>  
> -	client_info = test_get_client_info(tctx, WIN_2000, 3, SPOOLSS_MINOR_VERSION_0);
> +	client_info = test_get_client_info(tctx, WIN_7, 6, 1);
>  
>  	torture_assert(tctx,
>  		test_AsyncOpenPrinter_byprinter(tctx, ctx, p, printer_name, client_info, &handle),
> diff --git a/source4/torture/rpc/spoolss_access.c b/source4/torture/rpc/spoolss_access.c
> index 28cecf08b14..946b420b60a 100644
> --- a/source4/torture/rpc/spoolss_access.c
> +++ b/source4/torture/rpc/spoolss_access.c
> @@ -74,9 +74,10 @@ static bool test_openprinter_handle(struct torture_context *tctx,
>  	level1.size	= 28;
>  	level1.client	= talloc_asprintf(tctx, "\\\\%s", "smbtorture");
>  	level1.user	= username;
> -	level1.build	= 1381;
> -	level1.major	= 3;
> -	level1.minor	= 0;
> +	/* Windows 7 and Windows Server 2008 R2 */
> +	level1.build	= 7007;
> +	level1.major	= 6;
> +	level1.minor	= 1;
>  	level1.processor= 0;
>  
>  	r.in.printername	= printername;
> -- 
> 2.17.1
> 




More information about the samba-technical mailing list