xref: /titanic_41/usr/src/cmd/krb5/kwarn/kwarnd_handle.c (revision 40db2e2b777b79f3dd0d6d9629593a07f86b9c0a)
1 /*
2  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 #pragma ident	"%Z%%M%	%I%	%E% SMI"
7 /*	from kerbd_handle.c	1.3	92/01/29 SMI */
8 
9 /*
10  * kwarnd_handle.c, Interface to kwarnd
11  *
12  */
13 
14 #include <unistd.h>
15 #include <rpc/rpc.h>
16 #include <rpc/clnt.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <netconfig.h>
20 #include <sys/utsname.h>
21 #include "kwarnd.h"
22 
23 #ifdef DEBUG
24 #define	dprt(msg)
25 #else
26 #define	dprt(msg)
27 #endif /* DEBUG */
28 
29 
30 /*
31  * Keep the handle cached.  This call may be made quite often.
32  */
33 
34 CLIENT *
35 getkwarnd_handle(void)
36 {
37 	void *localhandle;
38 	struct netconfig *nconf;
39 	struct netconfig *tpconf;
40 	static CLIENT *clnt;
41 	struct timeval wait_time;
42 	struct utsname u;
43 	static char *hostname;
44 	static bool_t first_time = TRUE;
45 
46 #define	TOTAL_TIMEOUT	1000	/* total timeout talking to kwarnd */
47 #define	TOTAL_TRIES	1	/* Number of tries */
48 
49 	if (clnt)
50 		return (clnt);
51 	if (!(localhandle = setnetconfig()))
52 		return (NULL);
53 	tpconf = NULL;
54 	if (first_time == TRUE) {
55 		if (uname(&u) == -1) {
56 			(void) endnetconfig(localhandle);
57 			return ((CLIENT *)NULL);
58 		}
59 		if ((hostname = strdup(u.nodename)) == (char *)NULL) {
60 			(void) endnetconfig(localhandle);
61 			return ((CLIENT *)NULL);
62 		}
63 		first_time = FALSE;
64 	}
65 	while (nconf = getnetconfig(localhandle)) {
66 		if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
67 			if (nconf->nc_semantics == NC_TPI_COTS_ORD) {
68 				clnt = clnt_tp_create(hostname,
69 					KWARNPROG, KWARNVERS, nconf);
70 				if (clnt) {
71 					dprt("got COTS_ORD\n");
72 					break;
73 				}
74 			} else {
75 				tpconf = nconf;
76 			}
77 		}
78 	}
79 	if ((clnt == NULL) && (tpconf)) {
80 
81 		/* Now, try the connection-oriented loopback transport */
82 
83 		clnt = clnt_tp_create(hostname, KWARNPROG, KWARNVERS, tpconf);
84 #ifdef DEBUG
85 		if (clnt) {
86 			dprt("got COTS\n");
87 		}
88 #endif	/* DEBUG */
89 	}
90 	(void) endnetconfig(localhandle);
91 
92 	/*
93 	 * This bit of code uses an as yet unimplemented argument to
94 	 * clnt_control(). CLSET_SVC_PRIV specifies that the underlying
95 	 * loopback transport should be checked to ensure it is
96 	 * connected to a process running as root. If so, the clnt_control()
97 	 * call returns TRUE. If not, it returns FALSE.
98 	 */
99 
100 #ifdef CLSET_SVC_PRIV
101 
102 	if (clnt_control(clnt, CLSET_SVC_PRIV, NULL) != TRUE) {
103 		clnt_destroy(clnt);
104 		clnt = NULL;
105 		return (NULL);
106 	{
107 #endif
108 	if (clnt == NULL)
109 		return (NULL);
110 
111 	clnt->cl_auth = authsys_create("", getuid(), 0, 0, NULL);
112 	if (clnt->cl_auth == NULL) {
113 		clnt_destroy(clnt);
114 		clnt = NULL;
115 		return (NULL);
116 	}
117 	wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES;
118 	wait_time.tv_usec = 0;
119 	(void) clnt_control(clnt, CLSET_RETRY_TIMEOUT, (char *)&wait_time);
120 
121 	return (clnt);
122 }
123