UnrealIRCd Windows service failing to run as non-SYSTEM user

These are old archives. They are kept for historic purposes only.
Post Reply
Czujny
Posts: 6
Joined: Mon Jul 03, 2006 10:42 pm

UnrealIRCd Windows service failing to run as non-SYSTEM user

Post by Czujny »

This is a new installation of UnrealIRCd 3.2.5 pre-built package w/ SSL (Unreal3.2.5-SSL.exe) on a Win2k Server SP4 system. The SSL certificate is not (currently) encrypted since it's being run as a service (as per the FAQ). (Whenever I mention services in this post I'm referring to Windows services and not IRC services. And when I refer to "user" I'm referring to a Windows user account and not an IRC user account.)

Initially I set up the Unreal service to log in similarly to how I have my existing IRC server (IRCXPro) which uses a special user account created only for this purpose (Service Properties->Log On->This Account). When launched (either from services.msc or by running wircd.exe) it would try to start up and then fail (timeout). No service.log or ircd.log would be created anywhere.

As nothing was working, I decided to try running the Unreal service using the Local SYSTEM account (which is the default after installation) and it started up promptly and without any problems. However, this is an unacceptable security risk, so I need to see if I can get Unreal to work under the special user account.

I verified that the user had Full privileges to the UnrealIRCd directory and the user's documents and settings directory, as well as read and execute access to WINNT and WINNT/SYSTEM32 (and subdirs). This was the original configuration that would not work for Unreal although it works fine for all my other internet servers (apache, filezilla, proftpd, ircxpro, etc. each obviously to their own respective directory). I then tried (purely for experimental purposes) to give the special Unreal user Full privs to the entire WINNT structure and eventually to the entire System drive. But nothing improved the situation.

By watching file activity using Sysinternals' NTFilMon, I can see the process starting, accessing a whole slew of DLLs in both the UnrealIRCd and WINNT/SYSTEM32 directories, but ultimately just "stopping" and eventually timing out with no informative errors or logs.

Can anyone explain this behavior? What additional privileges do I need to give the user account used for the UnrealIRCd service? Thank you.

NOTE: Just as I was about to submit this post I had an idea. I added the special Unreal user account to the Administrators group and now it is able to launch without problems. It seems that this shouldn't be necessary, however, as all my other internet daemons run fine with my specialized user accounts which only belong to the group Users (which is a very restricted group). So I'm going to go ahead and submit this post anyways as (a) it could possibly be of use to someone in the future who runs into this and (b) I'm still hoping someone can suggest what individual privileges I need to give my special user so that I don't have to make him part of the Administrator group (which is still an unacceptable risk...better than SYSTEM but not by much). Thanks again.

Edit: Changed "read-only" to "read and execute"
Ron2K

Post by Ron2K »

My experience with Windows services show that they generally don't like running unless they have administrator privileges. The other day, I had to troubleshoot an instance of MSSQL 2000 that was seemingly not running. As it turned out, the service was stopped and I had to log in as administrator to fix the problem. This was on XP Professional, by the way. Your post does show, however, that it is possible to get a service running with limited permissions, so I would suggest heading off to the bugtracker and making the relevant feature request. Just don't be surprised if you find out that it cannot be done.
Jobe
Official supporter
Posts: 1180
Joined: Wed May 03, 2006 7:09 pm
Location: United Kingdom

Post by Jobe »

I think ive found why it doesnt work using the runas command. It comes up with the message "[error] Couldn't open "unrealircd.conf": No such file or directory" Which suggests that the problem is not the permissions but what directory it is using as its working directory.

The only way i have got it to work as a specific user with ONLY user permisions is using the following from a command prompt:

Code: Select all

runas /user:unrealuser "cmd /c cd c:\program files\unreal3.2 & wircd.exe"
I would like to note that the above command works until you remove the "cmd /c cd c:\program files\unreal3.2 & " part then you get the cannot find file message again.

So the question i would like to ask is: is there a way to provide the current working directory as a command line parameter to wircd.exe? If not for the purpose of running it as an unpriviledged user it would be a nice feature to have.
Czujny
Posts: 6
Joined: Mon Jul 03, 2006 10:42 pm

Post by Czujny »

Ron2k: Aye, I understand. At the very least my post will alert others who run their services as I do in the future to beware of potential problems with Unreal. But I haven't given up yet and if all else fails I'll submit it as a request to the tracker with no expectations. Obviously if I find a solution I'll post it here.

Jobe1986: I have both corroborating evidence and conflicting evidence regarding that. In corroboration that it's a working directory issue (which I also considered an option early on) is that, when watching what Unreal would do when launching with NTFilMon, it was searching for the .conf file in WINNT sometimes and WINNT/SYSTEM32 other times. I also thought that this might be related to why it wasn't writing any .logs. Additionally, Unreal was creating and using a directory named TMP in the SYSTEM32 directory which really should not be necessary and added to my security concerns. Anyways, this made me think that perhaps Unreal was using SYSTEM32 as its working directory which, like you said, would ideally be something adjustable from the command line (and usually is with internet daemons under Windows either directly or by command-line specification of the location of the .conf which then contains the working directory information).

But as far as I can tell that doesn't explain why, all other things set as I normally do, when I applied Administrative privs to that special user, it all just suddenly worked. That seems to point to it being a privileges issue. Or is my figuring on this point off?

But your info definately gives me more food for thought and things with which to tinker. Thank you.
Jobe
Official supporter
Posts: 1180
Joined: Wed May 03, 2006 7:09 pm
Location: United Kingdom

Post by Jobe »

This is just a guess but it's possible that the way the wIRCd determines where it is located or to change to that directory itself requires the Administrative priviledges. Because if it cant change to or detect the directory the exe is located in itll still carry on trying to load the config files from the current working directory.

I may be wrong but thats what appears to be happening.

My resoning behind this is if it has no problem with Administrator priviledges or no problem when you make sure its current working directory is the right place then it must be somthing associated with how it determines where to look for the config files.

Im pretty sure after my experiments earlier that it is the fact it cannot find the config files that it cant be run under a normal user account.

I am currently trying to find a way to make sure it is started with the correct current working directory. If i find a way without modifying the source ill let you know but as for modifying the source not only is it not supported but i wouldnt know where to begin anyway.
Czujny
Posts: 6
Joined: Mon Jul 03, 2006 10:42 pm

Post by Czujny »

Okay Jobe, thanks. I'll be sure to report on any additional information I come up with as well.

And I too have no interest in modifying the source both because of losing support here as well as the hassles of rolling changes into newer versions. Although worse comes to worse I might do a self-compile and see if I can see what's going wrong by stepping through a debug. But without familiarity with the source that can be a pain (especially since I hate debugging Windows services remotely, as it tends to give me a hassle). That's a last case option and only if I get really, really desperate. :D
Czujny
Posts: 6
Joined: Mon Jul 03, 2006 10:42 pm

Post by Czujny »

I believe I found the problem, but not yet a solution. I'm going to make a few guesses here so take it with a grain of salt. Only the devs know if my guesses are right.

The problem seems to stem from the fact that this is not a normal service executable, but a hybrid of a normal executable and a service. In fact, it has both bits in it and the normal executable is run and then it uses the Windows service manager to activate the Service portion of the code...if it can.

Unfortunately, the call to OpenService() in the code fails unless the user has Administrative rights. Then it proceeds to try to run the normal executable code and it seems to get confused (since it's being run as a service, I guess).

Now I found a heinously complex method to give administrative service rights to a user group for a single service, but even though I did this and added my special user to it, it still can't get past the OpenService() call. But I only just uncovered this new info about an hour ago so I have a lot more investigating to do. Currently I'm only investigating solutions that do not require customizing the source code.

(Additionally, I checked and the source code for ServiceMain() actually does set the current working directory to the location of the module, which is therefore whatever folder WIRCD.exe is in. But because this code is in the ServiceMain() it never gets called since I believe the OpenService() stuff I mentioned earlier has to succeed to get the service code running which will then set the working dir.)

I'll keep you informed of any progress.
Czujny
Posts: 6
Joined: Mon Jul 03, 2006 10:42 pm

Post by Czujny »

I wish I had happier news to report. There is good news, and that is that I got it working.

The bad news is twofold. First, it requires the heinously complex method of giving a user administrative rights for a single service I mentioned in the previous post. However, I can write a tutorial for doing that in about twenty minutes. But it likely will require very advanced users to even follow the tutorial (although pretty much only advanced users are going to run into this situation in the first place). I think an advanced user would only need ten minutes or so to follow the instructions.

The much more severe problem is that I had no choice but to make a single source code change (GENERIC_EXECUTE to SC_MANAGER_CONNECT in the OpenSCManager() call). And we all know that's no good since we lose the ability to request support if you make source code changes.

Essentially, the OpenSCManager() call (which, incidentally, doesn't fail) requests a level of permission (GENERIC_EXECUTE) that a non-administrative user cannot seem to have, although the denial doesn't actually take place until the OpenService() call. Interestingly, changing the rights for the OpenService() call does not help, it is most definately the OpenSCManager() call.

Now I could probably submit that source code change to the bugtracker but I don't know if it will adversely affect doing things other than "opening" the service (as there is code in there for doing things like restarting the service, etc.). It should be fine, but I'll have to run tests. There's obviously no reason yet for me to write the tutorial for the user rights adjustment until we work out this other bit. Since I'm an UnrealIRCd newbie, however, it'll take me a little time to do such testing.

As I'm new to the community, I'd like to know how best to proceed. Should I test it as best I can with this slight source code rights adjustment and then submit the change to the tracker with as much detail as possible?
aquanight
Official supporter
Posts: 862
Joined: Tue Mar 09, 2004 10:47 pm
Location: Boise, ID

Post by aquanight »

That probably might be a good idea, but I'm inclined to think that windows services weren't intended to run using standard user accounts. They generally run in one of three accounts: Local System, Network Service, or Local Service, with Local System having more administrative rights (but, obviously, only on the local machine) than the other two (indeed, more than even Administrator IIRC). I'm sure the two Service accounts have the necessary rights for the system calls you mention without having full admin (since other services can run as them just fine), so theoretically running unreal in the Network Service account shouldn't need more than maybe adding a few permission entries on the unreal dir (most notably, write privileges on tmp).
Jobe
Official supporter
Posts: 1180
Joined: Wed May 03, 2006 7:09 pm
Location: United Kingdom

Post by Jobe »

The main problem i can see with using these previledged users is if for any reason a service were to be compromised in some way it would have the permissions of the user it was running as whch in the case of Local System can be very dangerous.

Also on a side note. Im not sure about more recent versions but Micirosoft's server software such as MS Exchange or MS SQL Server create and run under a specific user for security. This would lead me to think that Microsoft designed services to be used under restriced users where necesary.

Just my thoughts.
Czujny
Posts: 6
Joined: Mon Jul 03, 2006 10:42 pm

Post by Czujny »

aquanight: I certainly can't say I know what was going through the heads of the MS developers (I say that a lot :P) but I've never previously run into a problem running services as a user and I make it a normal practice for any services that can take input from the net, so I don't know if I see reason to believe the MS developers didn't intend it. Indeed, it's usually quite easy to run services in a very restricted user account (this is of course common practice in *nix) once you _carefully_ remove a lot of the default rights that Windows assigns. (Don't ask me about the six months my Win2k Server had totally screwed up dialog boxes because I'd accidentally removed SYSTEM rights to the FONTS directory. :mrgreen:)

If all I said in my posts above is correct, then the problem with running the Unreal service as a user is not because it's a service, but because it's not a pure service but a hybrid app that also has a ServiceMain() which the regular app main() calls via the Windows Service Manager. This is fine, however, but I believe the Service Manager is being invoked requesting higher privileges than is necessary to do the job and that's what causes the problems.

Running it in one of those other user groups you mentioned really doesn't help the situation very much. The point of running it as a user is that you can usually assign that user write rights to only the service's folder (or sometimes even limit write to logs and read and read/execute to the remainder) and read/execute access only to system DLL folders. You can also give it absolutely no rights to everything else on the system. Then there's restricting registry access too... Using those included groups you just cannot do all this.

So far, using the resolution I described above, I'm happy to report that I've had no problems whatsoever with running the UnrealIRCd service in a user account.
aquanight
Official supporter
Posts: 862
Joined: Tue Mar 09, 2004 10:47 pm
Location: Boise, ID

Post by aquanight »

You may well be right, but just looking at my current Service list I only see the three I mentioned earlier (then again, this is just a workstation). Though when I had SFU installed, the "init" it uses was running as Administrator ... (not sure if that was a registered windows service though). There probably is a good point in using user accounts for paranoia-restrictions like that, though.
Post Reply