Subversion Repositories Aucun

Rev

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