winapi

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 18, 2023 License: MIT Imports: 22 Imported by: 0

README

GoLang Windows API Wrappers

For System Info / User Management.

For an internal project, this is a set of wrappers for snippets of the Windows API.

Tested and developed for Windows 10 x64.

All functions that return useful data, do so in the form of JSON exportable structs.

These structs are available in the shared library, "github.com/iamacarpet/go-win64api/shared"

Process List
package main

import (
    "fmt"
    wapi "github.com/iamacarpet/go-win64api"
)

func main(){
    pr, err := wapi.ProcessList()
    if err != nil {
        fmt.Printf("Error fetching process list... %s\r\n", err.Error())
    }
    for _, p := range pr {
        fmt.Printf("%8d - %-30s - %-30s - %s\r\n", p.Pid, p.Username, p.Executable, p.Fullpath)
    }
}
Active Session List (Logged in users + Run-As users)
package main

import (
    "fmt"
    wapi "github.com/iamacarpet/go-win64api"
)

func main(){
    // This check runs best as NT AUTHORITY\SYSTEM
    //
    // Running as a normal or even elevated user,
    // we can't properly detect who is an admin or not.
    //
    // This is because we require TOKEN_DUPLICATE permission,
    // which we don't seem to have otherwise (Win10).
    users, err := wapi.ListLoggedInUsers()
    if err != nil {
        fmt.Printf("Error fetching user session list.\r\n")
        return
    }

    fmt.Printf("Users currently logged in (Admin check doesn't work for AD Accounts):\r\n")
    for _, u := range users {
        fmt.Printf("\t%-50s - Local User: %-5t - Local Admin: %t\r\n", u.FullUser(), u.LocalUser, u.LocalAdmin)
    }
}
Installed Software List
package main

import (
    "fmt"
    wapi "github.com/iamacarpet/go-win64api"
)

func main(){
    sw, err := wapi.InstalledSoftwareList()
    if err != nil {
        fmt.Printf("%s\r\n", err.Error())
    }

    for _, s := range sw {
        fmt.Printf("%-100s - %s - %s\r\n", s.Name(), s.Architecture(), s.Version())
    }
}
Windows Update Status
package main

import (
        "fmt"
        "time"
        wapi "github.com/iamacarpet/go-win64api"
)

func main() {
        ret, err := wapi.UpdatesPending()
        if err != nil {
                fmt.Printf("Error fetching data... %s\r\n", err.Error())
        }

        fmt.Printf("Number of Updates Available: %d\n", ret.NumUpdates)
        fmt.Printf("Updates Pending:             %t\n\n", ret.UpdatesReq)
        fmt.Printf("%25s | %25s | %s\n", "EVENT DATE", "STATUS", "UPDATE NAME")
        for _, v := range ret.UpdateHistory {
                fmt.Printf("%25s | %25s | %s\n", v.EventDate.Format(time.RFC822), v.Status, v.UpdateName)
        }
}

Local Service Management

List Services
package main

import (
    "fmt"

    wapi "github.com/iamacarpet/go-win64api"
)

func main(){
    svc, err := wapi.GetServices()
    if err != nil {
        fmt.Printf("%s\r\n", err.Error())
    }

    for _, v := range svc {
        fmt.Printf("%-50s - %-75s - Status: %-20s - Accept Stop: %-5t, Running Pid: %d\r\n", v.SCName, v.DisplayName, v.StatusText, v.AcceptStop, v.RunningPid)
    }
}
Start Service
err := wapi.StartService(service_name)
Stop Service
err := wapi.StopService(service_name)

Local User Management

List Local Users
package main

import (
    "fmt"
    "time"
    wapi "github.com/iamacarpet/go-win64api"
)

func main(){
    users, err := wapi.ListLocalUsers()
    if err != nil {
        fmt.Printf("Error fetching user list, %s.\r\n", err.Error())
        return
    }

    for _, u := range users {
        fmt.Printf("%s (%s)\r\n", u.Username, u.FullName)
        fmt.Printf("\tIs Enabled:                   %t\r\n", u.IsEnabled)
        fmt.Printf("\tIs Locked:                    %t\r\n", u.IsLocked)
        fmt.Printf("\tIs Admin:                     %t\r\n", u.IsAdmin)
        fmt.Printf("\tPassword Never Expires:       %t\r\n", u.PasswordNeverExpires)
        fmt.Printf("\tUser can't change password:   %t\r\n", u.NoChangePassword)
        fmt.Printf("\tPassword Age:                 %.0f days\r\n", (u.PasswordAge.Hours()/24))
        fmt.Printf("\tLast Logon Time:              %s\r\n", u.LastLogon.Format(time.RFC850))
        fmt.Printf("\tBad Password Count:           %d\r\n", u.BadPasswordCount)
        fmt.Printf("\tNumber Of Logons:             %d\r\n", u.NumberOfLogons)
    }
}
Adding a Local User
ok, err := wapi.UserAdd(username, fullname, password)
Deleting a Local User
ok, err := wapi.UserDelete(username)
Set Full Name Attribute
ok, err := wapi.UserUpdateFullname(username, fullname)
Give Admin Privileges
ok, err := wapi.SetAdmin(username)
Revoke Admin Privileges
ok, err := wapi.RevokeAdmin(username)
Disable/Enable User
s := true   // disable user
s := false  // enable user
ok, err := wapi.UserDisabled(username, s)
Change Attribute - User Can't Change Password
s := true   // User can't change password
s := false  // User can change password
ok, err := wapi.UserDisablePasswordChange(username, s)
Change Attribute - Password Never Expires
s := true   // Password never expires.
s := false  // Enable password expiry.
ok, err := wapi.UserPasswordNoExpires(username, s)
Forced Password Change
ok, err := wapi.ChangePassword(username, newpassword)
Windows Firewall - Add Inbound Rule
added, err := wapi.FirewallRuleCreate(
	"App Rule Name",
	"App Rule Long Description.",
	"My Rule Group",
	"%systemDrive%\\path\\to\\my.exe",
	"port number as string",
	wapi.NET_FW_IP_PROTOCOL_TCP,
)

Documentation

Rendered for windows/amd64

Index

Examples

Constants

View Source
const (
	NET_FW_IP_PROTOCOL_TCP    = 6
	NET_FW_IP_PROTOCOL_UDP    = 17
	NET_FW_IP_PROTOCOL_ICMPv4 = 1
	NET_FW_IP_PROTOCOL_ICMPv6 = 58
	NET_FW_IP_PROTOCOL_ANY    = 256

	NET_FW_RULE_DIR_IN  = 1
	NET_FW_RULE_DIR_OUT = 2

	NET_FW_ACTION_BLOCK = 0
	NET_FW_ACTION_ALLOW = 1

	// NET_FW_PROFILE2_CURRENT is not real API constant, just helper used in FW functions.
	// It can mean one profile or multiple (even all) profiles. It depends on which profiles
	// are currently in use. Every active interface can have it's own profile. F.e.: Public for Wifi,
	// Domain for VPN, and Private for LAN. All at the same time.
	NET_FW_PROFILE2_CURRENT = 0
	NET_FW_PROFILE2_DOMAIN  = 1
	NET_FW_PROFILE2_PRIVATE = 2
	NET_FW_PROFILE2_PUBLIC  = 4
	NET_FW_PROFILE2_ALL     = 2147483647
)

Firewall related API constants.

View Source
const (
	NET_FW_FILE_AND_PRINTER_SHARING = "@FirewallAPI.dll,-28502"
	NET_FW_REMOTE_DESKTOP           = "@FirewallAPI.dll,-28752"
)

Firewall Rule Groups Use this magical strings instead of group names. It will work on all language Windows versions. You can find more string locations here: https://windows10dll.nirsoft.net/firewallapi_dll.html

View Source
const (
	NERR_GroupNotFound syscall.Errno = 2220 // 0x000008AC

	ERROR_ACCESS_DENIED       syscall.Errno = 5    // 0x00000005
	ERROR_MEMBER_NOT_IN_ALIAS syscall.Errno = 1377 // 0x00000561
	ERROR_MEMBER_IN_ALIAS     syscall.Errno = 1378 // 0x00000562
	ERROR_NO_SUCH_MEMBER      syscall.Errno = 1387 // 0x0000056B
	ERROR_INVALID_MEMBER      syscall.Errno = 1388 // 0x0000056C
)

Possible errors returned by local group management functions Error code enumerations taken from MS-ERREF documentation: https://msdn.microsoft.com/en-us/library/cc231196.aspx

View Source
const (
	ERROR_NO_MORE_FILES               = 0x12
	PROCESS_TERMINATE                 = 0x0001
	PROCESS_QUERY_INFORMATION         = 0x0400
	PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
	MAX_PATH                          = 260
	MAX_FULL_PATH                     = 4096

	ES_AWAYMODE_REQUIRED = 0x00000040
	ES_CONTINUOUS        = 0x80000000
	ES_DISPLAY_REQUIRED  = 0x00000002
	ES_SYSTEM_REQUIRED   = 0x00000001
	ES_USER_PRESENT      = 0x00000004

	PROC_TOKEN_DUPLICATE         = 0x0002
	PROC_TOKEN_QUERY             = 0x0008
	PROC_TOKEN_ADJUST_PRIVILEGES = 0x0020

	PROC_SE_PRIVILEGE_ENABLED = 0x00000002

	PROC_SE_DEBUG_NAME              = "SeDebugPrivilege"
	PROC_SE_SYSTEM_ENVIRONMENT_PRIV = "SeSystemEnvironmentPrivilege"

	PROC_SECURITY_BUILTIN_DOMAIN_RID = 0x00000020
	PROC_DOMAIN_ALIAS_RID_ADMINS     = 0x00000220

	PROC_ERROR_NO_SUCH_LOGON_SESSION = 1312
	PROC_ERROR_PRIVILEGE_NOT_HELD    = 1314
)

Some constants from the Windows API

View Source
const (
	SVC_SC_ENUM_PROCESS_INFO = 0
	SVC_SERVICE_WIN32        = 0x00000030
	SVC_SERVICE_STATE_ALL    = 0x00000003
	SVC_SERVICE_ACCEPT_STOP  = 0x00000001
)
View Source
const (
	NET_API_STATUS_NERR_Success                      = 0
	NET_API_STATUS_NERR_InvalidComputer              = 2351
	NET_API_STATUS_NERR_NotPrimary                   = 2226
	NET_API_STATUS_NERR_SpeGroupOp                   = 2234
	NET_API_STATUS_NERR_LastAdmin                    = 2452
	NET_API_STATUS_NERR_BadPassword                  = 2203
	NET_API_STATUS_NERR_PasswordTooShort             = 2245
	NET_API_STATUS_NERR_UserNotFound                 = 2221
	NET_API_STATUS_ERROR_ACCESS_DENIED               = 5
	NET_API_STATUS_ERROR_NOT_ENOUGH_MEMORY           = 8
	NET_API_STATUS_ERROR_INVALID_PARAMETER           = 87
	NET_API_STATUS_ERROR_INVALID_NAME                = 123
	NET_API_STATUS_ERROR_INVALID_LEVEL               = 124
	NET_API_STATUS_ERROR_MORE_DATA                   = 234
	NET_API_STATUS_ERROR_SESSION_CREDENTIAL_CONFLICT = 1219
	NET_API_STATUS_RPC_S_SERVER_UNAVAILABLE          = 2147944122
	NET_API_STATUS_RPC_E_REMOTE_DISABLED             = 2147549468

	USER_PRIV_MASK  = 0x3
	USER_PRIV_GUEST = 0
	USER_PRIV_USER  = 1
	USER_PRIV_ADMIN = 2

	USER_FILTER_NORMAL_ACCOUNT = 0x0002
	USER_MAX_PREFERRED_LENGTH  = 0xFFFFFFFF

	USER_UF_SCRIPT             = 1
	USER_UF_ACCOUNTDISABLE     = 2
	USER_UF_LOCKOUT            = 16
	USER_UF_PASSWD_CANT_CHANGE = 64
	USER_UF_NORMAL_ACCOUNT     = 512
	USER_UF_DONT_EXPIRE_PASSWD = 65536
)
View Source
const (
	ERROR_INVALID_FUNCTION = 1
)

Variables

This section is empty.

Functions

func AddGroupMembership

func AddGroupMembership(username, groupname string) (bool, error)

AddGroupMembership adds the user as a member of the specified group.

func BackupBitLockerRecoveryKeys

func BackupBitLockerRecoveryKeys(persistentVolumeIDs []string) error

BackupBitLockerRecoveryKeys backups up volume recovery information to Active Directory. Requires one or more PersistentVolumeIDs, available from GetBitLockerRecoveryInfo.

Ref: https://docs.microsoft.com/en-us/windows/win32/secprov/backuprecoveryinformationtoactivedirectory-win32-encryptablevolume

func ChangePassword

func ChangePassword(username string, password string) (bool, error)

ChangePassword changes the user's password.

func ConvertRawSidToStringSid

func ConvertRawSidToStringSid(rawSid []byte) (string, error)

ConvertRawSidToStringSid converts a buffer containing a raw _SID struct (like what is returned by GetRawSidForAccountName) into a string SID.

See: https://docs.microsoft.com/en-us/windows/desktop/api/sddl/nf-sddl-convertsidtostringsidw

func ConvertWMITime

func ConvertWMITime(s string) (time.Time, error)

func DomainUserLocked

func DomainUserLocked(username string, domain string) (bool, error)

func FirewallDisable

func FirewallDisable(profile int32) (bool, error)

FirewallDisable disables firewall for given profile. If firewall is disabled already for profile it will return false.

func FirewallEnable

func FirewallEnable(profile int32) (bool, error)

FirewallEnable enables firewall for given profile. If firewall is enabled already for profile it will return false.

func FirewallGroupDisable

func FirewallGroupDisable(name string, profile int32) error

FirewallGroupDisable disables given group in given profiles. The same rules as for FirewallGroupEnable applies.

func FirewallGroupEnable

func FirewallGroupEnable(name string, profile int32) error

FirewallGroupEnable allows to enable predefined firewall group. It is better to not use names as "File and Printer Sharing" because they are localized and your function will do not work on non-english Windows. Look at FILE_AND_PRINTER_SHARING const as example. This codes can be found here: https://windows10dll.nirsoft.net/firewallapi_dll.html

You can enable group in selected FW profiles or in current, use something like:

NET_FW_PROFILE2_DOMAIN|NET_FW_PROFILE2_PRIVATE

to enable group in given profiles.

func FirewallIsEnabled

func FirewallIsEnabled(profile int32) (bool, error)

FirewallIsEnabled returns true if firewall is enabled for given profile. You can use all NET_FW_PROFILE2* constants but NET_FW_PROFILE2_ALL. It will return error if Firewall status can not be checked.

func FirewallPingEnable

func FirewallPingEnable(name, description, group, remoteAddresses string, profile int32) (bool, error)

FirewallPingEnable creates Inbound ICMPv4 rule which allows to answer echo requests.

Rule Name is mandatory and must not contain the "|" character.

Description and Group are optional. Description also can not contain the "|" character.

RemoteAddresses allows you to limit pinging to f.e.:

"10.10.10.0/24"

This will be internally converted to:

"10.10.10.0/255.255.255.0"

Profile will decide in which profiles rule will apply. You can use:

NET_FW_PROFILE2_CURRENT // adds rule to currently used FW Profile
NET_FW_PROFILE2_ALL // adds rule to all profiles
NET_FW_PROFILE2_DOMAIN|NET_FW_PROFILE2_PRIVATE // rule in Private and Domain profile
Example
if _, err := FirewallPingEnable("Allow ping", "Start answering echo requests", "", "", NET_FW_PROFILE2_DOMAIN); err != nil {
	fmt.Println(err)
}
// To disable, delete the rule
if _, err := FirewallRuleDelete("Allow ping"); err != nil {
	fmt.Println(err)
}
FirewallRuleDelete("Allow ping") // check error!
Output:

func FirewallRuleAdd

func FirewallRuleAdd(name, description, group, ports string, protocol, profile int32) (bool, error)

FirewallRuleAdd creates Inbound rule for given port or ports.

Rule Name is mandatory and must not contain the "|" character.

Description and Group are optional. Description also can not contain the "|" character.

Port(-s) is mandatory. Ports string can look like:

"5800, 5900, 6810-6812"

Protocol will usually be:

NET_FW_IP_PROTOCOL_TCP
// or
NET_FW_IP_PROTOCOL_UDP

Profile will decide in which profiles rule will apply. You can use:

NET_FW_PROFILE2_CURRENT // adds rule to currently used FW Profile(-s)
NET_FW_PROFILE2_ALL // adds rule to all profiles
NET_FW_PROFILE2_DOMAIN|NET_FW_PROFILE2_PRIVATE // rule in Private and Domain profile
Example
ok, err := FirewallRuleAdd("SQL Server", "Main static SQL Server port 1433", "SQL services", "1433",
	NET_FW_IP_PROTOCOL_TCP, NET_FW_PROFILE2_DOMAIN|NET_FW_PROFILE2_PRIVATE)
if ok {
	fmt.Println("Firewall rule created!")
} else {
	if err != nil {
		fmt.Printf("can't enable SQL Server remote access, err: %s\n", err)
	} else {
		fmt.Println("rule already exists")
	}
}
Output:

func FirewallRuleAddAdvanced

func FirewallRuleAddAdvanced(rule FWRule) (bool, error)

FirewallRuleAddAdvanced allows to modify almost all available FW Rule parameters. You probably do not want to use this, as function allows to create any rule, even opening all ports in given profile. So use with caution.

HINT: Use FirewallRulesGet to get examples how rules can be defined.

Example (IPv6Ping)
if !isAdmin() {
	fmt.Println("elevated shell is required!")
}
r := FWRule{
	Name:              "Allow IPv6 ping",
	Description:       "My rule",
	Grouping:          "My group",
	Enabled:           true,
	Protocol:          NET_FW_IP_PROTOCOL_ICMPv6,
	ICMPTypesAndCodes: "128:*", // https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml
}

// Enable IPv6 ping
ok, err := FirewallRuleAddAdvanced(r)
if !ok {
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("FW rule with name %q already exists.\n", r.Name)
	}
}
if ok {
	fmt.Println("Rule added!")
}
Output:

Example (RestrictedLocalPorts)
if !isAdmin() {
	fmt.Println("elevated shell is required!")
}
r := FWRule{
	Name:            "Application rule enabling incoming connections only on port 1234",
	Description:     "This is the same rule as created with FirewallRuleCreate",
	Grouping:        "My group",
	Enabled:         true,
	Protocol:        NET_FW_IP_PROTOCOL_TCP,
	LocalPorts:      "1234",
	ApplicationName: `C:\Test\myApp`,
	Profiles:        NET_FW_PROFILE2_PRIVATE | NET_FW_PROFILE2_DOMAIN, // let's enable it in 2 profiles
}

// Enable app rule restricted to port 1234 TCP
ok, err := FirewallRuleAddAdvanced(r)
if !ok {
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("FW rule with name %q already exists.\n", r.Name)
	}
}
if ok {
	fmt.Println("Rule added!")
}
FirewallRuleDelete("Application rule enabling incoming connections only on port 1234") // check error!
Output:

Rule added!
Example (ServiceRule)
if !isAdmin() {
	fmt.Println("elevated shell is required!")
}
r := FWRule{
	Name:        "All all connection to SQL Server Browser service",
	Description: "This is rule created for specific service",
	Grouping:    "My group",
	Enabled:     true,
	Protocol:    NET_FW_IP_PROTOCOL_ANY,
	ServiceName: "SQLBrowser",
	Profiles:    NET_FW_PROFILE2_CURRENT, // let's enable it in currently used profiles
}

// Enable service rule
ok, err := FirewallRuleAddAdvanced(r)
if !ok {
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("FW rule with name %q already exists.\n", r.Name)
	}
}
if ok {
	fmt.Println("Rule added!")
}
FirewallRuleDelete("All all connection to SQL Server Browser service") // check error!
Output:

Rule added!

func FirewallRuleAddApplication

func FirewallRuleAddApplication(name, description, group, appPath string, profile int32) (bool, error)

FirewallRuleAddApplication creates Inbound rule for given application.

Rule Name is mandatory and must not contain the "|" character.

Description and Group are optional. Description also can not contain the "|" character.

AppPath is mandatory. AppPath string should look like:

`%ProgramFiles% (x86)\RemoteControl\winvnc.exe`

Protocol will usually be:

NET_FW_IP_PROTOCOL_TCP
// or
NET_FW_IP_PROTOCOL_UDP

Profile will decide in which profiles rule will apply. You can use:

NET_FW_PROFILE2_CURRENT // adds rule to currently used FW Profile
NET_FW_PROFILE2_ALL // adds rule to all profiles
NET_FW_PROFILE2_DOMAIN|NET_FW_PROFILE2_PRIVATE // rule in Private and Domain profile
Example
_, err := FirewallRuleAddApplication("SQL Browser App", "App rule for SQL Browser", "SQL Services",
	`%ProgramFiles% (x86)\Microsoft SQL Server\90\Shared\sqlbrowser.exe`, NET_FW_PROFILE2_CURRENT)
if err != nil {
	log.Fatalln(err)
}
FirewallRuleDelete("SQL Browser App") // check error!
Output:

func FirewallRuleCreate

func FirewallRuleCreate(name, description, group, appPath, port string, protocol int32) (bool, error)

FirewallRuleCreate is deprecated, use FirewallRuleAddApplication instead.

func FirewallRuleDelete

func FirewallRuleDelete(name string) (bool, error)

FirewallRuleDelete allows you to delete existing rule by name. If multiple rules with the same name exists, first (random?) is deleted. You can run this function in loop if You want to remove all of them:

var err error
for {
    if ok, err := wapi.FirewallRuleDelete("anydesk.exe"); !ok || err != nil {
        break
    }
 }
 if err != nil {
     fmt.Println(err)
 }

func FirewallRuleExistsByName

func FirewallRuleExistsByName(rules *ole.IDispatch, name string) (bool, error)

func GetBitLockerConversionStatus

func GetBitLockerConversionStatus() ([]*so.BitLockerConversionStatus, error)

GetBitLockerConversionStatus returns the Bitlocker conversion status for all local drives.

func GetBitLockerConversionStatusForDrive

func GetBitLockerConversionStatusForDrive(driveLetter string) (*so.BitLockerConversionStatus, error)

GetBitLockerConversionStatusForDrive returns the Bitlocker conversion status for a specific drive.

func GetBitLockerRecoveryInfo

func GetBitLockerRecoveryInfo() ([]*so.BitLockerDeviceInfo, error)

GetBitLockerRecoveryInfo returns the Bitlocker device info for all local drives.

func GetBitLockerRecoveryInfoForDrive

func GetBitLockerRecoveryInfoForDrive(driveLetter string) (*so.BitLockerDeviceInfo, error)

GetBitLockerRecoveryInfoForDrive returns the Bitlocker device info for a specific drive.

func GetDefaultUserProfileDirectory

func GetDefaultUserProfileDirectory() (string, error)

GetDefaultUserProfileDirectory returns the path to the directory in which the default user's profile is stored.

See: https://docs.microsoft.com/en-us/windows/desktop/api/userenv/nf-userenv-getdefaultuserprofiledirectoryw

func GetProfilesDirectory

func GetProfilesDirectory() (string, error)

GetProfilesDirectory returns the path to the directory in which user profiles are stored. Profiles for new users are stored in subdirectories.

See: https://docs.microsoft.com/en-us/windows/desktop/api/userenv/nf-userenv-getprofilesdirectoryw

func GetRawSidForAccountName

func GetRawSidForAccountName(accountName string) ([]byte, error)

GetRawSidForAccountName looks up the SID for a given account name using the LookupAccountNameW system call. The SID is returned as a buffer containing the raw _SID struct.

See: https://docs.microsoft.com/en-us/windows/desktop/api/winbase/nf-winbase-lookupaccountnamew

func GetServices

func GetServices() ([]so.Service, error)

func GetSoftwareList

func GetSoftwareList(baseKey string, arch string) ([]so.Software, error)

func GetSystemProfile

func GetSystemProfile() (so.Hardware, so.OperatingSystem, so.Memory, []so.Disk, []so.Network, error)

func InstalledSoftwareList

func InstalledSoftwareList() ([]so.Software, error)

func IsDomainUserAdmin

func IsDomainUserAdmin(username string, domain string) (bool, error)

IsDomainUserAdmin returns whether the specified user is an administrator for the specified domain.

func IsLocalUserAdmin

func IsLocalUserAdmin(username string) (bool, error)

IsLocalUserAdmin returns whether the user with the specified user name has administration rights on the local machine.

func ListLocalGroups

func ListLocalGroups() ([]so.LocalGroup, error)

ListLocalGroups enumerates the local groups defined on the system.

If an error occurs in the call to the underlying NetLocalGroupEnum function, the returned error will be a syscall.Errno containing the error code. See: https://docs.microsoft.com/en-us/windows/desktop/api/lmaccess/nf-lmaccess-netlocalgroupenum

func ListLocalUsers

func ListLocalUsers() ([]so.LocalUser, error)

ListLocalUsers lists information about local user accounts.

func ListLoggedInUsers

func ListLoggedInUsers() ([]so.SessionDetails, error)

func LocalGroupAdd

func LocalGroupAdd(name, comment string) (bool, error)

LocalGroupAdd adds a new local group with the specified name and comment.

func LocalGroupAddMembers

func LocalGroupAddMembers(groupname string, usernames []string) (bool, error)

LocalGroupAddMembers adds the specified members to the group, if they are not already members.

If an error occurs in the call to the underlying NetLocalGroupAddMembers function, the returned error will be a syscall.Errno containing the error code. See: https://docs.microsoft.com/en-us/windows/desktop/api/lmaccess/nf-lmaccess-netlocalgroupaddmembers

func LocalGroupDel

func LocalGroupDel(name string) (bool, error)

LocalGroupDel deletes the specified local group.

If an error occurs in the call to the underlying NetLocalGroupDel function, the returned error will be a syscall.Errno containing the error code. See: https://docs.microsoft.com/en-us/windows/desktop/api/lmaccess/nf-lmaccess-netlocalgroupdel

func LocalGroupDelMembers

func LocalGroupDelMembers(groupname string, usernames []string) (bool, error)

LocalGroupDelMembers removes the specified members from the local group.

If an error occurs in the call to the underlying NetLocalGroupDelMembers function, the returned error will be a syscall.Errno containing the error code. See: https://docs.microsoft.com/en-us/windows/desktop/api/lmaccess/nf-lmaccess-netlocalgroupdelmembers

func LocalGroupGetMembers

func LocalGroupGetMembers(groupname string) ([]so.LocalGroupMember, error)

LocalGroupGetMembers returns information about the members of the specified local group.

If an error occurs in the call to the underlying NetLocalGroupGetMembers function, the returned error will be a syscall.Errno containing the error code. See: https://docs.microsoft.com/en-us/windows/desktop/api/lmaccess/nf-lmaccess-netlocalgroupgetmembers

func LocalGroupSetMembers

func LocalGroupSetMembers(groupname string, usernames []string) (bool, error)

LocalGroupSetMembers sets the membership of the group to contain exactly the set of users specified in usernames.

If an error occurs in the call to the underlying NetLocalGroupSetMembers function, the returned error will be a syscall.Errno containing the error code. See: https://docs.microsoft.com/en-us/windows/desktop/api/lmaccess/nf-lmaccess-netlocalgroupsetmembers

func LsatoString

func LsatoString(p LSA_UNICODE_STRING) string

func ParseIPv4Mask

func ParseIPv4Mask(s string) net.IPMask

func ProcessKill

func ProcessKill(pid uint32) (bool, error)

func ProcessLUIDList

func ProcessLUIDList() (map[uint32]SessionLUID, error)

func ProcessList

func ProcessList() ([]so.Process, error)

func RemoveGroupMembership

func RemoveGroupMembership(username, groupname string) (bool, error)

RemoveGroupMembership removes the user from the specified group.

func RevokeAdmin

func RevokeAdmin(username string) (bool, error)

RevokeAdmin removes the user from the "Administrators" group.

func SetAdmin

func SetAdmin(username string) (bool, error)

SetAdmin adds the user to the "Administrators" group.

func SetThreadExecutionState

func SetThreadExecutionState(state uint32) (uint32, error)

func StartService

func StartService(name string) error

func StopService

func StopService(name string) error

func UTF16toString

func UTF16toString(p *uint16) string

UTF16toString converts a pointer to a UTF16 string into a Go string.

func UpdatesPending

func UpdatesPending() (*so.WindowsUpdate, error)

func UserAdd

func UserAdd(username string, fullname string, password string) (bool, error)

UserAdd creates a new user account with the given username, full name, and password. The new account will have the standard User privilege level.

func UserAddEx

func UserAddEx(opts UserAddOptions) (bool, error)

UserAddEx creates a new user account. As opposed to the simpler UserAdd, UserAddEx allows specification of full level 1 information while creating a user.

func UserDelete

func UserDelete(username string) (bool, error)

UserDelete deletes the user with the given username.

func UserDisablePasswordChange

func UserDisablePasswordChange(username string, disabled bool) (bool, error)

UserDisablePasswordChange adds or removes the flag that determines whether the user is allowed to change their own password. If disabled is true, the user will be unable to change their own password. If disabled is false, the user will be allowed to change their own password.

func UserDisabled

func UserDisabled(username string, disable bool) (bool, error)

UserDisabled adds or removes the flag that disables a user's account, preventing them from logging in. If disable is true, the user's account is disabled. If disable is false, the user's account is enabled.

func UserPasswordNoExpires

func UserPasswordNoExpires(username string, noexpire bool) (bool, error)

UserPasswordNoExpires adds or removes the flag that determines whether the user's password expires. If noexpire is true, the user's password will not expire. If noexpire is false, the user's password will expire according to the system's password policy.

func UserSetProfile

func UserSetProfile(username string, path string) (bool, error)

UserSetProfile sets the profile path for the user to path.

func UserUpdateFullname

func UserUpdateFullname(username string, fullname string) (bool, error)

UserUpdateFullName changes the full name attached to the user's account.

Types

type ENUM_SERVICE_STATUS_PROCESS

type ENUM_SERVICE_STATUS_PROCESS struct {
	ServiceStatusProcess SERVICE_STATUS_PROCESS
	// contains filtered or unexported fields
}

type FWProfiles

type FWProfiles struct {
	Domain, Private, Public bool
}

FWProfiles represents currently active Firewall profile(-s).

func FirewallCurrentProfiles

func FirewallCurrentProfiles() (FWProfiles, error)

FirewallCurrentProfiles return which profiles are currently active. Every active interface can have it's own profile. F.e.: Public for Wifi, Domain for VPN, and Private for LAN. All at the same time.

type FWRule

type FWRule struct {
	Name, Description, ApplicationName, ServiceName string
	LocalPorts, RemotePorts                         string
	// LocalAddresses, RemoteAddresses are always returned with netmask, f.e.:
	//   `10.10.1.1/255.255.255.0`
	LocalAddresses, RemoteAddresses string
	// ICMPTypesAndCodes is string. You can find define multiple codes separated by ":" (colon).
	// Types are listed here:
	// https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml
	// So to allow ping set it to:
	//   "0"
	ICMPTypesAndCodes string
	Grouping          string
	// InterfaceTypes can be:
	//   "LAN", "Wireless", "RemoteAccess", "All"
	// You can add multiple deviding with comma:
	//   "LAN, Wireless"
	InterfaceTypes                        string
	Protocol, Direction, Action, Profiles int32
	Enabled, EdgeTraversal                bool
}

FWRule represents Firewall Rule.

func FirewallRuleGet

func FirewallRuleGet(name string) (FWRule, error)

FirewallRuleGet returns firewall rule by given name. Error is returned if there is problem calling API.

If rule is not found, no error is returned, so check:

if len(returnedRule) == 0 {
    if err != nil {
        fmt.Println(err)
    } else {
        fmt.Println("rule not found")
    }
}

func FirewallRulesGet

func FirewallRulesGet() ([]FWRule, error)

FirewallRulesGet returns all rules defined in firewall.

Example (OnlyEnabledInPrivateProfile)
// let's get rules which are active in given profile
rr, err := FirewallRulesGet()
if err != nil {
	panic(err) // panic used only for brevity
}
for _, r := range rr {
	if r.Profiles&NET_FW_PROFILE2_PRIVATE != 0 && r.Enabled {
		fmt.Println(r.Name)
	}
}
Output:

func (*FWRule) InProfiles

func (r *FWRule) InProfiles() FWProfiles

InProfiles returns FWProfiles struct, so You can check in which Profiles rule is active.

As alternative You can analyze FWRule.Profile value.

type LOCALGROUP_INFO_0

type LOCALGROUP_INFO_0 struct {
	Lgrpi0_name *uint16 // UTF-16 group name
}

LOCALGROUP_INFO_0 represents level 0 information about local Windows groups. This struct matches the struct definition in the Windows headers (lmaccess.h).

type LOCALGROUP_INFO_1

type LOCALGROUP_INFO_1 struct {
	Lgrpi1_name    *uint16 // UTF-16 group name
	Lgrpi1_comment *uint16 // UTF-16 group comment
}

LOCALGROUP_INFO_1 represents level 1 information about local Windows groups. This struct matches the struct definition in the Windows headers (lmaccess.h).

type LOCALGROUP_MEMBERS_INFO_3

type LOCALGROUP_MEMBERS_INFO_3 struct {
	Lgrmi3_domainandname *uint16
}

type LSA_UNICODE_STRING

type LSA_UNICODE_STRING struct {
	Length        uint16
	MaximumLength uint16
	// contains filtered or unexported fields
}

type LUID

type LUID struct {
	LowPart  uint32
	HighPart int32
}

type LUID_AND_ATTRIBUTES

type LUID_AND_ATTRIBUTES struct {
	LUID       LUID
	Attributes uint32
}

type PROCESSENTRY32

type PROCESSENTRY32 struct {
	Size              uint32
	CntUsage          uint32
	ProcessID         uint32
	DefaultHeapID     uintptr
	ModuleID          uint32
	CntThreads        uint32
	ParentProcessID   uint32
	PriorityClassBase int32
	Flags             uint32
	ExeFile           [MAX_PATH]uint16
}

PROCESSENTRY32 is the Windows API structure that contains a process's information.

type PSID

type PSID uintptr

type SECURITY_LOGON_SESSION_DATA

type SECURITY_LOGON_SESSION_DATA struct {
	Size                  uint32
	LogonId               LUID
	UserName              LSA_UNICODE_STRING
	LogonDomain           LSA_UNICODE_STRING
	AuthenticationPackage LSA_UNICODE_STRING
	LogonType             uint32
	Session               uint32
	Sid                   uintptr
	LogonTime             uint64
	LogonServer           LSA_UNICODE_STRING
	DnsDomainName         LSA_UNICODE_STRING
	Upn                   LSA_UNICODE_STRING
}

type SERVICE_STATUS_PROCESS

type SERVICE_STATUS_PROCESS struct {
	// contains filtered or unexported fields
}

type SID_AND_ATTRIBUTES

type SID_AND_ATTRIBUTES struct {
	Sid        uintptr
	Attributes uint32
}

type SID_IDENTIFIER_AUTHORITY

type SID_IDENTIFIER_AUTHORITY struct {
	Value [6]byte
}

type SessionLUID

type SessionLUID struct {
	Value   LUID
	IsAdmin bool
}

type TOKEN_PRIVILEGES

type TOKEN_PRIVILEGES struct {
	PrivilegeCount uint32
	Privileges     [1]LUID_AND_ATTRIBUTES
}

type TOKEN_STATISTICS

type TOKEN_STATISTICS struct {
	TokenId            LUID
	AuthenticationId   LUID
	ExpirationTime     uint64
	TokenType          uint32
	ImpersonationLevel uint32
	DynamicCharged     uint32
	DynamicAvailable   uint32
	GroupCount         uint32
	PrivilegeCount     uint32
	ModifiedId         LUID
}

type TOKEN_USER

type TOKEN_USER struct {
	User SID_AND_ATTRIBUTES
}

type USER_INFO_1

type USER_INFO_1 struct {
	Usri1_name         *uint16
	Usri1_password     *uint16
	Usri1_password_age uint32
	Usri1_priv         uint32
	Usri1_home_dir     *uint16
	Usri1_comment      *uint16
	Usri1_flags        uint32
	Usri1_script_path  *uint16
}

type USER_INFO_1003

type USER_INFO_1003 struct {
	Usri1003_password *uint16
}

type USER_INFO_1008

type USER_INFO_1008 struct {
	Usri1008_flags uint32
}

type USER_INFO_1011

type USER_INFO_1011 struct {
	Usri1011_full_name *uint16
}

type USER_INFO_1052

type USER_INFO_1052 struct {
	Useri1052_profile *uint16
}

USER_INFO_1052 is the Go representation of the Windwos _USER_INFO_1052 struct used to set a user's profile directory.

See: https://docs.microsoft.com/en-us/windows/desktop/api/lmaccess/ns-lmaccess-_user_info_1052

type USER_INFO_2

type USER_INFO_2 struct {
	Usri2_name           *uint16
	Usri2_password       *uint16
	Usri2_password_age   uint32
	Usri2_priv           uint32
	Usri2_home_dir       *uint16
	Usri2_comment        *uint16
	Usri2_flags          uint32
	Usri2_script_path    *uint16
	Usri2_auth_flags     uint32
	Usri2_full_name      *uint16
	Usri2_usr_comment    *uint16
	Usri2_parms          *uint16
	Usri2_workstations   *uint16
	Usri2_last_logon     uint32
	Usri2_last_logoff    uint32
	Usri2_acct_expires   uint32
	Usri2_max_storage    uint32
	Usri2_units_per_week uint32
	Usri2_logon_hours    uintptr
	Usri2_bad_pw_count   uint32
	Usri2_num_logons     uint32
	Usri2_logon_server   *uint16
	Usri2_country_code   uint32
	Usri2_code_page      uint32
}

type UserAddOptions

type UserAddOptions struct {
	// Required
	Username string
	Password string

	// Optional
	FullName   string
	PrivLevel  uint32
	HomeDir    string
	Comment    string
	ScriptPath string
}

UserAddOptions contains extended options for creating a new user account.

The only required fields are Username and Password.

Fields:

  • Username account username, limited to 20 characters.
  • Password account password
  • FullName user's full name (default: none)
  • PrivLevel account's prvilege level, must be one of the USER_PRIV_* constants (default: USER_PRIV_GUEST)
  • HomeDir If non-empty, the user's home directory is set to the specified path.
  • Comment A comment to associate with the account (default: none)
  • ScriptPath If non-empty, the path to the user's logon script file, which can be a .CMD, .EXE, or .BAT file. (default: none)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL