28
28
#include "string_utils.h"
29
29
#include "error_translation.h"
30
30
#include "secured_env_vars.h"
31
+ #include "io_utils.h"
31
32
32
33
#if defined (HAVE_NTIFS )
33
34
#include <ntifs.h>
@@ -523,11 +524,27 @@ static bool get_System_Volume(char *winSysVol, size_t winSysVolLen)
523
524
return validsystemvol ;
524
525
}
525
526
526
- static bool is_Folder_Secure (const char * securityDescriptorString , const char * dirptr )
527
+ FUNC_ATTR_PRINTF (2 , 3 ) static void set_dir_security_output_error_message (char * * outputError , const char * format , ...)
528
+ {
529
+ if (outputError != M_NULLPTR )
530
+ {
531
+ va_list args ;
532
+ va_start (args , format );
533
+ int result = vasprintf (outputError , format , args );
534
+ va_end (args );
535
+ if (result < 0 && * outputError != M_NULLPTR )
536
+ {
537
+ safe_free (outputError );
538
+ }
539
+ }
540
+ }
541
+
542
+ static bool is_Folder_Secure (const char * securityDescriptorString , const char * dirptr , char * * outputError )
527
543
{
528
544
bool secure = true;
529
545
if (securityDescriptorString == M_NULLPTR || dirptr == M_NULLPTR )
530
546
{
547
+ set_dir_security_output_error_message (outputError , "Invalid security descriptor string or directory given.\n" );
531
548
return false;
532
549
}
533
550
DECLARE_ZERO_INIT_ARRAY (char , windowsSystemVolume , MAX_PATH );
@@ -549,36 +566,42 @@ static bool is_Folder_Secure(const char* securityDescriptorString, const char* d
549
566
if (FALSE == ConvertStringSidToSidA (mySidStr , & mySid ))
550
567
{
551
568
/* Handle Error */
569
+ set_dir_security_output_error_message (outputError , "Failed to convert current user's SID string to sid structure\n" );
552
570
secure = false;
553
571
break ;
554
572
}
555
573
if (FALSE == IsValidSid (mySid ))
556
574
{
557
575
/* Handle Error */
576
+ set_dir_security_output_error_message (outputError , "Invalid sid\n" );
558
577
secure = false;
559
578
break ;
560
579
}
561
580
if (FALSE == ConvertStringSecurityDescriptorToSecurityDescriptorA (securityDescriptorString , SDDL_REVISION , & secdesc , & secdesclen ))
562
581
{
563
582
/* Handle Error */
583
+ set_dir_security_output_error_message (outputError , "Failed to convert security descriptor string to security descriptor structure\n" );
564
584
secure = false;
565
585
break ;
566
586
}
567
587
if (FALSE == IsValidSecurityDescriptor (secdesc ))
568
588
{
569
589
/* Handle Error */
590
+ set_dir_security_output_error_message (outputError , "Invalid security descriptor\n" );
570
591
secure = false;
571
592
break ;
572
593
}
573
594
if (FALSE == GetSecurityDescriptorOwner (secdesc , & userSid , & defaultOwner ))
574
595
{
575
596
/* Handle Error */
597
+ set_dir_security_output_error_message (outputError , "Failed to get security descriptor owner\n" );
576
598
secure = false;
577
599
break ;
578
600
}
579
601
if (FALSE == IsValidSid (userSid ))
580
602
{
581
603
/* Handle Error */
604
+ set_dir_security_output_error_message (outputError , "Invalid SID for security descriptor owner\n" );
582
605
secure = false;
583
606
break ;
584
607
}
@@ -621,13 +644,13 @@ static bool is_Folder_Secure(const char* securityDescriptorString, const char* d
621
644
{
622
645
/* Directory is owned by someone besides user/system/administrator */
623
646
secure = false;
624
- #if defined (_DEBUG )
625
647
char * sidString = M_NULLPTR ;
626
648
if (ConvertSidToStringSidA (userSid , & sidString ))
627
649
{
628
- printf ("Untrusted Owner SID: %s\n" , sidString );
650
+ set_dir_security_output_error_message (outputError , "Directory (%s) owned by SID (not trusted): %s\n" , dirptr , sidString );
651
+ LocalFree (sidString );
652
+ sidString = M_NULLPTR ;
629
653
}
630
- #endif //_DEBUG
631
654
break ;
632
655
}
633
656
}
@@ -636,27 +659,27 @@ static bool is_Folder_Secure(const char* securityDescriptorString, const char* d
636
659
{
637
660
/* Directory is owned by someone besides user/system/administrator */
638
661
secure = false;
639
- #if defined (_DEBUG )
640
662
char * sidString = M_NULLPTR ;
641
663
if (ConvertSidToStringSidA (userSid , & sidString ))
642
664
{
643
- printf ("Untrusted Owner SID: %s\n" , sidString );
665
+ set_dir_security_output_error_message (outputError , "Directory (%s) owned by SID (not trusted): %s\n" , dirptr , sidString );
666
+ LocalFree (sidString );
667
+ sidString = M_NULLPTR ;
644
668
}
645
- #endif //_DEBUG
646
669
break ;
647
670
}
648
671
}
649
672
else
650
673
{
651
674
/* Directory is owned by someone besides user/system/administrator */
652
675
secure = false;
653
- #if defined (_DEBUG )
654
676
char * sidString = M_NULLPTR ;
655
677
if (ConvertSidToStringSidA (userSid , & sidString ))
656
678
{
657
- printf ("Untrusted Owner SID: %s\n" , sidString );
679
+ set_dir_security_output_error_message (outputError , "Directory (%s) owned by SID (not trusted): %s\n" , dirptr , sidString );
680
+ LocalFree (sidString );
681
+ sidString = M_NULLPTR ;
658
682
}
659
- #endif //_DEBUG
660
683
break ;
661
684
}
662
685
}
@@ -686,20 +709,23 @@ static bool is_Folder_Secure(const char* securityDescriptorString, const char* d
686
709
{
687
710
/* Handle Error */
688
711
secure = false;
712
+ set_dir_security_output_error_message (outputError , "Unable to retrieve DACL from security descriptor: %s\n" , dirptr );
689
713
break ;
690
714
}
691
715
692
716
if (FALSE == daclPresent || dacl == M_NULLPTR )
693
717
{
694
718
/* Missing DACL, so cannot verify permissions */
695
719
secure = false;
720
+ set_dir_security_output_error_message (outputError , "DACL Missing. Cannot verify permissions: %s\n" , dirptr );
696
721
break ;
697
722
}
698
723
699
724
if (FALSE == IsValidAcl (dacl ))
700
725
{
701
726
/* Handle Error */
702
727
secure = false;
728
+ set_dir_security_output_error_message (outputError , "Invalid DACL received. Cannot verify permissions: %s\n" , dirptr );
703
729
break ;
704
730
}
705
731
@@ -728,14 +754,14 @@ static bool is_Folder_Secure(const char* securityDescriptorString, const char* d
728
754
729
755
if (!(allowEveryoneGroup && everyoneGroupSID != M_NULLPTR && EqualSid (aceSID , everyoneGroupSID )))
730
756
{
731
- secure = false;
732
- #if defined (_DEBUG )
733
757
char * sidString = M_NULLPTR ;
758
+ secure = false;
734
759
if (ConvertSidToStringSidA (aceSID , & sidString ))
735
760
{
736
- printf ("Untrusted SID: %s\n" , sidString );
761
+ set_dir_security_output_error_message (outputError , "Directory (%s) can be accessed by SID (not trusted, must be removed to be secure): %s\n" , dirptr , sidString );
762
+ LocalFree (sidString );
763
+ sidString = M_NULLPTR ;
737
764
}
738
- #endif //_DEBUG
739
765
}
740
766
#if defined (_DEBUG )
741
767
else
@@ -744,6 +770,8 @@ static bool is_Folder_Secure(const char* securityDescriptorString, const char* d
744
770
if (ConvertSidToStringSidA (aceSID , & sidString ))
745
771
{
746
772
printf ("Trusted SID: %s\n" , sidString );
773
+ LocalFree (sidString );
774
+ sidString = M_NULLPTR ;
747
775
}
748
776
}
749
777
#endif //_DEBUG
@@ -761,6 +789,7 @@ static bool is_Folder_Secure(const char* securityDescriptorString, const char* d
761
789
}
762
790
else
763
791
{
792
+ set_dir_security_output_error_message (outputError , "Invalid ACE in DACL. Directory (%s) cannot be trusted\n" , dirptr );
764
793
secure = false;
765
794
}
766
795
}
@@ -946,6 +975,7 @@ static bool internal_OS_Is_Directory_Secure(const char* fullpath, unsigned int n
946
975
{
947
976
/* handle error */
948
977
secure = false;
978
+ set_dir_security_output_error_message (outputError , "Unable to read directory attributes: %s\n" , dirptr );
949
979
if (appendedTrailingSlash )
950
980
{
951
981
safe_free (& dirptr );
@@ -956,6 +986,7 @@ static bool internal_OS_Is_Directory_Secure(const char* fullpath, unsigned int n
956
986
{
957
987
/* handle error */
958
988
secure = false;
989
+ set_dir_security_output_error_message (outputError , "Too many symlinks in path (>%d): %s\n" , MAX_SYMLINKS_IN_PATH , dirptr );
959
990
free_File_Attributes (& attrs );
960
991
if (appendedTrailingSlash )
961
992
{
@@ -1005,22 +1036,26 @@ static bool internal_OS_Is_Directory_Secure(const char* fullpath, unsigned int n
1005
1036
}
1006
1037
else
1007
1038
{
1039
+ set_dir_security_output_error_message (outputError , "Unable to allocate memory to check reparse point in path: %s\n" , dirptr );
1008
1040
secure = false;
1009
1041
}
1010
1042
}
1011
1043
else
1012
1044
{
1045
+ set_dir_security_output_error_message (outputError , "Unable to calculate memory length to check reparse point in path: %s\n" , dirptr );
1013
1046
secure = false;
1014
1047
}
1015
1048
}
1016
1049
else
1017
1050
{
1051
+ set_dir_security_output_error_message (outputError , "Unable to issue FSCTL_GET_REPASE_POINT to validate reparse point in path: %s\n" , dirptr );
1018
1052
secure = false;
1019
1053
}
1020
1054
safe_free_reparse_data_buf (& reparseData );
1021
1055
}
1022
1056
else
1023
1057
{
1058
+ set_dir_security_output_error_message (outputError , "Unable to allocate memory to check reparse point in path: %s\n" , dirptr );
1024
1059
secure = false;
1025
1060
}
1026
1061
CloseHandle (link );
@@ -1039,6 +1074,7 @@ static bool internal_OS_Is_Directory_Secure(const char* fullpath, unsigned int n
1039
1074
}
1040
1075
else
1041
1076
{
1077
+ set_dir_security_output_error_message (outputError , "Unable to open handle to reparse point in path: %s\n" , dirptr );
1042
1078
secure = false;
1043
1079
free_File_Attributes (& attrs );
1044
1080
if (appendedTrailingSlash )
@@ -1053,6 +1089,7 @@ static bool internal_OS_Is_Directory_Secure(const char* fullpath, unsigned int n
1053
1089
{
1054
1090
/* Not a directory */
1055
1091
secure = false;
1092
+ set_dir_security_output_error_message (outputError , "%s is not a directory. Cannot validate as part of path.\n" , dirptr );
1056
1093
free_File_Attributes (& attrs );
1057
1094
if (appendedTrailingSlash )
1058
1095
{
@@ -1061,7 +1098,7 @@ static bool internal_OS_Is_Directory_Secure(const char* fullpath, unsigned int n
1061
1098
break ;
1062
1099
}
1063
1100
1064
- secure = is_Folder_Secure (attrs -> winSecurityDescriptor , dirptr );
1101
+ secure = is_Folder_Secure (attrs -> winSecurityDescriptor , dirptr , outputError );
1065
1102
if (appendedTrailingSlash )
1066
1103
{
1067
1104
safe_free (& dirptr );
0 commit comments