1 /* Tests for name switch cache daemon (nscd) door wrapper. */
10 #include <nss_dbdefs.h>
17 #if defined(SOLARIS_NSCD_DOOR_SYSTEM_VOLATILE)
18 #define DOOR_FILE "/system/volatile/name_service_door"
20 #define DOOR_FILE "/var/run/name_service_door"
23 #define HEADER(file, test_name) \
24 fprintf(file, "---------------------------------------------------------\n" \
26 "---------------------------------------------------------\n", \
32 /* It's possible that the system allocated a new memory for rbuf.
33 Unmap it if it is the case. */
34 static int handle_rbuf(door_arg_t
*params
, void *buf
)
36 if (params
->rbuf
!= buf
) {
37 if (munmap(params
->rbuf
, params
->rsize
) != 0) {
46 __attribute__((noinline
))
47 static int test_app_small_request(int did
)
49 /* Set call parameters. */
50 size_t buf_size
= sizeof(uint32_t);
51 char *buf
= malloc(buf_size
);
54 nss_pheader_t
*header
= (nss_pheader_t
*) buf
;
55 header
->nsc_callnumber
= x0
+ NSCD_GETENT
;
58 params
.data_ptr
= buf
;
59 params
.data_size
= buf_size
;
60 params
.desc_ptr
= NULL
;
63 params
.rsize
= buf_size
;
66 if (door_call(did
, ¶ms
) != 0) {
70 return handle_rbuf(¶ms
, buf
);
73 __attribute__((noinline
))
74 static int test_app_uninitialized_request(int did
)
76 /* Set call parameters. */
77 size_t buf_size
= sizeof(nss_pheader_t
) + sizeof(nss_dbd_t
);
78 char *buf
= malloc(buf_size
);
81 nss_pheader_t
*header
= (nss_pheader_t
*) buf
;
82 header
->nsc_callnumber
= x0
+ NSCD_GETENT
;
83 header
->dbd_off
= x0
+ sizeof(nss_pheader_t
);
84 header
->dbd_len
= x0
+ sizeof(nss_dbd_t
);
85 nss_dbd_t
*dbd
= (nss_dbd_t
*) (buf
+ sizeof(nss_pheader_t
));
87 dbd
->o_name
= x0
+ 100;
88 dbd
->o_config_name
= x0
+ 100;
89 dbd
->o_default_config
= x0
+ 100;
90 header
->key_off
= x0
+ sizeof(nss_pheader_t
) + sizeof(nss_dbd_t
);
91 header
->key_len
= x0
+ 1; // one byte past the end of 'buf'
92 header
->pbufsiz
= x0
+ 10000000;
95 params
.data_ptr
= buf
;
96 params
.data_size
= buf_size
;
97 params
.desc_ptr
= NULL
;
100 params
.rsize
= buf_size
;
103 if (door_call(did
, ¶ms
) != 0) {
107 /* Check definedness of response attributes ... */
109 if (header
->p_status
!= NSS_SUCCESS
) x
= -1; else x
= -2;
110 if (header
->p_herrno
!= 0) x
= -2; else x
= -3;
111 if (header
->key_off
!= 0) x
= -4; else x
= -5;
112 if (header
->key_len
!= 0) x
= -6; else x
= -7;
113 if (header
->data_off
!= 0) x
= -8; else x
= -9;
114 if (header
->data_len
!= 0) x
= -10; else x
= -11;
115 /* ... and now one which is not defined. */
116 if (header
->reserved1
!= 0) x
= -12; else x
= -13;
118 handle_rbuf(¶ms
, buf
);
122 __attribute__((noinline
))
123 static int test_app_proto_icmp(int did
)
128 /* Set call parameters. */
129 nss_pheader_t
*header
= (nss_pheader_t
*) buf
;
130 header
->nsc_callnumber
= NSCD_SEARCH
;
131 header
->p_ruid
= getuid();
132 header
->p_euid
= geteuid();
133 header
->p_version
= NSCD_HEADER_REV
;
134 header
->p_status
= 0;
136 header
->p_herrno
= 0;
138 header
->nss_dbop
= NSS_DBOP_PROTOCOLS_BYNAME
;
140 size_t name_len
= strlen(NSS_DBNAM_PROTOCOLS
);
141 size_t default_config_len
= strlen(NSS_FILES_ONLY
);
142 header
->dbd_off
= sizeof(nss_pheader_t
);
143 header
->dbd_len
= sizeof(nss_dbd_t
) + name_len
+ 1 + default_config_len
+ 1;
144 nss_dbd_t
*dbd
= (nss_dbd_t
*) (buf
+ sizeof(nss_pheader_t
));
145 dbd
->o_name
= sizeof(nss_dbd_t
);
146 dbd
->o_config_name
= 0;
147 dbd
->o_default_config
= dbd
->o_name
+ name_len
+ 1;
149 strcpy(buf
+ header
->dbd_off
+ dbd
->o_name
, NSS_DBNAM_PROTOCOLS
);
150 strcpy(buf
+ header
->dbd_off
+ dbd
->o_default_config
,
151 NSS_DEFCONF_PROTOCOLS
);
153 name_len
= strlen("icmp");
154 header
->key_off
= header
->dbd_off
+ ROUND_UP(header
->dbd_len
, sizeof(nssuint_t
));
155 header
->key_len
= name_len
+ 1;
156 strcpy(buf
+ header
->key_off
, "icmp");
158 header
->data_off
= header
->key_off
+ ROUND_UP(header
->key_len
, sizeof(nssuint_t
));
159 header
->data_len
= 0;
160 header
->pbufsiz
= header
->data_off
+ header
->data_len
;
162 params
.data_ptr
= buf
;
163 params
.data_size
= header
->pbufsiz
;
164 params
.desc_ptr
= NULL
;
167 params
.rsize
= sizeof(buf
);
169 /* Sanity checks on the nss_pheader_t header. */
170 assert(header
->p_version
== NSCD_HEADER_REV
);
171 assert(header
->dbd_off
== sizeof(nss_pheader_t
));
172 assert((params
.data_size
& 3) == 0);
173 assert((header
->dbd_off
& 3) == 0);
174 assert((header
->key_off
& 3) == 0);
175 assert((header
->data_off
& 3) == 0);
176 assert(header
->data_off
== params
.data_size
);
177 nssuint_t l1
= header
->key_off
- header
-> dbd_off
;
178 assert(l1
>= header
->dbd_len
);
179 nssuint_t l2
= header
->data_off
- header
->key_off
;
180 assert(l2
>= header
->key_len
);
181 assert(sizeof(nss_pheader_t
) + l1
+ l2
== header
->data_off
);
182 assert(header
->data_off
+ header
->data_len
== header
->pbufsiz
);
185 if (door_call(did
, ¶ms
) != 0) {
189 /* Print response attributes. */
190 HEADER(stdout
, "app_proto_icmp");
191 printf("status=%u\n", header
->p_status
);
192 printf("errno=%u\n", header
->p_errno
);
193 printf("herrno=%u\n", header
->p_herrno
);
194 printf("bufsiz=%" PRIu64
"\n", header
->pbufsiz
);
195 printf("dbd_off=%" PRIu64
" dbd_len=%" PRIu64
"\n",
196 header
->dbd_off
, header
->dbd_len
);
197 printf("key_off=%" PRIu64
" key_len=%" PRIu64
"\n",
198 header
->key_off
, header
->key_len
);
199 printf("data_off=%" PRIu64
" data_len=%" PRIu64
"\n",
200 header
->data_off
, header
->data_len
);
201 printf("ext_off=%" PRIu64
" ext_len=%" PRIu64
"\n",
202 header
->ext_off
, header
->ext_len
);
203 printf("key=%s\n", buf
+ header
->key_off
);
205 /* Parse response proto data. */
206 char *p
= buf
+ header
->data_off
;
207 char *limit
= p
+ header
->data_len
;
209 while ((p
< limit
) && isspace(*p
))
211 char *name_start
= p
;
212 while ((p
< limit
) && !isspace(*p
))
213 p
++; // skip over the name
214 name_len
= p
- name_start
;
216 while ((p
< limit
) && isspace(*p
))
218 char *number_start
= p
;
220 p
++; // skip over the proto number
221 } while ((p
< limit
) && !isspace(*p
));
222 size_t number_len
= p
- number_start
;
224 while ((p
< limit
) && isspace(*p
))
226 char *aliases_start
= p
;
227 while ((p
< limit
) && !isspace(*p
))
228 p
++; // skip over the aliases
229 size_t aliases_len
= p
- aliases_start
;
231 printf("data: name=%.*s number=%.*s aliases=%.*s\n",
232 (int) name_len
, name_start
, (int) number_len
, number_start
,
233 (int) aliases_len
, aliases_start
);
235 return handle_rbuf(¶ms
, buf
);
238 int main(int argc
, const char *argv
[])
240 /* Uninitialised, but we know px[0] is 0x0. */
241 long *px
= malloc(sizeof(long));
244 int did
= open(DOOR_FILE
, O_RDONLY
);
246 perror("open " DOOR_FILE
);
247 fprintf(stderr
, "Make sure the name service switch daemon (nscd) "
252 struct door_info info
;
253 if (door_info(did
, &info
) != 0) {
254 perror("door_info " DOOR_FILE
);
259 HEADER(stderr
, "app_small_request");
260 test_app_small_request(did
);
262 HEADER(stderr
, "app_uninitialized_request");
263 test_app_uninitialized_request(did
);
265 HEADER(stderr
, "app_proto_icmp");
266 test_app_proto_icmp(did
);