source: rtems-libbsd/freebsd/sbin/dhclient/privsep.c @ 68bf405

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 68bf405 was d48955b, checked in by Sebastian Huber <sebastian.huber@…>, on 11/06/13 at 08:02:16

Add and use <machine/rtems-bsd-user-space.h>

  • Property mode set to 100644
File size: 6.1 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*      $OpenBSD: privsep.c,v 1.7 2004/05/10 18:34:42 deraadt Exp $ */
4
5/*
6 * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
17 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
18 * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
19 */
20
21#include <sys/cdefs.h>
22__FBSDID("$FreeBSD$");
23
24#include "dhcpd.h"
25#include "privsep.h"
26
27struct buf *
28buf_open(size_t len)
29{
30        struct buf      *buf;
31
32        if ((buf = calloc(1, sizeof(struct buf))) == NULL)
33                return (NULL);
34        if ((buf->buf = malloc(len)) == NULL) {
35                free(buf);
36                return (NULL);
37        }
38        buf->size = len;
39
40        return (buf);
41}
42
43int
44buf_add(struct buf *buf, void *data, size_t len)
45{
46        if (buf->wpos + len > buf->size)
47                return (-1);
48
49        memcpy(buf->buf + buf->wpos, data, len);
50        buf->wpos += len;
51        return (0);
52}
53
54int
55buf_close(int sock, struct buf *buf)
56{
57        ssize_t n;
58
59        do {
60                n = write(sock, buf->buf + buf->rpos, buf->size - buf->rpos);
61                if (n != -1)
62                        buf->rpos += n;
63                if (n == 0) {                   /* connection closed */
64                        errno = 0;
65                        return (-1);
66                }
67        } while (n == -1 && (errno == EAGAIN || errno == EINTR));
68
69        if (buf->rpos < buf->size)
70                error("short write: wanted %lu got %ld bytes",
71                    (unsigned long)buf->size, (long)buf->rpos);
72
73        free(buf->buf);
74        free(buf);
75        return (n);
76}
77
78ssize_t
79buf_read(int sock, void *buf, size_t nbytes)
80{
81        ssize_t n, r = 0;
82        char *p = buf;
83
84        do {
85                n = read(sock, p, nbytes);
86                if (n == 0)
87                        error("connection closed");
88                if (n != -1) {
89                        r += n;
90                        p += n;
91                        nbytes -= n;
92                }
93        } while (n == -1 && (errno == EINTR || errno == EAGAIN));
94
95        if (n == -1)
96                error("buf_read: %m");
97
98        if (r < nbytes)
99                error("short read: wanted %lu got %ld bytes",
100                    (unsigned long)nbytes, (long)r);
101
102        return (r);
103}
104
105void
106dispatch_imsg(int fd)
107{
108        struct imsg_hdr          hdr;
109        char                    *medium, *reason, *filename,
110                                *servername, *prefix;
111        size_t                   medium_len, reason_len, filename_len,
112                                 servername_len, prefix_len, totlen;
113        struct client_lease      lease;
114        int                      ret, i, optlen;
115        struct buf              *buf;
116
117        buf_read(fd, &hdr, sizeof(hdr));
118
119        switch (hdr.code) {
120        case IMSG_SCRIPT_INIT:
121                if (hdr.len < sizeof(hdr) + sizeof(size_t))
122                        error("corrupted message received");
123                buf_read(fd, &medium_len, sizeof(medium_len));
124                if (hdr.len < medium_len + sizeof(size_t) + sizeof(hdr)
125                    + sizeof(size_t) || medium_len == SIZE_T_MAX)
126                        error("corrupted message received");
127                if (medium_len > 0) {
128                        if ((medium = calloc(1, medium_len + 1)) == NULL)
129                                error("%m");
130                        buf_read(fd, medium, medium_len);
131                } else
132                        medium = NULL;
133
134                buf_read(fd, &reason_len, sizeof(reason_len));
135                if (hdr.len < medium_len + reason_len + sizeof(hdr) ||
136                    reason_len == SIZE_T_MAX)
137                        error("corrupted message received");
138                if (reason_len > 0) {
139                        if ((reason = calloc(1, reason_len + 1)) == NULL)
140                                error("%m");
141                        buf_read(fd, reason, reason_len);
142                } else
143                        reason = NULL;
144
145                priv_script_init(reason, medium);
146                free(reason);
147                free(medium);
148                break;
149        case IMSG_SCRIPT_WRITE_PARAMS:
150                bzero(&lease, sizeof lease);
151                totlen = sizeof(hdr) + sizeof(lease) + sizeof(size_t);
152                if (hdr.len < totlen)
153                        error("corrupted message received");
154                buf_read(fd, &lease, sizeof(lease));
155
156                buf_read(fd, &filename_len, sizeof(filename_len));
157                totlen += filename_len + sizeof(size_t);
158                if (hdr.len < totlen || filename_len == SIZE_T_MAX)
159                        error("corrupted message received");
160                if (filename_len > 0) {
161                        if ((filename = calloc(1, filename_len + 1)) == NULL)
162                                error("%m");
163                        buf_read(fd, filename, filename_len);
164                } else
165                        filename = NULL;
166
167                buf_read(fd, &servername_len, sizeof(servername_len));
168                totlen += servername_len + sizeof(size_t);
169                if (hdr.len < totlen || servername_len == SIZE_T_MAX)
170                        error("corrupted message received");
171                if (servername_len > 0) {
172                        if ((servername =
173                            calloc(1, servername_len + 1)) == NULL)
174                                error("%m");
175                        buf_read(fd, servername, servername_len);
176                } else
177                        servername = NULL;
178
179                buf_read(fd, &prefix_len, sizeof(prefix_len));
180                totlen += prefix_len;
181                if (hdr.len < totlen || prefix_len == SIZE_T_MAX)
182                        error("corrupted message received");
183                if (prefix_len > 0) {
184                        if ((prefix = calloc(1, prefix_len + 1)) == NULL)
185                                error("%m");
186                        buf_read(fd, prefix, prefix_len);
187                } else
188                        prefix = NULL;
189
190                for (i = 0; i < 256; i++) {
191                        totlen += sizeof(optlen);
192                        if (hdr.len < totlen)
193                                error("corrupted message received");
194                        buf_read(fd, &optlen, sizeof(optlen));
195                        lease.options[i].data = NULL;
196                        lease.options[i].len = optlen;
197                        if (optlen > 0) {
198                                totlen += optlen;
199                                if (hdr.len < totlen || optlen == SIZE_T_MAX)
200                                        error("corrupted message received");
201                                lease.options[i].data =
202                                    calloc(1, optlen + 1);
203                                if (lease.options[i].data == NULL)
204                                    error("%m");
205                                buf_read(fd, lease.options[i].data, optlen);
206                        }
207                }
208                lease.server_name = servername;
209                lease.filename = filename;
210
211                priv_script_write_params(prefix, &lease);
212
213                free(servername);
214                free(filename);
215                free(prefix);
216                for (i = 0; i < 256; i++)
217                        if (lease.options[i].len > 0)
218                                free(lease.options[i].data);
219                break;
220        case IMSG_SCRIPT_GO:
221                if (hdr.len != sizeof(hdr))
222                        error("corrupted message received");
223
224                ret = priv_script_go();
225
226                hdr.code = IMSG_SCRIPT_GO_RET;
227                hdr.len = sizeof(struct imsg_hdr) + sizeof(int);
228                if ((buf = buf_open(hdr.len)) == NULL)
229                        error("buf_open: %m");
230                if (buf_add(buf, &hdr, sizeof(hdr)))
231                        error("buf_add: %m");
232                if (buf_add(buf, &ret, sizeof(ret)))
233                        error("buf_add: %m");
234                if (buf_close(fd, buf) == -1)
235                        error("buf_close: %m");
236                break;
237        default:
238                error("received unknown message, code %d", hdr.code);
239        }
240}
Note: See TracBrowser for help on using the repository browser.