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 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* from kerbd_handle.c 1.3 92/01/29 SMI */ 28 29 /* 30 * kwarnd_handle.c, Interface to kwarnd 31 * 32 */ 33 34 #include <unistd.h> 35 #include <rpc/rpc.h> 36 #include <rpc/clnt.h> 37 #include <stdio.h> 38 #include <string.h> 39 #include <netconfig.h> 40 #include <sys/utsname.h> 41 #include "kwarnd.h" 42 43 #ifdef DEBUG 44 #define dprt(msg) 45 #else 46 #define dprt(msg) 47 #endif /* DEBUG */ 48 49 CLIENT *kwarn_clnt; 50 51 /* 52 * Keep the handle cached. This call may be made quite often. 53 */ 54 55 CLIENT * 56 getkwarnd_handle(void) 57 { 58 void *localhandle; 59 struct netconfig *nconf; 60 struct netconfig *tpconf; 61 struct timeval wait_time; 62 struct utsname u; 63 static char *hostname; 64 static bool_t first_time = TRUE; 65 66 /* 67 * Total timeout (in seconds) talking to kwarnd. 68 */ 69 #define TOTAL_TIMEOUT 5 70 71 if (kwarn_clnt) 72 return (kwarn_clnt); 73 if (!(localhandle = setnetconfig())) 74 return (NULL); 75 tpconf = NULL; 76 if (first_time == TRUE) { 77 if (uname(&u) == -1) { 78 (void) endnetconfig(localhandle); 79 return ((CLIENT *)NULL); 80 } 81 if ((hostname = strdup(u.nodename)) == (char *)NULL) { 82 (void) endnetconfig(localhandle); 83 return ((CLIENT *)NULL); 84 } 85 first_time = FALSE; 86 } 87 while (nconf = getnetconfig(localhandle)) { 88 if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { 89 if (nconf->nc_semantics == NC_TPI_COTS_ORD) { 90 kwarn_clnt = clnt_tp_create(hostname, 91 KWARNPROG, KWARNVERS, nconf); 92 if (kwarn_clnt) { 93 dprt("got COTS_ORD\n"); 94 break; 95 } 96 } else { 97 tpconf = nconf; 98 } 99 } 100 } 101 if ((kwarn_clnt == NULL) && (tpconf)) { 102 103 /* Now, try the connection-oriented loopback transport */ 104 105 kwarn_clnt = clnt_tp_create(hostname, KWARNPROG, KWARNVERS, 106 tpconf); 107 #ifdef DEBUG 108 if (kwarn_clnt) { 109 dprt("got COTS\n"); 110 } 111 #endif /* DEBUG */ 112 } 113 (void) endnetconfig(localhandle); 114 115 /* 116 * This bit of code uses an as yet unimplemented argument to 117 * clnt_control(). CLSET_SVC_PRIV specifies that the underlying 118 * loopback transport should be checked to ensure it is 119 * connected to a process running as root. If so, the clnt_control() 120 * call returns TRUE. If not, it returns FALSE. 121 */ 122 123 #ifdef CLSET_SVC_PRIV 124 125 if (clnt_control(kwarn_clnt, CLSET_SVC_PRIV, NULL) != TRUE) { 126 clnt_destroy(kwarn_clnt); 127 kwarn_clnt = NULL; 128 return (NULL); 129 { 130 #endif 131 if (kwarn_clnt == NULL) 132 return (NULL); 133 134 kwarn_clnt->cl_auth = authsys_create("", getuid(), 0, 0, NULL); 135 if (kwarn_clnt->cl_auth == NULL) { 136 clnt_destroy(kwarn_clnt); 137 kwarn_clnt = NULL; 138 return (NULL); 139 } 140 wait_time.tv_sec = TOTAL_TIMEOUT; 141 wait_time.tv_usec = 0; 142 (void) clnt_control(kwarn_clnt, CLSET_TIMEOUT, (char *)&wait_time); 143 144 return (kwarn_clnt); 145 } 146 147 void 148 resetkwarnd_handle(void) 149 { 150 auth_destroy(kwarn_clnt->cl_auth); 151 clnt_destroy(kwarn_clnt); 152 kwarn_clnt = NULL; 153 } 154