39 Account( SID_NAME_USE ,
const std::string & ,
const std::string & ,
const std::string & ) ;
40 SID_NAME_USE type {SidTypeInvalid} ;
44 bool valid() const noexcept {
return type == SidTypeUser ; }
47 std::string rootsid() ;
48 std::string sidstr( PSID sid_p ) ;
49 std::string computername() ;
50 Account lookup(
const std::string & name ,
bool =
false ) ;
65 static_assert(
noexcept(std::string()) ,
"" ) ;
76 auto account = IdentityImp::lookup( name ) ;
77 if( !account.valid() )
78 throw NoSuchUser( name ) ;
84 return { -1 , -1 , IdentityImp::sid() } ;
104 Identity id(
"Administrator" ) ;
105 if(
id != invalid() )
107 return { -1 , -1 , IdentityImp::rootsid() } ;
117 if( m_sid.empty() )
return false ;
130 std::string(
"S-1-0-0") :
141 return m_sid == other.m_sid ;
146 return m_sid != other.m_sid ;
151 auto account = IdentityImp::lookup( name ,
true ) ;
152 if( !account.valid() )
153 throw NoSuchUser( name ) ;
156 id.m_sid = account.sid ;
157 return std::make_pair(
id , account.name ) ;
160std::pair<G::Identity,std::string>
G::Identity::lookup(
const std::string & name , std::nothrow_t )
162 auto account = IdentityImp::lookup( name ,
true ) ;
163 if( account.valid() )
166 id.m_sid = account.sid ;
167 return std::make_pair(
id , account.name ) ;
171 return std::make_pair( Identity() , std::string() ) ;
182 return G::Range::within( range , userid() ) ;
187std::string G::IdentityImp::sidstr( PSID sid_p )
189 char * sidstr_p = nullptr ;
190 if( !ConvertSidToStringSidA( sid_p , &sidstr_p ) || sidstr_p ==
nullptr )
192 std::string result( sidstr_p ) ;
193 LocalFree( sidstr_p ) ;
197std::string G::IdentityImp::sid()
199 HANDLE htoken = NULL ;
200 if( !OpenProcessToken( GetCurrentProcess() , TOKEN_QUERY , &htoken ) )
202 G::ScopeExit close( [htoken](){CloseHandle(htoken);} ) ;
205 if( !GetTokenInformation( htoken , TokenUser , &buffer[0] ,
static_cast<DWORD
>(buffer.size()) , &size ) && size )
206 buffer.resize(
static_cast<std::size_t
>(size) ) ;
207 if( !GetTokenInformation( htoken , TokenUser , &buffer[0] ,
static_cast<DWORD
>(buffer.size()) , &size ) )
209 TOKEN_USER * info_p = G::buffer_cast<TOKEN_USER*>( buffer ) ;
210 return sidstr( info_p->User.Sid ) ;
214std::string G::IdentityImp::username()
216 std::vector<char> buffer ;
217 buffer.reserve( 100U ) ;
218 buffer.resize( 1U ) ;
219 DWORD size =
static_cast<DWORD
>( buffer.size() ) ;
220 if( !GetUserNameA( &buffer[0] , &size ) && GetLastError() == ERROR_INSUFFICIENT_BUFFER && size )
221 buffer.resize(
static_cast<std::size_t
>(size) ) ;
222 if( size == 0 || !GetUserNameA( &buffer[0] , &size ) )
224 std::size_t n = std::min( buffer.size() ,
static_cast<std::size_t
>(size) ) ;
225 buffer.at( n-1U ) =
'\0' ;
226 return std::string( &buffer[0] ) ;
230std::string G::IdentityImp::computername()
232 std::vector<char> buffer ;
233 buffer.reserve( 100U ) ;
234 buffer.resize( 1U ) ;
235 DWORD size =
static_cast<DWORD
>( buffer.size() ) ;
236 if( !GetComputerNameExA( ComputerNameNetBIOS , &buffer[0] , &size ) && GetLastError() == ERROR_MORE_DATA && size )
237 buffer.resize(
static_cast<std::size_t
>(size) ) ;
238 if( !GetComputerNameExA( ComputerNameNetBIOS , &buffer[0] , &size ) )
240 std::size_t n = std::min( buffer.size()-1U ,
static_cast<std::size_t
>(size) ) ;
241 buffer.at( n ) =
'\0' ;
242 return std::string( &buffer[0] ) ;
245G::IdentityImp::Account G::IdentityImp::lookup(
const std::string & name ,
bool with_canonical_name )
247 const Account error ;
248 if( name.empty() || name.find(
'\\') != std::string::npos )
250 std::string domain = computername() ;
253 std::string full_name = domain.append(1U,
'\\').append(name) ;
255 DWORD domainsize = 0 ;
256 SID_NAME_USE type = SidTypeInvalid ;
257 if( LookupAccountNameA( NULL , full_name.c_str() , NULL , &sidsize , NULL , &domainsize , &type ) )
260 std::vector<char> domainbuffer( std::max(DWORD(1),domainsize) ) ;
261 if( !LookupAccountNameA( NULL , full_name.c_str() , &sidbuffer[0] , &sidsize , &domainbuffer[0] , &domainsize , &type ) )
263 SID * sid_p = G::buffer_cast<SID*>(sidbuffer) ;
265 std::string canonical_name ;
266 if( with_canonical_name )
268 DWORD namebuffersize = 0 ;
269 DWORD domainbuffersize = 0 ;
270 if( LookupAccountSidA( NULL , sid_p , NULL , &namebuffersize , NULL , &domainbuffersize , &type ) )
272 std::vector<char> namebuffer( std::max(DWORD(1),namebuffersize) ) ;
273 std::vector<char> domainbuffer2( std::max(DWORD(1),domainbuffersize) ) ;
274 if( !LookupAccountSidA( NULL , sid_p , &namebuffer[0] , &namebuffersize , &domainbuffer2[0] , &domainbuffersize , &type ) )
276 namebuffer[namebuffer.size()-1U] =
'\0' ;
277 canonical_name = std::string( &namebuffer[0] ) ;
278 if( canonical_name.empty() )
282 return { type , sidstr(sid_p) , &domain[0] , canonical_name } ;
285std::string G::IdentityImp::rootsid()
289 WELL_KNOWN_SID_TYPE type = WinLocalAccountAndAdministratorSid ;
290 if( !CreateWellKnownSid( type , NULL , &buffer[0] , &size ) && size )
291 buffer.resize(
static_cast<std::size_t
>(size) ) ;
292 if( !CreateWellKnownSid( type , NULL , &buffer[0] , &size ) )
294 SID * sid_p = G::buffer_cast<SID*>( buffer ) ;
295 return sidstr( sid_p ) ;
298G::IdentityImp::Account::Account( SID_NAME_USE type_ ,
const std::string & sid_ ,
299 const std::string & domain_ ,
const std::string & name_ ) :
A combination of user-id and group-id, with a very low-level interface to the get/set/e/uid/gid funct...
gid_t groupid() const noexcept
Returns the group part (Unix).
std::string sid() const
Returns the sid (Windows).
bool isRoot() const noexcept
Returns true if the userid is zero.
uid_t userid() const noexcept
Returns the user part (Unix).
static Identity invalid() noexcept
Returns an invalid identity.
bool operator==(const Identity &) const noexcept
Comparison operator.
bool match(std::pair< int, int > uid_range) const
Returns true if the user-id is in the given range or if not implemented.
static Identity root() noexcept
Returns the superuser identity.
static gid_t lookupGroup(const std::string &group)
Does a groupname lookup.
std::string str() const
Returns a string representation.
static Identity effective() noexcept
Returns the current effective identity.
bool operator!=(const Identity &) const noexcept
Comparison operator.
static std::pair< Identity, std::string > lookup(const std::string &user)
Does a username lookup returning the identity and the canonical name.
Identity(const std::string &username, const std::string &group_name_override={})
Constructor for the named identity.
static Identity real() noexcept
Returns the calling process's real identity.
A class that calls an exit function at the end of its scope.
static int toInt(string_view s)
Converts string 's' to an int.
static bool tailMatch(const std::string &in, string_view ending) noexcept
Returns true if the string has the given ending (or the given ending is empty).
static std::string tail(string_view in, std::size_t pos, string_view default_={})
Returns the last part of the string after the given position.
static bool headMatch(const std::string &in, string_view head) noexcept
Returns true if the string has the given start (or head is empty).
A substitute for std::vector<char> that has more useful alignment guarantees and explicitly avoids de...