Skip to content

Add Support for Security Descriptor Information#28

Merged
elfrucool merged 27 commits intomainfrom
handle-security-descriptor
Feb 6, 2025
Merged

Add Support for Security Descriptor Information#28
elfrucool merged 27 commits intomainfrom
handle-security-descriptor

Conversation

@elfrucool
Copy link
Collaborator

@elfrucool elfrucool commented Feb 3, 2025

This MR implements comprehensive support for querying and setting security descriptor information for both SMB shares and files. The implementation provides both high-level and low-level APIs to handle security descriptors.

Implementation Overview

The security descriptor functionality is implemented through four main method pairs, available on both Share and File structs:

  • SecurityInfo / SetSecurityInfo: High-level methods that work with parsed security descriptors
  • SecurityInfoRaw / SetSecurityInfoRaw: Low-level methods that work with raw binary data

note for high-level methods, both, the structure and parsing are imported from sddl package, it is important because, by depending on that package, this project will depend on golang 1.23 version

Method Comparison

Share Methods

  1. Share.SecurityInfo(name string, info SecurityInformationRequestFlags) (*sddl.SecurityDescriptor, error)

    • High-level method that returns a parsed security descriptor for a named file/directory within the share
    • Internally uses SecurityInfoRaw and parses the binary data into a structured SecurityDescriptor
    • Provides easy access to SDDL (Security Descriptor Definition Language) representation
  2. Share.SecurityInfoRaw(name string, info SecurityInformationRequestFlags) ([]byte, error)

    • Low-level method that returns raw binary security descriptor data
    • Handles file opening with appropriate access rights (READ_CONTROL and optionally ACCESS_SYSTEM_SECURITY)
    • Performs path validation and normalization
    • Used as the underlying implementation for SecurityInfo
  3. Share.SetSecurityInfo(name string, flags SecurityInformationRequestFlags, sd *sddl.SecurityDescriptor) error

    • High-level method that sets security descriptor for a named file/directory within the share
    • Takes a structured SecurityDescriptor as input
    • Wraps the descriptor in a SecurityDescriptorEncoder and delegates to SetSecurityInfoRaw
  4. Share.SetSecurityInfoRaw(name string, flags SecurityInformationRequestFlags, sd Encoder) error

    • Low-level method that sets raw security descriptor data
    • Handles complex access right management:
      • Always requires WRITE_DAC
      • Adds ACCESS_SYSTEM_SECURITY when SACL information is included
      • Adds WRITE_OWNER when owner information is included
    • Performs path validation and normalization
    • Opens the file with appropriate access rights and delegates to File.SetSecurityInfoRaw

File Methods

  1. File.SecurityInfo(flags SecurityInformationRequestFlags) (*sddl.SecurityDescriptor, error)

    • Similar to Share.SecurityInfo but operates on an already opened file
    • No need for path specification since it works on the current file handle
    • Returns parsed security descriptor structure
  2. File.SecurityInfoRaw(flags SecurityInformationRequestFlags) ([]byte, error)

    • Raw binary access to security descriptor for an opened file
    • Direct interface to the SMB2 QUERY_INFO command
    • Base implementation used by other security descriptor methods
  3. File.SetSecurityInfo(flags SecurityInformationRequestFlags, sd *sddl.SecurityDescriptor) error

    • Sets security descriptor on an already opened file
    • Converts structured SecurityDescriptor to raw format through encoder
    • Simple wrapper around SetSecurityInfoRaw
  4. File.SetSecurityInfoRaw(flags SecurityInformationRequestFlags, sd Encoder) error

    • Core implementation for setting security descriptors
    • Uses SMB2_SET_INFO command with:
      • InfoType: SMB2_0_INFO_SECURITY
      • AdditionalInformation: specified security flags
    • Handles SMB2 credit management for the operation
    • Returns os.PathError with context on failures

Key Differences

  1. Scope of Operation:

    • Share methods require a path and handle file opening/closing internally
    • File methods operate on already opened files and maintain existing handles
  2. API Level:

    • Raw methods (*Raw) provide direct access to binary security descriptor data
    • Non-raw methods provide parsed, structured access through the SDDL package
  3. Usage Context:

    • Share methods are better for one-off security queries
    • File methods are more efficient for multiple security operations on the same file

Technical Details

  • All methods support the full range of SecurityInformationRequestFlags
  • Implements proper access right validation and request
  • Handles path normalization and validation where applicable
  • Provides comprehensive error wrapping with context

Key Implementation Details

  1. Access Rights Management:

    • Automatically determines and requests necessary access rights based on security information flags
    • Implements proper privilege escalation when needed (e.g., for SACL or owner changes)
  2. Credit Management:

    • Implements proper SMB2 credit handling for set operations
    • Uses loan/charge pattern to manage credits across the operation
  3. Error Handling:

    • Consistent error wrapping using os.PathError
    • Proper cleanup of resources (file handles, credits) in error cases
    • Validation of security flags before operations
  4. Interface Design:

    • Raw methods accept any Encoder interface, allowing for custom security descriptor encoders
    • High-level methods use the standard SDDL package for security descriptor handling

Pending: proper build the request
And use them to get security descriptor

Also debug packets (will be temporal)
These commits are reverted with this commit:

361aaed Enforce LARGE_MTU cap on security compound call
60d1ae5 Support compound requests
28c7cf1 Do not use create contexts on get security info
b66229a Fix compound request
63edf77 [WIP] Get security info using compound request
By adding low and high level methods for both Share and File in both
getting and setting security info
@elfrucool
Copy link
Collaborator Author

@arashpayan at this moment the methods are named [Set]SecurityInfo[Raw], do you agree with that naming pattern or is it better [Set]SecurityDescriptor[Raw] ?

@elfrucool elfrucool merged commit eb06575 into main Feb 6, 2025
2 checks passed
@elfrucool elfrucool deleted the handle-security-descriptor branch February 6, 2025 18:57
leolovesmile pushed a commit to leolovesmile/go-smb2 that referenced this pull request Sep 29, 2025
The security descriptor functionality is implemented through four main
method pairs, available on both `Share` and `File` structs:

- `SecurityInfo` / `SetSecurityInfo`: High-level methods that work with
  parsed security descriptors.
- `SecurityInfoRaw` / `SetSecurityInfoRaw`: Low-level methods that work
  with raw binary data.

**note** for high-level methods, both, the structure and parsing are
  imported from https://github.com/cloudsoda/sddl package, it is
  important because, by depending on that package, this project will
  depend on golang `1.23` version.

See the following links for more details:

- CloudSoda/go-smb2#27
- CloudSoda/go-smb2#28

Signed-off-by: Gustavo Serrano <[email protected]>
(cherry picked from commit eb0657583727aba81d491b188455af656be144af)

# Conflicts:
#	client.go
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants

Comments