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