s3-printing: eliminate another non sec_initial_uid using security check.
[ira/wip.git] / source3 / printing / nt_printing.c
index 9c1323eaa2650c6af5e40a045ee8ca673e261c12..3e206becf4a930e16799a9398b7c4d4861aa525a 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 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 */
 #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}
 };
 
        {"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 },
 
        {"Windows 4.0",          SPL_ARCH_WIN40,        0 },
        {"Windows NT x86",       SPL_ARCH_W32X86,       2 },
@@ -276,9 +262,9 @@ static TDB_DATA make_printers_secdesc_tdbkey(TALLOC_CTX *ctx,
 static bool upgrade_to_version_3(void)
 {
        TDB_DATA kbuf, newkey, dbuf;
 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"));
        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), free(kbuf.dptr), kbuf=newkey) {
 
        for (kbuf = tdb_firstkey(tdb_drivers); kbuf.dptr;
                        newkey = tdb_nextkey(tdb_drivers, kbuf), free(kbuf.dptr), kbuf=newkey) {
 
@@ -297,7 +283,7 @@ static bool upgrade_to_version_3(void)
                                return False;
                        }
                }
                                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) {
                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;
                        }
                }
                                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) {
                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;
                        }
                }
                                return False;
                        }
                }
+
                SAFE_FREE(dbuf.dptr);
        }
 
                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.
  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 )
 {
  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;
        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 */
 
 
        /* 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 );
                /* 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) {
                return 0;
        }
 
        if (!sd_orig) {
-               prs_mem_free( &ps );
                return 0;
        }
        sec = sd_orig->sd;
                return 0;
        }
        sec = sd_orig->sd;
-               
+
        /* is this even valid? */
        /* is this even valid? */
-       
+
        if ( !sec->dacl ) {
        if ( !sec->dacl ) {
-               prs_mem_free( &ps );
                return 0;
        }
                return 0;
        }
-               
+
        /* update access masks */
        /* 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;
        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 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;
                        case READ_CONTROL_ACCESS:
                                sec->dacl->aces[i].access_mask = PRINTER_ACE_MANAGE_DOCUMENTS;
-                       
+
                        default:        /* no change */
                                break;
                }
                        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) {
                                 &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) {
                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 ));
                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;
        }
                return 0;
        }
-       
-       prs_mem_free( &ps );
 
        /* store it back */
 
        /* 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);
                + 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 ));
                DEBUG(0,("sec_desc_upg_fn: Failed to parse new sec_desc for %s\n", key.dptr ));
-               prs_mem_free( &ps );
                return 0;
        }
 
                return 0;
        }
 
-       data.dptr = (uint8 *)prs_data_p( &ps );
-       data.dsize = sd_size;
-       
        result = tdb_store( tdb_printers, key, data, TDB_REPLACE );
 
        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);
        /* 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"));
 
 
        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 );
                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.
  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.
 *******************************************************************/
 
  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 ) {
        /* 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;
        }
                        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"));
 
 
        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 );
                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_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);
        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;
        }
                        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);
        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;
        }
                        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);
        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;
        }
                        state_path("ntforms.tdb"), strerror(errno) ));
                return False;
        }
+
        /* handle a Samba upgrade */
        /* handle a Samba upgrade */
-       
+
        vers_id = tdb_fetch_int32(tdb_drivers, vstring);
        if (vers_id == -1) {
                DEBUG(10, ("Fresh database\n"));
        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_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 (!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. */
                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;
                }
        }
                        return False;
                }
        }
-       
+
        update_c_setprinter(True);
 
        /*
        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
                           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))
           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;
        }
 
        return True;
@@ -669,25 +634,30 @@ bool nt_printing_init(struct messaging_context *msg_ctx)
  Function to allow filename parsing "the old way".
 ********************************************************************/
 
  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);
        TALLOC_CTX *ctx = talloc_tos();
        char *name = talloc_strdup(ctx, old_name);
-       char *new_name = NULL;
 
        if (!name) {
 
        if (!name) {
-               return NULL;
+               return NT_STATUS_NO_MEMORY;
        }
        unix_format(name);
        name = unix_clean_name(ctx, name);
        if (!name) {
        }
        unix_format(name);
        name = unix_clean_name(ctx, name);
        if (!name) {
-               return NULL;
+               return NT_STATUS_NO_MEMORY;
        }
        trim_string(name,"/","/");
        }
        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;
                                       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));
        }
        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;
 }
        return 0;
 }
+
 /*******************************************************************
  Update the spooler global c_setprinter. This variable is initialized
  when the parent smbd starts with the number of existing printers. It
 /*******************************************************************
  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;
 {
        int32 c_setprinter;
        int32 printer_count = 0;
+
        tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
        tdb_lock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
+
        /* Traverse the tdb, counting the printers */
        tdb_traverse(tdb_printers, traverse_counting_printers, (void *)&printer_count);
        /* 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
         */
        /* 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;
                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);
        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);
        tdb_unlock_bystring(tdb_printers, GLOBAL_C_SETPRINTER);
+
        return (uint32)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);
 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);
        if (c_setprinter == (int32)-1)
                c_setprinter = update_c_setprinter(True);
+
        DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
        DEBUG(10,("get_c_setprinter: c_setprinter = %d\n", c_setprinter));
+
        return (uint32)c_setprinter;
 }
 
        return (uint32)c_setprinter;
 }
 
@@ -766,29 +736,26 @@ int get_builtin_ntforms(nt_forms_struct **list)
        if (!*list) {
                return 0;
        }
        if (!*list) {
                return 0;
        }
-       return sizeof(default_forms) / sizeof(default_forms[0]);
+       return ARRAY_SIZE(default_forms);
 }
 
 /****************************************************************************
  get a builtin form struct
 ****************************************************************************/
 
 }
 
 /****************************************************************************
  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));
        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));
                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;
 
        for (kbuf = tdb_firstkey(tdb_forms);
             kbuf.dptr;
-            newkey = tdb_nextkey(tdb_forms, kbuf), 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;
                        continue;
-               
+
                dbuf = tdb_fetch(tdb_forms, kbuf);
                dbuf = tdb_fetch(tdb_forms, kbuf);
-               if (!dbuf.dptr) 
+               if (!dbuf.dptr)
                        continue;
 
                fstrcpy(form.name, (const char *)kbuf.dptr+strlen(FORMS_PREFIX));
                        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);
                                 &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);
                        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++;
        }
                (*list)[n] = form;
                n++;
        }
-       
+
 
        return 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
 ****************************************************************************/
 /****************************************************************************
 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;
 {
        int n=0;
        bool update;
-       fstring form_name;
 
        /*
         * NT tries to add forms even when
 
        /*
         * 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;
         */
 
        update=False;
-       
-       unistr2_to_ascii(form_name, &form->name, sizeof(form_name));
+
        for (n=0; n<*count; n++) {
        for (n=0; n<*count; n++) {
-               if ( strequal((*list)[n].name, form_name) ) {
+               if ( strequal((*list)[n].name, form->form_name) ) {
                        update=True;
                        break;
                }
                        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;
                }
                        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)++;
        }
                (*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;
 }
 
        return True;
 }
@@ -937,25 +902,22 @@ bool add_a_form(nt_forms_struct **list, const FORM *form, int *count)
  Delete a named form struct.
 ****************************************************************************/
 
  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;
 {
        char *key = NULL;
        int n=0;
-       fstring form_name;
 
        *ret = WERR_OK;
 
 
        *ret = WERR_OK;
 
-       unistr2_to_ascii(form_name, del_name, sizeof(form_name));
-
        for (n=0; n<*count; n++) {
        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) {
                        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;
        }
                *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.
 ****************************************************************************/
 
  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;
 {
        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));
        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;
 
                        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;
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
@@ -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;
 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;
 
        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;
 
        uint32 old_minor;
        time_t old_create_time;
 
+       struct smb_filename *smb_fname = NULL;
        files_struct    *fsp = NULL;
        SMB_STRUCT_STAT st;
        files_struct    *fsp = NULL;
        SMB_STRUCT_STAT st;
-       SMB_STRUCT_STAT stat_buf;
 
        NTSTATUS status;
 
        NTSTATUS status;
+       int ret;
 
        SET_STAT_INVALID(st);
 
        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) */
        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;
        }
 
                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 */
 
        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 {
 
        } 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;
                }
                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;
                        }
                        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 */
                }
        }
        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;
        }
 
                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 */
 
        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 {
                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;
                }
                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;
                        }
                        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);
                }
        }
        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));
                        (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));
                }
                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));
                }
 
        } 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));
                }
                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
 ****************************************************************************/
 }
 
 /****************************************************************************
 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;
 {
        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;
        files_struct      *fsp = NULL;
-       SMB_STRUCT_STAT   st;
-       connection_struct *conn;
+       connection_struct *conn = NULL;
        NTSTATUS status;
        NTSTATUS status;
-
-       SET_STAT_INVALID(st);
+       char *oldcwd;
+       fstring printdollar;
+       int printdollar_snum;
 
        *perr = WERR_INVALID_PARAM;
 
 
        *perr = WERR_INVALID_PARAM;
 
@@ -1485,28 +1472,21 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
                return 3;
        }
 
                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;
        }
 
                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;
        }
 
                return -1;
        }
 
@@ -1521,47 +1501,60 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
                goto error_exit;
        }
 
                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;
        }
 
                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;
        }
 
                *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)) {
 
        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;
                *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) {
                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
                        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
                 * 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;
                 * 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;
                        case 2: /* WinNT drivers */
                        case 3: /* Win2K drivers */
                                break;
-                       
+
                        default:
                        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;
                }
 
                                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",
        }
 
        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_file(NULL, fsp, NORMAL_CLOSE);
-
-       close_cnum(conn, user->vuid);
-       unbecome_user();
-       return -1;
+       }
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free_internal(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;
 {
        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;
        }
        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.
        /* 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
         */
         *      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;
 }
                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;
 {
        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
         */
 
         *      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;
                        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;
 {
        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;
                }
                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;
                }
                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;
 {
        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 *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;
        NTSTATUS nt_status;
-       fstring res_type;
-       SMB_STRUCT_STAT st;
        int i;
        TALLOC_CTX *ctx = talloc_tos();
        int ver = 0;
        int i;
        TALLOC_CTX *ctx = talloc_tos();
        int ver = 0;
+       char *oldcwd;
+       fstring printdollar;
+       int printdollar_snum;
 
        *perr = WERR_OK;
 
 
        *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;
                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;
        }
 
                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;
        }
 
                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;
        }
 
                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",
        new_dir = talloc_asprintf(ctx,
                                "%s/%d",
-                               architecture,
+                               short_architecture,
                                driver->cversion);
        if (!new_dir) {
                *perr = WERR_NOMEM;
                goto err_exit;
        }
                                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;
        }
 
                *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:
 
        /* 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)) {
        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;
                        }
                                ver = -1;
                        }
+                       goto err_exit;
                }
        }
 
        if (driver->datafile && strlen(driver->datafile)) {
                if (!strequal(driver->datafile, driver->driverpath)) {
                }
        }
 
        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;
                                }
                                        ver = -1;
                                }
+                               goto err_exit;
                        }
                }
        }
 
        if (driver->configfile && strlen(driver->configfile)) {
                if (!strequal(driver->configfile, driver->driverpath) &&
                        }
                }
        }
 
        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;
                                }
                                        ver = -1;
                                }
+                               goto err_exit;
                        }
                }
        }
 
        if (driver->helpfile && strlen(driver->helpfile)) {
                if (!strequal(driver->helpfile, driver->driverpath) &&
                        }
                }
        }
 
        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;
                                }
                                        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) &&
        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])) {
                                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;
                                        }
                                                ver = -1;
                                        }
+                                       goto err_exit;
                                }
                        }
                NextDriver: ;
                                }
                        }
                NextDriver: ;
@@ -2091,9 +2068,12 @@ WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract
        }
 
   err_exit:
        }
 
   err_exit:
+       TALLOC_FREE(smb_dname);
 
 
-       close_cnum(conn, user->vuid);
-       unbecome_user();
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free_internal(conn);
+       }
 
        if (W_ERROR_EQUAL(*perr, WERR_OK)) {
                return WERR_OK;
 
        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;
        }
 
                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:
         * 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)) {
         *   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.name, driver);
        fstrcpy(info.defaultdatatype, "RAW");
-       
+
        fstrcpy(info.driverpath, "");
        fstrcpy(info.datafile, "");
        fstrcpy(info.configfile, "");
        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;
        }
                SAFE_FREE(info.dependentfiles);
                return WERR_NOMEM;
        }
-       
+
        return WERR_OK;
 }
 
 /****************************************************************************
 ****************************************************************************/
        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;
 {
        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;
        uint32 result;
        NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3;
        int i;
-       
+
        DEBUG(20,("Dumping printer driver at level [%d]\n", level));
        DEBUG(20,("Dumping printer driver at level [%d]\n", level));
-       
+
        switch (level)
        {
                case 3:
        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;
                                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));
                                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));
                                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",
                                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;
        }
                        result=1;
                        break;
        }
-       
+
        return result;
 }
 
        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->ttoption,
                        nt_devmode->collate,
                        nt_devmode->logpixels,
-                       
+
                        nt_devmode->fields,
                        nt_devmode->bitsperpel,
                        nt_devmode->pelswidth,
                        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;
 {
        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;
 
        char *path = NULL;
        int             num_values;
 
@@ -2550,9 +2532,9 @@ uint32 del_a_printer(const char *sharename)
 
        close_all_print_db();
 
 
        close_all_print_db();
 
-       if (geteuid() == 0) {
+       if (geteuid() == sec_initial_uid()) {
                if (asprintf(&printdb_path, "%s%s.tdb",
                if (asprintf(&printdb_path, "%s%s.tdb",
-                               lock_path("printing/"),
+                               cache_path("printing/"),
                                sharename) < 0) {
                        return (uint32)-1;
                }
                                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;
        int retlen;
        WERROR ret;
        TDB_DATA kbuf, dbuf;
-       
+
        /*
         * in addprinter: no servername and the printer is the name
         * in setprinter: servername is \\server
        /*
         * in addprinter: no servername and the printer is the name
         * in setprinter: servername is \\server
@@ -2687,8 +2669,8 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
        ZERO_STRUCTP(nt_devmode);
 
        slprintf(adevice, sizeof(adevice), "%s", 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;
        fstrcpy(nt_devmode->formname, "Letter");
 
        nt_devmode->specversion      = 0x0401;
@@ -2727,39 +2709,11 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
        nt_devmode->reserved2        = 0;
        nt_devmode->panningwidth     = 0;
        nt_devmode->panningheight    = 0;
        nt_devmode->reserved2        = 0;
        nt_devmode->panningwidth     = 0;
        nt_devmode->panningheight    = 0;
-       
+
        nt_devmode->nt_dev_private = NULL;
        return nt_devmode;
 }
 
        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.
 ****************************************************************************/
 /****************************************************************************
  Clean up and deallocate a (maybe partially) allocated NT_DEVICEMODE.
 ****************************************************************************/
@@ -2801,7 +2755,7 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
        int len = 0;
        int extra_len = 0;
        NT_DEVICEMODE devmode;
        int len = 0;
        int extra_len = 0;
        NT_DEVICEMODE devmode;
-       
+
        ZERO_STRUCT(devmode);
 
        len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
        ZERO_STRUCT(devmode);
 
        len += tdb_unpack(buf+len, buflen-len, "p", nt_devmode);
@@ -2830,7 +2784,7 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
                          &devmode.ttoption,
                          &devmode.collate,
                          &devmode.logpixels,
                          &devmode.ttoption,
                          &devmode.collate,
                          &devmode.logpixels,
-                       
+
                          &devmode.fields,
                          &devmode.bitsperpel,
                          &devmode.pelswidth,
                          &devmode.fields,
                          &devmode.bitsperpel,
                          &devmode.pelswidth,
@@ -2846,14 +2800,14 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
                          &devmode.panningwidth,
                          &devmode.panningheight,
                          &devmode.nt_dev_private);
                          &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;
        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;
                /* check to catch an invalid TDB entry so we don't segfault */
                if (devmode.driverextra == 0) {
                        devmode.nt_dev_private = NULL;
@@ -2876,37 +2830,37 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, const uint8 *buf, int buflen)
 /****************************************************************************
  Allocate and initialize a new slot.
 ***************************************************************************/
 /****************************************************************************
  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;
 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 ( !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;
        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;
        key_index = data->num_keys;
-       
+
        /* initialze new key */
        /* initialze new key */
-       
+
        data->keys[key_index].name = talloc_strdup( data, name );
        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;
                return -1;
-       
+
        data->num_keys++;
 
        DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
        data->num_keys++;
 
        DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
-       
+
        return key_index;
 }
 
        return key_index;
 }
 
@@ -2917,25 +2871,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;
 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 ) ) {
        for ( i=0; i<data->num_keys; i++ ) {
                if ( strequal( data->keys[i].name, name ) ) {
-               
+
                        /* cleanup memory */
                        /* cleanup memory */
-                       
+
                        TALLOC_FREE( data->keys[i].name );
                        TALLOC_FREE( data->keys[i].values );
                        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 */
                        /* 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) );
                        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;
                }
        }
                        break;
                }
        }
-       
+
 
        return data->num_keys;
 }
 
        return data->num_keys;
 }
@@ -2943,28 +2897,28 @@ int delete_printer_key( NT_PRINTER_DATA *data, const char *name )
 /****************************************************************************
  search for a registry key name in the existing printer data
  ***************************************************************************/
 /****************************************************************************
  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;
 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 */
        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;
        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;
 }
 
        return key_index;
 }
 
@@ -2979,7 +2933,7 @@ int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subke
        char    *p;
        fstring *subkeys_ptr = NULL;
        fstring subkeyname;
        char    *p;
        fstring *subkeys_ptr = NULL;
        fstring subkeyname;
-       
+
        *subkeys = NULL;
 
        if ( !data )
        *subkeys = NULL;
 
        if ( !data )
@@ -2992,33 +2946,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++ ) {
 
        if ( strlen(key) == 0 ) {
                for ( i=0; i<data->num_keys; i++ ) {
-               
+
                        /* found a match, so allocate space and copy the name */
                        /* found a match, so allocate space and copy the name */
-                       
+
                        if ( !(subkeys_ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
                        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;
                        }
                                        num_subkeys+1));
                                return -1;
                        }
-                       
+
                        fstrcpy( subkeys_ptr[num_subkeys], data->keys[i].name );
                        num_subkeys++;
                }
 
                goto done;
        }
                        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 ) {
        /* 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;
                        /* 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;
                        /* get subkey path */
 
                        p = data->keys[i].name + key_len;
@@ -3027,51 +2981,51 @@ int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subke
                        fstrcpy( subkeyname, p );
                        if ( (p = strchr( subkeyname, '\\' )) )
                                *p = '\0';
                        fstrcpy( subkeyname, p );
                        if ( (p = strchr( subkeyname, '\\' )) )
                                *p = '\0';
-                       
+
                        /* don't add a key more than once */
                        /* don't add a key more than once */
-                       
+
                        for ( j=0; j<num_subkeys; j++ ) {
                                if ( strequal( subkeys_ptr[j], subkeyname ) )
                                        break;
                        }
                        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 ( 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)) ) {
                        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;
                        }
                                        num_subkeys+1));
                                return 0;
                        }
-                       
+
                        fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
                        num_subkeys++;
                }
                        fstrcpy( subkeys_ptr[num_subkeys], subkeyname );
                        num_subkeys++;
                }
-               
+
        }
        }
-       
+
        /* return error if the key was not found */
        /* return error if the key was not found */
-       
+
        if ( i == data->num_keys ) {
                SAFE_FREE(subkeys_ptr);
                return -1;
        }
        if ( i == data->num_keys ) {
                SAFE_FREE(subkeys_ptr);
                return -1;
        }
-       
+
 done:
        /* tag off the end */
 done:
        /* tag off the end */
-       
+
        if (num_subkeys)
                fstrcpy(subkeys_ptr[num_subkeys], "" );
        if (num_subkeys)
                fstrcpy(subkeys_ptr[num_subkeys], "" );
-       
+
        *subkeys = subkeys_ptr;
 
        return num_subkeys;
 }
 
 #ifdef HAVE_ADS
        *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];
                            const char *sz)
 {
        smb_ucs2_t conv_str[1024];
@@ -3080,11 +3034,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_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);
 }
 
                            (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);
                               uint32 dword)
 {
        regval_ctr_delvalue(ctr, val_name);
@@ -3092,16 +3046,16 @@ static void map_dword_into_ctr(REGVAL_CTR *ctr, const char *val_name,
                            (char *) &dword, sizeof(dword));
 }
 
                            (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);
                              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));
 }
 
                            (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;
                                         const char *multi_sz)
 {
        smb_ucs2_t *conv_strs = NULL;
@@ -3117,12 +3071,12 @@ 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);
 
        /* 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);
                  STR_TERMINATE | STR_NOALIGN);
 
        regval_ctr_delvalue(ctr, val_name);
-       regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ, 
-                           (char *) conv_strs, str_size);      
+       regval_ctr_addvalue(ctr, val_name, REG_MULTI_SZ,
+                           (char *) conv_strs, str_size);
        SAFE_FREE(conv_strs);
 }
 
        SAFE_FREE(conv_strs);
 }
 
@@ -3135,7 +3089,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)
 {
 
 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;
        fstring longname;
        const char *dnssuffix;
        char *allocated_string = NULL;
@@ -3162,7 +3116,9 @@ static bool map_nt_printer_info2_to_dsspooler(NT_PRINTER_INFO_LEVEL_2 *info2)
 
        map_sz_into_ctr(ctr, SPOOL_REG_SERVERNAME, longname);
 
 
        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);
 
        map_sz_into_ctr(ctr, SPOOL_REG_UNCNAME, allocated_string);
        SAFE_FREE(allocated_string);
 
@@ -3177,7 +3133,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,
        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) {
                           PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS));
 
        switch (info2->attributes & 0x3) {
@@ -3201,11 +3157,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;
                               struct GUID guid)
 {
        int i;
-       REGVAL_CTR *ctr=NULL;
+       struct regval_ctr *ctr=NULL;
        UNISTR2 unistr_guid;
 
        /* find the DsSpooler key */
        UNISTR2 unistr_guid;
 
        /* find the DsSpooler key */
@@ -3218,15 +3174,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 */
 
        /* We used to store this as a REG_BINARY but that causes
           Vista to whine */
 
-       ZERO_STRUCT( unistr_guid );     
-       
+       ZERO_STRUCT( unistr_guid );
+
        init_unistr2( &unistr_guid, GUID_string(talloc_tos(), &guid),
                      UNI_STR_TERMINATE );
 
        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);
                            unistr_guid.uni_max_len*2);
-       
+
 }
 
 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
 }
 
 static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
@@ -3243,6 +3199,12 @@ static WERROR nt_printer_publish_ads(ADS_STRUCT *ads,
        WERROR win_rc = WERR_OK;
        size_t converted_size;
 
        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 */
        DEBUG(5, ("publishing printer %s\n", printer->info_2->printername));
 
        /* figure out where to publish */
@@ -3253,28 +3215,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) {
 
        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) {
                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);
                ldap_memfree(srv_dn_utf8);
-               ads_destroy(&ads);
                return WERR_SERVER_UNAVAILABLE;
        }
        /* Now convert to CH_UNIX. */
                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);
                ldap_memfree(srv_dn_utf8);
                ldap_memfree(srv_cn_utf8);
-               ads_destroy(&ads);
                return WERR_SERVER_UNAVAILABLE;
        }
                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);
                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;
        }
 
                return WERR_SERVER_UNAVAILABLE;
        }
 
@@ -3283,45 +3245,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) {
 
        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);
                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;
        }
 
                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);
 
        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);
        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);
                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 */
                    printer->info_2->sharename);
 
        /* publish it */
@@ -3336,8 +3284,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)));
 
        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))) {
 
        /* retreive the guid and store it locally */
        if (ADS_ERR_OK(ads_search_dn(ads, &res, prt_dn, attrs))) {
@@ -3346,9 +3292,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);
                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;
 }
 
        return win_rc;
 }
 
@@ -3356,26 +3302,28 @@ static WERROR nt_printer_unpublish_ads(ADS_STRUCT *ads,
                                        NT_PRINTER_INFO_LEVEL *printer)
 {
        ADS_STATUS ads_rc;
                                        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 */
        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());
 
                            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);
                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;
 }
 
        return WERR_OK;
 }
 
@@ -3398,8 +3346,8 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
                goto done;
 
        switch (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;
                /* set the DsSpooler info and attributes */
                if (!(map_nt_printer_info2_to_dsspooler(printer->info_2))) {
                        win_rc = WERR_NOMEM;
@@ -3408,7 +3356,7 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
 
                printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
                break;
 
                printer->info_2->attributes |= PRINTER_ATTRIBUTE_PUBLISHED;
                break;
-       case SPOOL_DS_UNPUBLISH:
+       case DSPRINT_UNPUBLISH:
                printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
                break;
        default:
                printer->info_2->attributes ^= PRINTER_ATTRIBUTE_PUBLISHED;
                break;
        default:
@@ -3433,7 +3381,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->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)));
        ads_rc = ads_connect(ads);
        if (!ADS_ERR_OK(ads_rc)) {
                DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
@@ -3442,11 +3390,11 @@ WERROR nt_printer_publish(Printer_entry *print_hnd, int snum, int action)
        }
 
        switch (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;
                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;
        }
                win_rc = nt_printer_unpublish_ads(ads, printer);
                break;
        }
@@ -3475,7 +3423,7 @@ WERROR check_published_printers(void)
        ads->auth.password = secrets_fetch_machine_password(lp_workgroup(),
                NULL, NULL);
 
        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)));
        ads_rc = ads_connect(ads);
        if (!ADS_ERR_OK(ads_rc)) {
                DEBUG(3, ("ads_connect failed: %s\n", ads_errstr(ads_rc)));
@@ -3501,12 +3449,12 @@ WERROR check_published_printers(void)
        return WERR_OK;
 }
 
        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;
                          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;
        WERROR win_rc;
        int i;
        bool ret = False;
@@ -3517,7 +3465,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) ||
            !(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;
        {
                free_a_printer(&printer, 2);
                return False;
@@ -3525,18 +3473,18 @@ bool is_printer_published(Printer_entry *print_hnd, int snum,
 
        /* fetching printer guids really ought to be a separate function. */
 
 
        /* fetching printer guids really ought to be a separate function. */
 
-       if ( guid ) {   
+       if ( guid ) {
                fstring guid_str;
                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) ){
                   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 = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
                                     sizeof(guid_str)-1, -1, STR_TERMINATE );
                        ret = NT_STATUS_IS_OK(GUID_from_string( guid_str, guid ));
-                       break;                  
+                       break;
                case REG_BINARY:
                        if ( regval_size(guid_val) != sizeof(struct GUID) ) {
                                ret = False;
                case REG_BINARY:
                        if ( regval_size(guid_val) != sizeof(struct GUID) ) {
                                ret = False;
@@ -3546,7 +3494,7 @@ bool is_printer_published(Printer_entry *print_hnd, int snum,
                        break;
                default:
                        DEBUG(0,("is_printer_published: GUID value stored as "
                        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;
                }
        }
                        break;
                }
        }
@@ -3565,7 +3513,7 @@ WERROR check_published_printers(void)
        return WERR_OK;
 }
 
        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;
                          struct GUID *guid)
 {
        return False;
@@ -3574,41 +3522,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;
 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;
        data = p2->data;
        empty_slot = data->num_keys;
 
        if ( !key )
                return WERR_INVALID_PARAM;
-       
+
        /* remove all keys */
 
        if ( !strlen(key) ) {
        /* 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 ));
                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) */
                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));
        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 );
 
                        TALLOC_FREE( data->keys[i].name );
                        TALLOC_FREE( data->keys[i].values );
 
@@ -3633,10 +3581,10 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
                return WERR_INVALID_PARAM;
 
        /* move everything down */
                return WERR_INVALID_PARAM;
 
        /* move everything down */
-       
+
        for ( i=empty_slot+1; i<data->num_keys; i++ ) {
                if ( data->keys[i].name ) {
        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++;
                        ZERO_STRUCTP( &data->keys[i] );
                        empty_slot++;
                        removed_keys++;
@@ -3644,7 +3592,7 @@ WERROR delete_all_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key )
        }
 
        /* update count */
        }
 
        /* update count */
-               
+
        data->num_keys -= removed_keys;
 
        /* sanity check to see if anything is left */
        data->num_keys -= removed_keys;
 
        /* sanity check to see if anything is left */
@@ -3661,62 +3609,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;
 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 */
        /* we must have names on non-zero length */
-       
+
        if ( !key || !*key|| !value || !*value )
                return WERR_INVALID_NAME;
        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;
        /* 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 */
        /* 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;
        if ( !regval_ctr_getvalue( p2->data->keys[key_index].values, value ) )
                return WERR_BADFILE;
-               
+
        regval_ctr_delvalue( p2->data->keys[key_index].values, value );
        regval_ctr_delvalue( p2->data->keys[key_index].values, value );
-       
+
        DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
                key, value ));
        DEBUG(8,("delete_printer_data: Removed key => [%s], value => [%s]\n",
                key, value ));
-       
+
        return result;
 }
 
 /****************************************************************************
  ***************************************************************************/
        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 */
                            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;
        if ( !key || !*key|| !value || !*value )
                return WERR_INVALID_NAME;
-               
+
        /* find the printer key first */
        /* 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 );
        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;
        if ( key_index == -1 )
                return WERR_NOMEM;
-       
+
        regval_ctr_addvalue( p2->data->keys[key_index].values, value,
                type, (const char *)data, real_len );
        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  ));
 
        DEBUG(8,("add_printer_data: Added key => [%s], value => [%s], type=> [%d], size => [%d]\n",
                key, value, type, real_len  ));
 
@@ -3726,7 +3674,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;
 
 {
        int             key_index;
 
@@ -3753,7 +3701,7 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
        char            *str;
        int             size;
        uint8           *data_p;
        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 */
        int             key_index;
 
        /* add the "PrinterDriverData" key first for performance reasons */
@@ -3840,10 +3788,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,
                        memcpy( &guid, data_p, sizeof(struct GUID) );
 
                        init_unistr2( &unistr_guid,
-                                     GUID_string(talloc_tos(), &guid), 
+                                     GUID_string(talloc_tos(), &guid),
                                      UNI_STR_TERMINATE );
 
                                      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 );
                                             valuename, REG_SZ,
                                             (const char *)unistr_guid.buffer,
                                             unistr_guid.uni_str_len*2 );
@@ -3851,8 +3799,8 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, const uint8 *buf, int bu
                } else {
                        /* add the value */
 
                } 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 );
                }
 
                                             size );
                }
 
@@ -3991,14 +3939,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);
        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
                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)
           installed on the Samba server for NT clients --jerry */
 #if 0  /* JERRY --do not uncomment-- */
        if (!*info->drivername)
@@ -4013,7 +3961,7 @@ static WERROR get_a_printer_2_default(NT_PRINTER_INFO_LEVEL_2 *info,
        fstrcpy(info->datatype, "RAW");
 
 #ifdef HAVE_CUPS
        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) )
                /* Pull the location and comment strings from cups if we don't
                   already have one */
                if ( !strlen(info->location) || !strlen(info->comment) )
@@ -4140,7 +4088,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
 
        /*
         * Some client drivers freak out if there is a NULL devmode
 
        /*
         * 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()
         * the devmode pointer)   --jerry
         *
         * See comments in get_a_printer_2_default()
@@ -4154,7 +4102,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info,
 
        slprintf( adevice, sizeof(adevice), "%s", info->printername );
        if (info->devmode) {
 
        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 )) ) {
        }
 
        if ( !(info->data = TALLOC_ZERO_P( info, NT_PRINTER_DATA )) ) {
@@ -4183,7 +4131,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));
 
        DEBUG(9,("Unpacked printer [%s] name [%s] running driver [%s]\n",
                 sharename, info->printername, info->drivername));
 
-       return WERR_OK; 
+       return WERR_OK;
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
@@ -4193,9 +4141,9 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
 {
        uint32 result;
        NT_PRINTER_INFO_LEVEL_2 *info2;
 {
        uint32 result;
        NT_PRINTER_INFO_LEVEL_2 *info2;
-       
+
        DEBUG(106,("Dumping printer at level [%d]\n", level));
        DEBUG(106,("Dumping printer at level [%d]\n", level));
-       
+
        switch (level) {
                case 2:
                {
        switch (level) {
                case 2:
                {
@@ -4204,7 +4152,7 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
                        else
                        {
                                info2=printer->info_2;
                        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));
                                DEBUGADD(106,("attributes:[%d]\n", info2->attributes));
                                DEBUGADD(106,("priority:[%d]\n", info2->priority));
                                DEBUGADD(106,("default_priority:[%d]\n", info2->default_priority));
@@ -4237,7 +4185,7 @@ static uint32 dump_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
                        result=1;
                        break;
        }
                        result=1;
                        break;
        }
-       
+
        return result;
 }
 
        return result;
 }
 
@@ -4282,15 +4230,15 @@ static uint32 rev_changeid(void)
 WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
 {
        WERROR result;
 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
        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).
                         */
 
                         *  global spooler variable (not per printer).
                         */
 
@@ -4305,7 +4253,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
                         * 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
                         *              A non-admin connection will only show the
                         *              changes after viewing the properites page
                         *              2 times.  Seems to be related to a
@@ -4449,7 +4397,7 @@ bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
  Delete driver init data stored for a specified driver
 ****************************************************************************/
 
  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;
 {
        char *key;
        bool ret;
@@ -4472,7 +4420,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
  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
@@ -4542,9 +4490,9 @@ done:
 static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
 {
        uint32 result;
 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);
        switch (level) {
                case 2:
                        result = update_driver_init_2(printer->info_2);
@@ -4553,34 +4501,35 @@ static uint32 update_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level)
                        result = 1;
                        break;
        }
                        result = 1;
                        break;
        }
-       
+
        return result;
 }
 
 /****************************************************************************
        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 :).
 ****************************************************************************/
 
  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);
 
 
        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);
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
@@ -4599,7 +4548,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.
 
  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
  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
@@ -4611,12 +4560,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;
        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"));
        /*
         * 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
        if ( !printer->info_2->devmode && data_len ) {
                /*
                 * Set devmode on printer info, so entire printer initialization can be
@@ -4630,7 +4579,7 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
                        status = WERR_NOMEM;
                        goto done;
                }
                        status = WERR_NOMEM;
                        goto done;
                }
-       
+
                ZERO_STRUCTP(nt_devmode);
 
                /*
                ZERO_STRUCTP(nt_devmode);
 
                /*
@@ -4649,7 +4598,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
        /*
         * 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 ) {
         */
 
        if ( update_driver_init(printer, 2) != 0 ) {
@@ -4657,10 +4606,10 @@ static WERROR save_driver_init_2(NT_PRINTER_INFO_LEVEL *printer, uint8 *data, ui
                status = WERR_NOMEM;
                goto done;
        }
                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);
         * as well as the driver.
         */
        status = mod_a_printer(printer, 2);
@@ -4668,11 +4617,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));
        }
                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 );
   done:
        talloc_destroy(ctx);
        free_nt_devicemode( &nt_devmode );
-       
+
        printer->info_2->devmode = tmp_devmode;
 
        return status;
        printer->info_2->devmode = tmp_devmode;
 
        return status;
@@ -4685,7 +4634,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;
 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 );
        switch (level) {
                case 2:
                        status = save_driver_init_2( printer, data, data_len );
@@ -4694,7 +4643,7 @@ WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *dat
                        status = WERR_UNKNOWN_LEVEL;
                        break;
        }
                        status = WERR_UNKNOWN_LEVEL;
                        break;
        }
-       
+
        return status;
 }
 
        return status;
 }
 
@@ -4702,22 +4651,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
  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
  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
  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
 
 ****************************************************************************/
 
                                                     --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;
                        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)) ) {
        DEBUG(10,("get_a_printer: [%s] level %u\n", sharename, (unsigned int)level));
 
        if ( !(*pp_printer = TALLOC_ZERO_P(NULL, NT_PRINTER_INFO_LEVEL)) ) {
@@ -4733,7 +4682,7 @@ static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_
                                return WERR_NOMEM;
                        }
 
                                return WERR_NOMEM;
                        }
 
-                       if ( print_hnd ) 
+                       if ( print_hnd )
                                fstrcpy( servername, print_hnd->servername );
                        else {
                                fstrcpy( servername, "%L" );
                                fstrcpy( servername, print_hnd->servername );
                        else {
                                fstrcpy( servername, "%L" );
@@ -4748,20 +4697,20 @@ static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_
 
                        if ( !W_ERROR_IS_OK(result) ) {
                                TALLOC_FREE( *pp_printer );
 
                        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);
                                return result;
                        }
 
                        dump_a_printer( *pp_printer, level);
-                       
+
                        break;
                        break;
-                       
+
                default:
                        TALLOC_FREE( *pp_printer );
                        return WERR_UNKNOWN_LEVEL;
        }
                default:
                        TALLOC_FREE( *pp_printer );
                        return WERR_UNKNOWN_LEVEL;
        }
-       
+
        return WERR_OK;
 }
 
        return WERR_OK;
 }
 
@@ -4793,10 +4742,10 @@ uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level)
 
        if ( !printer )
                return 0;
 
        if ( !printer )
                return 0;
-       
+
        switch (level) {
                case 2:
        switch (level) {
                case 2:
-                       if ( printer->info_2 ) 
+                       if ( printer->info_2 )
                                free_nt_printer_info_level_2(&printer->info_2);
                        break;
 
                                free_nt_printer_info_level_2(&printer->info_2);
                        break;
 
@@ -4817,7 +4766,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);
        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);
        switch (level) {
                case 3:
                        result=add_a_printer_driver_3(driver.info_3);
@@ -4831,44 +4780,45 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
                        result=1;
                        break;
        }
                        result=1;
                        break;
        }
-       
+
        return result;
 }
 /****************************************************************************
 ****************************************************************************/
 
        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;
 {
        WERROR result;
-       
+
        switch (level) {
                case 3:
                        /* Sometime we just want any version of the driver */
        switch (level) {
                case 3:
                        /* Sometime we just want any version of the driver */
-                       
+
                        if ( version == DRIVER_ANY_VERSION ) {
                                /* look for Win2k first and then for NT4 */
                        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);
                                                architecture, 3);
-                                               
+
                                if ( !W_ERROR_IS_OK(result) ) {
                                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 {
                                                        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;
                        }
                        break;
-                       
+
                default:
                        result=W_ERROR(1);
                        break;
        }
                default:
                        result=W_ERROR(1);
                        break;
        }
-       
+
        if (W_ERROR_IS_OK(result))
                dump_a_printer_driver(*driver, level);
        if (W_ERROR_IS_OK(result))
                dump_a_printer_driver(*driver, level);
-               
+
        return result;
 }
 
        return result;
 }
 
@@ -4877,7 +4827,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;
 uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level)
 {
        uint32 result;
-       
+
        switch (level) {
                case 3:
                {
        switch (level) {
                case 3:
                {
@@ -4929,50 +4879,50 @@ bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
        NT_PRINTER_INFO_LEVEL *printer = NULL;
        bool in_use = False;
 
        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"));
                return False;
 
        DEBUG(10,("printer_driver_in_use: Beginning search through ntprinters.tdb...\n"));
-       
+
        /* loop through the printers.tdb and check for the drivername */
        /* 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;
        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 ( !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;
                        in_use = True;
-               
+
                free_a_printer( &printer, 2 );
        }
                free_a_printer( &printer, 2 );
        }
-       
+
        DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
        DEBUG(10,("printer_driver_in_use: Completed search through ntprinters.tdb...\n"));
-       
+
        if ( in_use ) {
                NT_PRINTER_DRIVER_INFO_LEVEL d;
                WERROR werr;
        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));
                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 */
                   "Windows NT x86" version 2 or 3 left */
-                  
+
                if ( !strequal( "Windows NT x86", info_3->environment ) ) {
                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;
                }
                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:
                                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;
                                        info_3->cversion));
                                werr = WERR_UNKNOWN_PRINTER_DRIVER;
                                break;
@@ -4980,16 +4930,16 @@ bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 )
                }
 
                /* now check the error code */
                }
 
                /* 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 );
                }
        }
                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 */
        /* report that the driver is not in use by default */
-       
+
        return in_use;
 }
 
        return in_use;
 }
 
@@ -4997,7 +4947,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
  *********************************************************************/
 /**********************************************************************
  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;
 static bool drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
 {
        int i = 0;
@@ -5021,86 +4971,86 @@ static bool drv_file_in_use( char* file, NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
 
        if ( strequal(file, info->helpfile) )
                return True;
 
        if ( strequal(file, info->helpfile) )
                return True;
-       
+
        /* see of there are any dependent files to examine */
        /* see of there are any dependent files to examine */
-       
+
        if ( !info->dependentfiles )
                return False;
        if ( !info->dependentfiles )
                return False;
-       
+
        while ( *info->dependentfiles[i] ) {
                if ( strequal(file, info->dependentfiles[i]) )
                        return True;
                i++;
        }
        while ( *info->dependentfiles[i] ) {
                if ( strequal(file, info->dependentfiles[i]) )
                        return True;
                i++;
        }
-       
+
        return False;
 
 }
 
 /**********************************************************************
        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 )
 {
  *********************************************************************/
 
 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++;
        }
        /* bump everything down a slot */
 
        while( *files[idx+1] ) {
                fstrcpy( files[idx], files[idx+1] );
                idx++;
        }
-       
+
        *files[idx] = '\0';
 
        *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;
                                       NT_PRINTER_DRIVER_INFO_LEVEL_3 *drv )
 {
        bool    in_use = False;
        int     i = 0;
-       
+
        if ( !src || !drv )
                return False;
        if ( !src || !drv )
                return False;
-               
+
        /* check each file.  Remove it from the src structure if it overlaps */
        /* 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->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->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->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, "" );
        }
        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? */
        /* are there any dependentfiles to examine? */
-       
+
        if ( !src->dependentfiles )
                return in_use;
        if ( !src->dependentfiles )
                return in_use;
-               
+
        while ( *src->dependentfiles[i] ) {
                if ( drv_file_in_use(src->dependentfiles[i], drv) ) {
                        in_use = True;
        while ( *src->dependentfiles[i] ) {
                if ( drv_file_in_use(src->dependentfiles[i], drv) ) {
                        in_use = True;
@@ -5108,18 +5058,18 @@ static bool trim_overlap_drv_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *src,
                        trim_dependent_file( src->dependentfiles, i );
                } else
                        i++;
                        trim_dependent_file( src->dependentfiles, i );
                } else
                        i++;
-       }               
-               
+       }
+
        return in_use;
 }
 
 /****************************************************************************
        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.
   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
 
   Upon return, *info has been modified to only contain the driver files
   which are not in use
 
@@ -5141,36 +5091,36 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
 
        if ( !info )
                return False;
 
        if ( !info )
                return False;
-       
+
        version = info->cversion;
        version = info->cversion;
-       
+
        /* loop over all driver versions */
        /* loop over all driver versions */
-       
+
        DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
        DEBUG(5,("printer_driver_files_in_use: Beginning search through ntdrivers.tdb...\n"));
-       
+
        /* get the list of drivers */
        /* get the list of drivers */
-               
+
        list = NULL;
        ndrivers = get_ntdrivers(&list, info->environment, version);
        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 */
                ndrivers, info->environment, version));
 
        /* check each driver for overlap in files */
-               
+
        for (i=0; i<ndrivers; i++) {
                DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
        for (i=0; i<ndrivers; i++) {
                DEBUGADD(5,("\tdriver: [%s]\n", list[i]));
-                       
+
                ZERO_STRUCT(driver);
                ZERO_STRUCT(driver);
-                       
+
                if ( !W_ERROR_IS_OK(get_a_printer_driver(&driver, 3, list[i], info->environment, version)) ) {
                        SAFE_FREE(list);
                        return True;
                }
                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 */
                /* 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 -
                if ( !strequal(info->name, driver.info_3->name) ) {
                        if ( trim_overlap_drv_files(info, driver.info_3) ) {
                                /* mz: Do not instantly return -
@@ -5201,49 +5151,43 @@ bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info )
   this.
 ****************************************************************************/
 
   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;
 {
        int i = 0;
        char *s;
        const char *file;
        connection_struct *conn;
-       DATA_BLOB null_pw;
        NTSTATUS nt_status;
        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));
 
 
        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"));
        }
 
        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
        }
 
        /* now delete the files; must strip the '\print$' string from
@@ -5252,7 +5196,6 @@ 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;
        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);
                }
                        DEBUG(10,("deleting driverfile [%s]\n", s));
                        unlink_internals(conn, NULL, 0, file, False);
                }
@@ -5261,7 +5204,6 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
        if ( *info_3->configfile ) {
                if ( (s = strchr( &info_3->configfile[1], '\\' )) != NULL ) {
                        file = s;
        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);
                }
                        DEBUG(10,("deleting configfile [%s]\n", s));
                        unlink_internals(conn, NULL, 0, file, False);
                }
@@ -5270,7 +5212,6 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
        if ( *info_3->datafile ) {
                if ( (s = strchr( &info_3->datafile[1], '\\' )) != NULL ) {
                        file = s;
        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);
                }
                        DEBUG(10,("deleting datafile [%s]\n", s));
                        unlink_internals(conn, NULL, 0, file, False);
                }
@@ -5279,7 +5220,6 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
        if ( *info_3->helpfile ) {
                if ( (s = strchr( &info_3->helpfile[1], '\\' )) != NULL ) {
                        file = s;
        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);
                }
                        DEBUG(10,("deleting helpfile [%s]\n", s));
                        unlink_internals(conn, NULL, 0, file, False);
                }
@@ -5295,7 +5235,6 @@ 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;
 
                        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);
                        }
                                DEBUG(10,("deleting dependent file [%s]\n", file));
                                unlink_internals(conn, NULL, 0, file, False);
                        }
@@ -5304,9 +5243,15 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
                }
        }
 
                }
        }
 
-       unbecome_user();
-
-       return true;
+       goto done;
+ fail:
+       ret = false;
+ done:
+       if (conn != NULL) {
+               vfs_ChDir(conn, oldcwd);
+               conn_free_internal(conn);
+       }
+       return ret;
 }
 
 /****************************************************************************
 }
 
 /****************************************************************************
@@ -5314,8 +5259,9 @@ static bool delete_driver_files( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct
  previously looked up.
  ***************************************************************************/
 
  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;
 {
        char *key = NULL;
        const char     *arch;
@@ -5365,7 +5311,7 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
         */
 
        if ( delete_files )
         */
 
        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);
 
        DEBUG(5,("delete_printer_driver: driver delete successful [%s]\n", key));
        SAFE_FREE(key);
@@ -5381,11 +5327,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;
 {
        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;
        TALLOC_CTX *mem_ctx = NULL;
        TDB_DATA kbuf;
+       TDB_DATA dbuf;
+       DATA_BLOB blob;
        WERROR status;
        WERROR status;
+       NTSTATUS nt_status;
 
        mem_ctx = talloc_init("nt_printing_setsec");
        if (mem_ctx == NULL)
 
        mem_ctx = talloc_init("nt_printing_setsec");
        if (mem_ctx == NULL)
@@ -5447,25 +5394,19 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
 
        /* Store the security descriptor in a tdb */
 
 
        /* 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 );
 
                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));
                status = WERR_OK;
        } else {
                DEBUG(1,("Failed to store secdesc for %s\n", sharename));
@@ -5473,12 +5414,10 @@ WERROR nt_printing_setsec(const char *sharename, SEC_DESC_BUF *secdesc_ctr)
        }
 
        /* Free malloc'ed memory */
        }
 
        /* Free malloc'ed memory */
+       talloc_free(blob.data);
 
  out:
 
 
  out:
 
-       if (prs_init_done) {
-               prs_mem_free(&ps);
-       }
        if (mem_ctx)
                talloc_destroy(mem_ctx);
        return status;
        if (mem_ctx)
                talloc_destroy(mem_ctx);
        return status;
@@ -5506,16 +5445,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 */
                     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
 
        /* Add the domain admins group if we are a DC */
-       
+
        if ( IS_DC ) {
                DOM_SID domadmins_sid;
        if ( IS_DC ) {
                DOM_SID domadmins_sid;
-               
+
                sid_copy(&domadmins_sid, get_global_sam_sid());
                sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
                sid_copy(&domadmins_sid, get_global_sam_sid());
                sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
-               
+
                sa = PRINTER_ACE_FULL_CONTROL;
                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);
                        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);
@@ -5524,8 +5463,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;
                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);
                        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);
@@ -5534,10 +5473,10 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
        /* add BUILTIN\Administrators as FULL CONTROL */
 
        sa = PRINTER_ACE_FULL_CONTROL;
        /* 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);
                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);
 
                SEC_ACE_TYPE_ACCESS_ALLOWED,
                sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
 
@@ -5550,7 +5489,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,
 
        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);
        }
                        &global_sid_Builtin_Administrators,
                        NULL, psa, &sd_size);
        }
@@ -5574,47 +5513,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)
 {
 
 bool nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
 {
-       prs_struct ps;
        TDB_DATA kbuf;
        TDB_DATA kbuf;
+       TDB_DATA dbuf;
+       DATA_BLOB blob;
        char *temp;
        char *temp;
+       NTSTATUS status;
 
        if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
                sharename = temp + 1;
        }
 
 
        if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
                sharename = temp + 1;
        }
 
-       ZERO_STRUCT(ps);
-
        /* Fetch security descriptor from tdb */
 
        /* 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);
+       kbuf = make_printers_secdesc_tdbkey(ctx, sharename);
 
 
-               DEBUG(4,("using default secdesc for %s\n", sharename));
-
-               if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
-                       return False;
-               }
-
-               /* 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
 
        /* If security descriptor is owned by S-1-1-0 and winbindd is up,
           this security descriptor has been created when winbindd was
@@ -5664,14 +5601,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;
 
                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),
                           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));
                }
        }
 
                }
        }
 
@@ -5691,15 +5628,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 !
        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 :-).
        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.
        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
        3 files for the printers (1 by printer):
                NTprinter_laser A
                NTprinter_laser B
@@ -5757,7 +5694,7 @@ void map_job_permissions(SEC_DESC *sd)
        print_queue_purge
 
   Try access control in the following order (for performance reasons):
        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)
 
     2)  check security descriptor (bit comparisons in memory)
     3)  "printer admins" (may result in numerous calls to winbind)
 
@@ -5768,16 +5705,15 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
        SEC_DESC_BUF *secdesc = NULL;
        uint32 access_granted;
        NTSTATUS status;
        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;
        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 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;
        }
            || user_has_privileges(server_info->ptok, &se_printop ) ) {
                return True;
        }
@@ -5841,7 +5777,7 @@ bool print_access_check(struct auth_serversupplied_info *server_info, int snum,
         }
 
        talloc_destroy(mem_ctx);
         }
 
        talloc_destroy(mem_ctx);
-       
+
        if (!NT_STATUS_IS_OK(status)) {
                errno = EACCES;
        }
        if (!NT_STATUS_IS_OK(status)) {
                errno = EACCES;
        }