Running a process as a different user…

I’ve been doing a lot with configuration management lately. At work, I’ve used Chef to set up virtual machines on Amazon Web Services, and I’ve used Ansible at home to create and manage the configuration of my laptop and desktop. Both of these tools let you execute commands as different users than the one that invoked the original script. There are lots of reasons to do this, and it’s a great feature.

At the moment, I’m writing some custom Perl scripts, and I find that I also need to execute some commands as a different user.

So, by inspecting Ansible’s source code, I found that it just uses “sudo”. I figured Chef’s source code was probably a lot larger, so I asked around on IRC, and some very nice people on the #chef channel on freenode showed me the following links:

Rather than using sudo, Chef directly changes the EUID and UID of the process it’s running using the Ruby “Process” module.

A few nights ago, before I learned about how Chef handles it, I was reading about how to do this in Python and found “setuid” and “seteuid” with the Python “os” module.

In Perl, there are lots of ways to do it! If we look at http://perldoc.perl.org/perlvar.html, we’ll see that we can use “$<” and “$>” to change the UID and EUID respectively. That’s not very pretty though… so if you use the “English” module, you can refer to them as “$REAL_USER_ID” and “$EFFECTIVE_USER_ID” or “$UID” and “$EUID”. Or… you can use the “POSIX” module’s “setuid” method which will change both at once.

Cool, eh?

In my case, “sudo” would probably be fine, especially as it should take care of things like changing the group ID, the home directory, etc.


But let’s assume that we want to change the UID and EUID manually in our process. We won’t necessarily know what UID we want to use. We might just have a username. In that case, we can avail ourselves of Perl’s “getpwnam” function.

So let’s take a look at the documentation:

Well, that’s a bit sparse. Here are some alternatives:

So all we need is ‘my $uid = getpwnam(“postgres”);’
Then we can do something like ‘POSIX::setuid($uid);’ to change the UID and EUID of the current process!

Error Messages in Koha

I noticed a while ago that Koha 3.8.0 showed a “Debug is on (level 1)” message in the member/patron entry template, but I had forgotten about it until someone brought it up again recently.

So I started researching the cause of this Debug level.

I checked the system preference “Debug Level” in the system preferences, but it was turned off (i.e. set to 0). After my research, it seems to me that the Debug Level system preference does very little in Koha. It seems to me that it might handle varying levels of error messages for fatal errors, which I’ve never actually encountered first-hand.

Anyway…

What was causing this Debug level to be set to one?

Well, I found out that the script behind the memberentrygen.tt template was setting a local scalar variable from a global variable ($ENV{DEBUG”).

Ok. That makes sense. I can understand that there are different debug settings. But…where is this $ENV{DEBUG} being set?

Well, I Googled. I grepped. I eventually found a record of an email about an old Koha patch (http://lists.katipo.co.nz/public/koha/2010-December/026789.html) which talked about a command called “Setenv Debug 1” in the koha-httpd.conf file (which is an Apache web server configuration file that tells Apache how to serve and log Koha).

Sure enough…I found that very same command in all of my Apache configuration files! Awesome! If I turn that off, it’ll get rid of that original annoying message!

But…let’s step back for a second…that “Setenv Debug 1” command is probably there for a reason!

If we grep (a Linux/MacOS command/utility) our Koha files, we’ll notice that a variable called $debug is set by $ENV{DEBUG} in other files than just memberentry.pl. In fact, it is set in some pretty important Perl modules that can broadcast it across the entire Koha instance! So…if we grep $debug (remembering to escape the $ sign with a backslash /), we’ll notice that this environmental variable turns on A LOT of back-end system logging.

We definitely don’t want to turn this off…

So…$ENV{DEBUG} is important for our system logs…and the Debug Level system preference is (potentially) important for fatal error logging…

But what about the “Software Error” messages that get up when you make errors in your Perl scripts (we all make mistakes, which is why we test!)? Surely those have to come from somewhere…

Are they affected by this environmental variable and system preference?

As it turns out…nope!

They are produced and handled by Carp.pm, which is part of the core Perl5 lib (to the best of my knowledge). To find it…you can go to your Perl5 lib (probably in usr/lib/perl5) and grep for Carp.pm. You might wind up with a few results. You can also try grepping using some of the text from the “Software Error” messages that you’re receiving in your browser. Note that not all of the text will be “greppable” because the error message text is the product of concatenated (i.e. joined together) variables (i.e. dynamic storage containers) and strings (i.e. lines of text).

Anyway, you’ll find it in Carp.pm.

 

But wait…in your “Software Error” messages…you’ll notice that there is an email address! Where’s that coming from?

Carp.pm will tell you that it’s from $ENV{server_admin}.

Great! But…where is that from?

Well, these folks (http://www.perlmonks.org/bare/?node_id=456111) mention that it is set by the ServerAdmin directive (i.e. command) in the Apache configuration file, which we know is koha-httpd.conf.

Sure enough, we go there, and the address next to ServerAdmin is the same one that we see in our error messages.

Cool, n’est-ce pas?

In all honesty, all these conclusions took some time, and a lot of grepping, Googling, guessing, and reading through lines of code.

But…I fixed the problem and learned a lot doing it!