GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/amd/amd/info_nis.c Lines: 0 86 0.0 %
Date: 2017-11-13 Branches: 0 46 0.0 %

Line Branch Exec Source
1
/*
2
 * Copyright (c) 1989 Jan-Simon Pendry
3
 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine
4
 * Copyright (c) 1989, 1993
5
 *	The Regents of the University of California.  All rights reserved.
6
 *
7
 * This code is derived from software contributed to Berkeley by
8
 * Jan-Simon Pendry at Imperial College, London.
9
 *
10
 * Redistribution and use in source and binary forms, with or without
11
 * modification, are permitted provided that the following conditions
12
 * are met:
13
 * 1. Redistributions of source code must retain the above copyright
14
 *    notice, this list of conditions and the following disclaimer.
15
 * 2. Redistributions in binary form must reproduce the above copyright
16
 *    notice, this list of conditions and the following disclaimer in the
17
 *    documentation and/or other materials provided with the distribution.
18
 * 3. Neither the name of the University nor the names of its contributors
19
 *    may be used to endorse or promote products derived from this software
20
 *    without specific prior written permission.
21
 *
22
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32
 * SUCH DAMAGE.
33
 *
34
 *	from: @(#)info_nis.c	8.1 (Berkeley) 6/6/93
35
 *	$Id: info_nis.c,v 1.13 2014/10/26 03:28:41 guenther Exp $
36
 */
37
38
/*
39
 * Get info from NIS map
40
 */
41
42
#include "am.h"
43
44
#include <unistd.h>
45
46
#include <rpcsvc/yp_prot.h>
47
#include <rpcsvc/ypclnt.h>
48
#include <time.h>
49
50
/*
51
 * Sun's NIS+ server in NIS compat mode does not have yp_order()
52
 */
53
static int has_yp_order = FALSE;
54
55
/*
56
 * Figure out the nis domain name
57
 */
58
static int
59
determine_nis_domain(void)
60
{
61
	static int nis_not_running = 0;
62
63
	char default_domain[YPMAXDOMAIN];
64
65
	if (nis_not_running)
66
		return ENOENT;
67
68
	if (getdomainname(default_domain, sizeof(default_domain)) < 0) {
69
		nis_not_running = 1;
70
		plog(XLOG_ERROR, "getdomainname: %m");
71
		return EIO;
72
	}
73
74
	if (!*default_domain) {
75
		nis_not_running = 1;
76
		plog(XLOG_INFO, "NIS domain name is not set.  NIS ignored.");
77
		return ENOENT;
78
	}
79
80
	domain = strdup(default_domain);
81
82
	return 0;
83
}
84
85
86
struct nis_callback_data {
87
	mnt_map *ncd_m;
88
	char *ncd_map;
89
	void (*ncd_fn)(mnt_map *, char *, char *);
90
};
91
92
/*
93
 * Callback from yp_all
94
 */
95
static int
96
callback(unsigned long status, char *key, int kl, char *val, int vl, void *arg)
97
{
98
	struct nis_callback_data *data = arg;
99
100
	if (status == YP_TRUE) {
101
		/*
102
		 * Add to list of maps
103
		 */
104
		char *kp = strnsave(key, kl);
105
		char *vp = strnsave(val, vl);
106
107
		(*data->ncd_fn)(data->ncd_m, kp, vp);
108
109
		/*
110
		 * We want more ...
111
		 */
112
		return FALSE;
113
	} else {
114
		/*
115
		 * NOMORE means end of map - otherwise log error
116
		 */
117
		if (status != YP_NOMORE) {
118
			/*
119
			 * Check what went wrong
120
			 */
121
			int e = ypprot_err(status);
122
123
#ifdef DEBUG
124
			plog(XLOG_ERROR, "yp enumeration of %s: %s, status=%d, e=%d",
125
			    data->ncd_map, yperr_string(e), status, e);
126
#else
127
			plog(XLOG_ERROR, "yp enumeration of %s: %s",
128
			    data->ncd_map, yperr_string(e));
129
#endif
130
		}
131
		return TRUE;
132
	}
133
}
134
135
int
136
nis_reload(mnt_map *m, char *map, void (*fn)(mnt_map *, char *, char *))
137
{
138
	struct ypall_callback cbinfo;
139
	int error;
140
	struct nis_callback_data data;
141
142
	if (!domain) {
143
		error = determine_nis_domain();
144
		if (error)
145
			return error;
146
	}
147
148
	data.ncd_m = m;
149
	data.ncd_map = map;
150
	data.ncd_fn = fn;
151
	cbinfo.data = (void *)&data;
152
	cbinfo.foreach = &callback;
153
154
	error = yp_all(domain, map, &cbinfo);
155
156
	if (error)
157
		plog(XLOG_ERROR, "error grabbing nis map of %s: %s",
158
		    map, yperr_string(ypprot_err(error)));
159
160
	return error;
161
}
162
163
/*
164
 * Try to locate a key using NIS.
165
 */
166
int
167
nis_search(mnt_map *m, char *map, char *key, char **val, time_t *tp)
168
{
169
	int outlen;
170
	int order;
171
	int res;
172
173
	/*
174
	 * Make sure domain initialised
175
	 */
176
	if (has_yp_order) {
177
		/* check if map has changed */
178
		if (yp_order(domain, map, &order))
179
			return EIO;
180
		if ((time_t) order > *tp) {
181
			*tp = (time_t) order;
182
			return -1;
183
		}
184
	} else {
185
		/*
186
		 * NIS+ server without yp_order
187
		 * Check if timeout has expired to invalidate the cache
188
		 */
189
		order = time(NULL);
190
		if ((time_t)order - *tp > am_timeo) {
191
			*tp = (time_t)order;
192
			return(-1);
193
		}
194
	}
195
196
197
	if (has_yp_order) {
198
		/*
199
		 * Check if map has changed
200
		 */
201
		if (yp_order(domain, map, &order))
202
			return EIO;
203
		if ((time_t) order > *tp) {
204
			*tp = (time_t) order;
205
			return -1;
206
		}
207
	} else {
208
		/*
209
		 * NIS+ server without yp_order
210
		 * Check if timeout has expired to invalidate the cache
211
		 */
212
		order = time(NULL);
213
		if ((time_t)order - *tp > am_timeo) {
214
			*tp = (time_t)order;
215
			return(-1);
216
		}
217
	}
218
219
	/*
220
	 * Lookup key
221
	 */
222
	res = yp_match(domain, map, key, strlen(key), val, &outlen);
223
224
	/*
225
	 * Do something interesting with the return code
226
	 */
227
	switch (res) {
228
	case 0:
229
		return 0;
230
231
	case YPERR_KEY:
232
		return ENOENT;
233
234
	default:
235
		plog(XLOG_ERROR, "%s: %s", map, yperr_string(res));
236
		return EIO;
237
	}
238
}
239
240
int
241
nis_init(char *map, time_t *tp)
242
{
243
	int order;
244
	int yp_order_result;
245
	char *master;
246
247
	if (!domain) {
248
		int error = determine_nis_domain();
249
250
		if (error)
251
			return error;
252
	}
253
254
	/*
255
	 * To see if the map exists, try to find
256
	 * a master for it.
257
	 */
258
	yp_order_result = yp_order(domain, map, &order);
259
	switch (yp_order_result) {
260
	case 0:
261
		has_yp_order = TRUE;
262
		*tp = (time_t)order;
263
#ifdef DEBUG
264
		dlog("NIS master for %s@%s has order %d", map, domain, order);
265
#endif
266
		break;
267
	case YPERR_YPERR:
268
		plog(XLOG_ERROR, "%s: %s", map, "NIS+ server");
269
		/* NIS+ server found ! */
270
		has_yp_order = FALSE;
271
272
		/* try yp_master() instead */
273
		if (yp_master(domain, map, &master))
274
			return ENOENT;
275
		else
276
		        *tp = time(NULL); /* Use fake timestamps */
277
		break;
278
	default:
279
		return ENOENT;
280
	}
281
	return 0;
282
}