//go:build windows package winapi import ( "syscall" "golang.org/x/sys/windows" ) const UserNameCharLimit = 20 const ( USER_PRIV_GUEST uint32 = iota USER_PRIV_USER USER_PRIV_ADMIN ) const ( UF_NORMAL_ACCOUNT = 0x00200 UF_DONT_EXPIRE_PASSWD = 0x10000 ) const NERR_UserNotFound = syscall.Errno(0x8AD) // typedef struct _LOCALGROUP_MEMBERS_INFO_0 { // PSID lgrmi0_sid; // } LOCALGROUP_MEMBERS_INFO_0, *PLOCALGROUP_MEMBERS_INFO_0, *LPLOCALGROUP_MEMBERS_INFO_0; type LocalGroupMembersInfo0 struct { Sid *windows.SID } // typedef struct _LOCALGROUP_INFO_1 { // LPWSTR lgrpi1_name; // LPWSTR lgrpi1_comment; // } LOCALGROUP_INFO_1, *PLOCALGROUP_INFO_1, *LPLOCALGROUP_INFO_1; type LocalGroupInfo1 struct { Name *uint16 Comment *uint16 } // typedef struct _USER_INFO_1 { // LPWSTR usri1_name; // LPWSTR usri1_password; // DWORD usri1_password_age; // DWORD usri1_priv; // LPWSTR usri1_home_dir; // LPWSTR usri1_comment; // DWORD usri1_flags; // LPWSTR usri1_script_path; // } USER_INFO_1, *PUSER_INFO_1, *LPUSER_INFO_1; type UserInfo1 struct { Name *uint16 Password *uint16 PasswordAge uint32 Priv uint32 HomeDir *uint16 Comment *uint16 Flags uint32 ScriptPath *uint16 } // NET_API_STATUS NET_API_FUNCTION NetLocalGroupGetInfo( // [in] LPCWSTR servername, // [in] LPCWSTR groupname, // [in] DWORD level, // [out] LPBYTE *bufptr // ); // //sys netLocalGroupGetInfo(serverName *uint16, groupName *uint16, level uint32, bufptr **byte) (status error) = netapi32.NetLocalGroupGetInfo // NetLocalGroupGetInfo is a slightly go friendlier wrapper around the NetLocalGroupGetInfo function. Instead of taking in *uint16's, it takes in // go strings and does the conversion internally. func NetLocalGroupGetInfo(serverName, groupName string, level uint32, bufPtr **byte) (err error) { var ( serverNameUTF16 *uint16 groupNameUTF16 *uint16 ) if serverName != "" { serverNameUTF16, err = windows.UTF16PtrFromString(serverName) if err != nil { return err } } if groupName != "" { groupNameUTF16, err = windows.UTF16PtrFromString(groupName) if err != nil { return err } } return netLocalGroupGetInfo( serverNameUTF16, groupNameUTF16, level, bufPtr, ) } // NET_API_STATUS NET_API_FUNCTION NetUserAdd( // [in] LPCWSTR servername, // [in] DWORD level, // [in] LPBYTE buf, // [out] LPDWORD parm_err // ); // //sys netUserAdd(serverName *uint16, level uint32, buf *byte, parm_err *uint32) (status error) = netapi32.NetUserAdd // NetUserAdd is a slightly go friendlier wrapper around the NetUserAdd function. Instead of taking in *uint16's, it takes in // go strings and does the conversion internally. func NetUserAdd(serverName string, level uint32, buf *byte, parm_err *uint32) (err error) { var serverNameUTF16 *uint16 if serverName != "" { serverNameUTF16, err = windows.UTF16PtrFromString(serverName) if err != nil { return err } } return netUserAdd( serverNameUTF16, level, buf, parm_err, ) } // NET_API_STATUS NET_API_FUNCTION NetUserDel( // [in] LPCWSTR servername, // [in] LPCWSTR username // ); // //sys netUserDel(serverName *uint16, username *uint16) (status error) = netapi32.NetUserDel // NetUserDel is a slightly go friendlier wrapper around the NetUserDel function. Instead of taking in *uint16's, it takes in // go strings and does the conversion internally. func NetUserDel(serverName, userName string) (err error) { var ( serverNameUTF16 *uint16 userNameUTF16 *uint16 ) if serverName != "" { serverNameUTF16, err = windows.UTF16PtrFromString(serverName) if err != nil { return err } } if userName != "" { userNameUTF16, err = windows.UTF16PtrFromString(userName) if err != nil { return err } } return netUserDel( serverNameUTF16, userNameUTF16, ) } // NET_API_STATUS NET_API_FUNCTION NetLocalGroupAddMembers( // [in] LPCWSTR servername, // [in] LPCWSTR groupname, // [in] DWORD level, // [in] LPBYTE buf, // [in] DWORD totalentries // ); // //sys netLocalGroupAddMembers(serverName *uint16, groupName *uint16, level uint32, buf *byte, totalEntries uint32) (status error) = netapi32.NetLocalGroupAddMembers // NetLocalGroupAddMembers is a slightly go friendlier wrapper around the NetLocalGroupAddMembers function. Instead of taking in *uint16's, it takes in // go strings and does the conversion internally. func NetLocalGroupAddMembers(serverName, groupName string, level uint32, buf *byte, totalEntries uint32) (err error) { var ( serverNameUTF16 *uint16 groupNameUTF16 *uint16 ) if serverName != "" { serverNameUTF16, err = windows.UTF16PtrFromString(serverName) if err != nil { return err } } if groupName != "" { groupNameUTF16, err = windows.UTF16PtrFromString(groupName) if err != nil { return err } } return netLocalGroupAddMembers( serverNameUTF16, groupNameUTF16, level, buf, totalEntries, ) }