00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "kuser.h"
00022
00023 #include <QtCore/QMutableStringListIterator>
00024 #include <QtCore/QDebug>
00025 #include <QtCore/QDir>
00026
00027 #include <windows.h>
00028 #include <lm.h>
00029 #include <Sddl.h>
00030 #include <userenv.h>
00031
00032 class KUser::Private : public KShared
00033 {
00034 public:
00035 PUSER_INFO_11 userInfo;
00036 PSID sid;
00037
00038 Private() : userInfo(0), sid(0) {}
00039
00040 Private(PUSER_INFO_11 userInfo_, PSID sid_ = 0) : userInfo(userInfo_) {}
00041
00042 Private(const QString &name, PSID sid_ = 0) : userInfo(0), sid(NULL)
00043 {
00044 if (NetUserGetInfo(NULL, (LPCWSTR) name.utf16(), 11, (LPBYTE *) &userInfo) != NERR_Success)
00045 goto error;
00046
00047 if (!sid_) {
00048 DWORD size = 0;
00049 SID_NAME_USE nameuse;
00050 DWORD cchReferencedDomainName = 0;
00051 WCHAR* referencedDomainName = NULL;
00052
00053
00054
00055
00056 LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, referencedDomainName, &cchReferencedDomainName, &nameuse);
00057 sid = (PSID) new SID[size + 1];
00058 referencedDomainName = new WCHAR[cchReferencedDomainName + 1];
00059 if (!LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, referencedDomainName, &cchReferencedDomainName, &nameuse)) {
00060 delete[] referencedDomainName;
00061 goto error;
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 delete[] referencedDomainName;
00073 }
00074 else {
00075 if (!IsValidSid(sid_))
00076 goto error;
00077
00078 DWORD sidlength = GetLengthSid(sid_);
00079 sid = (PSID) new BYTE[sidlength];
00080 if (!CopySid(sidlength, sid, sid_))
00081 goto error;
00082 }
00083
00084 return;
00085
00086 error:
00087 delete[] sid;
00088 sid = 0;
00089 if (userInfo) {
00090 NetApiBufferFree(userInfo);
00091 userInfo = 0;
00092 }
00093 }
00094
00095 ~Private()
00096 {
00097 if (userInfo)
00098 NetApiBufferFree(userInfo);
00099
00100 delete[] sid;
00101 }
00102 };
00103
00104 KUser::KUser(UIDMode mode)
00105 : d(0)
00106 {
00107 Q_UNUSED(mode)
00108
00109 DWORD bufferLen = UNLEN + 1;
00110 ushort buffer[UNLEN + 1];
00111
00112 if (GetUserNameW((LPWSTR) buffer, &bufferLen))
00113 d = new Private(QString::fromUtf16(buffer));
00114 }
00115
00116 KUser::KUser(K_UID uid)
00117 : d(0)
00118 {
00119 DWORD bufferLen = UNLEN + 1;
00120 ushort buffer[UNLEN + 1];
00121 SID_NAME_USE eUse;
00122
00123 if (LookupAccountSidW(NULL, uid, (LPWSTR) buffer, &bufferLen, NULL, NULL, &eUse))
00124 d = new Private(QString::fromUtf16(buffer), uid);
00125 }
00126
00127 KUser::KUser(const QString &name)
00128 : d(new Private(name))
00129 {
00130 }
00131
00132 KUser::KUser(const char *name)
00133 :d(new Private(QString::fromLocal8Bit(name)))
00134 {
00135 }
00136
00137 KUser::KUser(const KUser &user)
00138 : d(user.d)
00139 {
00140 }
00141
00142 KUser &KUser::operator=(const KUser &user)
00143 {
00144 d = user.d;
00145 return *this;
00146 }
00147
00148 bool KUser::operator==(const KUser &user) const
00149 {
00150 if (!isValid() || !user.isValid())
00151 return false;
00152 return EqualSid(d->sid, user.d->sid);
00153 }
00154
00155 bool KUser::operator !=(const KUser &user) const
00156 {
00157 return !operator==(user);
00158 }
00159
00160 bool KUser::isValid() const
00161 {
00162 return d->userInfo != 0 && d->sid != 0;
00163 }
00164
00165 bool KUser::isSuperUser() const
00166 {
00167 return d->userInfo && d->userInfo->usri11_priv == USER_PRIV_ADMIN;
00168 }
00169
00170 QString KUser::loginName() const
00171 {
00172 return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_name) : QString());
00173 }
00174
00175 QString KUser::fullName() const
00176 {
00177 return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_full_name) : QString());
00178 }
00179
00180 QString KUser::homeDir() const
00181 {
00182 return QDir::fromNativeSeparators(qgetenv("USERPROFILE"));
00183 }
00184
00185 QString KUser::faceIconPath() const
00186 {
00187
00188 return QString();
00189 }
00190
00191 QString KUser::shell() const
00192 {
00193 return QString::fromAscii("cmd.exe");
00194 }
00195
00196 QList<KUserGroup> KUser::groups() const
00197 {
00198 QList<KUserGroup> result;
00199
00200 Q_FOREACH (const QString &name, groupNames()) {
00201 result.append(KUserGroup(name));
00202 }
00203
00204 return result;
00205 }
00206
00207 QStringList KUser::groupNames() const
00208 {
00209 QStringList result;
00210
00211 if (!d->userInfo) {
00212 return result;
00213 }
00214
00215 PGROUP_USERS_INFO_0 pGroups = NULL;
00216 DWORD dwEntriesRead = 0;
00217 DWORD dwTotalEntries = 0;
00218 NET_API_STATUS nStatus;
00219
00220 nStatus = NetUserGetGroups(NULL, d->userInfo->usri11_name, 0, (LPBYTE *) &pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries);
00221
00222 if (nStatus == NERR_Success) {
00223 for (DWORD i = 0; i < dwEntriesRead; ++i) {
00224 result.append(QString::fromUtf16((ushort *) pGroups[i].grui0_name));
00225 }
00226 }
00227
00228 if (pGroups) {
00229 NetApiBufferFree(pGroups);
00230 }
00231
00232 return result;
00233 }
00234
00235 K_UID KUser::uid() const
00236 {
00237 return d->sid;
00238 }
00239
00240 QVariant KUser::property(UserProperty which) const
00241 {
00242 if (which == FullName)
00243 return QVariant(d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_full_name) : QString());
00244
00245 return QVariant();
00246 }
00247
00248 QList<KUser> KUser::allUsers()
00249 {
00250 QList<KUser> result;
00251
00252 NET_API_STATUS nStatus;
00253 PUSER_INFO_11 pUser = NULL;
00254 DWORD dwEntriesRead = 0;
00255 DWORD dwTotalEntries = 0;
00256 DWORD dwResumeHandle = 0;
00257
00258 KUser tmp;
00259
00260 do {
00261 nStatus = NetUserEnum(NULL, 11, 0, (LPBYTE*) &pUser, 1, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
00262
00263 if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead > 0) {
00264 tmp.d = new Private(pUser);
00265 result.append(tmp);
00266 }
00267 } while (nStatus == ERROR_MORE_DATA);
00268
00269 return result;
00270 }
00271
00272 QStringList KUser::allUserNames()
00273 {
00274 QStringList result;
00275
00276 NET_API_STATUS nStatus;
00277 PUSER_INFO_0 pUsers = NULL;
00278 DWORD dwEntriesRead = 0;
00279 DWORD dwTotalEntries = 0;
00280
00281 nStatus = NetUserEnum(NULL, 0, 0, (LPBYTE*) &pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00282
00283 if (nStatus == NERR_Success) {
00284 for (DWORD i = 0; i < dwEntriesRead; ++i) {
00285 result.append(QString::fromUtf16((ushort *) pUsers[i].usri0_name));
00286 }
00287 }
00288
00289 if (pUsers) {
00290 NetApiBufferFree(pUsers);
00291 }
00292
00293 return result;
00294 }
00295
00296 KUser::~KUser()
00297 {
00298 }
00299
00300 class KUserGroup::Private : public KShared
00301 {
00302 public:
00303 PGROUP_INFO_0 groupInfo;
00304
00305 Private() : groupInfo(NULL) {}
00306 Private(PGROUP_INFO_0 groupInfo_) : groupInfo(groupInfo_) {}
00307 Private(const QString &Name) : groupInfo(NULL)
00308 {
00309 NetGroupGetInfo(NULL, (PCWSTR) Name.utf16(), 0, (PBYTE *) &groupInfo);
00310 }
00311
00312 ~Private()
00313 {
00314 if (groupInfo) {
00315 NetApiBufferFree(groupInfo);
00316 }
00317 }
00318 };
00319
00320 KUserGroup::KUserGroup(const QString &_name)
00321 : d(new Private(_name))
00322 {
00323 }
00324
00325 KUserGroup::KUserGroup(const char *_name)
00326 : d(new Private(QString(_name)))
00327 {
00328 }
00329
00330 KUserGroup::KUserGroup(const KUserGroup &group)
00331 : d(group.d)
00332 {
00333 }
00334
00335 KUserGroup& KUserGroup::operator =(const KUserGroup &group)
00336 {
00337 d = group.d;
00338 return *this;
00339 }
00340
00341 bool KUserGroup::operator==(const KUserGroup &group) const
00342 {
00343 if (d->groupInfo == NULL || group.d->groupInfo == NULL) {
00344 return false;
00345 }
00346 return wcscmp(d->groupInfo->grpi0_name, group.d->groupInfo->grpi0_name) == 0;
00347 }
00348
00349 bool KUserGroup::operator!=(const KUserGroup &group) const
00350 {
00351 return !operator==(group);
00352 }
00353
00354 bool KUserGroup::isValid() const
00355 {
00356 return d->groupInfo != NULL;
00357 }
00358
00359 QString KUserGroup::name() const
00360 {
00361 return QString::fromUtf16((ushort *) d->groupInfo->grpi0_name);
00362 }
00363
00364 QList<KUser> KUserGroup::users() const
00365 {
00366 QList<KUser> Result;
00367
00368 Q_FOREACH(const QString &user, userNames()) {
00369 Result.append(KUser(user));
00370 }
00371
00372 return Result;
00373 }
00374
00375 QStringList KUserGroup::userNames() const
00376 {
00377 QStringList result;
00378
00379 if (!d->groupInfo) {
00380 return result;
00381 }
00382
00383 PGROUP_USERS_INFO_0 pUsers = NULL;
00384 DWORD dwEntriesRead = 0;
00385 DWORD dwTotalEntries = 0;
00386 NET_API_STATUS nStatus;
00387
00388 nStatus = NetGroupGetUsers(NULL, d->groupInfo->grpi0_name, 0, (LPBYTE *) &pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00389
00390 if (nStatus == NERR_Success) {
00391 for (DWORD i = 0; i < dwEntriesRead; ++i) {
00392 result.append(QString::fromUtf16((ushort *) pUsers[i].grui0_name));
00393 }
00394 }
00395
00396 if (pUsers) {
00397 NetApiBufferFree(pUsers);
00398 }
00399
00400 return result;
00401 }
00402
00403 QList<KUserGroup> KUserGroup::allGroups()
00404 {
00405 QList<KUserGroup> result;
00406
00407 NET_API_STATUS nStatus;
00408 PGROUP_INFO_0 pGroup=NULL;
00409 DWORD dwEntriesRead=0;
00410 DWORD dwTotalEntries=0;
00411 DWORD dwResumeHandle=0;
00412
00413 KUserGroup tmp("");
00414
00415 do {
00416 nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroup, 1, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
00417
00418 if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead > 0) {
00419 tmp.d = new Private(pGroup);
00420 result.append(tmp);
00421 }
00422 } while (nStatus == ERROR_MORE_DATA);
00423
00424 return result;
00425 }
00426
00427 QStringList KUserGroup::allGroupNames()
00428 {
00429 QStringList result;
00430
00431 NET_API_STATUS nStatus;
00432 PGROUP_INFO_0 pGroups=NULL;
00433 DWORD dwEntriesRead=0;
00434 DWORD dwTotalEntries=0;
00435
00436 nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00437
00438 if (nStatus == NERR_Success) {
00439 for (DWORD i = 0; i < dwEntriesRead; ++i) {
00440 result.append(QString::fromUtf16((ushort *) pGroups[i].grpi0_name));
00441 }
00442 }
00443
00444 if (pGroups) {
00445 NetApiBufferFree(pGroups);
00446 }
00447
00448 return result;
00449 }
00450
00451 KUserGroup::~KUserGroup()
00452 {
00453 }