How to Fix Error 1935 on Win32 API LogonUser() Function - c++

I'm trying to use this Function.
The User I'm trying to impersonate is not in the same domain.
I can mount the Server using the credentials just fine.
But whenever I call LogonUser
bLogonSucc = ::LogonUser(sUserName
, sDomain
, sUserPW
, LOGON32_LOGON_INTERACTIVE
, LOGON32_PROVIDER_DEFAULT
, &hToken);
I get the error 1935:
ERROR_AUTHENTICATION_FIREWALL_FAILED
1935 (0x78F)
The computer you are signing into is protected by an authentication firewall. The specified account is not allowed to authenticate to the computer.
My goal is to open a File on a Server, where the User is used as Login to said destination and open the File.
If I use LOGON32_LOGON_NEW_CREDENTIALS as Parameter, the LogonUser Function & Impersonate works, but somehow still doesn't work later on in the code.
Can't seem to find a solution for this.
Any Ideas on how to solve this?
The Firewall should be setup correctly.

This error occurs because the user or group, has been granted the correct rights to access the share. But the share is in another domain, and even though that domain trusts the one the user is coming from, the trust was set up with ‘selective authentication’.
You can try this.
Go to the domain that’s providing the share, log into a domain controller
Open 'Control Panel\System and Security\Administrative Tools'
Open ‘Active Directory Users and Computers’
View
Advanced Features
Locate the COMPUTER you are trying to authenticate
Properties
Security
Add in the user (or group) that requires access
Grant the “Allowed to authenticate” right
Apply and OK

Related

Active Directory: ADsOpenObject fails when called from a Windows Service running under Network Service account

I have an application that can run as an EXE or as a windows service. This application, when it starts up, tries to connect to an Active Directory server and download a list of users that are members of a specified group. When I run as an EXE, this works fine, no problems. When I run as a windows service, I run under the Network Service account, and it does not work. Specifically, the following call to ADsOpenObject fails:
HRESULT hr = ADsOpenObject(ldapPath.c_str(),
NULL,
NULL,
ADS_SECURE_AUTHENTICATION,
IID_IDirectorySearch,
(void**)&domainToSearch);
The failure code returned is 0x8007952E, which means "supplied credentials are invalid".
The value of ldapPath is something like this: L"LDAP://(server-ip)/DC=(server-name),DC=local"
As you can see, I am passing in NULL and NULL for the user name and password. When running as an EXE, this call will present the credentials of the logged in user. As long as that user has an account on the Active Directory server, this call will succeed. When running as a service under the Network Service account, as I understand it, this call will present the credentials of my computer. I added a computer account for my machine on the AD server, but this call still fails every time. I looked at the security event log on the server, and I can see that the logon attempts from my service are failing with the error "Unknown user or bad password", and the "Account Name" is (my computer)$. So it appears that I have not setup the computer account correctly on the AD server.
So my question is: What is the correct way to setup a computer account in Active Directory in order for a service running on that computer to be able to make an ADsOpenObject call without providing a user name and password?
I should also point out that my computer is logged into a different domain than the AD server I am trying to query, that is why I include the IP address in the LDAP string. Is that a problem? Again, this approach works fine from an EXE, so I assumed it would work fine from a Service.
No, my computer is not on the same domain as the AD server.
This is your issue. The computer can only authenticate to the domain using the computer account only if it is joined to the same or a trusted domain. Otherwise, the domain will have no idea who you are.
You can pass different credentials into ADsOpenObject. The username and password are the second and third parameters that you are setting to NULL.

"'POWERBI_ROLE' specified in the connect string is not granted to this user....."

I'm following the tutorial from here: https://community.snowflake.com/s/article/Amplifying-Outcomes-with-Snowflake
In PowerBI Desktop, I'm trying to "Get Data" and receive the following error: Details: "ODBC: ERROR [28000] Role 'POWERBI_ROLE' specified in the connect string is not granted to this user. Contact your local system administrator, or attempt to login with another role, e.g. PUBLIC.
ERROR [28000] Role 'POWERBI_ROLE' specified in the connect string is not granted to this user. Contact your local system administrator, or attempt to login with another role, e.g. PUBLIC."
In snowflake I've added the role to the user by using the query:
ALTER USER POWERBI_USER_ACCOUNT SET DEFAULT_ROLE=POWERBI_ROLE;
I've done this multiple times in snowflake, and did not receive an
error.
I've tried editing the ODBC connection in the "ODBC Data Source
Administrator (64-bit)" WIndows OS pref pane, and used the role
PUBLIC as suggested, but still receive the same error.
Any suggestions?
Also, does snowflake provide technical support, or are users left to post in public forums for technical support? A bit confused.
You need to run the following to grant the role to the user
GRANT ROLE POWERBI_ROLE TO USER POWERBI_USER_ACCOUNT
Looks like the article is missing this step.
Snowflake does provide tech support, you need to work with your account rep to set it up.

Using LogonUser() only to Validate Credentials

We are developing an application with an internal user accounts system, but would like to be able to use credentials from Active Directory and/or Windows accounts. To that end we store the User SID in a field in the application's users table. Our login mechanism functions like this:
Prompt user for domain, login, password
Call LogonUser(logon, domain, password, logon_type, logon_provider, &hToken)
If successful, get User SID from hToken
Close hToken
Search our application's database for a user with the given SID; if found, we are considered logged in to that account.
The problem that has come up is this: we have been using LOGON32_LOGON_NETWORK for the logon_type, but we have now run into some security configurations where "Access this computer from the network" is denied, meaning the Network logon type is prohibited.
My question is what logon type should we be using for this situation? Interactive? We are not actually using the Logon token for anything other than extracting the user's SID. Our application has its own internal groups and permissions; we do not use Windows groups or permissions in any way. From the perspective of Windows and the domain controller, all we are doing is logging on and quickly logging off.
Or are we looking at this in a completely wrong way, and we should be using some other login method entirely?
Thanks
I also have been surprised to find out that the LogonUser() with the LOGON32_LOGON_NETWORK type fails when user right "Access this computer from the network" is not granted for Everyone on local computer.
I use the following workaround:
First try LogonUser() with the LOGON32_LOGON_NETWORK type.
If it fails with error ERROR_LOGON_TYPE_NOT_GRANTED, call LogonUser() with the LOGON32_LOGON_NEW_CREDENTIALS type and the LOGON32_PROVIDER_WINNT50 logon provider.
You can communicate with the SSPI services to validate a user's credentials and acquire a token, without requiring special privileges. This requires a lot of obscure code and
See http://support.microsoft.com/kb/180548 for an example; the SSPLogonUser function is where the token is acquired.
The convention is to use LOGON32_LOGON_BATCH, as documented:
This logon type is intended for batch servers, where processes may be executing on behalf of a user without their direct intervention. This type is also for higher performance servers that process many plaintext authentication attempts at a time, such as mail or web servers.
(emphasis mine).
The system administrators may still need to reconfigure the server to grant batch logon access to the users in question, but because this does not grant the user access to any Windows functionality (e.g., the ability to use Remote Desktop, to connect to a network share, or to log on interactively if they somehow gain access to the console) this should not be a problem.

WTSConnectSession

I am trying to use this function to connect to a specific user session. I have tried everything and the function always fails with either ERROR_ACCESS_DENIED 5 (0x5) Access is denied or ERROR_CTX_WINSTATION_ACCESS_DENIED 7045 (0x1B85) The requested session access is denied. Even hard-coding the session ID in and the password like this
WTSConnectSession(2, 1 ,TEXT("test1"),false);
Is there a better way to start a user session than to use this function. I am trying to implement Fast User Switching and this is the last piece in the puzzle is to logon a user session. Thank you.
Are sure that you are connecting with username (specified by TargetLogonId parameter) in "Remote Desktop Users" group?
You can check it using
net localgroup "Remote Desktop users"
Another option is to enable security auditing and analyzing security event log.
It will tells you exact root cause of ERROR_CTX_WINSTATION_ACCESS_DENIED

Using DefaultCredentials and DefaultNetworkCredentials

We're having a hard time figuring how these credentials objects work. In fact, they may not work how we expected them to work. Here's an explanation of the current issue.
We got 2 servers that needs to talk with each other through webservices. The first one (let's call it Server01) has a Windows Service running as the NetworkService account. The other one Server02 has ReportingServices running with IIS 6.0. The Windows Service on Server01 is trying to use the Server02 ReportingServices WebService to generate reports and send them by email.
So, here's what we tried so far.
Setting the credentials at runtime (This works perfectly fine):
rs.Credentials = new NetworkCredentials("user", "pass", "domain");
Now, if we could use a generic user all would be fine, however... we are not allowed to. So, we are trying to use the DefaultCredetials or DefaultNetworkCredentials and pass it to the RS Webservice:
rs.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials
Or:
rs.Credentials = System.Net.CredentialCache.DefaultCredentials
Either way won't work. We're always getting 401 Unauthrorized from IIS. Now, what we know is that if we want to give access to a resource logged as NetworkService, we need to grant it to DOMAIN\MachineName$ (http://msdn.microsoft.com/en-us/library/ms998320.aspx):
Granting Access to a Remote SQL Server
If you are accessing a database on another server in the same domain (or in a trusted domain), the Network Service account's network credentials are used to authenticate to the database. The Network Service account's credentials are of the form DomainName\AspNetServer$, where DomainName is the domain of the ASP.NET server and AspNetServer is your Web server name.
For example, if your ASP.NET application runs on a server named SVR1 in the domain CONTOSO, the SQL Server sees a database access request from CONTOSO\SVR1$.
We assumed that granting access the same way with IIS would work. However, it does not. Or at least, something is not set properly for it to authenticate correctly.
So, here are some questions:
We've read about "Impersonating Users" somewhere, do we need to set this somewhere in the Windows Service ?
Is it possible to grant access to the NetworkService built-in account to a remote IIS server ?
Thanks for reading!
All details you need are included in this very old article
In short, when you find it confusing to troubleshoot issues like this, you should first review the technical details behind ASP.NET impersonation carefully.
Here are some things you could check out:
- set an SPN (Service Principal Name) for the reporting service; you can find good examples in google;
- Allow delegation (ClientCredentials.Windows.AllowImpersonationLevel)
Is the problem that you're failing to authenticate to IIS, or failing to authenticate to SSRS? The DOMAIN\MachineName$ account may need to be granted permission in SSRS to run the report you're trying to automate.
SSRS usually does a pretty good job of getting IIS configured correctly, so you shouldn't need to mess with those settings. I double-checked my installation (which is SSRS 2005, things may have worked differently in SSRS 2000 and you didn't say which version you're running), and it's set to use Windows authentication and has impersonation enabled. That means IIS should basically just be authenticating your credentials (validating a correct username/password), not authorizing (determining whether that user has permission to run the report in question). IIS then passes the credentials on to SSRS, which has its own settings for determining what accounts have permission to view reports.
Also, you can automate sending reports on a scheduled basis directly in SSRS, so you may not need the Windows service at all if your scheduling is fairly basic (i.e., daily, weekly, etc.).