s3:nt_printing: use regval_ctr_init().
[amitay/samba.git] / source3 / printing / nt_printing.c
index b29000a2d8116fe71053d6e5c459c567a3b92d7d..1823b16a862d45fb3774a00c7218ac29e3789bd3 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 */
@@ -27,7 +30,6 @@ static TDB_CONTEXT *tdb_printers; /* used for printers files */
 
 #define FORMS_PREFIX "FORMS/"
 #define DRIVERS_PREFIX "DRIVERS/"
-#define DRIVER_INIT_PREFIX "DRIVER_INIT/"
 #define PRINTERS_PREFIX "PRINTERS/"
 #define SECDESC_PREFIX "SECDESC/"
 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
@@ -91,6 +93,8 @@ static const nt_forms_struct default_forms[] = {
        {"Legal",0x1,0x34b5c,0x56d10,0x0,0x0,0x34b5c,0x56d10},
        {"Statement",0x1,0x221b4,0x34b5c,0x0,0x0,0x221b4,0x34b5c},
        {"Executive",0x1,0x2cf56,0x411cc,0x0,0x0,0x2cf56,0x411cc},
+       {"A0",0x1,0xcd528,0x122488,0x0,0x0,0xcd528,0x122488},
+       {"A1",0x1,0x91050,0xcd528,0x0,0x0,0x91050,0xcd528},
        {"A3",0x1,0x48828,0x668a0,0x0,0x0,0x48828,0x668a0},
        {"A4",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
        {"A4 Small",0x1,0x33450,0x48828,0x0,0x0,0x33450,0x48828},
@@ -330,9 +334,9 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
                             TDB_DATA data, void *state )
 {
        NTSTATUS status;
-       SEC_DESC_BUF *sd_orig = NULL;
-       SEC_DESC_BUF *sd_new, *sd_store;
-       SEC_DESC *sec, *new_sec;
+       struct sec_desc_buf *sd_orig = NULL;
+       struct sec_desc_buf *sd_new, *sd_store;
+       struct security_descriptor *sec, *new_sec;
        TALLOC_CTX *ctx = state;
        int result, i;
        uint32 sd_size;
@@ -388,9 +392,9 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
                }
        }
 
-       /* create a new SEC_DESC with the appropriate owner and group SIDs */
+       /* create a new struct security_descriptor with the appropriate owner and group SIDs */
 
-       new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+       new_sec = make_sec_desc( ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
                                 &global_sid_Builtin_Administrators,
                                 &global_sid_Builtin_Administrators,
                                 NULL, NULL, &size_new_sec );
@@ -402,15 +406,15 @@ 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;
        }
 
        /* store it back */
 
-       sd_size = ndr_size_security_descriptor(sd_store->sd, NULL, 0)
-               + sizeof(SEC_DESC_BUF);
+       sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
+               + sizeof(struct sec_desc_buf);
 
        status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
        if (!NT_STATUS_IS_OK(status)) {
@@ -608,14 +612,6 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
        messaging_register(msg_ctx, NULL, MSG_PRINTER_DRVUPGRADE,
                           do_drv_upgrade_printer);
 
-       /*
-        * register callback to handle updating printer data
-        * when a driver is initialized
-        */
-
-       messaging_register(msg_ctx, NULL, MSG_PRINTERDATA_INIT_RESET,
-                          reset_all_printerdata);
-
        /* 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 serverid_register() */
@@ -918,7 +914,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;
        }
 
@@ -1605,7 +1601,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)); \
        } \
@@ -1626,6 +1622,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 !
@@ -1635,7 +1635,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++) {
@@ -2544,6 +2546,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)
+{
+       struct security_ace ace[5];     /* 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);
+
+       /* 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_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.
@@ -2734,6 +2897,7 @@ int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
 {
        NT_PRINTER_KEY  *d;
        int             key_index;
+       WERROR werr;
 
        if ( !name || !data )
                return -1;
@@ -2753,8 +2917,10 @@ int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
 
        data->keys[key_index].name = talloc_strdup( data, name );
 
-       if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, struct regval_ctr )) )
+       werr = regval_ctr_init(data, &(data->keys[key_index].values));
+       if (!W_ERROR_IS_OK(werr)) {
                return -1;
+       }
 
        data->num_keys++;
 
@@ -2936,7 +3102,7 @@ static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name,
 {
        regval_ctr_delvalue(ctr, val_name);
        regval_ctr_addvalue(ctr, val_name, REG_DWORD,
-                           (char *) &dword, sizeof(dword));
+                           (uint8 *) &dword, sizeof(dword));
 }
 
 static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
@@ -2945,7 +3111,7 @@ static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
        uint8 bin_bool = (b ? 1 : 0);
        regval_ctr_delvalue(ctr, val_name);
        regval_ctr_addvalue(ctr, val_name, REG_BINARY,
-                           (char *) &bin_bool, sizeof(bin_bool));
+                           (uint8 *) &bin_bool, sizeof(bin_bool));
 }
 
 static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
@@ -3538,7 +3704,7 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha
                return WERR_NOMEM;
 
        regval_ctr_addvalue( p2->data->keys[key_index].values, value,
-               type, (const char *)data, real_len );
+               type, data, real_len );
 
        DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
                key, value, type, real_len  ));
@@ -3667,7 +3833,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
                        /* add the value */
 
                        regval_ctr_addvalue( printer_data->keys[key_index].values,
-                                            valuename, type, (const char *)data_p,
+                                            valuename, type, data_p,
                                             size );
                }
 
@@ -3681,39 +3847,36 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
 /****************************************************************************
  ***************************************************************************/
 
-static char *last_from;
-static char *last_to;
+static char *win_driver;
+static char *os2_driver;
 
-static const char *get_last_from(void)
+static const char *get_win_driver(void)
 {
-       if (!last_from) {
+       if (win_driver == NULL) {
                return "";
        }
-       return last_from;
+       return win_driver;
 }
 
-static const char *get_last_to(void)
+static const char *get_os2_driver(void)
 {
-       if (!last_to) {
+       if (os2_driver == NULL) {
                return "";
        }
-       return last_to;
+       return os2_driver;
 }
 
-static bool set_last_from_to(const char *from, const char *to)
+static bool set_driver_mapping(const char *from, const char *to)
 {
-       char *orig_from = last_from;
-       char *orig_to = last_to;
-
-       last_from = SMB_STRDUP(from);
-       last_to = SMB_STRDUP(to);
+       SAFE_FREE(win_driver);
+       SAFE_FREE(os2_driver);
 
-       SAFE_FREE(orig_from);
-       SAFE_FREE(orig_to);
+       win_driver = SMB_STRDUP(from);
+       os2_driver = SMB_STRDUP(to);
 
-       if (!last_from || !last_to) {
-               SAFE_FREE(last_from);
-               SAFE_FREE(last_to);
+       if (win_driver == NULL || os2_driver == NULL) {
+               SAFE_FREE(win_driver);
+               SAFE_FREE(os2_driver);
                return false;
        }
        return true;
@@ -3732,10 +3895,10 @@ static void map_to_os2_driver(fstring drivername)
        if (!*mapfile)
                return;
 
-       if (strequal(drivername,get_last_from())) {
+       if (strequal(drivername, get_win_driver())) {
                DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
-                       drivername,get_last_to()));
-               fstrcpy(drivername,get_last_to());
+                       drivername, get_os2_driver()));
+               fstrcpy(drivername, get_os2_driver());
                return;
        }
 
@@ -3784,7 +3947,7 @@ static void map_to_os2_driver(fstring drivername)
 
                if (strequal(nt_name,drivername)) {
                        DEBUG(3,("Mapped windows driver %s to os2 driver%s\n",drivername,os2_name));
-                       set_last_from_to(drivername,os2_name);
+                       set_driver_mapping(drivername,os2_name);
                        fstrcpy(drivername,os2_name);
                        TALLOC_FREE(lines);
                        return;
@@ -3794,6 +3957,110 @@ static void map_to_os2_driver(fstring drivername)
        TALLOC_FREE(lines);
 }
 
+/**
+ * @internal
+ *
+ * @brief Map a Windows driver to a OS/2 driver.
+ *
+ * @param[in]  mem_ctx  The memory context to use.
+ *
+ * @param[in,out] pdrivername The drivername of Windows to remap.
+ *
+ * @return              WERR_OK on success, a corresponding WERROR on failure.
+ */
+WERROR spoolss_map_to_os2_driver(TALLOC_CTX *mem_ctx, const char **pdrivername)
+{
+       const char *mapfile = lp_os2_driver_map();
+       char **lines = NULL;
+       const char *drivername;
+       int numlines = 0;
+       int i;
+
+       if (pdrivername == NULL || *pdrivername == NULL || *pdrivername[0] == '\0') {
+               return WERR_INVALID_PARAMETER;
+       }
+
+       drivername = *pdrivername;
+
+       if (mapfile[0] == '\0') {
+               return WERR_BADFILE;
+       }
+
+       if (strequal(drivername, get_win_driver())) {
+               DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",
+                       drivername, get_os2_driver()));
+               drivername = talloc_strdup(mem_ctx, get_os2_driver());
+               if (drivername == NULL) {
+                       return WERR_NOMEM;
+               }
+               *pdrivername = drivername;
+               return WERR_OK;
+       }
+
+       lines = file_lines_load(mapfile, &numlines, 0, NULL);
+       if (numlines == 0 || lines == NULL) {
+               DEBUG(0,("No entries in OS/2 driver map %s\n", mapfile));
+               TALLOC_FREE(lines);
+               return WERR_EMPTY;
+       }
+
+       DEBUG(4,("Scanning OS/2 driver map %s\n",mapfile));
+
+       for( i = 0; i < numlines; i++) {
+               char *nt_name = lines[i];
+               char *os2_name = strchr(nt_name, '=');
+
+               if (os2_name == NULL) {
+                       continue;
+               }
+
+               *os2_name++ = '\0';
+
+               while (isspace(*nt_name)) {
+                       nt_name++;
+               }
+
+               if (*nt_name == '\0' || strchr("#;", *nt_name)) {
+                       continue;
+               }
+
+               {
+                       int l = strlen(nt_name);
+                       while (l && isspace(nt_name[l - 1])) {
+                               nt_name[l - 1] = 0;
+                               l--;
+                       }
+               }
+
+               while (isspace(*os2_name)) {
+                       os2_name++;
+               }
+
+               {
+                       int l = strlen(os2_name);
+                       while (l && isspace(os2_name[l-1])) {
+                               os2_name[l-1] = 0;
+                               l--;
+                       }
+               }
+
+               if (strequal(nt_name, drivername)) {
+                       DEBUG(3,("Mapped Windows driver %s to OS/2 driver %s\n",drivername,os2_name));
+                       set_driver_mapping(drivername, os2_name);
+                       drivername = talloc_strdup(mem_ctx, os2_name);
+                       TALLOC_FREE(lines);
+                       if (drivername == NULL) {
+                               return WERR_NOMEM;
+                       }
+                       *pdrivername = drivername;
+                       return WERR_OK;
+               }
+       }
+
+       TALLOC_FREE(lines);
+       return WERR_OK;
+}
+
 /****************************************************************************
  Get a default printer info 2 struct.
 ****************************************************************************/
@@ -3831,8 +4098,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
 
@@ -3953,8 +4229,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
 
@@ -4152,375 +4437,6 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
        return result;
 }
 
-/****************************************************************************
- Initialize printer devmode & data with previously saved driver init values.
-****************************************************************************/
-
-static bool set_driver_init_2( NT_PRINTER_INFO_LEVEL_2 *info_ptr )
-{
-       int                     len = 0;
-       char *key = NULL;
-       TDB_DATA                dbuf;
-       NT_PRINTER_INFO_LEVEL_2 info;
-
-
-       ZERO_STRUCT(info);
-
-       /*
-        * Delete any printer data 'values' already set. When called for driver
-        * replace, there will generally be some, but during an add printer, there
-        * should not be any (if there are delete them).
-        */
-
-       if ( info_ptr->data )
-               delete_all_printer_data( info_ptr, "" );
-
-       if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX,
-                               info_ptr->drivername) < 0) {
-               return false;
-       }
-
-       dbuf = tdb_fetch_bystring(tdb_drivers, key);
-       if (!dbuf.dptr) {
-               /*
-                * When changing to a driver that has no init info in the tdb, remove
-                * the previous drivers init info and leave the new on blank.
-                */
-               free_nt_devicemode(&info_ptr->devmode);
-               SAFE_FREE(key);
-               return false;
-       }
-
-       SAFE_FREE(key);
-       /*
-        * Get the saved DEVMODE..
-        */
-
-       len += unpack_devicemode(&info.devmode,dbuf.dptr+len, dbuf.dsize-len);
-
-       /*
-        * The saved DEVMODE contains the devicename from the printer used during
-        * the initialization save. Change it to reflect the new printer.
-        */
-
-       if ( info.devmode ) {
-               ZERO_STRUCT(info.devmode->devicename);
-               fstrcpy(info.devmode->devicename, info_ptr->printername);
-       }
-
-       /*
-        * NT/2k does not change out the entire DeviceMode of a printer
-        * when changing the driver.  Only the driverextra, private, &
-        * driverversion fields.   --jerry  (Thu Mar 14 08:58:43 CST 2002)
-        *
-        * Later examination revealed that Windows NT/2k does reset the
-        * the printer's device mode, bit **only** when you change a
-        * property of the device mode such as the page orientation.
-        * --jerry
-        */
-
-
-       /* Bind the saved DEVMODE to the new the printer */
-
-       free_nt_devicemode(&info_ptr->devmode);
-       info_ptr->devmode = info.devmode;
-
-       DEBUG(10,("set_driver_init_2: Set printer [%s] init %s DEVMODE for driver [%s]\n",
-               info_ptr->printername, info_ptr->devmode?"VALID":"NULL", info_ptr->drivername));
-
-       /* Add the printer data 'values' to the new printer */
-
-       if ( !(info_ptr->data = TALLOC_ZERO_P( info_ptr, NT_PRINTER_DATA )) ) {
-               DEBUG(0,("set_driver_init_2: talloc() failed!\n"));
-               return False;
-       }
-
-       len += unpack_values( info_ptr->data, dbuf.dptr+len, dbuf.dsize-len );
-
-       SAFE_FREE(dbuf.dptr);
-
-       return true;
-}
-
-/****************************************************************************
- Initialize printer devmode & data with previously saved driver init values.
- When a printer is created using AddPrinter, the drivername bound to the
- printer is used to lookup previously saved driver initialization info, which
- is bound to the new printer.
-****************************************************************************/
-
-bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
-       bool result = False;
-
-       switch (level) {
-               case 2:
-                       result = set_driver_init_2(printer->info_2);
-                       break;
-
-               default:
-                       DEBUG(0,("set_driver_init: Programmer's error!  Unknown driver_init level [%d]\n",
-                               level));
-                       break;
-       }
-
-       return result;
-}
-
-/****************************************************************************
- Delete driver init data stored for a specified driver
-****************************************************************************/
-
-bool del_driver_init(const char *drivername)
-{
-       char *key;
-       bool ret;
-
-       if (!drivername || !*drivername) {
-               DEBUG(3,("del_driver_init: No drivername specified!\n"));
-               return false;
-       }
-
-       if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, drivername) < 0) {
-               return false;
-       }
-
-       DEBUG(6,("del_driver_init: Removing driver init data for [%s]\n",
-                               drivername));
-
-       ret = (tdb_delete_bystring(tdb_drivers, key) == 0);
-       SAFE_FREE(key);
-       return ret;
-}
-
-/****************************************************************************
- Pack up the DEVMODE and values for a printer into a 'driver init' entry
- in the tdb. Note: this is different from the driver entry and the printer
- entry. There should be a single driver init entry for each driver regardless
- of whether it was installed from NT or 2K. Technically, they should be
- different, but they work out to the same struct.
-****************************************************************************/
-
-static uint32 update_driver_init_2(NT_PRINTER_INFO_LEVEL_2 *info)
-{
-       char *key = NULL;
-       uint8 *buf;
-       int buflen, len, ret;
-       int retlen;
-       TDB_DATA dbuf;
-
-       buf = NULL;
-       buflen = 0;
-
- again:
-       len = 0;
-       len += pack_devicemode(info->devmode, buf+len, buflen-len);
-
-       retlen = pack_values( info->data, buf+len, buflen-len );
-       if (retlen == -1) {
-               ret = -1;
-               goto done;
-       }
-       len += retlen;
-
-       if (buflen < len) {
-               buf = (uint8 *)SMB_REALLOC(buf, len);
-               if (!buf) {
-                       DEBUG(0, ("update_driver_init_2: failed to enlarge buffer!\n"));
-                       ret = -1;
-                       goto done;
-               }
-               buflen = len;
-               goto again;
-       }
-
-       SAFE_FREE(key);
-       if (asprintf(&key, "%s%s", DRIVER_INIT_PREFIX, info->drivername) < 0) {
-               ret = (uint32)-1;
-               goto done;
-       }
-
-       dbuf.dptr = buf;
-       dbuf.dsize = len;
-
-       ret = tdb_store_bystring(tdb_drivers, key, dbuf, TDB_REPLACE);
-
-done:
-       if (ret == -1)
-               DEBUG(8, ("update_driver_init_2: error updating printer init to tdb on disk\n"));
-
-       SAFE_FREE(buf);
-
-       DEBUG(10,("update_driver_init_2: Saved printer [%s] init DEVMODE & values for driver [%s]\n",
-                info->sharename, info->drivername));
-
-       return ret;
-}
-
-/****************************************************************************
- Update (i.e. save) the driver init info (DEVMODE and values) for a printer
-****************************************************************************/
-
-static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
-{
-       uint32 result;
-
-       dump_a_printer(printer, level);
-
-       switch (level) {
-               case 2:
-                       result = update_driver_init_2(printer->info_2);
-                       break;
-               default:
-                       result = 1;
-                       break;
-       }
-
-       return result;
-}
-
-/****************************************************************************
- Convert the printer data value, a REG_BINARY array, into an initialization
- DEVMODE. Note: the array must be parsed as if it was a DEVMODE in an rpc...
- got to keep the endians happy :).
-****************************************************************************/
-
-static bool convert_driver_init(TALLOC_CTX *mem_ctx, NT_DEVICEMODE *nt_devmode,
-                               const uint8_t *data, uint32_t data_len)
-{
-       struct spoolss_DeviceMode devmode;
-       enum ndr_err_code ndr_err;
-       DATA_BLOB blob;
-
-       ZERO_STRUCT(devmode);
-
-       blob = data_blob_const(data, data_len);
-
-       ndr_err = ndr_pull_struct_blob(&blob, mem_ctx, NULL, &devmode,
-                       (ndr_pull_flags_fn_t)ndr_pull_spoolss_DeviceMode);
-       if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
-               DEBUG(10,("convert_driver_init: error parsing spoolss_DeviceMode\n"));
-               return false;
-       }
-
-       return convert_devicemode("", &devmode, &nt_devmode);
-}
-
-/****************************************************************************
- Set the DRIVER_INIT info in the tdb. Requires Win32 client code that:
-
- 1. Use the driver's config DLL to this UNC printername and:
-    a. Call DrvPrintEvent with PRINTER_EVENT_INITIALIZE
-    b. Call DrvConvertDevMode with CDM_DRIVER_DEFAULT to get default DEVMODE
- 2. Call SetPrinterData with the 'magic' key and the DEVMODE as data.
-
- The last step triggers saving the "driver initialization" information for
- this printer into the tdb. Later, new printers that use this driver will
- have this initialization information bound to them. This simulates the
- driver initialization, as if it had run on the Samba server (as it would
- have done on NT).
-
- The Win32 client side code requirement sucks! But until we can run arbitrary
- Win32 printer driver code on any Unix that Samba runs on, we are stuck with it.
-
- It would have been easier to use SetPrinter because all the UNMARSHALLING of
- the DEVMODE is done there, but 2K/XP clients do not set the DEVMODE... think
- about it and you will realize why.  JRR 010720
-****************************************************************************/
-
-static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, uint32 data_len )
-{
-       WERROR        status       = WERR_OK;
-       TALLOC_CTX    *ctx         = NULL;
-       NT_DEVICEMODE *nt_devmode  = NULL;
-       NT_DEVICEMODE *tmp_devmode = printer->info_2->devmode;
-
-       /*
-        * When the DEVMODE is already set on the printer, don't try to unpack it.
-        */
-       DEBUG(8,("save_driver_init_2: Enter...\n"));
-
-       if ( !printer->info_2->devmode && data_len ) {
-               /*
-                * Set devmode on printer info, so entire printer initialization can be
-                * saved to tdb.
-                */
-
-               if ((ctx = talloc_init("save_driver_init_2")) == NULL)
-                       return WERR_NOMEM;
-
-               if ((nt_devmode = SMB_MALLOC_P(NT_DEVICEMODE)) == NULL) {
-                       status = WERR_NOMEM;
-                       goto done;
-               }
-
-               ZERO_STRUCTP(nt_devmode);
-
-               /*
-                * The DEVMODE is held in the 'data' component of the param in raw binary.
-                * Convert it to to a devmode structure
-                */
-               if ( !convert_driver_init( ctx, nt_devmode, data, data_len )) {
-                       DEBUG(10,("save_driver_init_2: error converting DEVMODE\n"));
-                       status = WERR_INVALID_PARAM;
-                       goto done;
-               }
-
-               printer->info_2->devmode = nt_devmode;
-       }
-
-       /*
-        * Pack up and add (or update) the DEVMODE and any current printer data to
-        * a 'driver init' element in the tdb
-        *
-        */
-
-       if ( update_driver_init(printer, 2) != 0 ) {
-               DEBUG(10,("save_driver_init_2: error updating DEVMODE\n"));
-               status = WERR_NOMEM;
-               goto done;
-       }
-
-       /*
-        * If driver initialization info was successfully saved, set the current
-        * printer to match it. This allows initialization of the current printer
-        * as well as the driver.
-        */
-       status = mod_a_printer(printer, 2);
-       if (!W_ERROR_IS_OK(status)) {
-               DEBUG(10,("save_driver_init_2: error setting DEVMODE on printer [%s]\n",
-                                 printer->info_2->printername));
-       }
-
-  done:
-       talloc_destroy(ctx);
-       free_nt_devicemode( &nt_devmode );
-
-       printer->info_2->devmode = tmp_devmode;
-
-       return status;
-}
-
-/****************************************************************************
- Update the driver init info (DEVMODE and specifics) for a printer
-****************************************************************************/
-
-WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len)
-{
-       WERROR status = WERR_OK;
-
-       switch (level) {
-               case 2:
-                       status = save_driver_init_2( printer, data, data_len );
-                       break;
-               default:
-                       status = WERR_UNKNOWN_LEVEL;
-                       break;
-       }
-
-       return status;
-}
-
 /****************************************************************************
  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
 
@@ -4636,17 +4552,13 @@ 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)
 {
        struct spoolss_DriverInfo8 info8;
 
        ZERO_STRUCT(info8);
 
-       DEBUG(10,("adding a printer at level [%d]\n", r->level));
-
        switch (r->level) {
        case 3:
                info8.version           = r->info.info3->version;
@@ -4718,6 +4630,27 @@ uint32_t add_a_printer_driver(TALLOC_CTX *mem_ctx,
                info8.min_inbox_driver_ver_version = r->info.info8->min_inbox_driver_ver_version;
                break;
        default:
+               return false;
+       }
+
+       *_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;
        }
 
@@ -5275,10 +5208,10 @@ WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
  Store a security desc for a printer.
 ****************************************************************************/
 
-WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
+WERROR nt_printing_setsec(const char *sharename, struct sec_desc_buf *secdesc_ctr)
 {
-       SEC_DESC_BUF *new_secdesc_ctr = NULL;
-       SEC_DESC_BUF *old_secdesc_ctr = NULL;
+       struct sec_desc_buf *new_secdesc_ctr = NULL;
+       struct sec_desc_buf *old_secdesc_ctr = NULL;
        TALLOC_CTX *mem_ctx = NULL;
        TDB_DATA kbuf;
        TDB_DATA dbuf;
@@ -5296,9 +5229,9 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
           descriptor then copy them over from the old one. */
 
        if (!secdesc_ctr->sd->owner_sid || !secdesc_ctr->sd->group_sid) {
-               DOM_SID *owner_sid, *group_sid;
-               SEC_ACL *dacl, *sacl;
-               SEC_DESC *psd = NULL;
+               struct dom_sid *owner_sid, *group_sid;
+               struct security_acl *dacl, *sacl;
+               struct security_descriptor *psd = NULL;
                size_t size;
 
                if (!nt_printing_getsec(mem_ctx, sharename, &old_secdesc_ctr)) {
@@ -5379,15 +5312,15 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
  Construct a default security descriptor buffer for a printer.
 ****************************************************************************/
 
-static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
+static struct sec_desc_buf *construct_default_printer_sdb(TALLOC_CTX *ctx)
 {
-       SEC_ACE ace[5]; /* max number of ace entries */
+       struct security_ace ace[5];     /* max number of ace entries */
        int i = 0;
        uint32_t sa;
-       SEC_ACL *psa = NULL;
-       SEC_DESC_BUF *sdb = NULL;
-       SEC_DESC *psd = NULL;
-       DOM_SID adm_sid;
+       struct security_acl *psa = NULL;
+       struct sec_desc_buf *sdb = NULL;
+       struct security_descriptor *psd = NULL;
+       struct dom_sid adm_sid;
        size_t sd_size;
 
        /* Create an ACE where Everyone is allowed to print */
@@ -5399,10 +5332,10 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
        /* Add the domain admins group if we are a DC */
 
        if ( IS_DC ) {
-               DOM_SID domadmins_sid;
+               struct dom_sid domadmins_sid;
 
                sid_compose(&domadmins_sid, get_global_sam_sid(),
-                           DOMAIN_GROUP_RID_ADMINS);
+                           DOMAIN_RID_ADMINS);
 
                sa = PRINTER_ACE_FULL_CONTROL;
                init_sec_ace(&ace[i++], &domadmins_sid,
@@ -5412,7 +5345,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,
@@ -5440,7 +5373,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
           NT5 machine. */
 
        if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
-               psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
+               psd = make_sec_desc(ctx, SD_REVISION, SEC_DESC_SELF_RELATIVE,
                        &global_sid_Builtin_Administrators,
                        &global_sid_Builtin_Administrators,
                        NULL, psa, &sd_size);
@@ -5463,7 +5396,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
  Get a security desc for a printer.
 ****************************************************************************/
 
-bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
+bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, struct sec_desc_buf **secdesc_ctr)
 {
        TDB_DATA kbuf;
        TDB_DATA dbuf;
@@ -5510,18 +5443,18 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
           down.  Take ownership of security descriptor. */
 
        if (sid_equal((*secdesc_ctr)->sd->owner_sid, &global_sid_World)) {
-               DOM_SID owner_sid;
+               struct dom_sid owner_sid;
 
                /* Change sd owner to workgroup administrator */
 
                if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
-                       SEC_DESC_BUF *new_secdesc_ctr = NULL;
-                       SEC_DESC *psd = NULL;
+                       struct sec_desc_buf *new_secdesc_ctr = NULL;
+                       struct security_descriptor *psd = NULL;
                        size_t size;
 
                        /* 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,
@@ -5550,7 +5483,7 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
        }
 
        if (DEBUGLEVEL >= 10) {
-               SEC_ACL *the_acl = (*secdesc_ctr)->sd->dacl;
+               struct security_acl *the_acl = (*secdesc_ctr)->sd->dacl;
                int i;
 
                DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
@@ -5607,7 +5540,7 @@ jfm: I should use this comment for the text file to explain
    It turns out that NT4 security descriptors use generic access rights and
    NT5 the object specific ones. */
 
-void map_printer_permissions(SEC_DESC *sd)
+void map_printer_permissions(struct security_descriptor *sd)
 {
        int i;
 
@@ -5617,7 +5550,7 @@ void map_printer_permissions(SEC_DESC *sd)
        }
 }
 
-void map_job_permissions(SEC_DESC *sd)
+void map_job_permissions(struct security_descriptor *sd)
 {
        int i;
 
@@ -5654,7 +5587,7 @@ void map_job_permissions(SEC_DESC *sd)
 bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
                        int access_type)
 {
-       SEC_DESC_BUF *secdesc = NULL;
+       struct sec_desc_buf *secdesc = NULL;
        uint32 access_granted;
        NTSTATUS status;
        const char *pname;
@@ -5693,7 +5626,7 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
        }
 
        if (access_type == JOB_ACCESS_ADMINISTER) {
-               SEC_DESC_BUF *parent_secdesc = secdesc;
+               struct sec_desc_buf *parent_secdesc = secdesc;
 
                /* Create a child security descriptor to check permissions
                   against.  This is because print jobs are child objects