s3-printing: add spoolss_get_short_filesys_environment function.
[vlendec/samba-autobuild/.git] / source3 / rpc_client / init_spoolss.c
index 736de269478dae790adb25933a923cae0f9947a7..9a4dab6d417176cde4626946b5f203036ad76cec 100644 (file)
  */
 
 #include "includes.h"
-#include "rpc_client/init_spoolss.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"
 
 /*******************************************************************
 ********************************************************************/
@@ -45,19 +48,71 @@ bool init_systemtime(struct spoolss_Time *r,
 
 time_t spoolss_Time_to_time_t(const struct spoolss_Time *r)
 {
-       struct tm unixtime;
-
-       unixtime.tm_year        = r->year - 1900;
-       unixtime.tm_mon         = r->month - 1;
-       unixtime.tm_wday        = r->day_of_week;
-       unixtime.tm_mday        = r->day;
-       unixtime.tm_hour        = r->hour;
-       unixtime.tm_min         = r->minute;
-       unixtime.tm_sec         = r->second;
+       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;
+}
+
 /*******************************************************************
  ********************************************************************/
 
@@ -70,7 +125,7 @@ WERROR pull_spoolss_PrinterData(TALLOC_CTX *mem_ctx,
        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_GENERAL_FAILURE;
+               return WERR_GEN_FAILURE;
        }
        return WERR_OK;
 }
@@ -86,7 +141,7 @@ WERROR push_spoolss_PrinterData(TALLOC_CTX *mem_ctx, DATA_BLOB *blob,
        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_GENERAL_FAILURE;
+               return WERR_GEN_FAILURE;
        }
        return WERR_OK;
 }
@@ -119,3 +174,275 @@ void spoolss_printerinfo2_to_setprinterinfo2(const struct spoolss_PrinterInfo2 *
        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;
+       }
+}