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]
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>
32 #include "nscd_door.h"
34 #include <getxby_door.h>
35 #include <sys/types.h>
40 initdoor(void *buf
, int *doorfd
)
42 nss_pheader_t
*phdr
= (nss_pheader_t
*)buf
;
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
,
53 NSCD_SET_STATUS(phdr
, NSS_ERROR
, errno
);
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
);
73 NSCD_SET_STATUS_SUCCESS(phdr
);
76 /* general door call functions used by nscd */
79 copy_output(void *outdata
, int outdlen
,
80 nss_pheader_t
*phdr
, nss_pheader_t
*outphdr
)
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
);
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
);
110 _nscd_doorcall(int callnum
)
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
);
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
)));
142 _nscd_doorcall_data(int callnum
, void *indata
, int indlen
,
143 void *outdata
, int outdlen
, nss_pheader_t
*phdr
)
151 nss_pheader_t
*phdr_d
;
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
);
163 datap
= NSCD_N2N_DOOR_DATA(void, dptr
);
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
)));
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 */
183 (void) munmap(dptr
, ndata
);
189 _nscd_doorcall_fd(int fd
, int callnum
, void *indata
, int indlen
,
190 void *outdata
, int outdlen
, nss_pheader_t
*phdr
)
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
);
211 datap
= NSCD_N2N_DOOR_DATA(void, dptr
);
213 (void) memmove(datap
, indata
, indlen
);
215 param
.rbuf
= (char *)dptr
;
217 param
.data_ptr
= (char *)dptr
;
218 param
.data_size
= adata
;
219 param
.desc_ptr
= NULL
;
221 ret
= door_call(fd
, ¶m
);
225 * door call did not get through, return errno
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
));
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
) {
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
));
258 ret
= copy_output(outdata
, outdlen
, phdr_d
, phdr
);
260 /* if new buffer allocated for this door call, free it */
262 (void) munmap(dptr
, param
.rsize
);
269 send_doorfd(void **dptr
, size_t *ndata
, size_t *adata
,
272 nss_pheader_t
*phdr
= (nss_pheader_t
*)*dptr
;
277 char *me
= "send_doorfd";
279 initdoor(*dptr
, &doorfd
);
280 if (NSCD_STATUS_IS_NOT_OK(phdr
))
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
;
289 ret
= door_call(doorfd
, ¶m
);
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
);
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
)
308 NSCD_SET_STATUS(phdr
, NSS_ERROR
, ENOTCONN
);
311 (void) close(doorfd
);
315 _nscd_doorcall_sendfd(int fd
, int callnum
, void *indata
, int indlen
,
324 nss_pheader_t
*phdr_d
;
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
);
336 datap
= NSCD_N2N_DOOR_DATA(void, dptr
);
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
)) {
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
));