~ubuntu-branches/ubuntu/oneiric/nis/oneiric-proposed

« back to all changes in this revision

Viewing changes to ypserv-2.18/rpc.ypxfrd/ypxfrd_server.c

  • Committer: Bazaar Package Importer
  • Author(s): Scott James Remnant
  • Date: 2005-11-16 23:42:06 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20051116234206-p00omaw5ji5q0qhr
Tags: 3.15-3ubuntu1
Resynchronise with Debian.  (me)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 1996, 1997, 1998, 1999, 2001, 2002 Thorsten Kukuk
 
2
   Author: Thorsten Kukuk <kukuk@suse.de>
 
3
 
 
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.
 
7
 
 
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.
 
12
 
 
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. */
 
17
 
 
18
#define _GNU_SOURCE
 
19
 
 
20
#ifdef HAVE_CONFIG_H
 
21
#include "config.h"
 
22
#endif
 
23
 
 
24
#include <string.h>
 
25
#include <unistd.h>
 
26
#include <errno.h>
 
27
#include <stdio.h>
 
28
#include <fcntl.h>
 
29
#include <sys/stat.h>
 
30
#include <sys/param.h>
 
31
#include <sys/types.h>
 
32
#include <sys/socket.h>
 
33
#include <netinet/in.h>
 
34
#include <arpa/inet.h>
 
35
#include <rpc/rpc.h>
 
36
#ifdef HAVE_RPC_SVC_SOC_H
 
37
#include <rpc/svc_soc.h>
 
38
#endif /* HAVE_RPC_SVC_SOC_H */
 
39
#include "log_msg.h"
 
40
#include "ypxfrd.h"
 
41
#include "access.h"
 
42
#include "yp_db.h"
 
43
#include "compat.h"
 
44
 
 
45
static int file = 0;
 
46
 
 
47
/* Read a block from a file and call xdr_xfr for sending */
 
48
static bool_t
 
49
xdr_ypxfrd_xfr (register XDR *xdrs, xfr *objp)
 
50
{
 
51
  static unsigned char buf[XFRBLOCKSIZE];
 
52
  long len;
 
53
 
 
54
  while (1)
 
55
    {
 
56
      if ((len = read (file, &buf, XFRBLOCKSIZE)) != -1)
 
57
        {
 
58
          /* We could send the next data block */
 
59
          objp->ok = TRUE;
 
60
          objp->xfr_u.xfrblock_buf.xfrblock_buf_len = len;
 
61
          objp->xfr_u.xfrblock_buf.xfrblock_buf_val = (char *) &buf;
 
62
        }
 
63
      else
 
64
        {
 
65
          /* We could not read the next data block, so send an
 
66
             error status */
 
67
          objp->ok = FALSE;
 
68
          objp->xfr_u.xfrstat = XFR_READ_ERR;
 
69
          log_msg ("read error: %s", strerror (errno));
 
70
        }
 
71
 
 
72
      /* call the next function for sending the data or status */
 
73
      if (!xdr_xfr (xdrs, objp))
 
74
        return FALSE;
 
75
 
 
76
      /* We have send the status report successfully, so exit the function
 
77
         with an OK message. This does not mean that there were no errors
 
78
         when reading the map, it only means that there were no errors
 
79
         while sending data or the status. */
 
80
      if (objp->ok == FALSE)
 
81
        return TRUE;
 
82
 
 
83
      /* Now, if we have send the last packet successfully, we could
 
84
         send the XFR_DONE message and quit the function with the
 
85
         return code of the xdr_xfr function */
 
86
      if (objp->xfr_u.xfrblock_buf.xfrblock_buf_len < XFRBLOCKSIZE)
 
87
        {
 
88
          /* This was the last packet, send the XFR_DONE message */
 
89
          objp->ok = FALSE;
 
90
          objp->xfr_u.xfrstat = XFR_DONE;
 
91
          return (xdr_xfr (xdrs, objp));
 
92
        }
 
93
    }
 
94
}
 
95
 
 
96
struct xfr *
 
97
ypxfrd_getmap_1_svc (ypxfr_mapname *argp, struct svc_req *rqstp)
 
98
{
 
99
  static struct xfr result;
 
100
  char buf[MAXPATHLEN];
 
101
  const struct sockaddr_in *rqhost;
 
102
  int valid;
 
103
 
 
104
  if (debug_flag)
 
105
    {
 
106
      rqhost = svc_getcaller (rqstp->rq_xprt);
 
107
      log_msg ("ypproc_null() [From: %s:%d]",
 
108
              inet_ntoa (rqhost->sin_addr),
 
109
              ntohs (rqhost->sin_port));
 
110
      log_msg ("\txfrdomain=%s", argp->xfrdomain);
 
111
      log_msg ("\txfrmap=%s", argp->xfrmap);
 
112
      log_msg ("\txfrmap_filename=%s", argp->xfrmap_filename);
 
113
    }
 
114
 
 
115
  result.ok = FALSE;
 
116
  result.xfr_u.xfrstat = XFR_DENIED;
 
117
 
 
118
  if ((valid = is_valid (rqstp, argp->xfrmap, argp->xfrdomain)) < 1)
 
119
    {
 
120
      if (valid == 0)
 
121
        {
 
122
          if (debug_flag)
 
123
            log_msg ("\t-> Ignored (not a valid source host)");
 
124
        }
 
125
      else
 
126
        {
 
127
          if (debug_flag)
 
128
            log_msg ("\t-> Ignored (not a valid domain)");
 
129
        }
 
130
      ypdb_close_all ();
 
131
 
 
132
      return &result;
 
133
    }
 
134
  ypdb_close_all ();
 
135
 
 
136
#if defined(HAVE_LIBGDBM)
 
137
#if SIZEOF_LONG == 8
 
138
  if ((argp->xfr_db_type != XFR_DB_GNU_GDBM64) &&
 
139
      (argp->xfr_db_type != XFR_DB_ANY))
 
140
#else
 
141
  if ((argp->xfr_db_type != XFR_DB_GNU_GDBM) &&
 
142
      (argp->xfr_db_type != XFR_DB_ANY))
 
143
#endif
 
144
#elif defined (HAVE_LIBNDBM)
 
145
#if defined(__sun__) || defined(sun)
 
146
    if ((argp->xfr_db_type != XFR_DB_NDBM) &&
 
147
        (argp->xfr_db_type != XFR_DB_ANY))
 
148
#else
 
149
    if ((argp->xfr_db_type != XFR_DB_BSD_NDBM) &&
 
150
        (argp->xfr_db_type != XFR_DB_ANY))
 
151
#endif /* sun */
 
152
#else
 
153
  if (argp->xfr_db_type != XFR_DB_ANY)
 
154
#endif
 
155
    {
 
156
      result.xfr_u.xfrstat = XFR_DB_TYPE_MISMATCH;
 
157
      return &result;
 
158
    }
 
159
 
 
160
#if defined(WORDS_BIGENDIAN)
 
161
  if ((argp->xfr_byte_order != XFR_ENDIAN_BIG) &&
 
162
      (argp->xfr_byte_order != XFR_ENDIAN_ANY))
 
163
#else
 
164
  if ((argp->xfr_byte_order != XFR_ENDIAN_LITTLE) &&
 
165
      (argp->xfr_byte_order != XFR_ENDIAN_ANY))
 
166
#endif
 
167
    {
 
168
      result.xfr_u.xfrstat = XFR_DB_ENDIAN_MISMATCH;
 
169
      return &result;
 
170
    }
 
171
 
 
172
  /* check, if the xfrmap and xfrmap_filename means the same map,
 
173
     not that some bad boys tell us that they will have the mail.aliases map,
 
174
     but put "../../../etc/shadow" in the xfrmap_filename. */
 
175
  if (strchr (argp->xfrmap_filename, '/') != NULL)
 
176
    {
 
177
      /* We don't have files in other directorys */
 
178
      result.xfr_u.xfrstat = XFR_NOFILE;
 
179
      return &result;
 
180
    }
 
181
 
 
182
  if (strncmp (argp->xfrmap, argp->xfrmap_filename, strlen (argp->xfrmap))
 
183
      != 0)
 
184
    return &result;
 
185
 
 
186
  if (strlen (argp->xfrdomain) + strlen (argp->xfrmap_filename) + 2
 
187
      < sizeof (buf))
 
188
    sprintf (buf, "%s/%s", argp->xfrdomain, argp->xfrmap_filename);
 
189
  else
 
190
    {
 
191
      log_msg ("Buffer overflow! [%s|%d]", __FILE__, __LINE__);
 
192
      result.xfr_u.xfrstat = XFR_NOFILE;
 
193
      return &result;
 
194
    }
 
195
 
 
196
  if (access ((char *) &buf, R_OK) == -1)
 
197
    {
 
198
      result.xfr_u.xfrstat = XFR_ACCESS;
 
199
      return &result;
 
200
    }
 
201
 
 
202
  if ((file = open ((char *) &buf, O_RDONLY)) == -1)
 
203
    {
 
204
      result.xfr_u.xfrstat = XFR_READ_ERR;
 
205
      return (&result);
 
206
    }
 
207
 
 
208
  /* Start with sending the database file */
 
209
  svc_sendreply (rqstp->rq_xprt, (xdrproc_t) xdr_ypxfrd_xfr, (char *) &result);
 
210
 
 
211
  close (file);
 
212
 
 
213
  return NULL;
 
214
}