package security import ( "io/ioutil" "os" "os/exec" "path/filepath" "regexp" "strings" "testing" ) // TestGrantVmGroupAccess verifies for the three case of a file, a directory, // and a file in a directory that the appropriate ACEs are set, including // inheritance in the second two examples. These are the expected ACES. Is // verified by running icacls and comparing output. // // File: // S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(R,W) // S-1-5-83-1-3166535780-1122986932-343720105-43916321:(R,W) // // Directory: // S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(OI)(CI)(R,W) // S-1-5-83-1-3166535780-1122986932-343720105-43916321:(OI)(CI)(R,W) // // File in directory (inherited): // S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(I)(R,W) // S-1-5-83-1-3166535780-1122986932-343720105-43916321:(I)(R,W) func TestGrantVmGroupAccess(t *testing.T) { f, err := ioutil.TempFile("", "gvmgafile") if err != nil { t.Fatal(err) } defer func() { f.Close() os.Remove(f.Name()) }() d, err := ioutil.TempDir("", "gvmgadir") if err != nil { t.Fatal(err) } defer os.RemoveAll(d) find, err := os.Create(filepath.Join(d, "find.txt")) if err != nil { t.Fatal(err) } if err := GrantVmGroupAccess(f.Name()); err != nil { t.Fatal(err) } if err := GrantVmGroupAccess(d); err != nil { t.Fatal(err) } verifyicacls(t, f.Name(), "S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(R,W)", "S-1-5-83-1-3166535780-1122986932-343720105-43916321:(R,W)", ) verifyicacls(t, d, "S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(OI)(CI)(R,W)", "S-1-5-83-1-3166535780-1122986932-343720105-43916321:(OI)(CI)(R,W)", ) verifyicacls(t, find.Name(), "S-1-15-3-1024-2268835264-3721307629-241982045-173645152-1490879176-104643441-2915960892-1612460704:(I)(R,W)", "S-1-5-83-1-3166535780-1122986932-343720105-43916321:(I)(R,W)", ) } func verifyicacls(t *testing.T, name string, ace1 string, ace2 string) { cmd := exec.Command("icacls", name) outb, err := cmd.CombinedOutput() if err != nil { t.Fatal(err) } out := string(outb) // Avoid () being part of match groups ace1 = strings.Replace(ace1, "(", "\\(", -1) ace1 = strings.Replace(ace1, ")", "\\)", -1) ace2 = strings.Replace(ace2, "(", "\\(", -1) ace2 = strings.Replace(ace2, ")", "\\)", -1) rx1 := regexp.MustCompile(ace1) matches1 := rx1.FindAllStringIndex(out, -1) if len(matches1) != 1 { t.Fatalf("expected one match for %s got %d", ace1, len(matches1)) } rx2 := regexp.MustCompile(ace1) matches2 := rx2.FindAllStringIndex(out, -1) if len(matches2) != 1 { t.Fatalf("expected one match for %s got %d", ace2, len(matches2)) } }