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

« back to all changes in this revision

Viewing changes to ypserv-2.18/lib/access.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) 1997, 1998, 1999, 2000, 2002, 2003 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
#ifdef HAVE_CONFIG_H
 
19
#include "config.h"
 
20
#endif
 
21
 
 
22
#include <netdb.h>
 
23
#include <syslog.h>
 
24
#ifndef LOG_DAEMON
 
25
#include <sys/syslog.h>
 
26
#endif
 
27
#include <string.h>
 
28
#include <stdlib.h>
 
29
#include <sys/stat.h>
 
30
#include <sys/socket.h>
 
31
#include <netinet/in.h>
 
32
#include <arpa/inet.h>
 
33
 
 
34
#include "log_msg.h"
 
35
#include "ypserv_conf.h"
 
36
#include "access.h"
 
37
#include "yp_db.h"
 
38
#include "yp.h"
 
39
#include "compat.h"
 
40
 
 
41
static conffile_t *conf = NULL;
 
42
 
 
43
void
 
44
load_config (void)
 
45
{
 
46
  conffile_t *tmp;
 
47
 
 
48
  if (conf != NULL)
 
49
    {
 
50
      log_msg ("Reloading %s/ypserv.conf", CONFDIR);
 
51
      while (conf)
 
52
        {
 
53
          tmp = conf;
 
54
          conf = conf->next;
 
55
 
 
56
          free (tmp->map);
 
57
          free (tmp);
 
58
        }
 
59
    }
 
60
 
 
61
  conf = load_ypserv_conf (CONFDIR);
 
62
}
 
63
 
 
64
/* Give a string with the DEFINE description back */
 
65
static char *
 
66
ypproc_name (int proc)
 
67
{
 
68
  switch (proc)
 
69
    {
 
70
    case YPPROC_NULL:
 
71
      return "ypproc_null";
 
72
    case YPPROC_DOMAIN:
 
73
      return "ypproc_domain";
 
74
    case YPPROC_DOMAIN_NONACK:
 
75
      return "ypproc_domain_nonack";
 
76
    case YPPROC_MATCH:
 
77
      return "ypproc_match";
 
78
    case YPPROC_FIRST:
 
79
      return "ypproc_first";
 
80
    case YPPROC_NEXT:
 
81
      return "ypproc_next";
 
82
    case YPPROC_XFR:
 
83
      return "ypproc_xfr";
 
84
    case YPPROC_CLEAR:
 
85
      return "ypproc_clear";
 
86
    case YPPROC_ALL:
 
87
      return "ypproc_all";
 
88
    case YPPROC_MASTER:
 
89
      return "ypproc_master";
 
90
    case YPPROC_ORDER:
 
91
      return "ypproc_order";
 
92
    case YPPROC_MAPLIST:
 
93
      return "ypproc_maplist";
 
94
    default:
 
95
      return "unknown ?";
 
96
    }
 
97
}
 
98
 
 
99
/* The is_valid_domain function checks the domain specified bye the
 
100
   caller to make sure it's actually served by this server.
 
101
 
 
102
   Return 1 if the name is a valid domain name served by us, else 0. */
 
103
int
 
104
is_valid_domain (const char *domain)
 
105
{
 
106
  struct stat sbuf;
 
107
 
 
108
  if (domain == NULL || domain[0] == '\0' ||
 
109
      strcmp (domain, "binding") == 0 ||
 
110
      strcmp (domain, "..") == 0 ||
 
111
      strcmp (domain, ".") == 0 ||
 
112
      strchr (domain, '/'))
 
113
    return 0;
 
114
 
 
115
  if (stat (domain, &sbuf) < 0 || !S_ISDIR (sbuf.st_mode))
 
116
    return 0;
 
117
 
 
118
  return 1;
 
119
}
 
120
 
 
121
/* By default, we use the securenet list, to check if the client
 
122
   is secure.
 
123
 
 
124
   return  1, if request comes from an authorized host
 
125
   return  0, if securenets does not allow access from this host
 
126
   return -1, if request comes from an unauthorized host
 
127
   return -2, if the map name is not valid
 
128
   return -3, if the domain is not valid */
 
129
 
 
130
int
 
131
is_valid (struct svc_req *rqstp, const char *map, const char *domain)
 
132
{
 
133
  const struct sockaddr_in *sin;
 
134
  int status;
 
135
  static unsigned long int oldaddr = 0;         /* so we dont log multiple times */
 
136
  static int oldstatus = -1;
 
137
 
 
138
  if (domain && is_valid_domain (domain) == 0)
 
139
    return -3;
 
140
 
 
141
  if (map && (map[0] == '\0' || strchr (map ,'/')))
 
142
    return -2;
 
143
 
 
144
  sin = svc_getcaller (rqstp->rq_xprt);
 
145
 
 
146
  status = securenet_host (sin->sin_addr);
 
147
 
 
148
  if ((map != NULL) && status)
 
149
    {
 
150
      conffile_t *work;
 
151
 
 
152
      work = conf;
 
153
      while (work)
 
154
        {
 
155
          if ((sin->sin_addr.s_addr & work->netmask.s_addr) == work->network.s_addr)
 
156
            if (strcmp (work->domain, domain) == 0 ||
 
157
                strcmp (work->domain, "*") == 0)
 
158
              if (strcmp (work->map, map) == 0 || strcmp (work->map, "*") == 0)
 
159
                break;
 
160
          work = work->next;
 
161
        }
 
162
 
 
163
      if (work != NULL)
 
164
        switch (work->security)
 
165
          {
 
166
          case SEC_NONE:
 
167
            if (work->mangle) status = 200 + work->mangle;
 
168
            break;
 
169
          case SEC_DENY:
 
170
            status = -1;
 
171
            break;
 
172
          case SEC_PORT:
 
173
            if (ntohs (sin->sin_port) >= IPPORT_RESERVED)
 
174
              status = (work->mangle) ? 200 + work->mangle : -1;
 
175
            break;
 
176
          }
 
177
      else if (domain != NULL)
 
178
        {
 
179
          /* The map is not in the access list, maybe it
 
180
             has a YP_SECURE key ? */
 
181
          DB_FILE dbp = ypdb_open (domain, map);
 
182
          if (dbp != NULL)
 
183
            {
 
184
              datum key;
 
185
 
 
186
              key.dsize = sizeof ("YP_SECURE") - 1;
 
187
              key.dptr = "YP_SECURE";
 
188
              if (ypdb_exists (dbp, key))
 
189
                if (ntohs (sin->sin_port) >= IPPORT_RESERVED)
 
190
                  status = -1;
 
191
              ypdb_close (dbp);
 
192
            }
 
193
        }
 
194
    }
 
195
 
 
196
  if (debug_flag)
 
197
    {
 
198
      log_msg ("%sconnect from %s", status ? "" : "refused ",
 
199
               inet_ntoa (sin->sin_addr));
 
200
    }
 
201
  else
 
202
    {
 
203
      if (status < 1 && ((sin->sin_addr.s_addr != oldaddr)
 
204
                         || (status != oldstatus)))
 
205
        syslog (LOG_WARNING,
 
206
                "refused connect from %s:%d to procedure %s (%s,%s;%d)\n",
 
207
                inet_ntoa (sin->sin_addr), ntohs (sin->sin_port),
 
208
                ypproc_name (rqstp->rq_proc),
 
209
                domain ? domain : "", map ? map : "", status);
 
210
    }
 
211
  oldaddr = sin->sin_addr.s_addr;
 
212
  oldstatus = status;
 
213
 
 
214
  return status;
 
215
}