LCOV - code coverage report
Current view: top level - source3/rpc_client - init_spoolss.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 96 257 37.4 %
Date: 2024-04-21 15:09:00 Functions: 5 12 41.7 %

          Line data    Source code
       1             : /*
       2             :  *  Unix SMB/CIFS implementation.
       3             :  *  RPC Pipe client / server routines
       4             :  *  Copyright (C) Guenther Deschner                  2009.
       5             :  *
       6             :  *  This program is free software; you can redistribute it and/or modify
       7             :  *  it under the terms of the GNU General Public License as published by
       8             :  *  the Free Software Foundation; either version 3 of the License, or
       9             :  *  (at your option) any later version.
      10             :  *
      11             :  *  This program is distributed in the hope that it will be useful,
      12             :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  *  GNU General Public License for more details.
      15             :  *
      16             :  *  You should have received a copy of the GNU General Public License
      17             :  *  along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include "includes.h"
      21             : #include "../librpc/gen_ndr/ndr_spoolss.h"
      22             : #include "rpc_client/init_spoolss.h"
      23             : #include "../libcli/security/security.h"
      24             : #include "secrets.h"
      25             : #include "passdb/machine_sid.h"
      26             : 
      27             : /*******************************************************************
      28             : ********************************************************************/
      29             : 
      30         668 : bool init_systemtime(struct spoolss_Time *r,
      31             :                      struct tm *unixtime)
      32             : {
      33         668 :         if (!r || !unixtime) {
      34           0 :                 return false;
      35             :         }
      36             : 
      37         668 :         r->year              = unixtime->tm_year+1900;
      38         668 :         r->month     = unixtime->tm_mon+1;
      39         668 :         r->day_of_week       = unixtime->tm_wday;
      40         668 :         r->day               = unixtime->tm_mday;
      41         668 :         r->hour              = unixtime->tm_hour;
      42         668 :         r->minute    = unixtime->tm_min;
      43         668 :         r->second    = unixtime->tm_sec;
      44         668 :         r->millisecond       = 0;
      45             : 
      46         668 :         return true;
      47             : }
      48             : 
      49           0 : time_t spoolss_Time_to_time_t(const struct spoolss_Time *r)
      50             : {
      51           0 :         struct tm unixtime = {
      52           0 :                 .tm_year        = r->year - 1900,
      53           0 :                 .tm_mon         = r->month - 1,
      54           0 :                 .tm_wday        = r->day_of_week,
      55           0 :                 .tm_mday        = r->day,
      56           0 :                 .tm_hour        = r->hour,
      57           0 :                 .tm_min         = r->minute,
      58           0 :                 .tm_sec         = r->second,
      59             :         };
      60             : 
      61           0 :         return mktime(&unixtime);
      62             : }
      63             : 
      64             : /*******************************************************************
      65             :  ********************************************************************/
      66             : 
      67           0 : bool spoolss_timestr_to_NTTIME(const char *str,
      68             :                                NTTIME *data)
      69             : {
      70           0 :         struct tm tm;
      71           0 :         time_t t;
      72             : 
      73           0 :         if (strequal(str, "01/01/1601")) {
      74           0 :                 *data = 0;
      75           0 :                 return true;
      76             :         }
      77             : 
      78           0 :         ZERO_STRUCT(tm);
      79             : 
      80           0 :         if (sscanf(str, "%d/%d/%d",
      81             :                    &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) {
      82           0 :                 return false;
      83             :         }
      84           0 :         tm.tm_mon -= 1;
      85           0 :         tm.tm_year -= 1900;
      86           0 :         tm.tm_isdst = -1;
      87             : 
      88           0 :         t = mktime(&tm);
      89           0 :         unix_to_nt_time(data, t);
      90             : 
      91           0 :         return true;
      92             : }
      93             : 
      94             : /*******************************************************************
      95             :  ********************************************************************/
      96             : 
      97           0 : bool spoolss_driver_version_to_qword(const char *str,
      98             :                                      uint64_t *data)
      99             : {
     100           0 :         unsigned int v1, v2, v3, v4 = 0;
     101             : 
     102           0 :         if ((sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) &&
     103           0 :             (sscanf(str, "%u.%u.%u", &v1, &v2, &v3) != 3))
     104             :         {
     105           0 :                 return false;
     106             :         }
     107             : 
     108           0 :         *data = ((uint64_t)(v1 & 0xFFFF) << 48) +
     109           0 :                 ((uint64_t)(v2 & 0xFFFF) << 32) +
     110           0 :                 ((uint64_t)(v3 & 0xFFFF) << 16) +
     111           0 :                 (uint64_t)(v4 & 0xFFFF);
     112             : 
     113           0 :         return true;
     114             : }
     115             : 
     116             : /*******************************************************************
     117             :  ********************************************************************/
     118             : 
     119           0 : WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx,
     120             :                                 const DATA_BLOB *blob,
     121             :                                 union spoolss_PrinterData *data,
     122             :                                 enum winreg_Type type)
     123             : {
     124           0 :         enum ndr_err_code ndr_err;
     125           0 :         ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type,
     126             :                         (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData);
     127           0 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     128           0 :                 return WERR_GEN_FAILURE;
     129             :         }
     130           0 :         return WERR_OK;
     131             : }
     132             : 
     133             : /*******************************************************************
     134             :  ********************************************************************/
     135             : 
     136         400 : WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
     137             :                                 enum winreg_Type type,
     138             :                                 union spoolss_PrinterData *data)
     139             : {
     140           0 :         enum ndr_err_code ndr_err;
     141         400 :         ndr_err = ndr_push_union_blob(blob, mem_ctx, data, type,
     142             :                         (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData);
     143         400 :         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
     144           0 :                 return WERR_GEN_FAILURE;
     145             :         }
     146         400 :         return WERR_OK;
     147             : }
     148             : 
     149             : /*******************************************************************
     150             :  ********************************************************************/
     151             : 
     152           0 : void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *i,
     153             :                                              struct spoolss_SetPrinterInfo2 *s)
     154             : {
     155           0 :         s->servername                = i->servername;
     156           0 :         s->printername               = i->printername;
     157           0 :         s->sharename         = i->sharename;
     158           0 :         s->portname          = i->portname;
     159           0 :         s->drivername                = i->drivername;
     160           0 :         s->comment           = i->comment;
     161           0 :         s->location          = i->location;
     162           0 :         s->devmode_ptr               = 0;
     163           0 :         s->sepfile           = i->sepfile;
     164           0 :         s->printprocessor    = i->printprocessor;
     165           0 :         s->datatype          = i->datatype;
     166           0 :         s->parameters                = i->parameters;
     167           0 :         s->secdesc_ptr               = 0;
     168           0 :         s->attributes                = i->attributes;
     169           0 :         s->priority          = i->priority;
     170           0 :         s->defaultpriority   = i->defaultpriority;
     171           0 :         s->starttime         = i->starttime;
     172           0 :         s->untiltime         = i->untiltime;
     173           0 :         s->status            = i->status;
     174           0 :         s->cjobs             = i->cjobs;
     175           0 :         s->averageppm                = i->averageppm;
     176           0 : }
     177             : 
     178             : /****************************************************************************
     179             : ****************************************************************************/
     180             : 
     181           0 : bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
     182             :                               struct spoolss_DriverInfo8 *_info8)
     183             : {
     184           0 :         struct spoolss_DriverInfo8 info8;
     185             : 
     186           0 :         ZERO_STRUCT(info8);
     187             : 
     188           0 :         switch (r->level) {
     189           0 :         case 3:
     190           0 :                 info8.version           = r->info.info3->version;
     191           0 :                 info8.driver_name       = r->info.info3->driver_name;
     192           0 :                 info8.architecture      = r->info.info3->architecture;
     193           0 :                 info8.driver_path       = r->info.info3->driver_path;
     194           0 :                 info8.data_file         = r->info.info3->data_file;
     195           0 :                 info8.config_file       = r->info.info3->config_file;
     196           0 :                 info8.help_file         = r->info.info3->help_file;
     197           0 :                 info8.monitor_name      = r->info.info3->monitor_name;
     198           0 :                 info8.default_datatype  = r->info.info3->default_datatype;
     199           0 :                 if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) {
     200           0 :                         info8.dependent_files   = r->info.info3->dependent_files->string;
     201             :                 }
     202           0 :                 break;
     203           0 :         case 6:
     204           0 :                 info8.version           = r->info.info6->version;
     205           0 :                 info8.driver_name       = r->info.info6->driver_name;
     206           0 :                 info8.architecture      = r->info.info6->architecture;
     207           0 :                 info8.driver_path       = r->info.info6->driver_path;
     208           0 :                 info8.data_file         = r->info.info6->data_file;
     209           0 :                 info8.config_file       = r->info.info6->config_file;
     210           0 :                 info8.help_file         = r->info.info6->help_file;
     211           0 :                 info8.monitor_name      = r->info.info6->monitor_name;
     212           0 :                 info8.default_datatype  = r->info.info6->default_datatype;
     213           0 :                 if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) {
     214           0 :                         info8.dependent_files   = r->info.info6->dependent_files->string;
     215             :                 }
     216           0 :                 info8.driver_date       = r->info.info6->driver_date;
     217           0 :                 info8.driver_version    = r->info.info6->driver_version;
     218           0 :                 info8.manufacturer_name = r->info.info6->manufacturer_name;
     219           0 :                 info8.manufacturer_url  = r->info.info6->manufacturer_url;
     220           0 :                 info8.hardware_id       = r->info.info6->hardware_id;
     221           0 :                 info8.provider          = r->info.info6->provider;
     222           0 :                 break;
     223           0 :         case 8:
     224           0 :                 info8.version           = r->info.info8->version;
     225           0 :                 info8.driver_name       = r->info.info8->driver_name;
     226           0 :                 info8.architecture      = r->info.info8->architecture;
     227           0 :                 info8.driver_path       = r->info.info8->driver_path;
     228           0 :                 info8.data_file         = r->info.info8->data_file;
     229           0 :                 info8.config_file       = r->info.info8->config_file;
     230           0 :                 info8.help_file         = r->info.info8->help_file;
     231           0 :                 info8.monitor_name      = r->info.info8->monitor_name;
     232           0 :                 info8.default_datatype  = r->info.info8->default_datatype;
     233           0 :                 if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) {
     234           0 :                         info8.dependent_files   = r->info.info8->dependent_files->string;
     235             :                 }
     236           0 :                 if (r->info.info8->previous_names && r->info.info8->previous_names->string) {
     237           0 :                         info8.previous_names    = r->info.info8->previous_names->string;
     238             :                 }
     239           0 :                 info8.driver_date       = r->info.info8->driver_date;
     240           0 :                 info8.driver_version    = r->info.info8->driver_version;
     241           0 :                 info8.manufacturer_name = r->info.info8->manufacturer_name;
     242           0 :                 info8.manufacturer_url  = r->info.info8->manufacturer_url;
     243           0 :                 info8.hardware_id       = r->info.info8->hardware_id;
     244           0 :                 info8.provider          = r->info.info8->provider;
     245           0 :                 info8.print_processor   = r->info.info8->print_processor;
     246           0 :                 info8.vendor_setup      = r->info.info8->vendor_setup;
     247           0 :                 if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) {
     248           0 :                         info8.color_profiles = r->info.info8->color_profiles->string;
     249             :                 }
     250           0 :                 info8.inf_path          = r->info.info8->inf_path;
     251           0 :                 info8.printer_driver_attributes = r->info.info8->printer_driver_attributes;
     252           0 :                 if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) {
     253           0 :                         info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string;
     254             :                 }
     255           0 :                 info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date;
     256           0 :                 info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
     257           0 :                 break;
     258           0 :         default:
     259           0 :                 return false;
     260             :         }
     261             : 
     262           0 :         *_info8 = info8;
     263             : 
     264           0 :         return true;
     265             : }
     266             : 
     267             : /****************************************************************************
     268             :  Create and allocate a default devicemode.
     269             : ****************************************************************************/
     270             : 
     271        7082 : WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx,
     272             :                                       const char *devicename,
     273             :                                       struct spoolss_DeviceMode **devmode)
     274             : {
     275           0 :         struct spoolss_DeviceMode *dm;
     276           0 :         char *dname;
     277             : 
     278        7082 :         dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode);
     279        7082 :         if (dm == NULL) {
     280           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     281             :         }
     282             : 
     283        7082 :         dname = talloc_asprintf(dm, "%s", devicename);
     284        7082 :         if (dname == NULL) {
     285           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     286             :         }
     287        7082 :         if (strlen(dname) > MAXDEVICENAME) {
     288          64 :                 dname[MAXDEVICENAME] = '\0';
     289             :         }
     290        7082 :         dm->devicename = dname;
     291             : 
     292        7082 :         dm->formname = talloc_strdup(dm, "Letter");
     293        7082 :         if (dm->formname == NULL) {
     294           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     295             :         }
     296             : 
     297        7082 :         dm->specversion          = DMSPEC_NT4_AND_ABOVE;
     298        7082 :         dm->driverversion        = 0x0400;
     299        7082 :         dm->size                 = 0x00DC;
     300        7082 :         dm->__driverextra_length = 0;
     301        7082 :         dm->fields               = DEVMODE_FORMNAME |
     302             :                                    DEVMODE_TTOPTION |
     303             :                                    DEVMODE_PRINTQUALITY |
     304             :                                    DEVMODE_DEFAULTSOURCE |
     305             :                                    DEVMODE_COPIES |
     306             :                                    DEVMODE_SCALE |
     307             :                                    DEVMODE_PAPERSIZE |
     308             :                                    DEVMODE_ORIENTATION;
     309        7082 :         dm->orientation          = DMORIENT_PORTRAIT;
     310        7082 :         dm->papersize            = DMPAPER_LETTER;
     311        7082 :         dm->paperlength          = 0;
     312        7082 :         dm->paperwidth           = 0;
     313        7082 :         dm->scale                = 0x64;
     314        7082 :         dm->copies               = 1;
     315        7082 :         dm->defaultsource        = DMBIN_FORMSOURCE;
     316        7082 :         dm->printquality         = DMRES_HIGH;           /* 0x0258 */
     317        7082 :         dm->color                = DMRES_MONOCHROME;
     318        7082 :         dm->duplex               = DMDUP_SIMPLEX;
     319        7082 :         dm->yresolution          = 0;
     320        7082 :         dm->ttoption             = DMTT_SUBDEV;
     321        7082 :         dm->collate              = DMCOLLATE_FALSE;
     322        7082 :         dm->icmmethod            = 0;
     323        7082 :         dm->icmintent            = 0;
     324        7082 :         dm->mediatype            = 0;
     325        7082 :         dm->dithertype           = 0;
     326             : 
     327        7082 :         dm->logpixels            = 0;
     328        7082 :         dm->bitsperpel           = 0;
     329        7082 :         dm->pelswidth            = 0;
     330        7082 :         dm->pelsheight           = 0;
     331        7082 :         dm->displayflags         = 0;
     332        7082 :         dm->displayfrequency     = 0;
     333        7082 :         dm->reserved1            = 0;
     334        7082 :         dm->reserved2            = 0;
     335        7082 :         dm->panningwidth         = 0;
     336        7082 :         dm->panningheight        = 0;
     337             : 
     338        7082 :         dm->driverextra_data.data = NULL;
     339        7082 :         dm->driverextra_data.length = 0;
     340             : 
     341        7082 :         *devmode = dm;
     342        7082 :         return WERR_OK;
     343             : }
     344             : 
     345          76 : WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx,
     346             :                                       struct spoolss_security_descriptor **secdesc)
     347             : {
     348           0 :         struct security_ace ace[7];     /* max number of ace entries */
     349          76 :         int i = 0;
     350           0 :         uint32_t sa;
     351          76 :         struct security_acl *psa = NULL;
     352          76 :         struct security_descriptor *psd = NULL;
     353           0 :         struct dom_sid adm_sid;
     354           0 :         size_t sd_size;
     355             : 
     356             :         /* Create an ACE where Everyone is allowed to print */
     357             : 
     358          76 :         sa = PRINTER_ACE_PRINT;
     359          76 :         init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
     360             :                      sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     361             : 
     362             :         /* Add the domain admins group if we are a DC */
     363             : 
     364         152 :         if ( IS_DC ) {
     365           0 :                 struct dom_sid domadmins_sid;
     366             : 
     367          76 :                 sid_compose(&domadmins_sid, get_global_sam_sid(),
     368             :                             DOMAIN_RID_ADMINS);
     369             : 
     370          76 :                 sa = PRINTER_ACE_FULL_CONTROL;
     371          76 :                 init_sec_ace(&ace[i++], &domadmins_sid,
     372             :                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
     373             :                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
     374          76 :                 init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
     375             :                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     376             :         }
     377           0 :         else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
     378           0 :                 sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
     379             : 
     380           0 :                 sa = PRINTER_ACE_FULL_CONTROL;
     381           0 :                 init_sec_ace(&ace[i++], &adm_sid,
     382             :                         SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
     383             :                         SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
     384           0 :                 init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
     385             :                         sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     386             :         }
     387             : 
     388             :         /* add BUILTIN\Administrators as FULL CONTROL */
     389             : 
     390          76 :         sa = PRINTER_ACE_FULL_CONTROL;
     391          76 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
     392             :                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
     393             :                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
     394          76 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
     395             :                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     396             :                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     397             : 
     398             :         /* add BUILTIN\Print Operators as FULL CONTROL */
     399             : 
     400          76 :         sa = PRINTER_ACE_FULL_CONTROL;
     401          76 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
     402             :                 SEC_ACE_TYPE_ACCESS_ALLOWED, sa,
     403             :                 SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
     404          76 :         init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators,
     405             :                 SEC_ACE_TYPE_ACCESS_ALLOWED,
     406             :                 sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
     407             : 
     408             :         /* Make the security descriptor owned by the BUILTIN\Administrators */
     409             : 
     410             :         /* The ACL revision number in rpc_secdesc.h differs from the one
     411             :            created by NT when setting ACE entries in printer
     412             :            descriptors.  NT4 complains about the property being edited by a
     413             :            NT5 machine. */
     414             : 
     415          76 :         if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
     416          76 :                 psd = make_sec_desc(mem_ctx,
     417             :                                     SD_REVISION,
     418             :                                     SEC_DESC_SELF_RELATIVE,
     419             :                                     &global_sid_Builtin_Administrators,
     420             :                                     &global_sid_Builtin_Administrators,
     421             :                                     NULL,
     422             :                                     psa,
     423             :                                     &sd_size);
     424             :         }
     425             : 
     426          76 :         if (psd == NULL) {
     427           0 :                 DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n"));
     428           0 :                 return WERR_NOT_ENOUGH_MEMORY;
     429             :         }
     430             : 
     431          76 :         DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
     432             :                  (unsigned int)sd_size));
     433             : 
     434          76 :         *secdesc = psd;
     435             : 
     436          76 :         return WERR_OK;
     437             : }
     438             : 
     439           0 : const char *spoolss_get_short_filesys_environment(const char *environment)
     440             : {
     441           0 :         if (strequal(environment, SPOOLSS_ARCHITECTURE_x64)) {
     442           0 :                 return "amd64";
     443           0 :         } else if (strequal(environment, SPOOLSS_ARCHITECTURE_NT_X86)) {
     444           0 :                 return "x86";
     445             :         } else {
     446           0 :                 return NULL;
     447             :         }
     448             : }
     449             : 
     450             : /* Windows 7 and Windows Server 2008 R2 */
     451             : #define GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT 6
     452             : #define GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT 1
     453             : #define GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT 7007
     454             : 
     455           6 : WERROR spoolss_init_spoolss_UserLevel1(TALLOC_CTX *mem_ctx,
     456             :                                        const char *username,
     457             :                                        struct spoolss_UserLevel1 *r)
     458             : {
     459           6 :         ZERO_STRUCTP(r);
     460             : 
     461           6 :         r->size              = 28;
     462           6 :         r->client    = talloc_asprintf(mem_ctx, "\\\\%s", lp_netbios_name());
     463           6 :         W_ERROR_HAVE_NO_MEMORY(r->client);
     464           6 :         r->user              = talloc_strdup(mem_ctx, username);
     465           6 :         W_ERROR_HAVE_NO_MEMORY(r->user);
     466           6 :         r->processor = 0;
     467             : 
     468           6 :         r->major     = lp_parm_int(GLOBAL_SECTION_SNUM,
     469             :                                       "spoolss_client", "os_major",
     470             :                                       GLOBAL_SPOOLSS_CLIENT_OS_MAJOR_DEFAULT);
     471           6 :         r->minor     = lp_parm_int(GLOBAL_SECTION_SNUM,
     472             :                                       "spoolss_client", "os_minor",
     473             :                                       GLOBAL_SPOOLSS_CLIENT_OS_MINOR_DEFAULT);
     474           6 :         r->build     = lp_parm_int(GLOBAL_SECTION_SNUM,
     475             :                                       "spoolss_client", "os_build",
     476             :                                       GLOBAL_SPOOLSS_CLIENT_OS_BUILD_DEFAULT);
     477             : 
     478           6 :         return WERR_OK;
     479             : }

Generated by: LCOV version 1.14