After reading several questions including Implementation of Custom Windows Authentication Package - LsaApUserLogonEx and Custom Windows Authentication Package I am still confused at how to make an AP.
I made a sample implementation with following functions:
LsaApInitializePackage
LsaApCallPackage
LsaApCallPackagePassthrough
LsaApCallPackageUntrusted
LsaApLogonTerminated
LsaApLogonUser
SpLsaModeInitialize
SpShutDown
SpInitialize
However, I can only use it to unlock a workstation, but it cannot be used to log a user on. And when I tried to change to LsaApLogonUser2
, things remained the same, but leaving Lsa crashed when logging users on.
More interestingly, the LogonType is always 2 (and I think that means Network), even though I passed the parameter "Interactive" to LsaLogonUser.
And I really wonder why these would happed. Below is my code for LsaApLogonUser.
NTSTATUS LsaApLogonUser(
PLSA_CLIENT_REQUEST ClientRequest,
SECURITY_LOGON_TYPE LogonType,
PVOID AuthenticationInformation,
PVOID ClientAuthenticationBase,
ULONG AuthenticationInformationLength,
PVOID *ProfileBuffer,
PULONG ProfileBufferLength,
PLUID LogonId,
PNTSTATUS SubStatus,
PLSA_TOKEN_INFORMATION_TYPE TokenInformationType,
PVOID *TokenInformation,
PLSA_UNICODE_STRING *AccountName,
PLSA_UNICODE_STRING *AuthenticatingAuthority
){
DispatchTable.AllocateClientBuffer(ClientRequest,32,ProfileBuffer);
*ProfileBufferLength=32;
AllocateLocallyUniqueId(LogonId);
DispatchTable.CreateLogonSession(LogonId);
*SubStatus=STATUS_SUCCESS;
*TokenInformationType=LsaTokenInformationV1;
_LSA_TOKEN_INFORMATION_V1 *tTokenInformation=reinterpret_cast<_LSA_TOKEN_INFORMATION_V1*>(DispatchTable.AllocateLsaHeap(sizeof(_LSA_TOKEN_INFORMATION_V1)));
tTokenInformation->ExpirationTime.QuadPart=99999999999l;
tTokenInformation->Privileges=reinterpret_cast<PTOKEN_PRIVILEGES>(DispatchTable.AllocateLsaHeap(sizeof(_TOKEN_PRIVILEGES)));
tTokenInformation->Privileges->PrivilegeCount=1;
LookupPrivilegeValue(NULL,"SeLockMemoryPrivilege",&tTokenInformation->Privileges->Privileges[0].Luid);
tTokenInformation->Privileges->Privileges[0].Attributes=SE_PRIVILEGE_ENABLED_BY_DEFAULT;
tTokenInformation->Owner.Owner=NULL;
tTokenInformation->DefaultDacl.DefaultDacl=NULL;
tTokenInformation->Groups=reinterpret_cast<PTOKEN_GROUPS>(DispatchTable.AllocateLsaHeap(sizeof(TOKEN_GROUPS)));
tTokenInformation->Groups->GroupCount=0;
LPUSER_INFO_23 pBuf = NULL;
NET_API_STATUS nStatus = NetUserGetInfo(NULL,L"6ziv", 23, (LPBYTE *) & pBuf);
tTokenInformation->User.User.Sid=pBuf->usri23_user_sid;
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
PSID tmp;
AllocateAndInitializeSid(&SIDAuth,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ACCOUNT_OPS,0,0,0,0,0,0,&tTokenInformation->PrimaryGroup.PrimaryGroup);
NetApiBufferFree(pBuf);
*TokenInformation=tTokenInformation;
*AccountName=reinterpret_cast<LSA_UNICODE_STRING*>(DispatchTable.AllocateLsaHeap(sizeof(LSA_UNICODE_STRING)));//
(*AccountName)->Length=4*sizeof(wchar_t);
(*AccountName)->MaximumLength=64;
(*AccountName)->Buffer=reinterpret_cast<PWSTR>(DispatchTable.AllocateLsaHeap(64));
wcscpy((*AccountName)->Buffer,L"6ziv");
*AuthenticatingAuthority=reinterpret_cast<LSA_UNICODE_STRING*>(DispatchTable.AllocateLsaHeap(sizeof(LSA_UNICODE_STRING)));//
(*AuthenticatingAuthority)->Length=10*sizeof(wchar_t);
(*AuthenticatingAuthority)->MaximumLength=64;
(*AuthenticatingAuthority)->Buffer=reinterpret_cast<PWSTR>(DispatchTable.AllocateLsaHeap(64));
wcscpy((*AuthenticatingAuthority)->Buffer,L"MyComputer");
ofstream myfile;
myfile.open("C:/Users/6ziv/Desktop/MySSP.txt", std::ofstream::app);
myfile << "LOGON"<<LogonType << endl;
myfile.close();
return STATUS_SUCCESS;
}