LsaGetLogonSessionData API returns session data without logonServer - windows

I am using LsaGetLogonSessionData to retrieve the logonSessionData on a machine that is using AD and Kerberos in a Domain Controller as a login method.
However, the logonServer field is empty in logonSessionData. But from commandline, I'm able to get the logonServer by using nltest/dsgetdc or set l command.
Anyone knows why I am not able to get logonServer from the code?
Attaching code snippet as below:
PSECURITY_LOGON_SESSION_DATA logonSessionData;
for (ULONG i = 0; i < logonSessionCount; i++) {
if (::LsaGetLogonSessionData(logonSessionList + i, &logonSessionData) != 0) {
LsaFreeReturnBuffer(logonSessionList);
DWORD error = ::GetLastError();
LOG_ERROR("GetActiveLogonUser: LsaGetLogonSessionData failed ", error);
return error;
}
if (std::count(sessions.begin(), sessions.end(), logonSessionData->Session) &&
(logonSessionData->LogonType == Interactive || logonSessionData->LogonType == RemoteInteractive)) {
const std::wstring logonServer = logonSessionData->LogonServer.Buffer;
if (!logonServer.size()) continue;
std::wstring domain = logonSessionData->LogonDomain.Buffer;
std::wstring userName = logonSessionData->UserName.Buffer;
logonUsers[StringUtils::GetStringFromWString(domain + std::wstring(TEXT("-")) + userName)] =
logonSessionData->Session;
}
}

Related

ESP32 send large file (http post) to server from LittleFS

I'm trying to post a (large) json file that's stored in the SPIFFS (LittleFS- of an arduino.
I first of all, fetch the JSON from a local IP address, which can change or is dynamic. Then, that json file gets stored in the internal flash of my ESP32 and sent over to our servers.
The goal is to have an ESP32 act as a bridge for local addresses.
For example:
Locally, there is a server running, that server is never accessible from outside of a network, but it is from within. We place an ESP32 in that network, to be able to read out data from the internal device and pass them through to our servers, for further processing.
The current code I have is the following;
HTTPClient http;
if (LittleFS.exists("/downloadedFile.json")) {
LittleFS.remove("/downloadedFile.json");
}
File f = LittleFS.open("/downloadedFile.json", "w", true);
if (f) {
String url;
// Build the URL...
if (username != "" && password != "") {
url = "http://" + username + ":" + password + "#" + ip + ":" + String(port) + "/data/file.json";
} else {
url = "http://" + ip + ":" + String(port) + "/data/file.json";
}
http.begin(url);
int httpCode = http.GET();
if (httpCode > 0) {
if (httpCode == HTTP_CODE_OK) {
http.writeToStream(&f);
}
} else {
// failed.
}
f.close();
} else {
// Unable to open file
}
http.end();
if (LittleFS.exists("/downloadedFile.json")) {
File f = LittleFS.open("/downloadedFile.json", "r");
if (f) {
WiFiClienSecure client;
client.setInsecure(); // test
if (!client.connect("my.somain.com", 443)) {
// failed to connect. (never gets in here)
return;
}
client.println("POST /path/to/my/endpoint HTTP/1.1");
client.println("Host: my.somain.com");
client.println("Content-Type: application/json");
client.println("Connection: keep-alive");
client.println("Content-Length: " + String(f.size()));
client.println();
// Build the body
int len = 0;
int total = 0;
uint8_t buf[1025] = {};
size_t _len = 256;
do {
len = f.read(buf, _len);
client.write(buf, len);
total += len;
} while (len > 0);
client.println(); // end line
client.stop();
f.close();
}
}
Downloading the file always works, except for sometimes random crashing the whole system. But that's the least of my concerns.
Locally I got it working to download and re-upload the file. Struggle is when I try to achieve the same result on the server (which uses https)
Only difference is this;
Server
Local
WiFiClienSecure client;
WiFiClient client;
client.setInsecure();
client.connect("my.somain.com", 443)
client.connect("IP", 80)
The main problem is that it doesn't work on the server and that it works really unstable. the file size (when I do f.size()) is 310831.
Any help and thoughts on getting this stable is appriciated!

SetPerTcpConnectionEStats and GetPerTcpConnectionEStats is returning error code 1214 (invalid NETNAME)

I am trying to get stats similar to the ones shown in "Resource Monitor" in windows in a my c++ service. For that I have used the example shown at https://learn.microsoft.com/en-gb/windows/win32/api/iphlpapi/nf-iphlpapi-getpertcp6connectionestats?redirectedfrom=MSDN. But I am stuck because SetPerTcpConnectionEStats and GetPerTcpConnectionEStats is returning with error code 1214. The only difference btn. the code in the example at above mentioned link and mine is that I am not working on a particular local and remote port but on all the entries in the tcp table, but I don't think that should make any difference.
Can somebody help me out here?
I can reproduce this error if I work with all the entries. According to the sample you linked, in addition to local and remote port, GetTcpRow has a search parameter MIB_TCP_STATE_ESTAB. The state is the normal state for the data transfer phase of the TCP connection.
The following sample works for me.
DWORD RunEstatsTest(bool v6) //set as IPv4(FALSE)
{
PMIB_TCPTABLE tcpTable = NULL;
DWORD status, size = 0;
status = GetTcpTable(tcpTable, &size, TRUE);
if (status != ERROR_INSUFFICIENT_BUFFER) {
return status;
}
tcpTable = (PMIB_TCPTABLE)malloc(size);
if (tcpTable == NULL) {
return ERROR_OUTOFMEMORY;
}
status = GetTcpTable(tcpTable, &size, TRUE);
if (status != ERROR_SUCCESS) {
free(tcpTable);
return status;
}
for (int i = 0; i < tcpTable->dwNumEntries; i++) {
if (MIB_TCP_STATE_ESTAB == tcpTable->table[i].State)
{
ToggleAllEstats(&tcpTable->table[i], TRUE, v6);
GetAllEstats(&tcpTable->table[i], v6);
ToggleAllEstats(&tcpTable->table[i], FALSE, v6);
}
}
free(tcpTable);
return ERROR_SUCCESS;
}

Catch incoming emails and send them to a web service (rather than just to a mail server)

I would like to catch incoming emails and send them a web service (rather than just to a mail server).
--
After some searching I found a way of getting new emails via polling - see below: This may be of some help to others. Is there a way to receive messages by SMTP? Perhaps by ISAPI ???
using Limilabs.Mail;
using Limilabs.Client.IMAP;
public ActionResult checkIMAPmail()
{
string rval = "not a sausage";
using (Imap imap = new Imap())
{
imap.Connect(<mail server>);
imap.Login(<username>, <password>);
imap.SelectInbox();
List<long> uids = imap.Search(Flag.Unseen);
foreach (long uid in uids)
{
byte[] ourBytes = imap.GetMessageByUID(uid);
IMail email = new MailBuilder().CreateFromEml(ourBytes);
rval = email.Subject + " [" + email.From + "][" + email.Text + "]";
}
imap.Close();
}
return Content(rval, "text/html");
}
See also http://stackoverflow.com/questions/670183/accessing-imap-in-c-sharp
for other IMAP packages, although note the change to using byte[], above.
Given that Limilabs.Mail is a paid service, I finally used MailKit:
using MailKit;
public int checkIMAPmail()
{
int numEmails = 0;
try {
using (var client = new MailKit.Net.Imap.ImapClient())
{
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect(ourSmtpClient);
// disable the XOAUTH2 authentication mechanism.
client.AuthenticationMechanisms.Remove("XOAUTH2");
client.Authenticate(ourSmtpAdminUser, ourSmtpAdminUserPwd);
// The Inbox folder is always available on all IMAP servers...
var inboxFolder = client.Inbox;
var savedFolder = client.GetFolder("saved");
inboxFolder.Open(FolderAccess.ReadWrite);
for (int ii = 0; ii < inboxFolder.Count; ii++)
{
var query = MailKit.Search.SearchQuery.NotSeen;
foreach (var uid in inboxFolder.Search(query))
{
var thisMsg = inboxFolder.GetMessage(uid);
string thisDate = notNullString(thisMsg.Date);
string thisSubject = notNullString( thisMsg.Subject);
string thisBody = notNullString(thisMsg.GetTextBody(0)); // plain text
string thisFromName = "";
string thisFromEmail = "";
if ( thisMsg.From != null)
{
// just get the first
foreach( var mb in thisMsg.From.Mailboxes)
{
thisFromName = notNullString( mb.Name);
thisFromEmail = notNullString( mb.Address);
break;
}
}
numEmails += 1;
// move email to saved
inboxFolder.MoveTo(uid, savedFolder);
}
}
client.Disconnect(true);
}
}
catch (Exception exc)
{
log2file("checkIMAPmail Error: " + exc.ToString());
}
return numEmails;
}

Get the local login name for the given Microsoft Account returned by NetWkstaUserEnum API on Windows 8 and above

I am using NetWkstaUserEnum() to get the local users name and its domain details.
Till Windows 7 it used to return only the login name and it worked fine. From Windows 8 onwards Microsoft Account was added and for this type of account the API started returning the Microsoft Account name instead of the local login name.
For example it returned username#outlook.com instead of usern_0000 which is the actual Windows local login name.
I cannot use NetUserEnum() as it does not return the domain name of the user.
So I need to get the local login name for the given Microsoft Account returned by NetWkstaUserEnum() API.
Any help will be appreciated.
Finally I was able to locate a way to get the Windows username for the given Microsoft Account.It uses NetUserGetInfo() to get the Microsoft Account name for the given username.
Code Snippet:
do
{
ntStatus = NetUserEnum(szSvr, 0, 0, (LPBYTE*)&userInfo0, dwPrefMaxLen, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
if( (ntStatus == NERR_Success) || (ntStatus == ERROR_MORE_DATA) )
{
tmpinfo = userInfo0;
for( i = 0; (i < dwEntriesRead); i++ )
{
if(tmpinfo != NULL)
{
ntStatus = NetUserGetInfo(szSvr, tmpinfo->usri0_name, 24,(LPBYTE*)&userInfo24);
if(ntStatus == NERR_Success)
{
CString internetPrincipalName = (LPCWSTR) userInfo24->usri24_internet_principal_name;
if(LoginUsrStr.CompareNoCase(internetPrincipalName) == 0)
{
OutputDebugString("###### Account Found ######");
localAccount = (LPCWSTR) tmpinfo->usri0_name;
userFound = TRUE;
break;
}
}
}
tmpinfo++;
}
}
if( userInfo0 != NULL )
{
NetApiBufferFree( userInfo0 ) ;
userInfo0 = NULL ;
}
if( userInfo24 != NULL )
{
NetApiBufferFree( userInfo24 ) ;
userInfo24 = NULL ;
}
} while( userFound == FALSE && ntStatus == ERROR_MORE_DATA ) ;

Windows Event Log : Event template - Output type: win:Xml

I am making Windows event log for my application that support Vista and above. I have a manifest created for each event, but I get a issue with the output type of win:Xml.
Below is what I specify for the data in event template.
<data name="StackTrace" inType="win:UnicodeString" outType="win:Xml">
</data>
I would like to set the StackTrace to be displayed as XML format in the Event logs. StackTrace must be input with well-formed XML. However, I still see it displayed as string(xs:string) in the Event Log viewer.
Do you know what I did wrong? How can I make it properly?
Below if update for my code:
const int NUM_OF_DATADESC = 6;
EVENT_DATA_DESCRIPTOR eventDataDesc[NUM_OF_DATADESC];
evDesc.Level = uLevel;
evDesc.Channel = nChannel;
evDesc.Keyword |= uKeyword;
for (int i = 0; i < NUM_OF_DATADESC; i++)
{
if (strings[i] != NULL)
EventDataDescCreate(&eventDataDesc[i], strings[i], ((ULONG)wcslen(strings[i])+1)*sizeof(WCHAR));
else
EventDataDescCreate(&eventDataDesc[i], L"", sizeof(WCHAR));
}
BOOL s = WriteEvent(evDesc,NUM_OF_DATADESC,&eventDataDesc[0]);
BOOL WriteEvent(EVENT_DESCRIPTOR eventID,DWORD userDataCount,PEVENT_DATA_DESCRIPTOR userData)
{
REGHANDLE hPub = NULL;
ULONG res = EventRegister(&MYCOMPANE_MYAPP_MYCOMPONENT, NULL, NULL, &hPub);
if (ERROR_SUCCESS != res){
return FALSE;
}
res = EventWrite(hPub, &eventID, userDataCount, userData);
if (ERROR_SUCCESS != res){
return FALSE;
}
EventUnregister(hPub);
return TRUE;
}
The code is working fine, but only issue with output type = win:Xml.

Resources