1 /*
2  * Windows NT Access Control Entry (ACE) functions
3  *
4  * Copyright (C) 2009-2020, 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 <narrow_string.h>
26 #include <system_string.h>
27 #include <types.h>
28 #include <wide_string.h>
29 
30 #include "libfwnt_access_control_entry.h"
31 #include "libfwnt_debug.h"
32 #include "libfwnt_definitions.h"
33 #include "libfwnt_libcerror.h"
34 #include "libfwnt_libcnotify.h"
35 #include "libfwnt_security_identifier.h"
36 #include "libfwnt_types.h"
37 
38 /* Creates an access control entry
39  * Make sure the value access_control_entry is referencing, is set to NULL
40  * Returns 1 if successful or -1 on error
41  */
libfwnt_access_control_entry_initialize(libfwnt_access_control_entry_t ** access_control_entry,libcerror_error_t ** error)42 int libfwnt_access_control_entry_initialize(
43      libfwnt_access_control_entry_t **access_control_entry,
44      libcerror_error_t **error )
45 {
46 	libfwnt_internal_access_control_entry_t *internal_access_control_entry = NULL;
47 	static char *function                                                  = "libfwnt_access_control_entry_initialize";
48 
49 	if( access_control_entry == NULL )
50 	{
51 		libcerror_error_set(
52 		 error,
53 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
54 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
55 		 "%s: invalid access control entry.",
56 		 function );
57 
58 		return( -1 );
59 	}
60 	if( *access_control_entry != NULL )
61 	{
62 		libcerror_error_set(
63 		 error,
64 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
65 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
66 		 "%s: invalid access control entry value already set.",
67 		 function );
68 
69 		return( -1 );
70 	}
71 	internal_access_control_entry = memory_allocate_structure(
72 	                                 libfwnt_internal_access_control_entry_t );
73 
74 	if( internal_access_control_entry == NULL )
75 	{
76 		libcerror_error_set(
77 		 error,
78 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
79 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
80 		 "%s: unable to create access control entry.",
81 		 function );
82 
83 		goto on_error;
84 	}
85 	if( memory_set(
86 	     internal_access_control_entry,
87 	     0,
88 	     sizeof( libfwnt_internal_access_control_entry_t ) ) == NULL )
89 	{
90 		libcerror_error_set(
91 		 error,
92 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
93 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
94 		 "%s: unable to clear access control entry.",
95 		 function );
96 
97 		goto on_error;
98 	}
99 	*access_control_entry = (libfwnt_access_control_entry_t *) internal_access_control_entry;
100 
101 	return( 1 );
102 
103 on_error:
104 	if( internal_access_control_entry != NULL )
105 	{
106 		memory_free(
107 		 internal_access_control_entry );
108 	}
109 	return( -1 );
110 }
111 
112 /* Frees an access control entry
113  * Returns 1 if successful or -1 on error
114  */
libfwnt_access_control_entry_free(libfwnt_access_control_entry_t ** access_control_entry,libcerror_error_t ** error)115 int libfwnt_access_control_entry_free(
116      libfwnt_access_control_entry_t **access_control_entry,
117      libcerror_error_t **error )
118 {
119 	static char *function = "libfwnt_access_control_entry_free";
120 
121 	if( access_control_entry == NULL )
122 	{
123 		libcerror_error_set(
124 		 error,
125 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
126 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
127 		 "%s: invalid access control entry.",
128 		 function );
129 
130 		return( -1 );
131 	}
132 	if( *access_control_entry != NULL )
133 	{
134 		*access_control_entry = NULL;
135 	}
136 	return( 1 );
137 }
138 
139 /* Frees an access control entry
140  * Returns 1 if successful or -1 on error
141  */
libfwnt_internal_access_control_entry_free(libfwnt_internal_access_control_entry_t ** internal_access_control_entry,libcerror_error_t ** error)142 int libfwnt_internal_access_control_entry_free(
143      libfwnt_internal_access_control_entry_t **internal_access_control_entry,
144      libcerror_error_t **error )
145 {
146 	static char *function = "libfwnt_internal_access_control_entry_free";
147 	int result            = 1;
148 
149 	if( internal_access_control_entry == NULL )
150 	{
151 		libcerror_error_set(
152 		 error,
153 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
154 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
155 		 "%s: invalid access control entry.",
156 		 function );
157 
158 		return( -1 );
159 	}
160 	if( *internal_access_control_entry != NULL )
161 	{
162 		if( ( *internal_access_control_entry )->security_identifier != NULL )
163 		{
164 			if( libfwnt_internal_security_identifier_free(
165 			     (libfwnt_internal_security_identifier_t **) &( ( *internal_access_control_entry )->security_identifier ),
166 			     error ) != 1 )
167 			{
168 				libcerror_error_set(
169 				 error,
170 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
171 				 LIBCERROR_RUNTIME_ERROR_FINALIZE_FAILED,
172 				 "%s: unable to free security identifier.",
173 				 function );
174 
175 				result = -1;
176 			}
177 		}
178 		memory_free(
179 		 *internal_access_control_entry );
180 
181 		*internal_access_control_entry = NULL;
182 	}
183 	return( result );
184 }
185 
186 /* Converts an access control entry stored in a byte stream into a runtime version
187  * Returns 1 if successful or -1 on error
188  */
libfwnt_access_control_entry_copy_from_byte_stream(libfwnt_access_control_entry_t * access_control_entry,const uint8_t * byte_stream,size_t byte_stream_size,int byte_order,libcerror_error_t ** error)189 int libfwnt_access_control_entry_copy_from_byte_stream(
190      libfwnt_access_control_entry_t *access_control_entry,
191      const uint8_t *byte_stream,
192      size_t byte_stream_size,
193      int byte_order,
194      libcerror_error_t **error )
195 {
196 	libfwnt_internal_access_control_entry_t *internal_access_control_entry = NULL;
197 	static char *function                                                  = "libfwnt_access_control_entry_copy_from_byte_stream";
198 	size_t access_mask_offset                                              = 0;
199 	size_t sid_offset                                                      = 0;
200 
201 #if defined( HAVE_DEBUG_OUTPUT )
202 	system_character_t *sid_string                                         = NULL;
203 	size_t sid_string_size                                                 = 0;
204 	int result                                                             = 0;
205 #endif
206 
207 	if( access_control_entry == NULL )
208 	{
209 		libcerror_error_set(
210 		 error,
211 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
212 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
213 		 "%s: invalid access control entry.",
214 		 function );
215 
216 		return( -1 );
217 	}
218 	internal_access_control_entry = (libfwnt_internal_access_control_entry_t *) access_control_entry;
219 
220 	if( byte_stream == NULL )
221 	{
222 		libcerror_error_set(
223 		 error,
224 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
225 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
226 		 "%s: invalid byte stream.",
227 		 function );
228 
229 		return( -1 );
230 	}
231 	if( byte_stream_size < 4 )
232 	{
233 		libcerror_error_set(
234 		 error,
235 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
236 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
237 		 "%s: byte stream too small.",
238 		 function );
239 
240 		return( -1 );
241 	}
242 	if( byte_stream_size > (size_t) SSIZE_MAX )
243 	{
244 		libcerror_error_set(
245 		 error,
246 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
247 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
248 		 "%s: byte stream size exceeds maximum.",
249 		 function );
250 
251 		return( -1 );
252 	}
253 	if( byte_order != LIBFWNT_ENDIAN_LITTLE )
254 	{
255 		libcerror_error_set(
256 		 error,
257 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
258 		 LIBCERROR_ARGUMENT_ERROR_UNSUPPORTED_VALUE,
259 		 "%s: unsupported byte order.",
260 		 function );
261 
262 		return( -1 );
263 	}
264 #if defined( HAVE_DEBUG_OUTPUT )
265 	if( libcnotify_verbose != 0 )
266 	{
267 		libcnotify_printf(
268 		 "%s: header data:\n",
269 		 function );
270 		libcnotify_print_data(
271 		 byte_stream,
272 		 4,
273 		 0 );
274 	}
275 #endif
276 	internal_access_control_entry->type  = byte_stream[ 0 ];
277 	internal_access_control_entry->flags = byte_stream[ 1 ];
278 
279 	byte_stream_copy_to_uint16_little_endian(
280 	 &( byte_stream[ 2 ] ),
281 	 internal_access_control_entry->size );
282 
283 #if defined( HAVE_DEBUG_OUTPUT )
284 	if( libcnotify_verbose != 0 )
285 	{
286 		libcnotify_printf(
287 		 "%s: type\t\t: %" PRIu8 " (%s)\n",
288 		 function,
289 		 internal_access_control_entry->type,
290 		 libfwnt_debug_print_access_control_entry_type(
291 		  internal_access_control_entry->type ) );
292 
293 		libcnotify_printf(
294 		 "%s: flags\t\t: 0x%02" PRIx8 "\n",
295 		 function,
296 		 internal_access_control_entry->flags );
297 		libfwnt_debug_print_access_control_entry_flags(
298 		 internal_access_control_entry->flags );
299 		libcnotify_printf(
300 		 "\n" );
301 
302 		libcnotify_printf(
303 		 "%s: size\t\t: %" PRIu16 "\n",
304 		 function,
305 		 internal_access_control_entry->size );
306 
307 		libcnotify_printf(
308 		 "\n" );
309 	}
310 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
311 
312 	if( ( internal_access_control_entry->size < 4 )
313 	 || ( (size_t) internal_access_control_entry->size > byte_stream_size ) )
314 
315 	{
316 		libcerror_error_set(
317 		 error,
318 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
319 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
320 		 "%s: access control entry size value out of bounds.",
321 		 function );
322 
323 		goto on_error;
324 	}
325 #if defined( HAVE_DEBUG_OUTPUT )
326 	if( libcnotify_verbose != 0 )
327 	{
328 		libcnotify_printf(
329 		 "%s: access control entry data:\n",
330 		 function );
331 		libcnotify_print_data(
332 		 &( byte_stream[ 4 ] ),
333 		 internal_access_control_entry->size - 4,
334 		 0 );
335 	}
336 #endif
337 	switch( internal_access_control_entry->type )
338 	{
339 		/* Basic types */
340 		case LIBFWNT_ACCESS_ALLOWED:
341 		case LIBFWNT_ACCESS_DENIED:
342 		case LIBFWNT_SYSTEM_AUDIT:
343 		case LIBFWNT_SYSTEM_ALARM:
344 		case LIBFWNT_ACCESS_ALLOWED_CALLBACK:
345 		case LIBFWNT_ACCESS_DENIED_CALLBACK:
346 		case LIBFWNT_SYSTEM_AUDIT_CALLBACK:
347 		case LIBFWNT_SYSTEM_ALARM_CALLBACK:
348 		case LIBFWNT_SYSTEM_MANDATORY_LABEL:
349 			access_mask_offset = 4;
350 			sid_offset         = 8;
351 			break;
352 
353 		/* Object types */
354 		case LIBFWNT_ACCESS_ALLOWED_OBJECT:
355 		case LIBFWNT_ACCESS_DENIED_OBJECT:
356 		case LIBFWNT_SYSTEM_AUDIT_OBJECT:
357 		case LIBFWNT_SYSTEM_ALARM_OBJECT:
358 		case LIBFWNT_ACCESS_ALLOWED_CALLBACK_OBJECT:
359 		case LIBFWNT_ACCESS_DENIED_CALLBACK_OBJECT:
360 		case LIBFWNT_SYSTEM_AUDIT_CALLBACK_OBJECT:
361 		case LIBFWNT_SYSTEM_ALARM_CALLBACK_OBJECT:
362 			access_mask_offset = 4;
363 			sid_offset         = 40;
364 			break;
365 
366 		/* Unknown types */
367 		case LIBFWNT_ACCESS_ALLOWED_COMPOUND:
368 		default:
369 			break;
370 	}
371 	if( access_mask_offset > 0 )
372 	{
373 		if( access_mask_offset > (size_t) ( internal_access_control_entry->size - 4 ) )
374 
375 		{
376 			libcerror_error_set(
377 			 error,
378 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
379 			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
380 			 "%s: access control mask offset value out of bounds.",
381 			 function );
382 
383 			goto on_error;
384 		}
385 		byte_stream_copy_to_uint32_little_endian(
386 		 &( byte_stream[ access_mask_offset ] ),
387 		 internal_access_control_entry->access_mask );
388 
389 #if defined( HAVE_DEBUG_OUTPUT )
390 		if( libcnotify_verbose != 0 )
391 		{
392 			libcnotify_printf(
393 			 "%s: access mask\t\t: 0x%08" PRIx32 "\n",
394 			 function,
395 			 internal_access_control_entry->access_mask );
396 			libfwnt_debug_print_access_control_entry_access_mask(
397 			 internal_access_control_entry->access_mask );
398 			libcnotify_printf(
399 			 "\n" );
400 		}
401 #endif
402 	}
403 	if( sid_offset > 0 )
404 	{
405 		if( sid_offset > internal_access_control_entry->size )
406 		{
407 			libcerror_error_set(
408 			 error,
409 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
410 			 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
411 			 "%s: security identifier offset value out of bounds.",
412 			 function );
413 
414 			goto on_error;
415 		}
416 		if( libfwnt_security_identifier_initialize(
417 		     &( internal_access_control_entry->security_identifier ),
418 		     error ) != 1 )
419 		{
420 			libcerror_error_set(
421 			 error,
422 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
423 			 LIBCERROR_RUNTIME_ERROR_INITIALIZE_FAILED,
424 			 "%s: unable to create security identifier.",
425 			 function );
426 
427 			goto on_error;
428 		}
429 		if( internal_access_control_entry->security_identifier == NULL )
430 		{
431 			libcerror_error_set(
432 			 error,
433 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
434 			 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
435 			 "%s: invalid access control entry - missing owner security identifier.",
436 			 function );
437 
438 			goto on_error;
439 		}
440 		( (libfwnt_internal_security_identifier_t *) internal_access_control_entry->security_identifier )->is_managed = 1;
441 
442 		if( libfwnt_security_identifier_copy_from_byte_stream(
443 		     internal_access_control_entry->security_identifier,
444 		     &( byte_stream[ sid_offset ] ),
445 		     byte_stream_size - sid_offset,
446 		     byte_order,
447 		     error ) != 1 )
448 		{
449 			libcerror_error_set(
450 			 error,
451 			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
452 			 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
453 			 "%s: unable to copy security identifier from byte stream.",
454 			 function );
455 
456 			goto on_error;
457 		}
458 #if defined( HAVE_DEBUG_OUTPUT )
459 		if( libcnotify_verbose != 0 )
460 		{
461 			if( libfwnt_security_identifier_get_string_size(
462 			     internal_access_control_entry->security_identifier,
463 			     &sid_string_size,
464 			     0,
465 			     error ) != 1 )
466 			{
467 				libcerror_error_set(
468 				 error,
469 				 LIBCERROR_ERROR_DOMAIN_RUNTIME,
470 				 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
471 				 "%s: unable to retrieve security identifier string size.",
472 				 function );
473 
474 				goto on_error;
475 			}
476 			libcnotify_printf(
477 			 "%s: SID\t\t\t: ",
478 			 function );
479 
480 			if( sid_string_size > 0 )
481 			{
482 				sid_string = system_string_allocate(
483 					      sid_string_size );
484 
485 				if( sid_string == NULL )
486 				{
487 					libcerror_error_set(
488 					 error,
489 					 LIBCERROR_ERROR_DOMAIN_MEMORY,
490 					 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
491 					 "%s: unable to create security identifier string.",
492 					 function );
493 
494 					goto on_error;
495 				}
496 #if defined( HAVE_WIDE_SYSTEM_CHARACTER )
497 				result = libfwnt_security_identifier_copy_to_utf16_string(
498 					  internal_access_control_entry->security_identifier,
499 					  (uint16_t *) sid_string,
500 					  sid_string_size,
501 					  0,
502 					  error );
503 #else
504 				result = libfwnt_security_identifier_copy_to_utf8_string(
505 					  internal_access_control_entry->security_identifier,
506 					  (uint8_t *) sid_string,
507 					  sid_string_size,
508 					  0,
509 					  error );
510 #endif
511 				if( result != 1 )
512 				{
513 					libcerror_error_set(
514 					 error,
515 					 LIBCERROR_ERROR_DOMAIN_RUNTIME,
516 					 LIBCERROR_RUNTIME_ERROR_COPY_FAILED,
517 					 "%s: unable to copy security identifier to string.",
518 					 function );
519 
520 					goto on_error;
521 				}
522 				libcnotify_printf(
523 				 "%" PRIs_SYSTEM "",
524 				 sid_string );
525 
526 				memory_free(
527 				 sid_string );
528 
529 				sid_string = NULL;
530 			}
531 			libcnotify_printf(
532 			 "\n" );
533 		}
534 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
535 	}
536 #if defined( HAVE_DEBUG_OUTPUT )
537 	if( libcnotify_verbose != 0 )
538 	{
539 		libcnotify_printf(
540 		 "\n" );
541 	}
542 #endif
543 	return( 1 );
544 
545 on_error:
546 #if defined( HAVE_DEBUG_OUTPUT )
547 	if( sid_string != NULL )
548 	{
549 		memory_free(
550 		 sid_string );
551 	}
552 #endif
553 	if( internal_access_control_entry->security_identifier != NULL )
554 	{
555 		libfwnt_internal_security_identifier_free(
556 		 (libfwnt_internal_security_identifier_t **) &( internal_access_control_entry->security_identifier ),
557 		 NULL );
558 	}
559 	return( -1 );
560 }
561 
562 /* Retrieves the type
563  * Returns 1 if successful or -1 on error
564  */
libfwnt_access_control_entry_get_type(libfwnt_access_control_entry_t * access_control_entry,uint8_t * type,libcerror_error_t ** error)565 int libfwnt_access_control_entry_get_type(
566      libfwnt_access_control_entry_t *access_control_entry,
567      uint8_t *type,
568      libcerror_error_t **error )
569 {
570 	libfwnt_internal_access_control_entry_t *internal_access_control_entry = NULL;
571 	static char *function                                                  = "libfwnt_access_control_entry_get_type";
572 
573 	if( access_control_entry == NULL )
574 	{
575 		libcerror_error_set(
576 		 error,
577 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
578 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
579 		 "%s: invalid access control entry.",
580 		 function );
581 
582 		return( -1 );
583 	}
584 	internal_access_control_entry = (libfwnt_internal_access_control_entry_t *) access_control_entry;
585 
586 	if( type == NULL )
587 	{
588 		libcerror_error_set(
589 		 error,
590 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
591 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
592 		 "%s: invalid type.",
593 		 function );
594 
595 		return( -1 );
596 	}
597 	*type = internal_access_control_entry->type;
598 
599 	return( 1 );
600 }
601 
602 /* Retrieves the flags
603  * Returns 1 if successful or -1 on error
604  */
libfwnt_access_control_entry_get_flags(libfwnt_access_control_entry_t * access_control_entry,uint8_t * flags,libcerror_error_t ** error)605 int libfwnt_access_control_entry_get_flags(
606      libfwnt_access_control_entry_t *access_control_entry,
607      uint8_t *flags,
608      libcerror_error_t **error )
609 {
610 	libfwnt_internal_access_control_entry_t *internal_access_control_entry = NULL;
611 	static char *function                                                  = "libfwnt_access_control_entry_get_flags";
612 
613 	if( access_control_entry == NULL )
614 	{
615 		libcerror_error_set(
616 		 error,
617 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
618 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
619 		 "%s: invalid access control entry.",
620 		 function );
621 
622 		return( -1 );
623 	}
624 	internal_access_control_entry = (libfwnt_internal_access_control_entry_t *) access_control_entry;
625 
626 	if( flags == NULL )
627 	{
628 		libcerror_error_set(
629 		 error,
630 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
631 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
632 		 "%s: invalid flags.",
633 		 function );
634 
635 		return( -1 );
636 	}
637 	*flags = internal_access_control_entry->flags;
638 
639 	return( 1 );
640 }
641 
642 /* Retrieves the access mask
643  * Returns 1 if successful, 0 if not available or -1 on error
644  */
libfwnt_access_control_entry_get_access_mask(libfwnt_access_control_entry_t * access_control_entry,uint32_t * access_mask,libcerror_error_t ** error)645 int libfwnt_access_control_entry_get_access_mask(
646      libfwnt_access_control_entry_t *access_control_entry,
647      uint32_t *access_mask,
648      libcerror_error_t **error )
649 {
650 	libfwnt_internal_access_control_entry_t *internal_access_control_entry = NULL;
651 	static char *function                                                  = "libfwnt_access_control_entry_get_access_mask";
652 
653 	if( access_control_entry == NULL )
654 	{
655 		libcerror_error_set(
656 		 error,
657 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
658 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
659 		 "%s: invalid access control entry.",
660 		 function );
661 
662 		return( -1 );
663 	}
664 	internal_access_control_entry = (libfwnt_internal_access_control_entry_t *) access_control_entry;
665 
666 	if( access_mask == NULL )
667 	{
668 		libcerror_error_set(
669 		 error,
670 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
671 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
672 		 "%s: invalid access mask.",
673 		 function );
674 
675 		return( -1 );
676 	}
677 	switch( internal_access_control_entry->type )
678 	{
679 		/* Basic types */
680 		case LIBFWNT_ACCESS_ALLOWED:
681 		case LIBFWNT_ACCESS_DENIED:
682 		case LIBFWNT_SYSTEM_AUDIT:
683 		case LIBFWNT_SYSTEM_ALARM:
684 		case LIBFWNT_ACCESS_ALLOWED_CALLBACK:
685 		case LIBFWNT_ACCESS_DENIED_CALLBACK:
686 		case LIBFWNT_SYSTEM_AUDIT_CALLBACK:
687 		case LIBFWNT_SYSTEM_ALARM_CALLBACK:
688 		case LIBFWNT_SYSTEM_MANDATORY_LABEL:
689 		/* Object types */
690 		case LIBFWNT_ACCESS_ALLOWED_OBJECT:
691 		case LIBFWNT_ACCESS_DENIED_OBJECT:
692 		case LIBFWNT_SYSTEM_AUDIT_OBJECT:
693 		case LIBFWNT_SYSTEM_ALARM_OBJECT:
694 		case LIBFWNT_ACCESS_ALLOWED_CALLBACK_OBJECT:
695 		case LIBFWNT_ACCESS_DENIED_CALLBACK_OBJECT:
696 		case LIBFWNT_SYSTEM_AUDIT_CALLBACK_OBJECT:
697 		case LIBFWNT_SYSTEM_ALARM_CALLBACK_OBJECT:
698 			break;
699 
700 		/* Unknown types */
701 		case LIBFWNT_ACCESS_ALLOWED_COMPOUND:
702 		default:
703 			return( 0 );
704 	}
705 	*access_mask = internal_access_control_entry->access_mask;
706 
707 	return( 1 );
708 }
709 
710 /* Retrieves the security identifier
711  * Returns 1 if successful, 0 if not available or -1 on error
712  */
libfwnt_access_control_entry_get_security_identifier(libfwnt_access_control_entry_t * access_control_entry,libfwnt_security_identifier_t ** security_identifier,libcerror_error_t ** error)713 int libfwnt_access_control_entry_get_security_identifier(
714      libfwnt_access_control_entry_t *access_control_entry,
715      libfwnt_security_identifier_t **security_identifier,
716      libcerror_error_t **error )
717 {
718 	libfwnt_internal_access_control_entry_t *internal_access_control_entry = NULL;
719 	static char *function                                                  = "libfwnt_access_control_entry_get_security_identifier";
720 
721 	if( access_control_entry == NULL )
722 	{
723 		libcerror_error_set(
724 		 error,
725 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
726 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
727 		 "%s: invalid access control entry.",
728 		 function );
729 
730 		return( -1 );
731 	}
732 	internal_access_control_entry = (libfwnt_internal_access_control_entry_t *) access_control_entry;
733 
734 	if( security_identifier == NULL )
735 	{
736 		libcerror_error_set(
737 		 error,
738 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
739 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
740 		 "%s: invalid security identifier.",
741 		 function );
742 
743 		return( -1 );
744 	}
745 	if( *security_identifier != NULL )
746 	{
747 		libcerror_error_set(
748 		 error,
749 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
750 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
751 		 "%s: invalid security identifier value already set.",
752 		 function );
753 
754 		return( -1 );
755 	}
756 	if( internal_access_control_entry->security_identifier == NULL )
757 	{
758 		return( 0 );
759 	}
760 	*security_identifier = internal_access_control_entry->security_identifier;
761 
762 	return( 1 );
763 }
764 
765