Article aug2006.tar

Questions and Answers

Amy Rich

Q I'm running an NFS home directory server on Solaris 8. When people have left the company, we've been doing userdel to remove their accounts. I've just discovered (because of UID reuse) that apparently the quota information stays around, though. I have two questions that deal with this topic. Is there a way to remove a user's quota information when the user is removed with userdel (or perhaps some other tool)? Also, how can I clean up the existing quota entries of users that have already been removed?

A Unfortunately there is no way to remove users' quotas when you delete them short of rolling your own script. This is generally a good idea, anyway, because userdel will not catch things like crontab entries, files outside of the home directory, etc. You can trivially do a mass cleanup of all of the quota entries that don't have usernames assigned with uids, though.

First, make sure there's a user on the file server that has no quotas. If there isn't one, set one up using /usr/sbin/edquota (nobody is often a good choice for a prototype user):

/usr/sbin/edquota nobody

fs /export/home blocks (soft = 0, hard = 0) inodes (soft = 0, hard = 0)
            
Second, run /usr/sbin/repquota -va to find all of the users who begin with #<uid> and run /usr/sbin/edquota -p nobody to remove the quota (make it match that of the prototype user, nobody) for that uid. You can wrap this in a shell script or a Perl script, which you can then run out of cron every so often if you don't get around to cleaning up quotas when you delete accounts. Try something like the following:

#!/usr/local/bin/perl

use strict;
use warnings;
use POSIX qw (WEXITSTATUS WIFSIGNALED WTERMSIG);

my $repquota = '/usr/sbin/repquota';
my $edquota = '/usr/sbin/edquota';

open (REPQUOTA, "$repquota -va |") || die "Can not open $repquota: $!\n";

while(<REPQUOTA>) {
  if (/^\#(\d+)/) {
    if (system ("$edquota", "-p", "nobody", "$1") != 0) {
      if ($? == -1) {
      die "Failed to execute $edquota: $!\n";
    }
    elsif (WIFSIGNALED ($?)) {
      die "$edquota terminated by signal: " . WTERMSIG($?)
         . (($? & 128) ? ", core dumped\n" : "\n");
    }
    else {
      die "$edquota exited with value " . WEXITSTATUS($?) . "\n";
    }
  }
}

close REPQUOTA;
Q Since upgrading to sendmail 8.13.6 because of the security hole, I'm noticing that a lot of df files are being left in my queue without corresponding qf files. Is there a problem with the new sendmail delivering my mail? Every time I test, all of the mail gets through okay (even if a df file is left behind).

A You don't offer a lot of details about your sendmail setup, but I suspect you're using buffered I/O (perhaps a milter?) and running into a known issue with 8.13.6. This problem will be corrected in later versions. From the release notes at:

http://www.sendmail.org/releases/8.13.6.html
    (2006-04-11) If a timeout occurs, a df file can be left in the mail queue if buffered files are used. This is a regression in 8.13.6 caused by the new I/O error handling. A fix will be available in the next release, in the meantime simply remove old df files (i.e., if they are older than the maximum queue timeout and if they have no corresponding qf, Qf, or hf files).

Q I was reading your answer about Solaris coreadm in the March issue of Sys Admin and was wondering if there was a way to make HP/UX 11.23 split core files out by name/pid. That would be much more useful than having the core files overwrite each other all the time.

A HP/UX 11.00 and later introduces the core_addpid kernel parameter, which will allow you to save core files as core.<pid>. Since you're running 11i v2, run the following command to modify the kernel:

echo 'core_addpid/W 1' | adb -o -w /stand/vmunix /dev/kmem
For HP/UX 11.00 and 11i v1, you can instead run:

echo 'core_addpid/W 1' | adb -k -w /stand/vmunix /dev/kmem
Q I'm investigating using wanboot for Solaris 9 and 10, but it appears that to do a hands-off install, you need to upgrade the OBP to a version that supports wanboot. I've searched the Sunsolve patch database and come up with some hits, but it looks like the majority of our hardware is unsupported. Is there a definitive list of systems that can be upgraded to support wanboot?

A Wanboot requires a minimum of OBP version 4.17 in the 4.x OBP source tree. Newer hardware like the T1000 and T2000 series machines will already be at the correct OBP version and not require an upgrade. You can find a definitive list of patches for various hardware types at the following URL if you have a Sunsolve account:

http://sunsolve.sun.com/handbook_private/Devices/Boot_PROM/ \
  BootPROM_Sun4u.html
The patches currently listed for the newest OBP versions equal to or greater than 4.17 are:

Sun Blade 100               119235-01      OBP 4.17
Sun Blade 150               119235-01      OBP 4.17
Sun Blade 1500 (1.062GHz)   119236-01      OBP 4.17
Sun Blade 1500 (1.503GHz)   119237-02      OBP 4.17
Sun Blade 2500 (1.280GHz)   119232-02      OBP 4.17
Sun Blade 2500 (1.600GHz)   119233-01      OBP 4.17
Sun Fire V480               118322-01      OBP 4.17
Sun Fire V490               119243-02      OBP 4.18
Sun Fire V880/V880z         119244-02      OBP 4.18
Sun Fire V890 PCI I/O       119244-02      OBP 4.18
Sun Fire V210               119234-01      OBP 4.17
Sun Fire V240 / Netra 240   119234-01      OBP 4.17
Sun Fire V440 / Netra 440   118319-02      OBP 4.17
If your systems are too old to support wanboot in the OBP, you'll need a CDROM drive on your machine. See:

http://docs.sun.com/app/docs/doc/817-5504/6mkv4nh7b?a=view
for information on performing a secure Solaris 10 wanboot from the local CDROM media. In this case, the client uses the wanboot program from the CDROM rather than from the server:

  boot cdrom -o prompt -F wanboot - install
Q I have two files of hostnames, where one is a complete list of all our machines and the other is a list of machines that have already been upgraded. I want to wind up with a list of machines that still need upgrading. What's the best way to accomplish this with the tools that come with the system? I'm not allowed to install any third-party tools, so this needs to be something pretty basic.

A You don't say what kind of system you have, so I won't assume anything fancy like perl. If your two lists are dictionary sorted, and you don't have duplicate entries (you can get there by using sort -u on both files if order isn't important), you can use the comm command. It takes two files as arguments and prints out three columns of output: lines only in the first file, lines only in the second file, and lines in both files. You can pass the arguments 1, 2, and/or 3 to comm to have it not print out certain columns.

Let's say all-hosts contains all of your hostnames and upgraded-hosts contains the ones you've already upgraded:

comm -23 all-hosts upgraded-hosts > remaining-hosts
If your list of hosts isn't sorted, you can use grep to accomplish the same thing. Make sure that your version of grep supports all of the following flags. If you're using Solaris, for example, you'll want to run /usr/xpg4/bin/grep instead of /bin/grep since /bin/grep does not contain the -x flag.

-x: All characters in the input line must be used to match the pattern.

-v: Invert the matching logic and only print lines that do NOT match
    the pattern.

-F: Interpret each pattern, separated by the newline character, as a 
    fixed string instead of a regular expression.

-f pattern_file: Read patterns from pattern_file, each separated by 
   the newline character.
The command-line syntax you'll use is:

grep -xvFf upgraded-hosts all-hosts > remaining-hosts
Q I'm running an Apache 1.3.33 Web server on five identically configured Fedora Core 4 systems. Apache is started at boot time via the script located at /etc/rc.d/rc3.d/S90apache (also /etc/rc.d/init.d/apache), which calls the /usr/local/apache/bin/apachectl script distributed with Apache. We use cronolog to handle the log messages for error_log and access_log in httpd.conf as follows (trimmed to a few hosts for the sake of brevity):

Listen 80
NameVirtualHost *:80

<VirtualHost *:80>
  DocumentRoot /data/www.my.domain
  ServerName www.my.domain
  ErrorLog "|/usr/local/sbin/cronolog \
    --symlink=/var/log/apache/error_log \
    /var/log/apache/%Y-%m/error_log"
  CustomLog "|/usr/local/sbin/cronolog \
    --symlink=/var/log/apache/access_log \
  /var/log/apache/%Y-%m/access_log.%Y-%m-%d" combined
</VirtualHost>

<VirtualHost *:80>
  DocumentRoot /data/www.hosta.domain
  ServerName www.hosta.domain
  ErrorLog "|/usr/local/sbin/cronolog \
    --symlink=/var/log/apache/hosta-error_log \
    /var/log/apache/%Y-%m/hosta-error_log"
  CustomLog "|/usr/local/sbin/cronolog \
    --symlink=/var/log/apache/hosta-access_log \
    /var/log/apache/%Y-%m/hosta-access_log.%Y-%m-%d" combined
</VirtualHost>

<VirtualHost *:80>
  DocumentRoot /data/www.hostb.domain
  ServerName www.hostb.domain
  ErrorLog "|/usr/local/sbin/cronolog \
    --symlink=/var/log/apache/hostb-error_log \
    /var/log/apache/%Y-%m/hostb-error_log"
  CustomLog "|/usr/local/sbin/cronolog \
    --symlink=/var/log/apache/hostb-access_log \
    /var/log/apache/%Y-%m/hostb-access_log.%Y-%m-%d" combined
</VirtualHost>

<IfModule mod_ssl.c>
  Listen 443
  <Virtualhost *:443>
    SSLEngine on
    SSLCertificateFile      conf/ssl.crt/www.host.domain.crt
    SSLCertificateKeyFile   conf/ssl.key/www.host.domain.key
    DocumentRoot    /data/www.my.domain
    ErrorLog        "|/usr/local/sbin/cronolog \
      --symlink=/var/log/apache/error_log \
      /var/log/apache/%Y-%m/ssl_error_log"
    CustomLog       "|/usr/local/sbin/cronolog \
      --symlink=/var/log/apache/access_log \
      /var/log/apache/%Y-%m/ssl_access_log.%Y-%m-%d" combined
  </VirtualHost>
</IfModule>
On four of the five machines, the log files were being created with cronolog with ownership of root:other and permissions of 0644. On the fifth box, we noticed a number of log files were all created with the same ownerships, but the permissions 0600. When we restarted the errant box, the log files were created with the correct permissions again. Within a month, though, we had more 0600 permissioned log files on one of the other machines. We rebooted this second machine, and it also started creating log files with the correct permissions again.

This is an issue for us since the log files need to be world readable so another process can do statistic reporting. It's also troublesome, since I'm not sure what's causing the change in permissions. Where should I start looking?

A If the machines are truly identical, including init scripts, cron jobs, etc., then the cause of the discrepancy must be something that's being run by a human and not an automated process being run by the machine. The difference in the permissions on the log files generally points towards a umask issue. Perhaps one of your admins is restarting apache with an environment different from the one that the operating system has when it boots. If you catch another one of your machines creating log files with the wrong permissions, you may want to use a small script to dump the environment that apache is running with. It might be illuminating if there are differences.

Make sure that people are starting/restarting apache in the same way all of the time and that their environment is not being carried over by something like sudo. To ensure that the correct environment is being passed to apache when it starts, you might want to explicitly set things like the PATH and umask in /etc/rc.d/rc3.d/S90apache and /etc/rc.d/init.d/apache.

There is also always the chance that one or more of your machines has been compromised, so you may want to boot from CDROM and make a full security sweep of all your machines if you think this might be the case.

Q I'm trying to build sendmail 8.13.6 from source on Solaris 8. I'm following the documentation and running the Build script, but it dies with the following:

gcc -o sendmail main.o alias.o arpadate.o bf.o collect.o conf.o
control.o convtime.o daemon.o deliver.o domain.o envelope.o err.o
headers.o macro.o map.o mci.o milter.o mime.o parseaddr.o queue.o
ratectrl.o readcf.o recipient.o sasl.o savemail.o sfsasl.o shmticklib.o
sm_resolve.o srvrsmtp.o stab.o stats.o sysexits.o timers.o tls.o trace.o
udb.o usersmtp.o util.o version.o
/usr/local/src/Security/sendmail-8.13.6/obj.SunOS.5.8.sun4/ \
  libsmutil/libsmutil.a
/usr/local/src/Security/sendmail-8.13.6/obj.SunOS.5.8.sun4/libsm/libsm.a
-lresolv -lsocket -lnsl
Undefined                       first referenced
symbol                             in file
dbm_pagfno                          map.o
dbm_dirfno                          map.o
ld: fatal: Symbol referencing errors. No output written to sendmail
collect2: ld returned 1 exit status
*** Error code 1
make: Fatal error: Command failed for target 'sendmail'
A This is generally indicative of having replaced the stock Solaris /usr/include/ndbm.h or having a conflicting ndbm.h file in your include path somewhere. You've probably installed Berkeley DB, and it's using the header file from that instead. You can temporarily rename the conflicting file (or remove it if you're not using whatever package it's attached to) and then rebuild the sendmail source using ./Build fresh.

Amy Rich has more than a decade of Unix systems administration experience in various types of environments. Her current roles include that of Senior Systems Administrator for the University Systems Group at Tufts University, Unix systems administration consultant, author, and charter member of LOPSA. She can be reached at: qna@oceanwave.com.