]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/afp_options.c
Sam Noble's ADMIN_GRP patch, removed Marc's old ADMIN_GRP patch.
[netatalk.git] / etc / afpd / afp_options.c
1 /* 
2  * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu)
3  * Copyright (c) 1990,1993 Regents of The University of Michigan.
4  * All Rights Reserved.  See COPYRIGHT.
5  *
6  * modified from main.c. this handles afp options.
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include "config.h"
11 #endif
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <ctype.h>
17 #include <unistd.h>
18 #include <sys/param.h>
19 #include <sys/socket.h>
20 #include <syslog.h>
21
22 #include <netinet/in.h>
23 #include <arpa/inet.h>
24 #include <netdb.h>
25
26 #include <atalk/paths.h>
27 #include "globals.h"
28 #include "status.h"
29 #include "auth.h"
30
31 #include <atalk/compat.h>
32
33 #ifdef ADMIN_GRP
34 #include <grp.h>
35 #include <sys/types.h>
36 #endif
37
38 #ifndef MIN
39 #define MIN(a, b)  ((a) < (b) ? (a) : (b))
40 #endif
41
42 #define OPTIONS "dn:f:s:uc:g:P:ptDS:TL:F:U:I"
43 #define LENGTH 512
44
45 /* return an option. this uses an internal array, so it's necessary
46  * to duplicate it if you want to hold it for long. this is probably
47  * non-optimal. */
48 static char *getoption(char *buf, const char *option)
49 {
50   static char string[LENGTH + 1];
51   char *end;
52   int len;
53
54   if (option && (buf = strstr(buf, option)))
55     buf = strpbrk(buf, " \t");
56
57   while (buf && isspace(*buf))
58     buf++;
59       
60   if (!buf)
61     return NULL;
62
63   /* search for any quoted stuff */
64   if (*buf == '"' && (end = strchr(buf + 1, '"'))) { 
65     buf++;
66     len = MIN(end - buf, LENGTH);
67   } else if ((end = strpbrk(buf, " \t\n"))) /* option or eoln */
68     len = MIN(end - buf, LENGTH);
69   else
70     len = MIN(strlen(buf), LENGTH);
71   
72   strncpy(string, buf, len);
73   string[len] = '\0';
74   return string;
75 }
76
77 /* get rid of any allocated afp_option buffers. */
78 void afp_options_free(struct afp_options *opt, 
79                       const struct afp_options *save)
80 {
81   if (opt->defaultvol && (opt->defaultvol != save->defaultvol))
82     free(opt->defaultvol);
83   if (opt->systemvol && (opt->systemvol != save->systemvol))
84     free(opt->systemvol);
85   if (opt->loginmesg && (opt->loginmesg != save->loginmesg))
86     free(opt->loginmesg);
87   if (opt->guest && (opt->guest != save->guest)) 
88     free(opt->guest);
89   if (opt->server && (opt->server != save->server))
90     free(opt->server);
91   if (opt->ipaddr && (opt->ipaddr != save->ipaddr))
92     free(opt->ipaddr);
93   if (opt->fqdn && (opt->fqdn != save->fqdn))
94     free(opt->fqdn);
95   if (opt->uampath && (opt->uampath != save->uampath))
96     free(opt->uampath);
97   if (opt->uamlist && (opt->uamlist != save->uamlist))
98     free(opt->uamlist);
99   if (opt->nlspath && (opt->nlspath != save->nlspath))
100     free(opt->nlspath);
101   if (opt->passwdfile && (opt->passwdfile != save->passwdfile))
102     free(opt->passwdfile);
103 }
104
105 /* initialize options */
106 void afp_options_init(struct afp_options *options)
107 {
108   memset(options, 0, sizeof(struct afp_options));
109   options->connections = 20;
110   options->pidfile = _PATH_AFPDLOCK;
111   options->defaultvol = _PATH_AFPDDEFVOL;
112   options->systemvol = _PATH_AFPDSYSVOL;
113   options->configfile = _PATH_AFPDCONF;
114   options->nlspath = _PATH_AFPDNLSPATH;
115   options->uampath = _PATH_AFPDUAMPATH;
116   options->uamlist = "uams_guest.so,uams_clrtxt.so,uams_dhx.so";
117   options->guest = "nobody";
118   options->loginmesg = "";
119   options->transports = AFPTRANS_ALL;
120   options->passwdfile = _PATH_AFPDPWFILE;
121   options->tickleval = 30;
122 #ifdef ADMIN_GRP
123   options->admingid = 0;
124 #endif ADMIN_GRP
125 }
126
127 /* parse an afpd.conf line. i'm doing it this way because it's
128  * easy. it is, however, massively hokey. sample afpd.conf:
129  * server:AFPServer@zone -loginmesg "blah blah blah" -nodsi 
130  * "private machine"@zone2 -noguest -port 11012
131  * server2 -nocleartxt -nodsi
132  *
133  * NOTE: this ignores unknown options 
134  */
135 int afp_options_parseline(char *buf, struct afp_options *options)
136 {
137   char *c, *opt;
138   
139   /* handle server */
140   if (*buf != '-' && (c = getoption(buf, NULL)) && (opt = strdup(c)))
141     options->server = opt;
142
143   /* parse toggles */
144   if (strstr(buf, " -nodebug"))
145     options->flags &= ~OPTION_DEBUG;
146
147   if (strstr(buf, " -nouservolfirst"))
148     options->flags &= ~OPTION_USERVOLFIRST;
149   if (strstr(buf, " -uservolfirst"))
150     options->flags |= OPTION_USERVOLFIRST;
151   if (strstr(buf, " -nouservol"))
152     options->flags |= OPTION_NOUSERVOL;
153   if (strstr(buf, " -uservol"))
154     options->flags &= ~OPTION_NOUSERVOL;
155   if (strstr(buf, " -proxy"))
156     options->flags |= OPTION_PROXY;
157   if (strstr(buf, " -noicon"))
158     options->flags &= ~OPTION_CUSTOMICON;
159   if (strstr(buf, " -icon"))
160     options->flags |= OPTION_CUSTOMICON;
161
162   /* passwd bits */
163   if (strstr(buf, " -nosavepassword"))
164     options->passwdbits |= PASSWD_NOSAVE;
165   if (strstr(buf, " -savepassword"))
166     options->passwdbits &= ~PASSWD_NOSAVE;
167   if (strstr(buf, " -nosetpassword"))
168     options->passwdbits &= ~PASSWD_SET;
169   if (strstr(buf, " -setpassword"))
170     options->passwdbits |= PASSWD_SET;
171   
172   /* transports */
173   if (strstr(buf, " -transall"))
174     options->transports = AFPTRANS_ALL;
175   if (strstr(buf, " -notransall"))
176     options->transports = AFPTRANS_NONE;
177   if (strstr(buf, " -tcp"))
178     options->transports |= AFPTRANS_TCP;
179   if (strstr(buf, " -notcp"))
180     options->transports &= ~AFPTRANS_TCP;
181   if (strstr(buf, " -ddp"))
182     options->transports |= AFPTRANS_DDP;
183   if (strstr(buf, " -noddp"))
184     options->transports &= ~AFPTRANS_DDP;
185
186   /* figure out options w/ values. currently, this will ignore the setting
187    * if memory is lacking. */
188   if ((c = getoption(buf, "-defaultvol")) && (opt = strdup(c)))
189     options->defaultvol = opt;
190   if ((c = getoption(buf, "-systemvol")) && (opt = strdup(c)))
191     options->systemvol = opt;
192   if ((c = getoption(buf, "-loginmesg")) && (opt = strdup(c)))
193     options->loginmesg = opt;
194   if ((c = getoption(buf, "-guestname")) && (opt = strdup(c)))
195     options->guest = opt;
196   if ((c = getoption(buf, "-passwdfile")) && (opt = strdup(c)))
197     options->passwdfile = opt;
198   if ((c = getoption(buf, "-passwdminlen")))
199     options->passwdminlen = MIN(1, atoi(c));
200   if ((c = getoption(buf, "-loginmaxfail")))
201     options->loginmaxfail = atoi(c);
202   if ((c = getoption(buf, "-tickleval")))
203     options->tickleval = atoi(c);
204
205   if (c = getoption(buf, "-server_quantum"))
206     options->server_quantum = strtoul(c, NULL, 0);
207
208
209 #ifdef ADMIN_GRP
210   if ((c = getoption(buf, "-admingroup"))) {
211     struct group *gr = getgrnam(c);
212     if (gr != NULL) { 
213       options->admingid = gr->gr_gid;
214     }
215   } 
216 #endif
217   if ((c = getoption(buf, "-uampath")) && (opt = strdup(c)))
218     options->uampath = opt;
219   if ((c = getoption(buf, "-uamlist")) && (opt = strdup(c)))
220     options->uamlist = opt;
221   if ((c = getoption(buf, "-nlspath")) && (opt = strdup(c)))
222     options->nlspath = opt;
223
224   if (c = getoption(buf, "-ipaddr")) {
225     struct in_addr inaddr;
226     if (inet_aton(c, &inaddr) && (opt = strdup(c))) { 
227       if (!gethostbyaddr((const char *) &inaddr, sizeof(inaddr), AF_INET)) 
228         syslog(LOG_INFO, "WARNING: can't find %s\n", opt);
229       options->ipaddr = opt;
230     }
231   }
232
233   if ((c = getoption(buf, "-port")))
234     options->port = atoi(c);
235   if (c = getoption(buf, "-ddpaddr"))
236     atalk_aton(c, &options->ddpaddr);
237
238   /* do a little checking for the domain name. */
239   if (c = getoption(buf, "-fqdn")) {
240     char *p = strchr(c, ':');
241     if (p)
242       *p = '\0';
243     if (gethostbyname(c)) {
244       if (p)
245         *p = ':';
246       if (opt = strdup(c))
247         options->fqdn = opt;
248     }
249   }
250
251   return 1;
252 }
253
254 int afp_options_parse(int ac, char **av, struct afp_options *options)
255 {
256   extern char *optarg;
257   extern int optind;
258   
259   char *p;
260   int c, err = 0;
261
262   if (gethostname(options->hostname, sizeof(options->hostname )) < 0 ) {
263     perror( "gethostname" );
264     return 0;
265   }
266     if (( p = strchr(options->hostname, '.' )) != 0 ) {
267         *p = '\0';
268     }
269
270     if (( p = strrchr( av[ 0 ], '/' )) == NULL ) {
271         p = av[ 0 ];
272     } else {
273         p++;
274     }
275
276     while (( c = getopt( ac, av, OPTIONS )) != EOF ) {
277         switch ( c ) {
278         case 'd' :
279             options->flags |= OPTION_DEBUG;
280             break;
281         case 'n' :
282             options->server = optarg;
283             break;
284         case 'f' :
285             options->defaultvol = optarg;
286             break;
287         case 's' :
288             options->systemvol = optarg;
289             break;
290         case 'u' :
291             options->flags |= OPTION_USERVOLFIRST;
292             break;
293         case 'c' :
294             options->connections = atoi( optarg );
295             break;
296         case 'g' :
297             options->guest = optarg;
298             break;
299
300         case 'P' :
301             options->pidfile = optarg;
302             break;
303
304         case 'p':
305             options->passwdbits |= PASSWD_NOSAVE;
306             break;
307         case 't':
308             options->passwdbits |= PASSWD_SET;
309             break;
310
311         case 'D':
312             options->transports &= ~AFPTRANS_DDP;
313             break;
314         case 'S':
315             options->port = atoi(optarg);
316             break;
317         case 'T':
318             options->transports &= ~AFPTRANS_TCP;
319             break;
320         case 'L':
321             options->loginmesg = optarg;
322             break;
323         case 'F':
324             options->configfile = optarg;
325             break;
326         case 'U':
327             options->uamlist = optarg;
328             break;
329         case 'I':
330             options->flags |= OPTION_CUSTOMICON;
331         default :
332             err++;
333         }
334     }
335     if ( err || optind != ac ) {
336         fprintf( stderr,
337                 "Usage:\t%s [ -dpDTIt ] [ -n nbpname ] [ -f defvols ] \
338 [ -P pidfile ] [ -s sysvols ] \n", p );
339         fprintf( stderr,
340                 "\t[ -u ] [ -c maxconn ] [ -g guest ] \
341 [ -S port ] [ -L loginmesg ] [ -F configfile ] [ -U uamlist ]\n" );
342         return 0;
343     }
344
345 #ifdef ultrix
346     openlog( p, LOG_PID );
347 #else ultrix
348     openlog( p, LOG_NDELAY|LOG_PID, LOG_LOCAL0 );
349 #endif ultrix
350
351     return 1;
352 }