Network drive is unavailable if mapped by service - c

I create a service which is defined to Log On as Administrator.
This service performs system("net use Z: \... /user:user password") and completes successfully.
If I (as Administrator) run "net use" I see Z: indeed added, but with status - unavailable.
I tried adding ImpersonateLoggedOnUser to the service, but that didn't help.
OS: Win XP
What am I missing?

ImpersonateLoggedOnUser doesn't impersonate the logon session from the user token, just the security context. CreateProcessAsUser, however, should be able to create a new process in the logon session associated with the specified user token.
Note that calling LogonUser to get a user token for CreateProcessAsUser won't work, because this token won't be in the same logon session as the logged-on user. You have to find one of the user's processes and duplicate its token.
Logon sessions are not well documented, but all you really need to know that each time a user is authenticated a distinct logon session is created, and that each such logon session has a distinct set of network drive mappings. Logon sessions are not the same as terminal services sessions.
In Windows Vista and above, two logon sessions are created when an administrative user logs in, one associated with the restricted token and one associated with the elevated token.
You can look up the logon session associated with a token using the GetTokenInformation function with the TokenStatistics option. The logon session is identified by the AuthenticationId LUID.
To make this work, your service would need to first figure out when a user has logged in, wait for a process associated with the new session to start, make sure it's not an elevated process, then duplicate the access token.
Instead, your best option is going to be to split the application into two components. One component will run as the user (you would probably launch this automatically using the Run key) and be responsible for mapping the network drive. It can contact the service to obtain any information it needs, either via a named pipe or a registry key.

Windows logs on Administrator and uses the logon token to start the service. If you logon interactively Windows creates a logon token for you. The two tokens are not related to each other. Mapped devices are mapped for one session/logon token, therefore if the service maps a device you do not see it in your logon session.

Related

Access remote resources with impersonated token

I want to impersonation a user on a windows server (2012/2016/2019) in a domain environment.
This should happened by a administrator account with SE_DEBUG and SE_IMPERSONATE privileges.
GetAccessToken()
DuplicateTokenEx()
CreateProcessWithTokenW(token, LOGON_NETCREDENTIALS_ONLY, L"c:\\windows\\system32\\cmd.exe", NULL, 0, FALSE, NULL, &si, &pi)
Until now its working fine.
But i have to read a fileshare on another server in context of the impersonated user/token.
On localhost the created process have all permissions from the original user/process.
If try to access a fileshare or any other server on the Network this results in "Access Denied".
I found out that it is depending on the logon type if users credentials are available on the system which is needed to connect to another system. (double hop)
But also if the impersonated process is started from an interactive logon (tried RDP und runas.exe)there seems to be no rights on remote systems.
I checked the Logon Type of the token GetTokenInformation() to get session id and then call LsaGetLogonSessionData() to get field LogonType.
Where is the difference between this and get TokenOrigin Variable from GetTokenInformation?
Which configuration allows me to access remote share with the impersonated token?
There's no difference in impersonating a admin vs non-admin, but a LOCAL admin does not necessarily have access to the another machine. A domain user does.

How to ensure the security of admin password stored in database for synchronization with LDAP

I have an application that needs to sync periodically to my directory service (OpenLDAP or AD).
To do so, it is necessary to bind an admin account with a DN and password, to access users on LDAP.
As far as I understand, there is the possibility of using anonymous, however for security reasons, its use is not recommended.
Since this periodic synchronization is done automatically by a routine (hourly), I need to store in addition to the account DN, also admin password in the application database.
However, passwords are usually sent to be authenticated in plaintext against
directory service (within a secure SSL / TLS connection) and the directory service itself that finds its password stored in plaintext or some hash (md5, sha-1, etc.)
How to ensure the security of admin password stored in database for synchronization with LDAP? Or, is there a best practice to implement a sync periodic using LDAP?
Applications examples that require password (admin) to read LDAP.
Moodle
(https://docs.moodle.org/37/en/LDAP_authentication#Bind_settings)
Sugar CRM (https://support.sugarcrm.com/Knowledge_Base/Password_Management/Configuring_LDAP_Authentication_Using_Active_Directory/#Prerequisites)
But it does not clear how the password is stored.
It's true that anonymous bind is disabled by default in Active Directory. However, if you are just reading, you don't need an "admin" account. You need any account. The account does not need to have any special permissions. You just need something that can authenticate to the domain.
But if you're going to be authenticating users, then you will need to get the user's password, and you can just use the user's credentials to read from LDAP. That would be true for both AD and OpenLDAP.

program using task scheduler that echos user while running as admin

I'm trying to create a program which echo's a current user.
As the program needs to be run as admin using the task scheduler the %username% always returns admin, NOT the user.
What I'm looking for in the end is a batch that echo's time stamp, user info and pc info every time a user logs on, off, locks, unlocks, switches user, ...
I ran into similar issue before, try using whoami
The current user IS admin. Windows supports multiple users (although only 1 live one at a time). What you can do is query for users logged on and choose the interactive one.
Lists of potential users
wmic PATH Win32_SystemUsers get /format:List
wmic PATH WIN32_UserAccount get /format:List
wmic PATH WIN32_Account get /format:List
All the users logged on incl system accounts.
NB Administrators will have two logons - one as a limited user and one elevated.
wmic PATH Win32_LoggedOnUser get /format:List
To find info about the logon types
wmic PATH Win32_LogonSession get /format:list
List of logon types - you want 2.
LogonTypeData type: uint32Access type: Read-only
Numeric value that indicates the type of logon session.
Value
Meaning
0
Used only by the System account.
Interactive2
Intended for users who are interactively using the machine, such as a user being logged on by a terminal server, remote shell, or similar process.
Network3
Intended for high-performance servers to authenticate clear text passwords. LogonUser does not cache credentials for this logon type.
Batch4
Intended for batch servers, where processes can be executed on behalf of a user without their direct intervention; or for higher performance servers that process many clear-text authentication attempts at a time, such as mail or web servers. LogonUser does not cache credentials for this logon type.
Service5
Indicates a service-type logon. The account provided must have the service privilege enabled.
Proxy6
Indicates a proxy-type logon.
Unlock7
This logon type is intended for GINA DLLs logging on users who are interactively using the machine. This logon type allows a unique audit record to be generated that shows when the workstation was unlocked.
NetworkCleartext8
Preserves the name and password in the authentication packages, allowing the server to make connections to other network servers while impersonating the client. This allows a server to accept clear text credentials from a client, call LogonUser, verify that the user can access the system across the network, and still communicate with other servers.
NewCredentials9
Allows the caller to clone its current token and specify new credentials for outbound connections. The new logon session has the same local identify, but uses different credentials for other network connections.
RemoteInteractive10
Terminal Services session that is both remote and interactive.
CachedInteractive11
Attempt cached credentials without accessing the network.
CachedRemoteInteractive12

SQL Server Application Role

I'm thinking of using application roles in SQL Server I've read the following on the Microsoft MSDN site:
http://msdn.microsoft.com/en-us/library/ms190998.aspx
Connecting with an Application Role
The following steps make up the process by which an application role switches security contexts:
A user executes a client application.
The client application connects to an instance of SQL Server as the user.
The application then executes the sp_setapprole stored procedure with a password known only to the application.
If the application role name and password are valid, the application role is enabled.
At this point the connection loses the permissions of the user and assumes the permissions of the application role.
I'm wondering, if the application must know the password, how best to achieve this. I would assume storing the password in source code is a security risk. Is there another secure way to deploy the password with the application (note this is a windows client application that will be deployed to user machines).
There is actually another way to deploy the password with the application.
You can store the password as a secret in the database itself.
For instance, use a stored procedure or a scalar function which returns this "secret". This is an additional step in the logic you describe, to be executed just after the connection is made by the application with the user credentials.
This is possible because the users will have access to the database using Windows Authentication anyway.
The permissions need to be setup so that users are granted access to connect to the database and to the programmable object only.
To "obfuscate" (NOT secure) the password, you can store an encrypted version in the database and use a simple encryption / decryption (like this one).
This approach has the following advantages:
The password is not stored in clear text anywhere (please note though that it will travel in clear text on the network if you do not use SSL Encryption)
Users of the application are not required to provide any input
The application source code does not include the password
The application deployment does not include the password
The password can be reset very easily, for instance on a schedule
There is no way to deploy a password on a user workstation w/o a local administrator being able to discover it. You can only raise the bar so high, but if the price is worth it they will find it.
You should rely on the user providing the password, which ultimately boils down to using Windows authentication instead, if possible. You should always assume that whatever privileges the application has, the user has them as well and he/she can exercise them using an alternative access API (ie. any query tool). If you cannot trust the user with certain privileges, then you must not deploy the application on his/her computer. For example use a multi-tier solution that isolates the database from the user and add any necessary validation in this intermediate tier (most ASP.Net and/or WCF apps would qualify as such multi-tier when done properly).

How to make permission re-apply for a logged-in user in Windows AD without making him log in again

I am remotely removing a user U from a Group G.
But I have to log off and log on the user U to ensure that permissions for Group G do not apply any more to User U.
This is on a Windows 2008 server.
Is there a way to force the entire exercise of calculating permissions (which is done when a user logs in) while the user is logged in?
Thanks in advance.
You can purge the Kerberos TGT (and all your service tickets) using something like klist purge. I don't know what APIs to call to do this programmatically.
This will just refresh the groups (and rights) in your token when you access remote resources, though.
The list of groups SIDs a user belongs to is computed in the user token, which is inserted in his processes, so in my opinion, you need the logoff/logon.
You can find the source of Klist.exe discribed by #Brian Desmond in the Windows Platform SDK (the API in us is LsaCallAuthenticationPackage)
C:\Program Files\Microsoft SDKs\Windows\v7.0\Samples\security\authorization\klist

Resources