...

Source file src/github.com/Microsoft/go-winio/pkg/security/grantvmgroupaccess_test.go

Documentation: github.com/Microsoft/go-winio/pkg/security

     1  //go:build windows
     2  // +build windows
     3  
     4  package security
     5  
     6  import (
     7  	"os"
     8  	"path/filepath"
     9  	"regexp"
    10  	"strings"
    11  	"testing"
    12  
    13  	exec "golang.org/x/sys/execabs"
    14  )
    15  
    16  const (
    17  	vmAccountName = `NT VIRTUAL MACHINE\\Virtual Machines`
    18  	vmAccountSID  = "S-1-5-83-0"
    19  )
    20  
    21  // TestGrantVmGroupAccess verifies for the three case of a file, a directory,
    22  // and a file in a directory that the appropriate ACEs are set, including
    23  // inheritance in the second two examples. These are the expected ACES. Is
    24  // verified by running icacls and comparing output.
    25  //
    26  // File:
    27  // S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(R,W)
    28  // S-1-5-83-1-3166535780-1122986932-343720105-43916321:(R,W)
    29  //
    30  // Directory:
    31  // S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(OI)(CI)(R,W)
    32  // S-1-5-83-1-3166535780-1122986932-343720105-43916321:(OI)(CI)(R,W)
    33  //
    34  // File in directory (inherited):
    35  // S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(I)(R,W)
    36  // S-1-5-83-1-3166535780-1122986932-343720105-43916321:(I)(R,W)
    37  
    38  func TestGrantVmGroupAccess(t *testing.T) {
    39  	f, err := os.CreateTemp("", "gvmgafile")
    40  	if err != nil {
    41  		t.Fatal(err)
    42  	}
    43  	defer func() {
    44  		f.Close()
    45  		os.Remove(f.Name())
    46  	}()
    47  
    48  	d := t.TempDir()
    49  	find, err := os.Create(filepath.Join(d, "find.txt"))
    50  	if err != nil {
    51  		t.Fatal(err)
    52  	}
    53  	defer find.Close()
    54  
    55  	if err := GrantVmGroupAccess(f.Name()); err != nil {
    56  		t.Fatal(err)
    57  	}
    58  
    59  	if err := GrantVmGroupAccess(d); err != nil {
    60  		t.Fatal(err)
    61  	}
    62  
    63  	verifyVMAccountDACLs(t,
    64  		f.Name(),
    65  		[]string{`(R)`},
    66  	)
    67  
    68  	// Two items here:
    69  	//  - One explicit read only.
    70  	//  - Other applies to this folder, subfolders and files
    71  	//      (OI): object inherit
    72  	//      (CI): container inherit
    73  	//      (IO): inherit only
    74  	//      (GR): generic read
    75  	//
    76  	// In properties for the directory, advanced security settings, this will
    77  	// show as a single line "Allow/Virtual Machines/Read/Inherited from none/This folder, subfolder and files
    78  	verifyVMAccountDACLs(t,
    79  		d,
    80  		[]string{`(R)`, `(OI)(CI)(IO)(GR)`},
    81  	)
    82  
    83  	verifyVMAccountDACLs(t,
    84  		find.Name(),
    85  		[]string{`(I)(R)`},
    86  	)
    87  }
    88  
    89  func verifyVMAccountDACLs(t *testing.T, name string, permissions []string) {
    90  	cmd := exec.Command("icacls", name)
    91  	outb, err := cmd.CombinedOutput()
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  	out := string(outb)
    96  
    97  	for _, p := range permissions {
    98  		// Avoid '(' and ')' being part of match groups
    99  		p = strings.Replace(p, "(", "\\(", -1)
   100  		p = strings.Replace(p, ")", "\\)", -1)
   101  
   102  		nameToCheck := vmAccountName + ":" + p
   103  		sidToCheck := vmAccountSID + ":" + p
   104  
   105  		rxName := regexp.MustCompile(nameToCheck)
   106  		rxSID := regexp.MustCompile(sidToCheck)
   107  
   108  		matchesName := rxName.FindAllStringIndex(out, -1)
   109  		matchesSID := rxSID.FindAllStringIndex(out, -1)
   110  
   111  		if len(matchesName) != 1 && len(matchesSID) != 1 {
   112  			t.Fatalf("expected one match for %s or %s\n%s", nameToCheck, sidToCheck, out)
   113  		}
   114  	}
   115  }
   116  

View as plain text