]>
jfr.im git - irc/quakenet/snircd.git/blob - tools/wrapper.c
2 ** Copyright (C) 2000 by Kevin L. Mitchell <klmitch@mit.edu>
4 ** This program is free software; you can redistribute it and/or modify
5 ** it under the terms of the GNU General Public License as published by
6 ** the Free Software Foundation; either version 2 of the License, or
7 ** (at your option) any later version.
9 ** This program is distributed in the hope that it will be useful,
10 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ** GNU General Public License for more details.
14 ** You should have received a copy of the GNU General Public License
15 ** along with this program; if not, write to the Free Software
16 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ** @(#)$Id: wrapper.c,v 1.3 2004/05/15 14:50:09 entrope Exp $
26 #include <sys/types.h>
27 #include <sys/resource.h>
31 * Try and find the correct name to use with getrlimit() for setting the max.
32 * number of files allowed to be open by this process.
34 * Shamelessly stolen from ircu...
37 #define RLIMIT_FD_MAX RLIMIT_FDMAX
40 #define RLIMIT_FD_MAX RLIMIT_NOFILE
42 #ifdef RLIMIT_OPEN_MAX
43 #define RLIMIT_FD_MAX RLIMIT_OPEN_MAX
45 #error Unable to find a valid RLIMIT_FD_MAX
50 /*fix for change uid/gid with chroot #ubra 08/02/03*/
54 * Set the hard and soft limits for maximum file descriptors.
57 set_fdlimit(unsigned int max_descriptors
)
61 limit
.rlim_max
= limit
.rlim_cur
= max_descriptors
;
63 return setrlimit(RLIMIT_FD_MAX
, &limit
);
67 * Change directories to the indicated root directory, then make it the
71 change_root(char *root
)
82 * Change the user and group ids--including supplementary groups!--as
85 * fix for change uid/gid with chroot #ubra 08/02/03
86 * old change_user() got splited into get_user() and set_user()
89 get_user(char *user
, char *group
)
95 /* Track down a struct passwd describing the desired user */
96 uid
= strtol(user
, &tmp
, 10); /* was the user given as a number? */
97 if (*tmp
) { /* strtol() failed to parse; look up as a user name */
98 if (!(pwd
= getpwnam(user
)))
100 } else if (!(pwd
= getpwuid(uid
))) /* look up uid */
103 uid
= pwd
->pw_uid
; /* uid to change to */
104 gid
= pwd
->pw_gid
; /* default gid for user */
106 if (group
) { /* a group was specified; track down struct group */
107 gid
= strtol(group
, &tmp
, 10); /* was the group given as a number? */
108 if (*tmp
) { /* strtol() failed to parse; look up as a group name */
109 if (!(grp
= getgrnam(group
)))
111 } else if (!(grp
= getgrgid(gid
))) /* look up gid */
114 gid
= grp
->gr_gid
; /* set the gid */
117 if (initgroups(pwd
->pw_name
, gid
)) /* initialize supplementary groups */
119 return 0; /* success! */
124 if (setgid(gid
)) /* change our current group */
126 if (setuid(uid
)) /* change our current user */
129 return 0; /* success! */
133 * Explain how to use this program.
136 usage(char *prog
, int retval
)
138 fprintf(stderr
, "Usage: %s [-u <user>] [-g <group>] [-l <limit>] [-c <root>]"
139 " -- \\\n\t\t<cmd> [<cmdargs>]\n", prog
);
140 fprintf(stderr
, " %s -h\n", prog
);
146 main(int argc
, char **argv
)
149 char *prog
, *user
= 0, *group
= 0, *root
= 0;
151 /* determine program name for error reporting */
152 if ((prog
= strrchr(argv
[0], '/')))
157 /* process command line arguments */
158 while ((c
= getopt(argc
, argv
, "hu:g:l:c:")) > 0)
160 case 'h': /* requested help */
164 case 'u': /* suggested a user */
168 case 'g': /* suggested a group */
172 case 'l': /* file descriptor limit */
173 limit
= strtol(optarg
, 0, 10);
176 case 'c': /* select a root directory */
180 default: /* unknown command line argument */
185 /* Not enough arguments; we must have a command to execute! */
189 if (limit
> 0) /* set the requested fd limit */
190 if (set_fdlimit(limit
) < 0) {
195 if(user
) /* get the selected user account uid/gid*/
196 if (get_user(user
, group
)) {
202 if (root
) /* change root directories */
203 if (change_root(root
)) {
208 if (user
) /* change to selected user account */
214 /* execute the requested command */
215 execvp(argv
[optind
], argv
+ optind
);
217 /* If we got here, execvp() failed; report the error */