github.com/keybase/client/go@v0.0.0-20241007131713-f10651d043c8/kbfs/dokan/winacl/ace.go (about) 1 // Copyright 2016 Keybase Inc. All rights reserved. 2 // Use of this source code is governed by a BSD 3 // license that can be found in the LICENSE file. 4 5 package winacl 6 7 import ( 8 "encoding/binary" 9 "unsafe" 10 ) 11 12 // ACL is the type for access control lists. 13 type ACL struct { 14 raw []byte 15 aceCount int 16 } 17 18 func (acl *ACL) initIfEmpty() { 19 if acl.raw == nil { 20 acl.raw = make([]byte, 8, 8+16) 21 acl.raw[0] = aclRevision 22 } 23 } 24 25 const ( 26 aclRevision = 2 27 ) 28 29 // AddAllowAccess add a new ALLOW_ACCESS ACE to the ACL. 30 func (acl *ACL) AddAllowAccess(accessMask uint32, sid *SID) { 31 acl.initIfEmpty() 32 ssize := sidSize(sid) 33 var bs [8]byte 34 // ACLs are little endian... 35 binary.LittleEndian.PutUint16(bs[2:], uint16(8+align4up(uint32(sidSize(sid))))) 36 binary.LittleEndian.PutUint32(bs[4:], accessMask) 37 acl.raw = append(acl.raw, bs[:]...) 38 acl.raw = append(acl.raw, bufToSlice(unsafe.Pointer(sid), ssize)...) 39 for len(acl.raw)&3 != 0 { 40 acl.raw = append(acl.raw, 0) 41 } 42 acl.aceCount++ 43 } 44 45 func (acl *ACL) bytes() []byte { 46 binary.LittleEndian.PutUint16(acl.raw[2:], uint16(len(acl.raw))) 47 binary.LittleEndian.PutUint16(acl.raw[4:], uint16(acl.aceCount)) 48 return acl.raw 49 } 50 51 func align4up(u uint32) uint32 { 52 return (u + 3) &^ 3 53 }