1 /* $OpenBSD: privsep.c,v 1.14 2007/02/15 15:22:27 stevesk Exp $ */
2 /* $DragonFly: src/sbin/dhclient/privsep.c,v 1.1 2008/08/30 16:07:58 hasso Exp $ */
5 * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
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.
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 MIND, USE, DATA OR PROFITS, WHETHER IN
16 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17 * OF OR IN CONNECTION WITH THE USE, ABUSE OR PERFORMANCE OF THIS SOFTWARE.
28 if ((buf
= calloc(1, sizeof(struct buf
))) == NULL
)
29 error("buf_open: %m");
30 if ((buf
->buf
= malloc(len
)) == NULL
) {
32 error("buf_open: %m");
40 buf_add(struct buf
*buf
, void *data
, size_t len
)
45 if (buf
->wpos
+ len
> buf
->size
)
48 memcpy(buf
->buf
+ buf
->wpos
, data
, len
);
53 buf_close(int sock
, struct buf
*buf
)
58 n
= write(sock
, buf
->buf
+ buf
->rpos
, buf
->size
- buf
->rpos
);
59 if (n
== 0) /* connection closed */
60 error("buf_close (connection closed)");
61 if (n
!= -1 && n
< buf
->size
- buf
->rpos
)
62 error("buf_close (short write): %m");
64 } while (n
== -1 && (errno
== EAGAIN
|| errno
== EINTR
));
67 error("buf_close: %m");
74 buf_read(int sock
, void *buf
, size_t nbytes
)
79 n
= read(sock
, buf
, nbytes
);
80 if (n
== 0) { /* connection closed */
81 debug("buf_read (connection closed)");
84 if (n
!= -1 && n
< nbytes
)
85 error("buf_read (short read): %m");
86 } while (n
== -1 && (errno
== EINTR
|| errno
== EAGAIN
));
89 error("buf_read: %m");
96 char *medium
, *reason
, *filename
,
98 size_t medium_len
, reason_len
, filename_len
,
99 servername_len
, prefix_len
, totlen
;
100 struct client_lease lease
;
104 buf_read(fd
, &hdr
, sizeof(hdr
));
107 case IMSG_SCRIPT_INIT
:
108 if (hdr
.len
< sizeof(hdr
) + sizeof(size_t))
109 error("corrupted message received");
110 buf_read(fd
, &medium_len
, sizeof(medium_len
));
111 if (hdr
.len
< medium_len
+ sizeof(size_t) + sizeof(hdr
)
112 + sizeof(size_t) || medium_len
== SIZE_T_MAX
)
113 error("corrupted message received");
114 if (medium_len
> 0) {
115 if ((medium
= calloc(1, medium_len
+ 1)) == NULL
)
117 buf_read(fd
, medium
, medium_len
);
121 buf_read(fd
, &reason_len
, sizeof(reason_len
));
122 if (hdr
.len
< medium_len
+ reason_len
+ sizeof(hdr
) ||
123 reason_len
== SIZE_T_MAX
)
124 error("corrupted message received");
125 if (reason_len
> 0) {
126 if ((reason
= calloc(1, reason_len
+ 1)) == NULL
)
128 buf_read(fd
, reason
, reason_len
);
132 priv_script_init(reason
, medium
);
136 case IMSG_SCRIPT_WRITE_PARAMS
:
137 bzero(&lease
, sizeof lease
);
138 totlen
= sizeof(hdr
) + sizeof(lease
) + sizeof(size_t);
139 if (hdr
.len
< totlen
)
140 error("corrupted message received");
141 buf_read(fd
, &lease
, sizeof(lease
));
143 buf_read(fd
, &filename_len
, sizeof(filename_len
));
144 totlen
+= filename_len
+ sizeof(size_t);
145 if (hdr
.len
< totlen
|| filename_len
== SIZE_T_MAX
)
146 error("corrupted message received");
147 if (filename_len
> 0) {
148 if ((filename
= calloc(1, filename_len
+ 1)) == NULL
)
150 buf_read(fd
, filename
, filename_len
);
154 buf_read(fd
, &servername_len
, sizeof(servername_len
));
155 totlen
+= servername_len
+ sizeof(size_t);
156 if (hdr
.len
< totlen
|| servername_len
== SIZE_T_MAX
)
157 error("corrupted message received");
158 if (servername_len
> 0) {
160 calloc(1, servername_len
+ 1)) == NULL
)
162 buf_read(fd
, servername
, servername_len
);
166 buf_read(fd
, &prefix_len
, sizeof(prefix_len
));
167 totlen
+= prefix_len
;
168 if (hdr
.len
< totlen
|| prefix_len
== SIZE_T_MAX
)
169 error("corrupted message received");
170 if (prefix_len
> 0) {
171 if ((prefix
= calloc(1, prefix_len
+ 1)) == NULL
)
173 buf_read(fd
, prefix
, prefix_len
);
177 for (i
= 0; i
< 256; i
++) {
178 totlen
+= sizeof(optlen
);
179 if (hdr
.len
< totlen
)
180 error("corrupted message received");
181 buf_read(fd
, &optlen
, sizeof(optlen
));
182 lease
.options
[i
].data
= NULL
;
183 lease
.options
[i
].len
= optlen
;
186 if (hdr
.len
< totlen
|| optlen
== SIZE_T_MAX
)
187 error("corrupted message received");
188 lease
.options
[i
].data
=
189 calloc(1, optlen
+ 1);
190 if (lease
.options
[i
].data
== NULL
)
192 buf_read(fd
, lease
.options
[i
].data
, optlen
);
195 lease
.server_name
= servername
;
196 lease
.filename
= filename
;
198 priv_script_write_params(prefix
, &lease
);
203 for (i
= 0; i
< 256; i
++)
204 if (lease
.options
[i
].len
> 0)
205 free(lease
.options
[i
].data
);
208 if (hdr
.len
!= sizeof(hdr
))
209 error("corrupted message received");
211 ret
= priv_script_go();
213 hdr
.code
= IMSG_SCRIPT_GO_RET
;
214 hdr
.len
= sizeof(struct imsg_hdr
) + sizeof(int);
215 if ((buf
= buf_open(hdr
.len
)) == NULL
)
216 error("buf_open: %m");
217 buf_add(buf
, &hdr
, sizeof(hdr
));
218 buf_add(buf
, &ret
, sizeof(ret
));
222 error("received unknown message, code %d", hdr
.code
);