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]
22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * Test nfsmapid. This program is not shipped on the binary release.
39 #include <netconfig.h>
41 #include <sys/types.h>
42 #include <sys/utsname.h>
43 #include <sys/param.h>
44 #include <sys/errno.h>
46 #include <sys/systm.h>
48 #include <sys/debug.h>
49 #include <rpcsvc/nfs4_prot.h>
50 #include <nfs/nfsid_map.h>
52 static char nobody_str
[] = "nobody";
53 static int nfs_idmap_str_uid(utf8string
*, uid_t
*);
54 static int nfs_idmap_uid_str(uid_t
, utf8string
*);
55 static int nfs_idmap_str_gid(utf8string
*, gid_t
*);
56 static int nfs_idmap_gid_str(gid_t
, utf8string
*);
61 fprintf(stderr
, gettext(
62 "\nUsage:\tstr2uid string\n"
70 static int read_line(char *buf
, int size
)
74 /* read the next line. If cntl-d, return with zero char count */
75 printf(gettext("\n> "));
77 if (fgets(buf
, size
, stdin
) == NULL
)
86 parse_input_line(char *input_line
, int *argc
, char ***argv
)
88 const char nil
= '\0';
95 chr_cnt
= strlen(input_line
);
97 /* Count the arguments in the input_line string */
101 for (chptr
= &input_line
[0]; *chptr
!= nil
; chptr
++) {
102 ch_is_space
= isspace(*chptr
);
103 if (ch_is_space
&& !ch_was_space
) {
106 ch_was_space
= ch_is_space
;
111 } /* minus trailing spaces */
113 /* Now that we know how many args calloc the argv array */
115 *argv
= calloc((*argc
)+1, sizeof (char *));
116 chptr
= (char *)(&input_line
[0]);
118 for (ch_was_space
= 1; *chptr
!= nil
; chptr
++) {
119 ch_is_space
= isspace(*chptr
);
121 *chptr
= nil
; /* replace each space with nil */
122 } else if (ch_was_space
) { /* begining of word? */
123 (*argv
)[arg_cnt
++] = chptr
; /* new argument ? */
126 ch_was_space
= ch_is_space
;
137 return ("NFSMAPID_OK");
138 case NFSMAPID_NUMSTR
:
139 return ("NFSMAPID_NUMSTR");
140 case NFSMAPID_UNMAPPABLE
:
141 return ("NFSMAPID_UNMAPPABLE");
142 case NFSMAPID_INVALID
:
143 return ("NFSMAPID_INVALID");
144 case NFSMAPID_INTERNAL
:
145 return ("NFSMAPID_INTERNAL");
146 case NFSMAPID_BADDOMAIN
:
147 return ("NFSMAPID_BADDOMAIN");
149 return ("NFSMAPID_BADID");
150 case NFSMAPID_NOTFOUND
:
151 return ("NFSMAPID_NOTFOUND");
159 printf(" unknown error %d ", stat
);
165 do_test(char *input_buf
)
168 char **argv
, **argv_array
;
170 int i
, bufsize
= 512;
179 if (parse_input_line(input_buf
, &argc
, &argv
) == 0) {
180 printf(gettext("\n"));
185 * remember argv_array address, which is memory calloc'd by
186 * parse_input_line, so it can be free'd at the end of the loop.
198 if (strcmp(cmd
, "str2uid") == 0) {
204 str
.utf8string_val
= argv
[1];
205 str
.utf8string_len
= strlen(argv
[1]);
206 stat
= nfs_idmap_str_uid(&str
, &uid
);
207 printf(gettext("%u stat=%s \n"), uid
, mapstat(stat
));
209 } else if (strcmp(cmd
, "str2gid") == 0) {
215 str
.utf8string_val
= argv
[1];
216 str
.utf8string_len
= strlen(argv
[1]);
217 stat
= nfs_idmap_str_gid(&str
, &gid
);
218 printf(gettext("%u stat=%s \n"), gid
, mapstat(stat
));
220 } else if (strcmp(cmd
, "uid2str") == 0) {
227 bzero(str_buf
, bufsize
);
228 str
.utf8string_val
= str_buf
;
229 stat
= nfs_idmap_uid_str(uid
, &str
);
230 printf(gettext("%s stat=%s\n"), str
.utf8string_val
,
233 } else if (strcmp(cmd
, "gid2str") == 0) {
240 bzero(str_buf
, bufsize
);
241 str
.utf8string_val
= str_buf
;
242 stat
= nfs_idmap_gid_str(gid
, &str
);
243 printf(gettext("%s stat=%s\n"), str
.utf8string_val
,
246 } else if (strcmp(cmd
, "echo") == 0) {
247 for (i
= 1; i
< argc
; i
++)
248 printf("%s ", argv
[i
]);
250 } else if (strcmp(cmd
, "exit") == 0 ||
251 strcmp(cmd
, "quit") == 0) {
252 printf(gettext("\n"));
259 /* free argv array */
266 main(int argc
, char **argv
)
271 (void) setlocale(LC_ALL
, "");
273 #define TEXT_DOMAIN ""
275 (void) textdomain(TEXT_DOMAIN
);
280 * Loop, repeatedly calling parse_input_line() to get the
281 * next line and parse it into argc and argv. Act on the
282 * arguements found on the line.
286 len
= read_line(buf
, 512);
294 #define NFSMAPID_DOOR "/var/run/nfsmapid_door"
297 * Gen the door handle for connecting to the nfsmapid process.
298 * Keep the door cached. This call may be made quite often.
303 static int doorfd
= -1;
308 if ((doorfd
= open(NFSMAPID_DOOR
, O_RDWR
)) == -1) {
309 perror(NFSMAPID_DOOR
);
316 * Convert a user utf-8 string identifier into its local uid.
319 nfs_idmap_str_uid(utf8string
*u8s
, uid_t
*uid
)
321 struct mapid_arg
*mapargp
;
322 struct mapid_res mapres
;
323 struct mapid_res
*mapresp
= &mapres
;
324 struct mapid_res
*resp
= mapresp
;
325 door_arg_t door_args
;
328 static int msg_done
= 0;
330 if (!u8s
|| !u8s
->utf8string_val
|| !u8s
->utf8string_len
||
331 (u8s
->utf8string_val
[0] == '\0')) {
336 if (bcmp(u8s
->utf8string_val
, "nobody", 6) == 0) {
338 * If "nobody", just short circuit and bail
345 if ((mapargp
= malloc(MAPID_ARG_LEN(u8s
->utf8string_len
))) == NULL
) {
346 (void) fprintf(stderr
, "Unable to malloc %d bytes\n",
347 MAPID_ARG_LEN(u8s
->utf8string_len
));
351 mapargp
->cmd
= NFSMAPID_STR_UID
;
352 mapargp
->u_arg
.len
= u8s
->utf8string_len
;
353 (void) bcopy(u8s
->utf8string_val
, mapargp
->str
, mapargp
->u_arg
.len
);
354 mapargp
->str
[mapargp
->u_arg
.len
] = '\0';
356 door_args
.data_ptr
= (char *)mapargp
;
357 door_args
.data_size
= MAPID_ARG_LEN(mapargp
->u_arg
.len
);
358 door_args
.desc_ptr
= NULL
;
359 door_args
.desc_num
= 0;
360 door_args
.rbuf
= (char *)mapresp
;
361 door_args
.rsize
= sizeof (struct mapid_res
);
364 * call to the nfsmapid daemon
366 if ((doorfd
= nfs_idmap_doorget()) == -1) {
368 fprintf(stderr
, "nfs_idmap_str_uid: Can't communicate"
369 " with mapping daemon nfsmapid\n");
377 if (door_call(doorfd
, &door_args
) == -1) {
378 perror("door_call failed");
386 resp
= (struct mapid_res
*)door_args
.rbuf
;
387 switch (resp
->status
) {
389 *uid
= resp
->u_res
.uid
;
392 case NFSMAPID_NUMSTR
:
393 *uid
= resp
->u_res
.uid
;
394 error
= resp
->status
;
398 case NFSMAPID_UNMAPPABLE
:
399 case NFSMAPID_INVALID
:
400 case NFSMAPID_INTERNAL
:
401 case NFSMAPID_BADDOMAIN
:
403 case NFSMAPID_NOTFOUND
:
404 error
= resp
->status
;
413 munmap(door_args
.rbuf
, door_args
.rsize
);
418 * Convert a uid into its utf-8 string representation.
421 nfs_idmap_uid_str(uid_t uid
, /* uid to map */
422 utf8string
*u8s
) /* resulting utf-8 string for uid */
424 struct mapid_arg maparg
;
425 struct mapid_res mapres
;
426 struct mapid_res
*mapresp
= &mapres
;
427 struct mapid_res
*resp
= mapresp
;
428 door_arg_t door_args
;
431 static int msg_done
= 0;
433 if (uid
== UID_NOBODY
) {
434 u8s
->utf8string_len
= strlen("nobody");
435 u8s
->utf8string_val
= nobody_str
;
442 maparg
.cmd
= NFSMAPID_UID_STR
;
443 maparg
.u_arg
.uid
= uid
;
445 door_args
.data_ptr
= (char *)&maparg
;
446 door_args
.data_size
= sizeof (struct mapid_arg
);
447 door_args
.desc_ptr
= NULL
;
448 door_args
.desc_num
= 0;
449 door_args
.rbuf
= (char *)mapresp
;
450 door_args
.rsize
= sizeof (struct mapid_res
);
452 if ((doorfd
= nfs_idmap_doorget()) == -1) {
454 fprintf(stderr
, "nfs_idmap_uid_str: Can't "
455 "communicate with mapping daemon nfsmapid\n");
462 if (door_call(doorfd
, &door_args
) == -1) {
463 perror("door_call failed");
468 resp
= (struct mapid_res
*)door_args
.rbuf
;
469 if (resp
->status
!= NFSMAPID_OK
) {
470 error
= resp
->status
;
474 if (resp
->u_res
.len
!= strlen(resp
->str
)) {
475 (void) fprintf(stderr
, "Incorrect length %d expected %d\n",
476 resp
->u_res
.len
, strlen(resp
->str
));
477 error
= NFSMAPID_INVALID
;
480 u8s
->utf8string_len
= resp
->u_res
.len
;
481 bcopy(resp
->str
, u8s
->utf8string_val
, u8s
->utf8string_len
);
485 munmap(door_args
.rbuf
, door_args
.rsize
);
490 * Convert a group utf-8 string identifier into its local gid.
493 nfs_idmap_str_gid(utf8string
*u8s
, gid_t
*gid
)
495 struct mapid_arg
*mapargp
;
496 struct mapid_res mapres
;
497 struct mapid_res
*mapresp
= &mapres
;
498 struct mapid_res
*resp
= mapresp
;
499 door_arg_t door_args
;
502 static int msg_done
= 0;
504 if (!u8s
|| !u8s
->utf8string_val
|| !u8s
->utf8string_len
||
505 (u8s
->utf8string_val
[0] == '\0')) {
510 if (bcmp(u8s
->utf8string_val
, "nobody", 6) == 0) {
512 * If "nobody", just short circuit and bail
519 if ((mapargp
= malloc(MAPID_ARG_LEN(u8s
->utf8string_len
))) == NULL
) {
520 (void) fprintf(stderr
, "Unable to malloc %d bytes\n",
521 MAPID_ARG_LEN(u8s
->utf8string_len
));
525 mapargp
->cmd
= NFSMAPID_STR_GID
;
526 mapargp
->u_arg
.len
= u8s
->utf8string_len
;
527 (void) bcopy(u8s
->utf8string_val
, mapargp
->str
, mapargp
->u_arg
.len
);
528 mapargp
->str
[mapargp
->u_arg
.len
] = '\0';
530 door_args
.data_ptr
= (char *)mapargp
;
531 door_args
.data_size
= MAPID_ARG_LEN(mapargp
->u_arg
.len
);
532 door_args
.desc_ptr
= NULL
;
533 door_args
.desc_num
= 0;
534 door_args
.rbuf
= (char *)mapresp
;
535 door_args
.rsize
= sizeof (struct mapid_res
);
538 * call to the nfsmapid daemon
540 if ((doorfd
= nfs_idmap_doorget()) == -1) {
542 fprintf(stderr
, "nfs_idmap_str_uid: Can't communicate"
543 " with mapping daemon nfsmapid\n");
551 if (door_call(doorfd
, &door_args
) == -1) {
552 perror("door_call failed");
560 resp
= (struct mapid_res
*)door_args
.rbuf
;
561 switch (resp
->status
) {
563 *gid
= resp
->u_res
.gid
;
566 case NFSMAPID_NUMSTR
:
567 *gid
= resp
->u_res
.gid
;
568 error
= resp
->status
;
572 case NFSMAPID_UNMAPPABLE
:
573 case NFSMAPID_INVALID
:
574 case NFSMAPID_INTERNAL
:
575 case NFSMAPID_BADDOMAIN
:
577 case NFSMAPID_NOTFOUND
:
578 error
= resp
->status
;
587 munmap(door_args
.rbuf
, door_args
.rsize
);
592 * Convert a gid into its utf-8 string representation.
595 nfs_idmap_gid_str(gid_t gid
, /* gid to map */
596 utf8string
*g8s
) /* resulting utf-8 string for gid */
598 struct mapid_arg maparg
;
599 struct mapid_res mapres
;
600 struct mapid_res
*mapresp
= &mapres
;
601 struct mapid_res
*resp
= mapresp
;
602 door_arg_t door_args
;
605 static int msg_done
= 0;
607 if (gid
== GID_NOBODY
) {
608 g8s
->utf8string_len
= strlen("nobody");
609 g8s
->utf8string_val
= nobody_str
;
617 maparg
.cmd
= NFSMAPID_GID_STR
;
618 maparg
.u_arg
.gid
= gid
;
620 door_args
.data_ptr
= (char *)&maparg
;
621 door_args
.data_size
= sizeof (struct mapid_arg
);
622 door_args
.desc_ptr
= NULL
;
623 door_args
.desc_num
= 0;
624 door_args
.rbuf
= (char *)mapresp
;
625 door_args
.rsize
= sizeof (struct mapid_res
);
627 if ((doorfd
= nfs_idmap_doorget()) == -1) {
629 fprintf(stderr
, "nfs_idmap_uid_str: Can't "
630 "communicate with mapping daemon nfsmapid\n");
637 if (door_call(doorfd
, &door_args
) == -1) {
638 perror("door_call failed");
643 resp
= (struct mapid_res
*)door_args
.rbuf
;
644 if (resp
->status
!= NFSMAPID_OK
) {
645 error
= resp
->status
;
649 if (resp
->u_res
.len
!= strlen(resp
->str
)) {
650 (void) fprintf(stderr
, "Incorrect length %d expected %d\n",
651 resp
->u_res
.len
, strlen(resp
->str
));
652 error
= NFSMAPID_INVALID
;
655 g8s
->utf8string_len
= resp
->u_res
.len
;
656 bcopy(resp
->str
, g8s
->utf8string_val
, g8s
->utf8string_len
);
660 munmap(door_args
.rbuf
, door_args
.rsize
);