~ubuntu-branches/ubuntu/precise/netatalk/precise

« back to all changes in this revision

Viewing changes to etc/afpd/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: main.c,v 1.20.2.1 2003/11/05 06:41:01 didg Exp $
 
3
 *
 
4
 * Copyright (c) 1990,1993 Regents of The University of Michigan.
 
5
 * All Rights Reserved.  See COPYRIGHT.
 
6
 */
 
7
 
 
8
#ifdef HAVE_CONFIG_H
 
9
#include "config.h"
 
10
#endif /* HAVE_CONFIG_H */
 
11
 
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <string.h>
 
15
#ifdef HAVE_UNISTD_H
 
16
#include <unistd.h>
 
17
#endif /* HAVE_UNISTD_H */
 
18
#ifdef HAVE_FCNTL_H
 
19
#include <fcntl.h>
 
20
#endif /* HAVE_FCNTL_H */
 
21
#include <signal.h>
 
22
 
 
23
#include <sys/types.h>
 
24
#include <sys/stat.h>
 
25
#include <sys/param.h>
 
26
#include <sys/uio.h>
 
27
#include <atalk/logger.h>
 
28
#include <sys/time.h>
 
29
#include <sys/socket.h>
 
30
 
 
31
#include <errno.h>
 
32
 
 
33
#include <netatalk/endian.h>
 
34
#include <netatalk/at.h>
 
35
#include <atalk/compat.h>
 
36
#include <atalk/dsi.h>
 
37
#include <atalk/atp.h>
 
38
#include <atalk/asp.h>
 
39
#include <atalk/afp.h>
 
40
#include <atalk/adouble.h>
 
41
#include <atalk/paths.h>
 
42
#include <atalk/util.h>
 
43
#include <atalk/server_child.h>
 
44
 
 
45
#include "globals.h"
 
46
#include "afp_config.h"
 
47
#include "status.h"
 
48
#include "fork.h"
 
49
#include "uam_auth.h"
 
50
 
 
51
#ifdef TRU64
 
52
#include <sys/security.h>
 
53
#include <prot.h>
 
54
#include <sia.h>
 
55
 
 
56
static int argc = 0;
 
57
static char **argv = NULL;
 
58
#endif /* TRU64 */
 
59
 
 
60
unsigned char   nologin = 0;
 
61
 
 
62
struct afp_options default_options;
 
63
static AFPConfig *configs;
 
64
static server_child *server_children;
 
65
static fd_set save_rfds;
 
66
 
 
67
#ifdef TRU64
 
68
void afp_get_cmdline( int *ac, char ***av)
 
69
{
 
70
    *ac = argc;
 
71
    *av = argv;
 
72
}
 
73
#endif /* TRU64 */
 
74
 
 
75
static void afp_exit(const int i)
 
76
{
 
77
    server_unlock(default_options.pidfile);
 
78
    exit(i);
 
79
}
 
80
 
 
81
static void afp_goaway(int sig)
 
82
{
 
83
#ifndef NO_DDP
 
84
    asp_kill(sig);
 
85
#endif /* ! NO_DDP */
 
86
    dsi_kill(sig);
 
87
    switch( sig ) {
 
88
    case SIGTERM :
 
89
        LOG(log_info, logtype_afpd, "shutting down on signal %d", sig );
 
90
        break;
 
91
    case SIGHUP :
 
92
        /* w/ a configuration file, we can force a re-read if we want */
 
93
        nologin++;
 
94
        if ((nologin + 1) & 1) {
 
95
            AFPConfig *config;
 
96
 
 
97
            LOG(log_info, logtype_afpd, "re-reading configuration file");
 
98
            for (config = configs; config; config = config->next)
 
99
                if (config->server_cleanup)
 
100
                    config->server_cleanup(config);
 
101
 
 
102
            configfree(configs, NULL);
 
103
            if (!(configs = configinit(&default_options))) {
 
104
                LOG(log_error, logtype_afpd, "config re-read: no servers configured");
 
105
                afp_exit(1);
 
106
            }
 
107
            FD_ZERO(&save_rfds);
 
108
            for (config = configs; config; config = config->next) {
 
109
                if (config->fd < 0)
 
110
                    continue;
 
111
                FD_SET(config->fd, &save_rfds);
 
112
            }
 
113
        } else {
 
114
            LOG(log_info, logtype_afpd, "disallowing logins");
 
115
            auth_unload();
 
116
        }
 
117
        break;
 
118
    default :
 
119
        LOG(log_error, logtype_afpd, "afp_goaway: bad signal" );
 
120
    }
 
121
    if ( sig == SIGTERM ) {
 
122
        AFPConfig *config;
 
123
 
 
124
        for (config = configs; config; config = config->next)
 
125
            if (config->server_cleanup)
 
126
                config->server_cleanup(config);
 
127
 
 
128
        afp_exit(0);
 
129
    }
 
130
    return;
 
131
}
 
132
 
 
133
static void child_handler()
 
134
{
 
135
    server_child_handler(server_children);
 
136
}
 
137
 
 
138
int main( ac, av )
 
139
int             ac;
 
140
char    **av;
 
141
{
 
142
    AFPConfig           *config;
 
143
    fd_set              rfds;
 
144
    struct sigaction    sv;
 
145
    sigset_t            sigs;
 
146
    int                 ret;
 
147
 
 
148
#ifdef TRU64
 
149
    argc = ac;
 
150
    argv = av;
 
151
    set_auth_parameters( ac, av );
 
152
#endif /* TRU64 */
 
153
 
 
154
    afp_options_init(&default_options);
 
155
    if (!afp_options_parse(ac, av, &default_options))
 
156
        exit(1);
 
157
 
 
158
    /* Save the user's current umask for use with CNID (and maybe some 
 
159
     * other things, too). */
 
160
    default_options.save_mask = umask( default_options.umask );
 
161
 
 
162
    switch(server_lock("afpd", default_options.pidfile,
 
163
                       default_options.flags & OPTION_DEBUG)) {
 
164
    case -1: /* error */
 
165
        exit(1);
 
166
    case 0: /* child */
 
167
        break;
 
168
    default: /* server */
 
169
        exit(0);
 
170
    }
 
171
 
 
172
    /* install child handler for asp and dsi. we do this before afp_goaway
 
173
     * as afp_goaway references stuff from here. 
 
174
     * XXX: this should really be setup after the initial connections. */
 
175
    if (!(server_children = server_child_alloc(default_options.connections,
 
176
                            CHILD_NFORKS))) {
 
177
        LOG(log_error, logtype_afpd, "main: server_child alloc: %s", strerror(errno) );
 
178
        afp_exit(1);
 
179
    }
 
180
 
 
181
    memset(&sv, 0, sizeof(sv));
 
182
    sv.sa_handler = child_handler;
 
183
    sigemptyset( &sv.sa_mask );
 
184
    sigaddset(&sv.sa_mask, SIGALRM);
 
185
    sigaddset(&sv.sa_mask, SIGHUP);
 
186
    sigaddset(&sv.sa_mask, SIGTERM);
 
187
    sv.sa_flags = SA_RESTART;
 
188
    if ( sigaction( SIGCHLD, &sv, 0 ) < 0 ) {
 
189
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
 
190
        afp_exit(1);
 
191
    }
 
192
 
 
193
    sv.sa_handler = afp_goaway;
 
194
    sigemptyset( &sv.sa_mask );
 
195
    sigaddset(&sv.sa_mask, SIGALRM);
 
196
    sigaddset(&sv.sa_mask, SIGTERM);
 
197
    sigaddset(&sv.sa_mask, SIGCHLD);
 
198
    sv.sa_flags = SA_RESTART;
 
199
    if ( sigaction( SIGHUP, &sv, 0 ) < 0 ) {
 
200
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
 
201
        afp_exit(1);
 
202
    }
 
203
 
 
204
    sigemptyset( &sv.sa_mask );
 
205
    sigaddset(&sv.sa_mask, SIGALRM);
 
206
    sigaddset(&sv.sa_mask, SIGHUP);
 
207
    sigaddset(&sv.sa_mask, SIGCHLD);
 
208
    sv.sa_flags = SA_RESTART;
 
209
    if ( sigaction( SIGTERM, &sv, 0 ) < 0 ) {
 
210
        LOG(log_error, logtype_afpd, "main: sigaction: %s", strerror(errno) );
 
211
        afp_exit(1);
 
212
    }
 
213
 
 
214
    /* afpd.conf: not in config file: lockfile, connections, configfile
 
215
     *            preference: command-line provides defaults.
 
216
     *                        config file over-writes defaults.
 
217
     *
 
218
     * we also need to make sure that killing afpd during startup
 
219
     * won't leave any lingering registered names around.
 
220
     */
 
221
 
 
222
    sigemptyset(&sigs);
 
223
    sigaddset(&sigs, SIGALRM);
 
224
    sigaddset(&sigs, SIGHUP);
 
225
#if 0 
 
226
    /* don't block SIGTERM */   
 
227
    sigaddset(&sigs, SIGTERM);
 
228
#endif    
 
229
    sigaddset(&sigs, SIGCHLD);
 
230
    sigprocmask(SIG_BLOCK, &sigs, NULL);
 
231
    if (!(configs = configinit(&default_options))) {
 
232
        LOG(log_error, logtype_afpd, "main: no servers configured: %s\n", strerror(errno));
 
233
        afp_exit(1);
 
234
    }
 
235
    sigprocmask(SIG_UNBLOCK, &sigs, NULL);
 
236
 
 
237
    /* watch atp and dsi sockets. */
 
238
    FD_ZERO(&save_rfds);
 
239
    for (config = configs; config; config = config->next) {
 
240
        if (config->fd < 0) /* for proxies */
 
241
            continue;
 
242
        FD_SET(config->fd, &save_rfds);
 
243
    }
 
244
 
 
245
    /* wait for an appleshare connection. parent remains in the loop
 
246
     * while the children get handled by afp_over_{asp,dsi}.  this is
 
247
     * currently vulnerable to a denial-of-service attack if a
 
248
     * connection is made without an actual login attempt being made
 
249
     * afterwards. establishing timeouts for logins is a possible 
 
250
     * solution. */
 
251
    while (1) {
 
252
        rfds = save_rfds;
 
253
        sigprocmask(SIG_UNBLOCK, &sigs, NULL);
 
254
        ret = select(FD_SETSIZE, &rfds, NULL, NULL, NULL);
 
255
        sigprocmask(SIG_BLOCK, &sigs, NULL);
 
256
        if (ret < 0) {
 
257
            if (errno == EINTR)
 
258
                continue;
 
259
            LOG(log_error, logtype_afpd, "main: can't wait for input: %s", strerror(errno));
 
260
            break;
 
261
        }
 
262
 
 
263
        for (config = configs; config; config = config->next) {
 
264
            if (config->fd < 0)
 
265
                continue;
 
266
            if (FD_ISSET(config->fd, &rfds))
 
267
                config->server_start(config, configs, server_children);
 
268
        }
 
269
    }
 
270
 
 
271
    return 0;
 
272
}