1 /*
2 * Security descriptor index functions
3 *
4 * Copyright (C) 2010-2021, Joachim Metz <joachim.metz@gmail.com>
5 *
6 * Refer to AUTHORS for acknowledgements.
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation, either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22 #include <common.h>
23 #include <byte_stream.h>
24 #include <memory.h>
25 #include <types.h>
26
27 #include "libfsntfs_data_stream.h"
28 #include "libfsntfs_definitions.h"
29 #include "libfsntfs_index.h"
30 #include "libfsntfs_index_node.h"
31 #include "libfsntfs_index_value.h"
32 #include "libfsntfs_libbfio.h"
33 #include "libfsntfs_libcdata.h"
34 #include "libfsntfs_libcerror.h"
35 #include "libfsntfs_libcnotify.h"
36 #include "libfsntfs_mft_attribute.h"
37 #include "libfsntfs_mft_entry.h"
38 #include "libfsntfs_security_descriptor_index.h"
39 #include "libfsntfs_security_descriptor_index_value.h"
40 #include "libfsntfs_security_descriptor_values.h"
41 #include "libfsntfs_sds_index_value.h"
42 #include "libfsntfs_types.h"
43
44 #include "fsntfs_secure.h"
45
46 /* Creates a security descriptor index
47 * Make sure the value security_descriptor_index is referencing, is set to NULL
48 * Returns 1 if successful or -1 on error
49 */
libfsntfs_security_descriptor_index_initialize(libfsntfs_security_descriptor_index_t ** security_descriptor_index,libfsntfs_io_handle_t * io_handle,libbfio_handle_t * file_io_handle,libfsntfs_mft_attribute_t * data_attribute,libcerror_error_t ** error)50 int libfsntfs_security_descriptor_index_initialize(
51 libfsntfs_security_descriptor_index_t **security_descriptor_index,
52 libfsntfs_io_handle_t *io_handle,
53 libbfio_handle_t *file_io_handle,
54 libfsntfs_mft_attribute_t *data_attribute,
55 libcerror_error_t **error )
56 {
57 static char *function = "libfsntfs_security_descriptor_index_initialize";
58
59 if( security_descriptor_index == NULL )
60 {
61 libcerror_error_set(
62 error,
63 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
64 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
65 "%s: invalid security descriptor index.",
66 function );
67
68 return( -1 );
69 }
70 if( *security_descriptor_index != NULL )
71 {
72 libcerror_error_set(
73 error,
74 LIBCERROR_ERROR_DOMAIN_RUNTIME,
75 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
76 "%s: invalid security descriptor index value already set.",
77 function );
78
79 return( -1 );
80 }
81 if( data_attribute == NULL )
82 {
83 libcerror_error_set(
84 error,
85 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
86 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
87 "%s: invalid $SDS data attribute.",
88 function );
89
90 return( -1 );
91 }
92 *security_descriptor_index = memory_allocate_structure(
93 libfsntfs_security_descriptor_index_t );
94
95 if( *security_descriptor_index == NULL )
96 {
97 libcerror_error_set(
98 error,
99 LIBCERROR_ERROR_DOMAIN_MEMORY,
100 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
101 "%s: unable to create security descriptor index.",
102 function );
103
104 goto on_error;
105 }
106 if( memory_set(
107 *security_descriptor_index,
108 0,
109 sizeof( libfsntfs_security_descriptor_index_t ) ) == NULL )
110 {
111 libcerror_error_set(
112 error,
113 LIBCERROR_ERROR_DOMAIN_MEMORY,
114 LIBCERROR_MEMORY_ERROR_SET_FAILED,
115 "%s: unable to clear security descriptor index.",
116 function );
117
118 memory_free(
119 *security_descriptor_index );
120
121 *security_descriptor_index = NULL;
122
123 return( -1 );
124 }
125 /* TODO move out of index ? */
126 if( libfsntfs_data_stream_initialize(
127 &( ( *security_descriptor_index )->data_stream ),
128 file_io_handle,
129 io_handle,
130 data_attribute,
131 error ) != 1 )
132 {
133 libcerror_error_set(
134 error,
135 LIBCERROR_ERROR_DOMAIN_RUNTIME,
136 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
137 "%s: unable to create $SDS data stream.",
138 function );
139
140 goto on_error;
141 }
142 return( 1 );
143
144 on_error:
145 if( *security_descriptor_index != NULL )
146 {
147 memory_free(
148 *security_descriptor_index );
149
150 *security_descriptor_index = NULL;
151 }
152 return( -1 );
153 }
154
155 /* Frees a security descriptor index
156 * Returns 1 if successful or -1 on error
157 */
libfsntfs_security_descriptor_index_free(libfsntfs_security_descriptor_index_t ** security_descriptor_index,libcerror_error_t ** error)158 int libfsntfs_security_descriptor_index_free(
159 libfsntfs_security_descriptor_index_t **security_descriptor_index,
160 libcerror_error_t **error )
161 {
162 static char *function = "libfsntfs_security_descriptor_index_free";
163 int result = 1;
164
165 if( security_descriptor_index == NULL )
166 {
167 libcerror_error_set(
168 error,
169 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
170 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
171 "%s: invalid security descriptor index.",
172 function );
173
174 return( -1 );
175 }
176 if( *security_descriptor_index != NULL )
177 {
178 if( ( *security_descriptor_index )->sii_index != NULL )
179 {
180 if( libfsntfs_index_free(
181 &( ( *security_descriptor_index )->sii_index ),
182 error ) != 1 )
183 {
184 libcerror_error_set(
185 error,
186 LIBCERROR_ERROR_DOMAIN_RUNTIME,
187 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
188 "%s: unable to free $SII index.",
189 function );
190
191 result = -1;
192 }
193 }
194 if( libfsntfs_data_stream_free(
195 &( ( *security_descriptor_index )->data_stream ),
196 error ) != 1 )
197 {
198 libcerror_error_set(
199 error,
200 LIBCERROR_ERROR_DOMAIN_RUNTIME,
201 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
202 "%s: unable to free $SDS data stream.",
203 function );
204
205 result = -1;
206 }
207 memory_free(
208 *security_descriptor_index );
209
210 *security_descriptor_index = NULL;
211 }
212 return( result );
213 }
214
215 /* Reads the security descriptor identifier ($SII) index
216 * Returns 1 if successful or -1 on error
217 */
libfsntfs_security_descriptor_index_read_sii_index(libfsntfs_security_descriptor_index_t * security_descriptor_index,libfsntfs_io_handle_t * io_handle,libbfio_handle_t * file_io_handle,libfsntfs_mft_entry_t * mft_entry,libcerror_error_t ** error)218 int libfsntfs_security_descriptor_index_read_sii_index(
219 libfsntfs_security_descriptor_index_t *security_descriptor_index,
220 libfsntfs_io_handle_t *io_handle,
221 libbfio_handle_t *file_io_handle,
222 libfsntfs_mft_entry_t *mft_entry,
223 libcerror_error_t **error )
224 {
225 static char *function = "libfsntfs_security_descriptor_index_read_sii_index";
226 uint32_t attribute_type = 0;
227 uint32_t collation_type = 0;
228 int result = 0;
229
230 if( security_descriptor_index == NULL )
231 {
232 libcerror_error_set(
233 error,
234 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
235 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
236 "%s: invalid security descriptor index.",
237 function );
238
239 return( -1 );
240 }
241 if( security_descriptor_index->sii_index != NULL )
242 {
243 libcerror_error_set(
244 error,
245 LIBCERROR_ERROR_DOMAIN_RUNTIME,
246 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
247 "%s: invalid security descriptor index - $SII index value already set.",
248 function );
249
250 return( -1 );
251 }
252 if( libfsntfs_index_initialize(
253 &( security_descriptor_index->sii_index ),
254 io_handle,
255 (uint8_t *) "$SII",
256 5,
257 error ) != 1 )
258 {
259 libcerror_error_set(
260 error,
261 LIBCERROR_ERROR_DOMAIN_RUNTIME,
262 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
263 "%s: unable to create $SII index.",
264 function );
265
266 goto on_error;
267 }
268 result = libfsntfs_index_read(
269 security_descriptor_index->sii_index,
270 file_io_handle,
271 mft_entry,
272 0,
273 error );
274
275 if( result == -1 )
276 {
277 libcerror_error_set(
278 error,
279 LIBCERROR_ERROR_DOMAIN_IO,
280 LIBCERROR_IO_ERROR_READ_FAILED,
281 "%s: unable to read $SII index.",
282 function );
283
284 goto on_error;
285 }
286 else if( result != 0 )
287 {
288 if( libfsntfs_index_get_attribute_type(
289 security_descriptor_index->sii_index,
290 &attribute_type,
291 error ) != 1 )
292 {
293 libcerror_error_set(
294 error,
295 LIBCERROR_ERROR_DOMAIN_RUNTIME,
296 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
297 "%s: unable to retrieve attribute type from index.",
298 function );
299
300 goto on_error;
301 }
302 if( attribute_type != 0 )
303 {
304 libcerror_error_set(
305 error,
306 LIBCERROR_ERROR_DOMAIN_RUNTIME,
307 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
308 "%s: unsupported index attribute type.",
309 function );
310
311 goto on_error;
312 }
313 if( libfsntfs_index_get_collation_type(
314 security_descriptor_index->sii_index,
315 &collation_type,
316 error ) != 1 )
317 {
318 libcerror_error_set(
319 error,
320 LIBCERROR_ERROR_DOMAIN_RUNTIME,
321 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
322 "%s: unable to retrieve collation type from index.",
323 function );
324
325 goto on_error;
326 }
327 if( collation_type != 16 )
328 {
329 libcerror_error_set(
330 error,
331 LIBCERROR_ERROR_DOMAIN_RUNTIME,
332 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
333 "%s: unsupported index collation type.",
334 function );
335
336 goto on_error;
337 }
338 }
339 return( 1 );
340
341 on_error:
342 if( security_descriptor_index->sii_index != NULL )
343 {
344 libfsntfs_index_free(
345 &( security_descriptor_index->sii_index ),
346 NULL );
347 }
348 return( -1 );
349 }
350
351 /* Retrieves the security descriptor from an index node for a specific identifier
352 * This function creates new security descriptor values
353 * Returns 1 if successful, 0 if no such security descriptor or -1 on error
354 */
libfsntfs_security_descriptor_index_get_entry_from_index_node_by_identifier(libfsntfs_security_descriptor_index_t * security_descriptor_index,libbfio_handle_t * file_io_handle,libfsntfs_index_node_t * index_node,uint32_t security_descriptor_identifier,libfsntfs_security_descriptor_values_t ** security_descriptor_values,int recursion_depth,libcerror_error_t ** error)355 int libfsntfs_security_descriptor_index_get_entry_from_index_node_by_identifier(
356 libfsntfs_security_descriptor_index_t *security_descriptor_index,
357 libbfio_handle_t *file_io_handle,
358 libfsntfs_index_node_t *index_node,
359 uint32_t security_descriptor_identifier,
360 libfsntfs_security_descriptor_values_t **security_descriptor_values,
361 int recursion_depth,
362 libcerror_error_t **error )
363 {
364 uint8_t secure_index_value_data[ sizeof( fsntfs_secure_index_value_t ) ];
365
366 libfsntfs_index_node_t *sub_node = NULL;
367 libfsntfs_index_value_t *index_value = NULL;
368 libfsntfs_sds_index_value_t *sds_index_value = NULL;
369 libfsntfs_security_descriptor_index_value_t *security_descriptor_index_value = NULL;
370 libfsntfs_security_descriptor_values_t *safe_security_descriptor_values = NULL;
371 static char *function = "libfsntfs_security_descriptor_index_get_entry_from_index_node_by_identifier";
372 size_t security_descriptor_data_size = 0;
373 ssize_t read_count = 0;
374 off64_t index_entry_offset = 0;
375 int compare_result = 0;
376 int index_value_entry = 0;
377 int is_allocated = 0;
378 int number_of_index_values = 0;
379 int result = 0;
380
381 if( security_descriptor_index == NULL )
382 {
383 libcerror_error_set(
384 error,
385 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
386 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
387 "%s: invalid security descriptor index.",
388 function );
389
390 return( -1 );
391 }
392 if( security_descriptor_index->sii_index == NULL )
393 {
394 libcerror_error_set(
395 error,
396 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
397 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
398 "%s: invalid security descriptor index - missing $SII index.",
399 function );
400
401 return( -1 );
402 }
403 if( security_descriptor_index->sii_index->io_handle == NULL )
404 {
405 libcerror_error_set(
406 error,
407 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
408 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
409 "%s: invalid security descriptor index - invalid $SII index - missing IO handle.",
410 function );
411
412 return( -1 );
413 }
414 if( security_descriptor_values == NULL )
415 {
416 libcerror_error_set(
417 error,
418 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
419 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
420 "%s: invalid security descriptor values.",
421 function );
422
423 return( -1 );
424 }
425 if( ( recursion_depth < 0 )
426 || ( recursion_depth > LIBFSNTFS_MAXIMUM_RECURSION_DEPTH ) )
427 {
428 libcerror_error_set(
429 error,
430 LIBCERROR_ERROR_DOMAIN_RUNTIME,
431 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
432 "%s: invalid recursion depth value out of bounds.",
433 function );
434
435 return( -1 );
436 }
437 if( libfsntfs_index_node_get_number_of_values(
438 index_node,
439 &number_of_index_values,
440 error ) != 1 )
441 {
442 libcerror_error_set(
443 error,
444 LIBCERROR_ERROR_DOMAIN_RUNTIME,
445 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
446 "%s: unable to retrieve number of values from index node.",
447 function );
448
449 goto on_error;
450 }
451 for( index_value_entry = 0;
452 index_value_entry < number_of_index_values;
453 index_value_entry++ )
454 {
455 if( libfsntfs_index_node_get_value_by_index(
456 index_node,
457 index_value_entry,
458 &index_value,
459 error ) != 1 )
460 {
461 libcerror_error_set(
462 error,
463 LIBCERROR_ERROR_DOMAIN_RUNTIME,
464 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
465 "%s: unable to retrieve value: %d from index node.",
466 function,
467 index_value_entry );
468
469 goto on_error;
470 }
471 if( ( index_value->flags & LIBFSNTFS_INDEX_VALUE_FLAG_HAS_SUB_NODE ) != 0 )
472 {
473 if( index_value->sub_node_vcn > (uint64_t) INT_MAX )
474 {
475 libcerror_error_set(
476 error,
477 LIBCERROR_ERROR_DOMAIN_RUNTIME,
478 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
479 "%s: node index value: %d sub node VCN value out of bounds.",
480 function,
481 index_value_entry );
482
483 goto on_error;
484 }
485 is_allocated = libfsntfs_index_sub_node_is_allocated(
486 security_descriptor_index->sii_index,
487 (int) index_value->sub_node_vcn,
488 error );
489
490 if( is_allocated == -1 )
491 {
492 libcerror_error_set(
493 error,
494 LIBCERROR_ERROR_DOMAIN_RUNTIME,
495 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
496 "%s: unable to determine if sub node with VCN: %d is allocated.",
497 function,
498 (int) index_value->sub_node_vcn );
499
500 goto on_error;
501 }
502 else if( is_allocated == 0 )
503 {
504 continue;
505 }
506 }
507 if( ( index_value->flags & LIBFSNTFS_INDEX_VALUE_FLAG_IS_LAST ) != 0 )
508 {
509 break;
510 }
511 if( libfsntfs_security_descriptor_index_value_initialize(
512 &security_descriptor_index_value,
513 error ) != 1 )
514 {
515 libcerror_error_set(
516 error,
517 LIBCERROR_ERROR_DOMAIN_RUNTIME,
518 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
519 "%s: unable to create security descriptor index value.",
520 function );
521
522 goto on_error;
523 }
524 if( libfsntfs_security_descriptor_index_value_read_data(
525 security_descriptor_index_value,
526 index_value->value_data,
527 (size_t) index_value->value_data_size,
528 error ) != 1 )
529 {
530 libcerror_error_set(
531 error,
532 LIBCERROR_ERROR_DOMAIN_IO,
533 LIBCERROR_IO_ERROR_READ_FAILED,
534 "%s: unable to read security descriptor index value.",
535 function );
536
537 goto on_error;
538 }
539 if( security_descriptor_identifier < security_descriptor_index_value->identifier )
540 {
541 compare_result = LIBCDATA_COMPARE_LESS;
542 }
543 else if( security_descriptor_identifier > security_descriptor_index_value->identifier )
544 {
545 compare_result = LIBCDATA_COMPARE_GREATER;
546 }
547 else
548 {
549 compare_result = LIBCDATA_COMPARE_EQUAL;
550 }
551 if( compare_result != LIBCDATA_COMPARE_EQUAL )
552 {
553 if( libfsntfs_security_descriptor_index_value_free(
554 &security_descriptor_index_value,
555 error ) != 1 )
556 {
557 libcerror_error_set(
558 error,
559 LIBCERROR_ERROR_DOMAIN_RUNTIME,
560 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
561 "%s: unable to free security descriptor index value.",
562 function );
563
564 goto on_error;
565 }
566 }
567 if( compare_result == LIBCDATA_COMPARE_LESS )
568 {
569 if( ( index_value->flags & LIBFSNTFS_INDEX_VALUE_FLAG_HAS_SUB_NODE ) != 0 )
570 {
571 break;
572 }
573 }
574 else if( compare_result == LIBCDATA_COMPARE_EQUAL )
575 {
576 break;
577 }
578 }
579 if( compare_result == LIBCDATA_COMPARE_EQUAL )
580 {
581 if( security_descriptor_index_value->data_size < (size64_t) ( sizeof( fsntfs_secure_index_value_t ) + 20 ) )
582 {
583 libcerror_error_set(
584 error,
585 LIBCERROR_ERROR_DOMAIN_RUNTIME,
586 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
587 "%s: unsupported security descriptor stream ($SDS) data size: %" PRIu64 "\n",
588 function,
589 security_descriptor_index_value->data_size );
590
591 return( -1 );
592 }
593 read_count = libfsntfs_data_stream_read_buffer_at_offset(
594 security_descriptor_index->data_stream,
595 secure_index_value_data,
596 sizeof( fsntfs_secure_index_value_t ),
597 (off64_t) security_descriptor_index_value->data_offset,
598 error );
599
600 if( read_count < 0 )
601 {
602 libcerror_error_set(
603 error,
604 LIBCERROR_ERROR_DOMAIN_IO,
605 LIBCERROR_IO_ERROR_READ_FAILED,
606 "%s: unable to read security descriptor stream ($SDS) data at offset: 0x%08" PRIx64 ".",
607 function,
608 security_descriptor_index_value->data_offset );
609
610 goto on_error;
611 }
612 if( libfsntfs_sds_index_value_initialize(
613 &sds_index_value,
614 error ) != 1 )
615 {
616 libcerror_error_set(
617 error,
618 LIBCERROR_ERROR_DOMAIN_RUNTIME,
619 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
620 "%s: unable to create $SDS index value.",
621 function );
622
623 goto on_error;
624 }
625 if( libfsntfs_sds_index_value_read_data(
626 sds_index_value,
627 secure_index_value_data,
628 sizeof( fsntfs_secure_index_value_t ),
629 error ) != 1 )
630 {
631 libcerror_error_set(
632 error,
633 LIBCERROR_ERROR_DOMAIN_IO,
634 LIBCERROR_IO_ERROR_READ_FAILED,
635 "%s: unable to read $SDS index value data.",
636 function );
637
638 goto on_error;
639 }
640 /* TODO check index values against secure_index_value */
641
642 if( libfsntfs_security_descriptor_values_initialize(
643 &safe_security_descriptor_values,
644 error ) != 1 )
645 {
646 libcerror_error_set(
647 error,
648 LIBCERROR_ERROR_DOMAIN_RUNTIME,
649 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
650 "%s: unable to create security descriptor values.",
651 function );
652
653 goto on_error;
654 }
655 security_descriptor_data_size = (size_t) ( security_descriptor_index_value->data_size - sizeof( fsntfs_secure_index_value_t ) );
656
657 if( ( security_descriptor_data_size == 0 )
658 || ( security_descriptor_data_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
659 {
660 libcerror_error_set(
661 error,
662 LIBCERROR_ERROR_DOMAIN_RUNTIME,
663 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
664 "%s: invalid security descriptor values data value out of bounds.",
665 function,
666 index_value_entry );
667
668 goto on_error;
669 }
670 safe_security_descriptor_values->data = memory_allocate(
671 sizeof( uint8_t ) * security_descriptor_data_size );
672
673 if( safe_security_descriptor_values->data == NULL )
674 {
675 libcerror_error_set(
676 error,
677 LIBCERROR_ERROR_DOMAIN_MEMORY,
678 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
679 "%s: unable to create security descriptor values data.",
680 function );
681
682 goto on_error;
683 }
684 safe_security_descriptor_values->data_size = security_descriptor_data_size;
685
686 if( memory_set(
687 safe_security_descriptor_values->data,
688 0,
689 sizeof( uint8_t ) * safe_security_descriptor_values->data_size ) == NULL )
690 {
691 libcerror_error_set(
692 error,
693 LIBCERROR_ERROR_DOMAIN_MEMORY,
694 LIBCERROR_MEMORY_ERROR_SET_FAILED,
695 "%s: unable to clear security descriptor data.",
696 function );
697
698 goto on_error;
699 }
700 read_count = libfsntfs_data_stream_read_buffer(
701 security_descriptor_index->data_stream,
702 safe_security_descriptor_values->data,
703 safe_security_descriptor_values->data_size,
704 error );
705
706 if( read_count < 0 )
707 {
708 libcerror_error_set(
709 error,
710 LIBCERROR_ERROR_DOMAIN_IO,
711 LIBCERROR_IO_ERROR_READ_FAILED,
712 "%s: unable to read security descriptor data at offset: 0x%08" PRIx64 ".",
713 function,
714 security_descriptor_index_value->data_offset );
715
716 goto on_error;
717 }
718 if( libfsntfs_security_descriptor_values_read_data(
719 safe_security_descriptor_values,
720 safe_security_descriptor_values->data,
721 safe_security_descriptor_values->data_size,
722 error ) != 1 )
723 {
724 libcerror_error_set(
725 error,
726 LIBCERROR_ERROR_DOMAIN_IO,
727 LIBCERROR_IO_ERROR_READ_FAILED,
728 "%s: unable to read security descriptor values.",
729 function );
730
731 goto on_error;
732 }
733 *security_descriptor_values = safe_security_descriptor_values;
734
735 result = 1;
736 }
737 else if( ( index_value->flags & LIBFSNTFS_INDEX_VALUE_FLAG_HAS_SUB_NODE ) != 0 )
738 {
739 index_entry_offset = (off64_t) ( index_value->sub_node_vcn * security_descriptor_index->sii_index->io_handle->cluster_block_size );
740
741 if( libfsntfs_index_get_sub_node(
742 security_descriptor_index->sii_index,
743 file_io_handle,
744 security_descriptor_index->sii_index->index_node_cache,
745 index_entry_offset,
746 (int) index_value->sub_node_vcn,
747 &sub_node,
748 error ) != 1 )
749 {
750 libcerror_error_set(
751 error,
752 LIBCERROR_ERROR_DOMAIN_RUNTIME,
753 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
754 "%s: unable to retrieve sub node with VCN: %d at offset: 0x%08" PRIx64 ".",
755 function,
756 (int) index_value->sub_node_vcn,
757 index_entry_offset );
758
759 goto on_error;
760 }
761 result = libfsntfs_security_descriptor_index_get_entry_from_index_node_by_identifier(
762 security_descriptor_index,
763 file_io_handle,
764 security_descriptor_index->sii_index->root_node,
765 security_descriptor_identifier,
766 security_descriptor_values,
767 recursion_depth + 1,
768 error );
769
770 if( result == -1 )
771 {
772 libcerror_error_set(
773 error,
774 LIBCERROR_ERROR_DOMAIN_IO,
775 LIBCERROR_IO_ERROR_READ_FAILED,
776 "%s: unable to retrieve security descriptor by identifier from index entry with VCN: %d at offset: 0x%08" PRIx64 ".",
777 function,
778 (int) index_value->sub_node_vcn,
779 index_entry_offset );
780
781 goto on_error;
782 }
783 }
784 return( result );
785
786 on_error:
787 if( safe_security_descriptor_values != NULL )
788 {
789 libfsntfs_security_descriptor_values_free(
790 &safe_security_descriptor_values,
791 NULL );
792 }
793 if( security_descriptor_index_value != NULL )
794 {
795 libfsntfs_security_descriptor_index_value_free(
796 &security_descriptor_index_value,
797 NULL );
798 }
799 return( -1 );
800 }
801
802 /* Retrieves the security descriptor for a specific identifier
803 * This function creates new security descriptor values
804 * Returns 1 if successful, 0 if not available or -1 on error
805 */
libfsntfs_security_descriptor_index_get_entry_by_identifier(libfsntfs_security_descriptor_index_t * security_descriptor_index,libbfio_handle_t * file_io_handle,uint32_t security_descriptor_identifier,libfsntfs_security_descriptor_values_t ** security_descriptor_values,libcerror_error_t ** error)806 int libfsntfs_security_descriptor_index_get_entry_by_identifier(
807 libfsntfs_security_descriptor_index_t *security_descriptor_index,
808 libbfio_handle_t *file_io_handle,
809 uint32_t security_descriptor_identifier,
810 libfsntfs_security_descriptor_values_t **security_descriptor_values,
811 libcerror_error_t **error )
812 {
813 static char *function = "libfsntfs_security_descriptor_index_get_entry_by_identifier";
814 int result = 0;
815
816 if( security_descriptor_index == NULL )
817 {
818 libcerror_error_set(
819 error,
820 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
821 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
822 "%s: invalid security descriptor index.",
823 function );
824
825 return( -1 );
826 }
827 result = libfsntfs_security_descriptor_index_get_entry_from_index_node_by_identifier(
828 security_descriptor_index,
829 file_io_handle,
830 security_descriptor_index->sii_index->root_node,
831 security_descriptor_identifier,
832 security_descriptor_values,
833 0,
834 error );
835
836 if( result == -1 )
837 {
838 libcerror_error_set(
839 error,
840 LIBCERROR_ERROR_DOMAIN_RUNTIME,
841 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
842 "%s: unable to retrieve security descriptor by identifier.",
843 function );
844
845 return( -1 );
846 }
847 return( result );
848 }
849
850