r8066: * had to modify the printer data storage slightly in ntprinters.tdb
[gd/samba/.git] / source / printing / nt_printing.c
index 552d2dfe3599c01aa52bca22e020447c6f432b50..47e0af963344d7e7ed57e89f4206fbb85652cd50 100644 (file)
@@ -354,7 +354,7 @@ static int sec_desc_upg_fn( TDB_CONTEXT *the_tdb, TDB_DATA key,
        /* create a new SEC_DESC with the appropriate owner and group SIDs */
 
        string_to_sid(&sid, "S-1-5-32-544" );
-       new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, 
+       new_sec = make_sec_desc( ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE,
                &sid, &sid,
                NULL, NULL, &size_new_sec );
        sd_new = make_sec_desc_buf( ctx, size_new_sec, new_sec );
@@ -396,7 +396,7 @@ static BOOL upgrade_to_version_4(void)
 
        DEBUG(0,("upgrade_to_version_4: upgrading printer security descriptors\n"));
 
-       if ( !(ctx = talloc_init_named( "upgrade_to_version_4" )) ) 
+       if ( !(ctx = talloc_init( "upgrade_to_version_4" )) ) 
                return False;
 
        result = tdb_traverse( tdb_printers, sec_desc_upg_fn, ctx );
@@ -412,11 +412,11 @@ static BOOL upgrade_to_version_4(void)
 
 BOOL nt_printing_init(void)
 {
-       static pid_t local_pid;
        const char *vstring = "INFO/version";
        WERROR win_rc;
+       uint32 vers_id;
 
-       if (tdb_drivers && tdb_printers && tdb_forms && local_pid == sys_getpid())
+       if ( tdb_drivers && tdb_printers && tdb_forms )
                return True;
  
        if (tdb_drivers)
@@ -446,8 +446,6 @@ BOOL nt_printing_init(void)
                return False;
        }
  
-       local_pid = sys_getpid();
        /* handle a Samba upgrade */
        tdb_lock_bystring(tdb_drivers, vstring, 0);
 
@@ -1151,8 +1149,8 @@ static int file_version_is_newer(connection_struct *conn, fstring new_file, fstr
        SMB_STRUCT_STAT stat_buf;
        BOOL bad_path;
 
-       ZERO_STRUCT(st);
-       ZERO_STRUCT(stat_buf);
+       SET_STAT_INVALID(st);
+       SET_STAT_INVALID(stat_buf);
        new_create_time = (time_t)0;
        old_create_time = (time_t)0;
 
@@ -1264,7 +1262,7 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
        SMB_STRUCT_STAT   st;
        connection_struct *conn;
 
-       ZERO_STRUCT(st);
+       SET_STAT_INVALID(st);
 
        *perr = WERR_INVALID_PARAM;
 
@@ -1306,10 +1304,16 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
 
        driver_unix_convert(driverpath,conn,NULL,&bad_path,&st);
 
+       if ( !vfs_file_exist( conn, driverpath, &st ) ) {
+               *perr = WERR_BADFILE;
+               goto error_exit;
+       }
+
        fsp = open_file_shared(conn, driverpath, &st,
-                                                  SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
-                                                  (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
-                                                  FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
+               SET_DENY_MODE(DENY_NONE)|SET_OPEN_MODE(DOS_OPEN_RDONLY),
+               (FILE_FAIL_IF_NOT_EXIST|FILE_EXISTS_OPEN),
+               FILE_ATTRIBUTE_NORMAL, INTERNAL_OPEN_ONLY, &access_mode, &action);
+
        if (!fsp) {
                DEBUG(3,("get_correct_cversion: Can't open file [%s], errno = %d\n",
                                driverpath, errno));
@@ -1350,8 +1354,8 @@ static uint32 get_correct_cversion(const char *architecture, fstring driverpath_
                                  driverpath, major, minor));
        }
 
-    DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
-                       driverpath, cversion));
+       DEBUG(10,("get_correct_cversion: Driver file [%s] cversion = %d\n",
+               driverpath, cversion));
 
        close_file(fsp, True);
        close_cnum(conn, user->vuid);
@@ -1428,9 +1432,8 @@ static WERROR clean_up_driver_struct_level_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 *dri
         *      NT 4: cversion=2
         *      NT2K: cversion=3
         */
-       if ((driver->cversion = get_correct_cversion( architecture,
-                                                                       driver->driverpath, user, &err)) == -1)
-               return err;
+       if ((driver->cversion = get_correct_cversion( architecture, driver->driverpath, user, &err)) == -1)
+                       return err;
 
        return WERR_OK;
 }
@@ -1492,8 +1495,9 @@ static WERROR clean_up_driver_struct_level_6(NT_PRINTER_DRIVER_INFO_LEVEL_6 *dri
         *      NT 4: cversion=2
         *      NT2K: cversion=3
         */
+
        if ((driver->version = get_correct_cversion(architecture, driver->driverpath, user, &err)) == -1)
-               return err;
+                       return err;
 
        return WERR_OK;
 }
@@ -1560,7 +1564,7 @@ static char* ffmt(unsigned char *c){
 
 /****************************************************************************
 ****************************************************************************/
-BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
+WERROR move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract, uint32 level, 
                                  struct current_user *user, WERROR *perr)
 {
        NT_PRINTER_DRIVER_INFO_LEVEL_3 *driver;
@@ -1579,6 +1583,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
        SMB_STRUCT_STAT st;
        int ver = 0;
        int i;
+       int err;
 
        memset(inbuf, '\0', sizeof(inbuf));
        memset(outbuf, '\0', sizeof(outbuf));
@@ -1591,7 +1596,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
                driver = &converted_driver;
        } else {
                DEBUG(0,("move_driver_to_download_area: Unknown info level (%u)\n", (unsigned int)level ));
-               return False;
+               return WERR_UNKNOWN_LEVEL;
        }
 
        architecture = get_short_archi(driver->environment);
@@ -1610,7 +1615,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
        if (conn == NULL) {
                DEBUG(0,("move_driver_to_download_area: Unable to connect\n"));
                *perr = ntstatus_to_werror(nt_status);
-               return False;
+               return WERR_NO_SUCH_SHARE;
        }
 
        /*
@@ -1619,7 +1624,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
 
        if (!become_user(conn, conn->vuid)) {
                DEBUG(0,("move_driver_to_download_area: Can't become user!\n"));
-               return False;
+               return WERR_ACCESS_DENIED;
        }
 
        /*
@@ -1654,20 +1659,14 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
                slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->driverpath);      
                slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->driverpath);   
                if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                       NTSTATUS status;
                        driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                       status = rename_internals(conn, new_name, old_name, 0, True);
-                       if (!NT_STATUS_IS_OK(status)) {
+                       if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
                                DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
                                                new_name, old_name));
-                               *perr = ntstatus_to_werror(status);
-                               unlink_internals(conn, 0, new_name);
+                               *perr = WERR_ACCESS_DENIED;
                                ver = -1;
                        }
-               } else {
-                       driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                       unlink_internals(conn, 0, new_name);
-               }
+               } 
        }
 
        if (driver->datafile && strlen(driver->datafile)) {
@@ -1675,19 +1674,13 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
                        slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->datafile);        
                        slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->datafile);     
                        if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               NTSTATUS status;
                                driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                               status = rename_internals(conn, new_name, old_name, 0, True);
-                               if (!NT_STATUS_IS_OK(status)) {
+                               if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
                                        DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
                                                        new_name, old_name));
-                                       *perr = ntstatus_to_werror(status);
-                                       unlink_internals(conn, 0, new_name);
+                                       *perr = WERR_ACCESS_DENIED;
                                        ver = -1;
                                }
-                       } else {
-                               driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                               unlink_internals(conn, 0, new_name);
                        }
                }
        }
@@ -1698,19 +1691,13 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
                        slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->configfile);      
                        slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->configfile);   
                        if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               NTSTATUS status;
                                driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                               status = rename_internals(conn, new_name, old_name, 0, True);
-                               if (!NT_STATUS_IS_OK(status)) {
+                               if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
                                        DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
                                                        new_name, old_name));
-                                       *perr = ntstatus_to_werror(status);
-                                       unlink_internals(conn, 0, new_name);
+                                       *perr = WERR_ACCESS_DENIED;
                                        ver = -1;
                                }
-                       } else {
-                               driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                               unlink_internals(conn, 0, new_name);
                        }
                }
        }
@@ -1722,19 +1709,13 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
                        slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->helpfile);        
                        slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->helpfile);     
                        if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                               NTSTATUS status;
                                driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                               status = rename_internals(conn, new_name, old_name, 0, True);
-                               if (!NT_STATUS_IS_OK(status)) {
+                               if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
                                        DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
                                                        new_name, old_name));
-                                       *perr = ntstatus_to_werror(status);
-                                       unlink_internals(conn, 0, new_name);
+                                       *perr = WERR_ACCESS_DENIED;
                                        ver = -1;
                                }
-                       } else {
-                               driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                               unlink_internals(conn, 0, new_name);
                        }
                }
        }
@@ -1755,19 +1736,13 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
                                slprintf(new_name, sizeof(new_name)-1, "%s/%s", architecture, driver->dependentfiles[i]);       
                                slprintf(old_name, sizeof(old_name)-1, "%s/%s", new_dir, driver->dependentfiles[i]);    
                                if (ver != -1 && (ver=file_version_is_newer(conn, new_name, old_name)) > 0) {
-                                       NTSTATUS status;
                                        driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                                       status = rename_internals(conn, new_name, old_name, 0, True);
-                                       if (!NT_STATUS_IS_OK(status)) {
+                                       if ( !copy_file(new_name, old_name, conn, FILE_EXISTS_TRUNCATE|FILE_CREATE_IF_NOT_EXIST, 0, False, &err) ) {
                                                DEBUG(0,("move_driver_to_download_area: Unable to rename [%s] to [%s]\n",
                                                                new_name, old_name));
-                                               *perr = ntstatus_to_werror(status);
-                                               unlink_internals(conn, 0, new_name);
+                                               *perr = WERR_ACCESS_DENIED;
                                                ver = -1;
                                        }
-                               } else {
-                                       driver_unix_convert(new_name, conn, NULL, &bad_path, &st);
-                                       unlink_internals(conn, 0, new_name);
                                }
                        }
                NextDriver: ;
@@ -1777,7 +1752,7 @@ BOOL move_driver_to_download_area(NT_PRINTER_DRIVER_INFO_LEVEL driver_abstract,
        close_cnum(conn, user->vuid);
        unbecome_user();
 
-       return ver == -1 ? False : True;
+       return ver != -1 ? WERR_OK : WERR_UNKNOWN_PRINTER_DRIVER;
 }
 
 /****************************************************************************
@@ -2115,13 +2090,13 @@ int pack_devicemode(NT_DEVICEMODE *nt_devmode, char *buf, int buflen)
                        nt_devmode->reserved2,
                        nt_devmode->panningwidth,
                        nt_devmode->panningheight,
-                       nt_devmode->private);
+                       nt_devmode->nt_dev_private);
 
        
-       if (nt_devmode->private) {
+       if (nt_devmode->nt_dev_private) {
                len += tdb_pack(buf+len, buflen-len, "B",
                                nt_devmode->driverextra,
-                               nt_devmode->private);
+                               nt_devmode->nt_dev_private);
        }
 
        DEBUG(8,("Packed devicemode [%s]\n", nt_devmode->formname));
@@ -2150,8 +2125,17 @@ static int pack_values(NT_PRINTER_DATA *data, char *buf, int buflen)
        for ( i=0; i<data->num_keys; i++ ) {    
                val_ctr = &data->keys[i].values;
                num_values = regval_ctr_numvals( val_ctr );
+
+               /* pack the keyname followed by a empty value */
+
+               len += tdb_pack(buf+len, buflen-len, "pPdB", 
+                               &data->keys[i].name,
+                               data->keys[i].name, 
+                               REG_NONE,
+                               0,
+                               NULL);
                
-               /* loop over all values */
+               /* now loop over all values */
                
                for ( j=0; j<num_values; j++ ) {
                        /* pathname should be stored as <key>\<value> */
@@ -2218,6 +2202,7 @@ uint32 del_a_printer(const char *sharename)
 static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
 {
        pstring key;
+       fstring norm_sharename;
        char *buf;
        int buflen, len;
        WERROR ret;
@@ -2299,6 +2284,11 @@ static WERROR update_a_printer_2(NT_PRINTER_INFO_LEVEL_2 *info)
        }
        
 
+       /* normalize the key */
+
+       fstrcpy( norm_sharename, info->sharename );
+       strlower_m( norm_sharename );
+
        slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, info->sharename);
 
        kbuf.dptr = key;
@@ -2380,7 +2370,7 @@ NT_DEVICEMODE *construct_nt_devicemode(const fstring default_devicename)
        nt_devmode->panningwidth     = 0;
        nt_devmode->panningheight    = 0;
        
-       nt_devmode->private = NULL;
+       nt_devmode->nt_dev_private = NULL;
        return nt_devmode;
 }
 
@@ -2400,9 +2390,9 @@ NT_DEVICEMODE *dup_nt_devicemode(NT_DEVICEMODE *nt_devicemode)
                return NULL;
        }
 
-       new_nt_devicemode->private = NULL;
-       if (nt_devicemode->private != NULL) {
-               if ((new_nt_devicemode->private = memdup(nt_devicemode->private, nt_devicemode->driverextra)) == NULL) {
+       new_nt_devicemode->nt_dev_private = NULL;
+       if (nt_devicemode->nt_dev_private != NULL) {
+               if ((new_nt_devicemode->nt_dev_private = 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;
@@ -2425,7 +2415,7 @@ void free_nt_devicemode(NT_DEVICEMODE **devmode_ptr)
 
        DEBUG(106,("free_nt_devicemode: deleting DEVMODE\n"));
 
-       SAFE_FREE(nt_devmode->private);
+       SAFE_FREE(nt_devmode->nt_dev_private);
        SAFE_FREE(*devmode_ptr);
 }
 
@@ -2511,25 +2501,25 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
                          &devmode.reserved2,
                          &devmode.panningwidth,
                          &devmode.panningheight,
-                         &devmode.private);
+                         &devmode.nt_dev_private);
        
-       if (devmode.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.private);
+               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.private = NULL;
+                       devmode.nt_dev_private = NULL;
                }
        }
 
        *nt_devmode = (NT_DEVICEMODE *)memdup(&devmode, sizeof(devmode));
 
        DEBUG(8,("Unpacked devicemode [%s](%s)\n", devmode.devicename, devmode.formname));
-       if (devmode.private)
+       if (devmode.nt_dev_private)
                DEBUG(8,("with a private section of %d bytes\n", devmode.driverextra));
 
        return len;
@@ -2539,7 +2529,7 @@ int unpack_devicemode(NT_DEVICEMODE **nt_devmode, char *buf, int buflen)
  Allocate and initialize a new slot.
 ***************************************************************************/
  
-static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
+int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
 {
        NT_PRINTER_KEY  *d;
        int             key_index;
@@ -2549,9 +2539,12 @@ static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
        
        /* allocate another slot in the NT_PRINTER_KEY array */
        
-       d = SMB_REALLOC_ARRAY( data->keys, NT_PRINTER_KEY, data->num_keys+1);
-       if ( d )
-               data->keys = d;
+       if ( !(d = SMB_REALLOC_ARRAY( 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;
        
@@ -2560,8 +2553,6 @@ static int add_new_printer_key( NT_PRINTER_DATA *data, const char *name )
        data->num_keys++;
        data->keys[key_index].name = SMB_STRDUP( name );
        
-       ZERO_STRUCTP( &data->keys[key_index].values );
-       
        regval_ctr_init( &data->keys[key_index].values );
        
        DEBUG(10,("add_new_printer_key: Inserted new data key [%s]\n", name ));
@@ -2600,7 +2591,7 @@ int lookup_printerkey( NT_PRINTER_DATA *data, const char *name )
 /****************************************************************************
  ***************************************************************************/
 
-uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
+int get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **subkeys )
 {
        int     i, j;
        int     key_len;
@@ -2611,14 +2602,42 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su
        
        if ( !data )
                return 0;
+
+       if ( !key )
+               return -1;
+
+       /* special case of asking for the top level printer data registry key names */
+
+       if ( strlen(key) == 0 ) {
+               for ( i=0; i<data->num_keys; i++ ) {
                
+                       /* found a match, so allocate space and copy the name */
+                       
+                       if ( !(ptr = SMB_REALLOC_ARRAY( subkeys_ptr, fstring, num_subkeys+2)) ) {
+                               DEBUG(0,("get_printer_subkeys: Realloc failed for [%d] entries!\n", 
+                                       num_subkeys+1));
+                               SAFE_FREE( subkeys );
+                               return -1;
+                       }
+                       
+                       subkeys_ptr = ptr;
+                       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 ) {
-                       /* match sure it is a subkey and not the key itself */
                        
+                       /* if we found the exact key, then break */
                        key_len = strlen( key );
                        if ( strlen(data->keys[i].name) == key_len )
-                               continue;
+                               break;
                        
                        /* get subkey path */
 
@@ -2655,7 +2674,13 @@ uint32 get_printer_subkeys( NT_PRINTER_DATA *data, const char* key, fstring **su
                
        }
        
-       /* tag of the end */
+       /* return error if the key was not found */
+       
+       if ( i == data->num_keys )
+               return -1;
+       
+done:
+       /* tag off the end */
        
        if (num_subkeys)
                fstrcpy(subkeys_ptr[num_subkeys], "" );
@@ -3296,6 +3321,15 @@ static int unpack_values(NT_PRINTER_DATA *printer_data, char *buf, int buflen)
                                  &type,
                                  &size,
                                  &data_p);
+
+               /* lookup for subkey names which have a type of REG_NONE */
+               /* there's no data with this entry */
+
+               if ( type == REG_NONE ) {
+                       if ( (key_index=lookup_printerkey( printer_data, string)) == -1 )
+                               add_new_printer_key( printer_data, string );
+                       continue;
+               }
        
                /*
                 * break of the keyname from the value name.  
@@ -3517,17 +3551,22 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *se
        TDB_DATA kbuf, dbuf;
        fstring printername;
        char adevice[MAXDEVICENAME];
+       fstring norm_sharename;
                
        ZERO_STRUCT(info);
 
-       slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, sharename);
+       /* normalize case */
+       fstrcpy( norm_sharename, sharename );
+       strlower_m( norm_sharename );
+
+       slprintf(key, sizeof(key)-1, "%s%s", PRINTERS_PREFIX, norm_sharename);
 
        kbuf.dptr = key;
        kbuf.dsize = strlen(key)+1;
 
        dbuf = tdb_fetch(tdb_printers, kbuf);
        if (!dbuf.dptr)
-               return get_a_printer_2_default(info_ptr, servername, sharename);
+               return get_a_printer_2_default(info_ptr, servername, norm_sharename);
 
        len += tdb_unpack(dbuf.dptr+len, dbuf.dsize-len, "dddddddddddfffffPfffff",
                        &info.attributes,
@@ -3561,7 +3600,7 @@ static WERROR get_a_printer_2(NT_PRINTER_INFO_LEVEL_2 **info_ptr, const char *se
        slprintf(info.servername, sizeof(info.servername)-1, "\\\\%s", servername);
 
        if ( lp_force_printername(snum) )
-               slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, sharename );
+               slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, norm_sharename );
        else 
                slprintf(printername, sizeof(printername)-1, "\\\\%s\\%s", servername, info.printername);
 
@@ -4894,7 +4933,7 @@ WERROR delete_printer_driver( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3, struct cur
  Store a security desc for a printer.
 ****************************************************************************/
 
-WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
+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;
@@ -4902,6 +4941,10 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
        TALLOC_CTX *mem_ctx = NULL;
        fstring key;
        WERROR status;
+       fstring norm_sharename;
+
+       fstrcpy( norm_sharename, sharename );
+       strlower_m( norm_sharename );
 
        mem_ctx = talloc_init("nt_printing_setsec");
        if (mem_ctx == NULL)
@@ -4918,7 +4961,7 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
                SEC_DESC *psd = NULL;
                size_t size;
 
-               nt_printing_getsec(mem_ctx, printername, &old_secdesc_ctr);
+               nt_printing_getsec(mem_ctx, norm_sharename, &old_secdesc_ctr);
 
                /* Pick out correct owner and group sids */
 
@@ -4964,12 +5007,12 @@ WERROR nt_printing_setsec(const char *printername, SEC_DESC_BUF *secdesc_ctr)
                goto out;
        }
 
-       slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
+       slprintf(key, sizeof(key)-1, "SECDESC/%s", norm_sharename);
 
        if (tdb_prs_store(tdb_printers, key, &ps)==0) {
                status = WERR_OK;
        } else {
-               DEBUG(1,("Failed to store secdesc for %s\n", printername));
+               DEBUG(1,("Failed to store secdesc for %s\n", norm_sharename));
                status = WERR_BADFUNC;
        }
 
@@ -4995,7 +5038,7 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
        SEC_ACL *psa = NULL;
        SEC_DESC_BUF *sdb = NULL;
        SEC_DESC *psd = NULL;
-       DOM_SID owner_sid;
+       DOM_SID adm_sid;
        size_t sd_size;
 
        /* Create an ACE where Everyone is allowed to print */
@@ -5004,30 +5047,6 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
        init_sec_ace(&ace[i++], &global_sid_World, SEC_ACE_TYPE_ACCESS_ALLOWED,
                     sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
 
-       /* Make the security descriptor owned by the Administrators group
-          on the PDC of the domain. */
-
-       if (secrets_fetch_domain_sid(lp_workgroup(), &owner_sid)) {
-               sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
-       } else {
-
-               /* Backup plan - make printer owned by admins.
-                  This should emulate a lanman printer as security
-                  settings can't be changed. */
-
-               sid_copy(&owner_sid, get_global_sam_sid());
-               sid_append_rid(&owner_sid, DOMAIN_USER_RID_ADMIN);
-       }
-
-       init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
-       init_sec_ace(&ace[i++], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    sa, SEC_ACE_FLAG_OBJECT_INHERIT |
-                    SEC_ACE_FLAG_INHERIT_ONLY);
-
-       init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
-       init_sec_ace(&ace[i++], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                    sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
-
        /* Add the domain admins group if we are a DC */
        
        if ( IS_DC ) {
@@ -5037,15 +5056,35 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
                sid_append_rid(&domadmins_sid, DOMAIN_GROUP_RID_ADMINS);
                
                init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
+               init_sec_ace(&ace[i++], &domadmins_sid, 
+                       SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 
+                       SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
                init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                            sa, SEC_ACE_FLAG_OBJECT_INHERIT |
-                            SEC_ACE_FLAG_INHERIT_ONLY);
+                       sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+       }
+       else if (secrets_fetch_domain_sid(lp_workgroup(), &adm_sid)) {
+               sid_append_rid(&adm_sid, DOMAIN_USER_RID_ADMIN);
 
                init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
-               init_sec_ace(&ace[i++], &domadmins_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
-                            sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+               init_sec_ace(&ace[i++], &adm_sid, 
+                       SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 
+                       SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+               init_sec_ace(&ace[i++], &adm_sid, SEC_ACE_TYPE_ACCESS_ALLOWED,
+                       sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
        }
-                    
+
+       /* add BUILTIN\Administrators as FULL CONTROL */
+
+       init_sec_access(&sa, PRINTER_ACE_FULL_CONTROL);
+       init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, 
+               SEC_ACE_TYPE_ACCESS_ALLOWED, sa, 
+               SEC_ACE_FLAG_OBJECT_INHERIT | SEC_ACE_FLAG_INHERIT_ONLY);
+       init_sec_ace(&ace[i++], &global_sid_Builtin_Administrators, 
+               SEC_ACE_TYPE_ACCESS_ALLOWED,
+               sa, SEC_ACE_FLAG_CONTAINER_INHERIT);
+
+       /* Make the security descriptor owned by the BUILTIN\Administrators */
+
        /* The ACL revision number in rpc_secdesc.h differs from the one
           created by NT when setting ACE entries in printer
           descriptors.  NT4 complains about the property being edited by a
@@ -5053,8 +5092,9 @@ 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,
-                                   &owner_sid, NULL,
-                                   NULL, psa, &sd_size);
+                       &global_sid_Builtin_Administrators, 
+                       &global_sid_Builtin_Administrators,
+                       NULL, psa, &sd_size);
        }
 
        if (!psd) {
@@ -5074,24 +5114,28 @@ static SEC_DESC_BUF *construct_default_printer_sdb(TALLOC_CTX *ctx)
  Get a security desc for a printer.
 ****************************************************************************/
 
-BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF **secdesc_ctr)
+BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *sharename, SEC_DESC_BUF **secdesc_ctr)
 {
        prs_struct ps;
        fstring key;
        char *temp;
+       fstring norm_sharename;
 
-       if (strlen(printername) > 2 && (temp = strchr(printername + 2, '\\'))) {
-               printername = temp + 1;
+       if (strlen(sharename) > 2 && (temp = strchr(sharename + 2, '\\'))) {
+               sharename = temp + 1;
        }
 
        /* Fetch security descriptor from tdb */
 
-       slprintf(key, sizeof(key)-1, "SECDESC/%s", printername);
+       fstrcpy( norm_sharename, sharename );
+       strlower_m( norm_sharename );
+
+       slprintf(key, sizeof(key)-1, "SECDESC/%s", norm_sharename);
 
        if (tdb_prs_fetch(tdb_printers, key, &ps, ctx)!=0 ||
            !sec_io_desc_buf("nt_printing_getsec", secdesc_ctr, &ps, 1)) {
 
-               DEBUG(4,("using default secdesc for %s\n", printername));
+               DEBUG(4,("using default secdesc for %s\n", norm_sharename));
 
                if (!(*secdesc_ctr = construct_default_printer_sdb(ctx))) {
                        return False;
@@ -5143,7 +5187,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF *
 
                        /* Set it */
 
-                       nt_printing_setsec(printername, *secdesc_ctr);
+                       nt_printing_setsec(norm_sharename, *secdesc_ctr);
                }
        }
 
@@ -5152,7 +5196,7 @@ BOOL nt_printing_getsec(TALLOC_CTX *ctx, const char *printername, SEC_DESC_BUF *
                int i;
 
                DEBUG(10, ("secdesc_ctr for %s has %d aces:\n", 
-                          printername, the_acl->num_aces));
+                          norm_sharename, the_acl->num_aces));
 
                for (i = 0; i < the_acl->num_aces; i++) {
                        fstring sid_str;