xref: /freebsd/usr.bin/ypwhich/ypwhich.c (revision 0c43d89a0d8e976ca494d4837f4c1f3734d2c300)
1 /*
2  * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. The name of the author may not be used to endorse or promote
14  *    products derived from this software without specific prior written
15  *    permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
18  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
21  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #ifndef LINT
31 static char rcsid[] = "ypwhich.c,v 1.2 1993/05/16 02:49:10 deraadt Exp";
32 #endif
33 
34 #include <sys/param.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <stdio.h>
38 #include <ctype.h>
39 #include <netdb.h>
40 #include <rpc/rpc.h>
41 #include <rpc/xdr.h>
42 #include <rpcsvc/yp_prot.h>
43 #include <rpcsvc/ypclnt.h>
44 
45 extern bool_t xdr_domainname();
46 
47 struct ypalias {
48 	char *alias, *name;
49 } ypaliases[] = {
50 	{ "passwd", "passwd.byname" },
51 	{ "group", "group.byname" },
52 	{ "networks", "networks.byaddr" },
53 	{ "hosts", "hosts.byaddr" },
54 	{ "protocols", "protocols.bynumber" },
55 	{ "services", "services.byname" },
56 	{ "aliases", "mail.aliases" },
57 	{ "ethers", "ethers.byname" },
58 };
59 
60 usage()
61 {
62 	fprintf(stderr, "Usage:\n");
63 	fprintf(stderr, "\typwhich [-d domain] [[-t] -m [mname] | host]\n");
64 	fprintf(stderr, "\typwhich -x\n");
65 	exit(1);
66 }
67 
68 
69 /*
70  * Like yp_bind except can query a specific host
71  */
72 bind_host(dom, sin)
73 char *dom;
74 struct sockaddr_in *sin;
75 {
76 	struct hostent *hent = NULL;
77 	struct ypbind_resp ypbr;
78 	struct dom_binding *ysd;
79 	struct timeval tv;
80 	CLIENT *client;
81 	int sock, r;
82 	u_long ss_addr;
83 
84 	sock = RPC_ANYSOCK;
85 	tv.tv_sec = 15;
86 	tv.tv_usec = 0;
87 	client = clntudp_create(sin, YPBINDPROG, YPBINDVERS, tv, &sock);
88 	if(client==NULL) {
89 		fprintf(stderr, "can't clntudp_create: %s\n",
90 			yperr_string(YPERR_YPBIND));
91 		return YPERR_YPBIND;
92 	}
93 
94 	tv.tv_sec = 5;
95 	tv.tv_usec = 0;
96 	r = clnt_call(client, YPBINDPROC_DOMAIN,
97 		xdr_domainname, dom, xdr_ypbind_resp, &ypbr, tv);
98 	if( r != RPC_SUCCESS) {
99 		fprintf(stderr, "can't clnt_call: %s\n",
100 			yperr_string(YPERR_YPBIND));
101 		clnt_destroy(client);
102 		return YPERR_YPBIND;
103 	} else {
104 		if (ypbr.ypbind_status != YPBIND_SUCC_VAL) {
105 			fprintf(stderr, "can't yp_bind: Reason: %s\n",
106 				yperr_string(ypbr.ypbind_status));
107 			clnt_destroy(client);
108 			return r;
109 		}
110 	}
111 	clnt_destroy(client);
112 
113 	ss_addr = ypbr.ypbind_respbody.ypbind_bindinfo.ypbind_binding_addr.s_addr;
114 	/*printf("%08x\n", ss_addr);*/
115 	hent = gethostbyaddr((char *)&ss_addr, sizeof(ss_addr), AF_INET);
116 	if (hent)
117 		printf("%s\n", hent->h_name);
118 	else
119 		printf("%s\n", inet_ntoa(ss_addr));
120 	return 0;
121 }
122 
123 int
124 main(argc, argv)
125 char **argv;
126 {
127 	char *domainname, *master, *map;
128 	struct ypmaplist *ypml, *y;
129 	extern char *optarg;
130 	extern int optind;
131 	struct hostent *hent;
132 	struct sockaddr_in sin;
133 	int notrans, mode, getmap;
134 	int c, r, i;
135 
136 	yp_get_default_domain(&domainname);
137 
138 	map = NULL;
139 	getmap = notrans = mode = 0;
140 	while( (c=getopt(argc, argv, "xd:mt")) != -1)
141 		switch(c) {
142 		case 'x':
143 			for(i=0; i<sizeof ypaliases/sizeof ypaliases[0]; i++)
144 				printf("Use \"%s\" for \"%s\"\n",
145 					ypaliases[i].alias,
146 					ypaliases[i].name);
147 			exit(0);
148 		case 'd':
149 			domainname = optarg;
150 			break;
151 		case 't':
152 			notrans++;
153 			break;
154 		case 'm':
155 			mode++;
156 			break;
157 		default:
158 			usage();
159 		}
160 
161 	if(mode==0) {
162 		switch(argc-optind) {
163 		case 0:
164 			bzero(&sin, sizeof sin);
165 			sin.sin_family = AF_INET;
166 			sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
167 
168 			if(bind_host(domainname, &sin))
169 				exit(1);
170 			break;
171 		case 1:
172 			bzero(&sin, sizeof sin);
173 			sin.sin_family = AF_INET;
174 			if( (sin.sin_addr.s_addr=inet_addr(argv[optind]))==-1) {
175 				hent = gethostbyname(argv[optind]);
176 				if(!hent) {
177 					fprintf(stderr, "ypwhich: host %s unknown\n",
178 						argv[optind]);
179 					exit(1);
180 				}
181 				bcopy((char *)hent->h_addr_list[0],
182 					(char *)&sin.sin_addr, sizeof sin.sin_addr);
183 			}
184 			if(bind_host(domainname, &sin))
185 				exit(1);
186 			break;
187 		default:
188 			usage();
189 		}
190 		exit(0);
191 	}
192 
193 	if( argc-optind > 1)
194 		usage();
195 
196 	if(argv[optind]) {
197 		map = argv[optind];
198 		for(i=0; (!notrans) && i<sizeof ypaliases/sizeof ypaliases[0]; i++)
199 			if( strcmp(map, ypaliases[i].alias) == 0)
200 				map = ypaliases[i].name;
201 		r = yp_master(domainname, map, &master);
202 		switch(r) {
203 		case 0:
204 			printf("%s\n", master);
205 			free(master);
206 			break;
207 		case YPERR_YPBIND:
208 			fprintf(stderr, "ypwhich: not running ypbind\n");
209 			exit(1);
210 		default:
211 			fprintf(stderr, "Can't find master for map %s. Reason: %s\n",
212 				map, yperr_string(r));
213 			exit(1);
214 		}
215 		exit(0);
216 	}
217 
218 	ypml = NULL;
219 	r = yp_maplist(domainname, &ypml);
220 	switch(r) {
221 	case 0:
222 		for(y=ypml; y; ) {
223 			ypml = y;
224 			r = yp_master(domainname, ypml->ypml_name, &master);
225 			switch(r) {
226 			case 0:
227 				printf("%s %s\n", ypml->ypml_name, master);
228 				free(master);
229 				break;
230 			default:
231 				fprintf(stderr,
232 					"YP: can't find the master of %s: Reason: %s\n",
233 					ypml->ypml_name, yperr_string(r));
234 				break;
235 			}
236 			y = ypml->ypml_next;
237 			free(ypml);
238 		}
239 		break;
240 	case YPERR_YPBIND:
241 		fprintf(stderr, "ypwhich: not running ypbind\n");
242 		exit(1);
243 	default:
244 		fprintf(stderr, "Can't get map list for domain %s. Reason: %s\n",
245 			domainname, yperr_string(r));
246 		exit(1);
247 	}
248 	exit(0);
249 }
250