github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/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  }