Home | History | Annotate | Line # | Download | only in util
      1 /*	$NetBSD: chroot_uid.c,v 1.1.1.1 2009/06/23 10:08:59 tron Exp $	*/
      2 
      3 /*++
      4 /* NAME
      5 /*	chroot_uid 3
      6 /* SUMMARY
      7 /*	limit possible damage a process can do
      8 /* SYNOPSIS
      9 /*	#include <chroot_uid.h>
     10 /*
     11 /*	void	chroot_uid(root_dir, user_name)
     12 /*	const char *root_dir;
     13 /*	const char *user_name;
     14 /* DESCRIPTION
     15 /*	\fBchroot_uid\fR changes the process root to \fIroot_dir\fR and
     16 /*	changes process privileges to those of \fIuser_name\fR.
     17 /* DIAGNOSTICS
     18 /*	System call errors are reported via the msg(3) interface.
     19 /*	All errors are fatal.
     20 /* LICENSE
     21 /* .ad
     22 /* .fi
     23 /*	The Secure Mailer license must be distributed with this software.
     24 /* AUTHOR(S)
     25 /*	Wietse Venema
     26 /*	IBM T.J. Watson Research
     27 /*	P.O. Box 704
     28 /*	Yorktown Heights, NY 10598, USA
     29 /*--*/
     30 
     31 /* System library. */
     32 
     33 #include <sys_defs.h>
     34 #include <pwd.h>
     35 #include <unistd.h>
     36 #include <grp.h>
     37 
     38 /* Utility library. */
     39 
     40 #include "msg.h"
     41 #include "chroot_uid.h"
     42 
     43 /* chroot_uid - restrict the damage that this program can do */
     44 
     45 void    chroot_uid(const char *root_dir, const char *user_name)
     46 {
     47     struct passwd *pwd;
     48     uid_t   uid;
     49     gid_t   gid;
     50 
     51     /*
     52      * Look up the uid/gid before entering the jail, and save them so they
     53      * can't be clobbered. Set up the primary and secondary groups.
     54      */
     55     if (user_name != 0) {
     56 	if ((pwd = getpwnam(user_name)) == 0)
     57 	    msg_fatal("unknown user: %s", user_name);
     58 	uid = pwd->pw_uid;
     59 	gid = pwd->pw_gid;
     60 	if (setgid(gid) < 0)
     61 	    msg_fatal("setgid(%ld): %m", (long) gid);
     62 	if (initgroups(user_name, gid) < 0)
     63 	    msg_fatal("initgroups: %m");
     64     }
     65 
     66     /*
     67      * Enter the jail.
     68      */
     69     if (root_dir) {
     70 	if (chroot(root_dir))
     71 	    msg_fatal("chroot(%s): %m", root_dir);
     72 	if (chdir("/"))
     73 	    msg_fatal("chdir(/): %m");
     74     }
     75 
     76     /*
     77      * Drop the user privileges.
     78      */
     79     if (user_name != 0)
     80 	if (setuid(uid) < 0)
     81 	    msg_fatal("setuid(%ld): %m", (long) uid);
     82 
     83     /*
     84      * Give the desperate developer a clue of what is happening.
     85      */
     86     if (msg_verbose > 1)
     87 	msg_info("chroot %s user %s",
     88 		 root_dir ? root_dir : "(none)",
     89 		 user_name ? user_name : "(none)");
     90 }
     91