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 /* HAVE_CONFIG_H */ 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 <atalk/logger.h> 21 22#include <netinet/in.h> 23#include <arpa/inet.h> 24 25#ifdef HAVE_NETDB_H 26#include <netdb.h> 27#endif /* HAVE_NETDB_H */ 28 29#ifdef ADMIN_GRP 30#include <grp.h> 31#include <sys/types.h> 32#endif /* ADMIN_GRP */ 33 34#include <atalk/paths.h> 35#include <atalk/util.h> 36#include <atalk/compat.h> 37#include <atalk/globals.h> 38#include <atalk/fce_api.h> 39 40#include "status.h" 41#include "auth.h" 42#include "dircache.h" 43 44#ifndef MIN 45#define MIN(a, b) ((a) < (b) ? (a) : (b)) 46#endif /* MIN */ 47 48/* FIXME CNID */ 49const char *Cnid_srv = "localhost"; 50const char *Cnid_port = "4700"; 51 52#define OPTIONS "dn:f:s:uc:g:P:ptDS:TL:F:U:hIvVm:" 53#define LENGTH 512 54 55/* return an option. this uses an internal array, so it's necessary 56 * to duplicate it if you want to hold it for long. this is probably 57 * non-optimal. */ 58static char *getoption(char *buf, const char *option) 59{ 60 static char string[LENGTH + 1]; 61 char *end; 62 int len; 63 64 if (option && (buf = strstr(buf, option))) 65 buf = strpbrk(buf, " \t"); 66 67 while (buf && isspace(*buf)) 68 buf++; 69 70 if (!buf) 71 return NULL; 72 73 /* search for any quoted stuff */ 74 if (*buf == '"' && (end = strchr(buf + 1, '"'))) { 75 buf++; 76 len = MIN(end - buf, LENGTH); 77 } else if ((end = strpbrk(buf, " \t\n"))) /* option or eoln */ 78 len = MIN(end - buf, LENGTH); 79 else 80 len = MIN(strlen(buf), LENGTH); 81 82 strncpy(string, buf, len); 83 string[len] = '\0'; 84 return string; 85} 86 87/* get rid of any allocated afp_option buffers. */ 88void afp_options_free(struct afp_options *opt, 89 const struct afp_options *save) 90{ 91 if (opt->defaultvol.name && (opt->defaultvol.name != save->defaultvol.name)) 92 free(opt->defaultvol.name); 93 if (opt->defaultvol.full_name && (opt->defaultvol.full_name != save->defaultvol.full_name)) 94 free(opt->defaultvol.full_name); 95 96 if (opt->systemvol.name && (opt->systemvol.name != save->systemvol.name)) 97 free(opt->systemvol.name); 98 if (opt->systemvol.full_name && (opt->systemvol.full_name != save->systemvol.full_name)) 99 free(opt->systemvol.full_name); 100 101 if (opt->uservol.name && (opt->uservol.name != save->uservol.name)) 102 free(opt->uservol.name); 103 if (opt->uservol.full_name && (opt->uservol.full_name != save->uservol.full_name)) 104 free(opt->uservol.full_name); 105 106 if (opt->loginmesg && (opt->loginmesg != save->loginmesg)) 107 free(opt->loginmesg); 108 if (opt->guest && (opt->guest != save->guest)) 109 free(opt->guest); 110 if (opt->server && (opt->server != save->server)) 111 free(opt->server); 112 if (opt->ipaddr && (opt->ipaddr != save->ipaddr)) 113 free(opt->ipaddr); 114 if (opt->port && (opt->port != save->port)) 115 free(opt->port); 116 if (opt->fqdn && (opt->fqdn != save->fqdn)) 117 free(opt->fqdn); 118 if (opt->uampath && (opt->uampath != save->uampath)) 119 free(opt->uampath); 120 if (opt->uamlist && (opt->uamlist != save->uamlist)) 121 free(opt->uamlist); 122 if (opt->passwdfile && (opt->passwdfile != save->passwdfile)) 123 free(opt->passwdfile); 124 if (opt->signatureopt && (opt->signatureopt != save->signatureopt)) 125 free(opt->signatureopt); 126 if (opt->k5service && (opt->k5service != save->k5service)) 127 free(opt->k5service); 128 if (opt->k5realm && (opt->k5realm != save->k5realm)) 129 free(opt->k5realm); 130 if (opt->k5keytab && (opt->k5keytab != save->k5keytab)) 131 free(opt->k5keytab); 132 if (opt->unixcodepage && (opt->unixcodepage != save->unixcodepage)) 133 free(opt->unixcodepage); 134 if (opt->maccodepage && (opt->maccodepage != save->maccodepage)) 135 free(opt->maccodepage); 136 137 if (opt->ntdomain && (opt->ntdomain != save->ntdomain)) 138 free(opt->ntdomain); 139 if (opt->ntseparator && (opt->ntseparator != save->ntseparator)) 140 free(opt->ntseparator); 141 if (opt->logconfig && (opt->logconfig != save->logconfig)) 142 free(opt->logconfig); 143 if (opt->mimicmodel && (opt->mimicmodel != save->mimicmodel)) 144 free(opt->mimicmodel); 145 if (opt->adminauthuser && (opt->adminauthuser != save->adminauthuser)) 146 free(opt->adminauthuser); 147} 148 149/* initialize options */ 150void afp_options_init(struct afp_options *options) 151{ 152 memset(options, 0, sizeof(struct afp_options)); 153 options->connections = 20; 154 options->pidfile = _PATH_AFPDLOCK; 155 options->defaultvol.name = _PATH_AFPDDEFVOL; 156 options->systemvol.name = _PATH_AFPDSYSVOL; 157 options->configfile = _PATH_AFPDCONF; 158 options->sigconffile = _PATH_AFPDSIGCONF; 159 options->uuidconf = _PATH_AFPDUUIDCONF; 160 options->uampath = _PATH_AFPDUAMPATH; 161 options->uamlist = "uams_dhx.so,uams_dhx2.so"; 162 options->guest = "nobody"; 163 options->loginmesg = ""; 164 options->transports = AFPTRANS_TCP; /* TCP only */ 165 options->passwdfile = _PATH_AFPDPWFILE; 166 options->tickleval = 30; 167 options->timeout = 4; /* 4 tickles = 2 minutes */ 168 options->sleep = 10 * 60 * 2; /* 10 h in 30 seconds tick */ 169 options->disconnected = 10 * 60 * 2; /* 10 h in 30 seconds tick */ 170 options->server_notif = 1; 171 options->authprintdir = NULL; 172 options->signatureopt = "auto"; 173 options->umask = 0; 174#ifdef ADMIN_GRP 175 options->admingid = 0; 176#endif /* ADMIN_GRP */ 177 options->k5service = NULL; 178 options->k5realm = NULL; 179 options->k5keytab = NULL; 180 options->unixcharset = CH_UNIX; 181 options->unixcodepage = "LOCALE"; 182 options->maccharset = CH_MAC; 183 options->maccodepage = "MAC_ROMAN"; 184 options->volnamelen = 80; /* spec: 255, 10.1: 73, 10.4/10.5: 80 */ 185 options->ntdomain = NULL; 186 options->ntseparator = NULL; 187#ifdef USE_SRVLOC 188 /* don't advertize slp by default */ 189 options->flags |= OPTION_NOSLP; 190#endif 191 options->dircachesize = DEFAULT_MAX_DIRCACHE_SIZE; 192 options->flags |= OPTION_ACL2MACCESS; 193 options->flags |= OPTION_UUID; 194 options->tcp_sndbuf = 0; /* 0 means don't change OS default */ 195 options->tcp_rcvbuf = 0; /* 0 means don't change OS default */ 196 options->dsireadbuf = 12; 197 options->mimicmodel = NULL; 198 options->fce_fmodwait = 60; /* put fmod events 60 seconds on hold */ 199 options->adminauthuser = NULL; 200} 201 202/* parse an afpd.conf line. i'm doing it this way because it's 203 * easy. it is, however, massively hokey. sample afpd.conf: 204 * server:AFPServer@zone -loginmesg "blah blah blah" -nodsi 205 * "private machine"@zone2 -noguest -port 11012 206 * server2 -nocleartxt -nodsi 207 * 208 * NOTE: this ignores unknown options 209 */ 210int afp_options_parseline(char *buf, struct afp_options *options) 211{ 212 char *c, *opt; 213 214 /* handle server */ 215 if (*buf != '-' && (c = getoption(buf, NULL)) && (opt = strdup(c))) 216 options->server = opt; 217 218 /* parse toggles */ 219 if (strstr(buf, " -nodebug")) 220 options->flags &= ~OPTION_DEBUG; 221#ifdef USE_SRVLOC 222 if (strstr(buf, " -slp")) 223 options->flags &= ~OPTION_NOSLP; 224#endif 225#ifdef USE_ZEROCONF 226 if (strstr(buf, " -nozeroconf")) 227 options->flags |= OPTION_NOZEROCONF; 228#endif 229 if (strstr(buf, " -nouservolfirst")) 230 options->flags &= ~OPTION_USERVOLFIRST; 231 if (strstr(buf, " -uservolfirst")) 232 options->flags |= OPTION_USERVOLFIRST; 233 if (strstr(buf, " -nouservol")) 234 options->flags |= OPTION_NOUSERVOL; 235 if (strstr(buf, " -uservol")) 236 options->flags &= ~OPTION_NOUSERVOL; 237 if (strstr(buf, " -proxy")) 238 options->flags |= OPTION_PROXY; 239 if (strstr(buf, " -noicon")) 240 options->flags &= ~OPTION_CUSTOMICON; 241 if (strstr(buf, " -icon")) 242 options->flags |= OPTION_CUSTOMICON; 243 if (strstr(buf, " -advertise_ssh")) 244 options->flags |= OPTION_ANNOUNCESSH; 245 if (strstr(buf, " -noacl2maccess")) 246 options->flags &= ~OPTION_ACL2MACCESS; 247 if (strstr(buf, " -keepsessions")) { 248 default_options.flags |= OPTION_KEEPSESSIONS; 249 options->flags |= OPTION_KEEPSESSIONS; 250 } 251 252 /* passwd bits */ 253 if (strstr(buf, " -nosavepassword")) 254 options->passwdbits |= PASSWD_NOSAVE; 255 if (strstr(buf, " -savepassword")) 256 options->passwdbits &= ~PASSWD_NOSAVE; 257 if (strstr(buf, " -nosetpassword")) 258 options->passwdbits &= ~PASSWD_SET; 259 if (strstr(buf, " -setpassword")) 260 options->passwdbits |= PASSWD_SET; 261 262 /* transports */ 263 if (strstr(buf, " -transall")) 264 options->transports = AFPTRANS_ALL; 265 if (strstr(buf, " -notransall")) 266 options->transports = AFPTRANS_NONE; 267 if (strstr(buf, " -tcp")) 268 options->transports |= AFPTRANS_TCP; 269 if (strstr(buf, " -notcp")) 270 options->transports &= ~AFPTRANS_TCP; 271 if (strstr(buf, " -ddp")) 272 options->transports |= AFPTRANS_DDP; 273 if (strstr(buf, " -noddp")) 274 options->transports &= ~AFPTRANS_DDP; 275 if (strstr(buf, "-client_polling")) 276 options->server_notif = 0; 277 278 /* figure out options w/ values. currently, this will ignore the setting 279 * if memory is lacking. */ 280 281 if ((c = getoption(buf, "-hostname"))) { 282 int len = strlen (c); 283 if (len <= MAXHOSTNAMELEN) { 284 memcpy(options->hostname, c, len); 285 options->hostname[len] = 0; 286 } 287 else 288 LOG(log_info, logtype_afpd, "WARNING: hostname %s is too long (%d)",c,len); 289 } 290 291 if ((c = getoption(buf, "-defaultvol")) && (opt = strdup(c))) 292 options->defaultvol.name = opt; 293 if ((c = getoption(buf, "-systemvol")) && (opt = strdup(c))) 294 options->systemvol.name = opt; 295 if ((c = getoption(buf, "-loginmesg")) && (opt = strdup(c))) { 296 int i = 0, j = 0; 297 while (c[i]) { 298 if (c[i] != '\\') { 299 opt[j++] = c[i]; 300 } else { 301 i++; 302 if (c[i] == 'n') 303 opt[j++] = '\n'; 304 } 305 i++; 306 } 307 opt[j] = 0; 308 options->loginmesg = opt; 309 310 } 311 if ((c = getoption(buf, "-guestname")) && (opt = strdup(c))) 312 options->guest = opt; 313 if ((c = getoption(buf, "-passwdfile")) && (opt = strdup(c))) 314 options->passwdfile = opt; 315 if ((c = getoption(buf, "-passwdminlen"))) 316 options->passwdminlen = MIN(1, atoi(c)); 317 if ((c = getoption(buf, "-loginmaxfail"))) 318 options->loginmaxfail = atoi(c); 319 if ((c = getoption(buf, "-tickleval"))) { 320 options->tickleval = atoi(c); 321 if (options->tickleval <= 0) { 322 options->tickleval = 30; 323 } 324 } 325 if ((c = getoption(buf, "-timeout"))) { 326 options->timeout = atoi(c); 327 if (options->timeout <= 0) { 328 options->timeout = 4; 329 } 330 } 331 332 if ((c = getoption(buf, "-sleep"))) { 333 options->disconnected = options->sleep = atoi(c) * 120; 334 if (options->sleep <= 4) { 335 options->disconnected = options->sleep = 4; 336 } 337 } 338 339 if ((c = getoption(buf, "-dsireadbuf"))) { 340 options->dsireadbuf = atoi(c); 341 if (options->dsireadbuf < 6) 342 options->dsireadbuf = 6; 343 } 344 345 if ((c = getoption(buf, "-server_quantum"))) 346 options->server_quantum = strtoul(c, NULL, 0); 347 348 if ((c = getoption(buf, "-volnamelen"))) { 349 options->volnamelen = atoi(c); 350 if (options->volnamelen < 8) { 351 options->volnamelen = 8; /* max mangled volname "???#FFFF" */ 352 } 353 if (options->volnamelen > 255) { 354 options->volnamelen = 255; /* AFP3 spec */ 355 } 356 } 357 358 /* -[no]setuplog <logtype> <loglevel> [<filename>]*/ 359 c = buf; 360 /* Now THIS is hokey! Multiple occurrences are not supported by our current code, */ 361 /* so I have to loop myself. */ 362 while (NULL != (c = strstr(c, "-setuplog"))) { 363 char *optstr; 364 if ((optstr = getoption(c, "-setuplog"))) { 365 /* hokey2: options->logconfig must be converted to store an array of logstrings */ 366 if (options->logconfig) 367 free(options->logconfig); 368 options->logconfig = strdup(optstr); 369 setuplog(optstr); 370 c += sizeof("-setuplog"); 371 } 372 } 373 374 if ((c = getoption(buf, "-unsetuplog"))) 375 unsetuplog(c); 376 377#ifdef ADMIN_GRP 378 if ((c = getoption(buf, "-admingroup"))) { 379 struct group *gr = getgrnam(c); 380 if (gr != NULL) { 381 options->admingid = gr->gr_gid; 382 } 383 } 384#endif /* ADMIN_GRP */ 385 386 if ((c = getoption(buf, "-k5service")) && (opt = strdup(c))) 387 options->k5service = opt; 388 if ((c = getoption(buf, "-k5realm")) && (opt = strdup(c))) 389 options->k5realm = opt; 390 if ((c = getoption(buf, "-k5keytab"))) { 391 if ( NULL == (options->k5keytab = (char *) malloc(sizeof(char)*(strlen(c)+14)) )) { 392 LOG(log_error, logtype_afpd, "malloc failed"); 393 exit(-1); 394 } 395 snprintf(options->k5keytab, strlen(c)+14, "KRB5_KTNAME=%s", c); 396 putenv(options->k5keytab); 397 /* setenv( "KRB5_KTNAME", c, 1 ); */ 398 } 399 if ((c = getoption(buf, "-authprintdir")) && (opt = strdup(c))) 400 options->authprintdir = opt; 401 if ((c = getoption(buf, "-uampath")) && (opt = strdup(c))) 402 options->uampath = opt; 403 if ((c = getoption(buf, "-uamlist")) && (opt = strdup(c))) 404 options->uamlist = opt; 405 406 if ((c = getoption(buf, "-ipaddr"))) { 407#if 0 408 struct in_addr inaddr; 409 if (inet_aton(c, &inaddr) && (opt = strdup(c))) { 410 if (!gethostbyaddr((const char *) &inaddr, sizeof(inaddr), AF_INET)) 411 LOG(log_info, logtype_afpd, "WARNING: can't find %s", opt); 412 options->ipaddr = opt; 413 } 414 else { 415 LOG(log_error, logtype_afpd, "Error parsing -ipaddr, is %s in numbers-and-dots notation?", c); 416 } 417#endif 418 options->ipaddr = strdup(c); 419 } 420 421 /* FIXME CNID Cnid_srv is a server attribute */ 422 if ((c = getoption(buf, "-cnidserver"))) { 423 char *p = strrchr(c, ':'); 424 if (p) 425 *p = 0; 426 Cnid_srv = strdup(c); 427 if (p) 428 Cnid_port = strdup(p + 1); 429 LOG(log_debug, logtype_afpd, "CNID Server: %s:%s", Cnid_srv, Cnid_port); 430 } 431 432 if ((c = getoption(buf, "-port"))) 433 options->port = strdup(c); 434#ifndef NO_DDP 435 if ((c = getoption(buf, "-ddpaddr"))) 436 atalk_aton(c, &options->ddpaddr); 437#endif 438 if ((c = getoption(buf, "-signature")) && (opt = strdup(c))) 439 options->signatureopt = opt; 440 441 /* do a little checking for the domain name. */ 442 if ((c = getoption(buf, "-fqdn"))) { 443 char *p = strchr(c, ':'); 444 if (p) 445 *p = '\0'; 446 if (gethostbyname(c)) { 447 if (p) 448 *p = ':'; 449 if ((opt = strdup(c))) 450 options->fqdn = opt; 451 } 452 else { 453 LOG(log_error, logtype_afpd, "error parsing -fqdn, gethostbyname failed for: %s", c); 454 } 455 } 456 457 if ((c = getoption(buf, "-unixcodepage"))) { 458 if ((charset_t)-1 == ( options->unixcharset = add_charset(c)) ) { 459 options->unixcharset = CH_UNIX; 460 LOG(log_warning, logtype_afpd, "setting Unix codepage to '%s' failed", c); 461 } 462 else { 463 if ((opt = strdup(c))) 464 options->unixcodepage = opt; 465 } 466 } 467 468 if ((c = getoption(buf, "-maccodepage"))) { 469 if ((charset_t)-1 == ( options->maccharset = add_charset(c)) ) { 470 options->maccharset = CH_MAC; 471 LOG(log_warning, logtype_afpd, "setting Mac codepage to '%s' failed", c); 472 } 473 else { 474 if ((opt = strdup(c))) 475 options->maccodepage = opt; 476 } 477 } 478 479 if ((c = strstr(buf, "-closevol"))) { 480 options->closevol= 1; 481 } 482 483 if ((c = getoption(buf, "-ntdomain")) && (opt = strdup(c))) 484 options->ntdomain = opt; 485 486 if ((c = getoption(buf, "-ntseparator")) && (opt = strdup(c))) 487 options->ntseparator = opt; 488 489 if ((c = getoption(buf, "-dircachesize"))) 490 options->dircachesize = atoi(c); 491 492 if ((c = getoption(buf, "-tcpsndbuf"))) 493 options->tcp_sndbuf = atoi(c); 494 495 if ((c = getoption(buf, "-tcprcvbuf"))) 496 options->tcp_rcvbuf = atoi(c); 497 498 if ((c = getoption(buf, "-fcelistener"))) { 499 LOG(log_note, logtype_afpd, "Adding fce listener \"%s\"", c); 500 fce_add_udp_socket(c); 501 } 502 if ((c = getoption(buf, "-fcecoalesce"))) { 503 LOG(log_note, logtype_afpd, "Fce coalesce: %s", c); 504 fce_set_coalesce(c); 505 } 506 if ((c = getoption(buf, "-fceevents"))) { 507 LOG(log_note, logtype_afpd, "Fce events: %s", c); 508 fce_set_events(c); 509 } 510 511 if ((c = getoption(buf, "-fceholdfmod"))) 512 options->fce_fmodwait = atoi(c); 513 514 if ((c = getoption(buf, "-mimicmodel")) && (opt = strdup(c))) 515 options->mimicmodel = opt; 516 517 if ((c = getoption(buf, "-adminauthuser")) && (opt = strdup(c))) 518 options->adminauthuser = opt; 519 520 return 1; 521} 522 523/* 524 * Show version information about afpd. 525 * Used by "afp -v". 526 */ 527static void show_version( void ) 528{ 529 int num, i; 530 531 printf( "afpd %s - Apple Filing Protocol (AFP) daemon of Netatalk\n\n", VERSION ); 532 533 puts( "This program is free software; you can redistribute it and/or modify it under" ); 534 puts( "the terms of the GNU General Public License as published by the Free Software" ); 535 puts( "Foundation; either version 2 of the License, or (at your option) any later" ); 536 puts( "version. Please see the file COPYING for further information and details.\n" ); 537 538 puts( "afpd has been compiled with support for these features:\n" ); 539 540 num = sizeof( afp_versions ) / sizeof( afp_versions[ 0 ] ); 541 printf( " AFP versions:\t" ); 542 for ( i = 0; i < num; i++ ) { 543 printf( "%d.%d ", afp_versions[ i ].av_number/10, afp_versions[ i ].av_number%10); 544 } 545 puts( "" ); 546 547 printf( "DDP(AppleTalk) Support:\t" ); 548#ifdef NO_DDP 549 puts( "No" ); 550#else 551 puts( "Yes" ); 552#endif 553 554 printf( " CNID backends:\t" ); 555#ifdef CNID_BACKEND_CDB 556 printf( "cdb "); 557#endif 558#ifdef CNID_BACKEND_DB3 559 printf( "db3 " ); 560#endif 561#ifdef CNID_BACKEND_DBD 562#ifdef CNID_BACKEND_DBD_TXN 563 printf( "dbd-txn " ); 564#else 565 printf( "dbd " ); 566#endif 567#endif 568#ifdef CNID_BACKEND_HASH 569 printf( "hash " ); 570#endif 571#ifdef CNID_BACKEND_LAST 572 printf( "last " ); 573#endif 574#ifdef CNID_BACKEND_MTAB 575 printf( "mtab " ); 576#endif 577#ifdef CNID_BACKEND_TDB 578 printf( "tdb " ); 579#endif 580 puts( "" ); 581} 582 583/* 584 * Show extended version information about afpd and Netatalk. 585 * Used by "afp -V". 586 */ 587static void show_version_extended(void ) 588{ 589 show_version( ); 590 591 printf( " SLP support:\t" ); 592#ifdef USE_SRVLOC 593 puts( "Yes" ); 594#else 595 puts( "No" ); 596#endif 597 598 printf( " Zeroconf support:\t" ); 599#if defined (HAVE_MDNS) 600 puts( "mDNSResponder" ); 601#elif defined (HAVE_AVAHI) 602 puts( "Avahi" ); 603#else 604 puts( "No" ); 605#endif 606 607 printf( " TCP wrappers support:\t" ); 608#ifdef TCPWRAP 609 puts( "Yes" ); 610#else 611 puts( "No" ); 612#endif 613 614 printf( " Quota support:\t" ); 615#ifndef NO_QUOTA_SUPPORT 616 puts( "Yes" ); 617#else 618 puts( "No" ); 619#endif 620 621 printf( " Admin group support:\t" ); 622#ifdef ADMIN_GRP 623 puts( "Yes" ); 624#else 625 puts( "No" ); 626#endif 627 628 printf( " Valid shell checks:\t" ); 629#ifndef DISABLE_SHELLCHECK 630 puts( "Yes" ); 631#else 632 puts( "No" ); 633#endif 634 635 printf( " cracklib support:\t" ); 636#ifdef USE_CRACKLIB 637 puts( "Yes" ); 638#else 639 puts( "No" ); 640#endif 641 642 printf( " Dropbox kludge:\t" ); 643#ifdef DROPKLUDGE 644 puts( "Yes" ); 645#else 646 puts( "No" ); 647#endif 648 649 printf( " Force volume uid/gid:\t" ); 650#ifdef FORCE_UIDGID 651 puts( "Yes" ); 652#else 653 puts( "No" ); 654#endif 655 656 printf( " EA support:\t" ); 657 puts( EA_MODULES ); 658 659 printf( " ACL support:\t" ); 660#ifdef HAVE_ACLS 661 puts( "Yes" ); 662#else 663 puts( "No" ); 664#endif 665 666 printf( " LDAP support:\t" ); 667#ifdef HAVE_LDAP 668 puts( "Yes" ); 669#else 670 puts( "No" ); 671#endif 672} 673 674/* 675 * Display compiled-in default paths 676 */ 677static void show_paths( void ) 678{ 679 printf( " afpd.conf:\t%s\n", _PATH_AFPDCONF ); 680 printf( " AppleVolumes.system:\t%s\n", _PATH_AFPDSYSVOL ); 681 printf( " AppleVolumes.default:\t%s\n", _PATH_AFPDDEFVOL ); 682 printf( " afp_signature.conf:\t%s\n", _PATH_AFPDSIGCONF ); 683 printf( " afp_voluuid.conf:\t%s\n", _PATH_AFPDUUIDCONF ); 684#ifdef HAVE_LDAP 685 printf( " afp_ldap.conf:\t%s\n", _PATH_ACL_LDAPCONF ); 686#else 687 printf( " afp_ldap.conf:\tnot supported\n"); 688#endif 689 printf( " UAM search path:\t%s\n", _PATH_AFPDUAMPATH ); 690 printf( " Server messages path:\t%s\n", SERVERTEXT); 691 printf( " lockfile:\t%s\n", _PATH_AFPDLOCK); 692} 693 694/* 695 * Display usage information about afpd. 696 */ 697static void show_usage( char *name ) 698{ 699 fprintf( stderr, "Usage:\t%s [-duptDTI] [-f defaultvolumes] [-s systemvolumes] [-n nbpname]\n", name ); 700 fprintf( stderr, "\t [-c maxconnections] [-g guest] [-P pidfile] [-S port] [-L message]\n" ); 701 fprintf( stderr, "\t [-F configfile] [-U uams] [-m umask]\n" ); 702 fprintf( stderr, "\t%s -h|-v|-V\n", name ); 703} 704 705int afp_options_parse(int ac, char **av, struct afp_options *options) 706{ 707 extern char *optarg; 708 extern int optind; 709 710 char *p; 711 char *tmp; /* Used for error checking the result of strtol */ 712 int c, err = 0; 713 714 if (gethostname(options->hostname, sizeof(options->hostname )) < 0 ) { 715 perror( "gethostname" ); 716 return 0; 717 } 718 if (NULL != ( p = strchr(options->hostname, '.' )) ) { 719 *p = '\0'; 720 } 721 722#ifdef ultrix 723 if (NULL == ( p = strrchr( av[ 0 ], '/' )) ) { 724 p = av[ 0 ]; 725 } else { 726 p++; 727 } 728 openlog( p, LOG_PID ); /* ultrix only */ 729#endif /* ultrix */ 730 731 while (EOF != ( c = getopt( ac, av, OPTIONS )) ) { 732 switch ( c ) { 733 case 'd' : 734 options->flags |= OPTION_DEBUG; 735 break; 736 case 'n' : 737 options->server = optarg; 738 break; 739 case 'f' : 740 options->defaultvol.name = optarg; 741 break; 742 case 's' : 743 options->systemvol.name = optarg; 744 break; 745 case 'u' : 746 options->flags |= OPTION_USERVOLFIRST; 747 break; 748 case 'c' : 749 options->connections = atoi( optarg ); 750 break; 751 case 'g' : 752 options->guest = optarg; 753 break; 754 755 case 'P' : 756 options->pidfile = optarg; 757 break; 758 759 case 'p': 760 options->passwdbits |= PASSWD_NOSAVE; 761 break; 762 case 't': 763 options->passwdbits |= PASSWD_SET; 764 break; 765 766 case 'D': 767 options->transports &= ~AFPTRANS_DDP; 768 break; 769 case 'S': 770 options->port = optarg; 771 break; 772 case 'T': 773 options->transports &= ~AFPTRANS_TCP; 774 break; 775 case 'L': 776 options->loginmesg = optarg; 777 break; 778 case 'F': 779 options->configfile = optarg; 780 break; 781 case 'U': 782 options->uamlist = optarg; 783 break; 784 case 'v': /* version */ 785 show_version( ); puts( "" ); 786 show_paths( ); puts( "" ); 787 exit( 0 ); 788 break; 789 case 'V': /* extended version */ 790 show_version_extended( ); puts( "" ); 791 show_paths( ); puts( "" ); 792 exit( 0 ); 793 break; 794 case 'h': /* usage */ 795 show_usage("afpd"); 796 exit( 0 ); 797 break; 798 case 'I': 799 options->flags |= OPTION_CUSTOMICON; 800 break; 801 case 'm': 802 options->umask = strtoul(optarg, &tmp, 8); 803 if ((options->umask > 0777)) { 804 fprintf(stderr, "%s: out of range umask setting provided\n", p); 805 err++; 806 } 807 if (tmp[0] != '\0') { 808 fprintf(stderr, "%s: invalid characters in umask setting provided\n", p); 809 err++; 810 } 811 break; 812 default : 813 err++; 814 } 815 } 816 if ( err || optind != ac ) { 817 show_usage( p ); 818 exit( 2 ); 819 } 820 821 return 1; 822} 823