00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00039 #include "blocxx/BLOCXX_config.h"
00040 #include "blocxx/Mutex.hpp"
00041 #include "blocxx/MutexLock.hpp"
00042 #include "blocxx/GlobalMutex.hpp"
00043 #include "blocxx/UserUtils.hpp"
00044
00045 #ifdef BLOCXX_HAVE_UNISTD_H
00046 #include <unistd.h>
00047 #endif
00048
00049 #ifdef BLOCXX_HAVE_SYS_TYPES_H
00050 #include <sys/types.h>
00051 #endif
00052
00053 #ifdef BLOCXX_HAVE_PWD_H
00054 #include <pwd.h>
00055 #endif
00056
00057 #include <cerrno>
00058 #include <vector>
00059
00060 #ifdef BLOCXX_WIN32
00061
00062 BLOCXX_NAMESPACE::UserId geteuid(void )
00063 {
00064
00065 BLOCXX_NAMESPACE::UserId sid = (BLOCXX_NAMESPACE::UserId)NULL;
00066 HANDLE pToken = (HANDLE)0L;
00067 DWORD bufLength = 256;
00068 static int* tkUser[256];
00069
00070 if ( ::OpenProcessToken(::GetCurrentProcess(), TOKEN_QUERY, &pToken) )
00071 {
00072 ::GetTokenInformation(pToken, TokenUser, tkUser, bufLength, &bufLength);
00073 sid = ((TOKEN_USER*)tkUser)->User.Sid;
00074 TCHAR sName[MAX_PATH], sDName[MAX_PATH];
00075 DWORD sNameLen, sDNameLen = sNameLen = MAX_PATH;
00076 SID_NAME_USE eUse;
00077 ::LookupAccountSid( NULL, sid, sName, &sNameLen, sDName, &sDNameLen, &eUse);
00078 CloseHandle(pToken);
00079 }
00080 return sid;
00081 }
00082 #endif //BLOCXX_WIN32
00083
00084 namespace BLOCXX_NAMESPACE
00085 {
00086
00087 namespace UserUtils
00088 {
00089
00091 String getEffectiveUserId()
00092 {
00093 #ifdef BLOCXX_WIN32
00094
00095
00096
00097
00098
00099
00100
00101 PSID_IDENTIFIER_AUTHORITY psia;
00102 DWORD dwSubAuthorities;
00103 DWORD dwSidRev=SID_REVISION;
00104 DWORD dwCounter;
00105 DWORD dwSidSize;
00106 UserId uid = ::geteuid();
00107 String strResult, strSubResult;
00108
00109 if (!uid || !IsValidSid(uid))
00110 return String();
00111 psia = GetSidIdentifierAuthority(uid);
00112 dwSubAuthorities = *GetSidSubAuthorityCount(uid);
00113 dwSidSize = (15 + 12 + (12 * dwSubAuthorities) + 1) * sizeof(TCHAR);
00114 if ( (psia->Value[0] != 0) || (psia->Value[1] != 0) )
00115 {
00116 strSubResult.format(
00117 TEXT("0x%02hx%02hx%02hx%02hx%02hx%02hx"),
00118 (USHORT)psia->Value[0],
00119 (USHORT)psia->Value[1],
00120 (USHORT)psia->Value[2],
00121 (USHORT)psia->Value[3],
00122 (USHORT)psia->Value[4],
00123 (USHORT)psia->Value[5]);
00124 }
00125 else
00126 {
00127 strSubResult.format(
00128 TEXT("%lu"),
00129 (ULONG)(psia->Value[5] ) +
00130 (ULONG)(psia->Value[4] << 8) +
00131 (ULONG)(psia->Value[3] << 16) +
00132 (ULONG)(psia->Value[2] << 24) );
00133 }
00134
00135 for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
00136 {
00137 strSubResult.format(
00138 TEXT("%s-%lu"), strSubResult.c_str(),
00139 *GetSidSubAuthority(uid, dwCounter) );
00140 }
00141
00142 strResult.format(TEXT("S-%lu-%s"), dwSidRev, strSubResult);
00143 return strResult;
00144 #else
00145 return String(Int64(::geteuid()));
00146 #endif
00147 }
00148
00150 String getCurrentUserName()
00151 {
00152 bool ok;
00153 #ifdef BLOCXX_WIN32
00154 return getUserName(geteuid(), ok);
00155 #else
00156 return getUserName(getuid(),ok);
00157 #endif
00158 }
00159
00160 namespace
00161 {
00162 GlobalMutex g_getpwMutex = BLOCXX_GLOBAL_MUTEX_INIT();
00163 }
00164
00165 namespace
00166 {
00167
00168 long getSysconfValue(int name, long default_value, int& error)
00169 {
00170 #ifdef BLOCXX_WIN32
00171 #pragma message(Reminder "TODO: Implement for Win if you use getSysconfValue not only for _SC_GETPW_R_SIZE_MAX")
00172 error = 0;
00173 return default_value;
00174 #else
00175 errno = 0;
00176
00177 long l = sysconf(name);
00178
00179 if( l == -1 )
00180 {
00181 if( errno == 0 )
00182 {
00183
00184 error = 0;
00185 return default_value;
00186 }
00187 else
00188 {
00189 error = errno;
00190 return default_value;
00191 }
00192 }
00193 else
00194 {
00195 error = 0;
00196 return l;
00197 }
00198 #endif
00199 }
00200
00201 long getSysconfValue(int name, long default_value)
00202 {
00203 int unused;
00204 return getSysconfValue(name, default_value, unused);
00205 }
00206 }
00207
00209 String getUserName(uid_t uid,bool& ok)
00210 {
00211 #ifdef BLOCXX_WIN32
00212
00213
00214
00215
00216
00217 TCHAR cchName[256], cchDomainName[256];
00218 SID_NAME_USE snuOutVar;
00219 DWORD cchNameBufLen = sizeof(cchName), cchDomainNameBufLen = sizeof(cchDomainName);
00220
00221 ok = ::LookupAccountSid(NULL,
00222 uid,
00223 cchName,
00224 &cchNameBufLen,
00225 cchDomainName,
00226 &cchDomainNameBufLen,
00227 &snuOutVar);
00228 return String(cchName);
00229 #else
00230
00231 #ifdef BLOCXX_HAVE_GETPWUID_R
00232 passwd pw;
00233 size_t const additionalSize =
00234 #ifdef _SC_GETPW_R_SIZE_MAX
00235 getSysconfValue(_SC_GETPW_R_SIZE_MAX, 10240);
00236 #else
00237 10240;
00238 #endif
00239 std::vector<char> additional(additionalSize);
00240 passwd* result;
00241 int rv = 0;
00242 do
00243 {
00244 rv = ::getpwuid_r(uid, &pw, &additional[0], additional.size(), &result);
00245 if (rv == ERANGE)
00246 {
00247 additional.resize(additional.size() * 2);
00248 }
00249 } while (rv == ERANGE);
00250 #else
00251 MutexLock lock(g_getpwMutex);
00252 passwd* result = ::getpwuid(uid);
00253 #endif
00254 if (result)
00255 {
00256 ok = true;
00257 return result->pw_name;
00258 }
00259 ok = false;
00260 return "";
00261 #endif
00262 }
00263
00265 UserID
00266 getUserId(const String& userName, bool& validUserName)
00267 {
00268 validUserName = false;
00269
00270 #ifdef BLOCXX_WIN32
00271
00272 static DWORD uid[64];
00273 DWORD cbUid = sizeof(uid) * sizeof(DWORD);
00274 SID_NAME_USE snuOutVar;
00275 DWORD cbDomainBufSize = MAX_PATH;
00276 TCHAR strDomainBuf[MAX_PATH] = {0};
00277
00278 return (validUserName=::LookupAccountName(
00279 NULL,
00280 userName.c_str(),
00281 &uid,
00282 &cbUid,
00283 strDomainBuf,
00284 &cbDomainBufSize,
00285 &snuOutVar))? &uid : NULL;
00286
00287 #else
00288
00289
00290 #ifdef BLOCXX_HAVE_GETPWNAM_R
00291 size_t bufsize =
00292 #ifdef _SC_GETPW_R_SIZE_MAX
00293 getSysconfValue(_SC_GETPW_R_SIZE_MAX, 10240);
00294 #else
00295 1024;
00296 #endif
00297 std::vector<char> buf(bufsize);
00298 struct passwd pwd;
00299 passwd* result = 0;
00300 int rv = 0;
00301 do
00302 {
00303 rv = ::getpwnam_r(userName.c_str(), &pwd, &buf[0], bufsize, &result);
00304 if (rv == ERANGE)
00305 {
00306 buf.resize(buf.size() * 2);
00307 }
00308 } while (rv == ERANGE);
00309
00310 if (rv != 0)
00311 {
00312 return INVALID_USERID;
00313 }
00314
00315 #else
00316 MutexLock ml(g_getpwMutex);
00317 struct passwd* result;
00318 result = ::getpwnam(userName.c_str());
00319 #endif
00320 if (result)
00321 {
00322 validUserName = true;
00323 return result->pw_uid;
00324 }
00325 return INVALID_USERID;
00326 #endif
00327 }
00328 }
00329 }
00330
00331