Standardize License information
[openafs.git] / src / WINNT / afsclass / c_usr.cpp
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  * 
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 extern "C" {
11 #include <afs/param.h>
12 #include <afs/stds.h>
13 }
14
15 #include <WINNT/afsclass.h>
16 #include "internal.h"
17
18
19 /*
20  * DEFINITIONS ________________________________________________________________
21  *
22  */
23
24 #define USERACCESS_TO_ACCOUNTACCESS(_ua) ( ((_ua) == PTS_USER_OWNER_ACCESS) ? aaOWNER_ONLY : aaANYONE )
25
26
27 /*
28  * ROUTINES ___________________________________________________________________
29  *
30  */
31
32 USER::USER (LPCELL lpCellParent, LPTSTR pszPrincipal, LPTSTR pszInstance)
33 {
34    m_lpiCell = lpCellParent->GetIdentifier();
35    lstrcpy (m_szPrincipal, pszPrincipal);
36    lstrcpy (m_szInstance, (pszInstance) ? pszInstance : TEXT(""));
37
38    m_lpiThis = NULL;
39    m_fStatusOutOfDate = TRUE;
40    m_mszOwnerOf = NULL;
41    m_mszMemberOf = NULL;
42 }
43
44
45 USER::~USER (void)
46 {
47    if (m_lpiThis)
48       m_lpiThis->m_cRef --;
49
50    FreeString (m_mszOwnerOf);
51    FreeString (m_mszMemberOf);
52 }
53
54
55 void USER::SendDeleteNotifications (void)
56 {
57    NOTIFYCALLBACK::SendNotificationToAll (evtDestroy, GetIdentifier());
58 }
59
60
61 void USER::Close (void)
62 {
63    AfsClass_Leave();
64 }
65
66
67 LPIDENT USER::GetIdentifier (void)
68 {
69    if (m_lpiThis == NULL)
70       {
71       if ((m_lpiThis = IDENT::FindIdent (this)) == NULL)
72          m_lpiThis = New2 (IDENT,(this));
73       m_lpiThis->m_cRef ++;
74       }
75
76    return m_lpiThis;
77 }
78
79
80 void USER::Invalidate (void)
81 {
82    m_fStatusOutOfDate = TRUE;
83 }
84
85
86 LPCELL USER::OpenCell (ULONG *pStatus)
87 {
88    return m_lpiCell->OpenCell (pStatus);
89 }
90
91
92 void USER::GetName (LPTSTR pszPrincipal, LPTSTR pszInstance)
93 {
94    if (pszPrincipal)
95       lstrcpy (pszPrincipal, m_szPrincipal);
96    if (pszInstance)
97       lstrcpy (pszInstance, m_szInstance);
98 }
99
100
101 BOOL USER::GetStatus (LPUSERSTATUS lpus, BOOL fNotify, ULONG *pStatus)
102 {
103    if (!RefreshStatus (fNotify, pStatus))
104       return FALSE;
105
106    memcpy (lpus, &m_us, sizeof(USERSTATUS));
107    return TRUE;
108 }
109
110
111 PVOID USER::GetUserParam (void)
112 {
113    return GetIdentifier()->GetUserParam();
114 }
115
116
117 void USER::SetUserParam (PVOID pUserParam)
118 {
119    GetIdentifier()->SetUserParam (pUserParam);
120 }
121
122
123 BOOL USER::GetOwnerOf (LPTSTR *ppmsz, ULONG *pStatus)
124 {
125    if (!RefreshStatus (TRUE, pStatus))
126       return FALSE;
127    *ppmsz = CloneMultiString (m_mszOwnerOf);
128    return TRUE;
129 }
130
131
132 BOOL USER::GetMemberOf (LPTSTR *ppmsz, ULONG *pStatus)
133 {
134    if (!RefreshStatus (TRUE, pStatus))
135       return FALSE;
136    *ppmsz = CloneMultiString (m_mszMemberOf);
137    return TRUE;
138 }
139
140
141 BOOL USER::RefreshStatus (BOOL fNotify, ULONG *pStatus)
142 {
143    BOOL rc = TRUE;
144    DWORD status = 0;
145    DWORD kasStatus = 0;
146    DWORD ptsStatus = 0;
147
148    if (m_fStatusOutOfDate)
149       {
150       m_fStatusOutOfDate = FALSE;
151
152       if (fNotify)
153          NOTIFYCALLBACK::SendNotificationToAll (evtRefreshStatusBegin, GetIdentifier());
154
155       memset (&m_us, 0x00, sizeof(m_us));
156
157       FreeString (m_mszOwnerOf);
158       m_mszOwnerOf = NULL;
159
160       FreeString (m_mszMemberOf);
161       m_mszMemberOf = NULL;
162
163       TCHAR szFullName[ cchNAME ];
164       AfsClass_GenFullUserName (szFullName, m_szPrincipal, m_szInstance);
165
166       LPCELL lpCell;
167       if ((lpCell = OpenCell (&status)) == NULL)
168          rc = FALSE;
169       else
170          {
171          PVOID hCell;
172          if ((hCell = lpCell->GetCellObject (&status)) == NULL)
173             rc = FALSE;
174          else
175             {
176             // Try to get KAS information.
177             //
178             WORKERPACKET wpGetKas;
179             wpGetKas.wpKasPrincipalGet.hCell = hCell;
180             wpGetKas.wpKasPrincipalGet.hServer = lpCell->GetKasObject (&kasStatus);
181             wpGetKas.wpKasPrincipalGet.pszPrincipal = m_szPrincipal;
182             wpGetKas.wpKasPrincipalGet.pszInstance = m_szInstance;
183
184             if (Worker_DoTask (wtaskKasPrincipalGet, &wpGetKas, &kasStatus))
185                {
186                m_us.fHaveKasInfo = TRUE;
187
188                TCHAR szLastModPrincipal[ cchNAME ];
189                TCHAR szLastModInstance[ cchNAME ];
190                CopyAnsiToString (szLastModPrincipal, wpGetKas.wpKasPrincipalGet.Data.lastModPrincipal.principal);
191                CopyAnsiToString (szLastModInstance, wpGetKas.wpKasPrincipalGet.Data.lastModPrincipal.instance);
192
193                m_us.KASINFO.fIsAdmin = (wpGetKas.wpKasPrincipalGet.Data.adminSetting == ADMIN) ? TRUE : FALSE;
194                m_us.KASINFO.fCanGetTickets = (wpGetKas.wpKasPrincipalGet.Data.tgsSetting == TGS) ? TRUE : FALSE;
195                m_us.KASINFO.fEncrypt = (wpGetKas.wpKasPrincipalGet.Data.encSetting == ENCRYPT) ? TRUE : FALSE;
196                m_us.KASINFO.fCanChangePassword = (wpGetKas.wpKasPrincipalGet.Data.cpwSetting == CHANGE_PASSWORD) ? TRUE : FALSE;
197                m_us.KASINFO.fCanReusePasswords = (wpGetKas.wpKasPrincipalGet.Data.rpwSetting == REUSE_PASSWORD) ? TRUE : FALSE;
198                AfsClass_UnixTimeToSystemTime (&m_us.KASINFO.timeExpires, wpGetKas.wpKasPrincipalGet.Data.userExpiration);
199                AfsClass_UnixTimeToSystemTime (&m_us.KASINFO.timeLastPwChange, wpGetKas.wpKasPrincipalGet.Data.lastChangePasswordTime);
200                AfsClass_UnixTimeToSystemTime (&m_us.KASINFO.timeLastMod, wpGetKas.wpKasPrincipalGet.Data.lastModTime);
201                m_us.KASINFO.lpiLastMod = IDENT::FindUser (m_lpiCell, szLastModPrincipal, szLastModInstance);
202                m_us.KASINFO.csecTicketLifetime = wpGetKas.wpKasPrincipalGet.Data.maxTicketLifetime;
203                m_us.KASINFO.keyVersion = wpGetKas.wpKasPrincipalGet.Data.keyVersion;
204                memcpy (&m_us.KASINFO.key.key, &wpGetKas.wpKasPrincipalGet.Data.key.key, ENCRYPTIONKEY_LEN);
205                m_us.KASINFO.dwKeyChecksum = wpGetKas.wpKasPrincipalGet.Data.keyCheckSum;
206                m_us.KASINFO.cdayPwExpire = wpGetKas.wpKasPrincipalGet.Data.daysToPasswordExpire;
207                m_us.KASINFO.cFailLogin = wpGetKas.wpKasPrincipalGet.Data.failLoginCount;
208                m_us.KASINFO.csecFailLoginLock = wpGetKas.wpKasPrincipalGet.Data.lockTime;
209                }
210
211             // Try to get PTS information.
212             //
213             WORKERPACKET wpGetPts;
214             wpGetPts.wpPtsUserGet.hCell = hCell;
215             wpGetPts.wpPtsUserGet.pszUser = szFullName;
216             if (Worker_DoTask (wtaskPtsUserGet, &wpGetPts, &ptsStatus))
217                {
218                m_us.fHavePtsInfo = TRUE;
219
220                m_us.PTSINFO.cgroupCreationQuota = wpGetPts.wpPtsUserGet.Entry.groupCreationQuota;
221                m_us.PTSINFO.cgroupMember = wpGetPts.wpPtsUserGet.Entry.groupMembershipCount;
222                m_us.PTSINFO.uidName = wpGetPts.wpPtsUserGet.Entry.nameUid;
223                m_us.PTSINFO.uidOwner = wpGetPts.wpPtsUserGet.Entry.ownerUid;
224                m_us.PTSINFO.uidCreator = wpGetPts.wpPtsUserGet.Entry.creatorUid;
225
226                CopyAnsiToString (m_us.PTSINFO.szOwner, wpGetPts.wpPtsUserGet.Entry.owner);
227                CopyAnsiToString (m_us.PTSINFO.szCreator, wpGetPts.wpPtsUserGet.Entry.creator);
228
229                m_us.PTSINFO.aaListStatus = USERACCESS_TO_ACCOUNTACCESS (wpGetPts.wpPtsUserGet.Entry.listStatus);
230                m_us.PTSINFO.aaGroupsOwned = USERACCESS_TO_ACCOUNTACCESS (wpGetPts.wpPtsUserGet.Entry.listGroupsOwned);
231                m_us.PTSINFO.aaMembership = USERACCESS_TO_ACCOUNTACCESS (wpGetPts.wpPtsUserGet.Entry.listMembership);
232                }
233
234             // Grab the list of groups to which this user belongs
235             //
236             WORKERPACKET wpBegin;
237             wpBegin.wpPtsUserMemberListBegin.hCell = hCell;
238             wpBegin.wpPtsUserMemberListBegin.pszUser = szFullName;
239             if (Worker_DoTask (wtaskPtsUserMemberListBegin, &wpBegin, &status))
240                {
241                for (;;)
242                   {
243                   TCHAR szGroup[ cchNAME ];
244
245                   WORKERPACKET wpNext;
246                   wpNext.wpPtsUserMemberListNext.hEnum = wpBegin.wpPtsUserMemberListBegin.hEnum;
247                   wpNext.wpPtsUserMemberListNext.pszGroup = szGroup;
248                   if (!Worker_DoTask (wtaskPtsUserMemberListNext, &wpNext))
249                      break;
250
251                   FormatMultiString (&m_mszMemberOf, FALSE, TEXT("%1"), TEXT("%s"), szGroup);
252                   }
253
254                WORKERPACKET wpDone;
255                wpDone.wpPtsUserMemberListDone.hEnum = wpBegin.wpPtsUserMemberListBegin.hEnum;
256                Worker_DoTask (wtaskPtsUserMemberListDone, &wpDone);
257                }
258
259             // Grab the list of groups which this user owns
260             //
261             wpBegin.wpPtsOwnedGroupListBegin.hCell = hCell;
262             wpBegin.wpPtsOwnedGroupListBegin.pszOwner = szFullName;
263             if (Worker_DoTask (wtaskPtsOwnedGroupListBegin, &wpBegin, &status))
264                {
265                for (;;)
266                   {
267                   TCHAR szGroup[ cchNAME ];
268
269                   WORKERPACKET wpNext;
270                   wpNext.wpPtsOwnedGroupListNext.hEnum = wpBegin.wpPtsOwnedGroupListBegin.hEnum;
271                   wpNext.wpPtsOwnedGroupListNext.pszGroup = szGroup;
272                   if (!Worker_DoTask (wtaskPtsOwnedGroupListNext, &wpNext))
273                      break;
274
275                   FormatMultiString (&m_mszOwnerOf, FALSE, TEXT("%1"), TEXT("%s"), szGroup);
276                   }
277
278                WORKERPACKET wpDone;
279                wpDone.wpPtsOwnedGroupListDone.hEnum = wpBegin.wpPtsOwnedGroupListBegin.hEnum;
280                Worker_DoTask (wtaskPtsOwnedGroupListDone, &wpDone);
281                }
282             }
283
284          lpCell->Close();
285          }
286
287       if (fNotify)
288          NOTIFYCALLBACK::SendNotificationToAll (evtRefreshStatusEnd, GetIdentifier(), ((rc) ? 0 : status));
289       }
290
291    if (rc && (!m_us.fHaveKasInfo) && (!status) && kasStatus)
292       {
293       status = kasStatus;
294       rc = FALSE;
295       }
296    if (rc && (!m_us.fHavePtsInfo) && (!status) && ptsStatus)
297       {
298       status = ptsStatus;
299       // not fatal; rc remains TRUE
300       }
301    if (pStatus && !rc)
302       *pStatus = status;
303    return TRUE;
304 }
305
306
307 void USER::SplitUserName (LPCTSTR pszFull, LPTSTR pszName, LPTSTR pszInstance)
308 {
309    if (pszName)
310       lstrcpy (pszName, pszFull);
311    if (pszInstance)
312       lstrcpy (pszInstance, TEXT(""));
313
314    if (!USER::IsMachineAccount (pszFull))
315       {
316       if (pszName && pszInstance)
317          {
318          LPTSTR pchDot;
319          if ((pchDot = (LPTSTR)lstrchr (pszName, TEXT('.'))) != NULL)
320             {
321             *pchDot = TEXT('\0');
322             lstrcpy (pszInstance, &pchDot[1]);
323             }
324          }
325       }
326 }
327
328
329 BOOL USER::IsMachineAccount (LPCTSTR pszName)
330 {
331    for ( ; pszName && *pszName; ++pszName)
332       {
333       if (!( (*pszName == TEXT('.')) || ((*pszName >= TEXT('0')) && (*pszName <= TEXT('9'))) ))
334          return FALSE;
335       }
336    return TRUE;
337 }
338