diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-05 17:47:29 +0000 |
commit | 4f5791ebd03eaec1c7da0865a383175b05102712 (patch) | |
tree | 8ce7b00f7a76baa386372422adebbe64510812d4 /source3/rpc_client/init_spoolss.c | |
parent | Initial commit. (diff) | |
download | samba-upstream.tar.xz samba-upstream.zip |
Adding upstream version 2:4.17.12+dfsg.upstream/2%4.17.12+dfsgupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'source3/rpc_client/init_spoolss.c')
-rw-r--r-- | source3/rpc_client/init_spoolss.c | 479 |
1 files changed, 479 insertions, 0 deletions
diff --git a/source3/rpc_client/init_spoolss.c b/source3/rpc_client/init_spoolss.c new file mode 100644 index 0000000..c341b82 --- /dev/null +++ b/source3/rpc_client/init_spoolss.c @@ -0,0 +1,479 @@ +/* + * Unix SMB/CIFS implementation. + * RPC Pipe client / server routines + * Copyright (C) Guenther Deschner 2009. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#include "includes.h" +#include "../librpc/gen_ndr/ndr_spoolss.h" +#include "rpc_client/init_spoolss.h" +#include "../libcli/security/security.h" +#include "secrets.h" +#include "passdb/machine_sid.h" + +/******************************************************************* +********************************************************************/ + +bool init_systemtime(struct spoolss_Time *r, + struct tm *unixtime) +{ + if (!r || !unixtime) { + return false; + } + + r->year = unixtime->tm_year+1900; + r->month = unixtime->tm_mon+1; + r->day_of_week = unixtime->tm_wday; + r->day = unixtime->tm_mday; + r->hour = unixtime->tm_hour; + r->minute = unixtime->tm_min; + r->second = unixtime->tm_sec; + r->millisecond = 0; + + return true; +} + +time_t spoolss_Time_to_time_t(const struct spoolss_Time *r) +{ + struct tm unixtime = { + .tm_year = r->year - 1900, + .tm_mon = r->month - 1, + .tm_wday = r->day_of_week, + .tm_mday = r->day, + .tm_hour = r->hour, + .tm_min = r->minute, + .tm_sec = r->second, + }; + + return mktime(&unixtime); +} + +/******************************************************************* + ********************************************************************/ + +bool spoolss_timestr_to_NTTIME(const char *str, + NTTIME *data) +{ + struct tm tm; + time_t t; + + if (strequal(str, "01/01/1601")) { + *data = 0; + return true; + } + + ZERO_STRUCT(tm); + + if (sscanf(str, "%d/%d/%d", + &tm.tm_mon, &tm.tm_mday, &tm.tm_year) != 3) { + return false; + } + tm.tm_mon -= 1; + tm.tm_year -= 1900; + tm.tm_isdst = -1; + + t = mktime(&tm); + unix_to_nt_time(data, t); + + return true; +} + +/******************************************************************* + ********************************************************************/ + +bool spoolss_driver_version_to_qword(const char *str, + uint64_t *data) +{ + unsigned int v1, v2, v3, v4 = 0; + + if ((sscanf(str, "%u.%u.%u.%u", &v1, &v2, &v3, &v4) != 4) && + (sscanf(str, "%u.%u.%u", &v1, &v2, &v3) != 3)) + { + return false; + } + + *data = ((uint64_t)(v1 & 0xFFFF) << 48) + + ((uint64_t)(v2 & 0xFFFF) << 32) + + ((uint64_t)(v3 & 0xFFFF) << 16) + + (uint64_t)(v4 & 0xFFFF); + + return true; +} + +/******************************************************************* + ********************************************************************/ + +WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx, + const DATA_BLOB *blob, + union spoolss_PrinterData *data, + enum winreg_Type type) +{ + enum ndr_err_code ndr_err; + ndr_err = ndr_pull_union_blob(blob, mem_ctx, data, type, + (ndr_pull_flags_fn_t)ndr_pull_spoolss_PrinterData); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_GEN_FAILURE; + } + return WERR_OK; +} + +/******************************************************************* + ********************************************************************/ + +WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob, + enum winreg_Type type, + union spoolss_PrinterData *data) +{ + enum ndr_err_code ndr_err; + ndr_err = ndr_push_union_blob(blob, mem_ctx, data, type, + (ndr_push_flags_fn_t)ndr_push_spoolss_PrinterData); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + return WERR_GEN_FAILURE; + } + return WERR_OK; +} + +/******************************************************************* + ********************************************************************/ + +void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *i, + struct spoolss_SetPrinterInfo2 *s) +{ + s->servername = i->servername; + s->printername = i->printername; + s->sharename = i->sharename; + s->portname = i->portname; + s->drivername = i->drivername; + s->comment = i->comment; + s->location = i->location; + s->devmode_ptr = 0; + s->sepfile = i->sepfile; + s->printprocessor = i->printprocessor; + s->datatype = i->datatype; + s->parameters = i->parameters; + s->secdesc_ptr = 0; + s->attributes = i->attributes; + s->priority = i->priority; + s->defaultpriority = i->defaultpriority; + s->starttime = i->starttime; + s->untiltime = i->untiltime; + s->status = i->status; + s->cjobs = i->cjobs; + s->averageppm = i->averageppm; +} + +/**************************************************************************** +****************************************************************************/ + +bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r, + struct spoolss_DriverInfo8 *_info8) +{ + struct spoolss_DriverInfo8 info8; + + ZERO_STRUCT(info8); + + switch (r->level) { + case 3: + info8.version = r->info.info3->version; + info8.driver_name = r->info.info3->driver_name; + info8.architecture = r->info.info3->architecture; + info8.driver_path = r->info.info3->driver_path; + info8.data_file = r->info.info3->data_file; + info8.config_file = r->info.info3->config_file; + info8.help_file = r->info.info3->help_file; + info8.monitor_name = r->info.info3->monitor_name; + info8.default_datatype = r->info.info3->default_datatype; + if (r->info.info3->dependent_files && r->info.info3->dependent_files->string) { + info8.dependent_files = r->info.info3->dependent_files->string; + } + break; + case 6: + info8.version = r->info.info6->version; + info8.driver_name = r->info.info6->driver_name; + info8.architecture = r->info.info6->architecture; + info8.driver_path = r->info.info6->driver_path; + info8.data_file = r->info.info6->data_file; + info8.config_file = r->info.info6->config_file; + info8.help_file = r->info.info6->help_file; + info8.monitor_name = r->info.info6->monitor_name; + info8.default_datatype = r->info.info6->default_datatype; + if (r->info.info6->dependent_files && r->info.info6->dependent_files->string) { + info8.dependent_files = r->info.info6->dependent_files->string; + } + info8.driver_date = r->info.info6->driver_date; + info8.driver_version = r->info.info6->driver_version; + info8.manufacturer_name = r->info.info6->manufacturer_name; + info8.manufacturer_url = r->info.info6->manufacturer_url; + info8.hardware_id = r->info.info6->hardware_id; + info8.provider = r->info.info6->provider; + break; + case 8: + info8.version = r->info.info8->version; + info8.driver_name = r->info.info8->driver_name; + info8.architecture = r->info.info8->architecture; + info8.driver_path = r->info.info8->driver_path; + info8.data_file = r->info.info8->data_file; + info8.config_file = r->info.info8->config_file; + info8.help_file = r->info.info8->help_file; + info8.monitor_name = r->info.info8->monitor_name; + info8.default_datatype = r->info.info8->default_datatype; + if (r->info.info8->dependent_files && r->info.info8->dependent_files->string) { + info8.dependent_files = r->info.info8->dependent_files->string; + } + if (r->info.info8->previous_names && r->info.info8->previous_names->string) { + info8.previous_names = r->info.info8->previous_names->string; + } + info8.driver_date = r->info.info8->driver_date; + info8.driver_version = r->info.info8->driver_version; + info8.manufacturer_name = r->info.info8->manufacturer_name; + info8.manufacturer_url = r->info.info8->manufacturer_url; + info8.hardware_id = r->info.info8->hardware_id; + info8.provider = r->info.info8->provider; + info8.print_processor = r->info.info8->print_processor; + info8.vendor_setup = r->info.info8->vendor_setup; + if (r->info.info8->color_profiles && r->info.info8->color_profiles->string) { + info8.color_profiles = r->info.info8->color_profiles->string; + } + info8.inf_path = r->info.info8->inf_path; + info8.printer_driver_attributes = r->info.info8->printer_driver_attributes; + if (r->info.info8->core_driver_dependencies && r->info.info8->core_driver_dependencies->string) { + info8.core_driver_dependencies = r->info.info8->core_driver_dependencies->string; + } + info8.min_inbox_driver_ver_date = r->info.info8->min_inbox_driver_ver_date; + info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version; + break; + default: + return false; + } + + *_info8 = info8; + + return true; +} + +/**************************************************************************** + Create and allocate a default devicemode. +****************************************************************************/ + +WERROR spoolss_create_default_devmode(TALLOC_CTX *mem_ctx, + const char *devicename, + struct spoolss_DeviceMode **devmode) +{ + struct spoolss_DeviceMode *dm; + char *dname; + + dm = talloc_zero(mem_ctx, struct spoolss_DeviceMode); + if (dm == NULL) { + return WERR_NOT_ENOUGH_MEMORY; + } + + dname = talloc_asprintf(dm, "%s", devicename); + if (dname == NULL) { + return WERR_NOT_ENOUGH_MEMORY; + } + if (strlen(dname) > MAXDEVICENAME) { + dname[MAXDEVICENAME] = '\0'; + } + dm->devicename = dname; + + dm->formname = talloc_strdup(dm, "Letter"); + if (dm->formname == NULL) { + return WERR_NOT_ENOUGH_MEMORY; + } + + dm->specversion = DMSPEC_NT4_AND_ABOVE; + dm->driverversion = 0x0400; + dm->size = 0x00DC; + dm->__driverextra_length = 0; + dm->fields = DEVMODE_FORMNAME | + DEVMODE_TTOPTION | + DEVMODE_PRINTQUALITY | + DEVMODE_DEFAULTSOURCE | + DEVMODE_COPIES | + DEVMODE_SCALE | + DEVMODE_PAPERSIZE | + DEVMODE_ORIENTATION; + dm->orientation = DMORIENT_PORTRAIT; + dm->papersize = DMPAPER_LETTER; + dm->paperlength = 0; + dm->paperwidth = 0; + dm->scale = 0x64; + dm->copies = 1; + dm->defaultsource = DMBIN_FORMSOURCE; + dm->printquality = DMRES_HIGH; /* 0x0258 */ + dm->color = DMRES_MONOCHROME; + dm->duplex = DMDUP_SIMPLEX; + dm->yresolution = 0; + dm->ttoption = DMTT_SUBDEV; + dm->collate = DMCOLLATE_FALSE; + dm->icmmethod = 0; + dm->icmintent = 0; + dm->mediatype = 0; + dm->dithertype = 0; + + dm->logpixels = 0; + dm->bitsperpel = 0; + dm->pelswidth = 0; + dm->pelsheight = 0; + dm->displayflags = 0; + dm->displayfrequency = 0; + dm->reserved1 = 0; + dm->reserved2 = 0; + dm->panningwidth = 0; + dm->panningheight = 0; + + dm->driverextra_data.data = NULL; + dm->driverextra_data.length = 0; + + *devmode = dm; + return WERR_OK; +} + +WERROR spoolss_create_default_secdesc(TALLOC_CTX *mem_ctx, + struct spoolss_security_descriptor **secdesc) +{ + struct security_ace ace[7]; /* max number of ace entries */ + int i = 0; + uint32_t sa; + struct security_acl *psa = NULL; + struct security_descriptor *psd = NULL; + struct dom_sid adm_sid; + size_t sd_size; + + /* Create an ACE where Everyone is allowed to print */ + + sa = PRINTER_ACE_PRINT; + init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + + /* Add the domain admins group if we are a DC */ + + if ( IS_DC ) { + struct dom_sid domadmins_sid; + + sid_compose(&domadmins_sid, get_global_sam_sid(), + DOMAIN_RID_ADMINS); + + sa = PRINTER_ACE_FULL_CONTROL; + init_sec_ace(&ace[i++], &domadmins_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, sa, + SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); + init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + } + else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) { + sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR); + + sa = PRINTER_ACE_FULL_CONTROL; + init_sec_ace(&ace[i++], &adm_sid, + SEC_ACE_TYPE_ACCESS_ALLOWED, sa, + SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); + init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + } + + /* add BUILTIN\Administrators as FULL CONTROL */ + + sa = PRINTER_ACE_FULL_CONTROL; + init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, + SEC_ACE_TYPE_ACCESS_ALLOWED, sa, + SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); + init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, + SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + + /* add BUILTIN\Print Operators as FULL CONTROL */ + + sa = PRINTER_ACE_FULL_CONTROL; + init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, + SEC_ACE_TYPE_ACCESS_ALLOWED, sa, + SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY); + init_sec_ace(&ace[i++], &global_sid_Builtin_Print_Operators, + SEC_ACE_TYPE_ACCESS_ALLOWED, + sa, SEC_ACE_FLAG_CONTAINER_INHERIT); + + /* Make the security descriptor owned by the BUILTIN\Administrators */ + + /* The ACL revision number in rpc_secdesc.h differs from the one + created by NT when setting ACE entries in printer + descriptors. NT4 complains about the property being edited by a + NT5 machine. */ + + if ((psa = make_sec_acl(mem_ctx, NT4_ACL_REVISION, i, ace)) != NULL) { + psd = make_sec_desc(mem_ctx, + SD_REVISION, + SEC_DESC_SELF_RELATIVE, + &global_sid_Builtin_Administrators, + &global_sid_Builtin_Administrators, + NULL, + psa, + &sd_size); + } + + if (psd == NULL) { + DEBUG(0,("construct_default_printer_sd: Failed to make SEC_DESC.\n")); + return WERR_NOT_ENOUGH_MEMORY; + } + + DEBUG(4,("construct_default_printer_sdb: size = %u.\n", + (unsigned int)sd_size)); + + *secdesc = psd; + + return WERR_OK; +} + +const char *spoolss_get_short_filesys_environment(const char *environment) +{ + if (strequal(environment, SPOOLSS_ARCHITECTURE_x64)) { + return "amd64"; + } else if (strequal(environment, SPOOLSS_ARCHITECTURE_NT_X86)) { + return "x86"; + } else { + return NULL; + } +} + +/* 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, + 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; +} |