WHAT IS 'fixowner'? 'fixowner' is a small utility to solve one of two problems commonly occurring in shared webserver setups where multiple users want to run their own Web-based scripts (eg. PHP or CGI scripts) that write files to the server's filesystem. Scripts usually run under the webserver user ID (typically "nobody"). So, in order to write data, "nobody" user needs write access to certain directories or files. This is the first problem, as the typical *nix access rights model (owner/group/other) does not allow for explicit specification of permissions for a particular user. Sometimes you can find advices on the Net to set your file/directory permissions to 777 (all permissions to everybody). This is, however, horribly insecure, as it will allow not only the webserver user, but ANY user on your system to change ANYTHING in that directory. It's certainly not what you want. This problem can be solved quite simply, as "nobody" user usually is a member of the special "nobody" group, so the file/directory in question can be assigned to that group and then write permission for the group may be set, like in the example below: drwxrwx--- 2 raj nobody 512 May 3 21:12 upload However, an ordinary user cannot change a file's or directory's group ID to a group it doesn't belong him/herself - only superuser can do this (and the users shouldn't be members of the "nobody" group, otherwise we'd have again open access for everyone, similar to the setup with 777 rights). You can do the trick using the "sudo" package, which allows users to run certain commands as root (or other user). Many *nix systems have sudo already installed; if yours doesn't, you can get sudo from http://www.sudo.ws/. To allow users to "chgrp" any file or directory to "nobody", just put this line into the /etc/sudoers file (or wherever your sudo configuration file is): ALL ALL = NOPASSWD: /usr/bin/chgrp nobody * (modify the path appropriately if your "chgrp" executable is not in /usr/bin) Users will then be able to change a file's or directory's group to "nobody", only they'll need to type "sudo chgrp nobody filename" instead of just "chgrp nobody filename". But if you've managed this one, there's another problem. Files that have been already written to your directory by a Web script are owned by the "nobody" user, like this one: -rwxr-xr-x 1 nobody nobody 3741 Jan 6 18:24 smile.jpg This means, if you want to modify the file from your account (eg. using shell commands or FTP), you can't! Only "nobody" user has write access to the file, and moreover, only "nobody" user as the file's owner can change the access rights. Sudo won't help in this situation and this is where my 'fixowner' utility comes in handy. It allows an user to "take back" a file owned by "nobody". The owner of the file will be changed to the owner of the directory that contains the file, if several conditions are met. First, the file *must* be owned by "nobody". The program will not, in any case, change the ownership of files owned by any user other than "nobody". Second, the user running program must be root, the same user who owns the directory with the file, or "nobody" itself (the latter allows calling the utility in Web scripts, eg. to fix ownership directly after writing a file to the server). Third, program won't operate on symbolic links, or anything that isn't a plain file or directory (character device, pipe etc.) USAGE It's used as follows: fixowner [-d] filename ... 'Filename' may refer to an actual file or directory. If you specify a file, it changes the owner of the file to the owner of the directory that contains the file. For example, if you type "fixowner /home/user/uploads/image.jpg", it will change the owner of the file "image.jpg" to the same user who is the owner of the directory "/home/user/uploads" (of course assuming the file is owned by "nobody"). If you specify a directory name, program will change ownership of all files in the directory that are owned by "nobody" to the owner of the directory, unless a "-d" option is specified. With the "-d" option, directories will be treated exactly the same way as files, ie. the owner of the directory itself (if owned by "nobody") will be changed to the owner of the parent directory. Files within the directory won't be affected. You can specify multiple file/directory names on a line. The program changes only the owner of the file/directory; it doesn't change the group. INSTALLATION The source consists of three files, fixowner.c, myname.c and (optional) strlcpy.c. Some *nix systems have functions strlcpy() and strlcat() in the standard library while the others don't. (These are very useful functions - you can find enclosed documentation for them excerpted from the Solaris system manual in the file strlcpy.doc) There's no makefile, as I'm not good at writing makefiles ;). If you *do* have strlcpy() and strlcat() in your system, to compile it just type gcc -o fixowner fixowner.c myname.c If you don't have these two functions, use the command gcc -DHAVE_NO_STRLCPY -o fixowner fixowner.c myname.c strlcpy.c Before you compile, if your webserver user's name is other than "nobody" (eg. "apache" or "wwwdata" as in some Linux setups), change the value of the #define NOBODY in the file fixowner.c appropriately. Place the executable file "fixowner" in some directory that is on your search path (I suggest /usr/local/bin), and - most important - make it setuid root! (issue the command "chmod u+s /usr/local/bin/fixowner" as root). The program won't work properly if it isn't setuid root (only root will be able to use it). LICENCE This program is distributed under the GNU GPL licence; see http://www.gnu.org/licenses/ for details. Copyright (C) Jaroslaw Rafa, 2008. email: raj@ap.krakow.pl