00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "includes.h"
00024
00025 #undef DBGC_CLASS
00026 #define DBGC_CLASS DBGC_RPC_SRV
00027
00028 static TDB_CONTEXT *tdb_reg;
00029 static int tdb_refcount;
00030
00031 #define VALUE_PREFIX "SAMBA_REGVAL"
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043 static const char *builtin_registry_paths[] = {
00044 KEY_PRINTING_2K,
00045 KEY_PRINTING_PORTS,
00046 KEY_PRINTING,
00047 KEY_SHARES,
00048 KEY_EVENTLOG,
00049 "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib",
00050 "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Perflib\\009",
00051 "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors",
00052 "HKLM\\SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
00053 "HKLM\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\DefaultUserConfiguration",
00054 "HKLM\\SYSTEM\\CurrentControlSet\\Services\\TcpIp\\Parameters",
00055 "HKLM\\SYSTEM\\CurrentControlSet\\Services\\Netlogon\\Parameters",
00056 "HKU",
00057 "HKCR",
00058 "HKPD",
00059 "HKPT",
00060 NULL };
00061
00062 struct builtin_regkey_value {
00063 const char *path;
00064 const char *valuename;
00065 uint32 type;
00066 union {
00067 const char *string;
00068 uint32 dw_value;
00069 } data;
00070 };
00071
00072 static struct builtin_regkey_value builtin_registry_values[] = {
00073 { KEY_PRINTING_PORTS,
00074 SAMBA_PRINTER_PORT_NAME, REG_SZ, { "" } },
00075 { KEY_PRINTING_2K,
00076 "DefaultSpoolDirectory", REG_SZ, { "C:\\Windows\\System32\\Spool\\Printers" } },
00077 { KEY_EVENTLOG,
00078 "DisplayName", REG_SZ, { "Event Log" } },
00079 { KEY_EVENTLOG,
00080 "ErrorControl", REG_DWORD, { (char*)0x00000001 } },
00081 { NULL, NULL, 0, { NULL } }
00082 };
00083
00084 #define REGVER_V1 1
00085
00086
00087
00088
00089
00090 static BOOL init_registry_data( void )
00091 {
00092 pstring path, base, remaining;
00093 fstring keyname, subkeyname;
00094 REGSUBKEY_CTR *subkeys;
00095 REGVAL_CTR *values;
00096 int i;
00097 const char *p, *p2;
00098 UNISTR2 data;
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 if ( tdb_transaction_start( tdb_reg ) == -1 ) {
00109 DEBUG(0, ("init_registry_data: tdb_transaction_start "
00110 "failed\n"));
00111 return False;
00112 }
00113
00114
00115
00116 for ( i=0; builtin_registry_paths[i] != NULL; i++ ) {
00117
00118 DEBUG(6,("init_registry_data: Adding [%s]\n", builtin_registry_paths[i]));
00119
00120 pstrcpy( path, builtin_registry_paths[i] );
00121 pstrcpy( base, "" );
00122 p = path;
00123
00124 while ( next_token(&p, keyname, "\\", sizeof(keyname)) ) {
00125
00126
00127
00128 if ( *base )
00129 pstrcat( base, "\\" );
00130 pstrcat( base, keyname );
00131
00132
00133
00134 *subkeyname = '\0';
00135 if ( *p ) {
00136 pstrcpy( remaining, p );
00137 p2 = remaining;
00138
00139 if ( !next_token(&p2, subkeyname, "\\", sizeof(subkeyname)) )
00140 fstrcpy( subkeyname, p2 );
00141 }
00142
00143 DEBUG(10,("init_registry_data: Storing key [%s] with subkey [%s]\n",
00144 base, *subkeyname ? subkeyname : "NULL"));
00145
00146
00147
00148
00149
00150 if ( !(subkeys = TALLOC_ZERO_P( NULL, REGSUBKEY_CTR )) ) {
00151 DEBUG(0,("talloc() failure!\n"));
00152 goto fail;
00153 }
00154
00155 regdb_fetch_keys( base, subkeys );
00156 if ( *subkeyname )
00157 regsubkey_ctr_addkey( subkeys, subkeyname );
00158 if ( !regdb_store_keys( base, subkeys ))
00159 goto fail;
00160
00161 TALLOC_FREE( subkeys );
00162 }
00163 }
00164
00165
00166
00167 for ( i=0; builtin_registry_values[i].path != NULL; i++ ) {
00168 if ( !(values = TALLOC_ZERO_P( NULL, REGVAL_CTR )) ) {
00169 DEBUG(0,("talloc() failure!\n"));
00170 goto fail;
00171 }
00172
00173 regdb_fetch_values( builtin_registry_values[i].path, values );
00174
00175
00176
00177 if ( !regval_ctr_key_exists( values, builtin_registry_values[i].valuename ) )
00178 {
00179 switch( builtin_registry_values[i].type ) {
00180 case REG_DWORD:
00181 regval_ctr_addvalue( values,
00182 builtin_registry_values[i].valuename,
00183 REG_DWORD,
00184 (char*)&builtin_registry_values[i].data.dw_value,
00185 sizeof(uint32) );
00186 break;
00187
00188 case REG_SZ:
00189 init_unistr2( &data, builtin_registry_values[i].data.string, UNI_STR_TERMINATE);
00190 regval_ctr_addvalue( values,
00191 builtin_registry_values[i].valuename,
00192 REG_SZ,
00193 (char*)data.buffer,
00194 data.uni_str_len*sizeof(uint16) );
00195 break;
00196
00197 default:
00198 DEBUG(0,("init_registry_data: invalid value type in builtin_registry_values [%d]\n",
00199 builtin_registry_values[i].type));
00200 }
00201 regdb_store_values( builtin_registry_values[i].path, values );
00202 }
00203
00204 TALLOC_FREE( values );
00205 }
00206
00207 if (tdb_transaction_commit( tdb_reg ) == -1) {
00208 DEBUG(0, ("init_registry_data: Could not commit "
00209 "transaction\n"));
00210 return False;
00211 }
00212
00213 return True;
00214
00215 fail:
00216
00217 if (tdb_transaction_cancel( tdb_reg ) == -1) {
00218 smb_panic("init_registry_data: tdb_transaction_cancel "
00219 "failed\n");
00220 }
00221
00222 return False;
00223 }
00224
00225
00226
00227
00228
00229 BOOL regdb_init( void )
00230 {
00231 const char *vstring = "INFO/version";
00232 uint32 vers_id;
00233
00234 if ( tdb_reg )
00235 return True;
00236
00237 if ( !(tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600)) )
00238 {
00239 tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
00240 if ( !tdb_reg ) {
00241 DEBUG(0,("regdb_init: Failed to open registry %s (%s)\n",
00242 lock_path("registry.tdb"), strerror(errno) ));
00243 return False;
00244 }
00245
00246 DEBUG(10,("regdb_init: Successfully created registry tdb\n"));
00247 }
00248
00249 tdb_refcount = 1;
00250
00251
00252 vers_id = tdb_fetch_int32(tdb_reg, vstring);
00253
00254 if ( vers_id != REGVER_V1 ) {
00255
00256 }
00257
00258
00259
00260 if ( !init_registry_data() ) {
00261 DEBUG(0,("init_registry: Failed to initialize data in registry!\n"));
00262 return False;
00263 }
00264
00265 return True;
00266 }
00267
00268
00269
00270
00271
00272 WERROR regdb_open( void )
00273 {
00274 WERROR result = WERR_OK;
00275
00276 if ( tdb_reg ) {
00277 DEBUG(10,("regdb_open: incrementing refcount (%d)\n", tdb_refcount));
00278 tdb_refcount++;
00279 return WERR_OK;
00280 }
00281
00282 become_root();
00283
00284 tdb_reg = tdb_open_log(lock_path("registry.tdb"), 0, TDB_DEFAULT, O_RDWR, 0600);
00285 if ( !tdb_reg ) {
00286 result = ntstatus_to_werror( map_nt_error_from_unix( errno ) );
00287 DEBUG(0,("regdb_open: Failed to open %s! (%s)\n",
00288 lock_path("registry.tdb"), strerror(errno) ));
00289 }
00290
00291 unbecome_root();
00292
00293 tdb_refcount = 1;
00294 DEBUG(10,("regdb_open: refcount reset (%d)\n", tdb_refcount));
00295
00296 return result;
00297 }
00298
00299
00300
00301
00302 int regdb_close( void )
00303 {
00304 int ret;
00305
00306 tdb_refcount--;
00307
00308 DEBUG(10,("regdb_close: decrementing refcount (%d)\n", tdb_refcount));
00309
00310 if ( tdb_refcount > 0 )
00311 return 0;
00312
00313 SMB_ASSERT( tdb_refcount >= 0 );
00314
00315 ret = tdb_close( tdb_reg );
00316 tdb_reg = NULL;
00317
00318 return ret;
00319 }
00320
00321
00322
00323
00324
00325
00326
00327 static BOOL regdb_store_keys_internal( const char *key, REGSUBKEY_CTR *ctr )
00328 {
00329 TDB_DATA kbuf, dbuf;
00330 char *buffer;
00331 int i = 0;
00332 uint32 len, buflen;
00333 BOOL ret = True;
00334 uint32 num_subkeys = regsubkey_ctr_numkeys( ctr );
00335 pstring keyname;
00336
00337 if ( !key )
00338 return False;
00339
00340 pstrcpy( keyname, key );
00341 normalize_reg_path( keyname );
00342
00343
00344
00345 if (!(buffer = (char *)SMB_MALLOC(sizeof(pstring)))) {
00346 return False;
00347 }
00348 buflen = sizeof(pstring);
00349 len = 0;
00350
00351
00352
00353 len += tdb_pack(buffer+len, buflen-len, "d", num_subkeys );
00354
00355
00356
00357 for (i=0; i<num_subkeys; i++) {
00358 len += tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
00359 if ( len > buflen ) {
00360
00361 if ((buffer = (char *)SMB_REALLOC( buffer, len*2 )) == NULL) {
00362 DEBUG(0,("regdb_store_keys: Failed to realloc memory of size [%d]\n", len*2));
00363 ret = False;
00364 goto done;
00365 }
00366 buflen = len*2;
00367
00368 len = tdb_pack( buffer+len, buflen-len, "f", regsubkey_ctr_specific_key(ctr, i) );
00369 }
00370 }
00371
00372
00373
00374 kbuf.dptr = keyname;
00375 kbuf.dsize = strlen(keyname)+1;
00376 dbuf.dptr = buffer;
00377 dbuf.dsize = len;
00378 if ( tdb_store( tdb_reg, kbuf, dbuf, TDB_REPLACE ) == -1) {
00379 ret = False;
00380 goto done;
00381 }
00382
00383 done:
00384 SAFE_FREE( buffer );
00385
00386 return ret;
00387 }
00388
00389
00390
00391
00392
00393
00394 BOOL regdb_store_keys( const char *key, REGSUBKEY_CTR *ctr )
00395 {
00396 int num_subkeys, i;
00397 pstring path;
00398 REGSUBKEY_CTR *subkeys, *old_subkeys;
00399 char *oldkeyname;
00400
00401
00402
00403 if ( !(old_subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) {
00404 DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
00405 return False;
00406 }
00407
00408 regdb_fetch_keys( key, old_subkeys );
00409
00410
00411
00412 if ( !regdb_store_keys_internal( key, ctr ) ) {
00413 DEBUG(0,("regdb_store_keys: Failed to store new subkey list for parent [%s}\n", key ));
00414 return False;
00415 }
00416
00417
00418
00419 num_subkeys = regsubkey_ctr_numkeys( old_subkeys );
00420 for ( i=0; i<num_subkeys; i++ ) {
00421 oldkeyname = regsubkey_ctr_specific_key( old_subkeys, i );
00422 if ( !regsubkey_ctr_key_exists( ctr, oldkeyname ) ) {
00423 pstr_sprintf( path, "%s%c%s", key, '/', oldkeyname );
00424 normalize_reg_path( path );
00425 tdb_delete_bystring( tdb_reg, path );
00426 }
00427 }
00428
00429 TALLOC_FREE( old_subkeys );
00430
00431
00432
00433 num_subkeys = regsubkey_ctr_numkeys( ctr );
00434 for ( i=0; i<num_subkeys; i++ ) {
00435 pstr_sprintf( path, "%s%c%s", key, '/', regsubkey_ctr_specific_key( ctr, i ) );
00436
00437 if ( !(subkeys = TALLOC_ZERO_P( ctr, REGSUBKEY_CTR )) ) {
00438 DEBUG(0,("regdb_store_keys: talloc() failure!\n"));
00439 return False;
00440 }
00441
00442 if ( regdb_fetch_keys( path, subkeys ) == -1 ) {
00443
00444 if ( !regdb_store_keys_internal( path, subkeys ) ) {
00445 DEBUG(0,("regdb_store_keys: Failed to store new record for key [%s}\n", path ));
00446 TALLOC_FREE( subkeys );
00447 return False;
00448 }
00449 }
00450
00451 TALLOC_FREE( subkeys );
00452 }
00453
00454 return True;
00455 }
00456
00457
00458
00459
00460
00461
00462
00463 int regdb_fetch_keys( const char* key, REGSUBKEY_CTR *ctr )
00464 {
00465 pstring path;
00466 uint32 num_items;
00467 TDB_DATA dbuf;
00468 char *buf;
00469 uint32 buflen, len;
00470 int i;
00471 fstring subkeyname;
00472
00473 DEBUG(11,("regdb_fetch_keys: Enter key => [%s]\n", key ? key : "NULL"));
00474
00475 pstrcpy( path, key );
00476
00477
00478 pstring_sub( path, "\\", "/" );
00479 strupper_m( path );
00480
00481 dbuf = tdb_fetch_bystring( tdb_reg, path );
00482
00483 buf = dbuf.dptr;
00484 buflen = dbuf.dsize;
00485
00486 if ( !buf ) {
00487 DEBUG(5,("regdb_fetch_keys: tdb lookup failed to locate key [%s]\n", key));
00488 return -1;
00489 }
00490
00491 len = tdb_unpack( buf, buflen, "d", &num_items);
00492
00493 for (i=0; i<num_items; i++) {
00494 len += tdb_unpack( buf+len, buflen-len, "f", subkeyname );
00495 regsubkey_ctr_addkey( ctr, subkeyname );
00496 }
00497
00498 SAFE_FREE( dbuf.dptr );
00499
00500 DEBUG(11,("regdb_fetch_keys: Exit [%d] items\n", num_items));
00501
00502 return num_items;
00503 }
00504
00505
00506
00507
00508
00509 static int regdb_unpack_values(REGVAL_CTR *values, char *buf, int buflen)
00510 {
00511 int len = 0;
00512 uint32 type;
00513 pstring valuename;
00514 uint32 size;
00515 uint8 *data_p;
00516 uint32 num_values = 0;
00517 int i;
00518
00519
00520
00521
00522
00523 len += tdb_unpack(buf+len, buflen-len, "d", &num_values);
00524
00525 for ( i=0; i<num_values; i++ ) {
00526
00527
00528 type = REG_NONE;
00529 size = 0;
00530 data_p = NULL;
00531 len += tdb_unpack(buf+len, buflen-len, "fdB",
00532 valuename,
00533 &type,
00534 &size,
00535 &data_p);
00536
00537
00538
00539 if ( size && data_p ) {
00540 regval_ctr_addvalue( values, valuename, type, (const char *)data_p, size );
00541 SAFE_FREE(data_p);
00542 }
00543
00544 DEBUG(8,("specific: [%s], len: %d\n", valuename, size));
00545 }
00546
00547 return len;
00548 }
00549
00550
00551
00552
00553
00554 static int regdb_pack_values(REGVAL_CTR *values, char *buf, int buflen)
00555 {
00556 int len = 0;
00557 int i;
00558 REGISTRY_VALUE *val;
00559 int num_values;
00560
00561 if ( !values )
00562 return 0;
00563
00564 num_values = regval_ctr_numvals( values );
00565
00566
00567
00568 len += tdb_pack( buf+len, buflen-len, "d", num_values );
00569
00570
00571
00572 for ( i=0; i<num_values; i++ ) {
00573 val = regval_ctr_specific_value( values, i );
00574 len += tdb_pack(buf+len, buflen-len, "fdB",
00575 regval_name(val),
00576 regval_type(val),
00577 regval_size(val),
00578 regval_data_p(val) );
00579 }
00580
00581 return len;
00582 }
00583
00584
00585
00586
00587
00588
00589 int regdb_fetch_values( const char* key, REGVAL_CTR *values )
00590 {
00591 TDB_DATA data;
00592 pstring keystr;
00593
00594 DEBUG(10,("regdb_fetch_values: Looking for value of key [%s] \n", key));
00595
00596 pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key );
00597 normalize_reg_path( keystr );
00598
00599 data = tdb_fetch_bystring( tdb_reg, keystr );
00600
00601 if ( !data.dptr ) {
00602
00603 return 0;
00604 }
00605
00606 regdb_unpack_values( values, data.dptr, data.dsize );
00607
00608 SAFE_FREE( data.dptr );
00609
00610 return regval_ctr_numvals(values);
00611 }
00612
00613
00614
00615
00616
00617
00618 BOOL regdb_store_values( const char *key, REGVAL_CTR *values )
00619 {
00620 TDB_DATA data;
00621 pstring keystr;
00622 int len, ret;
00623
00624 DEBUG(10,("regdb_store_values: Looking for value of key [%s] \n", key));
00625
00626 ZERO_STRUCT( data );
00627
00628 len = regdb_pack_values( values, data.dptr, data.dsize );
00629 if ( len <= 0 ) {
00630 DEBUG(0,("regdb_store_values: unable to pack values. len <= 0\n"));
00631 return False;
00632 }
00633
00634 data.dptr = SMB_MALLOC_ARRAY( char, len );
00635 data.dsize = len;
00636
00637 len = regdb_pack_values( values, data.dptr, data.dsize );
00638
00639 SMB_ASSERT( len == data.dsize );
00640
00641 pstr_sprintf( keystr, "%s/%s", VALUE_PREFIX, key );
00642 normalize_reg_path( keystr );
00643
00644 ret = tdb_store_bystring(tdb_reg, keystr, data, TDB_REPLACE);
00645
00646 SAFE_FREE( data.dptr );
00647
00648 return ret != -1 ;
00649 }
00650
00651
00652
00653
00654
00655
00656 REGISTRY_OPS regdb_ops = {
00657 regdb_fetch_keys,
00658 regdb_fetch_values,
00659 regdb_store_keys,
00660 regdb_store_values,
00661 NULL
00662 };
00663
00664