s3-registry: only include registry headers when really needed.
[amitay/samba.git] / source3 / printing / nt_printing.c
index 5f5f3445861abfc0c2d4190d2894f12f59b6a2ed..8e8695c20e6583c81de865c347686ada89012c8e 100644 (file)
@@ -20,6 +20,9 @@
  */
 
 #include "includes.h"
+#include "librpc/gen_ndr/messaging.h"
+#include "printing/pcap.h"
+#include "registry.h"
 
 static TDB_CONTEXT *tdb_forms; /* used for forms files */
 static TDB_CONTEXT *tdb_drivers; /* used for driver files */
@@ -402,7 +405,7 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
                return 0;
        }
 
-       if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {
+       if ( !(sd_store = sec_desc_merge_buf( ctx, sd_new, sd_orig )) ) {
                DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
                return 0;
        }
@@ -618,7 +621,7 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
 
        /* of course, none of the message callbacks matter if you don't
           tell messages.c that you interested in receiving PRINT_GENERAL
-          msgs.  This is done in claim_connection() */
+          msgs.  This is done in serverid_register() */
 
 
        if ( lp_security() == SEC_ADS ) {
@@ -918,7 +921,7 @@ bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WER
 
        if (n == *count) {
                DEBUG(10,("delete_a_form, [%s] not found\n", del_name));
-               *ret = WERR_INVALID_PARAM;
+               *ret = WERR_INVALID_FORM_NAME;
                return False;
        }
 
@@ -1315,6 +1318,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
                INTERNAL_OPEN_ONLY,                     /* oplock_request */
                0,                                      /* allocation_size */
+               0,                                      /* private_flags */
                NULL,                                   /* sd */
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
@@ -1367,6 +1371,7 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
                INTERNAL_OPEN_ONLY,                     /* oplock_request */
                0,                                      /* allocation_size */
+               0,                                      /* private_flags */
                NULL,                                   /* sd */
                NULL,                                   /* ea_list */
                &fsp,                                   /* result */
@@ -1524,6 +1529,7 @@ static uint32 get_correct_cversion(struct pipes_struct *p,
                0,                                      /* create_options */
                FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
                INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               0,                                      /* private_flags */
                0,                                      /* allocation_size */
                NULL,                                   /* sd */
                NULL,                                   /* ea_list */
@@ -1602,7 +1608,7 @@ static uint32 get_correct_cversion(struct pipes_struct *p,
 ****************************************************************************/
 
 #define strip_driver_path(_mem_ctx, _element) do { \
-       if ((_p = strrchr((_element), '\\')) != NULL) { \
+       if (_element && ((_p = strrchr((_element), '\\')) != NULL)) { \
                (_element) = talloc_asprintf((_mem_ctx), "%s", _p+1); \
                W_ERROR_HAVE_NO_MEMORY((_element)); \
        } \
@@ -1623,6 +1629,10 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
        WERROR err;
        char *_p;
 
+       if (!*driver_path || !*data_file || !*config_file) {
+               return WERR_INVALID_PARAM;
+       }
+
        /* clean up the driver name.
         * we can get .\driver.dll
         * or worse c:\windows\system\driver.dll !
@@ -1632,7 +1642,9 @@ static WERROR clean_up_driver_struct_level(TALLOC_CTX *mem_ctx,
        strip_driver_path(mem_ctx, *driver_path);
        strip_driver_path(mem_ctx, *data_file);
        strip_driver_path(mem_ctx, *config_file);
-       strip_driver_path(mem_ctx, *help_file);
+       if (help_file) {
+               strip_driver_path(mem_ctx, *help_file);
+       }
 
        if (dependent_files && dependent_files->string) {
                for (i=0; dependent_files->string[i]; i++) {
@@ -1717,6 +1729,32 @@ static void convert_level_6_to_level3(struct spoolss_AddDriverInfo3 *dst,
        dst->dependent_files    = src->dependent_files;
 }
 
+/****************************************************************************
+ This function sucks and should be replaced. JRA.
+****************************************************************************/
+
+static void convert_level_8_to_level3(TALLOC_CTX *mem_ctx,
+                                     struct spoolss_AddDriverInfo3 *dst,
+                                     const struct spoolss_DriverInfo8 *src)
+{
+       dst->version            = src->version;
+       dst->driver_name        = src->driver_name;
+       dst->architecture       = src->architecture;
+       dst->driver_path        = src->driver_path;
+       dst->data_file          = src->data_file;
+       dst->config_file        = src->config_file;
+       dst->help_file          = src->help_file;
+       dst->monitor_name       = src->monitor_name;
+       dst->default_datatype   = src->default_datatype;
+       if (src->dependent_files) {
+               dst->dependent_files = talloc_zero(mem_ctx, struct spoolss_StringArray);
+               if (!dst->dependent_files) return;
+               dst->dependent_files->string = src->dependent_files;
+       } else {
+               dst->dependent_files = NULL;
+       }
+}
+
 /****************************************************************************
 ****************************************************************************/
 
@@ -2120,15 +2158,19 @@ done:
 /****************************************************************************
 ****************************************************************************/
 
-static uint32 add_a_printer_driver_6(struct spoolss_AddDriverInfo6 *driver)
+static uint32_t add_a_printer_driver_8(struct spoolss_DriverInfo8 *driver)
 {
+       TALLOC_CTX *mem_ctx = talloc_new(talloc_tos());
        struct spoolss_AddDriverInfo3 info3;
+       uint32_t ret;
 
-       convert_level_6_to_level3(&info3, driver);
+       convert_level_8_to_level3(mem_ctx, &info3, driver);
 
-       return add_a_printer_driver_3(&info3);
-}
+       ret = add_a_printer_driver_3(&info3);
+       talloc_free(mem_ctx);
 
+       return ret;
+}
 
 /****************************************************************************
 ****************************************************************************/
@@ -2511,6 +2553,167 @@ done:
        return ret;
 }
 
+/****************************************************************************
+ 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_NOMEM;
+       }
+
+       dname = talloc_asprintf(dm, "%s", devicename);
+       if (dname == NULL) {
+               return WERR_NOMEM;
+       }
+       if (strlen(dname) > MAXDEVICENAME) {
+               dname[MAXDEVICENAME] = '\0';
+       }
+       dm->devicename = dname;
+
+       dm->formname = talloc_strdup(dm, "Letter");
+       if (dm->formname == NULL) {
+               return WERR_NOMEM;
+       }
+
+       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)
+{
+       SEC_ACE ace[5]; /* max number of ace entries */
+       int i = 0;
+       uint32_t sa;
+       SEC_ACL *psa = NULL;
+       SEC_DESC *psd = NULL;
+       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 ) {
+               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);
+
+       /* 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,
+                                   SEC_DESC_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_NOMEM;
+       }
+
+       DEBUG(4,("construct_default_printer_sdb: size = %u.\n",
+                (unsigned int)sd_size));
+
+       *secdesc = psd;
+
+       return WERR_OK;
+}
 
 /****************************************************************************
  Malloc and return an NT devicemode.
@@ -3323,7 +3526,7 @@ bool is_printer_published(Printer_entry *print_hnd, int snum,
                case REG_SZ:
                        blob = data_blob_const(regval_data_p(guid_val),
                                               regval_size(guid_val));
-                       pull_reg_sz(talloc_tos(), &blob, (const char **)&guid_str);
+                       pull_reg_sz(talloc_tos(), NULL, &blob, (const char **)&guid_str);
                        ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
                        talloc_free(guid_str);
                        break;
@@ -3798,8 +4001,17 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
        if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
                /* Pull the location and comment strings from cups if we don't
                   already have one */
-               if ( !strlen(info->location) || !strlen(info->comment) )
-                       cups_pull_comment_location( info );
+               if ( !strlen(info->location) || !strlen(info->comment) ) {
+                       char *comment = NULL;
+                       char *location = NULL;
+                       if (cups_pull_comment_location(info, info->sharename,
+                                                      &comment, &location)) {
+                               strlcpy(info->comment, comment, sizeof(info->comment));
+                               fstrcpy(info->location, location);
+                               TALLOC_FREE(comment);
+                               TALLOC_FREE(location);
+                       }
+               }
        }
 #endif
 
@@ -3833,6 +4045,13 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
                goto fail;
        }
 
+       info->data = TALLOC_ZERO_P(info, NT_PRINTER_DATA);
+       if (!info->data) {
+               goto fail;
+       }
+
+       add_new_printer_key(info->data, SPOOL_PRINTERDATA_KEY);
+
        return WERR_OK;
 
 fail:
@@ -3913,8 +4132,17 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
        if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {
                /* Pull the location and comment strings from cups if we don't
                   already have one */
-               if ( !strlen(info->location) || !strlen(info->comment) )
-                       cups_pull_comment_location( info );
+               if ( !strlen(info->location) || !strlen(info->comment) ) {
+                       char *location = NULL;
+                       comment = NULL;
+                       if (cups_pull_comment_location(info, info->sharename,
+                                                      &comment, &location)) {
+                               strlcpy(info->comment, comment, sizeof(info->comment));
+                               fstrcpy(info->location, location);
+                               TALLOC_FREE(comment);
+                               TALLOC_FREE(location);
+                       }
+               }
        }
 #endif
 
@@ -4595,93 +4823,175 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
 
 /****************************************************************************
 ****************************************************************************/
-uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
-                             struct spoolss_AddDriverInfoCtr *r,
-                             char **driver_name,
-                             uint32_t *version)
+
+bool driver_info_ctr_to_info8(struct spoolss_AddDriverInfoCtr *r,
+                             struct spoolss_DriverInfo8 *_info8)
 {
-       uint32 result;
-       DEBUG(10,("adding a printer at level [%d]\n", r->level));
+       struct spoolss_DriverInfo8 info8;
+
+       ZERO_STRUCT(info8);
 
        switch (r->level) {
        case 3:
-               result = add_a_printer_driver_3(r->info.info3);
-               if (result == 0) {
-                       *driver_name = talloc_strdup(mem_ctx, r->info.info3->driver_name);
-                       if (!*driver_name) {
-                               return -1;
-                       }
-                       *version = r->info.info3->version;
+               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:
-               result = add_a_printer_driver_6(r->info.info6);
-               if (result == 0) {
-                       *driver_name = talloc_strdup(mem_ctx, r->info.info6->driver_name);
-                       if (!*driver_name) {
-                               return -1;
-                       }
-                       *version = r->info.info6->version;
+               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;
-       default:
-               result = 1;
+       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;
        }
 
-       return result;
+       *_info8 = info8;
+
+       return true;
+}
+
+
+uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
+                             struct spoolss_AddDriverInfoCtr *r,
+                             char **driver_name,
+                             uint32_t *version)
+{
+       struct spoolss_DriverInfo8 info8;
+
+       ZERO_STRUCT(info8);
+
+       DEBUG(10,("adding a printer at level [%d]\n", r->level));
+
+       if (!driver_info_ctr_to_info8(r, &info8)) {
+               return -1;
+       }
+
+       *driver_name = talloc_strdup(mem_ctx, info8.driver_name);
+       if (!*driver_name) {
+               return -1;
+       }
+       *version = info8.version;
+
+       return add_a_printer_driver_8(&info8);
 }
+
 /****************************************************************************
 ****************************************************************************/
 
 WERROR get_a_printer_driver(TALLOC_CTX *mem_ctx,
-                           union spoolss_DriverInfo **driver_p, uint32_t level,
+                           struct spoolss_DriverInfo8 **driver,
                            const char *drivername, const char *architecture,
                            uint32_t version)
 {
        WERROR result;
-       union spoolss_DriverInfo *driver;
-
-       driver = talloc_zero(mem_ctx, union spoolss_DriverInfo);
-       W_ERROR_HAVE_NO_MEMORY(driver);
-
-       switch (level) {
-               case 3:
-                       /* Sometime we just want any version of the driver */
-
-                       if ( version == DRIVER_ANY_VERSION ) {
-                               /* look for Win2k first and then for NT4 */
-                               result = get_a_printer_driver_3(driver,
-                                                               &driver->info3,
-                                                               drivername,
-                                                               architecture, 3);
-
-                               if ( !W_ERROR_IS_OK(result) ) {
-                                       result = get_a_printer_driver_3(driver,
-                                                                       &driver->info3,
-                                                                       drivername,
-                                                                       architecture, 2);
-                               }
-                       } else {
-                               result = get_a_printer_driver_3(driver,
-                                                               &driver->info3,
-                                                               drivername,
-                                                               architecture,
-                                                               version);
-                       }
-                       break;
-
-               default:
-                       result=W_ERROR(1);
-                       break;
+       struct spoolss_DriverInfo3 info3;
+       struct spoolss_DriverInfo8 *info8;
+
+       ZERO_STRUCT(info3);
+
+       /* Sometime we just want any version of the driver */
+
+       if (version == DRIVER_ANY_VERSION) {
+               /* look for Win2k first and then for NT4 */
+               result = get_a_printer_driver_3(mem_ctx,
+                                               &info3,
+                                               drivername,
+                                               architecture, 3);
+               if (!W_ERROR_IS_OK(result)) {
+                       result = get_a_printer_driver_3(mem_ctx,
+                                                       &info3,
+                                                       drivername,
+                                                       architecture, 2);
+               }
+       } else {
+               result = get_a_printer_driver_3(mem_ctx,
+                                               &info3,
+                                               drivername,
+                                               architecture,
+                                               version);
        }
 
        if (!W_ERROR_IS_OK(result)) {
-               TALLOC_FREE(driver);
                return result;
        }
 
-       *driver_p = driver;
+       info8 = talloc_zero(mem_ctx, struct spoolss_DriverInfo8);
+       if (!info8) {
+               return WERR_NOMEM;
+       }
+
+       info8->version          = info3.version;
+       info8->driver_name      = info3.driver_name;
+       info8->architecture     = info3.architecture;
+       info8->driver_path      = info3.driver_path;
+       info8->data_file        = info3.data_file;
+       info8->config_file      = info3.config_file;
+       info8->help_file        = info3.help_file;
+       info8->dependent_files  = info3.dependent_files;
+       info8->monitor_name     = info3.monitor_name;
+       info8->default_datatype = info3.default_datatype;
+
+       *driver = info8;
 
        return WERR_OK;
 }
@@ -4689,7 +4999,7 @@ WERROR get_a_printer_driver(TALLOC_CTX *mem_ctx,
 /****************************************************************************
 ****************************************************************************/
 
-uint32_t free_a_printer_driver(union spoolss_DriverInfo *driver)
+uint32_t free_a_printer_driver(struct spoolss_DriverInfo8 *driver)
 {
        talloc_free(driver);
        return 0;
@@ -4701,15 +5011,16 @@ uint32_t free_a_printer_driver(union spoolss_DriverInfo *driver)
   to a printer
 ****************************************************************************/
 
-bool printer_driver_in_use(const struct spoolss_DriverInfo3 *info_3)
+bool printer_driver_in_use(const struct spoolss_DriverInfo8 *r)
 {
        int snum;
        int n_services = lp_numservices();
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        bool in_use = False;
 
-       if ( !info_3 )
-               return False;
+       if (!r) {
+               return false;
+       }
 
        DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
 
@@ -4722,7 +5033,7 @@ bool printer_driver_in_use(const struct spoolss_DriverInfo3 *info_3)
                if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
                        continue;
 
-               if (strequal(info_3->driver_name, printer->info_2->drivername))
+               if (strequal(r->driver_name, printer->info_2->drivername))
                        in_use = True;
 
                free_a_printer( &printer, 2 );
@@ -4731,28 +5042,28 @@ bool printer_driver_in_use(const struct spoolss_DriverInfo3 *info_3)
        DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
 
        if ( in_use ) {
-               union spoolss_DriverInfo *d;
+               struct spoolss_DriverInfo8 *d;
                WERROR werr;
 
-               DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", info_3->driver_name));
+               DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", r->driver_name));
 
                /* we can still remove the driver if there is one of
                   "Windows NT x86" version 2 or 3 left */
 
-               if (!strequal("Windows NT x86", info_3->architecture)) {
-                       werr = get_a_printer_driver(talloc_tos(), &d, 3, info_3->driver_name, "Windows NT x86", DRIVER_ANY_VERSION);
+               if (!strequal("Windows NT x86", r->architecture)) {
+                       werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", DRIVER_ANY_VERSION);
                }
                else {
-                       switch (info_3->version) {
+                       switch (r->version) {
                        case 2:
-                               werr = get_a_printer_driver(talloc_tos(), &d, 3, info_3->driver_name, "Windows NT x86", 3);
+                               werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 3);
                                break;
                        case 3:
-                               werr = get_a_printer_driver(talloc_tos(), &d, 3, info_3->driver_name, "Windows NT x86", 2);
+                               werr = get_a_printer_driver(talloc_tos(), &d, r->driver_name, "Windows NT x86", 2);
                                break;
                        default:
                                DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n",
-                                       info_3->version));
+                                       r->version));
                                werr = WERR_UNKNOWN_PRINTER_DRIVER;
                                break;
                        }
@@ -4777,7 +5088,7 @@ bool printer_driver_in_use(const struct spoolss_DriverInfo3 *info_3)
  Check to see if a ogiven file is in use by *info
  *********************************************************************/
 
-static bool drv_file_in_use(const char *file, const struct spoolss_DriverInfo3 *info)
+static bool drv_file_in_use(const char *file, const struct spoolss_DriverInfo8 *info)
 {
        int i = 0;
 
@@ -4841,8 +5152,8 @@ static void trim_dependent_file(TALLOC_CTX *mem_ctx, const char **files, int idx
  *********************************************************************/
 
 static bool trim_overlap_drv_files(TALLOC_CTX *mem_ctx,
-                                  struct spoolss_DriverInfo3 *src,
-                                  const struct spoolss_DriverInfo3 *drv)
+                                  struct spoolss_DriverInfo8 *src,
+                                  const struct spoolss_DriverInfo8 *drv)
 {
        bool    in_use = False;
        int     i = 0;
@@ -4915,13 +5226,13 @@ static bool trim_overlap_drv_files(TALLOC_CTX *mem_ctx,
 ****************************************************************************/
 
 bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
-                                struct spoolss_DriverInfo3 *info)
+                                struct spoolss_DriverInfo8 *info)
 {
        int                             i;
        int                             ndrivers;
        uint32                          version;
        fstring                         *list = NULL;
-       union spoolss_DriverInfo        *driver;
+       struct spoolss_DriverInfo8      *driver;
        bool in_use = false;
 
        if ( !info )
@@ -4948,7 +5259,7 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
 
                driver = NULL;
 
-               if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, 3, list[i], info->architecture, version))) {
+               if (!W_ERROR_IS_OK(get_a_printer_driver(talloc_tos(), &driver, list[i], info->architecture, version))) {
                        SAFE_FREE(list);
                        return True;
                }
@@ -4956,8 +5267,8 @@ bool printer_driver_files_in_use(TALLOC_CTX *mem_ctx,
                /* check if d2 uses any files from d1 */
                /* only if this is a different driver than the one being deleted */
 
-               if (!strequal(info->driver_name, driver->info3.driver_name)) {
-                       if (trim_overlap_drv_files(mem_ctx, info, &driver->info3)) {
+               if (!strequal(info->driver_name, driver->driver_name)) {
+                       if (trim_overlap_drv_files(mem_ctx, info, driver)) {
                                /* mz: Do not instantly return -
                                 * we need to ensure this file isn't
                                 * also in use by other drivers. */
@@ -5000,7 +5311,7 @@ static NTSTATUS driver_unlink_internals(connection_struct *conn,
 ****************************************************************************/
 
 static bool delete_driver_files(struct pipes_struct *rpc_pipe,
-                               const struct spoolss_DriverInfo3 *info_3)
+                               const struct spoolss_DriverInfo8 *r)
 {
        int i = 0;
        char *s;
@@ -5012,11 +5323,12 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
        int printdollar_snum;
        bool ret = false;
 
-       if ( !info_3 )
-               return False;
+       if (!r) {
+               return false;
+       }
 
        DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n",
-               info_3->driver_name, info_3->version));
+               r->driver_name, r->version));
 
        fstrcpy(printdollar, "print$");
 
@@ -5042,32 +5354,32 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
        /* now delete the files; must strip the '\print$' string from
           fron of path                                                */
 
-       if (info_3->driver_path && info_3->driver_path[0]) {
-               if ((s = strchr(&info_3->driver_path[1], '\\')) != NULL) {
+       if (r->driver_path && r->driver_path[0]) {
+               if ((s = strchr(&r->driver_path[1], '\\')) != NULL) {
                        file = s;
                        DEBUG(10,("deleting driverfile [%s]\n", s));
                        driver_unlink_internals(conn, file);
                }
        }
 
-       if (info_3->config_file && info_3->config_file[0]) {
-               if ((s = strchr(&info_3->config_file[1], '\\')) != NULL) {
+       if (r->config_file && r->config_file[0]) {
+               if ((s = strchr(&r->config_file[1], '\\')) != NULL) {
                        file = s;
                        DEBUG(10,("deleting configfile [%s]\n", s));
                        driver_unlink_internals(conn, file);
                }
        }
 
-       if (info_3->data_file && info_3->data_file[0]) {
-               if ((s = strchr(&info_3->data_file[1], '\\')) != NULL) {
+       if (r->data_file && r->data_file[0]) {
+               if ((s = strchr(&r->data_file[1], '\\')) != NULL) {
                        file = s;
                        DEBUG(10,("deleting datafile [%s]\n", s));
                        driver_unlink_internals(conn, file);
                }
        }
 
-       if (info_3->help_file && info_3->help_file[0]) {
-               if ((s = strchr( &info_3->help_file[1], '\\')) != NULL) {
+       if (r->help_file && r->help_file[0]) {
+               if ((s = strchr(&r->help_file[1], '\\')) != NULL) {
                        file = s;
                        DEBUG(10,("deleting helpfile [%s]\n", s));
                        driver_unlink_internals(conn, file);
@@ -5076,13 +5388,13 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
 
        /* check if we are done removing files */
 
-       if (info_3->dependent_files) {
-               while (info_3->dependent_files[i] && info_3->dependent_files[i][0]) {
+       if (r->dependent_files) {
+               while (r->dependent_files[i] && r->dependent_files[i][0]) {
                        char *p;
 
                        /* bypass the "\print$" portion of the path */
 
-                       if ((p = strchr(info_3->dependent_files[i]+1, '\\')) != NULL) {
+                       if ((p = strchr(r->dependent_files[i]+1, '\\')) != NULL) {
                                file = p;
                                DEBUG(10,("deleting dependent file [%s]\n", file));
                                driver_unlink_internals(conn, file);
@@ -5109,7 +5421,7 @@ static bool delete_driver_files(struct pipes_struct *rpc_pipe,
  ***************************************************************************/
 
 WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
-                            const struct spoolss_DriverInfo3 *info_3,
+                            const struct spoolss_DriverInfo8 *r,
                             uint32 version, bool delete_files )
 {
        char *key = NULL;
@@ -5118,12 +5430,12 @@ WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
 
        /* delete the tdb data first */
 
-       arch = get_short_archi(info_3->architecture);
+       arch = get_short_archi(r->architecture);
        if (!arch) {
                return WERR_UNKNOWN_PRINTER_DRIVER;
        }
        if (asprintf(&key, "%s%s/%d/%s", DRIVERS_PREFIX,
-                       arch, version, info_3->driver_name) < 0) {
+                       arch, version, r->driver_name) < 0) {
                return WERR_NOMEM;
        }
 
@@ -5156,7 +5468,7 @@ WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
         */
 
        if ( delete_files )
-               delete_driver_files(rpc_pipe, info_3);
+               delete_driver_files(rpc_pipe, r);
 
        DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
        SAFE_FREE(key);
@@ -5294,8 +5606,8 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
        if ( IS_DC ) {
                DOM_SID domadmins_sid;
 
-               sid_copy(&domadmins_sid, get_global_sam_sid());
-               sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
+               sid_compose(&domadmins_sid, get_global_sam_sid(),
+                           DOMAIN_RID_ADMINS);
 
                sa = PRINTER_ACE_FULL_CONTROL;
                init_sec_ace(&ace[i++], &domadmins_sid,
@@ -5305,7 +5617,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
                        sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
        }
        else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
-               sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);
+               sid_append_rid(&adm_sid, DOMAIN_RID_ADMINISTRATOR);
 
                sa = PRINTER_ACE_FULL_CONTROL;
                init_sec_ace(&ace[i++], &adm_sid,
@@ -5414,7 +5726,7 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
 
                        /* Create new sd */
 
-                       sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
+                       sid_append_rid(&owner_sid, DOMAIN_RID_ADMINISTRATOR);
 
                        psd = make_sec_desc(ctx, (*secdesc_ctr)->sd->revision, (*secdesc_ctr)->sd->type,
                                            &owner_sid,
@@ -5613,7 +5925,7 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
 
         /* see if we need to try the printer admin list */
 
-        if ((access_granted == 0) &&
+        if (!NT_STATUS_IS_OK(status) &&
            (token_contains_name_in_list(uidtoname(server_info->utok.uid),
                                         NULL, NULL, server_info->ptok,
                                         lp_printer_admin(snum)))) {