Cover V10, I11



Questions and Answers

Amy Rich

Back in the August issue of Sys Admin, someone asked a question about how to read a file backwards, and I provided a handy one-liner in Perl. Thanks to Tillman Hodgson for pointing out that there is also a GNU program called tac (cat spelled backwards) that does the same thing. Also thanks to Tom Payerle for pointing out the program rev, which prints lines from right to left.

Q I have our Sendmail server configured with RBL and DUL, but these lists are not complete enough to catch all the spam that we receive. We get nothing but spam, for instance, from several top-level country domains, and I'm trying to block those with the access_db feature. I'm having some difficulty blocking a TLD and all of its subdomains, however. I can successfully block the addresses in the access.db when I have an exact match. For example, the following entry works:

host.sub.domain            REJECT
I obviously don't want to go through and match every host, so I was trying to write a match for the entire TLD:

.domain                    REJECT
When I test my access rules with sendmail -bt -v it doesn't seem to work:

> /map access .domain
map_lookup: access (.domain) returns REJECT (0)
which is fine, but:

> /map access sub.domain
map_lookup: access (sub.domain) no match (0)
which fails. How do I correctly block an entire TLD?

A Your access.db entry is syntactically incorrect and should look like the following:

domain                     REJECT
You don't want the leading '.' on the domain when you're trying to block the whole domain. When lookups are done against the access database, they're done in tokens, separated by dots. When the lookup for host.sub.domain is done, it then iterates through, taking off a token and a dot each time:

Your other issue is that you're trying to validate your matches in testing mode with /map. This won't work because of the above-mentioned recursive token removal. This happens as part of the check_* rulesets, not the map lookup. The check_* rulesets will do multiple map lookups until the TLD is reached.

Q I just installed Solaris 8 on my E450 and flashed the OBP. Now whenever I try to boot the machine, it insists on booting off the network instead of the disk. This, of course, fails because I don't have a network boot server. I've set the boot device to disk and tried again, but it still tries to boot from the network. Why won't my machine boot from the disk that Solaris is installed on?

A Suns usually boot from the network for diagnostic purposes. Your machine may not see the disk, may not have the boot device set correctly, or may just be tagged to do a diagnostic boot. First, make sure that the machine can actually see the disk device. At the OK prompt, type the following (assuming you have SCSI disks):

If you don't see your disk, verify that the disk is connected properly and is actually spinning up. If you still can't see your disk, you may have damaged your disk or controller (or some other piece of hardware) that you'll need to replace.

If you can see your disk with the probe, verify that the boot device and any aliases are set correctly. You can see the values of each variable by using printenv from the ok prompt. Verify that boot-device is set to boot from disk first. An example boot device line looks like the following:

boot-device=disk net
Verify that disk is actually correctly aliased to your boot disk. The address of your boot device will look different depending on what sort of hardware you have in your machine. You can use the command devalias from the ok prompt to view your aliases. On a PCI bus, the disk alias may look something like the following:

You may also want to try booting directly from the disk path if you suspect problems with the NVRAM aliases. If you need to reset the alias, you can use the nvalias command, and be sure to set use-nvramrc? to true.

Most machines will have diag-device=net, so verify that the diag-switch is set to false:

If you still can't get your machine to boot from the disk, you may have hardware issues. If you have a Sun contract, call them and have them help. If you don't have a contract, Sun also offers per-incident pricing.

Q I've just been handed the systems administration tasks at work, and I'm not really all that UNIX-savvy yet. Right now I'm trying to change ftpd so that all the incoming files have the permissions -rwxrwxrwx instead of -rw-rw-rw. I've tried changing both root and ftp's umask to 0, but this doesn't seem to help. How can I change the default incoming ftp permissions?

A To help you understand why your umask command didn't work, let's start with a bit of information about file modes, file creation modes, and umask. UNIX file permissions have two sorts of representations (letters, as you listed) and octal numbers. To understand the umask, it's important that you understand octal permissions.

With standard UNIX permissions (no extended ACLs), there are three catagories of permissions: user, group, and other. In both the octal and alphabetic representations, the categories are read from left to right. For each category, you can set three basic permission types: read, write, and execute. (We'll skip SUID, SGID, and other special permissions for now.) Using the alphabetic output, read is represented by the letter r, write by w, and execute by x. Using the octal output, read is represented by the number 4, write by the number 2, and execute by the number 1. To translate your desired permissions from alphabetic to octal, you add up the numbers for each category (user, group, and other):

-rwxrwxrwx  is equivalent to 0777  (4+2+1 4+2+1 4+2+1)
-rw-rw-rw-  is equivalent to 0666  (4+2 4+2 4+2)
-rw-r--r--  is equivalent to 0644  (4+2 4 4)
The default file creation mode for files in UNIX is 0666. For directories, the default creation mode is 0777. The umask is another octal number that is subtracted from the default creation permission. If you have a umask of 2 (you can also pad it out with leading zeros so the umask becomes 0002), you get the following:

directories     0777           drwxrwxrwx
- umask         0002         - --------w-
____________________           __________            
creation mode   0775           drwxrwxr-x

files           0666           -rw-rw-rw- 
- umask         0002         - --------w-
____________________           __________            
creation mode   0664           -rw-rw-r--
If you have a umask of 22 (or 0022), then you get file creation modes of 0644 (-rw-r--r--), and directory creation modes of 0755 (drwx-r--r--). The "d" in the first position of the alphabetic listings above denotes that the entry in is a directory.

Your problem with ftp is that all ftp file uploads start off with the creation permission for 0666. Umask cannot add permissions, only take them away. You'll never be able to upload files with the execute bit set by using ftp. There are a couple ways to get around this. You can use something like scp (part of ssh) to upload files instead of ftp. Scp will subtract the destination user's umask from the existing permissions on the remote machine. So, if you scp a file with the permissions of 0775 from a remote machine and your umask is 22, you will then have a resulting file on the local machine of 0755.

As an aside, root's umask should be something fairly restrictive, such as 22, so that random people on the system cannot write to files owned by root.

Taking a different approach, you can also run a cron job to change the permissions of the uploaded files on a regular basis if they are in a known location. Beware when adding the execute bit to uploaded files, though -- malicious users can upload trojans and when you change the permissions on them, people may unwittingly execute those trojan binaries.

Amy Rich, president of the Boston-based Oceanwave Consulting, Inc. (, has been a UNIX systems administrator for more than five years. She received a BSCS at Worcester Polytechnic Institute, and can be reached at: