Fix bug #7781 (Samba transforms "ShareName" to lowercase when adding new share via...
[samba.git] / source3 / registry / reg_backend_printing.c
index 0854d7d8fc5bbed517fad116a6d8066929566fe9..cba4f798d3802fb12dec10b0178cf512ab13296d 100644 (file)
@@ -278,7 +278,7 @@ done:
 static bool add_printers_by_registry( struct regsubkey_ctr *subkeys )
 {
        int i, num_keys, snum;
-       char *printername;
+       char *printername_in;
        NT_PRINTER_INFO_LEVEL_2 info2;
        NT_PRINTER_INFO_LEVEL printer;
        
@@ -289,8 +289,9 @@ static bool add_printers_by_registry( struct regsubkey_ctr *subkeys )
        
        become_root();
        for ( i=0; i<num_keys; i++ ) {
-               printername = regsubkey_ctr_specific_key( subkeys, i );
-               snum = find_service( printername );
+               fstring printername;
+               printername_in = regsubkey_ctr_specific_key( subkeys, i );
+               snum = find_service(printername_in, printername);
                
                /* just verify a valied snum for now */
                if ( snum == -1 ) {
@@ -386,7 +387,6 @@ static bool key_printers_store_keys( const char *key, struct regsubkey_ctr *subk
 static void fill_in_printer_values(NT_PRINTER_INFO_LEVEL_2 *info2, struct regval_ctr *values)
 {
        struct spoolss_DeviceMode *devmode;
-       UNISTR2         data;
        char            *p;
        uint32 printer_status = PRINTER_STATUS_OK;
        
@@ -406,35 +406,17 @@ static void fill_in_printer_values(NT_PRINTER_INFO_LEVEL_2 *info2, struct regval
                p = info2->printername;
        else
                p++;
-       init_unistr2( &data, p, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
 
-       init_unistr2( &data, info2->location, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Location", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-       init_unistr2( &data, info2->comment, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Description", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-       init_unistr2( &data, info2->parameters, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Parameters", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-       init_unistr2( &data, info2->portname, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Port", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-       init_unistr2( &data, info2->sharename, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Share Name", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-       init_unistr2( &data, info2->drivername, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Printer Driver", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-       init_unistr2( &data, info2->sepfile, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Separator File", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-       init_unistr2( &data, "WinPrint", UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Print Processor",  REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
-
-       init_unistr2( &data, "RAW", UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Datatype", REG_SZ, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+       regval_ctr_addvalue_sz(values, "Name", p);
+       regval_ctr_addvalue_sz(values, "Location", info2->location);
+       regval_ctr_addvalue_sz(values, "Description", info2->comment);
+       regval_ctr_addvalue_sz(values, "Parameters", info2->parameters);
+       regval_ctr_addvalue_sz(values, "Port", info2->portname);
+       regval_ctr_addvalue_sz(values, "Share Name", info2->sharename);
+       regval_ctr_addvalue_sz(values, "Printer Driver", info2->drivername);
+       regval_ctr_addvalue_sz(values, "Separator File", info2->sepfile);
+       regval_ctr_addvalue_sz(values, "Print Processor", "WinPrint");
+       regval_ctr_addvalue_sz(values, "Datatype", "RAW");
 
        /* stream the device mode */
 
@@ -594,7 +576,16 @@ static int find_valuename_index( const char *valuename )
 /**********************************************************************
  *********************************************************************/
 
-static void convert_values_to_printer_info_2(NT_PRINTER_INFO_LEVEL_2 *printer2, struct regval_ctr *values)
+static void pull_reg_sz_fstring(TALLOC_CTX *mem_ctx, const DATA_BLOB *blob, fstring s)
+{
+       const char *str;
+       pull_reg_sz(mem_ctx, blob, &str);
+       fstrcpy(s, str);
+}
+
+static void convert_values_to_printer_info_2(TALLOC_CTX *mem_ctx,
+                                            NT_PRINTER_INFO_LEVEL_2 *printer2,
+                                            struct regval_ctr *values)
 {
        int num_values = regval_ctr_numvals( values );
        uint32 value_index;
@@ -602,8 +593,11 @@ static void convert_values_to_printer_info_2(NT_PRINTER_INFO_LEVEL_2 *printer2,
        int i;
        
        for ( i=0; i<num_values; i++ ) {
+               DATA_BLOB blob;
                val = regval_ctr_specific_value( values, i );
                value_index = find_valuename_index( regval_name( val ) );
+
+               blob = data_blob_const(regval_data_p(val), regval_size(val));
                
                switch( value_index ) {
                        case REG_IDX_ATTRIBUTES:
@@ -625,34 +619,34 @@ static void convert_values_to_printer_info_2(NT_PRINTER_INFO_LEVEL_2 *printer2,
                                printer2->untiltime = (uint32)(*regval_data_p(val));
                                break;
                        case REG_IDX_NAME:
-                               rpcstr_pull( printer2->printername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->printername);
                                break;
                        case REG_IDX_LOCATION:
-                               rpcstr_pull( printer2->location, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->location);
                                break;
                        case REG_IDX_DESCRIPTION:
-                               rpcstr_pull( printer2->comment, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->comment);
                                break;
                        case REG_IDX_PARAMETERS:
-                               rpcstr_pull( printer2->parameters, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->parameters);
                                break;
                        case REG_IDX_PORT:
-                               rpcstr_pull( printer2->portname, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->portname);
                                break;
                        case REG_IDX_SHARENAME:
-                               rpcstr_pull( printer2->sharename, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->sharename);
                                break;
                        case REG_IDX_DRIVER:
-                               rpcstr_pull( printer2->drivername, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->drivername);
                                break;
                        case REG_IDX_SEP_FILE:
-                               rpcstr_pull( printer2->sepfile, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->sepfile);
                                break;
                        case REG_IDX_PRINTPROC:
-                               rpcstr_pull( printer2->printprocessor, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->printprocessor);
                                break;
                        case REG_IDX_DATATYPE:
-                               rpcstr_pull( printer2->datatype, regval_data_p(val), sizeof(fstring), regval_size(val), 0 );
+                               pull_reg_sz_fstring(mem_ctx, &blob, printer2->datatype);
                                break;
                        case REG_IDX_DEVMODE:
                                break;
@@ -677,6 +671,7 @@ static bool key_printers_store_values(const char *key, struct regval_ctr *values
        char *printername, *keyname;
        NT_PRINTER_INFO_LEVEL   *printer = NULL;
        WERROR result;
+       TALLOC_CTX *mem_ctx = talloc_init("key_printers_store_values");
        
        printers_key = strip_printers_prefix( key );
        
@@ -697,7 +692,7 @@ static bool key_printers_store_values(const char *key, struct regval_ctr *values
        /* deal with setting values directly under the printername */
 
        if ( !keyname ) {
-               convert_values_to_printer_info_2( printer->info_2, values );
+               convert_values_to_printer_info_2(mem_ctx, printer->info_2, values );
        }
        else {
                int num_values = regval_ctr_numvals( values );
@@ -718,6 +713,7 @@ static bool key_printers_store_values(const char *key, struct regval_ctr *values
                                DEBUG(0,("key_printers_store_values: failed to set printer data [%s]!\n",
                                        keyname));
                                free_a_printer( &printer, 2 );
+                               talloc_destroy(mem_ctx);
                                return False;
                        }
                }
@@ -726,6 +722,7 @@ static bool key_printers_store_values(const char *key, struct regval_ctr *values
        result = mod_a_printer( printer, 2 );
 
        free_a_printer( &printer, 2 );
+       talloc_destroy(mem_ctx);
 
        return W_ERROR_IS_OK(result);
 }
@@ -878,7 +875,7 @@ static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys
 
        /* if anything else left, just say if has no subkeys */
 
-       DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s\n",
+       DEBUG(1,("key_driver_fetch_keys unhandled key [%s] (subkey == %s)\n",
                key, subkeypath ));
 
        return 0;
@@ -888,50 +885,41 @@ static int key_driver_fetch_keys( const char *key, struct regsubkey_ctr *subkeys
 /**********************************************************************
  *********************************************************************/
 
-static void fill_in_driver_values(NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, struct regval_ctr *values)
+static void fill_in_driver_values(const struct spoolss_DriverInfo8 *r,
+                                 struct regval_ctr *values)
 {
        char *buffer = NULL;
        int buffer_size = 0;
        int i, length;
        const char *filename;
-       UNISTR2 data;
+       DATA_BLOB data;
 
-       filename = dos_basename( info3->driverpath );
-       init_unistr2( &data, filename, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Driver", REG_SZ, (char*)data.buffer,
-               data.uni_str_len*sizeof(uint16) );
+       filename = dos_basename(r->driver_path);
+       regval_ctr_addvalue_sz(values, "Driver", filename);
 
-       filename = dos_basename( info3->configfile );
-       init_unistr2( &data, filename, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Configuration File", REG_SZ, (char*)data.buffer, 
-               data.uni_str_len*sizeof(uint16) );
+       filename = dos_basename(r->config_file);
+       regval_ctr_addvalue_sz(values, "Configuration File", filename);
 
-       filename = dos_basename( info3->datafile );
-       init_unistr2( &data, filename, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Data File", REG_SZ, (char*)data.buffer,
-               data.uni_str_len*sizeof(uint16) );
+       filename = dos_basename(r->data_file);
+       regval_ctr_addvalue_sz(values, "Data File", filename);
 
-       filename = dos_basename( info3->helpfile );
-       init_unistr2( &data, filename, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Help File", REG_SZ, (char*)data.buffer,
-               data.uni_str_len*sizeof(uint16) );
+       filename = dos_basename(r->help_file);
+       regval_ctr_addvalue_sz(values, "Help File", filename);
 
-       init_unistr2( &data, info3->defaultdatatype, UNI_STR_TERMINATE);
-       regval_ctr_addvalue( values, "Data Type", REG_SZ, (char*)data.buffer,
-               data.uni_str_len*sizeof(uint16) );
+       regval_ctr_addvalue_sz(values, "Data Type", r->default_datatype);
 
-       regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&info3->cversion, 
-               sizeof(info3->cversion) );
+       regval_ctr_addvalue( values, "Version", REG_DWORD, (char*)&r->version,
+               sizeof(r->version) );
 
-       if ( info3->dependentfiles ) {
+       if (r->dependent_files) {
                /* place the list of dependent files in a single
                   character buffer, separating each file name by
                   a NULL */
 
-               for ( i=0; strcmp(info3->dependentfiles[i], ""); i++ ) {
+               for (i=0; r->dependent_files[i] && strcmp(r->dependent_files[i], ""); i++) {
                        /* strip the path to only the file's base name */
 
-                       filename = dos_basename( info3->dependentfiles[i] );
+                       filename = dos_basename(r->dependent_files[i]);
 
                        length = strlen(filename);
 
@@ -940,8 +928,8 @@ static void fill_in_driver_values(NT_PRINTER_DRIVER_INFO_LEVEL_3 *info3, struct
                                break;
                        }
 
-                       init_unistr2( &data, filename, UNI_STR_TERMINATE);
-                       memcpy( buffer+buffer_size, (char*)data.buffer, data.uni_str_len*sizeof(uint16) );
+                       push_reg_sz(talloc_tos(), &data, filename);
+                       memcpy( buffer+buffer_size, (char*)data.data, data.length);
 
                        buffer_size += (length + 1)*sizeof(uint16);
                }
@@ -973,7 +961,7 @@ static int driver_arch_fetch_values(char *key, struct regval_ctr *values)
        fstring         arch_environment;
        fstring         driver;
        int             version;
-       NT_PRINTER_DRIVER_INFO_LEVEL    driver_ctr;
+       struct spoolss_DriverInfo8 *driver_ctr;
        WERROR          w_result;
 
        if (!reg_split_path( key, &base, &subkeypath )) {
@@ -1034,14 +1022,14 @@ static int driver_arch_fetch_values(char *key, struct regval_ctr *values)
 
        fstrcpy( driver, base );
 
-       w_result = get_a_printer_driver( &driver_ctr, 3, driver, arch_environment, version );
+       w_result = get_a_printer_driver(talloc_tos(), &driver_ctr, driver, arch_environment, version);
 
        if ( !W_ERROR_IS_OK(w_result) )
                return -1;
 
-       fill_in_driver_values( driver_ctr.info_3, values );
+       fill_in_driver_values(driver_ctr, values);
 
-       free_a_printer_driver( driver_ctr, 3 );
+       free_a_printer_driver(driver_ctr);
 
        /* END PRINTER DRIVER NAME BLOCK */
 
@@ -1258,7 +1246,7 @@ static bool regprint_store_reg_values(const char *key, struct regval_ctr *values
  * Table of function pointers for accessing printing data
  */
 
-REGISTRY_OPS printing_ops = {
+struct registry_ops printing_ops = {
        .fetch_subkeys = regprint_fetch_reg_keys,
        .fetch_values = regprint_fetch_reg_values,
        .store_subkeys = regprint_store_reg_keys,