privsep.c (145840) | privsep.c (171172) |
---|---|
1/* $OpenBSD: privsep.c,v 1.13 2004/12/22 09:21:02 otto Exp $ */ | 1/* $OpenBSD: privsep.c,v 1.16 2006/10/25 20:55:04 moritz Exp $ */ |
2 3/* 4 * Copyright (c) 2003 Can Erkin Acar 5 * Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20#include <sys/cdefs.h> | 2 3/* 4 * Copyright (c) 2003 Can Erkin Acar 5 * Copyright (c) 2003 Anil Madhavapeddy <anil@recoil.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20#include <sys/cdefs.h> |
21__FBSDID("$FreeBSD: head/contrib/pf/pflogd/privsep.c 145840 2005-05-03 16:55:20Z mlaier $"); | 21__FBSDID("$FreeBSD: head/contrib/pf/pflogd/privsep.c 171172 2007-07-03 12:30:03Z mlaier $"); |
22 | 22 |
23#include <sys/param.h> | 23#include <sys/types.h> |
24#include <sys/time.h> 25#include <sys/socket.h> 26 27#include <net/if.h> 28#include <net/bpf.h> 29 30#include <err.h> 31#include <errno.h> 32#include <fcntl.h> | 24#include <sys/time.h> 25#include <sys/socket.h> 26 27#include <net/if.h> 28#include <net/bpf.h> 29 30#include <err.h> 31#include <errno.h> 32#include <fcntl.h> |
33#include <limits.h> 34#ifndef __FreeBSD__ 35#include <pcap.h> 36#include <pcap-int.h> 37#endif |
|
33#include <pwd.h> 34#include <signal.h> 35#include <stdio.h> 36#include <stdlib.h> 37#include <string.h> | 38#include <pwd.h> 39#include <signal.h> 40#include <stdio.h> 41#include <stdlib.h> 42#include <string.h> |
43#ifdef __FreeBSD__ 44/* XXX: pcap pollutes namespace with strlcpy if not present previously */ |
|
38#include <pcap.h> 39#include <pcap-int.h> | 45#include <pcap.h> 46#include <pcap-int.h> |
47#endif |
|
40#include <syslog.h> 41#include <unistd.h> 42#include "pflogd.h" 43 44enum cmd_types { 45 PRIV_SET_SNAPLEN, /* set the snaplength */ | 48#include <syslog.h> 49#include <unistd.h> 50#include "pflogd.h" 51 52enum cmd_types { 53 PRIV_SET_SNAPLEN, /* set the snaplength */ |
54 PRIV_MOVE_LOG, /* move logfile away */ |
|
46 PRIV_OPEN_LOG /* open logfile for appending */ 47}; 48 49static int priv_fd = -1; 50static volatile pid_t child_pid = -1; 51 52volatile sig_atomic_t gotsig_chld = 0; 53 54static void sig_pass_to_chld(int); 55static void sig_chld(int); 56static int may_read(int, void *, size_t); 57static void must_read(int, void *, size_t); 58static void must_write(int, void *, size_t); 59static int set_snaplen(int snap); | 55 PRIV_OPEN_LOG /* open logfile for appending */ 56}; 57 58static int priv_fd = -1; 59static volatile pid_t child_pid = -1; 60 61volatile sig_atomic_t gotsig_chld = 0; 62 63static void sig_pass_to_chld(int); 64static void sig_chld(int); 65static int may_read(int, void *, size_t); 66static void must_read(int, void *, size_t); 67static void must_write(int, void *, size_t); 68static int set_snaplen(int snap); |
69static int move_log(const char *name); |
|
60 | 70 |
61/* bpf filter expression common to parent and child */ 62extern char *filter; 63extern char *errbuf; | |
64extern char *filename; 65extern pcap_t *hpcap; 66 67/* based on syslogd privsep */ 68int 69priv_init(void) 70{ 71 int i, fd, socks[2], cmd; --- 25 unchanged lines hidden (view full) --- 97 98 /* Child - drop privileges and return */ 99 if (chroot(pw->pw_dir) != 0) 100 err(1, "unable to chroot"); 101 if (chdir("/") != 0) 102 err(1, "unable to chdir"); 103 104 gidset[0] = pw->pw_gid; | 71extern char *filename; 72extern pcap_t *hpcap; 73 74/* based on syslogd privsep */ 75int 76priv_init(void) 77{ 78 int i, fd, socks[2], cmd; --- 25 unchanged lines hidden (view full) --- 104 105 /* Child - drop privileges and return */ 106 if (chroot(pw->pw_dir) != 0) 107 err(1, "unable to chroot"); 108 if (chdir("/") != 0) 109 err(1, "unable to chdir"); 110 111 gidset[0] = pw->pw_gid; |
112 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) 113 err(1, "setresgid() failed"); |
|
105 if (setgroups(1, gidset) == -1) 106 err(1, "setgroups() failed"); | 114 if (setgroups(1, gidset) == -1) 115 err(1, "setgroups() failed"); |
107 if (setegid(pw->pw_gid) == -1) 108 err(1, "setegid() failed"); 109 if (setgid(pw->pw_gid) == -1) 110 err(1, "setgid() failed"); 111 if (seteuid(pw->pw_uid) == -1) 112 err(1, "seteuid() failed"); 113 if (setuid(pw->pw_uid) == -1) 114 err(1, "setuid() failed"); | 116 if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) 117 err(1, "setresuid() failed"); |
115 close(socks[0]); 116 priv_fd = socks[1]; 117 return 0; 118 } 119 120 /* Father */ 121 /* Pass ALRM/TERM/HUP/INT/QUIT through to child, and accept CHLD */ 122 signal(SIGALRM, sig_pass_to_chld); --- 37 unchanged lines hidden (view full) --- 160 if (fd < 0) 161 logmsg(LOG_NOTICE, 162 "[priv]: failed to open %s: %s", 163 filename, strerror(olderrno)); 164 else 165 close(fd); 166 break; 167 | 118 close(socks[0]); 119 priv_fd = socks[1]; 120 return 0; 121 } 122 123 /* Father */ 124 /* Pass ALRM/TERM/HUP/INT/QUIT through to child, and accept CHLD */ 125 signal(SIGALRM, sig_pass_to_chld); --- 37 unchanged lines hidden (view full) --- 163 if (fd < 0) 164 logmsg(LOG_NOTICE, 165 "[priv]: failed to open %s: %s", 166 filename, strerror(olderrno)); 167 else 168 close(fd); 169 break; 170 |
171 case PRIV_MOVE_LOG: 172 logmsg(LOG_DEBUG, 173 "[priv]: msg PRIV_MOVE_LOG received"); 174 ret = move_log(filename); 175 must_write(socks[0], &ret, sizeof(int)); 176 break; 177 |
|
168 default: 169 logmsg(LOG_ERR, "[priv]: unknown command %d", cmd); 170 _exit(1); 171 /* NOTREACHED */ 172 } 173 } 174 175 _exit(1); --- 7 unchanged lines hidden (view full) --- 183 return (1); 184 185 hpcap->snapshot = snap; 186 set_pcap_filter(); 187 188 return 0; 189} 190 | 178 default: 179 logmsg(LOG_ERR, "[priv]: unknown command %d", cmd); 180 _exit(1); 181 /* NOTREACHED */ 182 } 183 } 184 185 _exit(1); --- 7 unchanged lines hidden (view full) --- 193 return (1); 194 195 hpcap->snapshot = snap; 196 set_pcap_filter(); 197 198 return 0; 199} 200 |
201static int 202move_log(const char *name) 203{ 204 char ren[PATH_MAX]; 205 int len; |
|
191 | 206 |
207 for (;;) { 208 int fd; 209 210 len = snprintf(ren, sizeof(ren), "%s.bad.%08x", 211 name, arc4random()); 212 if (len >= sizeof(ren)) { 213 logmsg(LOG_ERR, "[priv] new name too long"); 214 return (1); 215 } 216 217 /* lock destinanion */ 218 fd = open(ren, O_CREAT|O_EXCL, 0); 219 if (fd >= 0) { 220 close(fd); 221 break; 222 } 223 /* if file exists, try another name */ 224 if (errno != EEXIST && errno != EINTR) { 225 logmsg(LOG_ERR, "[priv] failed to create new name: %s", 226 strerror(errno)); 227 return (1); 228 } 229 } 230 231 if (rename(name, ren)) { 232 logmsg(LOG_ERR, "[priv] failed to rename %s to %s: %s", 233 name, ren, strerror(errno)); 234 return (1); 235 } 236 237 logmsg(LOG_NOTICE, 238 "[priv]: log file %s moved to %s", name, ren); 239 240 return (0); 241} 242 |
|
192/* 193 * send the snaplength to privileged process 194 */ 195int 196priv_set_snaplen(int snaplen) 197{ 198 int cmd, ret; 199 --- 24 unchanged lines hidden (view full) --- 224 errx(1, "%s: called from privileged portion", __func__); 225 226 cmd = PRIV_OPEN_LOG; 227 must_write(priv_fd, &cmd, sizeof(int)); 228 fd = receive_fd(priv_fd); 229 230 return (fd); 231} | 243/* 244 * send the snaplength to privileged process 245 */ 246int 247priv_set_snaplen(int snaplen) 248{ 249 int cmd, ret; 250 --- 24 unchanged lines hidden (view full) --- 275 errx(1, "%s: called from privileged portion", __func__); 276 277 cmd = PRIV_OPEN_LOG; 278 must_write(priv_fd, &cmd, sizeof(int)); 279 fd = receive_fd(priv_fd); 280 281 return (fd); 282} |
283/* Move-away and reopen log-file */ 284int 285priv_move_log(void) 286{ 287 int cmd, ret; |
|
232 | 288 |
289 if (priv_fd < 0) 290 errx(1, "%s: called from privileged portion\n", __func__); 291 292 cmd = PRIV_MOVE_LOG; 293 must_write(priv_fd, &cmd, sizeof(int)); 294 must_read(priv_fd, &ret, sizeof(int)); 295 296 return (ret); 297} 298 |
|
233/* If priv parent gets a TERM or HUP, pass it through to child instead */ 234static void 235sig_pass_to_chld(int sig) 236{ 237 int oerrno = errno; 238 239 if (child_pid != -1) 240 kill(child_pid, sig); --- 75 unchanged lines hidden --- | 299/* If priv parent gets a TERM or HUP, pass it through to child instead */ 300static void 301sig_pass_to_chld(int sig) 302{ 303 int oerrno = errno; 304 305 if (child_pid != -1) 306 kill(child_pid, sig); --- 75 unchanged lines hidden --- |