Subversion Repositories Aucun

Rev

Rev 221 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
100 ixe013 1
/*
2
 Copyright (c) 2008, Guillaume Seguin ([email protected])
3
 All rights reserved.
2 ixe013 4
 
100 ixe013 5
 Redistribution and use in source and binary forms, with or without
6
 modification, are permitted provided that the following conditions
7
 are met:
2 ixe013 8
 
100 ixe013 9
 1. Redistributions of source code must retain the above copyright
10
    notice, this list of conditions and the following disclaimer.
2 ixe013 11
 
100 ixe013 12
 2. Redistributions in binary form must reproduce the above copyright
13
    notice, this list of conditions and the following disclaimer in the
14
    documentation and/or other materials provided with the distribution.
2 ixe013 15
 
100 ixe013 16
 THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
17
 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
 ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
20
 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
 SUCH DAMAGE.
27
*/
2 ixe013 28
 
29
#define _WIN32_WINNT 0x0501
30
 
31
#include <windows.h>
32
#include <winwlx.h>
165 ixe013 33
#include <lm.h>
2 ixe013 34
 
35
#include "Ginahook.h"
36
#include "GinaDlg.h"
40 ixe013 37
#include "global.h"
91 ixe013 38
#include "trace.h"
40 ixe013 39
#include "debug.h"
138 ixe013 40
#include "randpasswd.h"
91 ixe013 41
#include "SecurityHelper.h"
118 ixe013 42
#include "Settings.h"
138 ixe013 43
#include "Serialize.h"
2 ixe013 44
 
122 ixe013 45
#include "loggedout_dlg.h"
127 ixe013 46
#include "resource.h"
122 ixe013 47
 
2 ixe013 48
//
49
// Location of the real MSGINA.
50
//
51
 
52
#define REALGINA_PATH      TEXT("MSGINA.DLL")
127 ixe013 53
#define GINASTUB_VERSION   (WLX_VERSION_1_4)
40 ixe013 54
 
55
//Hooked instance of MSGINA
216 ixe013 56
HINSTANCE hDll;
57
HINSTANCE hResourceDll;
40 ixe013 58
 
2 ixe013 59
//
60
// Winlogon function dispatch table.
61
//
40 ixe013 62
PVOID g_pWinlogon = NULL;
2 ixe013 63
static DWORD g_dwVersion = WLX_VERSION_1_4;
64
 
40 ixe013 65
static MyGinaContext gAucunContext = {0};
215 ixe013 66
MyGinaContext* pgAucunContext = &gAucunContext;
40 ixe013 67
 
2 ixe013 68
//
69
// Pointers to the real MSGINA functions.
70
//
71
 
72
static PFWLXNEGOTIATE            pfWlxNegotiate;
73
static PFWLXINITIALIZE           pfWlxInitialize;
74
static PFWLXDISPLAYSASNOTICE     pfWlxDisplaySASNotice;
75
static PFWLXLOGGEDOUTSAS         pfWlxLoggedOutSAS;
76
static PFWLXACTIVATEUSERSHELL    pfWlxActivateUserShell;
77
static PFWLXLOGGEDONSAS          pfWlxLoggedOnSAS;
78
static PFWLXDISPLAYLOCKEDNOTICE  pfWlxDisplayLockedNotice;
79
static PFWLXWKSTALOCKEDSAS       pfWlxWkstaLockedSAS;
80
static PFWLXISLOCKOK             pfWlxIsLockOk;
81
static PFWLXISLOGOFFOK           pfWlxIsLogoffOk;
82
static PFWLXLOGOFF               pfWlxLogoff;
83
static PFWLXSHUTDOWN             pfWlxShutdown;
84
 
85
//
86
// New for version 1.1
87
//
88
static PFWLXSTARTAPPLICATION     pfWlxStartApplication  = NULL;
89
static PFWLXSCREENSAVERNOTIFY    pfWlxScreenSaverNotify = NULL;
90
 
91
//
92
// New for version 1.2 - No new GINA interface was added, except
93
//                       a new function in the dispatch table.
94
//
95
 
96
//
97
// New for version 1.3
98
//
99
static PFWLXNETWORKPROVIDERLOAD   pfWlxNetworkProviderLoad  = NULL;
100
static PFWLXDISPLAYSTATUSMESSAGE  pfWlxDisplayStatusMessage = NULL;
101
static PFWLXGETSTATUSMESSAGE      pfWlxGetStatusMessage     = NULL;
102
static PFWLXREMOVESTATUSMESSAGE   pfWlxRemoveStatusMessage  = NULL;
103
 
104
//
105
// New for version 1.4
106
//
107
static PWLXGETCONSOLESWITCHCREDENTIALS pfWlxGetConsoleSwitchCredentials = NULL;
108
static PWLXRECONNECTNOTIFY pfWlxReconnectNotify  = NULL;
109
static PWLXDISCONNECTNOTIFY pfWlxDisconnectNotify = NULL;
110
 
215 ixe013 111
MyGinaContext* GetMyContext(PVOID pWlxContext)
177 ixe013 112
{
215 ixe013 113
    return ((MyGinaContext*)pWlxContext);
176 ixe013 114
}
115
 
40 ixe013 116
PVOID GetHookedContext(PVOID pWlxContext)
117
{
215 ixe013 118
    return GetMyContext(pWlxContext)->mHookedContext;
40 ixe013 119
}
91 ixe013 120
 
2 ixe013 121
//
122
// Hook into the real MSGINA.
123
//
129 ixe013 124
BOOL MyInitialize(HINSTANCE hMsginaDll, DWORD dwWlxVersion)
2 ixe013 125
{
215 ixe013 126
    //
127
    // Get pointers to all of the WLX functions in the real MSGINA.
128
    //
129
    pfWlxInitialize = (PFWLXINITIALIZE) GetProcAddress(hMsginaDll, "WlxInitialize");
2 ixe013 130
 
215 ixe013 131
    if (!pfWlxInitialize)
132
    {
133
        return FALSE;
134
    }
2 ixe013 135
 
215 ixe013 136
    pfWlxDisplaySASNotice = (PFWLXDISPLAYSASNOTICE) GetProcAddress(hMsginaDll, "WlxDisplaySASNotice");
2 ixe013 137
 
215 ixe013 138
    if (!pfWlxDisplaySASNotice)
139
    {
140
        return FALSE;
141
    }
2 ixe013 142
 
215 ixe013 143
    pfWlxLoggedOutSAS = (PFWLXLOGGEDOUTSAS) GetProcAddress(hMsginaDll, "WlxLoggedOutSAS");
2 ixe013 144
 
215 ixe013 145
    if (!pfWlxLoggedOutSAS)
146
    {
147
        return FALSE;
148
    }
2 ixe013 149
 
215 ixe013 150
    pfWlxActivateUserShell = (PFWLXACTIVATEUSERSHELL) GetProcAddress(hMsginaDll, "WlxActivateUserShell");
2 ixe013 151
 
215 ixe013 152
    if (!pfWlxActivateUserShell)
153
    {
154
        return FALSE;
155
    }
2 ixe013 156
 
215 ixe013 157
    pfWlxLoggedOnSAS = (PFWLXLOGGEDONSAS) GetProcAddress(hMsginaDll, "WlxLoggedOnSAS");
2 ixe013 158
 
215 ixe013 159
    if (!pfWlxLoggedOnSAS)
160
    {
161
        return FALSE;
162
    }
2 ixe013 163
 
215 ixe013 164
    pfWlxDisplayLockedNotice = (PFWLXDISPLAYLOCKEDNOTICE) GetProcAddress(hMsginaDll, "WlxDisplayLockedNotice");
2 ixe013 165
 
215 ixe013 166
    if (!pfWlxDisplayLockedNotice)
167
    {
168
        return FALSE;
169
    }
2 ixe013 170
 
215 ixe013 171
    pfWlxIsLockOk = (PFWLXISLOCKOK) GetProcAddress(hMsginaDll, "WlxIsLockOk");
2 ixe013 172
 
215 ixe013 173
    if (!pfWlxIsLockOk)
174
    {
175
        return FALSE;
176
    }
2 ixe013 177
 
215 ixe013 178
    pfWlxWkstaLockedSAS = (PFWLXWKSTALOCKEDSAS) GetProcAddress(hMsginaDll, "WlxWkstaLockedSAS");
2 ixe013 179
 
215 ixe013 180
    if (!pfWlxWkstaLockedSAS)
181
    {
182
        return FALSE;
183
    }
2 ixe013 184
 
215 ixe013 185
    pfWlxIsLogoffOk = (PFWLXISLOGOFFOK) GetProcAddress(hMsginaDll, "WlxIsLogoffOk");
2 ixe013 186
 
215 ixe013 187
    if (!pfWlxIsLogoffOk)
188
    {
189
        return FALSE;
190
    }
2 ixe013 191
 
215 ixe013 192
    pfWlxLogoff = (PFWLXLOGOFF) GetProcAddress(hMsginaDll, "WlxLogoff");
2 ixe013 193
 
215 ixe013 194
    if (!pfWlxLogoff)
195
    {
196
        return FALSE;
197
    }
2 ixe013 198
 
215 ixe013 199
    pfWlxShutdown = (PFWLXSHUTDOWN) GetProcAddress(hMsginaDll, "WlxShutdown");
2 ixe013 200
 
215 ixe013 201
    if (!pfWlxShutdown)
202
    {
203
        return FALSE;
204
    }
2 ixe013 205
 
215 ixe013 206
    //
207
    // Load functions for version 1.1 as necessary.
208
    //
209
    if (dwWlxVersion > WLX_VERSION_1_0)
210
    {
211
        pfWlxStartApplication = (PFWLXSTARTAPPLICATION) GetProcAddress(hMsginaDll, "WlxStartApplication");
2 ixe013 212
 
215 ixe013 213
        if (!pfWlxStartApplication)
214
        {
215
            return FALSE;
216
        }
2 ixe013 217
 
215 ixe013 218
        pfWlxScreenSaverNotify = (PFWLXSCREENSAVERNOTIFY) GetProcAddress(hMsginaDll, "WlxScreenSaverNotify");
2 ixe013 219
 
215 ixe013 220
        if (!pfWlxScreenSaverNotify)
221
        {
222
            return FALSE;
223
        }
224
    }
2 ixe013 225
 
215 ixe013 226
    //
227
    // Load functions for version 1.3 as necessary.
228
    //
229
    if (dwWlxVersion > WLX_VERSION_1_2)
230
    {
231
        pfWlxNetworkProviderLoad = (PFWLXNETWORKPROVIDERLOAD)GetProcAddress(hMsginaDll, "WlxNetworkProviderLoad");
2 ixe013 232
 
215 ixe013 233
        if (!pfWlxNetworkProviderLoad)
234
        {
235
            return FALSE;
236
        }
2 ixe013 237
 
215 ixe013 238
        pfWlxDisplayStatusMessage = (PFWLXDISPLAYSTATUSMESSAGE)GetProcAddress(hMsginaDll, "WlxDisplayStatusMessage");
2 ixe013 239
 
215 ixe013 240
        if (!pfWlxDisplayStatusMessage)
241
        {
242
            return FALSE;
243
        }
2 ixe013 244
 
215 ixe013 245
        pfWlxGetStatusMessage = (PFWLXGETSTATUSMESSAGE)GetProcAddress(hMsginaDll, "WlxGetStatusMessage");
2 ixe013 246
 
215 ixe013 247
        if (!pfWlxGetStatusMessage)
248
        {
249
            return FALSE;
250
        }
23 ixe013 251
 
215 ixe013 252
        pfWlxRemoveStatusMessage =
253
            (PFWLXREMOVESTATUSMESSAGE)
254
            GetProcAddress(hMsginaDll, "WlxRemoveStatusMessage");
23 ixe013 255
 
215 ixe013 256
        if (!pfWlxRemoveStatusMessage)
257
        {
258
            return FALSE;
259
        }
260
    }
23 ixe013 261
 
215 ixe013 262
    //
263
    // Load functions for version 1.3 as necessary.
264
    //
265
    if (dwWlxVersion > WLX_VERSION_1_3)
266
    {
267
        pfWlxGetConsoleSwitchCredentials = (PWLXGETCONSOLESWITCHCREDENTIALS) GetProcAddress(hMsginaDll, "WlxGetConsoleSwitchCredentials");
23 ixe013 268
 
215 ixe013 269
        if (!pfWlxGetConsoleSwitchCredentials)
270
        {
271
            return FALSE;
272
        }
23 ixe013 273
 
215 ixe013 274
        pfWlxReconnectNotify = (PWLXRECONNECTNOTIFY) GetProcAddress(hMsginaDll, "WlxReconnectNotify");
275
 
276
        if (!pfWlxReconnectNotify)
277
        {
278
            return FALSE;
279
        }
280
 
281
        pfWlxDisconnectNotify = (PWLXDISCONNECTNOTIFY) GetProcAddress(hMsginaDll, "WlxDisconnectNotify");
282
 
283
        if (!pfWlxDisconnectNotify)
284
        {
285
            return FALSE;
286
        }
287
    }
288
 
289
    //
290
    // Everything loaded OK.
291
    //
292
    return TRUE;
2 ixe013 293
}
294
 
295
 
215 ixe013 296
BOOL WINAPI WlxNegotiate(DWORD dwWinlogonVersion, DWORD* pdwDllVersion)
2 ixe013 297
{
216 ixe013 298
    wchar_t original_gina[MAX_PATH];
215 ixe013 299
    DWORD dwWlxVersion = GINASTUB_VERSION;
217 ixe013 300
 
215 ixe013 301
    TRACE(eDEBUG, L"WlxNegotiate\n");
9 ixe013 302
 
222 ixe013 303
    //SAFEDEBUGBREAK();
221 ixe013 304
 
215 ixe013 305
    //
306
    // Load MSGINA.DLL.
307
    //
216 ixe013 308
    if(GetSettingText(L"SOFTWARE\\Paralint.com\\Aucun", L"Original Gina", original_gina, MAX_PATH) != S_OK)
215 ixe013 309
    {
216 ixe013 310
        wcscpy(original_gina, REALGINA_PATH);
311
    }
312
 
313
    if (!(hDll = LoadLibrary(original_gina)))
314
    {
215 ixe013 315
        return FALSE;
316
    }
213 ixe013 317
 
216 ixe013 318
    //Chances are this call will not result in a module load, because either aucun or a third party Gina chained
319
    //to us will have already loaded it.
320
    hResourceDll = LoadLibraryEx(REALGINA_PATH, 0, LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE | LOAD_LIBRARY_AS_IMAGE_RESOURCE);
215 ixe013 321
    //
322
    // Get pointers to WlxNegotiate function in the real MSGINA.
323
    //
216 ixe013 324
    pfWlxNegotiate = (PFWLXNEGOTIATE) GetProcAddress(hDll, "WlxNegotiate");
9 ixe013 325
 
215 ixe013 326
    if (!pfWlxNegotiate)
327
    {
328
        return FALSE;
329
    }
9 ixe013 330
 
215 ixe013 331
    //
332
    // Handle older version of Winlogon.
333
    //
334
    if (dwWinlogonVersion < dwWlxVersion)
335
    {
336
        dwWlxVersion = dwWinlogonVersion;
337
    }
2 ixe013 338
 
215 ixe013 339
    //
340
    // Negotiate with MSGINA for version that we can support.
341
    //
342
    if (!pfWlxNegotiate(dwWlxVersion, &dwWlxVersion))
343
    {
344
        return FALSE;
345
    }
2 ixe013 346
 
215 ixe013 347
    //
348
    // Load the rest of the WLX functions from the real MSGINA.
349
    //
216 ixe013 350
    if (!MyInitialize(hDll, dwWlxVersion))
215 ixe013 351
    {
352
        return FALSE;
353
    }
2 ixe013 354
 
215 ixe013 355
    //
356
    // Inform Winlogon which version to use.
357
    //
358
    *pdwDllVersion = g_dwVersion = dwWlxVersion;
359
    return TRUE;
2 ixe013 360
}
361
 
362
 
215 ixe013 363
BOOL WINAPI WlxInitialize(LPWSTR lpWinsta, HANDLE hWlx, PVOID pvReserved, PVOID pWinlogonFunctions, PVOID* pWlxContext)
2 ixe013 364
{
215 ixe013 365
    BOOL result;
366
    TRACE(eDEBUG, L"WlxInitialize\n");
367
    //
368
    // Save pointer to dispatch table.
369
    //
370
    // Note that g_pWinlogon will need to be properly casted to the
371
    // appropriate version when used to call function in the dispatch
372
    // table.
373
    //
374
    // For example, assuming we are at WLX_VERSION_1_3, we would call
375
    // WlxSasNotify() as follows:
376
    //
377
    // ((PWLX_DISPATCH_VERSION_1_3) g_pWinlogon)->WlxSasNotify(hWlx, MY_SAS);
378
    //
379
    g_pWinlogon = pWinlogonFunctions;
380
    //
381
    // Now hook the WlxDialogBoxParam() dispatch function.
382
    //
383
    HookWlxDialogBoxParam(g_pWinlogon, g_dwVersion);
384
    gAucunContext.mHookedContext = 0;
385
    *pWlxContext = &gAucunContext;
386
    gAucunContext.Winlogon = hWlx;
387
    result = pfWlxInitialize(lpWinsta, hWlx, pvReserved, pWinlogonFunctions, &gAucunContext.mHookedContext);
2 ixe013 388
 
215 ixe013 389
    if (result == TRUE)
390
    {
391
        gAucunContext.mLSA = 0; //safety
392
        RegisterLogonProcess(LOGON_PROCESS_NAME, &gAucunContext.mLSA);
393
        //The first winlogon process will set the password for the other processes
394
        SerializeEnter();
2 ixe013 395
 
215 ixe013 396
        /*
397
             * The password is saved, encrypted, to the registry. Only a process in the SYSTEM logon session that was
398
             * started with the system can read it. When we get here, we read the password and try to decrypt it.
399
             * If there is an error, it means it was encrypted in an earlier session, we need a new one.
400
             */
401
        if (GetSettingBinary(L"SOFTWARE\\Paralint.com\\Aucun\\SelfServe", L"Password", (LPBYTE)gEncryptedRandomSelfservePassword, gEncryptedRandomSelfservePassword_len) == S_OK)
402
        {
403
            //TODO : Decrypt and verify password
404
            /*
405
             if (CryptUnprotectMemory(gEncryptedRandomSelfservePassword, gEncryptedRandomSelfservePassword_len, CRYPTPROTECTMEMORY_SAME_LOGON))
406
             {
407
                if (wcsstr(gEncryptedRandomSelfservePassword, gEncryptedTag) != gEncryptedRandomSelfservePassword) //Password beacon does not match
408
                {
409
                        *gEncryptedRandomSelfservePassword = 0;
410
                }
411
             }
412
            //*/
413
        }
40 ixe013 414
 
215 ixe013 415
        if(!*gEncryptedRandomSelfservePassword)
416
        {
417
            wchar_t username[255];
418
            wcscpy(gEncryptedRandomSelfservePassword, gEncryptedTag);
419
            GenerateRandomUnicodePassword(gEncryptedRandomSelfservePassword + gEncryptedTag_len - 1, AUCUN_PWLEN); //-1 to overwrite the trailing null
420
            //*/
421
            GetSelfServeSetting(L"Username", username, sizeof username / sizeof * username);
91 ixe013 422
 
222 ixe013 423
            //DebugBreak();
221 ixe013 424
 
215 ixe013 425
            //Change the selfserve user's password
426
            if(SetSelfservePassword(username, gEncryptedRandomSelfservePassword + gEncryptedTag_len))
177 ixe013 427
            {
215 ixe013 428
                //TODO : Encrypt password
177 ixe013 429
            }
215 ixe013 430
            else
431
            {
432
                TRACE(eERROR, L"Unable to set password %s for selfserve user %s (error %d)\n", gEncryptedRandomSelfservePassword, username, GetLastError());
433
                *gEncryptedRandomSelfservePassword = 0;
434
            }
176 ixe013 435
 
215 ixe013 436
            SetSettingBinary(L"SOFTWARE\\Paralint.com\\Aucun\\SelfServe", L"Password", (LPBYTE)gEncryptedRandomSelfservePassword, gEncryptedRandomSelfservePassword_len);
437
        }
164 ixe013 438
 
215 ixe013 439
        SerializeLeave();
440
    }
164 ixe013 441
 
215 ixe013 442
    return result;
23 ixe013 443
}
2 ixe013 444
 
23 ixe013 445
VOID WINAPI WlxDisplaySASNotice(PVOID pWlxContext)
446
{
215 ixe013 447
    TRACE(eDEBUG, L"WlxDisplaySASNotice\n");
116 ixe013 448
 
215 ixe013 449
    //If we just finished a selfserve request (and pressed CTRL-ALT-DEL) we skip this notice.
450
    //If we did show the notice, the user would have to press CTRL-ALT-DEL a second time
451
    //It makes the mLogonScenario flag live a little longer than the actual self serve logon
452
    if((GetMyContext(pWlxContext)->mLogonScenario == eSelfServeLogon) ||
453
       (GetMyContext(pWlxContext)->mLogonScenario == eAutoLogon))
454
    {
455
        //Inform Winlogon that CTRL-ALT_DELETE was pressed
456
        ((PWLX_DISPATCH_VERSION_1_0) g_pWinlogon)->WlxSasNotify(gAucunContext.Winlogon, WLX_SAS_TYPE_CTRL_ALT_DEL);
457
    }
458
    else
459
    {
460
        //pfWlxDisplaySASNotice might be reentrant
461
        GetMyContext(pWlxContext)->mLogonScenario = eRegularLogon;
462
        pfWlxDisplaySASNotice(GetHookedContext(pWlxContext));
463
    }
23 ixe013 464
}
2 ixe013 465
 
466
 
215 ixe013 467
int WINAPI WlxLoggedOutSAS(PVOID pWlxContext, DWORD dwSasType, PLUID pAuthenticationId, PSID pLogonSid, PDWORD pdwOptions, PHANDLE phToken, PWLX_MPR_NOTIFY_INFO pMprNotifyInfo, PVOID* pProfile)
23 ixe013 468
{
215 ixe013 469
    int result;
470
    TRACE(eDEBUG, L"WlxLoggedOutSAS\n");
471
    result =  pfWlxLoggedOutSAS(GetHookedContext(pWlxContext), dwSasType, pAuthenticationId, pLogonSid, pdwOptions, phToken, pMprNotifyInfo, pProfile);
40 ixe013 472
 
215 ixe013 473
    //Wheter we were doing a normal, self serve or auto logon, its a regular logon from here on
474
    GetMyContext(pWlxContext)->mLogonScenario = eRegularLogon;
40 ixe013 475
 
215 ixe013 476
    if (result == WLX_SAS_ACTION_LOGON)
477
    {
478
        //A user might have gotten hold of the selfserve username's password.
479
        //Whatever the reason for logging in with the selfserve account, when
480
        //you do, you get the selfservice shell.
481
        wchar_t username[255];
91 ixe013 482
 
215 ixe013 483
        if (GetSelfServeSetting(L"Username", username, sizeof username / sizeof * username) == S_OK)
484
        {
485
            PSID selfservesid = 0;
91 ixe013 486
 
215 ixe013 487
            if (GetSIDFromUsername(username, &selfservesid))
134 ixe013 488
            {
218 ixe013 489
                TOKEN_USER *tu = 0;
134 ixe013 490
 
218 ixe013 491
                if (GetSIDFromToken(*phToken, &tu))
215 ixe013 492
                {
218 ixe013 493
                    PSID tokensid = 0;
494
                    tokensid = tu->User.Sid;
495
 
215 ixe013 496
                    if (EqualSid(selfservesid, tokensid))
497
                    {
498
                        GetMyContext(pWlxContext)->mLogonScenario = eSelfServeLogon;
499
                    }
500
 
218 ixe013 501
                    HeapFree(GetProcessHeap(), 0, tu);
215 ixe013 502
                }
503
 
504
                HeapFree(GetProcessHeap(), 0, selfservesid);
134 ixe013 505
            }
215 ixe013 506
        }
137 ixe013 507
 
215 ixe013 508
        GetMyContext(pWlxContext)->mCurrentUser = *phToken;
509
    }
510
    else
511
    {
512
        TRACE(eERROR, L"Logon failed or cancelled.\n");
513
    }
134 ixe013 514
 
215 ixe013 515
    return result;
2 ixe013 516
}
517
 
518
 
519
BOOL WINAPI WlxActivateUserShell(PVOID pWlxContext, PWSTR pszDesktopName, PWSTR pszMprLogonScript, PVOID pEnvironment)
520
{
215 ixe013 521
    BOOL result = FALSE;
522
    TRACE(eDEBUG, L"WlxActivateUserShell\n");
109 ixe013 523
 
215 ixe013 524
    if (GetMyContext(pWlxContext)->mLogonScenario == eSelfServeLogon)
525
    {
526
        wchar_t shell[MAX_PATH];
118 ixe013 527
 
215 ixe013 528
        if (GetSelfServeSetting(L"Shell", shell, sizeof shell / sizeof * shell) == S_OK)
529
        {
530
            TRACE(eERROR, L"Switching to selfservice account\n");
531
            //TODO : Deny Administrator group in token (not sure it will work)
532
            //TODO : Allow for command line parameters (could be in the registry, with placemarks ?)
533
            result = CreateProcessAsUserOnDesktop(GetMyContext(pWlxContext)->mCurrentUser, shell, pszDesktopName, pEnvironment);
534
        }
137 ixe013 535
 
215 ixe013 536
        if (*gUsername)
537
        {
538
            HKEY reg;
137 ixe013 539
 
215 ixe013 540
            if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon", 0, KEY_WRITE, &reg) == ERROR_SUCCESS)
541
            {
221 ixe013 542
                RegSetValueEx(reg, L"DefaultUserName", 0, REG_SZ, (BYTE*)gUsername, (DWORD)(sizeof(wchar_t) * (wcslen(gUsername) + 1)));
215 ixe013 543
                RegCloseKey(reg);
544
                *gUsername = 0;
545
            }
546
        }
547
    }
118 ixe013 548
 
215 ixe013 549
    if (!result)
550
    {
551
        result = pfWlxActivateUserShell(GetHookedContext(pWlxContext), pszDesktopName, pszMprLogonScript, pEnvironment);
552
    }
109 ixe013 553
 
215 ixe013 554
    return result;
2 ixe013 555
}
556
 
557
 
558
int WINAPI WlxLoggedOnSAS(PVOID pWlxContext, DWORD dwSasType, PVOID pReserved)
559
{
215 ixe013 560
    int result;
561
    TRACE(eDEBUG, L"WlxLoggedOnSAS, type %d\n", dwSasType);
91 ixe013 562
 
215 ixe013 563
    //WlxIsLockOk should have been called before getting here
564
    //But since this is not documented anywhere, I check for
565
    //that condition explicitly
566
    if (dwSasType == WLX_SAS_TYPE_TIMEOUT)
567
    {
568
        GetMyContext(pWlxContext)->mLogonScenario = eSelfServeLogonTimeout;
569
    }
91 ixe013 570
 
215 ixe013 571
    //If you press CTRL-ALT-DEL in the selfservice shell, the user is logged off
572
    if ((GetMyContext(pWlxContext)->mLogonScenario == eSelfServeLogon)
573
            || (GetMyContext(pWlxContext)->mLogonScenario == eSelfServeLogonTimeout))
574
    {
575
        TRACEMORE(eDEBUG, L" received in a selfservice context\n");
576
        result = WLX_SAS_ACTION_LOGOFF;
577
    }
578
    else
579
    {
580
        TRACEMORE(eDEBUG, L"\n");
581
        result = pfWlxLoggedOnSAS(GetHookedContext(pWlxContext), dwSasType, pReserved);
127 ixe013 582
 
215 ixe013 583
        //We unlocked a user. Maybe the user that unlock would like to log back in 
584
        //again without having to enter his password again. Flags were set, will get to that 
585
    }
91 ixe013 586
 
215 ixe013 587
    return result;
2 ixe013 588
}
589
 
590
 
591
VOID WINAPI WlxDisplayLockedNotice(PVOID pWlxContext)
592
{
215 ixe013 593
    TRACE(eDEBUG, L"WlxDisplayLockedNotice\n");
594
    pfWlxDisplayLockedNotice(GetHookedContext(pWlxContext));
2 ixe013 595
}
596
 
597
 
598
BOOL WINAPI WlxIsLockOk(PVOID pWlxContext)
599
{
215 ixe013 600
    BOOL result = TRUE;
601
    TRACE(eDEBUG, L"WlxIsLockOk\n");
129 ixe013 602
 
215 ixe013 603
    //Lock is not OK in self serve mode. Else let MSGINA decide
604
    if((GetMyContext(pWlxContext)->mLogonScenario == eSelfServeLogon)
605
    || (GetMyContext(pWlxContext)->mLogonScenario == eSelfServeLogon))
606
    {
607
        //Lock is not allowed, we just log off
608
        result = FALSE;
609
        ((PWLX_DISPATCH_VERSION_1_0) g_pWinlogon)->WlxSasNotify(gAucunContext.Winlogon, WLX_SAS_TYPE_CTRL_ALT_DEL);
610
        //We clear the flag right now, so the next user has to press CTRL-ALT-DEL
611
        GetMyContext(pWlxContext)->mLogonScenario = eSelfServeLogonTimeout;
612
    }
613
    else
614
    {
615
        result = pfWlxIsLockOk(GetHookedContext(pWlxContext));
616
    }
129 ixe013 617
 
215 ixe013 618
    return result;
2 ixe013 619
}
620
 
621
 
622
int WINAPI WlxWkstaLockedSAS(PVOID pWlxContext, DWORD dwSasType)
623
{
215 ixe013 624
    int result;
625
    TRACE(eDEBUG, L"WlxWkstaLockedSAS\n");
626
    result = pfWlxWkstaLockedSAS(GetHookedContext(pWlxContext), dwSasType);
40 ixe013 627
 
215 ixe013 628
    if (result == WLX_SAS_ACTION_LOGOFF)
629
    {
630
        TRACE(eERROR, L"Proceding with a force logoff (comming from AUCUN).\n");
631
        result = WLX_SAS_ACTION_FORCE_LOGOFF;
632
    }
40 ixe013 633
 
215 ixe013 634
    return result;
2 ixe013 635
}
636
 
637
 
638
BOOL WINAPI WlxIsLogoffOk(PVOID pWlxContext)
639
{
215 ixe013 640
    TRACE(eDEBUG, L"WlxIsLogoffOk\n");
641
    return pfWlxIsLogoffOk(GetHookedContext(pWlxContext));
2 ixe013 642
}
643
 
644
 
645
VOID WINAPI WlxLogoff(PVOID pWlxContext)
646
{
215 ixe013 647
    TRACE(eDEBUG, L"WlxLogoff\n");
648
    pfWlxLogoff(GetHookedContext(pWlxContext));
649
    GetMyContext(pWlxContext)->mCurrentUser = 0;
2 ixe013 650
}
651
 
652
 
653
VOID WINAPI WlxShutdown(PVOID pWlxContext, DWORD ShutdownType)
654
{
215 ixe013 655
    TRACE(eDEBUG, L"WlxShutdown\n");
656
    pfWlxShutdown(GetHookedContext(pWlxContext), ShutdownType);
657
    LsaDeregisterLogonProcess(GetMyContext(pWlxContext)->mLSA);
216 ixe013 658
    //The original Ginahook sample didn't release the DLL before shutting down.
659
    //A user noticed a crash when the machine was shutdown. Turns out that WlxShutdown
660
    //is not the last function called by Winlogon. WlxDisplayStatusMessage might be
661
    //called a few more times.
662
    //Since we are shutting down anyway, cleaning up is more trouble than its worth.
663
    //FreeLibrary(hDll);
664
    //FreeLibrary(hResourceDll);
2 ixe013 665
}
666
 
667
 
668
//
669
// New for version 1.1
670
//
215 ixe013 671
BOOL WINAPI WlxScreenSaverNotify(PVOID  pWlxContext, BOOL* pSecure)
2 ixe013 672
{
215 ixe013 673
    TRACE(eDEBUG, L"WlxScreenSaverNotify\n");
674
    return pfWlxScreenSaverNotify(GetHookedContext(pWlxContext), pSecure);
2 ixe013 675
}
676
 
677
BOOL WINAPI WlxStartApplication(PVOID pWlxContext, PWSTR pszDesktopName, PVOID pEnvironment, PWSTR pszCmdLine)
678
{
216 ixe013 679
    BOOL result;
680
    result = pfWlxStartApplication(GetHookedContext(pWlxContext), pszDesktopName, pEnvironment, pszCmdLine);
681
    TRACE(eDEBUG, L"WlxStartApplication %s returned %d\n", pszCmdLine, result);
682
    return result;
2 ixe013 683
}
684
 
685
 
686
//
687
// New for version 1.3
688
//
689
 
690
BOOL WINAPI WlxNetworkProviderLoad(PVOID pWlxContext, PWLX_MPR_NOTIFY_INFO pNprNotifyInfo)
691
{
215 ixe013 692
    TRACE(eDEBUG, L"WlxNetworkProviderLoad\n");
693
    return pfWlxNetworkProviderLoad(GetHookedContext(pWlxContext), pNprNotifyInfo);
2 ixe013 694
}
695
 
696
 
697
BOOL WINAPI WlxDisplayStatusMessage(PVOID pWlxContext, HDESK hDesktop, DWORD dwOptions, PWSTR pTitle, PWSTR pMessage)
698
{
215 ixe013 699
    TRACE(eDEBUG, L"WlxDisplayStatusMessage\n");
700
    return pfWlxDisplayStatusMessage(GetHookedContext(pWlxContext), hDesktop, dwOptions, pTitle, pMessage);
2 ixe013 701
}
702
 
703
 
215 ixe013 704
BOOL WINAPI WlxGetStatusMessage(PVOID pWlxContext, DWORD* pdwOptions, PWSTR pMessage, DWORD dwBufferSize)
2 ixe013 705
{
215 ixe013 706
    TRACE(eDEBUG, L"WlxGetStatusMessage\n");
707
    return pfWlxGetStatusMessage(GetHookedContext(pWlxContext), pdwOptions, pMessage, dwBufferSize);
2 ixe013 708
}
709
 
710
 
711
BOOL WINAPI WlxRemoveStatusMessage(PVOID pWlxContext)
712
{
215 ixe013 713
    TRACE(eDEBUG, L"WlxRemoveStatusMessage\n");
714
    return pfWlxRemoveStatusMessage(GetHookedContext(pWlxContext));
2 ixe013 715
}
716
 
717
 
718
//
719
// New for 1.4
720
//
23 ixe013 721
BOOL WINAPI WlxGetConsoleSwitchCredentials(PVOID pWlxContext, PVOID pCredInfo)
2 ixe013 722
{
215 ixe013 723
    TRACE(eDEBUG, L"WlxGetConsoleSwitchCredentials\n");
724
    return pfWlxGetConsoleSwitchCredentials(GetHookedContext(pWlxContext), pCredInfo);
2 ixe013 725
}
726
 
23 ixe013 727
VOID WINAPI WlxReconnectNotify(PVOID pWlxContext)
2 ixe013 728
{
215 ixe013 729
    TRACE(eDEBUG, L"WlxReconnectNotify\n");
730
    pfWlxReconnectNotify(GetHookedContext(pWlxContext));
2 ixe013 731
}
732
 
23 ixe013 733
VOID WINAPI WlxDisconnectNotify(PVOID pWlxContext)
2 ixe013 734
{
215 ixe013 735
    TRACE(eDEBUG, L"WlxDisconnectNotify\n");
736
    pfWlxDisconnectNotify(GetHookedContext(pWlxContext));
2 ixe013 737
}