Changeset 31
- Timestamp:
- 07/16/05 15:05:19 (19 years ago)
- Location:
- trunk
- Files:
-
- 3 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/regfio.h
r30 r31 34 34 #define _REGFIO_H 35 35 36 #include <stdlib.h> 37 #include <stdio.h> 36 38 #include <stdbool.h> 37 #include <st dio.h>39 #include <string.h> 38 40 #include <errno.h> 41 #include <time.h> 39 42 #include <fcntl.h> 40 43 #include <sys/stat.h> -
trunk/include/smb_deps.h
r30 r31 24 24 */ 25 25 26 #include <stdlib.h> 26 27 #include <stdbool.h> 27 28 #include <stdio.h> 29 #include <string.h> 28 30 #include <errno.h> 29 31 #include <fcntl.h> … … 38 40 void* zalloc(size_t size); 39 41 void* zcalloc(size_t size, unsigned int count); 40 void zerop(void* p);41 42 42 43 43 /* From includes.h */ … … 413 413 414 414 size_t sid_size(const DOM_SID *sid); 415 staticint sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2);415 int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2); 416 416 int sid_compare(const DOM_SID *sid1, const DOM_SID *sid2); 417 417 bool sid_equal(const DOM_SID *sid1, const DOM_SID *sid2); -
trunk/lib/regfio.c
r30 r31 37 37 38 38 /******************************************************************* 39 *******************************************************************/39 *******************************************************************/ 40 40 static int read_block( REGF_FILE *file, prs_struct *ps, uint32 file_offset, 41 41 uint32 block_size ) 42 42 { 43 44 45 46 47 48 49 50 DEBUG(0,("read_block: stat() failed! (%s)\n", strerror(errno))); 51 52 53 54 55 56 57 58 43 int bytes_read, returned; 44 char *buffer; 45 SMB_STRUCT_STAT sbuf; 46 47 /* check for end of file */ 48 49 if ( fstat( file->fd, &sbuf ) ) { 50 /*DEBUG(0,("read_block: stat() failed! (%s)\n", strerror(errno)));*/ 51 return -1; 52 } 53 54 if ( (size_t)file_offset >= sbuf.st_size ) 55 return -1; 56 57 /* if block_size == 0, we are parsnig HBIN records and need 58 to read some of the header to get the block_size from there */ 59 59 60 61 62 63 64 DEBUG(0,("read_block: lseek() failed! (%s)\n", strerror(errno) )); 65 66 67 68 69 70 DEBUG(0,("read_block: failed to read in HBIN header. Is the file corrupt?\n")); 71 72 73 74 75 76 77 DEBUG(0,("read_block: invalid block header!\n")); 78 79 80 81 82 83 84 DEBUG(10,("read_block: block_size == 0x%x\n", block_size )); 85 86 87 88 89 DEBUG(0,("read_block: lseek() failed! (%s)\n", strerror(errno) )); 90 91 92 93 94 95 96 97 98 99 DEBUG(0,("read_block: read() failed (%s)\n", strerror(errno) )); 100 101 102 103 DEBUG(0,("read_block: not a vald registry file ?\n" )); 104 105 106 107 108 109 110 111 } 112 113 114 /******************************************************************* 115 *******************************************************************/60 if ( block_size == 0 ) { 61 uint8 hdr[0x20]; 62 63 if ( lseek( file->fd, file_offset, SEEK_SET ) == -1 ) { 64 /*DEBUG(0,("read_block: lseek() failed! (%s)\n", strerror(errno) ));*/ 65 return -1; 66 } 67 68 returned = read( file->fd, hdr, 0x20 ); 69 if ( (returned == -1) || (returned < 0x20) ) { 70 /*DEBUG(0,("read_block: failed to read in HBIN header. Is the file corrupt?\n"));*/ 71 return -1; 72 } 73 74 /* make sure this is an hbin header */ 75 76 if ( strncmp( hdr, "hbin", HBIN_HDR_SIZE ) != 0 ) { 77 /*DEBUG(0,("read_block: invalid block header!\n"));*/ 78 return -1; 79 } 80 81 block_size = IVAL( hdr, 0x08 ); 82 } 83 84 /*DEBUG(10,("read_block: block_size == 0x%x\n", block_size ));*/ 85 86 /* set the offset, initialize the buffer, and read the block from disk */ 87 88 if ( lseek( file->fd, file_offset, SEEK_SET ) == -1 ) { 89 /*DEBUG(0,("read_block: lseek() failed! (%s)\n", strerror(errno) ));*/ 90 return -1; 91 } 92 93 prs_init( ps, block_size, file->mem_ctx, UNMARSHALL ); 94 buffer = ps->data_p; 95 bytes_read = returned = 0; 96 97 while ( bytes_read < block_size ) { 98 if ( (returned = read( file->fd, buffer+bytes_read, block_size-bytes_read )) == -1 ) { 99 /*DEBUG(0,("read_block: read() failed (%s)\n", strerror(errno) ));*/ 100 return false; 101 } 102 if ( (returned == 0) && (bytes_read < block_size) ) { 103 /*DEBUG(0,("read_block: not a vald registry file ?\n" ));*/ 104 return false; 105 } 106 107 bytes_read += returned; 108 } 109 110 return bytes_read; 111 } 112 113 114 /******************************************************************* 115 *******************************************************************/ 116 116 static bool prs_regf_block( const char *desc, prs_struct *ps, int depth, REGF_FILE *file ) 117 117 { 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 } 171 172 173 /******************************************************************* 174 *******************************************************************/118 depth++; 119 120 if ( !prs_uint8s( true, "header", ps, depth, file->header, sizeof( file->header )) ) 121 return false; 122 123 /* yes, these values are always identical so store them only once */ 124 125 if ( !prs_uint32( "unknown1", ps, depth, &file->unknown1 )) 126 return false; 127 if ( !prs_uint32( "unknown1 (again)", ps, depth, &file->unknown1 )) 128 return false; 129 130 /* get the modtime */ 131 132 if ( !prs_set_offset( ps, 0x0c ) ) 133 return false; 134 if ( !smb_io_time( "modtime", &file->mtime, ps, depth ) ) 135 return false; 136 137 /* constants */ 138 139 if ( !prs_uint32( "unknown2", ps, depth, &file->unknown2 )) 140 return false; 141 if ( !prs_uint32( "unknown3", ps, depth, &file->unknown3 )) 142 return false; 143 if ( !prs_uint32( "unknown4", ps, depth, &file->unknown4 )) 144 return false; 145 if ( !prs_uint32( "unknown5", ps, depth, &file->unknown5 )) 146 return false; 147 148 /* get file offsets */ 149 150 if ( !prs_set_offset( ps, 0x24 ) ) 151 return false; 152 if ( !prs_uint32( "data_offset", ps, depth, &file->data_offset )) 153 return false; 154 if ( !prs_uint32( "last_block", ps, depth, &file->last_block )) 155 return false; 156 157 /* one more constant */ 158 159 if ( !prs_uint32( "unknown6", ps, depth, &file->unknown6 )) 160 return false; 161 162 /* get the checksum */ 163 164 if ( !prs_set_offset( ps, 0x01fc ) ) 165 return false; 166 if ( !prs_uint32( "checksum", ps, depth, &file->checksum )) 167 return false; 168 169 return true; 170 } 171 172 173 /******************************************************************* 174 *******************************************************************/ 175 175 static bool prs_hbin_block( const char *desc, prs_struct *ps, int depth, REGF_HBIN *hbin ) 176 176 { 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 } 205 206 207 /******************************************************************* 208 *******************************************************************/177 uint32 block_size2; 178 179 depth++; 180 181 if ( !prs_uint8s( true, "header", ps, depth, hbin->header, sizeof( hbin->header )) ) 182 return false; 183 184 if ( !prs_uint32( "first_hbin_off", ps, depth, &hbin->first_hbin_off )) 185 return false; 186 187 /* The dosreg.cpp comments say that the block size is at 0x1c. 188 According to a WINXP NTUSER.dat file, this is wrong. The block_size 189 is at 0x08 */ 190 191 if ( !prs_uint32( "block_size", ps, depth, &hbin->block_size )) 192 return false; 193 194 block_size2 = hbin->block_size; 195 prs_set_offset( ps, 0x1c ); 196 if ( !prs_uint32( "block_size2", ps, depth, &block_size2 )) 197 return false; 198 199 if ( !ps->io ) 200 hbin->dirty = true; 201 202 203 return true; 204 } 205 206 207 /******************************************************************* 208 *******************************************************************/ 209 209 static bool prs_nk_rec( const char *desc, prs_struct *ps, int depth, REGF_NK_REC *nk ) 210 210 { 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, nk->rec_size)); 304 305 306 307 308 309 } 310 311 312 /******************************************************************* 313 *******************************************************************/211 uint16 class_length, name_length; 212 uint32 start; 213 uint32 data_size, start_off, end_off; 214 uint32 unknown_off = REGF_OFFSET_NONE; 215 216 nk->hbin_off = ps->data_offset; 217 start = nk->hbin_off; 218 219 depth++; 220 221 /* back up and get the data_size */ 222 223 if ( !prs_set_offset( ps, ps->data_offset-sizeof(uint32)) ) 224 return false; 225 start_off = ps->data_offset; 226 if ( !prs_uint32( "rec_size", ps, depth, &nk->rec_size )) 227 return false; 228 229 if ( !prs_uint8s( true, "header", ps, depth, nk->header, sizeof( nk->header )) ) 230 return false; 231 232 if ( !prs_uint16( "key_type", ps, depth, &nk->key_type )) 233 return false; 234 if ( !smb_io_time( "mtime", &nk->mtime, ps, depth )) 235 return false; 236 237 if ( !prs_set_offset( ps, start+0x0010 ) ) 238 return false; 239 if ( !prs_uint32( "parent_off", ps, depth, &nk->parent_off )) 240 return false; 241 if ( !prs_uint32( "num_subkeys", ps, depth, &nk->num_subkeys )) 242 return false; 243 244 if ( !prs_set_offset( ps, start+0x001c ) ) 245 return false; 246 if ( !prs_uint32( "subkeys_off", ps, depth, &nk->subkeys_off )) 247 return false; 248 if ( !prs_uint32( "unknown_off", ps, depth, &unknown_off) ) 249 return false; 250 251 if ( !prs_set_offset( ps, start+0x0024 ) ) 252 return false; 253 if ( !prs_uint32( "num_values", ps, depth, &nk->num_values )) 254 return false; 255 if ( !prs_uint32( "values_off", ps, depth, &nk->values_off )) 256 return false; 257 if ( !prs_uint32( "sk_off", ps, depth, &nk->sk_off )) 258 return false; 259 if ( !prs_uint32( "classname_off", ps, depth, &nk->classname_off )) 260 return false; 261 262 if ( !prs_uint32( "max_bytes_subkeyname", ps, depth, &nk->max_bytes_subkeyname)) 263 return false; 264 if ( !prs_uint32( "max_bytes_subkeyclassname", ps, depth, &nk->max_bytes_subkeyclassname)) 265 return false; 266 if ( !prs_uint32( "max_bytes_valuename", ps, depth, &nk->max_bytes_valuename)) 267 return false; 268 if ( !prs_uint32( "max_bytes_value", ps, depth, &nk->max_bytes_value)) 269 return false; 270 if ( !prs_uint32( "unknown index", ps, depth, &nk->unk_index)) 271 return false; 272 273 name_length = nk->keyname ? strlen(nk->keyname) : 0 ; 274 class_length = nk->classname ? strlen(nk->classname) : 0 ; 275 if ( !prs_uint16( "name_length", ps, depth, &name_length )) 276 return false; 277 if ( !prs_uint16( "class_length", ps, depth, &class_length )) 278 return false; 279 280 if ( class_length ) { 281 ;; 282 } 283 284 if ( name_length ) { 285 if ( ps->io ) { 286 if ( !(nk->keyname = (char*)zcalloc(sizeof(char), name_length+1 )) ) 287 return false; 288 } 289 290 if ( !prs_uint8s( true, "name", ps, depth, nk->keyname, name_length) ) 291 return false; 292 293 if ( ps->io ) 294 nk->keyname[name_length] = '\0'; 295 } 296 297 end_off = ps->data_offset; 298 299 /* data_size must be divisible by 8 and large enough to hold the original record */ 300 301 data_size = ((start_off - end_off) & 0xfffffff8 ); 302 if ( data_size > nk->rec_size ) 303 /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, nk->rec_size));*/ 304 305 if ( !ps->io ) 306 nk->hbin->dirty = true; 307 308 return true; 309 } 310 311 312 /******************************************************************* 313 *******************************************************************/ 314 314 static uint32 regf_block_checksum( prs_struct *ps ) 315 315 { 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 } 331 332 333 /******************************************************************* 334 *******************************************************************/316 char *buffer = ps->data_p; 317 uint32 checksum, x; 318 int i; 319 320 /* XOR of all bytes 0x0000 - 0x01FB */ 321 322 checksum = x = 0; 323 324 for ( i=0; i<0x01FB; i+=4 ) { 325 x = IVAL(buffer, i ); 326 checksum ^= x; 327 } 328 329 return checksum; 330 } 331 332 333 /******************************************************************* 334 *******************************************************************/ 335 335 static bool read_regf_block( REGF_FILE *file ) 336 336 { 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 DEBUG(0,("read_regf_block: invalid checksum\n" )); 360 361 362 363 364 } 365 366 367 /******************************************************************* 368 *******************************************************************/337 prs_struct ps; 338 uint32 checksum; 339 340 /* grab the first block from the file */ 341 342 if ( read_block( file, &ps, 0, REGF_BLOCKSIZE ) == -1 ) 343 return false; 344 345 /* parse the block and verify the checksum */ 346 347 if ( !prs_regf_block( "regf_header", &ps, 0, file ) ) 348 return false; 349 350 checksum = regf_block_checksum( &ps ); 351 352 if(ps.is_dynamic) 353 SAFE_FREE(ps.data_p); 354 ps.is_dynamic = false; 355 ps.buffer_size = 0; 356 ps.data_offset = 0; 357 358 if ( file->checksum != checksum ) { 359 /*DEBUG(0,("read_regf_block: invalid checksum\n" ));*/ 360 return false; 361 } 362 363 return true; 364 } 365 366 367 /******************************************************************* 368 *******************************************************************/ 369 369 static REGF_HBIN* read_hbin_block( REGF_FILE *file, off_t offset ) 370 370 { 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 DEBUG(10,("read_hbin_block: free space offset == 0x%x\n", hbin->free_off)); 447 448 449 450 451 371 REGF_HBIN *hbin; 372 uint32 record_size, curr_off, block_size, header; 373 374 if ( !(hbin = (REGF_HBIN*)zalloc(sizeof(REGF_HBIN))) ) 375 return NULL; 376 hbin->file_off = offset; 377 hbin->free_off = -1; 378 379 if ( read_block( file, &hbin->ps, offset, 0 ) == -1 ) 380 return NULL; 381 382 if ( !prs_hbin_block( "hbin", &hbin->ps, 0, hbin ) ) 383 return NULL; 384 385 /* this should be the same thing as hbin->block_size but just in case */ 386 387 block_size = hbin->ps.buffer_size; 388 389 /* Find the available free space offset. Always at the end, 390 so walk the record list and stop when you get to the end. 391 The end is defined by a record header of 0xffffffff. The 392 previous 4 bytes contains the amount of free space remaining 393 in the hbin block. */ 394 395 /* remember that the record_size is in the 4 bytes preceeding the record itself */ 396 397 if ( !prs_set_offset( &hbin->ps, file->data_offset+HBIN_HDR_SIZE-sizeof(uint32) ) ) 398 return false; 399 400 record_size = 0; 401 curr_off = hbin->ps.data_offset; 402 while ( header != 0xffffffff ) { 403 /* not done yet so reset the current offset to the 404 next record_size field */ 405 406 curr_off = curr_off+record_size; 407 408 /* for some reason the record_size of the last record in 409 an hbin block can extend past the end of the block 410 even though the record fits within the remaining 411 space....aaarrrgggghhhhhh */ 412 413 if ( curr_off >= block_size ) { 414 record_size = -1; 415 curr_off = -1; 416 break; 417 } 418 419 if ( !prs_set_offset( &hbin->ps, curr_off) ) 420 return false; 421 422 if ( !prs_uint32( "rec_size", &hbin->ps, 0, &record_size ) ) 423 return false; 424 if ( !prs_uint32( "header", &hbin->ps, 0, &header ) ) 425 return false; 426 427 assert( record_size != 0 ); 428 429 if ( record_size & 0x80000000 ) { 430 /* absolute_value(record_size) */ 431 record_size = (record_size ^ 0xffffffff) + 1; 432 } 433 } 434 435 /* save the free space offset */ 436 437 if ( header == 0xffffffff ) { 438 439 /* account for the fact that the curr_off is 4 bytes behind the actual 440 record header */ 441 442 hbin->free_off = curr_off + sizeof(uint32); 443 hbin->free_size = record_size; 444 } 445 446 /*DEBUG(10,("read_hbin_block: free space offset == 0x%x\n", hbin->free_off));*/ 447 448 if ( !prs_set_offset( &hbin->ps, file->data_offset+HBIN_HDR_SIZE ) ) 449 return false; 450 451 return hbin; 452 452 } 453 453 … … 459 459 static bool hbin_contains_offset( REGF_HBIN *hbin, uint32 offset ) 460 460 { 461 462 463 464 465 466 467 461 if ( !hbin ) 462 return false; 463 464 if ( (offset > hbin->first_hbin_off) && (offset < (hbin->first_hbin_off+hbin->block_size)) ) 465 return true; 466 467 return false; 468 468 } 469 469 … … 475 475 static REGF_HBIN* lookup_hbin_block( REGF_FILE *file, uint32 offset ) 476 476 { 477 478 479 480 481 482 483 DEBUG(10,("lookup_hbin_block: address = 0x%x [0x%x]\n", hbin->file_off, (uint32)hbin )); 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 } 516 517 518 /******************************************************************* 519 *******************************************************************/477 REGF_HBIN *hbin = NULL; 478 uint32 block_off; 479 480 /* start with the open list */ 481 482 for ( hbin=file->block_list; hbin; hbin=hbin->next ) { 483 /* DEBUG(10,("lookup_hbin_block: address = 0x%x [0x%x]\n", hbin->file_off, (uint32)hbin ));*/ 484 if ( hbin_contains_offset( hbin, offset ) ) 485 return hbin; 486 } 487 488 if ( !hbin ) { 489 /* start at the beginning */ 490 491 block_off = REGF_BLOCKSIZE; 492 do { 493 /* cleanup before the next round */ 494 if ( hbin ) 495 { 496 if(hbin->ps.is_dynamic) 497 SAFE_FREE(hbin->ps.data_p); 498 hbin->ps.is_dynamic = false; 499 hbin->ps.buffer_size = 0; 500 hbin->ps.data_offset = 0; 501 } 502 503 hbin = read_hbin_block( file, block_off ); 504 505 if ( hbin ) 506 block_off = hbin->file_off + hbin->block_size; 507 508 } while ( hbin && !hbin_contains_offset( hbin, offset ) ); 509 } 510 511 if ( hbin ) 512 DLIST_ADD( file->block_list, hbin ); 513 514 return hbin; 515 } 516 517 518 /******************************************************************* 519 *******************************************************************/ 520 520 static bool prs_hash_rec( const char *desc, prs_struct *ps, int depth, REGF_HASH_REC *hash ) 521 521 { 522 523 524 525 526 527 528 529 530 } 531 532 533 /******************************************************************* 534 *******************************************************************/522 depth++; 523 524 if ( !prs_uint32( "nk_off", ps, depth, &hash->nk_off )) 525 return false; 526 if ( !prs_uint8s( true, "keycheck", ps, depth, hash->keycheck, sizeof( hash->keycheck )) ) 527 return false; 528 529 return true; 530 } 531 532 533 /******************************************************************* 534 *******************************************************************/ 535 535 static bool hbin_prs_lf_records( const char *desc, REGF_HBIN *hbin, int depth, REGF_NK_REC *nk ) 536 536 { 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->rec_size)); 584 585 586 587 588 589 } 590 591 592 /******************************************************************* 593 *******************************************************************/537 int i; 538 REGF_LF_REC *lf = &nk->subkeys; 539 uint32 data_size, start_off, end_off; 540 541 depth++; 542 543 /* check if we have anything to do first */ 544 545 if ( nk->num_subkeys == 0 ) 546 return true; 547 548 /* move to the LF record */ 549 550 if ( !prs_set_offset( &hbin->ps, nk->subkeys_off + HBIN_HDR_SIZE - hbin->first_hbin_off ) ) 551 return false; 552 553 /* backup and get the data_size */ 554 555 if ( !prs_set_offset( &hbin->ps, hbin->ps.data_offset-sizeof(uint32)) ) 556 return false; 557 start_off = hbin->ps.data_offset; 558 if ( !prs_uint32( "rec_size", &hbin->ps, depth, &lf->rec_size )) 559 return false; 560 561 if ( !prs_uint8s( true, "header", &hbin->ps, depth, lf->header, sizeof( lf->header )) ) 562 return false; 563 564 if ( !prs_uint16( "num_keys", &hbin->ps, depth, &lf->num_keys)) 565 return false; 566 567 if ( hbin->ps.io ) { 568 if ( !(lf->hashes = (REGF_HASH_REC*)zcalloc(sizeof(REGF_HASH_REC), lf->num_keys )) ) 569 return false; 570 } 571 572 for ( i=0; i<lf->num_keys; i++ ) { 573 if ( !prs_hash_rec( "hash_rec", &hbin->ps, depth, &lf->hashes[i] ) ) 574 return false; 575 } 576 577 end_off = hbin->ps.data_offset; 578 579 /* data_size must be divisible by 8 and large enough to hold the original record */ 580 581 data_size = ((start_off - end_off) & 0xfffffff8 ); 582 if ( data_size > lf->rec_size ) 583 /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, lf->rec_size));*/ 584 585 if ( !hbin->ps.io ) 586 hbin->dirty = true; 587 588 return true; 589 } 590 591 592 /******************************************************************* 593 *******************************************************************/ 594 594 static bool hbin_prs_sk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_SK_REC *sk ) 595 595 { 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->rec_size)); 638 639 640 641 642 643 } 644 645 646 /******************************************************************* 647 *******************************************************************/596 prs_struct *ps = &hbin->ps; 597 uint16 tag = 0xFFFF; 598 uint32 data_size, start_off, end_off; 599 600 601 depth++; 602 603 if ( !prs_set_offset( &hbin->ps, sk->sk_off + HBIN_HDR_SIZE - hbin->first_hbin_off ) ) 604 return false; 605 606 /* backup and get the data_size */ 607 608 if ( !prs_set_offset( &hbin->ps, hbin->ps.data_offset-sizeof(uint32)) ) 609 return false; 610 start_off = hbin->ps.data_offset; 611 if ( !prs_uint32( "rec_size", &hbin->ps, depth, &sk->rec_size )) 612 return false; 613 614 if ( !prs_uint8s( true, "header", ps, depth, sk->header, sizeof( sk->header )) ) 615 return false; 616 if ( !prs_uint16( "tag", ps, depth, &tag)) 617 return false; 618 619 if ( !prs_uint32( "prev_sk_off", ps, depth, &sk->prev_sk_off)) 620 return false; 621 if ( !prs_uint32( "next_sk_off", ps, depth, &sk->next_sk_off)) 622 return false; 623 if ( !prs_uint32( "ref_count", ps, depth, &sk->ref_count)) 624 return false; 625 if ( !prs_uint32( "size", ps, depth, &sk->size)) 626 return false; 627 628 if ( !sec_io_desc( "sec_desc", &sk->sec_desc, ps, depth )) 629 return false; 630 631 end_off = hbin->ps.data_offset; 632 633 /* data_size must be divisible by 8 and large enough to hold the original record */ 634 635 data_size = ((start_off - end_off) & 0xfffffff8 ); 636 if ( data_size > sk->rec_size ) 637 /*DEBUG(10,("Encountered reused record (0x%x < 0x%x)\n", data_size, sk->rec_size));*/ 638 639 if ( !hbin->ps.io ) 640 hbin->dirty = true; 641 642 return true; 643 } 644 645 646 /******************************************************************* 647 *******************************************************************/ 648 648 static bool hbin_prs_vk_rec( const char *desc, REGF_HBIN *hbin, int depth, 649 649 REGF_VK_REC *vk, REGF_FILE *file ) 650 650 { 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 DEBUG(10,("prs_vk_rec: data_size check failed (0x%x < 0x%x)\n", data_size, vk->rec_size)); 753 754 755 756 757 651 uint32 offset; 652 uint16 name_length; 653 prs_struct *ps = &hbin->ps; 654 uint32 data_size, start_off, end_off; 655 656 depth++; 657 658 /* backup and get the data_size */ 659 660 if ( !prs_set_offset( &hbin->ps, hbin->ps.data_offset-sizeof(uint32)) ) 661 return false; 662 start_off = hbin->ps.data_offset; 663 if ( !prs_uint32( "rec_size", &hbin->ps, depth, &vk->rec_size )) 664 return false; 665 666 if ( !prs_uint8s( true, "header", ps, depth, vk->header, sizeof( vk->header )) ) 667 return false; 668 669 if ( !hbin->ps.io ) 670 name_length = strlen(vk->valuename); 671 672 if ( !prs_uint16( "name_length", ps, depth, &name_length )) 673 return false; 674 if ( !prs_uint32( "data_size", ps, depth, &vk->data_size )) 675 return false; 676 if ( !prs_uint32( "data_off", ps, depth, &vk->data_off )) 677 return false; 678 if ( !prs_uint32( "type", ps, depth, &vk->type)) 679 return false; 680 if ( !prs_uint16( "flag", ps, depth, &vk->flag)) 681 return false; 682 683 offset = ps->data_offset; 684 offset += 2; /* skip 2 bytes */ 685 prs_set_offset( ps, offset ); 686 687 /* get the name */ 688 689 if ( vk->flag&VK_FLAG_NAME_PRESENT ) { 690 691 if ( hbin->ps.io ) { 692 if ( !(vk->valuename = (char*)zcalloc(sizeof(char), name_length+1 ))) 693 return false; 694 } 695 if ( !prs_uint8s( true, "name", ps, depth, vk->valuename, name_length ) ) 696 return false; 697 } 698 699 end_off = hbin->ps.data_offset; 700 701 /* get the data if necessary */ 702 703 if ( vk->data_size != 0 ) { 704 bool charmode = false; 705 706 if ( (vk->type == REG_SZ) || (vk->type == REG_MULTI_SZ) ) 707 charmode = true; 708 709 /* the data is stored in the offset if the size <= 4 */ 710 711 if ( !(vk->data_size & VK_DATA_IN_OFFSET) ) { 712 REGF_HBIN *hblock = hbin; 713 uint32 data_rec_size; 714 715 if ( hbin->ps.io ) { 716 if ( !(vk->data = (uint8*)zcalloc(sizeof(uint8), vk->data_size) ) ) 717 return false; 718 } 719 720 /* this data can be in another hbin */ 721 if ( !hbin_contains_offset( hbin, vk->data_off ) ) { 722 if ( !(hblock = lookup_hbin_block( file, vk->data_off )) ) 723 return false; 724 } 725 if ( !(prs_set_offset( &hblock->ps, (vk->data_off+HBIN_HDR_SIZE-hblock->first_hbin_off)-sizeof(uint32) )) ) 726 return false; 727 728 if ( !hblock->ps.io ) { 729 data_rec_size = ( (vk->data_size+sizeof(uint32)) & 0xfffffff8 ) + 8; 730 data_rec_size = ( data_rec_size - 1 ) ^ 0xFFFFFFFF; 731 } 732 if ( !prs_uint32( "data_rec_size", &hblock->ps, depth, &data_rec_size )) 733 return false; 734 if ( !prs_uint8s( charmode, "data", &hblock->ps, depth, vk->data, vk->data_size) ) 735 return false; 736 737 if ( !hblock->ps.io ) 738 hblock->dirty = true; 739 } 740 else { 741 if ( !(vk->data = zcalloc(sizeof(uint8), 4) ) ) 742 return false; 743 SIVAL( vk->data, 0, vk->data_off ); 744 } 745 746 } 747 748 /* data_size must be divisible by 8 and large enough to hold the original record */ 749 750 data_size = ((start_off - end_off ) & 0xfffffff8 ); 751 if ( data_size != vk->rec_size ) 752 /*DEBUG(10,("prs_vk_rec: data_size check failed (0x%x < 0x%x)\n", data_size, vk->rec_size));*/ 753 754 if ( !hbin->ps.io ) 755 hbin->dirty = true; 756 757 return true; 758 758 } 759 759 … … 766 766 int depth, REGF_NK_REC *nk, REGF_FILE *file ) 767 767 { 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 nk->values[i].hbin_off));810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 } 827 828 829 /******************************************************************* 830 *******************************************************************/768 int i; 769 uint32 record_size; 770 771 depth++; 772 773 /* check if we have anything to do first */ 774 775 if ( nk->num_values == 0 ) 776 return true; 777 778 if ( hbin->ps.io ) { 779 if ( !(nk->values = (REGF_VK_REC*)zcalloc(sizeof(REGF_VK_REC), nk->num_values ) ) ) 780 return false; 781 } 782 783 /* convert the offset to something relative to this HBIN block */ 784 785 if ( !prs_set_offset( &hbin->ps, nk->values_off+HBIN_HDR_SIZE-hbin->first_hbin_off-sizeof(uint32)) ) 786 return false; 787 788 if ( !hbin->ps.io ) { 789 record_size = ( ( nk->num_values * sizeof(uint32) ) & 0xfffffff8 ) + 8; 790 record_size = (record_size - 1) ^ 0xFFFFFFFF; 791 } 792 793 if ( !prs_uint32( "record_size", &hbin->ps, depth, &record_size ) ) 794 return false; 795 796 for ( i=0; i<nk->num_values; i++ ) { 797 if ( !prs_uint32( "vk_off", &hbin->ps, depth, &nk->values[i].rec_off ) ) 798 return false; 799 } 800 801 for ( i=0; i<nk->num_values; i++ ) { 802 REGF_HBIN *sub_hbin = hbin; 803 uint32 new_offset; 804 805 if ( !hbin_contains_offset( hbin, nk->values[i].rec_off ) ) { 806 sub_hbin = lookup_hbin_block( file, nk->values[i].rec_off ); 807 if ( !sub_hbin ) { 808 /*DEBUG(0,("hbin_prs_vk_records: Failed to find HBIN block containing offset [0x%x]\n", 809 nk->values[i].hbin_off));*/ 810 return false; 811 } 812 } 813 814 new_offset = nk->values[i].rec_off + HBIN_HDR_SIZE - sub_hbin->first_hbin_off; 815 if ( !prs_set_offset( &sub_hbin->ps, new_offset ) ) 816 return false; 817 if ( !hbin_prs_vk_rec( "vk_rec", sub_hbin, depth, &nk->values[i], file ) ) 818 return false; 819 } 820 821 if ( !hbin->ps.io ) 822 hbin->dirty = true; 823 824 825 return true; 826 } 827 828 829 /******************************************************************* 830 *******************************************************************/ 831 831 832 832 static REGF_SK_REC* find_sk_record_by_offset( REGF_FILE *file, uint32 offset ) 833 833 { 834 835 836 837 838 839 840 841 842 } 843 844 /******************************************************************* 845 *******************************************************************/834 REGF_SK_REC *p_sk; 835 836 for ( p_sk=file->sec_desc_list; p_sk; p_sk=p_sk->next ) { 837 if ( p_sk->sk_off == offset ) 838 return p_sk; 839 } 840 841 return NULL; 842 } 843 844 /******************************************************************* 845 *******************************************************************/ 846 846 847 847 static REGF_SK_REC* find_sk_record_by_sec_desc( REGF_FILE *file, SEC_DESC *sd ) 848 848 { 849 850 851 852 853 854 855 856 857 858 859 } 860 861 /******************************************************************* 862 *******************************************************************/849 REGF_SK_REC *p; 850 851 for ( p=file->sec_desc_list; p; p=p->next ) { 852 if ( sec_desc_equal( p->sec_desc, sd ) ) 853 return p; 854 } 855 856 /* failure */ 857 858 return NULL; 859 } 860 861 /******************************************************************* 862 *******************************************************************/ 863 863 864 864 static bool hbin_prs_key( REGF_FILE *file, REGF_HBIN *hbin, REGF_NK_REC *nk ) 865 865 { 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 nk->values_off));885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 nk->subkeys_off));902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 nk->subkeys_off));920 921 922 923 924 925 926 927 928 866 int depth = 0; 867 REGF_HBIN *sub_hbin; 868 869 depth++; 870 871 /* get the initial nk record */ 872 873 if ( !prs_nk_rec( "nk_rec", &hbin->ps, depth, nk )) 874 return false; 875 876 /* fill in values */ 877 878 if ( nk->num_values && (nk->values_off!=REGF_OFFSET_NONE) ) { 879 sub_hbin = hbin; 880 if ( !hbin_contains_offset( hbin, nk->values_off ) ) { 881 sub_hbin = lookup_hbin_block( file, nk->values_off ); 882 if ( !sub_hbin ) { 883 /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing value_list_offset [0x%x]\n", 884 nk->values_off));*/ 885 return false; 886 } 887 } 888 889 if ( !hbin_prs_vk_records( "vk_rec", sub_hbin, depth, nk, file )) 890 return false; 891 } 892 893 /* now get subkeys */ 894 895 if ( nk->num_subkeys && (nk->subkeys_off!=REGF_OFFSET_NONE) ) { 896 sub_hbin = hbin; 897 if ( !hbin_contains_offset( hbin, nk->subkeys_off ) ) { 898 sub_hbin = lookup_hbin_block( file, nk->subkeys_off ); 899 if ( !sub_hbin ) { 900 /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing subkey_offset [0x%x]\n", 901 nk->subkeys_off));*/ 902 return false; 903 } 904 } 905 906 if ( !hbin_prs_lf_records( "lf_rec", sub_hbin, depth, nk )) 907 return false; 908 } 909 910 /* get the to the security descriptor. First look if we have already parsed it */ 911 912 if ( (nk->sk_off!=REGF_OFFSET_NONE) && !( nk->sec_desc = find_sk_record_by_offset( file, nk->sk_off )) ) { 913 914 sub_hbin = hbin; 915 if ( !hbin_contains_offset( hbin, nk->sk_off ) ) { 916 sub_hbin = lookup_hbin_block( file, nk->sk_off ); 917 if ( !sub_hbin ) { 918 /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing sk_offset [0x%x]\n", 919 nk->subkeys_off));*/ 920 return false; 921 } 922 } 923 924 if ( !(nk->sec_desc = (REGF_SK_REC*)zalloc(sizeof(REGF_SK_REC) )) ) 925 return false; 926 nk->sec_desc->sk_off = nk->sk_off; 927 if ( !hbin_prs_sk_rec( "sk_rec", sub_hbin, depth, nk->sec_desc )) 928 return false; 929 929 930 931 932 933 934 935 936 937 } 938 939 /******************************************************************* 940 *******************************************************************/930 /* add to the list of security descriptors (ref_count has been read from the files) */ 931 932 nk->sec_desc->sk_off = nk->sk_off; 933 DLIST_ADD( file->sec_desc_list, nk->sec_desc ); 934 } 935 936 return true; 937 } 938 939 /******************************************************************* 940 *******************************************************************/ 941 941 942 942 static bool next_record( REGF_HBIN *hbin, const char *hdr, bool *eob ) 943 943 { 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 } 1001 1002 1003 /******************************************************************* 1004 *******************************************************************/944 char header[REC_HDR_SIZE] = ""; 945 uint32 record_size; 946 uint32 curr_off, block_size; 947 bool found = false; 948 prs_struct *ps = &hbin->ps; 949 950 curr_off = ps->data_offset; 951 if ( curr_off == 0 ) 952 prs_set_offset( ps, HBIN_HEADER_REC_SIZE ); 953 954 /* assume that the current offset is at the reacord header 955 and we need to backup to read the record size */ 956 957 curr_off -= sizeof(uint32); 958 959 block_size = ps->buffer_size; 960 record_size = 0; 961 while ( !found ) { 962 963 curr_off = curr_off+record_size; 964 if ( curr_off >= block_size ) 965 break; 966 967 if ( !prs_set_offset( &hbin->ps, curr_off) ) 968 return false; 969 970 if ( !prs_uint32( "record_size", ps, 0, &record_size ) ) 971 return false; 972 if ( !prs_uint8s( true, "header", ps, 0, header, REC_HDR_SIZE ) ) 973 return false; 974 975 if ( record_size & 0x80000000 ) { 976 /* absolute_value(record_size) */ 977 record_size = (record_size ^ 0xffffffff) + 1; 978 } 979 980 if ( memcmp( header, hdr, REC_HDR_SIZE ) == 0 ) { 981 found = true; 982 curr_off += sizeof(uint32); 983 } 984 } 985 986 /* mark prs_struct as done ( at end ) if no more SK records */ 987 /* mark end-of-block as true */ 988 989 if ( !found ) 990 { 991 prs_set_offset( &hbin->ps, hbin->ps.buffer_size ); 992 *eob = true; 993 return false; 994 } 995 996 if ( !prs_set_offset( ps, curr_off ) ) 997 return false; 998 999 return true; 1000 } 1001 1002 1003 /******************************************************************* 1004 *******************************************************************/ 1005 1005 static bool next_nk_record( REGF_FILE *file, REGF_HBIN *hbin, REGF_NK_REC *nk, bool *eob ) 1006 1006 { 1007 if ( next_record( hbin, "nk", eob ) && hbin_prs_key( file, hbin, nk ) ) 1008 return true; 1009 1010 return false; 1011 } 1012 1013 1014 /******************************************************************* 1015 Intialize the newly created REGF_BLOCK in *file and write the 1016 block header to disk 1017 *******************************************************************/ 1018 static bool init_regf_block( REGF_FILE *file ) 1019 { 1020 prs_struct ps; 1021 bool result = true; 1022 1023 if ( !prs_init( &ps, REGF_BLOCKSIZE, file->mem_ctx, MARSHALL ) ) 1024 return false; 1025 1026 memcpy( file->header, "regf", REGF_HDR_SIZE ); 1027 file->data_offset = 0x20; 1028 file->last_block = 0x1000; 1029 1030 /* set mod time */ 1031 1032 unix_to_nt_time( &file->mtime, time(NULL) ); 1033 1034 /* hard coded values...no diea what these are ... maybe in time */ 1035 1036 file->unknown1 = 0x2; 1037 file->unknown2 = 0x1; 1038 file->unknown3 = 0x3; 1039 file->unknown4 = 0x0; 1040 file->unknown5 = 0x1; 1041 file->unknown6 = 0x1; 1042 1043 /* write header to the buffer */ 1044 1045 if ( !prs_regf_block( "regf_header", &ps, 0, file ) ) { 1046 result = false; 1047 goto out; 1048 } 1049 1050 /* calculate the checksum, re-marshall data (to include the checksum) 1051 and write to disk */ 1052 1053 file->checksum = regf_block_checksum( &ps ); 1054 prs_set_offset( &ps, 0 ); 1055 if ( !prs_regf_block( "regf_header", &ps, 0, file ) ) { 1056 result = false; 1057 goto out; 1058 } 1059 1060 out: 1061 if(ps.is_dynamic) 1062 SAFE_FREE(ps.data_p); 1063 ps.is_dynamic = false; 1064 ps.buffer_size = 0; 1065 ps.data_offset = 0; 1066 1067 return result; 1007 if ( next_record( hbin, "nk", eob ) && hbin_prs_key( file, hbin, nk ) ) 1008 return true; 1009 1010 return false; 1068 1011 } 1069 1012 … … 1075 1018 REGF_FILE* regfio_open( const char *filename ) 1076 1019 { 1077 REGF_FILE *rb; 1078 int flags = O_RDONLY; 1079 1080 if ( !(rb = (REGF_FILE*)malloc(sizeof(REGF_FILE))) ) { 1081 DEBUG(0,("ERROR allocating memory\n")); 1082 return NULL; 1083 } 1084 zerop( rb ); 1085 rb->fd = -1; 1086 1087 /* if ( !(rb->mem_ctx = talloc_init( "read_regf_block" )) ) 1088 { 1089 regfio_close( rb ); 1090 return NULL; 1091 } 1092 */ 1093 rb->open_flags = flags; 1094 1095 /* open and existing file */ 1096 1097 if ( (rb->fd = open(filename, flags)) == -1 ) { 1098 DEBUG(0,("regfio_open: failure to open %s (%s)\n", filename, strerror(errno))); 1099 regfio_close( rb ); 1100 return NULL; 1101 } 1102 1103 /* check if we are creating a new file or overwriting an existing one */ 1104 1105 if ( flags & (O_CREAT|O_TRUNC) ) { 1106 if ( !init_regf_block( rb ) ) { 1107 DEBUG(0,("regfio_open: Failed to read initial REGF block\n")); 1108 regfio_close( rb ); 1109 return NULL; 1110 } 1111 1112 /* success */ 1113 return rb; 1114 } 1115 1116 /* read in an existing file */ 1117 1118 if ( !read_regf_block( rb ) ) { 1119 DEBUG(0,("regfio_open: Failed to read initial REGF block\n")); 1120 regfio_close( rb ); 1121 return NULL; 1122 } 1123 1124 /* success */ 1125 1126 return rb; 1127 } 1128 1129 1130 /******************************************************************* 1131 *******************************************************************/ 1020 REGF_FILE *rb; 1021 int flags = O_RDONLY; 1022 1023 if ( !(rb = (REGF_FILE*)malloc(sizeof(REGF_FILE))) ) { 1024 /* DEBUG(0,("ERROR allocating memory\n")); */ 1025 return NULL; 1026 } 1027 memset(rb, 0, sizeof(REGF_FILE)); 1028 rb->fd = -1; 1029 1030 /* if ( !(rb->mem_ctx = talloc_init( "read_regf_block" )) ) 1031 { 1032 regfio_close( rb ); 1033 return NULL; 1034 } 1035 */ 1036 rb->open_flags = flags; 1037 1038 /* open and existing file */ 1039 1040 if ( (rb->fd = open(filename, flags)) == -1 ) { 1041 /* DEBUG(0,("regfio_open: failure to open %s (%s)\n", filename, strerror(errno)));*/ 1042 regfio_close( rb ); 1043 return NULL; 1044 } 1045 1046 /* read in an existing file */ 1047 1048 if ( !read_regf_block( rb ) ) { 1049 /* DEBUG(0,("regfio_open: Failed to read initial REGF block\n"));*/ 1050 regfio_close( rb ); 1051 return NULL; 1052 } 1053 1054 /* success */ 1055 1056 return rb; 1057 } 1058 1059 1060 /******************************************************************* 1061 *******************************************************************/ 1132 1062 static void regfio_mem_free( REGF_FILE *file ) 1133 1063 { 1134 1064 /* free any zalloc()'d memory */ 1135 1065 1136 1066 /* if ( file && file->mem_ctx ) 1137 1067 free(file->mem_ctx); 1138 1068 */ 1139 1069 } … … 1141 1071 1142 1072 /******************************************************************* 1143 *******************************************************************/1073 *******************************************************************/ 1144 1074 int regfio_close( REGF_FILE *file ) 1145 1075 { 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1076 int fd; 1077 1078 regfio_mem_free( file ); 1079 1080 /* nothing to do if there is no open file */ 1081 1082 if ( !file || (file->fd == -1) ) 1083 return 0; 1084 1085 fd = file->fd; 1086 file->fd = -1; 1087 SAFE_FREE( file ); 1088 1089 return close( fd ); 1160 1090 } 1161 1091 … … 1167 1097 REGF_NK_REC* regfio_rootkey( REGF_FILE *file ) 1168 1098 { 1169 REGF_NK_REC *nk; 1170 REGF_HBIN *hbin; 1171 uint32 offset = REGF_BLOCKSIZE; 1172 bool found = false; 1173 bool eob; 1174 1175 if ( !file ) 1176 return NULL; 1177 1178 if ( !(nk = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC) )) ) { 1179 DEBUG(0,("regfio_rootkey: zalloc() failed!\n")); 1180 return NULL; 1099 REGF_NK_REC *nk; 1100 REGF_HBIN *hbin; 1101 uint32 offset = REGF_BLOCKSIZE; 1102 bool found = false; 1103 bool eob; 1104 1105 if ( !file ) 1106 return NULL; 1107 1108 if ( !(nk = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC) )) ) { 1109 /*DEBUG(0,("regfio_rootkey: zalloc() failed!\n"));*/ 1110 return NULL; 1111 } 1112 1113 /* scan through the file on HBIN block at a time looking 1114 for an NK record with a type == 0x002c. 1115 Normally this is the first nk record in the first hbin 1116 block (but I'm not assuming that for now) */ 1117 1118 while ( (hbin = read_hbin_block( file, offset )) ) { 1119 eob = false; 1120 1121 while ( !eob) { 1122 if ( next_nk_record( file, hbin, nk, &eob ) ) { 1123 if ( nk->key_type == NK_TYPE_ROOTKEY ) { 1124 found = true; 1125 break; 1181 1126 } 1182 1183 /* scan through the file on HBIN block at a time looking 1184 for an NK record with a type == 0x002c. 1185 Normally this is the first nk record in the first hbin 1186 block (but I'm not assuming that for now) */ 1187 1188 while ( (hbin = read_hbin_block( file, offset )) ) { 1189 eob = false; 1190 1191 while ( !eob) { 1192 if ( next_nk_record( file, hbin, nk, &eob ) ) { 1193 if ( nk->key_type == NK_TYPE_ROOTKEY ) { 1194 found = true; 1195 break; 1196 } 1197 } 1198 if(hbin->ps.is_dynamic) 1199 SAFE_FREE(hbin->ps.data_p); 1200 hbin->ps.is_dynamic = false; 1201 hbin->ps.buffer_size = 0; 1202 hbin->ps.data_offset = 0; 1203 } 1204 1205 if ( found ) 1206 break; 1207 1208 offset += hbin->block_size; 1209 } 1210 1211 if ( !found ) { 1212 DEBUG(0,("regfio_rootkey: corrupt registry file ? No root key record located\n")); 1213 return NULL; 1214 } 1215 1216 DLIST_ADD( file->block_list, hbin ); 1217 1218 return nk; 1127 } 1128 if(hbin->ps.is_dynamic) 1129 SAFE_FREE(hbin->ps.data_p); 1130 hbin->ps.is_dynamic = false; 1131 hbin->ps.buffer_size = 0; 1132 hbin->ps.data_offset = 0; 1133 } 1134 1135 if ( found ) 1136 break; 1137 1138 offset += hbin->block_size; 1139 } 1140 1141 if ( !found ) { 1142 /*DEBUG(0,("regfio_rootkey: corrupt registry file ? No root key record located\n"));*/ 1143 return NULL; 1144 } 1145 1146 DLIST_ADD( file->block_list, hbin ); 1147 1148 return nk; 1219 1149 } 1220 1150 … … 1226 1156 REGF_NK_REC* regfio_fetch_subkey( REGF_FILE *file, REGF_NK_REC *nk ) 1227 1157 { 1228 REGF_NK_REC *subkey; 1229 REGF_HBIN *hbin; 1230 uint32 nk_offset; 1231 1232 /* see if there is anything left to report */ 1233 1234 if ( !nk || (nk->subkeys_off==REGF_OFFSET_NONE) || (nk->subkey_index >= nk->num_subkeys) ) 1235 return NULL; 1236 1237 /* find the HBIN block which should contain the nk record */ 1238 1239 if ( !(hbin = lookup_hbin_block( file, nk->subkeys.hashes[nk->subkey_index].nk_off )) ) { 1240 DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing offset [0x%x]\n", 1241 nk->subkeys.hashes[nk->subkey_index].nk_off)); 1242 return NULL; 1243 } 1244 1245 nk_offset = nk->subkeys.hashes[nk->subkey_index].nk_off; 1246 if ( !prs_set_offset( &hbin->ps, (HBIN_HDR_SIZE + nk_offset - hbin->first_hbin_off) ) ) 1247 return NULL; 1248 1249 nk->subkey_index++; 1250 if (!(subkey = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC)))) 1251 return NULL; 1252 1253 if ( !hbin_prs_key( file, hbin, subkey ) ) 1254 return NULL; 1255 1256 return subkey; 1257 } 1158 REGF_NK_REC *subkey; 1159 REGF_HBIN *hbin; 1160 uint32 nk_offset; 1161 1162 /* see if there is anything left to report */ 1163 1164 if ( !nk || (nk->subkeys_off==REGF_OFFSET_NONE) || (nk->subkey_index >= nk->num_subkeys) ) 1165 return NULL; 1166 1167 /* find the HBIN block which should contain the nk record */ 1168 1169 if(!(hbin 1170 = lookup_hbin_block(file, nk->subkeys.hashes[nk->subkey_index].nk_off ))) 1171 { 1172 /*DEBUG(0,("hbin_prs_key: Failed to find HBIN block containing offset [0x%x]\n", 1173 nk->subkeys.hashes[nk->subkey_index].nk_off));*/ 1174 return NULL; 1175 } 1176 1177 nk_offset = nk->subkeys.hashes[nk->subkey_index].nk_off; 1178 if ( !prs_set_offset( &hbin->ps, (HBIN_HDR_SIZE + nk_offset - hbin->first_hbin_off) ) ) 1179 return NULL; 1180 1181 nk->subkey_index++; 1182 if (!(subkey = (REGF_NK_REC*)zalloc(sizeof(REGF_NK_REC)))) 1183 return NULL; 1184 1185 if ( !hbin_prs_key( file, hbin, subkey ) ) 1186 return NULL; 1187 1188 return subkey; 1189 } -
trunk/lib/smb_deps.c
r30 r31 33 33 { 34 34 void* ret_val = NULL; 35 if( ret_val = (void*)malloc(size))35 if((ret_val = (void*)malloc(size)) != NULL) 36 36 memset(ret_val, 0, size); 37 37 return ret_val; … … 42 42 return zalloc(size*count); 43 43 } 44 45 void zerop(void* p)46 {47 if(p)48 memset((char*)p, 0, sizeof(*p));49 }50 51 44 52 45 /* From lib/time.c */ … … 182 175 bool prs_init(prs_struct *ps, uint32 size, void *ctx, bool io) 183 176 { 184 zerop(ps);185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 177 memset(ps, 0, sizeof(prs_struct)); 178 ps->io = io; 179 ps->bigendian_data = RPC_LITTLE_ENDIAN; 180 ps->align = RPC_PARSE_ALIGN; 181 ps->is_dynamic = false; 182 ps->data_offset = 0; 183 ps->buffer_size = 0; 184 ps->data_p = NULL; 185 ps->mem_ctx = ctx; 186 187 if (size != 0) { 188 ps->buffer_size = size; 189 if((ps->data_p = (char *)zalloc((size_t)size)) == NULL) { 190 return false; 191 } 192 memset(ps->data_p, '\0', (size_t)size); 193 ps->is_dynamic = true; /* We own this memory. */ 194 } 195 196 return true; 204 197 } 205 198 … … 529 522 Compare the auth portion of two sids. 530 523 *****************************************************************/ 531 staticint sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2)524 int sid_compare_auth(const DOM_SID *sid1, const DOM_SID *sid2) 532 525 { 533 526 int i; -
trunk/test/Makefile
r30 r31 3 3 ################################################################################ 4 4 5 CC=gcc 6 OPTS=-ggdb -std=gnu89 -pedantic -Wall 7 5 8 REGFIO_O=../lib/regfio.o 6 9 LIB_REGFIO_O=lib-regfio.o 7 10 LIB_REGFIO=lib-regfio 8 FILES=$(LIB_REGFIO) $( REGFIO_O)11 FILES=$(LIB_REGFIO) $(LIB_REGFIO_O) 9 12 10 13 all: $(FILES) 11 12 $(REGFIO_O): ../lib/regfio.c13 $(CC) $(CFLAGS) $(OPTS) -c -o $@ ../lib/regfio.c14 14 15 15 $(LIB_REGFIO_O): lib-regfio.c 16 16 $(CC) $(CFLAGS) $(OPTS) -c -o $@ lib-regfio.c 17 17 18 $(LIB_REGFIO): $(LIB_REGFIO_O) $(REGFIO_O) 19 $(CC) $(CFLAGS) $(OPTS) -o $@ $(LIB_REGFIO_O) $(REGFIO_O) ../lib/smb_deps.c 18 $(LIB_REGFIO): $(LIB_REGFIO_O) $(REGFIO_O) ../lib/smb_deps.o ../lib/void_stack.o 19 $(CC) $(CFLAGS) $(OPTS) -o $@ $(LIB_REGFIO_O) $(REGFIO_O) ../lib/smb_deps.o ../lib/void_stack.o 20 21 22 clean: 23 rm -f $(FILES) -
trunk/test/lib-regfio.c
r30 r31 1 1 /* 2 * A utility to test functionality of Gerald Carter''s reg io interface.2 * A utility to test functionality of Gerald Carter''s regfio interface. 3 3 * 4 4 * Copyright (C) 2005 Timothy D. Morgan … … 25 25 #include <string.h> 26 26 #include "../include/regfio.h" 27 #include "../include/void_stack.h" 27 28 28 void printKeyTree(REGF_FILE* f, REGF_NK_REC* cur, char* prefix) 29 30 char* getStackPath(void_stack* nk_stack) 29 31 { 32 REGF_NK_REC* cur; 33 unsigned int buf_left = 127; 34 unsigned int buf_len = buf_left+1; 35 unsigned int name_len = 0; 36 unsigned int grow_amt; 37 char* buf; 38 char* new_buf; 39 void_stack_iterator* iter; 40 41 buf = (char*)malloc((buf_len)*sizeof(char)); 42 if (buf == NULL) 43 return NULL; 44 buf[0] = '\0'; 45 46 iter = void_stack_iterator_new(nk_stack); 47 if (iter == NULL) 48 { 49 free(buf); 50 return NULL; 51 } 52 53 while((cur = void_stack_iterator_next(iter)) != NULL) 54 { 55 name_len = strlen(cur->keyname); 56 if(name_len+1 > buf_left) 57 { 58 grow_amt = (unsigned int)(buf_len/3); 59 buf_len += name_len+1+grow_amt-buf_left; 60 if((new_buf = realloc(buf, buf_len)) == NULL) 61 { 62 free(buf); 63 free(iter); 64 return NULL; 65 } 66 buf = new_buf; 67 buf_left = grow_amt + name_len + 1; 68 } 69 strncpy(buf+(buf_len-buf_left-1), cur->keyname, name_len); 70 buf_left -= name_len; 71 buf[buf_len-buf_left-1] = '/'; 72 buf_left -= 1; 73 buf[buf_len-buf_left-1] = '\0'; 74 } 75 76 return buf; 77 } 78 79 80 void printKeyTree(REGF_FILE* f, void_stack* nk_stack) 81 { 82 REGF_NK_REC* cur; 30 83 REGF_NK_REC* sub; 31 char* sub_prefix;84 char* path; 32 85 33 if(prefix!= NULL)86 while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL) 34 87 { 35 sub_prefix = (char*)zalloc(strlen(prefix)+strlen(cur->keyname)+2); 36 strcpy(sub_prefix, prefix); 37 strcat(sub_prefix, "/"); 88 if((sub = regfio_fetch_subkey(f, cur)) != NULL) 89 { 90 path = getStackPath(nk_stack); 91 if(path != NULL) 92 { 93 printf("%s%s:KEY\n", path, sub->keyname); 94 free(path); 95 } 96 void_stack_push(nk_stack, sub); 97 } 98 else 99 { 100 cur = void_stack_pop(nk_stack); 101 /* XXX: This is just a shallow free. Need to write deep free 102 * routines to replace the Samba code for this. 103 */ 104 if(cur != NULL) 105 free(cur); 106 } 38 107 } 39 else40 sub_prefix = (char*)zalloc(strlen(cur->keyname)+2);41 42 strcat(sub_prefix, cur->keyname);43 44 printf("%s:KEY\n", sub_prefix);45 while ((sub = regfio_fetch_subkey(f, cur)) != NULL)46 printKeyTree(f, sub, sub_prefix);47 48 free(sub_prefix);49 108 } 50 109 … … 52 111 int main(int argc, char** argv) 53 112 { 113 void_stack* nk_stack; 114 REGF_FILE* f; 115 REGF_NK_REC* root; 116 54 117 if(argc < 2) 55 118 { … … 58 121 } 59 122 60 REGF_FILE*f = regfio_open( argv[1] );61 REGF_NK_REC*root = regfio_rootkey(f);123 f = regfio_open( argv[1] ); 124 root = regfio_rootkey(f); 62 125 63 printKeyTree(f, root, NULL); 126 nk_stack = void_stack_new(1024); 127 if(void_stack_push(nk_stack, root)) 128 printKeyTree(f, nk_stack); 129 void_stack_destroy(nk_stack); 130 64 131 regfio_close(f); 65 132 /*
Note: See TracChangeset
for help on using the changeset viewer.