1 /* $OpenBSD: src/sbin/dhclient/privsep.c,v 1.16 2011/04/04 11:14:52 krw Exp $ */
4 * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER IN
15 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
27 if ((buf
= calloc(1, sizeof(struct buf
))) == NULL
)
28 error("buf_open: %m");
29 if ((buf
->buf
= malloc(len
)) == NULL
) {
31 error("buf_open: %m");
39 buf_add(struct buf
*buf
, void *data
, size_t len
)
44 if (buf
->wpos
+ len
> buf
->size
)
47 memcpy(buf
->buf
+ buf
->wpos
, data
, len
);
52 buf_close(int sock
, struct buf
*buf
)
57 n
= write(sock
, buf
->buf
+ buf
->rpos
, buf
->size
- buf
->rpos
);
58 if (n
== 0) /* connection closed */
59 error("buf_close (connection closed)");
60 if (n
!= -1 && n
< buf
->size
- buf
->rpos
)
61 error("buf_close (short write): %m");
63 } while (n
== -1 && (errno
== EAGAIN
|| errno
== EINTR
));
66 error("buf_close: %m");
73 buf_read(int sock
, void *buf
, size_t nbytes
)
78 n
= read(sock
, buf
, nbytes
);
79 if (n
== 0) { /* connection closed */
81 debug("buf_read (connection closed)");
85 if (n
!= -1 && n
< nbytes
)
86 error("buf_read (short read): %m");
87 } while (n
== -1 && (errno
== EINTR
|| errno
== EAGAIN
));
90 error("buf_read: %m");
97 char *reason
, *filename
,
99 size_t reason_len
, filename_len
,
100 servername_len
, prefix_len
, totlen
;
101 struct client_lease lease
;
105 buf_read(fd
, &hdr
, sizeof(hdr
));
108 case IMSG_SCRIPT_INIT
:
109 if (hdr
.len
< sizeof(hdr
) + sizeof(size_t))
110 error("corrupted message received");
111 buf_read(fd
, &reason_len
, sizeof(reason_len
));
112 if (hdr
.len
< reason_len
+ sizeof(hdr
) + sizeof(size_t) ||
113 reason_len
== SIZE_T_MAX
)
114 error("corrupted message received");
115 if (reason_len
> 0) {
116 if ((reason
= calloc(1, reason_len
+ 1)) == NULL
)
118 buf_read(fd
, reason
, reason_len
);
122 priv_script_init(reason
);
125 case IMSG_SCRIPT_WRITE_PARAMS
:
126 bzero(&lease
, sizeof lease
);
127 totlen
= sizeof(hdr
) + sizeof(lease
) + sizeof(size_t);
128 if (hdr
.len
< totlen
)
129 error("corrupted message received");
130 buf_read(fd
, &lease
, sizeof(lease
));
132 buf_read(fd
, &filename_len
, sizeof(filename_len
));
133 totlen
+= filename_len
+ sizeof(size_t);
134 if (hdr
.len
< totlen
|| filename_len
== SIZE_T_MAX
)
135 error("corrupted message received");
136 if (filename_len
> 0) {
137 if ((filename
= calloc(1, filename_len
+ 1)) == NULL
)
139 buf_read(fd
, filename
, filename_len
);
143 buf_read(fd
, &servername_len
, sizeof(servername_len
));
144 totlen
+= servername_len
+ sizeof(size_t);
145 if (hdr
.len
< totlen
|| servername_len
== SIZE_T_MAX
)
146 error("corrupted message received");
147 if (servername_len
> 0) {
149 calloc(1, servername_len
+ 1)) == NULL
)
151 buf_read(fd
, servername
, servername_len
);
155 buf_read(fd
, &prefix_len
, sizeof(prefix_len
));
156 totlen
+= prefix_len
;
157 if (hdr
.len
< totlen
|| prefix_len
== SIZE_T_MAX
)
158 error("corrupted message received");
159 if (prefix_len
> 0) {
160 if ((prefix
= calloc(1, prefix_len
+ 1)) == NULL
)
162 buf_read(fd
, prefix
, prefix_len
);
166 for (i
= 0; i
< 256; i
++) {
167 totlen
+= sizeof(optlen
);
168 if (hdr
.len
< totlen
)
169 error("corrupted message received");
170 buf_read(fd
, &optlen
, sizeof(optlen
));
171 lease
.options
[i
].data
= NULL
;
172 lease
.options
[i
].len
= optlen
;
175 if (hdr
.len
< totlen
|| optlen
== SIZE_T_MAX
)
176 error("corrupted message received");
177 lease
.options
[i
].data
=
178 calloc(1, optlen
+ 1);
179 if (lease
.options
[i
].data
== NULL
)
181 buf_read(fd
, lease
.options
[i
].data
, optlen
);
184 lease
.server_name
= servername
;
185 lease
.filename
= filename
;
187 priv_script_write_params(prefix
, &lease
);
192 for (i
= 0; i
< 256; i
++)
193 if (lease
.options
[i
].len
> 0)
194 free(lease
.options
[i
].data
);
197 if (hdr
.len
!= sizeof(hdr
))
198 error("corrupted message received");
200 ret
= priv_script_go();
202 hdr
.code
= IMSG_SCRIPT_GO_RET
;
203 hdr
.len
= sizeof(struct imsg_hdr
) + sizeof(int);
204 if ((buf
= buf_open(hdr
.len
)) == NULL
)
205 error("buf_open: %m");
206 buf_add(buf
, &hdr
, sizeof(hdr
));
207 buf_add(buf
, &ret
, sizeof(ret
));
211 error("received unknown message, code %d", hdr
.code
);