]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/afp_config.c
Fixes
[netatalk.git] / etc / afpd / afp_config.c
1 /*
2  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3  * All Rights Reserved.  See COPYRIGHT.
4  */
5
6 #ifdef HAVE_CONFIG_H
7 #include "config.h"
8 #endif /* HAVE_CONFIG_H */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <errno.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <ctype.h>
17 #include <sys/socket.h>
18 #include <netinet/in.h>
19 #include <arpa/inet.h>
20
21 #include <atalk/logger.h>
22 #include <atalk/util.h>
23 #include <atalk/dsi.h>
24 #include <atalk/afp.h>
25 #include <atalk/compat.h>
26 #include <atalk/server_child.h>
27 #include <atalk/globals.h>
28
29 #ifdef HAVE_LDAP
30 #include <atalk/ldapconfig.h>
31 #endif
32
33 #include "afp_config.h"
34 #include "uam_auth.h"
35 #include "status.h"
36 #include "volume.h"
37 #include "afp_zeroconf.h"
38
39 /* get rid of unneeded configurations. i use reference counts to deal
40  * w/ multiple configs sharing the same afp_options. oh, to dream of
41  * garbage collection ... */
42 void configfree(AFPConfig *configs, const AFPConfig *config)
43 {
44     AFPConfig *p, *q;
45
46     for (p = configs; p; p = q) {
47         q = p->next;
48         if (p == config)
49             continue;
50
51         afp_options_free(&p->obj.options, p->defoptions);
52
53         switch (p->obj.proto) {
54         case AFPPROTO_DSI:
55             close(p->fd);
56             free(p->obj.dsi);
57             break;
58         }
59         free(p);
60     }
61
62     /* the master loaded the volumes for zeroconf, get rid of that */
63     unload_volumes_and_extmap();
64 }
65
66
67 static void dsi_cleanup(const AFPConfig *config)
68 {
69     return;
70 }
71
72 static afp_child_t *dsi_start(AFPConfig *config, AFPConfig *configs,
73                               server_child *server_children)
74 {
75     DSI *dsi = config->obj.dsi;
76     afp_child_t *child = NULL;
77
78     if (!(child = dsi_getsession(dsi,
79                                  server_children,
80                                  config->obj.options.tickleval))) {
81         LOG(log_error, logtype_afpd, "dsi_start: session error: %s", strerror(errno));
82         return NULL;
83     }
84
85     /* we've forked. */
86     if (parent_or_child == 1) {
87         configfree(configs, config);
88         config->obj.ipc_fd = child->ipc_fds[1];
89         close(child->ipc_fds[0]); /* Close parent IPC fd */
90         free(child);
91         afp_over_dsi(&config->obj); /* start a session */
92         exit (0);
93     }
94
95     return child;
96 }
97
98 static AFPConfig *DSIConfigInit(const struct afp_options *options,
99                                 unsigned char *refcount,
100                                 const dsi_proto protocol)
101 {
102     AFPConfig *config;
103     DSI *dsi;
104     char *p, *q;
105
106     if ((config = (AFPConfig *) calloc(1, sizeof(AFPConfig))) == NULL) {
107         LOG(log_error, logtype_afpd, "DSIConfigInit: malloc(config): %s", strerror(errno) );
108         return NULL;
109     }
110
111     LOG(log_debug, logtype_afpd, "DSIConfigInit: hostname: %s, ip/port: %s/%s, ",
112         options->hostname,
113         options->ipaddr ? options->ipaddr : "default",
114         options->port ? options->port : "548");
115
116     if ((dsi = dsi_init(protocol, "afpd", options->hostname,
117                         options->ipaddr, options->port,
118                         0, options->server_quantum)) == NULL) {
119         LOG(log_error, logtype_afpd, "main: dsi_init: %s", strerror(errno) );
120         free(config);
121         return NULL;
122     }
123     dsi->dsireadbuf = options->dsireadbuf;
124
125     LOG(log_note, logtype_afpd, "AFP/TCP started, advertising %s:%d (%s)",
126         getip_string((struct sockaddr *)&dsi->server), getip_port((struct sockaddr *)&dsi->server), VERSION);
127
128     config->dsi = dsi;
129
130     memcpy(&config->obj.options, options, sizeof(struct afp_options));
131     /* get rid of any appletalk info. we use the fact that the DSI
132      * stuff is done after the ASP stuff. */
133     p = config->obj.options.server;
134     if (p && (q = strchr(p, ':')))
135         *q = '\0';
136
137     return config;
138 }
139
140 /* allocate server configurations. this should really store the last
141  * entry in config->last or something like that. that would make
142  * supporting multiple dsi transports easier. */
143 static AFPConfig *AFPConfigInit(struct afp_options *options,
144                                 const struct afp_options *defoptions)
145 {
146     AFPConfig *next = NULL;
147     unsigned char *refcount;
148
149     if ((refcount = (unsigned char *)
150                     calloc(1, sizeof(unsigned char))) == NULL) {
151         LOG(log_error, logtype_afpd, "AFPConfigInit: calloc(refcount): %s", strerror(errno) );
152         return NULL;
153     }
154
155     /* set signature */
156     set_signature(options);
157
158     if ((next = DSIConfigInit(options, refcount, DSI_TCPIP)))
159         /* load in all the authentication modules. we can load the same
160            things multiple times if necessary. however, loading different
161            things with the same names will cause complaints. by not loading
162            in any uams with proxies, we prevent ddp connections from succeeding.
163         */
164         auth_load(options->uampath, options->uamlist);
165
166     /* this should be able to accept multiple dsi transports. i think
167      * the only thing that gets affected is the net addresses. */
168     status_init(next, options);
169
170     return next;
171 }
172
173 /*!
174  * Get everything running
175  */
176 int configinit(AFPObj *AFPObj)
177 {
178     AFPConfigInit(AFPObj);
179
180 #ifdef HAVE_LDAP
181     /* Parse afp_ldap.conf */
182     acl_ldap_readconfig(AFPObj->iniconfig);
183 #endif /* HAVE_LDAP */
184
185     /* Now register with zeroconf, we also need the volumes for that */
186     if (! (AFPObj->options.flags & OPTION_NOZEROCONF)) {
187         load_volumes(AFPObj);
188         zeroconf_register(AFPObj);
189     }
190
191     return first;
192 }