1
/* Copyright (c) 2000, 2001, 2002, 2003, 2005 Thorsten Kukuk
2
Author: Thorsten Kukuk <kukuk@suse.de>
4
The YP Server is free software; you can redistribute it and/or
5
modify it under the terms of the GNU General Public License
6
version 2 as published by the Free Software Foundation.
8
The YP Server is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
General Public License for more details.
13
You should have received a copy of the GNU General Public
14
License along with the YP Server; see the file COPYING. If
15
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
16
Cambridge, MA 02139, USA. */
25
#include <sys/types.h>
26
#include <sys/socket.h>
27
#include <netinet/in.h>
28
#include <arpa/inet.h>
32
#endif /* HAVE_ALLOCA_H */
42
#include "ypserv_conf.h"
48
mangle(datum *val, int vcode)
55
if (vcode < 201) return;
58
for (i = 0, s = val->dptr; i < val->dsize && *s; i++, s++) {
59
if (n == field) break;
62
if (n != field) return;
64
if ((p = malloc(val->dsize + 1)) == NULL) return;
65
memcpy(p, val->dptr, i);
66
memcpy(p + i, "x", 1);
70
for (; i < val->dsize; i++, s++)
72
memcpy(q, s, val->dsize - i);
73
newsize += val->dsize - i;
81
ypproc_null_2_svc (void *argp UNUSED, void *result UNUSED,
82
struct svc_req *rqstp)
86
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
87
log_msg ("ypproc_null() [From: %s:%d]",
88
inet_ntoa (rqhost->sin_addr),
89
ntohs (rqhost->sin_port));
92
if (is_valid (rqstp, NULL, NULL) < 1)
100
ypproc_domain_2_svc (domainname *argp, bool_t *result,
101
struct svc_req *rqstp)
105
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
106
log_msg ("ypproc_domain(\"%s\") [From: %s:%d]",
107
*argp, inet_ntoa (rqhost->sin_addr),
108
ntohs (rqhost->sin_port));
111
switch (is_valid (rqstp, NULL, *argp))
114
case -2: /* -2 should not happen */
119
log_msg ("\t-> Ignored (not a valid source host)");
124
log_msg ("\t-> Ignored (forbidden by securenets)");
133
(*result == TRUE ? "Ok" : "Not served by us"));
140
ypproc_domain_nonack_2_svc (domainname *argp, bool_t *result,
141
struct svc_req *rqstp)
145
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
146
log_msg ("ypproc_domain_nonack(\"%s\") [From: %s:%d]",
147
*argp, inet_ntoa (rqhost->sin_addr),
148
ntohs (rqhost->sin_port));
151
switch (is_valid (rqstp, NULL, *argp))
155
log_msg ("\t-> Ignored (not a valid domain)");
156
/* Bail out and don't return any RPC value */
158
case -2: /* Should not happen */
159
log_msg ("Map name not valid, this cannot happen???");
163
log_msg ("\t-> Ignored (not a valid source host)");
167
log_msg ("\t-> Ignored (forbidden by securenets)");
175
log_msg ("\t-> OK.");
182
ypproc_match_2_svc (ypreq_key *argp, ypresp_val *result,
183
struct svc_req *rqstp)
189
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
191
log_msg ("ypproc_match(): [From: %s:%d]",
192
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
194
log_msg ("\t\tdomainname = \"%s\"", argp->domain);
195
log_msg ("\t\tmapname = \"%s\"", argp->map);
196
log_msg ("\t\tkeydat = \"%.*s\"", (int) argp->key.keydat_len,
197
argp->key.keydat_val);
200
memset (result, 0, sizeof (ypresp_val));
202
valid = is_valid (rqstp, argp->map, argp->domain);
209
log_msg ("\t-> Ignored (not a valid source host)");
210
result->stat = YP_NOMAP;
214
log_msg ("\t-> Ignored (not a valid map name)");
215
result->stat = YP_BADARGS;
219
log_msg ("\t-> Ignored (not a valid domain)");
220
result->stat = YP_NODOM;
224
log_msg ("\t-> Ignored (forbidden by securenets)");
225
result->stat = YP_NOMAP;
231
if (argp->key.keydat_len == 0 || argp->key.keydat_val[0] == '\0')
232
result->stat = YP_BADARGS;
237
DB_FILE dbp = ypdb_open (argp->domain, argp->map);
239
result->stat = YP_NOMAP;
242
qdat.dsize = argp->key.keydat_len;
243
qdat.dptr = argp->key.keydat_val;
245
rdat = ypdb_fetch (dbp, qdat);
246
mangle(&rdat, valid);
248
if (rdat.dptr != NULL)
250
result->stat = YP_TRUE;
251
result->val.valdat_len = rdat.dsize;
252
result->val.valdat_val = rdat.dptr;
255
result->stat = YP_NOKEY;
263
if (result->stat == YP_TRUE)
264
log_msg ("\t-> Value = \"%.*s\"",
265
(int) result->val.valdat_len, result->val.valdat_val);
267
log_msg ("\t-> Error #%d", result->stat);
275
ypproc_first_2_svc (ypreq_nokey *argp, ypresp_key_val *result,
276
struct svc_req *rqstp)
283
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
284
log_msg ("ypproc_first(): [From: %s:%d]",
285
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
287
log_msg ("\tdomainname = \"%s\"", argp->domain);
288
log_msg ("\tmapname = \"%s\"", argp->map);
291
memset (result, 0, sizeof (ypresp_key_val));
293
valid = is_valid (rqstp, argp->map, argp->domain);
300
log_msg ("\t-> Ignored (not a valid source host)");
301
result->stat = YP_NOMAP;
305
log_msg ("\t-> Ignored (not a valid map name)");
306
result->stat = YP_BADARGS;
310
log_msg ("\t-> Ignored (not a valid domain)");
311
result->stat = YP_NODOM;
315
log_msg ("\t-> Ignored (forbidden by securenets)");
316
result->stat = YP_NOMAP;
323
dbp = ypdb_open (argp->domain, argp->map);
325
result->stat = YP_NOMAP;
328
datum dkey = ypdb_firstkey (dbp);
330
while (dkey.dptr != NULL && dkey.dptr[0] == 'Y' &&
331
dkey.dptr[1] == 'P' && dkey.dptr[2] == '_')
333
#if defined(HAVE_NDBM)
334
/* This is much more faster then ypdb_nextkey, but
335
it is terrible to port to other databases */
336
dkey = dbm_nextkey (dbp);
339
dkey = ypdb_nextkey (dbp, tkey);
340
ypdb_free (tkey.dptr);
344
if (dkey.dptr != NULL)
346
datum dval = ypdb_fetch (dbp, dkey);
347
mangle(&dval, valid);
348
result->stat = YP_TRUE;
350
result->key.keydat_len = dkey.dsize;
351
result->key.keydat_val = dkey.dptr;
353
result->val.valdat_len = dval.dsize;
354
result->val.valdat_val = dval.dptr;
357
result->stat = YP_NOKEY;
363
if (result->stat == YP_TRUE)
364
log_msg ("\t-> Key = \"%.*s\", Value = \"%.*s\"",
365
(int) result->key.keydat_len, result->key.keydat_val,
366
(int) result->val.valdat_len, result->val.valdat_val);
367
else if (result->stat == YP_NOMORE)
368
log_msg ("\t-> No more entry's");
370
log_msg ("\t-> Error #%d", result->stat);
377
ypproc_next_2_svc (ypreq_key *argp, ypresp_key_val *result,
378
struct svc_req *rqstp)
385
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
387
log_msg ("ypproc_next(): [From: %s:%d]",
388
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
390
log_msg ("\tdomainname = \"%s\"", argp->domain);
391
log_msg ("\tmapname = \"%s\"", argp->map);
392
log_msg ("\tkeydat = \"%.*s\"",
393
(int) argp->key.keydat_len,
394
argp->key.keydat_val);
397
memset (result, 0, sizeof (ypresp_key_val));
399
valid = is_valid (rqstp, argp->map, argp->domain);
406
log_msg ("\t-> Ignored (not a valid source host)");
407
result->stat = YP_NOMAP;
411
log_msg ("\t-> Ignored (not a valid map name)");
412
result->stat = YP_BADARGS;
416
log_msg ("\t-> Ignored (not a valid domain)");
417
result->stat = YP_NODOM;
421
log_msg ("\t-> Ignored (forbidden by securenets)");
422
result->stat = YP_NOMAP;
428
dbp = ypdb_open (argp->domain, argp->map);
430
result->stat = YP_NOMAP;
435
oldkey.dsize = argp->key.keydat_len;
436
oldkey.dptr = strndup (argp->key.keydat_val, oldkey.dsize);
438
dkey = ypdb_nextkey (dbp, oldkey);
439
while (dkey.dptr != NULL && dkey.dptr[0] == 'Y' &&
440
dkey.dptr[1] == 'P' && dkey.dptr[2] == '_')
443
oldkey.dsize = dkey.dsize;
444
oldkey.dptr = strndup (dkey.dptr, dkey.dsize);
445
ypdb_free (dkey.dptr);
446
dkey = ypdb_nextkey (dbp, oldkey);
451
if (dkey.dptr == NULL)
452
result->stat = YP_NOMORE;
455
datum dval = ypdb_fetch (dbp, dkey);
456
mangle(&dval, valid);
458
result->stat = YP_TRUE;
459
result->key.keydat_len = dkey.dsize;
460
result->key.keydat_val = dkey.dptr;
462
result->val.valdat_len = dval.dsize;
463
result->val.valdat_val = dval.dptr;
470
if (result->stat == YP_TRUE)
471
log_msg ("\t-> Key = \"%.*s\", Value = \"%.*s\"",
472
(int) result->key.keydat_len, result->key.keydat_val,
473
(int) result->val.valdat_len, result->val.valdat_val);
474
else if (result->stat == YP_NOMORE)
475
log_msg ("\t-> No more entry's");
477
log_msg ("\t-> Error #%d", result->stat);
484
ypproc_xfr_2_svc (ypreq_xfr *argp, ypresp_xfr *result,
485
struct svc_req *rqstp)
488
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
493
log_msg ("ypproc_xfr_2_svc(): [From: %s:%d]\n\tmap_parms:",
494
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
496
log_msg ("\t\tdomain = \"%s\"", argp->map_parms.domain);
497
log_msg ("\t\tmap = \"%s\"", argp->map_parms.map);
498
log_msg ("\t\tordernum = %u", argp->map_parms.ordernum);
499
log_msg ("\t\tpeer = \"%s\"", argp->map_parms.peer);
500
log_msg ("\t\ttransid = %u", argp->transid);
501
log_msg ("\t\tprog = %u", argp->prog);
502
log_msg ("\t\tport = %u", argp->port);
505
memset (result, 0, sizeof (ypresp_xfr));
506
result->transid = argp->transid;
508
valid = is_valid (rqstp, argp->map_parms.map, argp->map_parms.domain);
515
log_msg ("\t-> Ignored (forbidden by securenets)");
517
log_msg ("refuse to transfer map from %s",
518
inet_ntoa (rqhost->sin_addr));
519
result->xfrstat = YPXFR_REFUSED;
523
log_msg ("\t-> Ignored (not a valid source host)");
525
log_msg ("refuse to transfer map from %s",
526
inet_ntoa (rqhost->sin_addr));
527
result->xfrstat = YPXFR_REFUSED;
531
log_msg ("\t-> Ignored (map contains \"/\"!)");
533
log_msg ("refuse to transfer map from %s, no valid mapname",
534
inet_ntoa (rqhost->sin_addr));
535
result->xfrstat = YPXFR_REFUSED;
539
log_msg ("\t-> Ignored (not a valid domain)");
541
log_msg ("refuse to transfer map from %s, no valid domain",
542
inet_ntoa (rqhost->sin_addr));
543
result->xfrstat = YPXFR_NODOM;
551
if(ntohs(rqhost->sin_port) >= IPPORT_RESERVED)
554
log_msg ("\t-> Ignored (no reserved port!)");
556
log_msg ("refuse to transfer %s from %s, no valid port",
557
argp->map_parms.map, inet_ntoa (rqhost->sin_addr));
559
result->xfrstat = YPXFR_REFUSED;
564
/* If we have the map, check, if the master name is the same as in
565
the ypreq_xfr struct. If we doesn't have the map, refuse. */
566
dbp = ypdb_open(argp->map_parms.domain, argp->map_parms.map);
571
key.dsize = sizeof ("YP_MASTER_NAME") - 1;
572
key.dptr = "YP_MASTER_NAME";
574
if(ypdb_exists (dbp, key))
576
datum val = ypdb_fetch (dbp, key);
579
if ((size_t)val.dsize != strlen (argp->map_parms.peer) ||
580
strncmp (val.dptr, argp->map_parms.peer, val.dsize) != 0)
582
char *buf = alloca (val.dsize + 1);
584
strncpy (buf, val.dptr, val.dsize);
585
buf[val.dsize] = '\0';
588
log_msg ("\t->Ignored (%s is not the master, master is %s)",
589
argp->map_parms.peer, buf);
591
log_msg ("refuse to transfer %s from %s, master is %s)",
592
argp->map_parms.map, inet_ntoa (rqhost->sin_addr),
596
result->xfrstat = YPXFR_NODOM;
602
/* If we do not have a YP_MASTER_NAME key, we don't have a
603
master/slave NIS system */
605
log_msg ("\t->Ignored (no YP_MASTER_NAME key in local map)");
608
result->xfrstat = YPXFR_REFUSED;
613
else if (trusted_master != NULL)
615
/* We have a new map. We only allow new maps from a NIS master
616
we trust (which means, the admin told us this master is ok. */
617
if (strcasecmp (trusted_master, argp->map_parms.peer) != 0)
620
log_msg ("\t->Ignored (%s is not a trusted master!)",
621
argp->map_parms.peer);
623
log_msg ("refuse to transfer %s from %s, no trusted master",
624
argp->map_parms.map, inet_ntoa (rqhost->sin_addr));
627
result->xfrstat = YPXFR_NODOM;
631
/* If you wish to allow the transfer of new maps, change the next
632
#if 1 statement to #if 0 */
636
/* We doesn't have the map, refuse the transfer */
638
log_msg ("\t->Ignored (I don't have this map)");
640
log_msg ("refuse to transfer %s from %s, map doesn't exist",
641
argp->map_parms.map, inet_ntoa (rqhost->sin_addr));
643
result->xfrstat = YPXFR_REFUSED;
652
char *ypxfr_command = alloca (sizeof (YPBINDIR) + 8);
653
char g[30], t[30], p[30];
657
i = open ("/dev/null", O_RDWR);
661
sprintf (ypxfr_command, "%s/ypxfr", YPBINDIR);
662
snprintf (t, sizeof (t), "%u", argp->transid);
663
snprintf (g, sizeof (g), "%u", argp->prog);
664
snprintf (p, sizeof (p), "%u", argp->port);
666
execl (ypxfr_command, "ypxfr", "--debug", "-d",
667
argp->map_parms.domain, "-h", argp->map_parms.peer,
669
inet_ntoa (rqhost->sin_addr), p, argp->map_parms.map, NULL);
671
execl (ypxfr_command, "ypxfr", "-d", argp->map_parms.domain, "-h",
672
argp->map_parms.peer, "-C", t, g,
673
inet_ntoa (rqhost->sin_addr), p, argp->map_parms.map, NULL);
675
log_msg ("ypxfr execl(): %s", strerror (errno));
679
log_msg ("Cannot fork: %s", strerror (errno));
680
result->xfrstat = YPXFR_XFRERR;
683
result->xfrstat = YPXFR_SUCC;
690
bool_t ypproc_clear_2_svc (void *argp UNUSED, void *result UNUSED,
691
struct svc_req *rqstp)
695
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
696
log_msg ("ypproc_clear_2_svc() [From: %s:%d]",
697
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
700
if (is_valid (rqstp, NULL, NULL) < 1)
703
log_msg ("\t-> Ignored (not a valid source host)");
711
/* We need the struct for giving ypall_encode the DB_FILE handle */
712
typedef struct ypall_data {
720
ypall_close (void *data)
724
log_msg ("ypall_close() called with NULL pointer.");
728
ypdb_close (((ypall_data_t) data)->dbm);
729
if (((ypall_data_t) data)->dkey.dptr)
730
ypdb_free (((ypall_data_t) data)->dkey.dptr);
731
if (((ypall_data_t) data)->dval.dptr)
732
ypdb_free (((ypall_data_t) data)->dval.dptr);
738
ypall_encode (ypresp_key_val *val, void *data)
742
oldkey.dsize = val->key.keydat_len;
743
oldkey.dptr = strndup (val->key.keydat_val, oldkey.dsize);
744
ypdb_free (((ypall_data_t) data)->dkey.dptr);
745
((ypall_data_t) data)->dkey.dptr = NULL;
746
ypdb_free (((ypall_data_t) data)->dval.dptr);
747
((ypall_data_t) data)->dval.dptr = NULL;
749
((ypall_data_t) data)->dkey = ypdb_nextkey (((ypall_data_t) data)->dbm,
752
while (((ypall_data_t) data)->dkey.dptr != NULL &&
753
((ypall_data_t) data)->dkey.dptr[0] == 'Y' &&
754
((ypall_data_t) data)->dkey.dptr[1] == 'P' &&
755
((ypall_data_t) data)->dkey.dptr[2] == '_')
758
oldkey.dsize = ((ypall_data_t) data)->dkey.dsize;
759
oldkey.dptr = strndup (((ypall_data_t) data)->dkey.dptr,
760
((ypall_data_t) data)->dkey.dsize);
761
ypdb_free (((ypall_data_t) data)->dkey.dptr);
762
((ypall_data_t) data)->dkey.dptr = NULL;
764
((ypall_data_t) data)->dkey = ypdb_nextkey (((ypall_data_t) data)->dbm,
770
if (((ypall_data_t) data)->dkey.dptr == NULL)
771
val->stat = YP_NOMORE;
774
((ypall_data_t) data)->dval =
775
ypdb_fetch (((ypall_data_t) data)->dbm, ((ypall_data_t) data)->dkey);
776
mangle(&(((ypall_data_t) data)->dval), ((ypall_data_t) data)->vcode);
780
val->key.keydat_val = ((ypall_data_t) data)->dkey.dptr;
781
val->key.keydat_len = ((ypall_data_t) data)->dkey.dsize;
783
val->val.valdat_val = ((ypall_data_t) data)->dval.dptr;
784
val->val.valdat_len = ((ypall_data_t) data)->dval.dsize;
789
extern xdr_ypall_cb_t xdr_ypall_cb;
792
ypproc_all_2_svc (ypreq_nokey *argp, ypresp_all *result, struct svc_req *rqstp)
799
const struct sockaddr_in *rqhost;
801
rqhost = svc_getcaller (rqstp->rq_xprt);
802
log_msg ("ypproc_all_2_svc(): [From: %s:%d]",
803
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
805
log_msg ("\t\tdomain = \"%s\"", argp->domain);
806
log_msg ("\t\tmap = \"%s\"", argp->map);
809
memset (result, 0, sizeof (ypresp_all));
810
xdr_ypall_cb.u.encode = NULL;
811
xdr_ypall_cb.u.close = NULL;
812
xdr_ypall_cb.data = NULL;
814
/* Set this to TRUE so that the client will be forced to read
815
at least one record from us. This could be the error code. */
818
valid = is_valid (rqstp, argp->map, argp->domain);
825
log_msg ("\t-> Ignored (forbidden by securenets)");
826
result->ypresp_all_u.val.stat = YP_NOMAP;
830
log_msg ("\t-> Ignored (not a valid source host)");
831
result->ypresp_all_u.val.stat = YP_NOMAP;
835
log_msg ("\t-> Ignored (not a valid map name)");
836
result->ypresp_all_u.val.stat = YP_BADARGS;
840
log_msg ("\t-> Ignored (not a valid domain)");
841
result->ypresp_all_u.val.stat = YP_NODOM;
850
log_msg ("ypserv has forked for ypproc_all(): pid=%i", getpid ());
853
case -1: /* parent, error */
854
log_msg ("WARNING(ypproc_all_2_svc): cannot fork: %s",
856
result->ypresp_all_u.val.stat = YP_YPERR;
858
default: /* parent, default */
863
/* We are now in the child part. Don't let the child ypserv share
864
DB handles with the parent process. */
867
if ((data = calloc (1, sizeof (struct ypall_data))) == NULL)
869
log_msg ("ERROR: could not allocate enough memory! [%s|%d]",
871
result->ypresp_all_u.val.stat = YP_YPERR;
875
data->dbm = ypdb_open (argp->domain, argp->map);
877
if (data->dbm == NULL)
878
result->ypresp_all_u.val.stat = YP_NOMAP;
881
data->dkey = ypdb_firstkey (data->dbm);
883
while (data->dkey.dptr != NULL && data->dkey.dptr[0] == 'Y'
884
&& data->dkey.dptr[1] == 'P' && data->dkey.dptr[2] == '_')
886
datum tkey = data->dkey;
887
data->dkey = ypdb_nextkey (data->dbm, tkey);
888
ypdb_free (tkey.dptr);
891
if (data->dkey.dptr != NULL)
893
data->dval = ypdb_fetch (data->dbm, data->dkey);
894
mangle(&(data->dval), valid);
896
result->ypresp_all_u.val.stat = YP_TRUE;
898
result->ypresp_all_u.val.key.keydat_len = data->dkey.dsize;
899
result->ypresp_all_u.val.key.keydat_val = data->dkey.dptr;
901
result->ypresp_all_u.val.val.valdat_len = data->dval.dsize;
902
result->ypresp_all_u.val.val.valdat_val = data->dval.dptr;
906
xdr_ypall_cb.u.encode = ypall_encode;
907
xdr_ypall_cb.u.close = ypall_close;
908
xdr_ypall_cb.data = (void *) data;
911
log_msg ("\t -> First value returned.");
913
if (result->ypresp_all_u.val.stat == YP_TRUE)
914
goto out; /* We return to commit the data.
915
This also means, we don't give
919
result->ypresp_all_u.val.stat = YP_NOMORE;
921
ypdb_close (data->dbm);
927
log_msg ("\t -> Exit from ypproc_all without sending data.");
930
if (!svc_sendreply (rqstp->rq_xprt, (xdrproc_t) xdr_ypresp_all,
932
svcerr_systemerr (rqstp->rq_xprt);
933
/* Note: no need to free args; we're exiting. */
938
ypproc_master_2_svc (ypreq_nokey *argp, ypresp_master *result,
939
struct svc_req *rqstp)
946
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
947
log_msg ("ypproc_master_2_svc(): [From: %s:%d]",
948
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
950
log_msg ("\t\tdomain = \"%s\"", argp->domain);
951
log_msg ("\t\tmap = \"%s\"", argp->map);
954
memset (result, 0, sizeof (ypresp_master));
956
valid = is_valid (rqstp, argp->map, argp->domain);
963
log_msg ("\t-> Ignored (not a valid source host)");
964
result->stat = YP_NOMAP;
968
log_msg ("\t-> Ignored (not a valid map name)");
969
result->stat = YP_BADARGS;
973
log_msg ("\t-> Ignored (not a domain)");
974
result->stat = YP_NODOM;
978
log_msg ("\t-> Ignored (forbidden by securenets)");
979
result->stat = YP_NOMAP;
982
result->peer = strdup ("");
986
dbp = ypdb_open (argp->domain, argp->map);
988
result->stat = YP_NOMAP;
993
key.dsize = sizeof ("YP_MASTER_NAME") - 1;
994
key.dptr = "YP_MASTER_NAME";
996
val = ypdb_fetch (dbp, key);
999
if (val.dptr == NULL)
1001
/* No YP_MASTER_NAME record in map? There is someting wrong */
1002
result->stat = YP_BADDB;
1007
char *hostbuf = alloca (val.dsize + 1);
1009
/* put the eof string mark at the end of the string */
1010
for (i = 0; i < val.dsize; ++i)
1011
hostbuf[i] = val.dptr[i];
1012
hostbuf[val.dsize] = '\0';
1013
ypdb_free (val.dptr);
1015
if ((result->peer = strdup (hostbuf)) == NULL)
1016
result->stat = YP_YPERR;
1018
result->stat = YP_TRUE;
1024
if (result->peer == NULL)
1025
result->peer = strdup ("");
1028
log_msg ("\t-> Peer = \"%s\"", result->peer);
1034
/* Get the DateTimeModified value for a certain map database */
1035
static inline unsigned long
1036
get_dtm (const char *domain, const char *map)
1039
char *buf = alloca (strlen (domain) + strlen (map) + 3);
1042
cp = stpcpy (buf, domain);
1046
if (stat (buf, &sbuf) < 0)
1047
return time (NULL); /* We set it to the current time. */
1049
return (unsigned long) sbuf.st_mtime;
1053
ypproc_order_2_svc (ypreq_nokey *argp, ypresp_order *result,
1054
struct svc_req *rqstp)
1061
const struct sockaddr_in *rqhost;
1063
rqhost = svc_getcaller (rqstp->rq_xprt);
1065
log_msg ("ypproc_order_2_svc(): [From: %s:%d]",
1066
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
1068
log_msg ("\t\tdomain = \"%s\"", argp->domain);
1069
log_msg ("\t\tmap = \"%s\"", argp->map);
1072
memset (result, 0, sizeof (ypresp_order));
1074
valid = is_valid (rqstp, argp->map, argp->domain);
1081
log_msg ("\t-> Ignored (not a valid source host)");
1082
result->stat = YP_NOMAP;
1086
log_msg ("\t-> Ignored (not a valid map name)");
1087
result->stat = YP_BADARGS;
1091
log_msg ("\t-> Ignored (not a valid domain)");
1092
result->stat = YP_NODOM;
1096
log_msg ("\t-> Ignored (forbidden by securenets)");
1097
result->stat = YP_NOMAP;
1103
dbp = ypdb_open (argp->domain, argp->map);
1106
result->stat = YP_NOMAP;
1111
key.dsize = sizeof ("YP_LAST_MODIFIED") - 1;
1112
key.dptr = "YP_LAST_MODIFIED";
1114
val = ypdb_fetch (dbp, key);
1115
mangle(&val, valid);
1117
if (val.dptr == NULL)
1119
/* No YP_LAST_MODIFIED record in map? Use DTM timestamp.. */
1120
result->ordernum = get_dtm (argp->domain, argp->map);
1124
char *buf = alloca (val.dsize + 1);
1126
memcpy (buf, val.dptr, val.dsize);
1127
buf[val.dsize] = '\0';
1128
result->ordernum = atoi (buf);
1129
ypdb_free (val.dptr);
1132
result->stat = YP_TRUE;
1137
log_msg ("-> Order # %u", result->ordernum);
1144
add_maplist (ypmaplist **mlhp, char *map)
1147
#if defined(HAVE_NDBM)
1148
#if defined(sun) || defined(__sun__)
1149
int len = strlen (map);
1151
/* We have all maps twice: with .dir and with .pag. Ignore .pag */
1152
if (len > 3 && map[len - 4] == '.' && map[len - 3] == 'p' &&
1153
map[len - 2] == 'a' && map[len - 1] == 'g')
1156
if (len > 3 && map[len - 4] == '.' && map[len - 3] == 'd' &&
1157
map[len - 2] == 'i' && map[len - 1] == 'r')
1158
map[len - 4] = '\0';
1160
int len = strlen (map);
1162
if (len > 2 && map[len - 3] == '.' && map[len - 2] == 'd' &&
1163
map[len - 1] == 'b')
1164
map[len - 3] = '\0';
1168
if ((mlp = malloc (sizeof (*mlp))) == NULL)
1171
if ((mlp->map = strdup (map)) == NULL)
1184
ypproc_maplist_2_svc (domainname *argp, ypresp_maplist *result,
1185
struct svc_req *rqstp)
1192
const struct sockaddr_in *rqhost = svc_getcaller (rqstp->rq_xprt);
1194
log_msg ("ypproc_maplist_2_svc(): [From: %s:%d]",
1195
inet_ntoa (rqhost->sin_addr), ntohs (rqhost->sin_port));
1197
log_msg ("\t\tdomain = \"%s\"", *argp);
1200
memset (result, 0, sizeof (ypresp_maplist));
1202
valid = is_valid (rqstp, NULL, *argp);
1209
log_msg ("\t-> Ignored (forbidden by securenets)");
1210
result->stat = YP_NOMAP;
1214
log_msg ("\t-> Ignored (not a valid source host)");
1215
result->stat = YP_NOMAP;
1217
case -2: /* should never happen */
1220
log_msg ("\t-> Ignored (not a valid domain)");
1221
result->stat = YP_NODOM;
1227
/* open domain directory */
1228
dp = opendir (*argp);
1232
log_msg ("opendir: %s", strerror (errno));
1234
result->stat = YP_BADDB;
1240
while ((dep = readdir (dp)) != NULL)
1242
/* ignore files starting with . */
1243
if (dep->d_name[0] == '.')
1245
if (add_maplist (&result->maps, dep->d_name) < 0)
1247
result->stat = YP_YPERR;
1252
result->stat = YP_TRUE;
1257
if (result->stat == YP_TRUE)
1266
log_msg (" %s,", p->map);
1268
log_msg (" %s", p->map);
1273
log_msg ("\t-> Error #%d", result->stat);
1280
ypprog_2_freeresult (SVCXPRT *transp UNUSED,
1281
xdrproc_t xdr_result, caddr_t result)
1283
xdr_free (xdr_result, result);