permcheck: imp code, docs
This commit is contained in:
parent
09e4ae1ba1
commit
c076c93669
|
@ -25,71 +25,64 @@ func check(
|
||||||
querylogDir string,
|
querylogDir string,
|
||||||
confFilePath string,
|
confFilePath string,
|
||||||
) {
|
) {
|
||||||
checkDir(ctx, l, workDir)
|
dirLoggger, fileLogger := l.With("type", typeDir), l.With("type", typeFile)
|
||||||
|
|
||||||
checkFile(ctx, l, confFilePath)
|
checkDir(ctx, dirLoggger, workDir)
|
||||||
|
|
||||||
|
checkFile(ctx, fileLogger, confFilePath)
|
||||||
|
|
||||||
// TODO(a.garipov): Put all paths in one place and remove this duplication.
|
// TODO(a.garipov): Put all paths in one place and remove this duplication.
|
||||||
checkDir(ctx, l, dataDir)
|
checkDir(ctx, dirLoggger, dataDir)
|
||||||
checkDir(ctx, l, filepath.Join(dataDir, "filters"))
|
checkDir(ctx, dirLoggger, filepath.Join(dataDir, "filters"))
|
||||||
checkFile(ctx, l, filepath.Join(dataDir, "sessions.db"))
|
checkFile(ctx, fileLogger, filepath.Join(dataDir, "sessions.db"))
|
||||||
checkFile(ctx, l, filepath.Join(dataDir, "leases.json"))
|
checkFile(ctx, fileLogger, filepath.Join(dataDir, "leases.json"))
|
||||||
|
|
||||||
if dataDir != querylogDir {
|
if dataDir != querylogDir {
|
||||||
checkDir(ctx, l, querylogDir)
|
checkDir(ctx, dirLoggger, querylogDir)
|
||||||
}
|
}
|
||||||
checkFile(ctx, l, filepath.Join(querylogDir, "querylog.json"))
|
checkFile(ctx, fileLogger, filepath.Join(querylogDir, "querylog.json"))
|
||||||
checkFile(ctx, l, filepath.Join(querylogDir, "querylog.json.1"))
|
checkFile(ctx, fileLogger, filepath.Join(querylogDir, "querylog.json.1"))
|
||||||
|
|
||||||
if dataDir != statsDir {
|
if dataDir != statsDir {
|
||||||
checkDir(ctx, l, statsDir)
|
checkDir(ctx, dirLoggger, statsDir)
|
||||||
}
|
}
|
||||||
checkFile(ctx, l, filepath.Join(statsDir, "stats.db"))
|
checkFile(ctx, fileLogger, filepath.Join(statsDir, "stats.db"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkDir checks the permissions of a single directory. The results are
|
// checkDir checks the permissions of a single directory. The results are
|
||||||
// logged at the appropriate level.
|
// logged at the appropriate level.
|
||||||
func checkDir(ctx context.Context, l *slog.Logger, dirPath string) {
|
func checkDir(ctx context.Context, l *slog.Logger, dirPath string) {
|
||||||
checkPath(ctx, l, dirPath, typeDir, aghos.DefaultPermDir)
|
checkPath(ctx, l, dirPath, aghos.DefaultPermDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkFile checks the permissions of a single file. The results are logged at
|
// checkFile checks the permissions of a single file. The results are logged at
|
||||||
// the appropriate level.
|
// the appropriate level.
|
||||||
func checkFile(ctx context.Context, l *slog.Logger, filePath string) {
|
func checkFile(ctx context.Context, l *slog.Logger, filePath string) {
|
||||||
checkPath(ctx, l, filePath, typeFile, aghos.DefaultPermFile)
|
checkPath(ctx, l, filePath, aghos.DefaultPermFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkPath checks the permissions of a single filesystem entity. The results
|
// checkPath checks the permissions of a single filesystem entity. The results
|
||||||
// are logged at the appropriate level.
|
// are logged at the appropriate level.
|
||||||
func checkPath(ctx context.Context, l *slog.Logger, entPath, fileType string, want fs.FileMode) {
|
func checkPath(ctx context.Context, l *slog.Logger, fpath string, want fs.FileMode) {
|
||||||
s, err := os.Stat(entPath)
|
l = l.With("path", fpath)
|
||||||
|
s, err := os.Stat(fpath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logFunc := l.ErrorContext
|
lvl := slog.LevelError
|
||||||
if errors.Is(err, os.ErrNotExist) {
|
if errors.Is(err, os.ErrNotExist) {
|
||||||
logFunc = l.DebugContext
|
lvl = slog.LevelDebug
|
||||||
}
|
}
|
||||||
|
|
||||||
logFunc(
|
l.Log(ctx, lvl, "checking permissions", slogutil.KeyError, err)
|
||||||
ctx,
|
|
||||||
"checking permissions",
|
|
||||||
"type", fileType,
|
|
||||||
"path", entPath,
|
|
||||||
slogutil.KeyError, err,
|
|
||||||
)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(a.garipov): Add a more fine-grained check and result reporting.
|
// TODO(a.garipov): Add a more fine-grained check and result reporting.
|
||||||
perm := s.Mode().Perm()
|
perm := s.Mode().Perm()
|
||||||
if perm != want {
|
if perm == want {
|
||||||
l.WarnContext(
|
return
|
||||||
ctx,
|
|
||||||
"found unexpected permissions",
|
|
||||||
"type", fileType,
|
|
||||||
"path", entPath,
|
|
||||||
"got", fmt.Sprintf("%#o", perm),
|
|
||||||
"want", fmt.Sprintf("%#o", want),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
permOct, wantOct := fmt.Sprintf("%#o", perm), fmt.Sprintf("%#o", want)
|
||||||
|
l.WarnContext(ctx, "found unexpected permissions", "perm", permOct, "want", wantOct)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import (
|
||||||
|
|
||||||
// check is the Windows-specific implementation of [Check].
|
// check is the Windows-specific implementation of [Check].
|
||||||
func check(ctx context.Context, l *slog.Logger, workDir, _, _, _, _ string) {
|
func check(ctx context.Context, l *slog.Logger, workDir, _, _, _, _ string) {
|
||||||
|
l = l.With("type", typeDir, "path", workDir)
|
||||||
|
|
||||||
dacl, owner, err := getSecurityInfo(workDir)
|
dacl, owner, err := getSecurityInfo(workDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.ErrorContext(ctx, "getting security info", slogutil.KeyError, err)
|
l.ErrorContext(ctx, "getting security info", slogutil.KeyError, err)
|
||||||
|
@ -20,12 +22,14 @@ func check(ctx context.Context, l *slog.Logger, workDir, _, _, _, _ string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !owner.IsWellKnown(windows.WinBuiltinAdministratorsSid) {
|
if !owner.IsWellKnown(windows.WinBuiltinAdministratorsSid) {
|
||||||
l.WarnContext(ctx, "working directory owner is not in administrators group")
|
l.WarnContext(ctx, "owner is not in administrators group")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = rangeACEs(dacl, func(hdr windows.ACE_HEADER, mask windows.ACCESS_MASK, sid *windows.SID) (cont bool) {
|
err = rangeACEs(dacl, func(
|
||||||
l.DebugContext(ctx, "checking entry", "sid", sid, "mask", mask)
|
hdr windows.ACE_HEADER,
|
||||||
|
mask windows.ACCESS_MASK,
|
||||||
|
sid *windows.SID,
|
||||||
|
) (cont bool) {
|
||||||
warn := false
|
warn := false
|
||||||
switch {
|
switch {
|
||||||
case hdr.AceType != windows.ACCESS_ALLOWED_ACE_TYPE:
|
case hdr.AceType != windows.ACCESS_ALLOWED_ACE_TYPE:
|
||||||
|
|
|
@ -45,63 +45,63 @@ func migrate(
|
||||||
querylogDir string,
|
querylogDir string,
|
||||||
confFilePath string,
|
confFilePath string,
|
||||||
) {
|
) {
|
||||||
chmodDir(ctx, l, workDir)
|
dirLoggger, fileLogger := l.With("type", typeDir), l.With("type", typeFile)
|
||||||
|
|
||||||
chmodFile(ctx, l, confFilePath)
|
chmodDir(ctx, dirLoggger, workDir)
|
||||||
|
|
||||||
|
chmodFile(ctx, fileLogger, confFilePath)
|
||||||
|
|
||||||
// TODO(a.garipov): Put all paths in one place and remove this duplication.
|
// TODO(a.garipov): Put all paths in one place and remove this duplication.
|
||||||
chmodDir(ctx, l, dataDir)
|
chmodDir(ctx, dirLoggger, dataDir)
|
||||||
chmodDir(ctx, l, filepath.Join(dataDir, "filters"))
|
chmodDir(ctx, dirLoggger, filepath.Join(dataDir, "filters"))
|
||||||
chmodFile(ctx, l, filepath.Join(dataDir, "sessions.db"))
|
chmodFile(ctx, fileLogger, filepath.Join(dataDir, "sessions.db"))
|
||||||
chmodFile(ctx, l, filepath.Join(dataDir, "leases.json"))
|
chmodFile(ctx, fileLogger, filepath.Join(dataDir, "leases.json"))
|
||||||
|
|
||||||
if dataDir != querylogDir {
|
if dataDir != querylogDir {
|
||||||
chmodDir(ctx, l, querylogDir)
|
chmodDir(ctx, dirLoggger, querylogDir)
|
||||||
}
|
}
|
||||||
chmodFile(ctx, l, filepath.Join(querylogDir, "querylog.json"))
|
chmodFile(ctx, fileLogger, filepath.Join(querylogDir, "querylog.json"))
|
||||||
chmodFile(ctx, l, filepath.Join(querylogDir, "querylog.json.1"))
|
chmodFile(ctx, fileLogger, filepath.Join(querylogDir, "querylog.json.1"))
|
||||||
|
|
||||||
if dataDir != statsDir {
|
if dataDir != statsDir {
|
||||||
chmodDir(ctx, l, statsDir)
|
chmodDir(ctx, dirLoggger, statsDir)
|
||||||
}
|
}
|
||||||
chmodFile(ctx, l, filepath.Join(statsDir, "stats.db"))
|
chmodFile(ctx, fileLogger, filepath.Join(statsDir, "stats.db"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// chmodDir changes the permissions of a single directory. The results are
|
// chmodDir changes the permissions of a single directory. The results are
|
||||||
// logged at the appropriate level.
|
// logged at the appropriate level.
|
||||||
func chmodDir(ctx context.Context, l *slog.Logger, dirPath string) {
|
func chmodDir(ctx context.Context, l *slog.Logger, dirPath string) {
|
||||||
chmodPath(ctx, l, dirPath, typeDir, aghos.DefaultPermDir)
|
chmodPath(ctx, l, dirPath, aghos.DefaultPermDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
// chmodFile changes the permissions of a single file. The results are logged
|
// chmodFile changes the permissions of a single file. The results are logged
|
||||||
// at the appropriate level.
|
// at the appropriate level.
|
||||||
func chmodFile(ctx context.Context, l *slog.Logger, filePath string) {
|
func chmodFile(ctx context.Context, l *slog.Logger, filePath string) {
|
||||||
chmodPath(ctx, l, filePath, typeFile, aghos.DefaultPermFile)
|
chmodPath(ctx, l, filePath, aghos.DefaultPermFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
// chmodPath changes the permissions of a single filesystem entity. The results
|
// chmodPath changes the permissions of a single filesystem entity. The results
|
||||||
// are logged at the appropriate level.
|
// are logged at the appropriate level.
|
||||||
func chmodPath(ctx context.Context, l *slog.Logger, entPath, fileType string, fm fs.FileMode) {
|
func chmodPath(ctx context.Context, l *slog.Logger, fpath string, fm fs.FileMode) {
|
||||||
switch err := os.Chmod(entPath, fm); {
|
var lvl slog.Level
|
||||||
|
var msg string
|
||||||
|
args := []any{"path", fpath}
|
||||||
|
|
||||||
|
switch err := os.Chmod(fpath, fm); {
|
||||||
case err == nil:
|
case err == nil:
|
||||||
l.InfoContext(ctx, "changed permissions", "type", fileType, "path", entPath)
|
lvl = slog.LevelInfo
|
||||||
|
msg = "changed permissions"
|
||||||
case errors.Is(err, os.ErrNotExist):
|
case errors.Is(err, os.ErrNotExist):
|
||||||
l.DebugContext(
|
lvl = slog.LevelDebug
|
||||||
ctx,
|
msg = "checking permissions"
|
||||||
"changing permissions",
|
args = append(args, slogutil.KeyError, err)
|
||||||
"type", fileType,
|
|
||||||
"path", entPath,
|
|
||||||
slogutil.KeyError, err,
|
|
||||||
)
|
|
||||||
default:
|
default:
|
||||||
l.ErrorContext(
|
lvl = slog.LevelError
|
||||||
ctx,
|
msg = "can not change permissions; this can leave your system vulnerable, see " +
|
||||||
"can not change permissions; this can leave your system vulnerable, see "+
|
"https://adguard-dns.io/kb/adguard-home/running-securely/#os-service-concerns"
|
||||||
"https://adguard-dns.io/kb/adguard-home/running-securely/#os-service-concerns",
|
args = append(args, "target_perm", fmt.Sprintf("%#o", fm), slogutil.KeyError, err)
|
||||||
"type", fileType,
|
|
||||||
"path", entPath,
|
|
||||||
"target_perm", fmt.Sprintf("%#o", fm),
|
|
||||||
slogutil.KeyError, err,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
l.Log(ctx, lvl, msg, args...)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,8 @@ import (
|
||||||
|
|
||||||
// needsMigration is the Windows-specific implementation of [NeedsMigration].
|
// needsMigration is the Windows-specific implementation of [NeedsMigration].
|
||||||
func needsMigration(ctx context.Context, l *slog.Logger, workDir, _ string) (ok bool) {
|
func needsMigration(ctx context.Context, l *slog.Logger, workDir, _ string) (ok bool) {
|
||||||
|
l = l.With("type", typeDir, "path", workDir)
|
||||||
|
|
||||||
dacl, owner, err := getSecurityInfo(workDir)
|
dacl, owner, err := getSecurityInfo(workDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.ErrorContext(ctx, "getting security info", slogutil.KeyError, err)
|
l.ErrorContext(ctx, "getting security info", slogutil.KeyError, err)
|
||||||
|
@ -54,9 +56,11 @@ func needsMigration(ctx context.Context, l *slog.Logger, workDir, _ string) (ok
|
||||||
|
|
||||||
// migrate is the Windows-specific implementation of [Migrate].
|
// migrate is the Windows-specific implementation of [Migrate].
|
||||||
func migrate(ctx context.Context, l *slog.Logger, workDir, _, _, _, _ string) {
|
func migrate(ctx context.Context, l *slog.Logger, workDir, _, _, _, _ string) {
|
||||||
|
dirLogger := l.With("type", typeDir, "path", workDir)
|
||||||
|
|
||||||
dacl, owner, err := getSecurityInfo(workDir)
|
dacl, owner, err := getSecurityInfo(workDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.ErrorContext(ctx, "getting security info", slogutil.KeyError, err)
|
dirLogger.ErrorContext(ctx, "getting security info", slogutil.KeyError, err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -65,9 +69,10 @@ func migrate(ctx context.Context, l *slog.Logger, workDir, _, _, _, _ string) {
|
||||||
var admins *windows.SID
|
var admins *windows.SID
|
||||||
admins, err = windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
|
admins, err = windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
// This log message is not related to the directory.
|
||||||
l.ErrorContext(ctx, "creating administrators sid", slogutil.KeyError, err)
|
l.ErrorContext(ctx, "creating administrators sid", slogutil.KeyError, err)
|
||||||
} else {
|
} else {
|
||||||
l.InfoContext(ctx, "migrating working directory owner", "sid", admins)
|
dirLogger.InfoContext(ctx, "migrating owner", "sid", admins)
|
||||||
owner = admins
|
owner = admins
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,26 +87,26 @@ func migrate(ctx context.Context, l *slog.Logger, workDir, _, _, _, _ string) {
|
||||||
switch {
|
switch {
|
||||||
case hdr.AceType != windows.ACCESS_ALLOWED_ACE_TYPE:
|
case hdr.AceType != windows.ACCESS_ALLOWED_ACE_TYPE:
|
||||||
// Add non-allowed access control entries as is.
|
// Add non-allowed access control entries as is.
|
||||||
l.InfoContext(ctx, "migrating deny control entry", "sid", sid)
|
dirLogger.InfoContext(ctx, "migrating deny control entry", "sid", sid)
|
||||||
accessEntries = append(accessEntries, newDenyExplicitAccess(sid, mask))
|
accessEntries = append(accessEntries, newDenyExplicitAccess(sid, mask))
|
||||||
case !sid.IsWellKnown(windows.WinBuiltinAdministratorsSid):
|
case !sid.IsWellKnown(windows.WinBuiltinAdministratorsSid):
|
||||||
// Skip non-administrator ACEs.
|
// Skip non-administrator ACEs.
|
||||||
l.InfoContext(ctx, "removing access control entry", "sid", sid)
|
dirLogger.InfoContext(ctx, "removing access control entry", "sid", sid)
|
||||||
default:
|
default:
|
||||||
l.InfoContext(ctx, "migrating access control entry", "sid", sid, "mask", mask)
|
dirLogger.InfoContext(ctx, "migrating access control entry", "sid", sid, "mask", mask)
|
||||||
accessEntries = append(accessEntries, newFullExplicitAccess(sid))
|
accessEntries = append(accessEntries, newFullExplicitAccess(sid))
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.ErrorContext(ctx, "ranging trough access control entries", slogutil.KeyError, err)
|
dirLogger.ErrorContext(ctx, "filtering access control entries", slogutil.KeyError, err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
err = setSecurityInfo(workDir, owner, accessEntries)
|
err = setSecurityInfo(workDir, owner, accessEntries)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
l.ErrorContext(ctx, "setting security info", slogutil.KeyError, err)
|
dirLogger.ErrorContext(ctx, "setting security info", slogutil.KeyError, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,6 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// File type constants for logging.
|
// File type constants for logging.
|
||||||
//
|
|
||||||
// TODO(e.burkov): !! Use in Windows logging.
|
|
||||||
const (
|
const (
|
||||||
typeDir = "directory"
|
typeDir = "directory"
|
||||||
typeFile = "file"
|
typeFile = "file"
|
||||||
|
|
|
@ -16,6 +16,8 @@ const securityInfo windows.SECURITY_INFORMATION = windows.OWNER_SECURITY_INFORMA
|
||||||
windows.PROTECTED_DACL_SECURITY_INFORMATION |
|
windows.PROTECTED_DACL_SECURITY_INFORMATION |
|
||||||
windows.UNPROTECTED_DACL_SECURITY_INFORMATION
|
windows.UNPROTECTED_DACL_SECURITY_INFORMATION
|
||||||
|
|
||||||
|
// objectType is the type of the object for directories in context of security
|
||||||
|
// API.
|
||||||
const objectType = windows.SE_FILE_OBJECT
|
const objectType = windows.SE_FILE_OBJECT
|
||||||
|
|
||||||
// fileDeleteChildRight is the mask bit for the right to delete a child object.
|
// fileDeleteChildRight is the mask bit for the right to delete a child object.
|
||||||
|
@ -41,8 +43,8 @@ const fullControlMask windows.ACCESS_MASK = windows.FILE_LIST_DIRECTORY |
|
||||||
windows.SYNCHRONIZE
|
windows.SYNCHRONIZE
|
||||||
|
|
||||||
// aceFunc is a function that handles access control entries in the
|
// aceFunc is a function that handles access control entries in the
|
||||||
// discretionary access control list. It should return true to continue ranging
|
// discretionary access control list. It should return true to continue
|
||||||
// or false to stop.
|
// iterating over the entries, or false to stop.
|
||||||
type aceFunc = func(
|
type aceFunc = func(
|
||||||
hdr windows.ACE_HEADER,
|
hdr windows.ACE_HEADER,
|
||||||
mask windows.ACCESS_MASK,
|
mask windows.ACCESS_MASK,
|
||||||
|
@ -50,7 +52,7 @@ type aceFunc = func(
|
||||||
) (cont bool)
|
) (cont bool)
|
||||||
|
|
||||||
// rangeACEs ranges over the access control entries in the discretionary access
|
// rangeACEs ranges over the access control entries in the discretionary access
|
||||||
// control list of the specified security descriptor.
|
// control list of the specified security descriptor and calls f for each one.
|
||||||
func rangeACEs(dacl *windows.ACL, f aceFunc) (err error) {
|
func rangeACEs(dacl *windows.ACL, f aceFunc) (err error) {
|
||||||
var errs []error
|
var errs []error
|
||||||
for i := range uint32(dacl.AceCount) {
|
for i := range uint32(dacl.AceCount) {
|
||||||
|
@ -119,15 +121,14 @@ func getSecurityInfo(fname string) (dacl *windows.ACL, owner *windows.SID, err e
|
||||||
|
|
||||||
// newFullExplicitAccess creates a new explicit access entry with full control
|
// newFullExplicitAccess creates a new explicit access entry with full control
|
||||||
// permissions.
|
// permissions.
|
||||||
func newFullExplicitAccess(sid *windows.SID) (expAcc windows.EXPLICIT_ACCESS) {
|
func newFullExplicitAccess(sid *windows.SID) (accEnt windows.EXPLICIT_ACCESS) {
|
||||||
// TODO(e.burkov): !! lookup account type
|
|
||||||
return windows.EXPLICIT_ACCESS{
|
return windows.EXPLICIT_ACCESS{
|
||||||
AccessPermissions: fullControlMask,
|
AccessPermissions: fullControlMask,
|
||||||
AccessMode: windows.GRANT_ACCESS,
|
AccessMode: windows.GRANT_ACCESS,
|
||||||
Inheritance: windows.SUB_CONTAINERS_AND_OBJECTS_INHERIT,
|
Inheritance: windows.SUB_CONTAINERS_AND_OBJECTS_INHERIT,
|
||||||
Trustee: windows.TRUSTEE{
|
Trustee: windows.TRUSTEE{
|
||||||
TrusteeForm: windows.TRUSTEE_IS_SID,
|
TrusteeForm: windows.TRUSTEE_IS_SID,
|
||||||
TrusteeType: windows.TRUSTEE_IS_GROUP,
|
TrusteeType: windows.TRUSTEE_IS_UNKNOWN,
|
||||||
TrusteeValue: windows.TrusteeValueFromSID(sid),
|
TrusteeValue: windows.TrusteeValueFromSID(sid),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -135,15 +136,17 @@ func newFullExplicitAccess(sid *windows.SID) (expAcc windows.EXPLICIT_ACCESS) {
|
||||||
|
|
||||||
// newDenyExplicitAccess creates a new explicit access entry with specified deny
|
// newDenyExplicitAccess creates a new explicit access entry with specified deny
|
||||||
// permissions.
|
// permissions.
|
||||||
func newDenyExplicitAccess(sid *windows.SID, mask windows.ACCESS_MASK) (expAcc windows.EXPLICIT_ACCESS) {
|
func newDenyExplicitAccess(
|
||||||
// TODO(e.burkov): !! lookup account type
|
sid *windows.SID,
|
||||||
|
mask windows.ACCESS_MASK,
|
||||||
|
) (accEnt windows.EXPLICIT_ACCESS) {
|
||||||
return windows.EXPLICIT_ACCESS{
|
return windows.EXPLICIT_ACCESS{
|
||||||
AccessPermissions: mask,
|
AccessPermissions: mask,
|
||||||
AccessMode: windows.DENY_ACCESS,
|
AccessMode: windows.DENY_ACCESS,
|
||||||
Inheritance: windows.SUB_CONTAINERS_AND_OBJECTS_INHERIT,
|
Inheritance: windows.SUB_CONTAINERS_AND_OBJECTS_INHERIT,
|
||||||
Trustee: windows.TRUSTEE{
|
Trustee: windows.TRUSTEE{
|
||||||
TrusteeForm: windows.TRUSTEE_IS_SID,
|
TrusteeForm: windows.TRUSTEE_IS_SID,
|
||||||
TrusteeType: windows.TRUSTEE_IS_GROUP,
|
TrusteeType: windows.TRUSTEE_IS_UNKNOWN,
|
||||||
TrusteeValue: windows.TrusteeValueFromSID(sid),
|
TrusteeValue: windows.TrusteeValueFromSID(sid),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue