Discussion:
Calling WNetAddConnection() from a service
(too old to reply)
EricC
2006-05-05 20:29:02 UTC
Permalink
I have a service that monitors network traffic and handles specific requests
on certain ports. The service has worked through several product cycles just
fine.

One of the drawbacks is that the user must login before the service will run
(manual launch) and connect to network drives if data is to be accessed from
those drives. I am adding code so that the service can connect to those
remote drives on the domain and assign a local drive letter. I have code that
handles securing the user name/password and I can retrieve them.

When I call WNetAddConnection from the service, I get error 1326
(ERROR_LOGON_FAILURE) connecting to a server on the domain. I have r/w access
(just checked). I can do a 'net use z: \\foo\f$' and it works fine. I can
even issue WNetAddConnection() in a standalone application and it works fine.
What it will not do is work from the service, either manually started while
logged in or automatically started on boot.

Does anyone have any insight that will prevent me from pulling the rest of
my hair out?

Thanks

-E
EricC
2006-05-05 21:03:01 UTC
Permalink
FWIW, the NETRESOURCE parameter has the following values...

rNet.dwType = RESOURCETYPE_DISK;
rNet.lpLocalName = szDriveLetter;
rNet.lpRemoteName = szVolumeName;
rNet.lpProvider = NULL;

Since posting, I've tried forcing the credentials using LogonUser() and it
succeeds, but it doesn't help the cause.

Thanks

-E
Kellie Fitton
2006-05-05 21:49:33 UTC
Permalink
Hi,

You don't need to use the function WNetAddConnection2(), if you
have access rights to the network resources, you can access the
the network server and perform your operation. Also, in a service
process you can Only access the network drives via the UNC path,
you can use the following API to access the shared hard drives on
the remote server machine:

WNetGetUniversalName() using UNIVERSAL_NAME_INFO_LEVEL

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wnet/wnet/wnetgetuniversalname.asp

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/wnet/wnet/wnetaddconnection2.asp

Hope these suggestions helps,

Kellie.
Chris P. [MVP]
2006-05-05 22:28:24 UTC
Permalink
Post by EricC
I have a service that monitors network traffic and handles specific requests
on certain ports. The service has worked through several product cycles just
fine.
One of the drawbacks is that the user must login before the service will run
(manual launch) and connect to network drives if data is to be accessed from
those drives. I am adding code so that the service can connect to those
remote drives on the domain and assign a local drive letter. I have code that
handles securing the user name/password and I can retrieve them.
When I call WNetAddConnection from the service, I get error 1326
(ERROR_LOGON_FAILURE) connecting to a server on the domain. I have r/w access
(just checked). I can do a 'net use z: \\foo\f$' and it works fine. I can
even issue WNetAddConnection() in a standalone application and it works fine.
What it will not do is work from the service, either manually started while
logged in or automatically started on boot.
Does anyone have any insight that will prevent me from pulling the rest of
my hair out?
By default a service running as the LocalSystem account does not have
network access. You can instead elect to run the service under a user
account, but you should generally make sure that the access of the account
is limited to just the data you want access to.

You'll find that WNetAddConnection also works from the service once running
as a user account, however these connections will not be reflected in the
logged on user context.
--
http://www.chrisnet.net/code.htm
http://www.avdevforum.com/AV
Joe Richards [MVP]
2006-05-05 23:00:22 UTC
Permalink
As long as kerberos is being used LocalSystem will have the rights of the local
machine account on the network. This could be very little to a lot depending on
any groups the computer account has been added to or if people have open shares
(like shares that allow everyone or auth user access).

--
Joe Richards Microsoft MVP Windows Server Directory Services
Author of O'Reilly Active Directory Third Edition
www.joeware.net


---O'Reilly Active Directory Third Edition now available---

http://www.joeware.net/win/ad3e.htm
Post by Chris P. [MVP]
Post by EricC
I have a service that monitors network traffic and handles specific requests
on certain ports. The service has worked through several product cycles just
fine.
One of the drawbacks is that the user must login before the service will run
(manual launch) and connect to network drives if data is to be accessed from
those drives. I am adding code so that the service can connect to those
remote drives on the domain and assign a local drive letter. I have code that
handles securing the user name/password and I can retrieve them.
When I call WNetAddConnection from the service, I get error 1326
(ERROR_LOGON_FAILURE) connecting to a server on the domain. I have r/w access
(just checked). I can do a 'net use z: \\foo\f$' and it works fine. I can
even issue WNetAddConnection() in a standalone application and it works fine.
What it will not do is work from the service, either manually started while
logged in or automatically started on boot.
Does anyone have any insight that will prevent me from pulling the rest of
my hair out?
By default a service running as the LocalSystem account does not have
network access. You can instead elect to run the service under a user
account, but you should generally make sure that the access of the account
is limited to just the data you want access to.
You'll find that WNetAddConnection also works from the service once running
as a user account, however these connections will not be reflected in the
logged on user context.
Joe Richards [MVP]
2006-05-05 23:02:01 UTC
Permalink
You do not want to map drive letters from a service, all network access from a
service should be UNC based, MSFT has been warning against this since at least
1996. Please google through the MSFT KB Articles looking for hits on this. Over
the last few revs of the OS the visibility of drive letters across security
contexts and process contexts have changed considerably to lock it all down and
segregate the access for security.

joe

--
Joe Richards Microsoft MVP Windows Server Directory Services
Author of O'Reilly Active Directory Third Edition
www.joeware.net


---O'Reilly Active Directory Third Edition now available---

http://www.joeware.net/win/ad3e.htm
Post by EricC
I have a service that monitors network traffic and handles specific requests
on certain ports. The service has worked through several product cycles just
fine.
One of the drawbacks is that the user must login before the service will run
(manual launch) and connect to network drives if data is to be accessed from
those drives. I am adding code so that the service can connect to those
remote drives on the domain and assign a local drive letter. I have code that
handles securing the user name/password and I can retrieve them.
When I call WNetAddConnection from the service, I get error 1326
(ERROR_LOGON_FAILURE) connecting to a server on the domain. I have r/w access
(just checked). I can do a 'net use z: \\foo\f$' and it works fine. I can
even issue WNetAddConnection() in a standalone application and it works fine.
What it will not do is work from the service, either manually started while
logged in or automatically started on boot.
Does anyone have any insight that will prevent me from pulling the rest of
my hair out?
Thanks
-E
EricC
2006-05-07 02:52:01 UTC
Permalink
Kellie, Joe, Chris,

Thank you for the replies.

Let me try to describe this a little better. For starts, this is a project
that I've inherited. Perhaps what I'm trying to do here is fundamentally
undoable. In which case, I need to find another way to get something done.

The company has a number of legacy products dating back to the early 1990's
that ship on different schedules. These products communicate on a port to an
application that runs on the server. The drawback of the application is that
it requires someone to be logged in for it to start up. We've made a service
that starts up when the OS starts. The service has a C# wrapper that calls an
unmanaged DLL from the same code as the application. That works fine, but we
need network drive access because the server that handles requests doesn't
necessarily have the data stored on it. So, I need the service to find
network drives while not logged in and assign them drive letters.

From reading your replies, is there a way for me to configure my service to
run as something other than localSystem so that I can assign drive letters?

Joe, I take your point about not using drive letters but I'm stuck on this
one. The core of this code dates back to the OS/2 days. We're talking about
millions of lines of code in the applications. There is a lot of drive letter
data and logic in these applications. They aren't going to allow me to rip
that stuff out.

Any insights are appreciated.

-E
Joe Richards [MVP]
2006-05-07 19:42:09 UTC
Permalink
Doesn't matter if this stuff has been working this way since UNIVAC-I; the
underlying OS pieces are changing and working more and more against you. The
fact that the code is so old leads me to believe there are probably just an
amazing mess of issues in it anyway has it has been hacked for this that and
other function.

Someone really needs to start looking at re-architecting and rewriting which
obviously assumes that it was initially architected and not just grown up the
way it is which I expect is a stretch in thinking from what I have seen from
most vendors. I have done a lot of work on old OS/2 systems back in the late
90's moving them to NT and in each case I could see trying to run them like they
ran on OS/2 was more hassle and insecure than was necessary (or truly
acceptable) so I re-architected them. It requires understanding the need and
then looking at it from the Windows viewpoint on how to solve.


Check out this article to start, it gives more insight into what I am saying.
Notice the trend in how drive letters are being handled.

http://support.microsoft.com/default.aspx?scid=kb;en-us;Q180362

Again, you can map drives as localsystem, the person who said that was
incorrect. You can do it by specifying any security context or by using the
computer's security context if you are using kerberos for authentication. Or
even, if you really don't care about security, null session shares. I have found
valid cases over the last 10-12 or so years where a null session share was ok
from a security stand point (read only access to info anyone could get anyway
such as shared application binaries, etc).


It is probably good you don't mention what company this is because I expect
every person who saw this chain that used that product would be (or at least
should be) scared.

Overall though, and you can feed this straight to your highest management from a
very visible someone who does a lot of consulting to large enterprises and
working with vendors that if I encounter their app, they can expect me to tell
customers don't even consider running it. I have ripped more than one app out of
companies when I am asked to review them and determine if they are good from a
security/efficiency standpoint. I am also a developer and understand the
difference between doing things because of technical issues or other reasons. If
you guys don't start fixing this stuff you will just get worse and worse off
until you have nothing you can really use. To put it another way, putting it off
more and more will make it more and more expensive to correct, development time
isn't getting cheaper and I don't forsee anything coming out that will magically
solve your issue until someone really figures out the requirements so they know
what to look for.

joe


--
Joe Richards Microsoft MVP Windows Server Directory Services
Author of O'Reilly Active Directory Third Edition
www.joeware.net


---O'Reilly Active Directory Third Edition now available---

http://www.joeware.net/win/ad3e.htm
Post by EricC
Kellie, Joe, Chris,
Thank you for the replies.
Let me try to describe this a little better. For starts, this is a project
that I've inherited. Perhaps what I'm trying to do here is fundamentally
undoable. In which case, I need to find another way to get something done.
The company has a number of legacy products dating back to the early 1990's
that ship on different schedules. These products communicate on a port to an
application that runs on the server. The drawback of the application is that
it requires someone to be logged in for it to start up. We've made a service
that starts up when the OS starts. The service has a C# wrapper that calls an
unmanaged DLL from the same code as the application. That works fine, but we
need network drive access because the server that handles requests doesn't
necessarily have the data stored on it. So, I need the service to find
network drives while not logged in and assign them drive letters.
From reading your replies, is there a way for me to configure my service to
run as something other than localSystem so that I can assign drive letters?
Joe, I take your point about not using drive letters but I'm stuck on this
one. The core of this code dates back to the OS/2 days. We're talking about
millions of lines of code in the applications. There is a lot of drive letter
data and logic in these applications. They aren't going to allow me to rip
that stuff out.
Any insights are appreciated.
-E
EricC
2006-05-08 19:05:02 UTC
Permalink
Joe,

Thank you for the detailed and thoughtful writeup. You've now scared the
bejezus out of me. I'll rattle the CTO and see about taking this stuff out of
the service. The rest of it is going to take time.

-E

Loading...