comm: add -Wall
[unleashed.git] / usr / src / cmd / nscd / nscd_door.c
blob9b02c1ea88dc010a58f27fb80b451c24fee70fb7
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2012 Milan Jurik. All rights reserved.
28 #include <sys/param.h>
29 #include <string.h>
30 #include <door.h>
31 #include <sys/mman.h>
32 #include "nscd_door.h"
33 #include "nscd_log.h"
34 #include <getxby_door.h>
35 #include <sys/types.h>
36 #include <errno.h>
37 #include <fcntl.h>
39 static void
40 initdoor(void *buf, int *doorfd)
42 nss_pheader_t *phdr = (nss_pheader_t *)buf;
43 door_info_t doori;
44 char *me = "initdoor";
46 *doorfd = open64(NAME_SERVICE_DOOR, O_RDONLY, 0);
48 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
49 (me, "door is %s (fd is %d)\n", NAME_SERVICE_DOOR,
50 *doorfd);
52 if (*doorfd == -1) {
53 NSCD_SET_STATUS(phdr, NSS_ERROR, errno);
54 return;
57 if (door_info(*doorfd, &doori) < 0 ||
58 (doori.di_attributes & DOOR_REVOKED) ||
59 doori.di_data != (uintptr_t)NAME_SERVICE_DOOR_COOKIE) {
62 * we should close doorfd because we just opened it
64 (void) close(*doorfd);
66 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
67 (me, "door %d not valid\n", *doorfd);
69 NSCD_SET_STATUS(phdr, NSS_ERROR, ECONNREFUSED);
70 return;
73 NSCD_SET_STATUS_SUCCESS(phdr);
76 /* general door call functions used by nscd */
78 static nss_status_t
79 copy_output(void *outdata, int outdlen,
80 nss_pheader_t *phdr, nss_pheader_t *outphdr)
82 void *dp;
83 nss_status_t ret = NSS_SUCCESS;
84 char *me = "copy_output";
86 if (outdata != NULL && phdr->data_off > 0 && phdr->data_len > 0) {
87 if (phdr->data_len <= outdlen) {
88 dp = (char *)phdr + phdr->data_off;
89 (void) memmove(outdata, dp, phdr->data_len);
90 } else {
92 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
93 (me, "output buffer not large enough "
94 " should be > %d but is %d\n",
95 phdr->data_len, outdlen);
97 if (outphdr != NULL) {
98 NSCD_SET_N2N_STATUS(phdr, NSS_NSCD_PRIV,
99 0, NSCD_INVALID_ARGUMENT);
100 NSCD_COPY_STATUS(outphdr, phdr);
102 ret = NSS_NSCD_PRIV;
106 return (ret);
109 nss_status_t
110 _nscd_doorcall(int callnum)
112 size_t buflen;
113 nss_pheader_t *phdr;
114 void *dptr;
115 size_t ndata;
116 size_t adata;
117 int ret;
118 char *me = "_nscd_doorcall";
120 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
121 (me, "processing door call %d ...\n", callnum);
123 /* allocate door buffer from the stack */
124 NSCD_ALLOC_DOORBUF(callnum, 0, dptr, buflen);
125 ndata = buflen;
126 adata = buflen;
128 ret = _nsc_trydoorcall(&dptr, &ndata, &adata);
130 if (ret != NSS_SUCCESS) {
131 phdr = (nss_pheader_t *)dptr;
132 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
133 (me, "door call (%d) failed (status = %d, error = %s)\n",
134 callnum, ret, strerror(NSCD_GET_ERRNO(phdr)));
137 return (ret);
141 nss_status_t
142 _nscd_doorcall_data(int callnum, void *indata, int indlen,
143 void *outdata, int outdlen, nss_pheader_t *phdr)
145 void *uptr;
146 size_t buflen;
147 void *dptr;
148 void *datap;
149 size_t ndata;
150 size_t adata;
151 nss_pheader_t *phdr_d;
152 int ret;
153 char *me = "_nscd_doorcall_data";
155 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
156 (me, "processing door call %d ...\n", callnum);
158 /* allocate door buffer from the stack */
159 NSCD_ALLOC_DOORBUF(callnum, indlen, uptr, buflen);
160 dptr = uptr;
161 ndata = buflen;
162 adata = buflen;
163 datap = NSCD_N2N_DOOR_DATA(void, dptr);
164 if (indata != NULL)
165 (void) memmove(datap, indata, indlen);
167 ret = _nsc_trydoorcall(&dptr, &ndata, &adata);
169 phdr_d = (nss_pheader_t *)dptr;
170 if (ret != NSS_SUCCESS) {
171 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
172 (me, "door call (%d) failed (status = %d, error = %s)\n",
173 callnum, ret, strerror(NSCD_GET_ERRNO(phdr_d)));
174 } else {
175 if (phdr != NULL) {
176 NSCD_COPY_STATUS(phdr, phdr_d);
178 ret = copy_output(outdata, outdlen, phdr_d, phdr);
181 /* if new buffer allocated for this door call, free it */
182 if (dptr != uptr)
183 (void) munmap(dptr, ndata);
185 return (ret);
188 nss_status_t
189 _nscd_doorcall_fd(int fd, int callnum, void *indata, int indlen,
190 void *outdata, int outdlen, nss_pheader_t *phdr)
192 void *uptr;
193 void *dptr;
194 void *datap;
195 size_t ndata;
196 size_t adata;
197 size_t buflen;
198 door_arg_t param;
199 int ret, errnum;
200 nss_pheader_t *phdr_d;
201 char *me = "_nscd_doorcall_fd";
203 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
204 (me, "processing door call %d (fd = %d)...\n", callnum, fd);
206 /* allocate door buffer from the stack */
207 NSCD_ALLOC_DOORBUF(callnum, indlen, uptr, buflen);
208 dptr = uptr;
209 ndata = buflen;
210 adata = buflen;
211 datap = NSCD_N2N_DOOR_DATA(void, dptr);
212 if (indata != NULL)
213 (void) memmove(datap, indata, indlen);
215 param.rbuf = (char *)dptr;
216 param.rsize = ndata;
217 param.data_ptr = (char *)dptr;
218 param.data_size = adata;
219 param.desc_ptr = NULL;
220 param.desc_num = 0;
221 ret = door_call(fd, &param);
222 if (ret < 0) {
223 errnum = errno;
225 * door call did not get through, return errno
226 * if requested
228 if (phdr != NULL) {
229 NSCD_SET_STATUS(phdr, NSS_ERROR, errnum);
232 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
233 (me, "door call (%d to %d) did not get through (%s)\n",
234 callnum, fd, strerror(errnum));
236 return (NSS_ERROR);
238 ndata = param.rsize;
239 dptr = (void *)param.data_ptr;
242 * door call got through, check if operation failed.
243 * if so, return error info if requested
245 phdr_d = (nss_pheader_t *)dptr;
246 ret = NSCD_GET_STATUS(phdr_d);
247 if (ret != NSS_SUCCESS) {
248 if (phdr != NULL) {
249 NSCD_COPY_STATUS(phdr, phdr_d);
252 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
253 (me, "door call (%d to %d) failed: p_status = %d, "
254 "p_errno = %s, nscd status = %d\n", callnum, fd,
255 ret, strerror(NSCD_GET_ERRNO(phdr_d)),
256 NSCD_GET_NSCD_STATUS(phdr_d));
257 } else
258 ret = copy_output(outdata, outdlen, phdr_d, phdr);
260 /* if new buffer allocated for this door call, free it */
261 if (dptr != uptr)
262 (void) munmap(dptr, param.rsize);
265 return (ret);
268 static void
269 send_doorfd(void **dptr, size_t *ndata, size_t *adata,
270 door_desc_t *pdesc)
272 nss_pheader_t *phdr = (nss_pheader_t *)*dptr;
273 door_arg_t param;
274 int ret;
275 int doorfd;
276 int errnum;
277 char *me = "send_doorfd";
279 initdoor(*dptr, &doorfd);
280 if (NSCD_STATUS_IS_NOT_OK(phdr))
281 return;
283 param.rbuf = (char *)*dptr;
284 param.rsize = *ndata;
285 param.data_ptr = (char *)*dptr;
286 param.data_size = *adata;
287 param.desc_ptr = pdesc;
288 param.desc_num = 1;
289 ret = door_call(doorfd, &param);
290 if (ret < 0) {
291 errnum = errno;
293 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
294 (me, "door call (to fd %d) failed (%s)\n",
295 doorfd, strerror(errnum));
296 (void) close(doorfd);
297 NSCD_SET_STATUS(phdr, NSS_ERROR, errnum);
298 return;
300 *adata = param.data_size;
301 *ndata = param.rsize;
302 *dptr = (void *)param.data_ptr;
304 if (*adata == 0 || *dptr == NULL) {
305 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
306 (me, "no data\n");
308 NSCD_SET_STATUS(phdr, NSS_ERROR, ENOTCONN);
311 (void) close(doorfd);
314 nss_status_t
315 _nscd_doorcall_sendfd(int fd, int callnum, void *indata, int indlen,
316 nss_pheader_t *phdr)
318 void *uptr;
319 void *dptr;
320 void *datap;
321 size_t ndata;
322 size_t adata;
323 size_t buflen;
324 nss_pheader_t *phdr_d;
325 door_desc_t desc;
326 char *me = "_nscd_doorcall_sendfd";
328 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
329 (me, "processing door call %d (fd = %d)...\n", callnum, fd);
331 /* allocate door buffer from the stack */
332 NSCD_ALLOC_DOORBUF(callnum, indlen, uptr, buflen);
333 dptr = uptr;
334 ndata = buflen;
335 adata = buflen;
336 datap = NSCD_N2N_DOOR_DATA(void, dptr);
337 if (indata != NULL)
338 (void) memmove(datap, indata, indlen);
339 desc.d_attributes = DOOR_DESCRIPTOR;
340 desc.d_data.d_desc.d_descriptor = fd;
342 send_doorfd(&dptr, &ndata, &adata, &desc);
344 phdr_d = (nss_pheader_t *)dptr;
345 if (NSCD_STATUS_IS_NOT_OK(phdr_d)) {
346 if (phdr != NULL)
347 *phdr = *phdr_d;
349 _NSCD_LOG(NSCD_LOG_FRONT_END, NSCD_LOG_LEVEL_DEBUG)
350 (me, "door call (%d) failed (status = %d, error = %s)\n",
351 callnum, NSCD_GET_STATUS(phdr_d),
352 strerror(NSCD_GET_ERRNO(phdr_d)));
355 return (NSCD_GET_STATUS(phdr_d));