1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * User-space door client routines for both SMB daemon and CLIs. 28 */ 29 30 #include <syslog.h> 31 #include <door.h> 32 #include <string.h> 33 #include <strings.h> 34 #include <stdlib.h> 35 #include <errno.h> 36 #include <sys/mman.h> 37 #include <smbsrv/libsmb.h> 38 #include <smbsrv/wintypes.h> 39 #include <smbsrv/smb_door_svc.h> 40 #include <smbsrv/smb_common_door.h> 41 42 #define SMB_DOOR_CALL_RETRIES 3 43 44 void 45 smb_dr_clnt_setup(door_arg_t *arg, char *buf, size_t buflen) 46 { 47 arg->data_ptr = buf; 48 arg->data_size = buflen; 49 arg->desc_ptr = NULL; 50 arg->desc_num = 0; 51 arg->rbuf = buf; 52 arg->rsize = buflen; 53 } 54 55 /* 56 * Free resources allocated for a door call. If the result buffer provided 57 * by the client is too small, the doorfs will have allocated a new buffer, 58 * which must be unmapped here. 59 * 60 * This function must be called to free both the argument and result door 61 * buffers regardless of the status of the door call. 62 */ 63 void 64 smb_dr_clnt_cleanup(door_arg_t *arg) 65 { 66 if (arg->rbuf && (arg->rbuf != arg->data_ptr)) 67 (void) munmap(arg->rbuf, arg->rsize); 68 69 free(arg->data_ptr); 70 } 71 72 /* 73 * Make a door call to the server function associated with the door 74 * descriptor fd. 75 * 76 * After a successful door call the local door_arg->data_ptr is assigned 77 * to the caller's arg->rbuf so that arg has references to both input and 78 * response buffers, which is required by smb_dr_clnt_free. 79 * 80 * On success, 0 will be returned and the call results can be referenced 81 * via arg->rbuf and arg->rsize. Otherwise -1 will be returned. 82 */ 83 int 84 smb_dr_clnt_call(int fd, door_arg_t *arg) 85 { 86 door_arg_t door_arg; 87 int rc; 88 int i; 89 90 if (fd < 0 || arg == NULL) 91 return (-1); 92 93 bcopy(arg, &door_arg, sizeof (door_arg_t)); 94 95 for (i = 0; i < SMB_DOOR_CALL_RETRIES; ++i) { 96 errno = 0; 97 98 if ((rc = door_call(fd, &door_arg)) == 0) 99 break; 100 101 if (errno != EAGAIN && errno != EINTR) 102 return (-1); 103 } 104 105 if (rc != 0) 106 return (-1); 107 108 if ((rc = smb_dr_get_res_stat(door_arg.data_ptr, door_arg.rsize)) != 0) 109 rc = -1; 110 111 arg->rbuf = door_arg.data_ptr; 112 arg->rsize = door_arg.rsize; 113 return (rc); 114 } 115