s3-spoolss: remove device mode defines from nt_printing.h.
[ira/wip.git] / source3 / printing / nt_printing.c
index 85f42feb91a1b6253fd04a82e80fd2c53ac28fce..b75e30bb3e85d0ef7be5fd2a123f09148c470ca4 100644 (file)
@@ -31,7 +31,7 @@ static TDB_CONTEXT *tdb_printers; /* used for printers files */
 #define PRINTERS_PREFIX "PRINTERS/"
 #define SECDESC_PREFIX "SECDESC/"
 #define GLOBAL_C_SETPRINTER "GLOBALS/c_setprinter"
+
 #define NTDRIVERS_DATABASE_VERSION_1 1
 #define NTDRIVERS_DATABASE_VERSION_2 2
 #define NTDRIVERS_DATABASE_VERSION_3 3 /* little endian version of v2 */
@@ -204,21 +204,7 @@ static const nt_forms_struct default_forms[] = {
        {"PRC Envelope #10 Rotated",0x1,0x6fd10,0x4f1a0,0x0,0x0,0x6fd10,0x4f1a0}
 };
 
-struct table_node {
-       const char      *long_archi;
-       const char      *short_archi;
-       int     version;
-};
-#define SPL_ARCH_WIN40         "WIN40"
-#define SPL_ARCH_W32X86                "W32X86"
-#define SPL_ARCH_W32MIPS       "W32MIPS"
-#define SPL_ARCH_W32ALPHA      "W32ALPHA"
-#define SPL_ARCH_W32PPC                "W32PPC"
-#define SPL_ARCH_IA64          "IA64"
-#define SPL_ARCH_X64           "x64"
-
-static const struct table_node archi_table[]= {
+static const struct print_architecture_table_node archi_table[]= {
 
        {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
        {"Windows NT x86",       SPL_ARCH_W32X86,       2 },
@@ -276,11 +262,11 @@ static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
 static bool upgrade_to_version_3(void)
 {
        TDB_DATA kbuf, newkey, dbuf;
+
        DEBUG(0,("upgrade_to_version_3: upgrading print tdb's to version 3\n"));
+
        for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
-                       newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
+                       newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
 
                dbuf = tdb_fetch(tdb_drivers, kbuf);
 
@@ -297,7 +283,7 @@ static bool upgrade_to_version_3(void)
                                return False;
                        }
                }
+
                if (strncmp((const char *)kbuf.dptr, PRINTERS_PREFIX, strlen(PRINTERS_PREFIX)) == 0) {
                        DEBUG(0,("upgrade_to_version_3:moving printer\n"));
                        if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
@@ -311,7 +297,7 @@ static bool upgrade_to_version_3(void)
                                return False;
                        }
                }
+
                if (strncmp((const char *)kbuf.dptr, SECDESC_PREFIX, strlen(SECDESC_PREFIX)) == 0) {
                        DEBUG(0,("upgrade_to_version_3:moving secdesc\n"));
                        if (tdb_store(tdb_printers, kbuf, dbuf, TDB_REPLACE) != 0) {
@@ -325,7 +311,7 @@ static bool upgrade_to_version_3(void)
                                return False;
                        }
                }
+
                SAFE_FREE(dbuf.dptr);
        }
 
@@ -333,17 +319,17 @@ static bool upgrade_to_version_3(void)
 }
 
 /*******************************************************************
- Fix an issue with security descriptors.  Printer sec_desc must 
- use more than the generic bits that were previously used 
+ Fix an issue with security descriptors.  Printer sec_desc must
+ use more than the generic bits that were previously used
  in <= 3.0.14a.  They must also have a owner and group SID assigned.
- Otherwise, any printers than have been migrated to a Windows 
+ Otherwise, any printers than have been migrated to a Windows
  host using printmig.exe will not be accessible.
 *******************************************************************/
 
 static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
                             TDB_DATA data, void *state )
 {
-       prs_struct ps;
+       NTSTATUS status;
        SEC_DESC_BUF *sd_orig = NULL;
        SEC_DESC_BUF *sd_new, *sd_store;
        SEC_DESC *sec, *new_sec;
@@ -362,48 +348,41 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
 
        /* upgrade the security descriptor */
 
-       ZERO_STRUCT( ps );
-
-       prs_init_empty( &ps, ctx, UNMARSHALL );
-       prs_give_memory( &ps, (char *)data.dptr, data.dsize, False );
-
-       if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_orig, &ps, 1 ) ) {
+       status = unmarshall_sec_desc_buf(ctx, data.dptr, data.dsize, &sd_orig);
+       if (!NT_STATUS_IS_OK(status)) {
                /* delete bad entries */
                DEBUG(0,("sec_desc_upg_fn: Failed to parse original sec_desc for %si.  Deleting....\n",
                        (const char *)key.dptr ));
                tdb_delete( tdb_printers, key );
-               prs_mem_free( &ps );
                return 0;
        }
 
        if (!sd_orig) {
-               prs_mem_free( &ps );
                return 0;
        }
        sec = sd_orig->sd;
-               
+
        /* is this even valid? */
-       
+
        if ( !sec->dacl ) {
-               prs_mem_free( &ps );
                return 0;
        }
-               
+
        /* update access masks */
-       
+
        for ( i=0; i<sec->dacl->num_aces; i++ ) {
                switch ( sec->dacl->aces[i].access_mask ) {
                        case (GENERIC_READ_ACCESS | GENERIC_WRITE_ACCESS | GENERIC_EXECUTE_ACCESS):
                                sec->dacl->aces[i].access_mask = PRINTER_ACE_PRINT;
                                break;
-                               
+
                        case GENERIC_ALL_ACCESS:
                                sec->dacl->aces[i].access_mask = PRINTER_ACE_FULL_CONTROL;
                                break;
-                               
+
                        case READ_CONTROL_ACCESS:
                                sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
-                       
+
                        default:        /* no change */
                                break;
                }
@@ -416,45 +395,31 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
                                 &global_sid_Builtin_Administrators,
                                 NULL, NULL, &size_new_sec );
        if (!new_sec) {
-               prs_mem_free( &ps );
                return 0;
        }
        sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
        if (!sd_new) {
-               prs_mem_free( &ps );
                return 0;
        }
 
        if ( !(sd_store = sec_desc_merge( ctx, sd_new, sd_orig )) ) {
                DEBUG(0,("sec_desc_upg_fn: Failed to update sec_desc for %s\n", key.dptr ));
-               prs_mem_free( &ps );
                return 0;
        }
-       
-       prs_mem_free( &ps );
 
        /* store it back */
-       
-       sd_size = ndr_size_security_descriptor(sd_store->sd, 0)
+
+       sd_size = ndr_size_security_descriptor(sd_store->sd, NULL, 0)
                + sizeof(SEC_DESC_BUF);
-       if ( !prs_init(&ps, sd_size, ctx, MARSHALL) ) {
-               DEBUG(0,("sec_desc_upg_fn: Failed to allocate prs memory for %s\n", key.dptr ));
-               return 0;
-       }
 
-       if ( !sec_io_desc_buf( "sec_desc_upg_fn", &sd_store, &ps, 1 ) ) {
+       status = marshall_sec_desc_buf(ctx, sd_store, &data.dptr, &data.dsize);
+       if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
-               prs_mem_free( &ps );
                return 0;
        }
 
-       data.dptr = (uint8 *)prs_data_p( &ps );
-       data.dsize = sd_size;
-       
        result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
 
-       prs_mem_free( &ps );
-       
        /* 0 to continue and non-zero to stop traversal */
 
        return (result == -1);
@@ -470,7 +435,7 @@ static bool upgrade_to_version_4(void)
 
        DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
 
-       if ( !(ctx = talloc_init( "upgrade_to_version_4" )) ) 
+       if ( !(ctx = talloc_init( "upgrade_to_version_4" )) )
                return False;
 
        result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
@@ -481,10 +446,10 @@ static bool upgrade_to_version_4(void)
 }
 
 /*******************************************************************
- Fix an issue with security descriptors.  Printer sec_desc must 
- use more than the generic bits that were previously used 
+ Fix an issue with security descriptors.  Printer sec_desc must
+ use more than the generic bits that were previously used
  in <= 3.0.14a.  They must also have a owner and group SID assigned.
- Otherwise, any printers than have been migrated to a Windows 
+ Otherwise, any printers than have been migrated to a Windows
  host using printmig.exe will not be accessible.
 *******************************************************************/
 
@@ -513,7 +478,7 @@ static int normalize_printers_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
        /* delete the original record and store under the normalized key */
 
        if ( tdb_delete( the_tdb, key ) != 0 ) {
-               DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n", 
+               DEBUG(0,("normalize_printers_fn: tdb_delete for [%s] failed!\n",
                        key.dptr));
                return 1;
        }
@@ -537,7 +502,7 @@ static bool upgrade_to_version_5(void)
 
        DEBUG(0,("upgrade_to_version_5: normalizing printer keys\n"));
 
-       if ( !(ctx = talloc_init( "upgrade_to_version_5" )) ) 
+       if ( !(ctx = talloc_init( "upgrade_to_version_5" )) )
                return False;
 
        result = tdb_traverse( tdb_printers, normalize_printers_fn, NULL );
@@ -559,7 +524,7 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
 
        if ( tdb_drivers && tdb_printers && tdb_forms )
                return True;
+
        if (tdb_drivers)
                tdb_close(tdb_drivers);
        tdb_drivers = tdb_open_log(state_path("ntdrivers.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
@@ -568,7 +533,7 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
                        state_path("ntdrivers.tdb"), strerror(errno) ));
                return False;
        }
+
        if (tdb_printers)
                tdb_close(tdb_printers);
        tdb_printers = tdb_open_log(state_path("ntprinters.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
@@ -577,7 +542,7 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
                        state_path("ntprinters.tdb"), strerror(errno) ));
                return False;
        }
+
        if (tdb_forms)
                tdb_close(tdb_forms);
        tdb_forms = tdb_open_log(state_path("ntforms.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
@@ -586,9 +551,9 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
                        state_path("ntforms.tdb"), strerror(errno) ));
                return False;
        }
+
        /* handle a Samba upgrade */
-       
+
        vers_id = tdb_fetch_int32(tdb_drivers, vstring);
        if (vers_id == -1) {
                DEBUG(10, ("Fresh database\n"));
@@ -598,13 +563,13 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
 
        if ( vers_id != NTDRIVERS_DATABASE_VERSION_5 ) {
 
-               if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) { 
+               if ((vers_id == NTDRIVERS_DATABASE_VERSION_1) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_1)) {
                        if (!upgrade_to_version_3())
                                return False;
                        tdb_store_int32(tdb_drivers, vstring, NTDRIVERS_DATABASE_VERSION_3);
                        vers_id = NTDRIVERS_DATABASE_VERSION_3;
-               } 
-               
+               }
+
                if ((vers_id == NTDRIVERS_DATABASE_VERSION_2) || (IREV(vers_id) == NTDRIVERS_DATABASE_VERSION_2)) {
                        /* Written on a bigendian machine with old fetch_int code. Save as le. */
                        /* The only upgrade between V2 and V3 is to save the version in little-endian. */
@@ -632,7 +597,7 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
                        return False;
                }
        }
-       
+
        update_c_setprinter(True);
 
        /*
@@ -652,14 +617,14 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
                           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 
+          tell messages.c that you interested in receiving PRINT_GENERAL
           msgs.  This is done in claim_connection() */
 
 
        if ( lp_security() == SEC_ADS ) {
                win_rc = check_published_printers();
                if (!W_ERROR_IS_OK(win_rc))
-                       DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", dos_errstr(win_rc)));
+                       DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc)));
        }
 
        return True;
@@ -669,25 +634,30 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
  Function to allow filename parsing "the old way".
 ********************************************************************/
 
-static char *driver_unix_convert(connection_struct *conn,
-               const char *old_name,
-               SMB_STRUCT_STAT *pst)
+static NTSTATUS driver_unix_convert(connection_struct *conn,
+                                   const char *old_name,
+                                   struct smb_filename **smb_fname)
 {
+       NTSTATUS status;
        TALLOC_CTX *ctx = talloc_tos();
        char *name = talloc_strdup(ctx, old_name);
-       char *new_name = NULL;
 
        if (!name) {
-               return NULL;
+               return NT_STATUS_NO_MEMORY;
        }
        unix_format(name);
        name = unix_clean_name(ctx, name);
        if (!name) {
-               return NULL;
+               return NT_STATUS_NO_MEMORY;
        }
        trim_string(name,"/","/");
-       unix_convert(ctx,conn, name, false, &new_name, NULL, pst);
-       return new_name;
+
+       status = unix_convert(ctx, conn, name, smb_fname, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       return NT_STATUS_OK;
 }
 
 /*******************************************************************
@@ -698,15 +668,15 @@ static int traverse_counting_printers(TDB_CONTEXT *t, TDB_DATA key,
                                       TDB_DATA data, void *context)
 {
        int *printer_count = (int*)context;
+
        if (memcmp(PRINTERS_PREFIX, key.dptr, sizeof(PRINTERS_PREFIX)-1) == 0) {
                (*printer_count)++;
                DEBUG(10,("traverse_counting_printers: printer = [%s]  printer_count = %d\n", key.dptr, *printer_count));
        }
+
        return 0;
 }
+
 /*******************************************************************
  Update the spooler global c_setprinter. This variable is initialized
  when the parent smbd starts with the number of existing printers. It
@@ -718,12 +688,12 @@ uint32 update_c_setprinter(bool initialize)
 {
        int32 c_setprinter;
        int32 printer_count = 0;
+
        tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
+
        /* Traverse the tdb, counting the printers */
        tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
+
        /* If initializing, set c_setprinter to current printers count
         * otherwise, bump it by the current printer count
         */
@@ -731,12 +701,12 @@ uint32 update_c_setprinter(bool initialize)
                c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER) + printer_count;
        else
                c_setprinter = printer_count;
+
        DEBUG(10,("update_c_setprinter: c_setprinter = %u\n", (unsigned int)c_setprinter));
        tdb_store_int32(tdb_printers, GLOBAL_C_SETPRINTER, c_setprinter);
+
        tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
+
        return (uint32)c_setprinter;
 }
 
@@ -747,12 +717,12 @@ uint32 update_c_setprinter(bool initialize)
 uint32 get_c_setprinter(void)
 {
        int32 c_setprinter = tdb_fetch_int32(tdb_printers, GLOBAL_C_SETPRINTER);
+
        if (c_setprinter == (int32)-1)
                c_setprinter = update_c_setprinter(True);
+
        DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
+
        return (uint32)c_setprinter;
 }
 
@@ -766,29 +736,26 @@ int get_builtin_ntforms(nt_forms_struct **list)
        if (!*list) {
                return 0;
        }
-       return sizeof(default_forms) / sizeof(default_forms[0]);
+       return ARRAY_SIZE(default_forms);
 }
 
 /****************************************************************************
  get a builtin form struct
 ****************************************************************************/
 
-bool get_a_builtin_ntform(UNISTR2 *uni_formname,nt_forms_struct *form)
+bool get_a_builtin_ntform_by_string(const char *form_name, nt_forms_struct *form)
 {
-       int i,count;
-       fstring form_name;
-       unistr2_to_ascii(form_name, uni_formname, sizeof(form_name));
+       int i;
        DEBUGADD(6,("Looking for builtin form %s \n", form_name));
-       count = sizeof(default_forms) / sizeof(default_forms[0]);
-       for (i=0;i<count;i++) {
+       for (i=0; i<ARRAY_SIZE(default_forms); i++) {
                if (strequal(form_name,default_forms[i].name)) {
                        DEBUGADD(6,("Found builtin form %s \n", form_name));
                        memcpy(form,&default_forms[i],sizeof(*form));
-                       break;
+                       return true;
                }
        }
 
-       return (i !=count);
+       return false;
 }
 
 /****************************************************************************
@@ -807,13 +774,13 @@ int get_ntforms(nt_forms_struct **list)
 
        for (kbuf = tdb_firstkey(tdb_forms);
             kbuf.dptr;
-            newkey = tdb_nextkey(tdb_forms, kbuf), safe_free(kbuf.dptr), kbuf=newkey) 
+            newkey = tdb_nextkey(tdb_forms, kbuf), free(kbuf.dptr), kbuf=newkey)
        {
-               if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0) 
+               if (strncmp((const char *)kbuf.dptr, FORMS_PREFIX, strlen(FORMS_PREFIX)) != 0)
                        continue;
-               
+
                dbuf = tdb_fetch(tdb_forms, kbuf);
-               if (!dbuf.dptr) 
+               if (!dbuf.dptr)
                        continue;
 
                fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));
@@ -821,7 +788,7 @@ int get_ntforms(nt_forms_struct **list)
                                 &i, &form.flag, &form.width, &form.length, &form.left,
                                 &form.top, &form.right, &form.bottom);
                SAFE_FREE(dbuf.dptr);
-               if (ret != dbuf.dsize) 
+               if (ret != dbuf.dsize)
                        continue;
 
                *list = SMB_REALLOC_ARRAY(*list, nt_forms_struct, n+1);
@@ -832,7 +799,7 @@ int get_ntforms(nt_forms_struct **list)
                (*list)[n] = form;
                n++;
        }
-       
+
 
        return n;
 }
@@ -888,11 +855,10 @@ int write_ntforms(nt_forms_struct **list, int number)
 /****************************************************************************
 add a form struct at the end of the list
 ****************************************************************************/
-bool add_a_form(nt_forms_struct **list, const FORM *form, int *count)
+bool add_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int *count)
 {
        int n=0;
        bool update;
-       fstring form_name;
 
        /*
         * NT tries to add forms even when
@@ -901,10 +867,9 @@ bool add_a_form(nt_forms_struct **list, const FORM *form, int *count)
         */
 
        update=False;
-       
-       unistr2_to_ascii(form_name, &form->name, sizeof(form_name));
+
        for (n=0; n<*count; n++) {
-               if ( strequal((*list)[n].name, form_name) ) {
+               if ( strequal((*list)[n].name, form->form_name) ) {
                        update=True;
                        break;
                }
@@ -915,20 +880,20 @@ bool add_a_form(nt_forms_struct **list, const FORM *form, int *count)
                        DEBUG(0,("add_a_form: failed to enlarge forms list!\n"));
                        return False;
                }
-               unistr2_to_ascii((*list)[n].name, &form->name, sizeof((*list)[n].name));
+               fstrcpy((*list)[n].name, form->form_name);
                (*count)++;
        }
-       
-       (*list)[n].flag=form->flags;
-       (*list)[n].width=form->size_x;
-       (*list)[n].length=form->size_y;
-       (*list)[n].left=form->left;
-       (*list)[n].top=form->top;
-       (*list)[n].right=form->right;
-       (*list)[n].bottom=form->bottom;
 
-       DEBUG(6,("add_a_form: Successfully %s form [%s]\n", 
-               update ? "updated" : "added", form_name));
+       (*list)[n].flag         = form->flags;
+       (*list)[n].width        = form->size.width;
+       (*list)[n].length       = form->size.height;
+       (*list)[n].left         = form->area.left;
+       (*list)[n].top          = form->area.top;
+       (*list)[n].right        = form->area.right;
+       (*list)[n].bottom       = form->area.bottom;
+
+       DEBUG(6,("add_a_form: Successfully %s form [%s]\n",
+               update ? "updated" : "added", form->form_name));
 
        return True;
 }
@@ -937,25 +902,22 @@ bool add_a_form(nt_forms_struct **list, const FORM *form, int *count)
  Delete a named form struct.
 ****************************************************************************/
 
-bool delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR *ret)
+bool delete_a_form(nt_forms_struct **list, const char *del_name, int *count, WERROR *ret)
 {
        char *key = NULL;
        int n=0;
-       fstring form_name;
 
        *ret = WERR_OK;
 
-       unistr2_to_ascii(form_name, del_name, sizeof(form_name));
-
        for (n=0; n<*count; n++) {
-               if (!strncmp((*list)[n].name, form_name, strlen(form_name))) {
-                       DEBUG(103, ("delete_a_form, [%s] in list\n", form_name));
+               if (!strncmp((*list)[n].name, del_name, strlen(del_name))) {
+                       DEBUG(103, ("delete_a_form, [%s] in list\n", del_name));
                        break;
                }
        }
 
        if (n == *count) {
-               DEBUG(10,("delete_a_form, [%s] not found\n", form_name));
+               DEBUG(10,("delete_a_form, [%s] not found\n", del_name));
                *ret = WERR_INVALID_PARAM;
                return False;
        }
@@ -977,28 +939,26 @@ bool delete_a_form(nt_forms_struct **list, UNISTR2 *del_name, int *count, WERROR
  Update a form struct.
 ****************************************************************************/
 
-void update_a_form(nt_forms_struct **list, const FORM *form, int count)
+void update_a_form(nt_forms_struct **list, struct spoolss_AddFormInfo1 *form, int count)
 {
        int n=0;
-       fstring form_name;
-       unistr2_to_ascii(form_name, &(form->name), sizeof(form_name));
 
-       DEBUG(106, ("[%s]\n", form_name));
+       DEBUG(106, ("[%s]\n", form->form_name));
        for (n=0; n<count; n++) {
                DEBUGADD(106, ("n [%d]:[%s]\n", n, (*list)[n].name));
-               if (!strncmp((*list)[n].name, form_name, strlen(form_name)))
+               if (!strncmp((*list)[n].name, form->form_name, strlen(form->form_name)))
                        break;
        }
 
        if (n==count) return;
 
-       (*list)[n].flag=form->flags;
-       (*list)[n].width=form->size_x;
-       (*list)[n].length=form->size_y;
-       (*list)[n].left=form->left;
-       (*list)[n].top=form->top;
-       (*list)[n].right=form->right;
-       (*list)[n].bottom=form->bottom;
+       (*list)[n].flag         = form->flags;
+       (*list)[n].width        = form->size.width;
+       (*list)[n].length       = form->size.height;
+       (*list)[n].left         = form->area.left;
+       (*list)[n].top          = form->area.top;
+       (*list)[n].right        = form->area.right;
+       (*list)[n].bottom       = form->area.bottom;
 }
 
 /****************************************************************************
@@ -1024,7 +984,7 @@ int get_ntdrivers(fstring **list, const char *architecture, uint32 version)
 
        for (kbuf = tdb_firstkey(tdb_drivers);
             kbuf.dptr;
-            newkey = tdb_nextkey(tdb_drivers, kbuf), safe_free(kbuf.dptr), kbuf=newkey) {
+            newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
 
                if (strncmp((const char *)kbuf.dptr, key, strlen(key)) != 0)
                        continue;
@@ -1317,7 +1277,6 @@ the modification date). Otherwise chose the numerically larger version number.
 static int file_version_is_newer(connection_struct *conn, fstring new_file, fstring old_file)
 {
        bool use_version = true;
-       char *filepath = NULL;
 
        uint32 new_major;
        uint32 new_minor;
@@ -1327,40 +1286,50 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
        uint32 old_minor;
        time_t old_create_time;
 
+       struct smb_filename *smb_fname = NULL;
        files_struct    *fsp = NULL;
        SMB_STRUCT_STAT st;
-       SMB_STRUCT_STAT stat_buf;
 
        NTSTATUS status;
+       int ret;
 
        SET_STAT_INVALID(st);
-       SET_STAT_INVALID(stat_buf);
        new_create_time = (time_t)0;
        old_create_time = (time_t)0;
 
        /* Get file version info (if available) for previous file (if it exists) */
-       filepath = driver_unix_convert(conn,old_file,&stat_buf);
-       if (!filepath) {
+       status = driver_unix_convert(conn, old_file, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
                goto error_exit;
        }
 
-       status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
-                               FILE_GENERIC_READ,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE,
-                               FILE_OPEN,
-                               0,
-                               FILE_ATTRIBUTE_NORMAL,
-                               INTERNAL_OPEN_ONLY,
-                               NULL, &fsp);
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               NULL,                                   /* req */
+               0,                                      /* root_dir_fid */
+               smb_fname,                              /* fname */
+               FILE_GENERIC_READ,                      /* access_mask */
+               FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               NULL);                                  /* pinfo */
 
        if (!NT_STATUS_IS_OK(status)) {
                /* Old file not found, so by definition new file is in fact newer */
-               DEBUG(10,("file_version_is_newer: Can't open old file [%s], errno = %d\n",
-                               filepath, errno));
-               return 1;
+               DEBUG(10,("file_version_is_newer: Can't open old file [%s], "
+                         "errno = %d\n", smb_fname_str_dbg(smb_fname),
+                         errno));
+               ret = 1;
+               goto done;
 
        } else {
-               int ret = get_file_version(fsp, old_file, &old_major, &old_minor);
+               ret = get_file_version(fsp, old_file, &old_major, &old_minor);
                if (ret == -1) {
                        goto error_exit;
                }
@@ -1372,36 +1341,45 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                        if (SMB_VFS_FSTAT(fsp, &st) == -1) {
                                 goto error_exit;
                        }
-                       old_create_time = st.st_mtime;
-                       DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", old_create_time));
+                       old_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
+                       DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
+                               (long)old_create_time));
                }
        }
        close_file(NULL, fsp, NORMAL_CLOSE);
        fsp = NULL;
 
        /* Get file version info (if available) for new file */
-       filepath = driver_unix_convert(conn,new_file,&stat_buf);
-       if (!filepath) {
+       status = driver_unix_convert(conn, new_file, &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
                goto error_exit;
        }
 
-       status = open_file_ntcreate(conn, NULL, filepath, &stat_buf,
-                               FILE_GENERIC_READ,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE,
-                               FILE_OPEN,
-                               0,
-                               FILE_ATTRIBUTE_NORMAL,
-                               INTERNAL_OPEN_ONLY,
-                               NULL, &fsp);
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               NULL,                                   /* req */
+               0,                                      /* root_dir_fid */
+               smb_fname,                              /* fname */
+               FILE_GENERIC_READ,                      /* access_mask */
+               FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               NULL);                                  /* pinfo */
 
        if (!NT_STATUS_IS_OK(status)) {
                /* New file not found, this shouldn't occur if the caller did its job */
-               DEBUG(3,("file_version_is_newer: Can't open new file [%s], errno = %d\n",
-                               filepath, errno));
+               DEBUG(3,("file_version_is_newer: Can't open new file [%s], "
+                        "errno = %d\n", smb_fname_str_dbg(smb_fname), errno));
                goto error_exit;
 
        } else {
-               int ret = get_file_version(fsp, new_file, &new_major, &new_minor);
+               ret = get_file_version(fsp, new_file, &new_major, &new_minor);
                if (ret == -1) {
                        goto error_exit;
                }
@@ -1413,8 +1391,9 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                        if (SMB_VFS_FSTAT(fsp, &st) == -1) {
                                goto error_exit;
                        }
-                       new_create_time = st.st_mtime;
-                       DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n", new_create_time));
+                       new_create_time = convert_timespec_to_time_t(st.st_ex_mtime);
+                       DEBUGADD(6,("file_version_is_newer: mod time = %ld sec\n",
+                               (long)new_create_time));
                }
        }
        close_file(NULL, fsp, NORMAL_CLOSE);
@@ -1426,48 +1405,56 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
                        (new_major == old_major && new_minor > old_minor)) {
 
                        DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
-                       return 1;
+                       ret = 1;
+                       goto done;
                }
                else {
                        DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
-                       return 0;
+                       ret = 0;
+                       goto done;
                }
 
        } else {
                /* Compare modification time/dates and choose the newest time/date */
                if (new_create_time > old_create_time) {
                        DEBUG(6,("file_version_is_newer: Replacing [%s] with [%s]\n", old_file, new_file));
-                       return 1;
+                       ret = 1;
+                       goto done;
                }
                else {
                        DEBUG(6,("file_version_is_newer: Leaving [%s] unchanged\n", old_file));
-                       return 0;
+                       ret = 0;
+                       goto done;
                }
        }
 
-       error_exit:
-               if(fsp)
-                       close_file(NULL, fsp, NORMAL_CLOSE);
-               return -1;
+ error_exit:
+       if(fsp)
+               close_file(NULL, fsp, NORMAL_CLOSE);
+       ret = -1;
+ done:
+       TALLOC_FREE(smb_fname);
+       return ret;
 }
 
 /****************************************************************************
 Determine the correct cVersion associated with an architecture and driver
 ****************************************************************************/
-static uint32 get_correct_cversion(const char *architecture, fstring driverpath_in,
-                                  struct current_user *user, WERROR *perr)
+static uint32 get_correct_cversion(struct pipes_struct *p,
+                                  const char *architecture,
+                                  fstring driverpath_in,
+                                  WERROR *perr)
 {
        int               cversion;
        NTSTATUS          nt_status;
-       char *driverpath = NULL;
-       DATA_BLOB         null_pw;
-       fstring           res_type;
+       struct smb_filename *smb_fname = NULL;
+       char *driverpath = NULL;
        files_struct      *fsp = NULL;
-       SMB_STRUCT_STAT   st;
-       connection_struct *conn;
+       connection_struct *conn = NULL;
        NTSTATUS status;
-
-       SET_STAT_INVALID(st);
+       char *oldcwd;
+       fstring printdollar;
+       int printdollar_snum;
 
        *perr = WERR_INVALID_PARAM;
 
@@ -1485,28 +1472,21 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
                return 3;
        }
 
-       /*
-        * Connect to the print$ share under the same account as the user connected
-        * to the rpc pipe. Note we must still be root to do this.
-        */
+       fstrcpy(printdollar, "print$");
 
-       /* Null password is ok - we are already an authenticated user... */
-       null_pw = data_blob_null;
-       fstrcpy(res_type, "A:");
-       become_root();
-       conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
-       unbecome_root();
-
-       if (conn == NULL) {
-               DEBUG(0,("get_correct_cversion: Unable to connect\n"));
-               *perr = ntstatus_to_werror(nt_status);
+       printdollar_snum = find_service(printdollar);
+       if (printdollar_snum == -1) {
+               *perr = WERR_NO_SUCH_SHARE;
                return -1;
        }
 
-       /* We are temporarily becoming the connection user. */
-       if (!become_user(conn, user->vuid)) {
-               DEBUG(0,("get_correct_cversion: Can't become user!\n"));
-               *perr = WERR_ACCESS_DENIED;
+       nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+                                      lp_pathname(printdollar_snum),
+                                      p->server_info, &oldcwd);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(0,("get_correct_cversion: create_conn_struct "
+                        "returned %s\n", nt_errstr(nt_status)));
+               *perr = ntstatus_to_werror(nt_status);
                return -1;
        }
 
@@ -1521,47 +1501,60 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
                goto error_exit;
        }
 
-       driverpath = driver_unix_convert(conn,driverpath,&st);
-       if (!driverpath) {
-               *perr = WERR_NOMEM;
+       nt_status = driver_unix_convert(conn, driverpath, &smb_fname);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               *perr = ntstatus_to_werror(nt_status);
                goto error_exit;
        }
 
-       if (!vfs_file_exist(conn, driverpath, &st)) {
+       nt_status = vfs_file_exist(conn, smb_fname);
+       if (!NT_STATUS_IS_OK(nt_status)) {
                *perr = WERR_BADFILE;
                goto error_exit;
        }
 
-       status = open_file_ntcreate(conn, NULL, driverpath, &st,
-                               FILE_GENERIC_READ,
-                               FILE_SHARE_READ|FILE_SHARE_WRITE,
-                               FILE_OPEN,
-                               0,
-                               FILE_ATTRIBUTE_NORMAL,
-                               INTERNAL_OPEN_ONLY,
-                               NULL, &fsp);
+       status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               NULL,                                   /* req */
+               0,                                      /* root_dir_fid */
+               smb_fname,                              /* fname */
+               FILE_GENERIC_READ,                      /* access_mask */
+               FILE_SHARE_READ | FILE_SHARE_WRITE,     /* share_access */
+               FILE_OPEN,                              /* create_disposition*/
+               0,                                      /* create_options */
+               FILE_ATTRIBUTE_NORMAL,                  /* file_attributes */
+               INTERNAL_OPEN_ONLY,                     /* oplock_request */
+               0,                                      /* allocation_size */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               NULL);                                  /* pinfo */
 
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
-                               driverpath, errno));
+               DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = "
+                        "%d\n", smb_fname_str_dbg(smb_fname), errno));
                *perr = WERR_ACCESS_DENIED;
                goto error_exit;
        } else {
                uint32 major;
                uint32 minor;
-               int    ret = get_file_version(fsp, driverpath, &major, &minor);
+               int    ret;
+
+               ret = get_file_version(fsp, smb_fname->base_name, &major, &minor);
                if (ret == -1) goto error_exit;
 
                if (!ret) {
-                       DEBUG(6,("get_correct_cversion: Version info not found [%s]\n", driverpath));
+                       DEBUG(6,("get_correct_cversion: Version info not "
+                                "found [%s]\n",
+                                smb_fname_str_dbg(smb_fname)));
                        goto error_exit;
                }
 
                /*
                 * This is a Microsoft'ism. See references in MSDN to VER_FILEVERSION
-                * for more details. Version in this case is not just the version of the 
+                * for more details. Version in this case is not just the version of the
                 * file, but the version in the sense of kernal mode (2) vs. user mode
-                * (3) drivers. Other bits of the version fields are the version info. 
+                * (3) drivers. Other bits of the version fields are the version info.
                 * JRR 010716
                */
                cversion = major & 0x0000ffff;
@@ -1569,41 +1562,46 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
                        case 2: /* WinNT drivers */
                        case 3: /* Win2K drivers */
                                break;
-                       
+
                        default:
-                               DEBUG(6,("get_correct_cversion: cversion invalid [%s]  cversion = %d\n", 
-                                       driverpath, cversion));
+                               DEBUG(6,("get_correct_cversion: cversion "
+                                        "invalid [%s]  cversion = %d\n",
+                                        smb_fname_str_dbg(smb_fname),
+                                        cversion));
                                goto error_exit;
                }
 
-               DEBUG(10,("get_correct_cversion: Version info found [%s]  major = 0x%x  minor = 0x%x\n",
-                                 driverpath, major, minor));
+               DEBUG(10,("get_correct_cversion: Version info found [%s] major"
+                         " = 0x%x  minor = 0x%x\n",
+                         smb_fname_str_dbg(smb_fname), major, minor));
        }
 
        DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
-               driverpath, cversion));
-
-       close_file(NULL, fsp, NORMAL_CLOSE);
-       close_cnum(conn, user->vuid);
-       unbecome_user();
-       *perr = WERR_OK;
-       return cversion;
-
+                 smb_fname_str_dbg(smb_fname), cversion));
 
-  error_exit:
+       goto done;
 
-       if(fsp)
+ error_exit:
+       cversion = -1;
+ done:
+       TALLOC_FREE(smb_fname);
+       if (fsp != NULL) {
                close_file(NULL, fsp, NORMAL_CLOSE);
-
-       close_cnum(conn, user->vuid);
-       unbecome_user();
-       return -1;
+       }
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free(conn);
+       }
+       if (cversion != -1) {
+               *perr = WERR_OK;
+       }
+       return cversion;
 }
 
 /****************************************************************************
 ****************************************************************************/
-static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver,
-                                                                                        struct current_user *user)
+static WERROR clean_up_driver_struct_level_3(struct pipes_struct *rpc_pipe,
+                                            NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
 {
        const char *architecture;
        fstring new_name;
@@ -1649,7 +1647,7 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
        if (!architecture) {
                return WERR_UNKNOWN_PRINTER_DRIVER;
        }
-       
+
        /* jfm:7/16/2000 the client always sends the cversion=0.
         * The server should check which version the driver is by reading
         * the PE header of driver->driverpath.
@@ -1661,15 +1659,18 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
         *      NT 4: cversion=2
         *      NT2K: cversion=3
         */
-       if ((driver->cversion = get_correct_cversion( architecture, driver->driverpath, user, &err)) == -1)
+       if ((driver->cversion = get_correct_cversion(rpc_pipe, architecture,
+                                                    driver->driverpath,
+                                                    &err)) == -1)
                return err;
 
        return WERR_OK;
 }
-       
+
 /****************************************************************************
 ****************************************************************************/
-static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver, struct current_user *user)
+static WERROR clean_up_driver_struct_level_6(struct pipes_struct *rpc_pipe,
+                                            NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver)
 {
        const char *architecture;
        fstring new_name;
@@ -1728,7 +1729,9 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
         *      NT2K: cversion=3
         */
 
-       if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
+       if ((driver->version = get_correct_cversion(rpc_pipe, architecture,
+                                                   driver->driverpath,
+                                                   &err)) == -1)
                        return err;
 
        return WERR_OK;
@@ -1736,21 +1739,24 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
 
 /****************************************************************************
 ****************************************************************************/
-WERROR clean_up_driver_struct(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
-                                                         uint32 level, struct current_user *user)
+WERROR clean_up_driver_struct(struct pipes_struct *rpc_pipe,
+                             NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+                             uint32 level)
 {
        switch (level) {
                case 3:
                {
                        NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
                        driver=driver_abstract.info_3;
-                       return clean_up_driver_struct_level_3(driver, user);
+                       return clean_up_driver_struct_level_3(rpc_pipe,
+                                                             driver);
                }
                case 6:
                {
                        NT_PRINTER_DRIVER_INFO_LEVEL_6 *driver;
                        driver=driver_abstract.info_6;
-                       return clean_up_driver_struct_level_6(driver, user);
+                       return clean_up_driver_struct_level_6(rpc_pipe,
+                                                             driver);
                }
                default:
                        return WERR_INVALID_PARAM;
@@ -1796,89 +1802,148 @@ static char* ffmt(unsigned char *c){
 
 /****************************************************************************
 ****************************************************************************/
-WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
-                                 struct current_user *user, WERROR *perr)
+
+static WERROR move_driver_file_to_download_area(TALLOC_CTX *mem_ctx,
+                                               connection_struct *conn,
+                                               const char *driver_file,
+                                               const char *short_architecture,
+                                               uint32_t driver_version,
+                                               uint32_t version)
+{
+       struct smb_filename *smb_fname_old = NULL;
+       struct smb_filename *smb_fname_new = NULL;
+       char *old_name = NULL;
+       char *new_name = NULL;
+       NTSTATUS status;
+       WERROR ret;
+
+       old_name = talloc_asprintf(mem_ctx, "%s/%s",
+                                  short_architecture, driver_file);
+       W_ERROR_HAVE_NO_MEMORY(old_name);
+
+       new_name = talloc_asprintf(mem_ctx, "%s/%d/%s",
+                                  short_architecture, driver_version, driver_file);
+       if (new_name == NULL) {
+               TALLOC_FREE(old_name);
+               return WERR_NOMEM;
+       }
+
+       if (version != -1 && (version = file_version_is_newer(conn, old_name, new_name)) > 0) {
+
+               status = driver_unix_convert(conn, old_name, &smb_fname_old);
+               if (!NT_STATUS_IS_OK(status)) {
+                       ret = WERR_NOMEM;
+                       goto out;
+               }
+
+               /* Setup a synthetic smb_filename struct */
+               smb_fname_new = TALLOC_ZERO_P(mem_ctx, struct smb_filename);
+               if (!smb_fname_new) {
+                       ret = WERR_NOMEM;
+                       goto out;
+               }
+
+               smb_fname_new->base_name = new_name;
+
+               DEBUG(10,("move_driver_file_to_download_area: copying '%s' to "
+                         "'%s'\n", smb_fname_old->base_name,
+                         smb_fname_new->base_name));
+
+               status = copy_file(mem_ctx, conn, smb_fname_old, smb_fname_new,
+                                  OPENX_FILE_EXISTS_TRUNCATE |
+                                  OPENX_FILE_CREATE_IF_NOT_EXIST,
+                                  0, false);
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       DEBUG(0,("move_driver_file_to_download_area: Unable "
+                                "to rename [%s] to [%s]: %s\n",
+                                smb_fname_old->base_name, new_name,
+                                nt_errstr(status)));
+                       ret = WERR_ACCESS_DENIED;
+                       goto out;
+               }
+       }
+
+       ret = WERR_OK;
+ out:
+       TALLOC_FREE(smb_fname_old);
+       TALLOC_FREE(smb_fname_new);
+       return ret;
+}
+
+WERROR move_driver_to_download_area(struct pipes_struct *p,
+                                   NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
+                                   uint32 level, WERROR *perr)
 {
        NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
        NT_PRINTER_DRIVER_INFO_LEVEL_3 converted_driver;
-       const char *architecture;
+       const char *short_architecture;
+       struct smb_filename *smb_dname = NULL;
        char *new_dir = NULL;
-       char *old_name = NULL;
-       char *new_name = NULL;
-       DATA_BLOB null_pw;
-       connection_struct *conn;
+       connection_struct *conn = NULL;
        NTSTATUS nt_status;
-       fstring res_type;
-       SMB_STRUCT_STAT st;
        int i;
        TALLOC_CTX *ctx = talloc_tos();
        int ver = 0;
+       char *oldcwd;
+       fstring printdollar;
+       int printdollar_snum;
 
        *perr = WERR_OK;
 
-       if (level==3)
-               driver=driver_abstract.info_3;
-       else if (level==6) {
+       switch (level) {
+       case 3:
+               driver = driver_abstract.info_3;
+               break;
+       case 6:
                convert_level_6_to_level3(&converted_driver, driver_abstract.info_6);
                driver = &converted_driver;
-       } else {
+               break;
+       default:
                DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
                return WERR_UNKNOWN_LEVEL;
        }
 
-       architecture = get_short_archi(driver->environment);
-       if (!architecture) {
+       short_architecture = get_short_archi(driver->environment);
+       if (!short_architecture) {
                return WERR_UNKNOWN_PRINTER_DRIVER;
        }
 
-       /*
-        * Connect to the print$ share under the same account as the user connected to the rpc pipe.
-        * Note we must be root to do this.
-        */
-
-       null_pw = data_blob_null;
-       fstrcpy(res_type, "A:");
-       become_root();
-       conn = make_connection_with_chdir("print$", null_pw, res_type, user->vuid, &nt_status);
-       unbecome_root();
+       fstrcpy(printdollar, "print$");
 
-       if (conn == NULL) {
-               DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
-               *perr = ntstatus_to_werror(nt_status);
+       printdollar_snum = find_service(printdollar);
+       if (printdollar_snum == -1) {
+               *perr = WERR_NO_SUCH_SHARE;
                return WERR_NO_SUCH_SHARE;
        }
 
-       /*
-        * Save who we are - we are temporarily becoming the connection user.
-        */
-
-       if (!become_user(conn, conn->vuid)) {
-               DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
-               return WERR_ACCESS_DENIED;
+       nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+                                      lp_pathname(printdollar_snum),
+                                      p->server_info, &oldcwd);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(0,("move_driver_to_download_area: create_conn_struct "
+                        "returned %s\n", nt_errstr(nt_status)));
+               *perr = ntstatus_to_werror(nt_status);
+               return *perr;
        }
 
-       /* WE ARE NOW RUNNING AS USER conn->vuid !!!!! */
-
-       /*
-        * make the directories version and version\driver_name
-        * under the architecture directory.
-        */
-       DEBUG(5,("Creating first directory\n"));
        new_dir = talloc_asprintf(ctx,
                                "%s/%d",
-                               architecture,
+                               short_architecture,
                                driver->cversion);
        if (!new_dir) {
                *perr = WERR_NOMEM;
                goto err_exit;
        }
-       new_dir = driver_unix_convert(conn,new_dir,&st);
-       if (!new_dir) {
+       nt_status = driver_unix_convert(conn, new_dir, &smb_dname);
+       if (!NT_STATUS_IS_OK(nt_status)) {
                *perr = WERR_NOMEM;
                goto err_exit;
        }
 
-       create_directory(conn, NULL, new_dir);
+       DEBUG(5,("Creating first directory: %s\n", smb_dname->base_name));
+
+       create_directory(conn, NULL, smb_dname);
 
        /* For each driver file, archi\filexxx.yyy, if there is a duplicate file
         * listed for this driver which has already been moved, skip it (note:
@@ -1900,143 +1965,74 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
        DEBUG(5,("Moving files now !\n"));
 
        if (driver->driverpath && strlen(driver->driverpath)) {
-               new_name = talloc_asprintf(ctx,
-                                       "%s/%s",
-                                       architecture,
-                                       driver->driverpath);
-               if (!new_name) {
-                       *perr = WERR_NOMEM;
-                       goto err_exit;
-               }
-               old_name = talloc_asprintf(ctx,
-                                       "%s/%s",
-                                       new_dir,
-                                       driver->driverpath);
-               if (!old_name) {
-                       *perr = WERR_NOMEM;
-                       goto err_exit;
-               }
 
-               if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                       new_name = driver_unix_convert(conn,new_name,&st);
-                       if (!new_name) {
-                               *perr = WERR_NOMEM;
-                               goto err_exit;
-                       }
-                       if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
-                                               OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
-                               DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                               new_name, old_name));
-                               *perr = WERR_ACCESS_DENIED;
+               *perr = move_driver_file_to_download_area(ctx,
+                                                         conn,
+                                                         driver->driverpath,
+                                                         short_architecture,
+                                                         driver->cversion,
+                                                         ver);
+               if (!W_ERROR_IS_OK(*perr)) {
+                       if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
                                ver = -1;
                        }
+                       goto err_exit;
                }
        }
 
        if (driver->datafile && strlen(driver->datafile)) {
                if (!strequal(driver->datafile, driver->driverpath)) {
-                       new_name = talloc_asprintf(ctx,
-                                       "%s/%s",
-                                       architecture,
-                                       driver->datafile);
-                       if (!new_name) {
-                               *perr = WERR_NOMEM;
-                               goto err_exit;
-                       }
-                       old_name = talloc_asprintf(ctx,
-                                       "%s/%s",
-                                       new_dir,
-                                       driver->datafile);
-                       if (!old_name) {
-                               *perr = WERR_NOMEM;
-                               goto err_exit;
-                       }
-                       if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               new_name = driver_unix_convert(conn,new_name,&st);
-                               if (!new_name) {
-                                       *perr = WERR_NOMEM;
-                                       goto err_exit;
-                               }
-                               if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
-                                               OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
-                                       DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                                       new_name, old_name));
-                                       *perr = WERR_ACCESS_DENIED;
+
+                       *perr = move_driver_file_to_download_area(ctx,
+                                                                 conn,
+                                                                 driver->datafile,
+                                                                 short_architecture,
+                                                                 driver->cversion,
+                                                                 ver);
+                       if (!W_ERROR_IS_OK(*perr)) {
+                               if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
                                        ver = -1;
                                }
+                               goto err_exit;
                        }
                }
        }
 
        if (driver->configfile && strlen(driver->configfile)) {
                if (!strequal(driver->configfile, driver->driverpath) &&
-                       !strequal(driver->configfile, driver->datafile)) {
-                       new_name = talloc_asprintf(ctx,
-                                               "%s/%s",
-                                               architecture,
-                                               driver->configfile);
-                       if (!new_name) {
-                               *perr = WERR_NOMEM;
-                               goto err_exit;
-                       }
-                       old_name = talloc_asprintf(ctx,
-                                               "%s/%s",
-                                               new_dir,
-                                               driver->configfile);
-                       if (!old_name) {
-                               *perr = WERR_NOMEM;
-                               goto err_exit;
-                       }
-                       if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               new_name = driver_unix_convert(conn,new_name,&st);
-                               if (!new_name) {
-                                       *perr = WERR_NOMEM;
-                                       goto err_exit;
-                               }
-                               if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
-                                               OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
-                                       DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                                       new_name, old_name));
-                                       *perr = WERR_ACCESS_DENIED;
+                   !strequal(driver->configfile, driver->datafile)) {
+
+                       *perr = move_driver_file_to_download_area(ctx,
+                                                                 conn,
+                                                                 driver->configfile,
+                                                                 short_architecture,
+                                                                 driver->cversion,
+                                                                 ver);
+                       if (!W_ERROR_IS_OK(*perr)) {
+                               if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
                                        ver = -1;
                                }
+                               goto err_exit;
                        }
                }
        }
 
        if (driver->helpfile && strlen(driver->helpfile)) {
                if (!strequal(driver->helpfile, driver->driverpath) &&
-                       !strequal(driver->helpfile, driver->datafile) &&
-                       !strequal(driver->helpfile, driver->configfile)) {
-                       new_name = talloc_asprintf(ctx,
-                                       "%s/%s",
-                                       architecture,
-                                       driver->helpfile);
-                       if (!new_name) {
-                               *perr = WERR_NOMEM;
-                               goto err_exit;
-                       }
-                       old_name = talloc_asprintf(ctx,
-                                       "%s/%s",
-                                       new_dir,
-                                       driver->helpfile);
-                       if (!old_name) {
-                               *perr = WERR_NOMEM;
-                               goto err_exit;
-                       }
-                       if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               new_name = driver_unix_convert(conn,new_name,&st);
-                               if (!new_name) {
-                                       *perr = WERR_NOMEM;
-                                       goto err_exit;
-                               }
-                               if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name, OPENX_FILE_EXISTS_TRUNCATE|
-                                               OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
-                                       DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                                       new_name, old_name));
-                                       *perr = WERR_ACCESS_DENIED;
+                   !strequal(driver->helpfile, driver->datafile) &&
+                   !strequal(driver->helpfile, driver->configfile)) {
+
+                       *perr = move_driver_file_to_download_area(ctx,
+                                                                 conn,
+                                                                 driver->helpfile,
+                                                                 short_architecture,
+                                                                 driver->cversion,
+                                                                 ver);
+                       if (!W_ERROR_IS_OK(*perr)) {
+                               if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
                                        ver = -1;
                                }
+                               goto err_exit;
                        }
                }
        }
@@ -2044,9 +2040,9 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
        if (driver->dependentfiles) {
                for (i=0; *driver->dependentfiles[i]; i++) {
                        if (!strequal(driver->dependentfiles[i], driver->driverpath) &&
-                               !strequal(driver->dependentfiles[i], driver->datafile) &&
-                               !strequal(driver->dependentfiles[i], driver->configfile) &&
-                               !strequal(driver->dependentfiles[i], driver->helpfile)) {
+                           !strequal(driver->dependentfiles[i], driver->datafile) &&
+                           !strequal(driver->dependentfiles[i], driver->configfile) &&
+                           !strequal(driver->dependentfiles[i], driver->helpfile)) {
                                int j;
                                for (j=0; j < i; j++) {
                                        if (strequal(driver->dependentfiles[i], driver->dependentfiles[j])) {
@@ -2054,36 +2050,17 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
                                        }
                                }
 
-                               new_name = talloc_asprintf(ctx,
-                                               "%s/%s",
-                                               architecture,
-                                               driver->dependentfiles[i]);
-                               if (!new_name) {
-                                       *perr = WERR_NOMEM;
-                                       goto err_exit;
-                               }
-                               old_name = talloc_asprintf(ctx,
-                                               "%s/%s",
-                                               new_dir,
-                                               driver->dependentfiles[i]);
-                               if (!old_name) {
-                                       *perr = WERR_NOMEM;
-                                       goto err_exit;
-                               }
-                               if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                                       new_name = driver_unix_convert(conn,new_name,&st);
-                                       if (!new_name) {
-                                               *perr = WERR_NOMEM;
-                                               goto err_exit;
-                                       }
-                                       if ( !NT_STATUS_IS_OK(copy_file(ctx,conn, new_name, old_name,
-                                                       OPENX_FILE_EXISTS_TRUNCATE|
-                                                       OPENX_FILE_CREATE_IF_NOT_EXIST, 0, False))) {
-                                               DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
-                                                               new_name, old_name));
-                                               *perr = WERR_ACCESS_DENIED;
+                               *perr = move_driver_file_to_download_area(ctx,
+                                                                         conn,
+                                                                         driver->dependentfiles[i],
+                                                                         short_architecture,
+                                                                         driver->cversion,
+                                                                         ver);
+                               if (!W_ERROR_IS_OK(*perr)) {
+                                       if (W_ERROR_EQUAL(*perr, WERR_ACCESS_DENIED)) {
                                                ver = -1;
                                        }
+                                       goto err_exit;
                                }
                        }
                NextDriver: ;
@@ -2091,9 +2068,12 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
        }
 
   err_exit:
+       TALLOC_FREE(smb_dname);
 
-       close_cnum(conn, user->vuid);
-       unbecome_user();
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free(conn);
+       }
 
        if (W_ERROR_EQUAL(*perr, WERR_OK)) {
                return WERR_OK;
@@ -2135,10 +2115,10 @@ static uint32 add_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver)
                return (uint32)-1;
        }
 
-       /* .inf files do not always list a file for each of the four standard files. 
+       /* .inf files do not always list a file for each of the four standard files.
         * Don't prepend a path to a null filename, or client claims:
-        *   "The server on which the printer resides does not have a suitable 
-        *   <printer driver name> printer driver installed. Click OK if you 
+        *   "The server on which the printer resides does not have a suitable
+        *   <printer driver name> printer driver installed. Click OK if you
         *   wish to install the driver on your local machine."
         */
        if (strlen(driver->driverpath)) {
@@ -2255,7 +2235,7 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in
 
        fstrcpy(info.name, driver);
        fstrcpy(info.defaultdatatype, "RAW");
-       
+
        fstrcpy(info.driverpath, "");
        fstrcpy(info.datafile, "");
        fstrcpy(info.configfile, "");
@@ -2272,13 +2252,15 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in
                SAFE_FREE(info.dependentfiles);
                return WERR_NOMEM;
        }
-       
+
        return WERR_OK;
 }
 
 /****************************************************************************
 ****************************************************************************/
-static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, const char *arch, uint32 version)
+static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr,
+                                    const char *drivername, const char *arch,
+                                    uint32_t version)
 {
        NT_PRINTER_DRIVER_INFO_LEVEL_3 driver;
        TDB_DATA dbuf;
@@ -2366,9 +2348,9 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
        uint32 result;
        NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
        int i;
-       
+
        DEBUG(20,("Dumping printer driver at level [%d]\n", level));
-       
+
        switch (level)
        {
                case 3:
@@ -2377,7 +2359,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
                                result=5;
                        else {
                                info3=driver.info_3;
-                       
+
                                DEBUGADD(20,("version:[%d]\n",         info3->cversion));
                                DEBUGADD(20,("name:[%s]\n",            info3->name));
                                DEBUGADD(20,("environment:[%s]\n",     info3->environment));
@@ -2387,7 +2369,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
                                DEBUGADD(20,("helpfile:[%s]\n",        info3->helpfile));
                                DEBUGADD(20,("monitorname:[%s]\n",     info3->monitorname));
                                DEBUGADD(20,("defaultdatatype:[%s]\n", info3->defaultdatatype));
-                               
+
                                for (i=0; info3->dependentfiles &&
                                          *info3->dependentfiles[i]; i++) {
                                        DEBUGADD(20,("dependentfile:[%s]\n",
@@ -2402,7 +2384,7 @@ static uint32 dump_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32
                        result=1;
                        break;
        }
-       
+
        return result;
 }
 
@@ -2439,7 +2421,7 @@ int pack_devicemode(NT_DEVICEMODE *nt_devmode, uint8 *buf, int buflen)
                        nt_devmode->ttoption,
                        nt_devmode->collate,
                        nt_devmode->logpixels,
-                       
+
                        nt_devmode->fields,
                        nt_devmode->bitsperpel,
                        nt_devmode->pelswidth,
@@ -2475,8 +2457,8 @@ static int pack_values(NT_PRINTER_DATA *data, uint8 *buf, int buflen)
 {
        int             len = 0;
        int             i, j;
-       REGISTRY_VALUE  *val;
-       REGVAL_CTR      *val_ctr;
+       struct regval_blob      *val;
+       struct regval_ctr       *val_ctr;
        char *path = NULL;
        int             num_values;
 
@@ -2550,9 +2532,9 @@ uint32 del_a_printer(const char *sharename)
 
        close_all_print_db();
 
-       if (geteuid() == 0) {
+       if (geteuid() == sec_initial_uid()) {
                if (asprintf(&printdb_path, "%s%s.tdb",
-                               lock_path("printing/"),
+                               cache_path("printing/"),
                                sharename) < 0) {
                        return (uint32)-1;
                }
@@ -2572,7 +2554,7 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
        int retlen;
        WERROR ret;
        TDB_DATA kbuf, dbuf;
-       
+
        /*
         * in addprinter: no servername and the printer is the name
         * in setprinter: servername is \\server
@@ -2687,30 +2669,35 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
        ZERO_STRUCTP(nt_devmode);
 
        slprintf(adevice, sizeof(adevice), "%s", default_devicename);
-       fstrcpy(nt_devmode->devicename, adevice);       
-       
+       fstrcpy(nt_devmode->devicename, adevice);
+
        fstrcpy(nt_devmode->formname, "Letter");
 
-       nt_devmode->specversion      = 0x0401;
+       nt_devmode->specversion      = DMSPEC_NT4_AND_ABOVE;
        nt_devmode->driverversion    = 0x0400;
        nt_devmode->size             = 0x00DC;
        nt_devmode->driverextra      = 0x0000;
-       nt_devmode->fields           = FORMNAME | TTOPTION | PRINTQUALITY |
-                                      DEFAULTSOURCE | COPIES | SCALE |
-                                      PAPERSIZE | ORIENTATION;
-       nt_devmode->orientation      = 1;
-       nt_devmode->papersize        = PAPER_LETTER;
+       nt_devmode->fields           = DEVMODE_FORMNAME |
+                                      DEVMODE_TTOPTION |
+                                      DEVMODE_PRINTQUALITY |
+                                      DEVMODE_DEFAULTSOURCE |
+                                      DEVMODE_COPIES |
+                                      DEVMODE_SCALE |
+                                      DEVMODE_PAPERSIZE |
+                                      DEVMODE_ORIENTATION;
+       nt_devmode->orientation      = DMORIENT_PORTRAIT;
+       nt_devmode->papersize        = DMPAPER_LETTER;
        nt_devmode->paperlength      = 0;
        nt_devmode->paperwidth       = 0;
        nt_devmode->scale            = 0x64;
        nt_devmode->copies           = 1;
-       nt_devmode->defaultsource    = BIN_FORMSOURCE;
-       nt_devmode->printquality     = RES_HIGH;           /* 0x0258 */
-       nt_devmode->color            = COLOR_MONOCHROME;
-       nt_devmode->duplex           = DUP_SIMPLEX;
+       nt_devmode->defaultsource    = DMBIN_FORMSOURCE;
+       nt_devmode->printquality     = DMRES_HIGH;           /* 0x0258 */
+       nt_devmode->color            = DMRES_MONOCHROME;
+       nt_devmode->duplex           = DMDUP_SIMPLEX;
        nt_devmode->yresolution      = 0;
-       nt_devmode->ttoption         = TT_SUBDEV;
-       nt_devmode->collate          = COLLATE_FALSE;
+       nt_devmode->ttoption         = DMTT_SUBDEV;
+       nt_devmode->collate          = DMCOLLATE_FALSE;
        nt_devmode->icmmethod        = 0;
        nt_devmode->icmintent        = 0;
        nt_devmode->mediatype        = 0;
@@ -2727,39 +2714,11 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
        nt_devmode->reserved2        = 0;
        nt_devmode->panningwidth     = 0;
        nt_devmode->panningheight    = 0;
-       
+
        nt_devmode->nt_dev_private = NULL;
        return nt_devmode;
 }
 
-/****************************************************************************
- Deepcopy an NT devicemode.
-****************************************************************************/
-
-NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
-{
-       NT_DEVICEMODE *new_nt_devicemode = NULL;
-
-       if ( !nt_devicemode )
-               return NULL;
-
-       if ((new_nt_devicemode = (NT_DEVICEMODE *)memdup(nt_devicemode, sizeof(NT_DEVICEMODE))) == NULL) {
-               DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
-               return NULL;
-       }
-
-       new_nt_devicemode->nt_dev_private = NULL;
-       if (nt_devicemode->nt_dev_private != NULL) {
-               if ((new_nt_devicemode->nt_dev_private = (uint8 *)memdup(nt_devicemode->nt_dev_private, nt_devicemode->driverextra)) == NULL) {
-                       SAFE_FREE(new_nt_devicemode);
-                       DEBUG(0,("dup_nt_devicemode: malloc fail.\n"));
-                       return NULL;
-        }
-       }
-
-       return new_nt_devicemode;
-}
-
 /****************************************************************************
  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
 ****************************************************************************/
@@ -2801,7 +2760,7 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
        int len = 0;
        int extra_len = 0;
        NT_DEVICEMODE devmode;
-       
+
        ZERO_STRUCT(devmode);
 
        len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
@@ -2830,7 +2789,7 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
                          &devmode.ttoption,
                          &devmode.collate,
                          &devmode.logpixels,
-                       
+
                          &devmode.fields,
                          &devmode.bitsperpel,
                          &devmode.pelswidth,
@@ -2846,14 +2805,14 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
                          &devmode.panningwidth,
                          &devmode.panningheight,
                          &devmode.nt_dev_private);
-       
+
        if (devmode.nt_dev_private) {
                /* the len in tdb_unpack is an int value and
                 * devmode.driverextra is only a short
                 */
                len += tdb_unpack(buf+len, buflen-len, "B", &extra_len, &devmode.nt_dev_private);
                devmode.driverextra=(uint16)extra_len;
-               
+
                /* check to catch an invalid TDB entry so we don't segfault */
                if (devmode.driverextra == 0) {
                        devmode.nt_dev_private = NULL;
@@ -2876,37 +2835,37 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
 /****************************************************************************
  Allocate and initialize a new slot.
 ***************************************************************************/
+
 int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
 {
        NT_PRINTER_KEY  *d;
        int             key_index;
-       
+
        if ( !name || !data )
                return -1;
 
        /* allocate another slot in the NT_PRINTER_KEY array */
-       
+
        if ( !(d = TALLOC_REALLOC_ARRAY( data, data->keys, NT_PRINTER_KEY, data->num_keys+1)) ) {
                DEBUG(0,("add_new_printer_key: Realloc() failed!\n"));
                return -1;
        }
 
        data->keys = d;
-       
+
        key_index = data->num_keys;
-       
+
        /* initialze new key */
-       
+
        data->keys[key_index].name = talloc_strdup( data, name );
-       
-       if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, REGVAL_CTR )) ) 
+
+       if ( !(data->keys[key_index].values = TALLOC_ZERO_P( data, struct regval_ctr )) )
                return -1;
-       
+
        data->num_keys++;
 
        DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
-       
+
        return key_index;
 }
 
@@ -2917,25 +2876,25 @@ int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
 int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
 {
        int i;
-       
+
        for ( i=0; i<data->num_keys; i++ ) {
                if ( strequal( data->keys[i].name, name ) ) {
-               
+
                        /* cleanup memory */
-                       
+
                        TALLOC_FREE( data->keys[i].name );
                        TALLOC_FREE( data->keys[i].values );
-                       
+
                        /* if not the end of the array, move remaining elements down one slot */
-                       
+
                        data->num_keys--;
                        if ( data->num_keys && (i < data->num_keys) )
                                memmove( &data->keys[i], &data->keys[i+1], sizeof(NT_PRINTER_KEY)*(data->num_keys-i) );
-                               
+
                        break;
                }
        }
-       
+
 
        return data->num_keys;
 }
@@ -2943,28 +2902,28 @@ int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
 /****************************************************************************
  search for a registry key name in the existing printer data
  ***************************************************************************/
+
 int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
 {
        int             key_index = -1;
        int             i;
-       
+
        if ( !data || !name )
                return -1;
 
        DEBUG(12,("lookup_printerkey: Looking for [%s]\n", name));
 
        /* loop over all existing keys */
-       
+
        for ( i=0; i<data->num_keys; i++ ) {
                if ( strequal(data->keys[i].name, name) ) {
                        DEBUG(12,("lookup_printerkey: Found [%s]!\n", name));
                        key_index = i;
                        break;
-               
+
                }
        }
-       
+
        return key_index;
 }
 
@@ -2979,7 +2938,7 @@ int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subke
        char    *p;
        fstring *subkeys_ptr = NULL;
        fstring subkeyname;
-       
+
        *subkeys = NULL;
 
        if ( !data )
@@ -2992,33 +2951,33 @@ int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subke
 
        if ( strlen(key) == 0 ) {
                for ( i=0; i<data->num_keys; i++ ) {
-               
+
                        /* found a match, so allocate space and copy the name */
-                       
+
                        if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
-                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 
+                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
                                        num_subkeys+1));
                                return -1;
                        }
-                       
+
                        fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
                        num_subkeys++;
                }
 
                goto done;
        }
-               
+
        /* asking for the subkeys of some key */
        /* subkey paths are stored in the key name using '\' as the delimiter */
 
        for ( i=0; i<data->num_keys; i++ ) {
                if ( StrnCaseCmp(data->keys[i].name, key, strlen(key)) == 0 ) {
-                       
+
                        /* if we found the exact key, then break */
                        key_len = strlen( key );
                        if ( strlen(data->keys[i].name) == key_len )
                                break;
-                       
+
                        /* get subkey path */
 
                        p = data->keys[i].name + key_len;
@@ -3027,51 +2986,51 @@ int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subke
                        fstrcpy( subkeyname, p );
                        if ( (p = strchr( subkeyname, '\\' )) )
                                *p = '\0';
-                       
+
                        /* don't add a key more than once */
-                       
+
                        for ( j=0; j<num_subkeys; j++ ) {
                                if ( strequal( subkeys_ptr[j], subkeyname ) )
                                        break;
                        }
-                       
+
                        if ( j != num_subkeys )
                                continue;
 
                        /* found a match, so allocate space and copy the name */
-                       
+
                        if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
-                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 
+                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n",
                                        num_subkeys+1));
                                return 0;
                        }
-                       
+
                        fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
                        num_subkeys++;
                }
-               
+
        }
-       
+
        /* return error if the key was not found */
-       
+
        if ( i == data->num_keys ) {
                SAFE_FREE(subkeys_ptr);
                return -1;
        }
-       
+
 done:
        /* tag off the end */
-       
+
        if (num_subkeys)
                fstrcpy(subkeys_ptr[num_subkeys], "" );
-       
+
        *subkeys = subkeys_ptr;
 
        return num_subkeys;
 }
 
 #ifdef HAVE_ADS
-static void map_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name, 
+static void map_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
                            const char *sz)
 {
        smb_ucs2_t conv_str[1024];
@@ -3080,11 +3039,11 @@ static void map_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
        regval_ctr_delvalue(ctr, val_name);
        str_size = push_ucs2(NULL, conv_str, sz, sizeof(conv_str),
                             STR_TERMINATE | STR_NOALIGN);
-       regval_ctr_addvalue(ctr, val_name, REG_SZ, 
+       regval_ctr_addvalue(ctr, val_name, REG_SZ,
                            (char *) conv_str, str_size);
 }
 
-static void map_dword_into_ctr(REGVAL_CTR *ctr, const char *val_name, 
+static void map_dword_into_ctr(struct regval_ctr *ctr, const char *val_name,
                               uint32 dword)
 {
        regval_ctr_delvalue(ctr, val_name);
@@ -3092,16 +3051,16 @@ static void map_dword_into_ctr(REGVAL_CTR *ctr, const char *val_name,
                            (char *) &dword, sizeof(dword));
 }
 
-static void map_bool_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+static void map_bool_into_ctr(struct regval_ctr *ctr, const char *val_name,
                              bool b)
 {
        uint8 bin_bool = (b ? 1 : 0);
        regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue(ctr, val_name, REG_BINARY, 
+       regval_ctr_addvalue(ctr, val_name, REG_BINARY,
                            (char *) &bin_bool, sizeof(bin_bool));
 }
 
-static void map_single_multi_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
+static void map_single_multi_sz_into_ctr(struct regval_ctr *ctr, const char *val_name,
                                         const char *multi_sz)
 {
        smb_ucs2_t *conv_strs = NULL;
@@ -3117,14 +3076,13 @@ static void map_single_multi_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
 
        /* Change to byte units. */
        str_size *= sizeof(smb_ucs2_t);
-       push_ucs2(NULL, conv_strs, multi_sz, str_size, 
+       push_ucs2(NULL, conv_strs, multi_sz, str_size,
                  STR_TERMINATE | STR_NOALIGN);
 
        regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ, 
-                           (char *) conv_strs, str_size);      
-       safe_free(conv_strs);
-       
+       regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ,
+                           (char *) conv_strs, str_size);
+       SAFE_FREE(conv_strs);
 }
 
 /****************************************************************************
@@ -3136,7 +3094,7 @@ static void map_single_multi_sz_into_ctr(REGVAL_CTR *ctr, const char *val_name,
 
 static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
 {
-       REGVAL_CTR *ctr = NULL;
+       struct regval_ctr *ctr = NULL;
        fstring longname;
        const char *dnssuffix;
        char *allocated_string = NULL;
@@ -3163,7 +3121,9 @@ static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
 
        map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
 
-       asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename);
+       if (asprintf(&allocated_string, "\\\\%s\\%s", longname, info2->sharename) == -1) {
+               return false;
+       }
        map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
        SAFE_FREE(allocated_string);
 
@@ -3178,7 +3138,7 @@ static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
        map_dword_into_ctr(ctr, SPOOL_REG_PRIORITY, info2->priority);
 
        map_bool_into_ctr(ctr, SPOOL_REG_PRINTKEEPPRINTEDJOBS,
-                         (info2->attributes & 
+                         (info2->attributes &
                           PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
 
        switch (info2->attributes & 0x3) {
@@ -3202,11 +3162,11 @@ static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
 /*****************************************************************
  ****************************************************************/
 
-static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2, 
+static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
                               struct GUID guid)
 {
        int i;
-       REGVAL_CTR *ctr=NULL;
+       struct regval_ctr *ctr=NULL;
        UNISTR2 unistr_guid;
 
        /* find the DsSpooler key */
@@ -3219,15 +3179,15 @@ static void store_printer_guid(NT_PRINTER_INFO_LEVEL_2 *info2,
        /* We used to store this as a REG_BINARY but that causes
           Vista to whine */
 
-       ZERO_STRUCT( unistr_guid );     
-       
-       init_unistr2( &unistr_guid, smb_uuid_string(talloc_tos(), guid),
+       ZERO_STRUCT( unistr_guid );
+
+       init_unistr2( &unistr_guid, GUID_string(talloc_tos(), &guid),
                      UNI_STR_TERMINATE );
 
-       regval_ctr_addvalue(ctr, "objectGUID", REG_SZ, 
-                           (char *)unistr_guid.buffer, 
+       regval_ctr_addvalue(ctr, "objectGUID", REG_SZ,
+                           (char *)unistr_guid.buffer,
                            unistr_guid.uni_max_len*2);
-       
+
 }
 
 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
@@ -3244,6 +3204,12 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
        WERROR win_rc = WERR_OK;
        size_t converted_size;
 
+       /* build the ads mods */
+       ctx = talloc_init("nt_printer_publish_ads");
+       if (ctx == NULL) {
+               return WERR_NOMEM;
+       }
+
        DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
 
        /* figure out where to publish */
@@ -3254,28 +3220,28 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
 
        srv_dn_utf8 = ldap_get_dn((LDAP *)ads->ldap.ld, (LDAPMessage *)res);
        if (!srv_dn_utf8) {
-               ads_destroy(&ads);
+               TALLOC_FREE(ctx);
                return WERR_SERVER_UNAVAILABLE;
        }
        ads_msgfree(ads, res);
        srv_cn_utf8 = ldap_explode_dn(srv_dn_utf8, 1);
        if (!srv_cn_utf8) {
+               TALLOC_FREE(ctx);
                ldap_memfree(srv_dn_utf8);
-               ads_destroy(&ads);
                return WERR_SERVER_UNAVAILABLE;
        }
        /* Now convert to CH_UNIX. */
-       if (!pull_utf8_allocate(&srv_dn, srv_dn_utf8, &converted_size)) {
+       if (!pull_utf8_talloc(ctx, &srv_dn, srv_dn_utf8, &converted_size)) {
+               TALLOC_FREE(ctx);
                ldap_memfree(srv_dn_utf8);
                ldap_memfree(srv_cn_utf8);
-               ads_destroy(&ads);
                return WERR_SERVER_UNAVAILABLE;
        }
-       if (!pull_utf8_allocate(&srv_cn_0, srv_cn_utf8[0], &converted_size)) {
+       if (!pull_utf8_talloc(ctx, &srv_cn_0, srv_cn_utf8[0], &converted_size)) {
+               TALLOC_FREE(ctx);
                ldap_memfree(srv_dn_utf8);
                ldap_memfree(srv_cn_utf8);
-               ads_destroy(&ads);
-               SAFE_FREE(srv_dn);
+               TALLOC_FREE(srv_dn);
                return WERR_SERVER_UNAVAILABLE;
        }
 
@@ -3284,45 +3250,31 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
 
        srv_cn_escaped = escape_rdn_val_string_alloc(srv_cn_0);
        if (!srv_cn_escaped) {
-               SAFE_FREE(srv_cn_0);
-               ldap_memfree(srv_dn_utf8);
-               ads_destroy(&ads);
+               TALLOC_FREE(ctx);
                return WERR_SERVER_UNAVAILABLE;
        }
        sharename_escaped = escape_rdn_val_string_alloc(printer->info_2->sharename);
        if (!sharename_escaped) {
                SAFE_FREE(srv_cn_escaped);
-               SAFE_FREE(srv_cn_0);
-               ldap_memfree(srv_dn_utf8);
-               ads_destroy(&ads);
+               TALLOC_FREE(ctx);
                return WERR_SERVER_UNAVAILABLE;
        }
 
+       prt_dn = talloc_asprintf(ctx, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
 
-       asprintf(&prt_dn, "cn=%s-%s,%s", srv_cn_escaped, sharename_escaped, srv_dn);
-
-       SAFE_FREE(srv_dn);
-       SAFE_FREE(srv_cn_0);
        SAFE_FREE(srv_cn_escaped);
        SAFE_FREE(sharename_escaped);
 
-       /* build the ads mods */
-       ctx = talloc_init("nt_printer_publish_ads");
-       if (ctx == NULL) {
-               SAFE_FREE(prt_dn);
-               return WERR_NOMEM;
-       }
-
        mods = ads_init_mods(ctx);
 
        if (mods == NULL) {
                SAFE_FREE(prt_dn);
-               talloc_destroy(ctx);
+               TALLOC_FREE(ctx);
                return WERR_NOMEM;
        }
 
        get_local_printer_publishing_data(ctx, &mods, printer->info_2->data);
-       ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME, 
+       ads_mod_str(ctx, &mods, SPOOL_REG_PRINTERNAME,
                    printer->info_2->sharename);
 
        /* publish it */
@@ -3337,8 +3289,6 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
 
        if (!ADS_ERR_OK(ads_rc))
                DEBUG(3, ("error publishing %s: %s\n", printer->info_2->sharename, ads_errstr(ads_rc)));
-       
-       talloc_destroy(ctx);
 
        /* retreive the guid and store it locally */
        if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
@@ -3347,9 +3297,9 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
                ads_msgfree(ads, res);
                store_printer_guid(printer->info_2, guid);
                win_rc = mod_a_printer(printer, 2);
-       } 
+       }
+       TALLOC_FREE(ctx);
 
-       SAFE_FREE(prt_dn);
        return win_rc;
 }
 
@@ -3357,26 +3307,28 @@ static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
                                        NT_PRINTER_INFO_LEVEL *printer)
 {
        ADS_STATUS ads_rc;
-       LDAPMessage *res;
+       LDAPMessage *res = NULL;
        char *prt_dn = NULL;
 
        DEBUG(5, ("unpublishing printer %s\n", printer->info_2->printername));
 
        /* remove the printer from the directory */
-       ads_rc = ads_find_printer_on_server(ads, &res, 
+       ads_rc = ads_find_printer_on_server(ads, &res,
                            printer->info_2->sharename, global_myname());
 
-       if (ADS_ERR_OK(ads_rc) && ads_count_replies(ads, res)) {
-               prt_dn = ads_get_dn(ads, res);
+       if (ADS_ERR_OK(ads_rc) && res && ads_count_replies(ads, res)) {
+               prt_dn = ads_get_dn(ads, talloc_tos(), res);
                if (!prt_dn) {
                        ads_msgfree(ads, res);
                        return WERR_NOMEM;
                }
                ads_rc = ads_del_dn(ads, prt_dn);
-               ads_memfree(ads, prt_dn);
+               TALLOC_FREE(prt_dn);
        }
 
-       ads_msgfree(ads, res);
+       if (res) {
+               ads_msgfree(ads, res);
+       }
        return WERR_OK;
 }
 
@@ -3399,8 +3351,8 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
                goto done;
 
        switch (action) {
-       case SPOOL_DS_PUBLISH:
-       case SPOOL_DS_UPDATE:
+       case DSPRINT_PUBLISH:
+       case DSPRINT_UPDATE:
                /* set the DsSpooler info and attributes */
                if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) {
                        win_rc = WERR_NOMEM;
@@ -3409,7 +3361,7 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
 
                printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
                break;
-       case SPOOL_DS_UNPUBLISH:
+       case DSPRINT_UNPUBLISH:
                printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
                break;
        default:
@@ -3434,7 +3386,7 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
        ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
                NULL, NULL);
 
-       /* ads_connect() will find the DC for us */                                         
+       /* ads_connect() will find the DC for us */
        ads_rc = ads_connect(ads);
        if (!ADS_ERR_OK(ads_rc)) {
                DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
@@ -3443,11 +3395,11 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
        }
 
        switch (action) {
-       case SPOOL_DS_PUBLISH:
-       case SPOOL_DS_UPDATE:
+       case DSPRINT_PUBLISH:
+       case DSPRINT_UPDATE:
                win_rc = nt_printer_publish_ads(ads, printer);
                break;
-       case SPOOL_DS_UNPUBLISH:
+       case DSPRINT_UNPUBLISH:
                win_rc = nt_printer_unpublish_ads(ads, printer);
                break;
        }
@@ -3476,7 +3428,7 @@ WERROR check_published_printers(void)
        ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
                NULL, NULL);
 
-       /* ads_connect() will find the DC for us */                                         
+       /* ads_connect() will find the DC for us */
        ads_rc = ads_connect(ads);
        if (!ADS_ERR_OK(ads_rc)) {
                DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
@@ -3502,12 +3454,12 @@ WERROR check_published_printers(void)
        return WERR_OK;
 }
 
-bool is_printer_published(Printer_entry *print_hnd, int snum, 
+bool is_printer_published(Printer_entry *print_hnd, int snum,
                          struct GUID *guid)
 {
        NT_PRINTER_INFO_LEVEL *printer = NULL;
-       REGVAL_CTR *ctr;
-       REGISTRY_VALUE *guid_val;
+       struct regval_ctr *ctr;
+       struct regval_blob *guid_val;
        WERROR win_rc;
        int i;
        bool ret = False;
@@ -3518,7 +3470,7 @@ bool is_printer_published(Printer_entry *print_hnd, int snum,
            !(printer->info_2->attributes & PRINTER_ATTRIBUTE_PUBLISHED) ||
            ((i = lookup_printerkey(printer->info_2->data, SPOOL_DSSPOOLER_KEY)) < 0) ||
            !(ctr = printer->info_2->data->keys[i].values) ||
-           !(guid_val = regval_ctr_getvalue(ctr, "objectGUID"))) 
+           !(guid_val = regval_ctr_getvalue(ctr, "objectGUID")))
        {
                free_a_printer(&printer, 2);
                return False;
@@ -3526,18 +3478,18 @@ bool is_printer_published(Printer_entry *print_hnd, int snum,
 
        /* fetching printer guids really ought to be a separate function. */
 
-       if ( guid ) {   
+       if ( guid ) {
                fstring guid_str;
-               
-               /* We used to store the guid as REG_BINARY, then swapped 
+
+               /* We used to store the guid as REG_BINARY, then swapped
                   to REG_SZ for Vista compatibility so check for both */
 
                switch ( regval_type(guid_val) ){
-               case REG_SZ:            
-                       rpcstr_pull( guid_str, regval_data_p(guid_val), 
+               case REG_SZ:
+                       rpcstr_pull( guid_str, regval_data_p(guid_val),
                                     sizeof(guid_str)-1, -1, STR_TERMINATE );
-                       ret = smb_string_to_uuid( guid_str, guid );
-                       break;                  
+                       ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
+                       break;
                case REG_BINARY:
                        if ( regval_size(guid_val) != sizeof(struct GUID) ) {
                                ret = False;
@@ -3547,7 +3499,7 @@ bool is_printer_published(Printer_entry *print_hnd, int snum,
                        break;
                default:
                        DEBUG(0,("is_printer_published: GUID value stored as "
-                                "invaluid type (%d)\n", regval_type(guid_val) ));                      
+                                "invaluid type (%d)\n", regval_type(guid_val) ));
                        break;
                }
        }
@@ -3566,7 +3518,7 @@ WERROR check_published_printers(void)
        return WERR_OK;
 }
 
-bool is_printer_published(Printer_entry *print_hnd, int snum, 
+bool is_printer_published(Printer_entry *print_hnd, int snum,
                          struct GUID *guid)
 {
        return False;
@@ -3575,41 +3527,41 @@ bool is_printer_published(Printer_entry *print_hnd, int snum,
 
 /****************************************************************************
  ***************************************************************************/
+
 WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
 {
        NT_PRINTER_DATA *data;
        int             i;
        int             removed_keys = 0;
        int             empty_slot;
-       
+
        data = p2->data;
        empty_slot = data->num_keys;
 
        if ( !key )
                return WERR_INVALID_PARAM;
-       
+
        /* remove all keys */
 
        if ( !strlen(key) ) {
-       
+
                TALLOC_FREE( data );
 
                p2->data = NULL;
 
                DEBUG(8,("delete_all_printer_data: Removed all Printer Data from printer [%s]\n",
                        p2->printername ));
-       
+
                return WERR_OK;
        }
 
        /* remove a specific key (and all subkeys) */
-       
+
        for ( i=0; i<data->num_keys; i++ ) {
                if ( StrnCaseCmp( data->keys[i].name, key, strlen(key)) == 0 ) {
                        DEBUG(8,("delete_all_printer_data: Removed all Printer Data from key [%s]\n",
                                data->keys[i].name));
-               
+
                        TALLOC_FREE( data->keys[i].name );
                        TALLOC_FREE( data->keys[i].values );
 
@@ -3634,10 +3586,10 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
                return WERR_INVALID_PARAM;
 
        /* move everything down */
-       
+
        for ( i=empty_slot+1; i<data->num_keys; i++ ) {
                if ( data->keys[i].name ) {
-                       memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) ); 
+                       memcpy( &data->keys[empty_slot], &data->keys[i], sizeof(NT_PRINTER_KEY) );
                        ZERO_STRUCTP( &data->keys[i] );
                        empty_slot++;
                        removed_keys++;
@@ -3645,7 +3597,7 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
        }
 
        /* update count */
-               
+
        data->num_keys -= removed_keys;
 
        /* sanity check to see if anything is left */
@@ -3662,62 +3614,62 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
 
 /****************************************************************************
  ***************************************************************************/
+
 WERROR delete_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
 {
        WERROR          result = WERR_OK;
        int             key_index;
-       
+
        /* we must have names on non-zero length */
-       
+
        if ( !key || !*key|| !value || !*value )
                return WERR_INVALID_NAME;
-               
+
        /* find the printer key first */
 
        key_index = lookup_printerkey( p2->data, key );
        if ( key_index == -1 )
                return WERR_OK;
-       
+
        /* make sure the value exists so we can return the correct error code */
-       
+
        if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
                return WERR_BADFILE;
-               
+
        regval_ctr_delvalue( p2->data->keys[key_index].values, value );
-       
+
        DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
                key, value ));
-       
+
        return result;
 }
 
 /****************************************************************************
  ***************************************************************************/
-WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value, 
+
+WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value,
                            uint32 type, uint8 *data, int real_len )
 {
        WERROR          result = WERR_OK;
        int             key_index;
 
        /* we must have names on non-zero length */
-       
+
        if ( !key || !*key|| !value || !*value )
                return WERR_INVALID_NAME;
-               
+
        /* find the printer key first */
-       
+
        key_index = lookup_printerkey( p2->data, key );
        if ( key_index == -1 )
                key_index = add_new_printer_key( p2->data, key );
-               
+
        if ( key_index == -1 )
                return WERR_NOMEM;
-       
+
        regval_ctr_addvalue( p2->data->keys[key_index].values, value,
                type, (const char *)data, real_len );
-       
+
        DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
                key, value, type, real_len  ));
 
@@ -3727,7 +3679,7 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha
 /****************************************************************************
  ***************************************************************************/
 
-REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
+struct regval_blob* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value )
 {
        int             key_index;
 
@@ -3754,7 +3706,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
        char            *str;
        int             size;
        uint8           *data_p;
-       REGISTRY_VALUE  *regval_p;
+       struct regval_blob      *regval_p;
        int             key_index;
 
        /* add the "PrinterDriverData" key first for performance reasons */
@@ -3841,10 +3793,10 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
                        memcpy( &guid, data_p, sizeof(struct GUID) );
 
                        init_unistr2( &unistr_guid,
-                                     smb_uuid_string(talloc_tos(), guid), 
+                                     GUID_string(talloc_tos(), &guid),
                                      UNI_STR_TERMINATE );
 
-                       regval_ctr_addvalue( printer_data->keys[key_index].values, 
+                       regval_ctr_addvalue( printer_data->keys[key_index].values,
                                             valuename, REG_SZ,
                                             (const char *)unistr_guid.buffer,
                                             unistr_guid.uni_str_len*2 );
@@ -3852,8 +3804,8 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
                } else {
                        /* add the value */
 
-                       regval_ctr_addvalue( printer_data->keys[key_index].values, 
-                                            valuename, type, (const char *)data_p, 
+                       regval_ctr_addvalue( printer_data->keys[key_index].values,
+                                            valuename, type, (const char *)data_p,
                                             size );
                }
 
@@ -3992,14 +3944,14 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
        int snum = lp_servicenumber(sharename);
 
        slprintf(info->servername, sizeof(info->servername)-1, "\\\\%s", servername);
-       slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s", 
+       slprintf(info->printername, sizeof(info->printername)-1, "\\\\%s\\%s",
                servername, sharename);
        fstrcpy(info->sharename, sharename);
        fstrcpy(info->portname, SAMBA_PRINTER_PORT_NAME);
 
        /* by setting the driver name to an empty string, a local NT admin
           can now run the **local** APW to install a local printer driver
-          for a Samba shared printer in 2.2.  Without this, drivers **must** be 
+          for a Samba shared printer in 2.2.  Without this, drivers **must** be
           installed on the Samba server for NT clients --jerry */
 #if 0  /* JERRY --do not uncomment-- */
        if (!*info->drivername)
@@ -4014,7 +3966,7 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
        fstrcpy(info->datatype, "RAW");
 
 #ifdef HAVE_CUPS
-       if (get_loc_com && (enum printing_types)lp_printing(snum) == PRINT_CUPS ) {             
+       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) )
@@ -4141,7 +4093,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
 
        /*
         * Some client drivers freak out if there is a NULL devmode
-        * (probably the driver is not checking before accessing 
+        * (probably the driver is not checking before accessing
         * the devmode pointer)   --jerry
         *
         * See comments in get_a_printer_2_default()
@@ -4155,7 +4107,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
 
        slprintf( adevice, sizeof(adevice), "%s", info->printername );
        if (info->devmode) {
-               fstrcpy(info->devmode->devicename, adevice);    
+               fstrcpy(info->devmode->devicename, adevice);
        }
 
        if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
@@ -4184,7 +4136,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
        DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
                 sharename, info->printername, info->drivername));
 
-       return WERR_OK; 
+       return WERR_OK;
 }
 
 /****************************************************************************
@@ -4194,9 +4146,9 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
 {
        uint32 result;
        NT_PRINTER_INFO_LEVEL_2 *info2;
-       
+
        DEBUG(106,("Dumping printer at level [%d]\n", level));
-       
+
        switch (level) {
                case 2:
                {
@@ -4205,7 +4157,7 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
                        else
                        {
                                info2=printer->info_2;
-                       
+
                                DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
                                DEBUGADD(106,("priority:[%d]\n", info2->priority));
                                DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
@@ -4238,7 +4190,7 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
                        result=1;
                        break;
        }
-       
+
        return result;
 }
 
@@ -4283,15 +4235,15 @@ static uint32 rev_changeid(void)
 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
 {
        WERROR result;
-       
-       dump_a_printer(printer, level); 
-       
+
+       dump_a_printer(printer, level);
+
        switch (level) {
                case 2:
                {
                        /*
                         * Update the changestamp.  Emperical tests show that the
-                        * ChangeID is always updated,but c_setprinter is  
+                        * ChangeID is always updated,but c_setprinter is
                         *  global spooler variable (not per printer).
                         */
 
@@ -4306,7 +4258,7 @@ WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
                         * NT->NT       An admin connection to a remote
                         *              printer show changes imeediately in
                         *              the properities dialog
-                        *      
+                        *
                         *              A non-admin connection will only show the
                         *              changes after viewing the properites page
                         *              2 times.  Seems to be related to a
@@ -4450,7 +4402,7 @@ bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
  Delete driver init data stored for a specified driver
 ****************************************************************************/
 
-bool del_driver_init(char *drivername)
+bool del_driver_init(const char *drivername)
 {
        char *key;
        bool ret;
@@ -4473,7 +4425,7 @@ bool del_driver_init(char *drivername)
 }
 
 /****************************************************************************
- Pack up the DEVMODE and values for a printer into a 'driver init' entry 
+ 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
@@ -4543,9 +4495,9 @@ done:
 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
 {
        uint32 result;
-       
-       dump_a_printer(printer, level); 
-       
+
+       dump_a_printer(printer, level);
+
        switch (level) {
                case 2:
                        result = update_driver_init_2(printer->info_2);
@@ -4554,34 +4506,35 @@ static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
                        result = 1;
                        break;
        }
-       
+
        return result;
 }
 
 /****************************************************************************
- Convert the printer data value, a REG_BINARY array, into an initialization 
+ 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 *ctx, NT_DEVICEMODE *nt_devmode, uint8 *data, uint32 data_len )
+static bool convert_driver_init(TALLOC_CTX *mem_ctx, NT_DEVICEMODE *nt_devmode,
+                               const uint8_t *data, uint32_t data_len)
 {
-       bool       result = False;
-       prs_struct ps;
-       DEVICEMODE devmode;
+       struct spoolss_DeviceMode devmode;
+       enum ndr_err_code ndr_err;
+       DATA_BLOB blob;
 
        ZERO_STRUCT(devmode);
 
-       prs_init_empty(&ps, ctx, UNMARSHALL);
-       ps.data_p      = (char *)data;
-       ps.buffer_size = data_len;
+       blob = data_blob_const(data, data_len);
 
-       if (spoolss_io_devmode("phantom DEVMODE", &ps, 0, &devmode))
-               result = convert_devicemode("", &devmode, &nt_devmode);
-       else
-               DEBUG(10,("convert_driver_init: error parsing DEVMODE\n"));
+       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 result;
+       return convert_devicemode("", &devmode, &nt_devmode);
 }
 
 /****************************************************************************
@@ -4600,7 +4553,7 @@ static bool convert_driver_init( TALLOC_CTX *ctx, NT_DEVICEMODE *nt_devmode, uin
 
  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
@@ -4612,12 +4565,12 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
        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
@@ -4631,7 +4584,7 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
                        status = WERR_NOMEM;
                        goto done;
                }
-       
+
                ZERO_STRUCTP(nt_devmode);
 
                /*
@@ -4650,7 +4603,7 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
        /*
         * 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 ) {
@@ -4658,10 +4611,10 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
                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 
+        * 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);
@@ -4669,11 +4622,11 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
                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;
@@ -4686,7 +4639,7 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
 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 );
@@ -4695,7 +4648,7 @@ WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *dat
                        status = WERR_UNKNOWN_LEVEL;
                        break;
        }
-       
+
        return status;
 }
 
@@ -4703,22 +4656,22 @@ WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *dat
  Get a NT_PRINTER_INFO_LEVEL struct. It returns malloced memory.
 
  Previously the code had a memory allocation problem because it always
- used the TALLOC_CTX from the Printer_entry*.   This context lasts 
- as a long as the original handle is open.  So if the client made a lot 
+ used the TALLOC_CTX from the Printer_entry*.   This context lasts
+ as a long as the original handle is open.  So if the client made a lot
  of getprinter[data]() calls, the memory usage would climb.  Now we use
- a short lived TALLOC_CTX for printer_info_2 objects returned.  We 
+ a short lived TALLOC_CTX for printer_info_2 objects returned.  We
  still use the Printer_entry->ctx for maintaining the cache copy though
- since that object must live as long as the handle by definition.  
+ since that object must live as long as the handle by definition.
                                                     --jerry
 
 ****************************************************************************/
 
-static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level, 
+static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level,
                        const char *sharename, bool get_loc_com)
 {
        WERROR result;
        fstring servername;
-       
+
        DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
 
        if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
@@ -4734,7 +4687,7 @@ static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_
                                return WERR_NOMEM;
                        }
 
-                       if ( print_hnd ) 
+                       if ( print_hnd )
                                fstrcpy( servername, print_hnd->servername );
                        else {
                                fstrcpy( servername, "%L" );
@@ -4749,20 +4702,20 @@ static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_
 
                        if ( !W_ERROR_IS_OK(result) ) {
                                TALLOC_FREE( *pp_printer );
-                               DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", 
-                                       sharename, (unsigned int)level, dos_errstr(result)));
+                               DEBUG(10,("get_a_printer: [%s] level %u returning %s\n",
+                                       sharename, (unsigned int)level, win_errstr(result)));
                                return result;
                        }
 
                        dump_a_printer( *pp_printer, level);
-                       
+
                        break;
-                       
+
                default:
                        TALLOC_FREE( *pp_printer );
                        return WERR_UNKNOWN_LEVEL;
        }
-       
+
        return WERR_OK;
 }
 
@@ -4794,10 +4747,10 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
 
        if ( !printer )
                return 0;
-       
+
        switch (level) {
                case 2:
-                       if ( printer->info_2 ) 
+                       if ( printer->info_2 )
                                free_nt_printer_info_level_2(&printer->info_2);
                        break;
 
@@ -4818,7 +4771,7 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
        uint32 result;
        DEBUG(104,("adding a printer at level [%d]\n", level));
        dump_a_printer_driver(driver, level);
-       
+
        switch (level) {
                case 3:
                        result=add_a_printer_driver_3(driver.info_3);
@@ -4832,44 +4785,45 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
                        result=1;
                        break;
        }
-       
+
        return result;
 }
 /****************************************************************************
 ****************************************************************************/
 
-WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
-                            fstring drivername, const char *architecture, uint32 version)
+WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32_t level,
+                           const char *drivername, const char *architecture,
+                           uint32_t version)
 {
        WERROR result;
-       
+
        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->info_3, drivername, 
+                               result = get_a_printer_driver_3(&driver->info_3, drivername,
                                                architecture, 3);
-                                               
+
                                if ( !W_ERROR_IS_OK(result) ) {
-                                       result = get_a_printer_driver_3( &driver->info_3, 
+                                       result = get_a_printer_driver_3( &driver->info_3,
                                                        drivername, architecture, 2 );
                                }
                        } else {
-                               result = get_a_printer_driver_3(&driver->info_3, drivername, 
-                                       architecture, version);                         
+                               result = get_a_printer_driver_3(&driver->info_3, drivername,
+                                       architecture, version);
                        }
                        break;
-                       
+
                default:
                        result=W_ERROR(1);
                        break;
        }
-       
+
        if (W_ERROR_IS_OK(result))
                dump_a_printer_driver(*driver, level);
-               
+
        return result;
 }
 
@@ -4878,7 +4832,7 @@ WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level,
 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
 {
        uint32 result;
-       
+
        switch (level) {
                case 3:
                {
@@ -4930,50 +4884,50 @@ bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        bool in_use = False;
 
-       if ( !info_3 ) 
+       if ( !info_3 )
                return False;
 
        DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
-       
+
        /* loop through the printers.tdb and check for the drivername */
-       
+
        for (snum=0; snum<n_services && !in_use; snum++) {
                if ( !(lp_snum_ok(snum) && lp_print_ok(snum) ) )
                        continue;
-               
+
                if ( !W_ERROR_IS_OK(get_a_printer(NULL, &printer, 2, lp_servicename(snum))) )
                        continue;
-               
-               if ( strequal(info_3->name, printer->info_2->drivername) ) 
+
+               if ( strequal(info_3->name, printer->info_2->drivername) )
                        in_use = True;
-               
+
                free_a_printer( &printer, 2 );
        }
-       
+
        DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
-       
+
        if ( in_use ) {
                NT_PRINTER_DRIVER_INFO_LEVEL d;
                WERROR werr;
-               
+
                DEBUG(5,("printer_driver_in_use: driver \"%s\" is currently in use\n", info_3->name));
-               
-               /* we can still remove the driver if there is one of 
+
+               /* 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->environment ) ) {
-                       werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", DRIVER_ANY_VERSION );                       
+                       werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", DRIVER_ANY_VERSION );
                }
                else {
                        switch ( info_3->cversion ) {
                        case 2:
                                werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", 3 );
                                break;
-                       case 3: 
+                       case 3:
                                werr = get_a_printer_driver( &d, 3, info_3->name, "Windows NT x86", 2 );
                                break;
                        default:
-                               DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n", 
+                               DEBUG(0,("printer_driver_in_use: ERROR! unknown driver version (%d)\n",
                                        info_3->cversion));
                                werr = WERR_UNKNOWN_PRINTER_DRIVER;
                                break;
@@ -4981,16 +4935,16 @@ bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
                }
 
                /* now check the error code */
-                               
+
                if ( W_ERROR_IS_OK(werr) ) {
                        /* it's ok to remove the driver, we have other architctures left */
                        in_use = False;
                        free_a_printer_driver( d, 3 );
                }
        }
-       
+
        /* report that the driver is not in use by default */
-       
+
        return in_use;
 }
 
@@ -4998,7 +4952,7 @@ bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
 /**********************************************************************
  Check to see if a ogiven file is in use by *info
  *********************************************************************/
+
 static bool drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
 {
        int i = 0;
@@ -5022,86 +4976,86 @@ static bool drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
 
        if ( strequal(file, info->helpfile) )
                return True;
-       
+
        /* see of there are any dependent files to examine */
-       
+
        if ( !info->dependentfiles )
                return False;
-       
+
        while ( *info->dependentfiles[i] ) {
                if ( strequal(file, info->dependentfiles[i]) )
                        return True;
                i++;
        }
-       
+
        return False;
 
 }
 
 /**********************************************************************
- Utility function to remove the dependent file pointed to by the 
- input parameter from the list 
+ Utility function to remove the dependent file pointed to by the
+ input parameter from the list
  *********************************************************************/
 
 static void trim_dependent_file( fstring files[], int idx )
 {
-       
+
        /* bump everything down a slot */
 
        while( *files[idx+1] ) {
                fstrcpy( files[idx], files[idx+1] );
                idx++;
        }
-       
+
        *files[idx] = '\0';
 
-       return; 
+       return;
 }
 
 /**********************************************************************
- Check if any of the files used by src are also used by drv 
+ Check if any of the files used by src are also used by drv
  *********************************************************************/
 
-static bool trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src, 
+static bool trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
                                       NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
 {
        bool    in_use = False;
        int     i = 0;
-       
+
        if ( !src || !drv )
                return False;
-               
+
        /* check each file.  Remove it from the src structure if it overlaps */
-       
+
        if ( drv_file_in_use(src->driverpath, drv) ) {
                in_use = True;
                DEBUG(10,("Removing driverfile [%s] from list\n", src->driverpath));
                fstrcpy( src->driverpath, "" );
        }
-               
+
        if ( drv_file_in_use(src->datafile, drv) ) {
                in_use = True;
                DEBUG(10,("Removing datafile [%s] from list\n", src->datafile));
                fstrcpy( src->datafile, "" );
        }
-               
+
        if ( drv_file_in_use(src->configfile, drv) ) {
                in_use = True;
                DEBUG(10,("Removing configfile [%s] from list\n", src->configfile));
                fstrcpy( src->configfile, "" );
        }
-               
+
        if ( drv_file_in_use(src->helpfile, drv) ) {
                in_use = True;
                DEBUG(10,("Removing helpfile [%s] from list\n", src->helpfile));
                fstrcpy( src->helpfile, "" );
        }
-       
+
        /* are there any dependentfiles to examine? */
-       
+
        if ( !src->dependentfiles )
                return in_use;
-               
+
        while ( *src->dependentfiles[i] ) {
                if ( drv_file_in_use(src->dependentfiles[i], drv) ) {
                        in_use = True;
@@ -5109,18 +5063,18 @@ static bool trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
                        trim_dependent_file( src->dependentfiles, i );
                } else
                        i++;
-       }               
-               
+       }
+
        return in_use;
 }
 
 /****************************************************************************
-  Determine whether or not a particular driver files are currently being 
-  used by any other driver.  
-  
+  Determine whether or not a particular driver files are currently being
+  used by any other driver.
+
   Return value is True if any files were in use by other drivers
   and False otherwise.
-  
+
   Upon return, *info has been modified to only contain the driver files
   which are not in use
 
@@ -5142,36 +5096,36 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
 
        if ( !info )
                return False;
-       
+
        version = info->cversion;
-       
+
        /* loop over all driver versions */
-       
+
        DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
-       
+
        /* get the list of drivers */
-               
+
        list = NULL;
        ndrivers = get_ntdrivers(&list, info->environment, version);
-               
-       DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n", 
+
+       DEBUGADD(4,("we have:[%d] drivers in environment [%s] and version [%d]\n",
                ndrivers, info->environment, version));
 
        /* check each driver for overlap in files */
-               
+
        for (i=0; i<ndrivers; i++) {
                DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
-                       
+
                ZERO_STRUCT(driver);
-                       
+
                if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], info->environment, version)) ) {
                        SAFE_FREE(list);
                        return True;
                }
-                       
+
                /* check if d2 uses any files from d1 */
                /* only if this is a different driver than the one being deleted */
-                       
+
                if ( !strequal(info->name, driver.info_3->name) ) {
                        if ( trim_overlap_drv_files(info, driver.info_3) ) {
                                /* mz: Do not instantly return -
@@ -5196,55 +5150,67 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
        return in_use;
 }
 
+static NTSTATUS driver_unlink_internals(connection_struct *conn,
+                                       const char *name)
+{
+       struct smb_filename *smb_fname = NULL;
+       NTSTATUS status;
+
+       status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL,
+           &smb_fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = unlink_internals(conn, NULL, 0, smb_fname, false);
+
+       TALLOC_FREE(smb_fname);
+       return status;
+}
+
 /****************************************************************************
   Actually delete the driver files.  Make sure that
   printer_driver_files_in_use() return False before calling
   this.
 ****************************************************************************/
 
-static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user )
+static bool delete_driver_files(struct pipes_struct *rpc_pipe,
+                               NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3)
 {
        int i = 0;
        char *s;
        const char *file;
        connection_struct *conn;
-       DATA_BLOB null_pw;
        NTSTATUS nt_status;
-       fstring res_type;
-       SMB_STRUCT_STAT  st;
+       char *oldcwd;
+       fstring printdollar;
+       int printdollar_snum;
+       bool ret = false;
 
        if ( !info_3 )
                return False;
 
        DEBUG(6,("delete_driver_files: deleting driver [%s] - version [%d]\n", info_3->name, info_3->cversion));
 
-       /*
-        * Connect to the print$ share under the same account as the
-        * user connected to the rpc pipe. Note we must be root to
-        * do this.
-        */
+       fstrcpy(printdollar, "print$");
 
-       null_pw = data_blob_null;
-       fstrcpy(res_type, "A:");
-       become_root();
-        conn = make_connection_with_chdir( "print$", null_pw, res_type, user->vuid, &nt_status );
-       unbecome_root();
+       printdollar_snum = find_service(printdollar);
+       if (printdollar_snum == -1) {
+               return false;
+       }
 
-       if ( !conn ) {
-               DEBUG(0,("delete_driver_files: Unable to connect\n"));
-               return False;
+       nt_status = create_conn_struct(talloc_tos(), &conn, printdollar_snum,
+                                      lp_pathname(printdollar_snum),
+                                      rpc_pipe->server_info, &oldcwd);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               DEBUG(0,("delete_driver_files: create_conn_struct "
+                        "returned %s\n", nt_errstr(nt_status)));
+               return false;
        }
 
        if ( !CAN_WRITE(conn) ) {
                DEBUG(3,("delete_driver_files: Cannot delete print driver when [print$] is read-only\n"));
-               return False;
-       }
-
-        /* Save who we are - we are temporarily becoming the connection user. */
-
-       if ( !become_user(conn, conn->vuid) ) {
-               DEBUG(0,("delete_driver_files: Can't become user!\n"));
-               return False;
+               goto fail;
        }
 
        /* now delete the files; must strip the '\print$' string from
@@ -5253,36 +5219,32 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
        if ( *info_3->driverpath ) {
                if ( (s = strchr( &info_3->driverpath[1], '\\' )) != NULL ) {
                        file = s;
-                       driver_unix_convert(conn,file,&st);
                        DEBUG(10,("deleting driverfile [%s]\n", s));
-                       unlink_internals(conn, NULL, 0, file, False);
+                       driver_unlink_internals(conn, file);
                }
        }
 
        if ( *info_3->configfile ) {
                if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
                        file = s;
-                       driver_unix_convert(conn,file,&st);
                        DEBUG(10,("deleting configfile [%s]\n", s));
-                       unlink_internals(conn, NULL, 0, file, False);
+                       driver_unlink_internals(conn, file);
                }
        }
 
        if ( *info_3->datafile ) {
                if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
                        file = s;
-                       driver_unix_convert(conn,file,&st);
                        DEBUG(10,("deleting datafile [%s]\n", s));
-                       unlink_internals(conn, NULL, 0, file, False);
+                       driver_unlink_internals(conn, file);
                }
        }
 
        if ( *info_3->helpfile ) {
                if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
                        file = s;
-                       driver_unix_convert(conn,file,&st);
                        DEBUG(10,("deleting helpfile [%s]\n", s));
-                       unlink_internals(conn, NULL, 0, file, False);
+                       driver_unlink_internals(conn, file);
                }
        }
 
@@ -5296,18 +5258,23 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
 
                        if ( (p = strchr( info_3->dependentfiles[i]+1, '\\' )) != NULL ) {
                                file = p;
-                               driver_unix_convert(conn,file,&st);
                                DEBUG(10,("deleting dependent file [%s]\n", file));
-                               unlink_internals(conn, NULL, 0, file, False);
+                               driver_unlink_internals(conn, file);
                        }
 
                        i++;
                }
        }
 
-       unbecome_user();
-
-       return true;
+       goto done;
+ fail:
+       ret = false;
+ done:
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free(conn);
+       }
+       return ret;
 }
 
 /****************************************************************************
@@ -5315,8 +5282,9 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
  previously looked up.
  ***************************************************************************/
 
-WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct current_user *user,
-                              uint32 version, bool delete_files )
+WERROR delete_printer_driver(struct pipes_struct *rpc_pipe,
+                            NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3,
+                            uint32 version, bool delete_files )
 {
        char *key = NULL;
        const char     *arch;
@@ -5366,7 +5334,7 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
         */
 
        if ( delete_files )
-               delete_driver_files( info_3, user );
+               delete_driver_files(rpc_pipe, info_3);
 
        DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
        SAFE_FREE(key);
@@ -5382,11 +5350,12 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
 {
        SEC_DESC_BUF *new_secdesc_ctr = NULL;
        SEC_DESC_BUF *old_secdesc_ctr = NULL;
-       prs_struct ps;
-       bool prs_init_done = false;
        TALLOC_CTX *mem_ctx = NULL;
        TDB_DATA kbuf;
+       TDB_DATA dbuf;
+       DATA_BLOB blob;
        WERROR status;
+       NTSTATUS nt_status;
 
        mem_ctx = talloc_init("nt_printing_setsec");
        if (mem_ctx == NULL)
@@ -5448,25 +5417,19 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
 
        /* Store the security descriptor in a tdb */
 
-       if (!prs_init(&ps,
-               (uint32)ndr_size_security_descriptor(new_secdesc_ctr->sd, 0)
-               + sizeof(SEC_DESC_BUF), mem_ctx, MARSHALL) ) {
-               status = WERR_NOMEM;
-               goto out;
-       }
-
-
-       prs_init_done = true;
-
-       if (!sec_io_desc_buf("nt_printing_setsec", &new_secdesc_ctr,
-                            &ps, 1)) {
-               status = WERR_BADFUNC;
+       nt_status = marshall_sec_desc_buf(mem_ctx, new_secdesc_ctr,
+                                         &blob.data, &blob.length);
+       if (!NT_STATUS_IS_OK(nt_status)) {
+               status = ntstatus_to_werror(nt_status);
                goto out;
        }
 
        kbuf = make_printers_secdesc_tdbkey(mem_ctx, sharename );
 
-       if (tdb_prs_store(tdb_printers, kbuf, &ps)==0) {
+       dbuf.dptr = (unsigned char *)blob.data;
+       dbuf.dsize = blob.length;
+
+       if (tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE)==0) {
                status = WERR_OK;
        } else {
                DEBUG(1,("Failed to store secdesc for %s\n", sharename));
@@ -5474,12 +5437,10 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
        }
 
        /* Free malloc'ed memory */
+       talloc_free(blob.data);
 
  out:
 
-       if (prs_init_done) {
-               prs_mem_free(&ps);
-       }
        if (mem_ctx)
                talloc_destroy(mem_ctx);
        return status;
@@ -5507,16 +5468,16 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
                     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
 
        /* Add the domain admins group if we are a DC */
-       
+
        if ( IS_DC ) {
                DOM_SID domadmins_sid;
-               
+
                sid_copy(&domadmins_sid, get_global_sam_sid());
                sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
-               
+
                sa = PRINTER_ACE_FULL_CONTROL;
-               init_sec_ace(&ace[i++], &domadmins_sid, 
-                       SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 
+               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);
@@ -5525,8 +5486,8 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
                sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);
 
                sa = PRINTER_ACE_FULL_CONTROL;
-               init_sec_ace(&ace[i++], &adm_sid, 
-                       SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 
+               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);
@@ -5535,10 +5496,10 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
        /* 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, 
+       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, 
+       init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators,
                SEC_ACE_TYPE_ACCESS_ALLOWED,
                sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
 
@@ -5551,7 +5512,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
 
        if ((psa = make_sec_acl(ctx, NT4_ACL_REVISION, i, ace)) != NULL) {
                psd = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
-                       &global_sid_Builtin_Administrators, 
+                       &global_sid_Builtin_Administrators,
                        &global_sid_Builtin_Administrators,
                        NULL, psa, &sd_size);
        }
@@ -5575,47 +5536,45 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
 
 bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
 {
-       prs_struct ps;
        TDB_DATA kbuf;
+       TDB_DATA dbuf;
+       DATA_BLOB blob;
        char *temp;
+       NTSTATUS status;
 
        if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
                sharename = temp + 1;
        }
 
-       ZERO_STRUCT(ps);
-
        /* Fetch security descriptor from tdb */
 
-       kbuf = make_printers_secdesc_tdbkey(ctx, sharename  );
-
-       if (tdb_prs_fetch(tdb_printers, kbuf, &ps, ctx)!=0 ||
-           !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
-
-               prs_mem_free(&ps);
-
-               DEBUG(4,("using default secdesc for %s\n", sharename));
-
-               if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
-                       return False;
-               }
+       kbuf = make_printers_secdesc_tdbkey(ctx, sharename);
 
-               /* Save default security descriptor for later */
+       dbuf = tdb_fetch(tdb_printers, kbuf);
+       if (dbuf.dptr) {
 
-               if (!prs_init(&ps, (uint32)ndr_size_security_descriptor((*secdesc_ctr)->sd, 0) +
-                       sizeof(SEC_DESC_BUF), ctx, MARSHALL))
-                       return False;
+               status = unmarshall_sec_desc_buf(ctx, dbuf.dptr, dbuf.dsize,
+                                                secdesc_ctr);
+               SAFE_FREE(dbuf.dptr);
 
-               if (sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
-                       tdb_prs_store(tdb_printers, kbuf, &ps);
+               if (NT_STATUS_IS_OK(status)) {
+                       return true;
                }
+       }
 
-               prs_mem_free(&ps);
-
-               return True;
+       *secdesc_ctr = construct_default_printer_sdb(ctx);
+       if (!*secdesc_ctr) {
+               return false;
        }
 
-       prs_mem_free(&ps);
+       status = marshall_sec_desc_buf(ctx, *secdesc_ctr,
+                                      &blob.data, &blob.length);
+       if (NT_STATUS_IS_OK(status)) {
+               dbuf.dptr = (unsigned char *)blob.data;
+               dbuf.dsize = blob.length;
+               tdb_trans_store(tdb_printers, kbuf, dbuf, TDB_REPLACE);
+               talloc_free(blob.data);
+       }
 
        /* If security descriptor is owned by S-1-1-0 and winbindd is up,
           this security descriptor has been created when winbindd was
@@ -5665,14 +5624,14 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
                SEC_ACL *the_acl = (*secdesc_ctr)->sd->dacl;
                int i;
 
-               DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", 
+               DEBUG(10, ("secdesc_ctr for %s has %d aces:\n",
                           sharename, the_acl->num_aces));
 
                for (i = 0; i < the_acl->num_aces; i++) {
                        DEBUG(10, ("%s %d %d 0x%08x\n",
                                   sid_string_dbg(&the_acl->aces[i].trustee),
-                                  the_acl->aces[i].type, the_acl->aces[i].flags, 
-                                  the_acl->aces[i].access_mask)); 
+                                  the_acl->aces[i].type, the_acl->aces[i].flags,
+                                  the_acl->aces[i].access_mask));
                }
        }
 
@@ -5692,15 +5651,15 @@ bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **s
        A printer and a printer driver are 2 different things.
        NT manages them separatelly, Samba does the same.
        Why ? Simply because it's easier and it makes sense !
-       
+
        Now explanation: You have 3 printers behind your samba server,
        2 of them are the same make and model (laser A and B). But laser B
        has an 3000 sheet feeder and laser A doesn't such an option.
        Your third printer is an old dot-matrix model for the accounting :-).
-       
+
        If the /usr/local/samba/lib directory (default dir), you will have
        5 files to describe all of this.
-       
+
        3 files for the printers (1 by printer):
                NTprinter_laser A
                NTprinter_laser B
@@ -5758,7 +5717,7 @@ void map_job_permissions(SEC_DESC *sd)
        print_queue_purge
 
   Try access control in the following order (for performance reasons):
-    1)  root ans SE_PRINT_OPERATOR can do anything (easy check) 
+    1)  root and SE_PRINT_OPERATOR can do anything (easy check)
     2)  check security descriptor (bit comparisons in memory)
     3)  "printer admins" (may result in numerous calls to winbind)
 
@@ -5769,16 +5728,15 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
        SEC_DESC_BUF *secdesc = NULL;
        uint32 access_granted;
        NTSTATUS status;
-       bool result;
        const char *pname;
        TALLOC_CTX *mem_ctx = NULL;
        SE_PRIV se_printop = SE_PRINT_OPERATOR;
-       
+
        /* If user is NULL then use the current_user structure */
 
        /* Always allow root or SE_PRINT_OPERATROR to do anything */
 
-       if (server_info->utok.uid == 0
+       if (server_info->utok.uid == sec_initial_uid()
            || user_has_privileges(server_info->ptok, &se_printop ) ) {
                return True;
        }
@@ -5812,11 +5770,11 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
                   against.  This is because print jobs are child objects
                   objects of a printer. */
 
-               secdesc = se_create_child_secdesc(mem_ctx, parent_secdesc->sd, False);
+               status = se_create_child_secdesc_buf(mem_ctx, &secdesc, parent_secdesc->sd, False);
 
-               if (!secdesc) {
+               if (!NT_STATUS_IS_OK(status)) {
                        talloc_destroy(mem_ctx);
-                       errno = ENOMEM;
+                       errno = map_errno_from_nt_status(status);
                        return False;
                }
 
@@ -5826,10 +5784,10 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
        }
 
        /* Check access */
-       result = se_access_check(secdesc->sd, server_info->ptok, access_type,
-                                &access_granted, &status);
+       status = se_access_check(secdesc->sd, server_info->ptok, access_type,
+                                &access_granted);
 
-       DEBUG(4, ("access check was %s\n", result ? "SUCCESS" : "FAILURE"));
+       DEBUG(4, ("access check was %s\n", NT_STATUS_IS_OK(status) ? "SUCCESS" : "FAILURE"));
 
         /* see if we need to try the printer admin list */
 
@@ -5842,12 +5800,12 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
         }
 
        talloc_destroy(mem_ctx);
-       
-       if (!result) {
+
+       if (!NT_STATUS_IS_OK(status)) {
                errno = EACCES;
        }
 
-       return result;
+       return NT_STATUS_IS_OK(status);
 }
 
 /****************************************************************************