xref: /illumos-gate/usr/src/cmd/krb5/kwarn/kwarnd_handle.c (revision 4df55fde49134f9735f84011f23a767c75e393c7)
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