1 // $Id: rpm-fake-resolver.c,v 1.15 2005/07/03 13:16:34 ensc Exp $ --*- c -*--
3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
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.
21 // 2. initialize (setuid, ctx-migrate, chroot, ...)
22 // 3. send "." token to fd 3
23 // 4. wait one character on fd 1
24 // 5. process this character and consume further characters from fd 1 as far
26 // 6. go to 3) (or exit)
44 #define ENSC_WRAPPERS_PREFIX "rpm-fake-resolver: "
45 #define ENSC_WRAPPERS_VSERVER 1
46 #define ENSC_WRAPPERS_UNISTD 1
47 #define ENSC_WRAPPERS_IO 1
48 #define ENSC_WRAPPERS_FCNTL 1
51 #define MAX_RQSIZE 0x1000
53 int wrapper_exit_code = 1;
61 char const * pid_file;
67 static struct option const
69 { "help", no_argument, 0, 'h' },
70 { "version", no_argument, 0, 'v' },
75 showHelp(int fd, char const *cmd, int res)
77 WRITE_MSG(fd, "Usage: ");
80 " [-c <ctx>] [-u <uid>] [-g <gid>] [-r <chroot>] [-s] [-n]\n"
81 "Please report bugs to " PACKAGE_BUGREPORT "\n");
89 "rpm-fake-resolver " VERSION " -- NSS resovler for rpm-fake\n"
90 "This program is part of " PACKAGE_STRING "\n\n"
91 "Copyright (C) 2003 Enrico Scholz\n"
92 VERSION_COPYRIGHT_DISCLAIMER);
98 parseArgs(struct ArgInfo *args, int argc, char *argv[])
101 int c = getopt_long(argc, argv, "F:C:c:u:g:r:ns", CMDLINE_OPTIONS, 0);
105 case 'h' : showHelp(1, argv[0], 0);
106 case 'v' : showVersion();
108 case 'c' : args->ctx = atoi(optarg); break;
109 case 'u' : args->uid = atoi(optarg); break;
110 case 'g' : args->gid = atoi(optarg); break;
111 case 'F' : args->flags = atoi(optarg); break;
112 case 'C' : args->caps = atoi(optarg); break;
113 case 'r' : args->chroot = optarg; break;
114 case 'n' : args->do_fork = false; break;
115 case 's' : args->in_ctx = true; break;
117 WRITE_MSG(2, "Try '");
118 WRITE_STR(2, argv[0]);
119 WRITE_MSG(2, " --help\" for more information.\n");
126 WRITE_MSG(2, "No further options allowed; aborting ...\n");
130 if (args->chroot==0) {
131 WRITE_MSG(2, "No chroot specified; aborting...\n");
137 sendResult(bool state, uint32_t res)
140 static uint8_t ONE = 1;
141 Ewrite(1, &ONE, sizeof ONE);
144 static uint8_t ZERO = 0;
145 Ewrite(1, &ZERO, sizeof ZERO);
148 Ewrite(1, &res, sizeof res);
156 if (EreadAll(0, &len, sizeof len) &&
159 struct passwd * res = 0;
161 if (EreadAll(0, buf, len)) {
166 if (res!=0) sendResult(true, res->pw_uid);
167 else sendResult(false, -1);
177 if (EreadAll(0, &len, sizeof len) &&
180 struct group * res = 0;
182 if (EreadAll(0, buf, len)) {
187 if (res!=0) sendResult(true, res->gr_gid);
188 else sendResult(false, -1);
198 if (EreadAll(0, &what, sizeof what)) {
200 case 'p' : endpwent(); break;
201 case 'g' : endgrent(); break;
212 while (EwriteAll(3, ".", 1),
213 EreadAll (0, &c, sizeof c)) {
215 case 'P' : do_getpwnam(); break;
216 case 'G' : do_getgrnam(); break;
218 case 'C' : do_closenss(); break;
219 case '.' : Ewrite(1, ".", 1); break;
220 default : Ewrite(1, "?", 1); break;
226 daemonize(struct ArgInfo const UNUSED * args, int pid_fd)
237 char buf[sizeof(id_t)*3 + 2];
240 l = utilvserver_fmt_uint(buf, pid);
241 Ewrite(pid_fd, buf, l);
242 Ewrite(pid_fd, "\n", 1);
247 TEMP_FAILURE_RETRY(read(p[0], &c, 1));
252 activateContext(xid_t xid, bool in_ctx,
253 uint32_t xid_caps, int xid_flags)
256 struct vc_ctx_flags flags = {
258 .mask = VC_VXF_STATE_SETUP,
261 Evc_set_cflags(xid, &flags);
263 else if (vc_isSupported(vcFEATURE_MIGRATE))
264 Evc_ctx_migrate(xid);
266 #ifdef VC_ENABLE_API_COMPAT
267 Evc_new_s_context(xid, xid_caps, xid_flags);
269 WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "can not change context: migrate kernel feature missing and 'compat' API disabled\n");
270 exit(wrapper_exit_code);
275 int main(int argc, char * argv[])
277 struct ArgInfo args = {
278 .ctx = VC_DYNAMIC_XID,
285 .flags = S_CTX_INFO_LOCK,
290 # warning *** rpm-fake-resolver is built against glibc; please do not report errors before trying a dietlibc version ***
292 "*** rpm-fake-resolver was built with glibc; please do ***\n"
293 "*** not report errors before trying a dietlibc version. ***\n");
296 parseArgs(&args, argc, argv);
297 if (args.pid_file && args.do_fork)
298 pid_fd = EopenD(args.pid_file, O_CREAT|O_WRONLY, 0644);
300 if (args.chroot) Echroot(args.chroot);
303 activateContext(args.ctx, args.in_ctx, args.caps, args.flags);
304 Esetgroups(0, &args.gid);
308 if (args.do_fork) daemonize(&args, pid_fd);
309 if (pid_fd!=-1) close(pid_fd);