• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KDECore

kuser_win.cpp

Go to the documentation of this file.
00001 /*
00002  *  KUser - represent a user/account (Windows)
00003  *  Copyright (C) 2007 Bernhard Loos <nhuh.put@web.de>
00004  *
00005  *  This library is free software; you can redistribute it and/or
00006  *  modify it under the terms of the GNU Library General Public
00007  *  License as published by the Free Software Foundation; either
00008  *  version 2 of the License, or (at your option) any later version.
00009  *
00010  *  This library is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  *  Library General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU Library General Public License
00016  *  along with this library; see the file COPYING.LIB.  If not, write to
00017  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  *  Boston, MA 02110-1301, USA.
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 
00031 class KUser::Private : public KShared
00032 {
00033     public:
00034         PUSER_INFO_11 userInfo;
00035         PSID sid;
00036 
00037         Private() : userInfo(0), sid(0) {}
00038 
00039         Private(PUSER_INFO_11 userInfo_, PSID sid_ = 0) : userInfo(userInfo_) {}
00040 
00041         Private(const QString &name, PSID sid_ = 0) : userInfo(0), sid(NULL)
00042         {
00043             LPBYTE servername;
00044             NET_API_STATUS status = NetGetAnyDCName(0, 0, &servername);
00045             if (status != NERR_Success)
00046             {
00047                 servername = NULL;
00048             }
00049 
00050             if (NetUserGetInfo((LPCWSTR) servername, (LPCWSTR) name.utf16(), 11, (LPBYTE *) &userInfo) != NERR_Success) {
00051                 goto error;
00052             }
00053             if (servername)
00054             {
00055                 NetApiBufferFree(servername);
00056                 servername = 0;
00057             }
00058 
00059             if (!sid_) {
00060                 DWORD size = 0;
00061                 SID_NAME_USE nameuse;
00062                 DWORD cchReferencedDomainName = 0;
00063                 WCHAR* referencedDomainName = NULL;
00064 
00065                 // the following line definitely fails:
00066                 // both the sizes for sid and for referencedDomainName are Null
00067                 // the needed sizes are set in size and cchReferencedDomainName
00068                 LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, referencedDomainName, &cchReferencedDomainName, &nameuse);
00069                 sid = (PSID) new SID[size + 1];
00070                 referencedDomainName = new WCHAR[cchReferencedDomainName + 1];
00071                 if (!LookupAccountNameW(NULL, (LPCWSTR) name.utf16(), sid, &size, referencedDomainName, &cchReferencedDomainName, &nameuse)) {
00072                     delete[] referencedDomainName;
00073                     goto error;
00074                 }
00075 
00076                 // if you want to see both the DomainName and the sid of the user
00077                 // uncomment the following lines
00078 /*                LPWSTR sidstring;
00079                 ConvertSidToStringSidW(sid, &sidstring);
00080                 qDebug() << QString("\\\\") + QString::fromUtf16(reinterpret_cast<ushort*>(referencedDomainName)) + \
00081                             "\\" + name + "(" + QString::fromUtf16(reinterpret_cast<ushort*>(sidstring)) + ")";
00082 
00083                 LocalFree(sidstring);*/
00084                 delete[] referencedDomainName;
00085             }
00086             else {
00087                 if (!IsValidSid(sid_))
00088                     goto error;
00089 
00090                 DWORD sidlength = GetLengthSid(sid_);
00091                 sid = (PSID) new BYTE[sidlength];
00092                 if (!CopySid(sidlength, sid, sid_))
00093                     goto error;
00094             }
00095 
00096             return;
00097 
00098           error:
00099             delete[] sid;
00100             sid = 0;
00101             if (userInfo) {
00102                 NetApiBufferFree(userInfo);
00103                 userInfo = 0;
00104             }
00105             if (servername)
00106             {
00107                 NetApiBufferFree(servername);
00108                 servername = 0;
00109             }
00110         }
00111 
00112         ~Private()
00113         {
00114             if (userInfo)
00115                 NetApiBufferFree(userInfo);
00116 
00117             delete[] sid;
00118         }
00119 };
00120 
00121 KUser::KUser(UIDMode mode)
00122         : d(0)
00123 {
00124     Q_UNUSED(mode)
00125 
00126     DWORD bufferLen = UNLEN + 1;
00127     ushort buffer[UNLEN + 1];
00128 
00129     if (GetUserNameW((LPWSTR) buffer, &bufferLen))
00130         d = new Private(QString::fromUtf16(buffer));
00131 }
00132 
00133 KUser::KUser(K_UID uid)
00134     : d(0)
00135 {
00136     DWORD bufferLen = UNLEN + 1;
00137     ushort buffer[UNLEN + 1];
00138     SID_NAME_USE eUse;
00139 
00140     if (LookupAccountSidW(NULL, uid, (LPWSTR) buffer, &bufferLen, NULL, NULL, &eUse))
00141         d = new Private(QString::fromUtf16(buffer), uid);
00142 }
00143 
00144 KUser::KUser(const QString &name)
00145     : d(new Private(name))
00146 {
00147 }
00148 
00149 KUser::KUser(const char *name)
00150     :d(new Private(QString::fromLocal8Bit(name)))
00151 {
00152 }
00153 
00154 KUser::KUser(const KUser &user)
00155     : d(user.d)
00156 {
00157 }
00158 
00159 KUser &KUser::operator=(const KUser &user)
00160 {
00161     d = user.d;
00162     return *this;
00163 }
00164 
00165 bool KUser::operator==(const KUser &user) const
00166 {
00167     if (!isValid() || !user.isValid())
00168         return false;
00169     return EqualSid(d->sid, user.d->sid);
00170 }
00171 
00172 bool KUser::operator !=(const KUser &user) const
00173 {
00174     return !operator==(user);
00175 }
00176 
00177 bool KUser::isValid() const
00178 {
00179     return d->userInfo != 0 && d->sid != 0;
00180 }
00181 
00182 bool KUser::isSuperUser() const
00183 {
00184     return d->userInfo && d->userInfo->usri11_priv == USER_PRIV_ADMIN;
00185 }
00186 
00187 QString KUser::loginName() const
00188 {
00189     return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_name) : QString());
00190 }
00191 
00192 #ifndef KDE_NO_DEPRECATED
00193 QString KUser::fullName() const
00194 {
00195     return (d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_full_name) : QString());
00196 }
00197 #endif
00198 
00199 QString KUser::homeDir() const
00200 {
00201     return QDir::fromNativeSeparators(QString::fromLocal8Bit(qgetenv("USERPROFILE")));
00202 }
00203 
00204 QString KUser::faceIconPath() const
00205 {
00206     // FIXME: this needs to be adapted to windows systems (BC changes)
00207     return QString();
00208 }
00209 
00210 QString KUser::shell() const
00211 {
00212     return QString::fromAscii("cmd.exe");
00213 }
00214 
00215 QList<KUserGroup> KUser::groups() const
00216 {
00217     QList<KUserGroup> result;
00218 
00219     Q_FOREACH (const QString &name, groupNames()) {
00220         result.append(KUserGroup(name));
00221     }
00222 
00223     return result;
00224 }
00225 
00226 QStringList KUser::groupNames() const
00227 {
00228     QStringList result;
00229 
00230     if (!d->userInfo) {
00231         return result;
00232     }
00233 
00234     PGROUP_USERS_INFO_0 pGroups = NULL;
00235     DWORD dwEntriesRead = 0;
00236     DWORD dwTotalEntries = 0;
00237     NET_API_STATUS nStatus;
00238 
00239     nStatus = NetUserGetGroups(NULL, d->userInfo->usri11_name, 0, (LPBYTE *) &pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries);
00240 
00241     if (nStatus == NERR_Success) {
00242         for (DWORD i = 0; i < dwEntriesRead; ++i) {
00243             result.append(QString::fromUtf16((ushort *) pGroups[i].grui0_name));
00244         }
00245     }
00246 
00247     if (pGroups) {
00248         NetApiBufferFree(pGroups);
00249     }
00250 
00251     return result;
00252 }
00253 
00254 K_UID KUser::uid() const
00255 {
00256     return d->sid;
00257 }
00258 
00259 QVariant KUser::property(UserProperty which) const
00260 {
00261     if (which == FullName)
00262         return QVariant(d->userInfo ? QString::fromUtf16((ushort *) d->userInfo->usri11_full_name) : QString());
00263 
00264     return QVariant();
00265 }
00266 
00267 QList<KUser> KUser::allUsers()
00268 {
00269     QList<KUser> result;
00270 
00271     NET_API_STATUS nStatus;
00272     PUSER_INFO_11 pUser = NULL;
00273     DWORD dwEntriesRead = 0;
00274     DWORD dwTotalEntries = 0;
00275     DWORD dwResumeHandle = 0;
00276 
00277     KUser tmp;
00278 
00279     do {
00280         nStatus = NetUserEnum(NULL, 11, 0, (LPBYTE*) &pUser, 1, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
00281 
00282         if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead > 0) {
00283             tmp.d = new Private(pUser);
00284             result.append(tmp);
00285         }
00286     } while (nStatus == ERROR_MORE_DATA);
00287 
00288     return result;
00289 }
00290 
00291 QStringList KUser::allUserNames()
00292 {
00293     QStringList result;
00294 
00295     NET_API_STATUS nStatus;
00296     PUSER_INFO_0 pUsers = NULL;
00297     DWORD dwEntriesRead = 0;
00298     DWORD dwTotalEntries = 0;
00299 
00300     nStatus = NetUserEnum(NULL, 0, 0, (LPBYTE*) &pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00301 
00302     if (nStatus == NERR_Success) {
00303         for (DWORD i = 0; i < dwEntriesRead; ++i) {
00304             result.append(QString::fromUtf16((ushort *) pUsers[i].usri0_name));
00305         }
00306     }
00307 
00308     if (pUsers) {
00309         NetApiBufferFree(pUsers);
00310     }
00311 
00312     return result;
00313 }
00314 
00315 KUser::~KUser()
00316 {
00317 }
00318 
00319 class KUserGroup::Private : public KShared
00320 {
00321     public:
00322         PGROUP_INFO_0 groupInfo;
00323 
00324         Private() : groupInfo(NULL) {}
00325         Private(PGROUP_INFO_0 groupInfo_) : groupInfo(groupInfo_) {}
00326         Private(const QString &Name) : groupInfo(NULL)
00327         {
00328             NetGroupGetInfo(NULL, (PCWSTR) Name.utf16(), 0, (PBYTE *) &groupInfo);
00329         }
00330 
00331         ~Private()
00332         {
00333             if (groupInfo) {
00334                 NetApiBufferFree(groupInfo);
00335             }
00336         }
00337 };
00338 
00339 KUserGroup::KUserGroup(const QString &_name)
00340     : d(new Private(_name))
00341 {
00342 }
00343 
00344 KUserGroup::KUserGroup(const char *_name)
00345     : d(new Private(QLatin1String(_name)))
00346 {
00347 }
00348 
00349 KUserGroup::KUserGroup(const KUserGroup &group)
00350     : d(group.d)
00351 {
00352 }
00353 
00354 KUserGroup& KUserGroup::operator =(const KUserGroup &group)
00355 {
00356     d = group.d;
00357     return *this;
00358 }
00359 
00360 bool KUserGroup::operator==(const KUserGroup &group) const
00361 {
00362     if (d->groupInfo == NULL || group.d->groupInfo == NULL) {
00363         return false;
00364     }
00365     return wcscmp(d->groupInfo->grpi0_name, group.d->groupInfo->grpi0_name) == 0;
00366 }
00367 
00368 bool KUserGroup::operator!=(const KUserGroup &group) const
00369 {
00370     return !operator==(group);
00371 }
00372 
00373 bool KUserGroup::isValid() const
00374 {
00375     return d->groupInfo != NULL;
00376 }
00377 
00378 QString KUserGroup::name() const
00379 {
00380     if(d && d->groupInfo)
00381         return QString::fromUtf16((ushort *) d->groupInfo->grpi0_name);
00382     return QString();
00383 }
00384 
00385 QList<KUser> KUserGroup::users() const
00386 {
00387     QList<KUser> Result;
00388 
00389     Q_FOREACH(const QString &user, userNames()) {
00390         Result.append(KUser(user));
00391     }
00392 
00393     return Result;
00394 }
00395 
00396 QStringList KUserGroup::userNames() const
00397 {
00398     QStringList result;
00399 
00400     if (!d->groupInfo) {
00401         return result;
00402     }
00403 
00404     PGROUP_USERS_INFO_0 pUsers = NULL;
00405     DWORD dwEntriesRead = 0;
00406     DWORD dwTotalEntries = 0;
00407     NET_API_STATUS nStatus;
00408 
00409     nStatus = NetGroupGetUsers(NULL, d->groupInfo->grpi0_name, 0, (LPBYTE *) &pUsers, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00410 
00411     if (nStatus == NERR_Success) {
00412         for (DWORD i = 0; i < dwEntriesRead; ++i) {
00413             result.append(QString::fromUtf16((ushort *) pUsers[i].grui0_name));
00414         }
00415     }
00416 
00417     if (pUsers) {
00418         NetApiBufferFree(pUsers);
00419     }
00420 
00421     return result;
00422 }
00423 
00424 QList<KUserGroup> KUserGroup::allGroups()
00425 {
00426     QList<KUserGroup> result;
00427 
00428     NET_API_STATUS nStatus;
00429     PGROUP_INFO_0 pGroup=NULL;
00430     DWORD dwEntriesRead=0;
00431     DWORD dwTotalEntries=0;
00432     DWORD dwResumeHandle=0;
00433 
00434     KUserGroup tmp("");
00435 
00436     do {
00437         nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroup, 1, &dwEntriesRead, &dwTotalEntries, (PDWORD_PTR)&dwResumeHandle);
00438 
00439         if ((nStatus == NERR_Success || nStatus == ERROR_MORE_DATA) && dwEntriesRead > 0) {
00440             tmp.d = new Private(pGroup);
00441             result.append(tmp);
00442         }
00443     } while (nStatus == ERROR_MORE_DATA);
00444 
00445     return result;
00446 }
00447 
00448 QStringList KUserGroup::allGroupNames()
00449 {
00450     QStringList result;
00451 
00452     NET_API_STATUS nStatus;
00453     PGROUP_INFO_0 pGroups=NULL;
00454     DWORD dwEntriesRead=0;
00455     DWORD dwTotalEntries=0;
00456 
00457     nStatus = NetGroupEnum(NULL, 0, (LPBYTE*) &pGroups, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, NULL);
00458 
00459     if (nStatus == NERR_Success) {
00460         for (DWORD i = 0; i < dwEntriesRead; ++i) {
00461             result.append(QString::fromUtf16((ushort *) pGroups[i].grpi0_name));
00462         }
00463     }
00464 
00465     if (pGroups) {
00466         NetApiBufferFree(pGroups);
00467     }
00468 
00469     return result;
00470 }
00471 
00472 KUserGroup::~KUserGroup()
00473 {
00474 }

KDECore

Skip menu "KDECore"
  • Main Page
  • Modules
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal