Access network share from service with another user [duplicate] - c++

This question already has an answer here:
Access to a protected network share using Win32 C++
(1 answer)
Closed 7 years ago.
I have a service that lives in a quite restricted server system. It must run under a specific user, let's call it user A.
The service must also be able to access a network share which user A does not have access to, but user B has. So the service must access this network share as user B, while running as user A.
The way I would do this if running locally on the computer is to map a network drive under a different user. But services can't access mapped network drives, even if it was mapped under the same user:
Services and Redirected Drives
Does anyone have a suggestion to what I could do? I'm the creator of the service so I can modify it as I please. Is there perhaps some way to let it access the network share as another user via a winapi call (unmanaged C++)?

The article you link to says:
Instead, the service should use client impersonation to impersonate the user.
In this context, that means using LogonUser and ImpersonateLoggedOnUser.
One caveat: that will only work if you are in a domain, i.e., the account that you want to log into the network server with is also valid on the local machine. If not, then you will have to establish a network connection explicitly using WNetAddConnection2 or similar. It is technically true that this risks exposing the connection to other services, but the risk is minimal in most contexts.

I think this SO post might actually be the answer I'm looking for:
Access to a protected network share using Win32 C++
Unless anyone has a better idea or other objections?

Related

How to use win api to check if the network is a pay-per-traffic link [duplicate]

This question already has answers here:
How can I tell if the connection is metered?
(2 answers)
Closed 6 months ago.
I see that since windows8 users can set up network as a pay-per-traffic internet link, so maybe some apps will use less data traffic
But I can't find an easy to use api to determine if the current network is billed or not when developing c++ applications
Does anyone have a link to the documentation for this?
Windows::Networking::Connectivity::NetworkInformation class is what you seek.
The GetInternetConnetionProfile method on this class returns a ConnectionProfile instance. On that object, you can invoke GetConnectionCost to get the NetworkCostType enum property. There's an event you can register a callback for when the user roams between networks so you know when to query it again.
If this property is "fixed" or "variable", you're on some sort of "metered network" connection where you might not want to have your app be conservative on network usage.
With that in mind, I believe the property that sets this bit simply a property of the network adapter. And maps to the user setting buried in Windows Settings:
I could be mistaken, but I'm not sure if there's any well known standard by which a network or ISP advertises the metered connection property dynamically in which Windows will pick it up. I think the OEM of the device sets this toggle switch when the machine is imaged.

access mapped network drive through impersonation

Is it impossible to access the mapped network drive( mapped in user session) from service after impersonating the current user by using ImpersonateLoggedOnUser Windows API?
Yes, this is impossible. Drive mappings are only established during an interactive logon. The ImpersonateLoggedOnUser function does not impersonate the user's entire logon session, just their security context. This is only one of the many things that cannot be done using impersonation.
I suppose you might be able to do this by duplicating the user's login token (obtained from one of their interactive processes), and then using that to call the CreateProcessAsUser function. You would then launch a process that would work with the mapped network drive(s). I'm not absolutely certain that this will work, as I've never done it, but it seems theoretically possible.
Of course, it begs the question of why you need to follow such a circuitous route. It would be eminently more sensible to just run your code in the user's interactive process to begin with, as a standard Windows application.
This is not something that a service is designed to do. Services do not support mapped network drives. If you want to access a network resource from within a service, you should just use the UNC path.

Can a web service talk to another web service?

I learned about service oriented architecture yesterday, and I have a question about it.
in order to talk to web service provider the initial communication has to be started by a service consumer. Then does it mean that a web service provider cannot talk to another web service directly (because it is not a consumer)?
I do not have enough information to grasp a full scope of what you're getting at exactly. However, I can say that this statement:
Then does it mean that a web service provider cannot talk to another web service directly (because it is not a consumer)
Isn't really true. A program can (programmatically) access data provided by a web service. The web service has no real awareness as to what a 'consumer' is. It only sees (programmatically) the data provided by the client (typically browser data, cookies, cache, etc..). But that doesn't stop anyone from opening a bash shell and curling the website.
This will retrieve any data statically provided by the server. Note that the data may obfuscated using JavaScript as to take measures to prevent any programs outside of a browser environment to access their critical data.
So the answer to that question, is yes and no.
You should ask this question on https://softwareengineering.stackexchange.com/ as it is more relevant to questions regarding programming concepts.
Both from technical and architectural points of view service of course can call another one. Simply, it is changing its role to behave as a consumer for the second service. Just be aware that things may become messy if both services are calling each other both ways to finish their task for a single client request. Though there are often valid scenarios for such behaviour, if both services are managed by the same entity, its worth looking if tasks shouldn't be moved or services merged as this may be a sign of a bad design decisions.
Any piece of software can talk to a web service as long as it can reach it.

Is my approach secure for implementing a one-time password in web service security

I have two systems (A & B) that i need to integrate with each other using web services, so i am thinking of implementing the following security mechanism:-
system B will send a request containing a username and password to system A asking for the one time 64-char password.
System A will send a onetime password containing 64 characters to system B.
System B will call system A web services using the 64 characters password.
System A will check if the 64 -char password is valid.
system A will respond to system B request.
system A will removed the 64 password from the valid password (so incase system B or another system calls system A web services using the previously generated 64-char password the call will fail)
system A will generate a new 64-char password and send it to system B when needed.
system B calls system A web service using the newly 64-password.
So my question will this approach be secure baring in mind that i will implement the communication between the two system to be under https.
Best Regards
There are many security considerations that need to be taken into account. So lets start:
Are both systems publicly accessible ?
Are both systems WS's publicly accessible?
Do you want to implements encrypton ? In transport or Access Control ?
From what I can tell I presume Your systems WS's are not publicly accessible and let's say proxies incorporate some sort of certificate authentication just as an extra layer of control, and some form of Access control Lists to limit IP range of client systems.
Second thing is that You probably want to do some kind of access controll rather than encryption i.e. user A can view doc aa and ab and your system A knows those rules but system B does not but he holds the actual data.
Analyzing your protocol If system A authenticates against system B and gets valid OTP, there are some things to consider
what will be validity period of such otp ?
how will you provide uniquness ?
will they be context dependent ?
All this is needed because you would not want, some more than avarage user to substitute data identifiers and with valid OPT access something that he/she shouldn't. Security is a slippery subject I would recomend Security Engineering by Ross Anderson and Computer Security by Dieter Gollman as starters :).

Alternatives to LogonUser for network impersonation (C++)

Are there any alternatives to LogonUser and for impersonating given account in order to access network resources? I'm looking for the method of impersonation which would let me connect to machine in foreign domains (or, workgroup machines for the same matter).
For initial data I have: machine name, username (or domain\username), cleartext password.
I know there's a way to establish connection using WNetAddConnection to a \\machinename\ipc$, then most network functions will run in a context of that account, however win2008 added another twist and some functions still use the account, that thread is running under.
I'm also aware, that there's some way to get an impersonation token using SSPI. Have anyone experimented with those tokens, are they good for accessing shares, SCM, remote registry and stuff? Is is what WNetAddConnection is using?
EDIT: To clarify, the reason I cannot use LogonUser is because I need to impersonate user in a non-trusted domain or workgroup
EDIT2: Another clarification: the item I'm trying to implement is similar to psexec, e.g.:
program should not modify host or active directory configuration (e.g.: create temporary local users, etc). Moreover assumption cannot be made that it is running on DC or not
there can be no assumptions made about which software is pre-installed on the remote host, only condition given is that windows file sharing is enabled on target
Account/password is known to be working on target, but target machine may be in local domain, foreign domain, not in domain at all.
EDIT3: I would really love to hear more about SSPI InitializeSecurityContext / AcquireCredentialsHandle option. Is there anybody who has been working with this API extensively? Is it possible to use the tokens returned with impersonation, so that a thread can access network shares and copy files, etc? Can someone post a working code snippet?
EDIT4: Thanks to Marsh Ray, problem got resolved. If anyone is looking to see the proof-of-concept code, it is here
If you're wanting to "access network resources" outside of your forest, do that with WNetAddConnection2/3 as you mentioned, or use the standard RPC APIs with RPC_ C__ AUTHN__ GSS__ NEGOTIATE and and explicit credentials structure.
Normally, "impersonation" is something that happens on the server side. The server side will be able to impersonate the connection as the account you're connecting as.
But the key is this: impersonation only makes sense for impersonating an account the server can access in his local SAM/domain/forest directory. If the client and server are in different forests, they clearly can't agree on the SID of an account for an impersonation token (except for the case of well-known SIDs like Administrator which serve mainly to confuse this kind of thing), and that seems necessary to check against DACLs etc.
Perhaps what you want is to call LogonUserEx with the LOGON32__ LOGON__ NEW__ CREDENTIALS flag. This should succeed (even in a different forest - it doesn't actually authenticate the credentials you give it) giving you a token with the username/password you specified. You may have to use DuplicateToken to turn this into an impersonation token. Then you can use SetThreadToken to replace the token on your thread.
IMHO this isn't really "impersonation", you're just using the credentials outright, but it allows you to access network resources transparently as the arbitrary username/password you supply.
Edit: Oh yeah, be aware that there is no protection against man-in-the-middle on this type of connection. The client especially cannot strongly authenticate the server (short of heroics like IPSEC), so in theory you can't trust anything the server tells you.
The theory goes that you pass the credentials as a SEC_WINNT_AUTH_IDENTITY structure to the AcquireCredentialsHandle function that creates the handle used in InitializeSecurityContext. I never tried this on foreign domains though and I don't know if it works.
Doing this directly and reliably via the Windows API seems next to impossible, plus Windows does so much work behind the scenes to make network access "just work". Plus the impersonation side of things only works for the single thread that called the APIs.
But... you can run a whole program under a different user... such as when you run a service.
So you could edit the registry in your main program to run various services under different security tokens and use IPC/Sockets to communicate with those processes from your main application. ie. a whole bunch (or restarting and reconfiguring the same process) of helper processes running under the different user(s) which your main app abuses.
I realize this is a hack but it seems viable ;)
You could open a command line, map the drive using the plaintext username and password. Then disconnect the drive:
net use m: \\machinename\share password /user:username
... do stuff ...
net use m: /delete
http://technet.microsoft.com/en-us/library/cc756153(WS.10).aspx