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

« back to all changes in this revision

Viewing changes to etc/afpd/volume.c

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2009-09-09 23:43:27 UTC
  • mfrom: (8.2.5 sid)
  • Revision ID: james.westby@ubuntu.com-20090909234327-dhgxhuanxheto4x8
Tags: 2.0.4-2
* Update copyright hints.
* Lower policy compliance to 3.8.0 (uncertain about sysv script
  requirements in 3.8.1).
* Fix order of db upgrade commands in README.Debian. Closes:
  bug#533344, thanks (again) to Itai Seggev.
* Update package-relations.mk: Cleanup unversioned+versioned
  dependency mix. Improve whitespace cleanup. Rewrite and silence
  applying dependencies.
* Fix and improve README.Debian section on recompiling with OpenSSL,
  thanks to Gijs Hillenius and others.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * $Id: volume.c,v 1.51.2.7.2.33.2.15 2008/11/25 15:16:33 didg Exp $
 
2
 * $Id: volume.c,v 1.51.2.7.2.33.2.24 2009/03/26 11:53:32 franklahm Exp $
3
3
 *
4
4
 * Copyright (c) 1990,1993 Regents of The University of Michigan.
5
5
 * All Rights Reserved.  See COPYRIGHT.
114
114
 
115
115
#define VOLOPT_FORCEUID  19  /* force uid for username x */
116
116
#define VOLOPT_FORCEGID  20  /* force gid for group x */
 
117
#endif /* FORCE_UIDGID */
 
118
 
117
119
#define VOLOPT_UMASK     21
118
 
#define VOLOPT_DFLTPERM  22
119
 
#else 
120
 
#define VOLOPT_UMASK     19
121
 
#define VOLOPT_DFLTPERM  20
122
 
#endif /* FORCE_UIDGID */
 
120
#define VOLOPT_ALLOWED_HOSTS 22
 
121
#define VOLOPT_DENIED_HOSTS  23
 
122
#define VOLOPT_DPERM     24  /* dperm default directories perms */
 
123
#define VOLOPT_FPERM     25  /* fperm default files perms */
 
124
#define VOLOPT_DFLTPERM  26  /* perm */
123
125
 
124
126
#define VOLOPT_MAX       (VOLOPT_DFLTPERM +1)
125
127
 
171
173
                                         * maybe because it will be mounted later in preexec */
172
174
    {AFPVOL_UNIX_PRIV,  "UNIXPRIV"},    /* support unix privileges */
173
175
    {AFPVOL_NODEV,      "NODEV"},       /* always use 0 for device number in cnid calls */
 
176
    {AFPVOL_EILSEQ,     "ILLEGALSEQ"},  /* encode illegal sequence */
174
177
    {AFPVOL_CACHE,      "CACHEID"},     /* Use adouble v2 CNID caching, default don't use it */
175
178
    {0, NULL}
176
179
};
473
476
                options[VOLOPT_FLAGS].i_value |= AFPVOL_UNIX_PRIV;
474
477
            else if (strcasecmp(p, "nodev") == 0)
475
478
                options[VOLOPT_FLAGS].i_value |= AFPVOL_NODEV;
 
479
            else if (strcasecmp(p, "illegalseq") == 0)
 
480
                options[VOLOPT_FLAGS].i_value |= AFPVOL_EILSEQ;
476
481
            else if (strcasecmp(p, "cachecnid") == 0)
477
482
                options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE;
478
483
 
484
489
 
485
490
    } else if (optionok(tmp, "umask:", val)) {
486
491
        options[VOLOPT_UMASK].i_value = (int)strtol(val +1, NULL, 8);
 
492
    } else if (optionok(tmp, "dperm:", val)) {
 
493
        options[VOLOPT_DPERM].i_value = (int)strtol(val+1, NULL, 8);
 
494
    } else if (optionok(tmp, "fperm:", val)) {
 
495
        options[VOLOPT_FPERM].i_value = (int)strtol(val+1, NULL, 8);
487
496
    } else if (optionok(tmp, "perm:", val)) {
488
497
        options[VOLOPT_DFLTPERM].i_value = (int)strtol(val+1, NULL, 8);
489
498
    } else if (optionok(tmp, "mapchars:",val)) {
513
522
    } else if (optionok(tmp, "postexec:", val)) {
514
523
        setoption(options, save, VOLOPT_POSTEXEC, val);
515
524
 
 
525
    } else if (optionok(tmp, "allowed_hosts:", val)) {
 
526
        setoption(options, save, VOLOPT_ALLOWED_HOSTS, val);
 
527
 
 
528
    } else if (optionok(tmp, "denied_hosts:", val)) {
 
529
        setoption(options, save, VOLOPT_DENIED_HOSTS, val);
 
530
 
516
531
    } else {
517
532
        /* ignore unknown options */
518
533
        LOG(log_debug, logtype_afpd, "ignoring unknown volume option: %s", tmp);
535
550
/* ----------------- 
536
551
 * FIXME should be define elsewhere
537
552
*/
 
553
static int netatalk_name(const char *name)
 
554
{
 
555
    return strcasecmp(name,".AppleDB") &&
 
556
        strcasecmp(name,".AppleDouble") &&
 
557
        strcasecmp(name,".AppleDesktop");
 
558
}
 
559
 
538
560
static int validupath_adouble(const struct vol *vol, const char *name) 
539
561
{
540
562
    return (vol->v_flags & AFPVOL_USEDOTS) ? 
541
 
        strcasecmp(name,".AppleDB") &&
542
 
        strcasecmp(name,".AppleDouble") &&
543
 
        strcasecmp(name,".AppleDesktop") &&
544
 
        strcasecmp(name,".Parent")
545
 
                                           : name[0] != '.';
 
563
        netatalk_name(name) && strcasecmp(name,".Parent"): name[0] != '.';
546
564
}                                           
547
565
 
548
566
/* ----------------- */
549
567
static int validupath_osx(const struct vol *vol _U_, const char *name) 
550
568
{
551
 
    return strncasecmp(name,".Apple", 6) && strncasecmp(name,"._", 2);
 
569
    return strncmp(name,"._", 2) && (
 
570
      (vol->v_flags & AFPVOL_USEDOTS) ? netatalk_name(name): name[0] != '.');
552
571
}             
553
572
 
554
573
/* ---------------- */
672
691
        if (options[VOLOPT_UMASK].i_value)
673
692
            volume->v_umask = (mode_t)options[VOLOPT_UMASK].i_value;
674
693
 
 
694
        if (options[VOLOPT_DPERM].i_value)
 
695
            volume->v_dperm = (mode_t)options[VOLOPT_DPERM].i_value;
 
696
 
 
697
        if (options[VOLOPT_FPERM].i_value)
 
698
            volume->v_fperm = (mode_t)options[VOLOPT_FPERM].i_value;
 
699
 
675
700
        if (options[VOLOPT_DFLTPERM].i_value)
676
701
            volume->v_perm = (mode_t)options[VOLOPT_DFLTPERM].i_value;
677
702
 
708
733
                volume->v_root_postexec = volxlate(obj, NULL, MAXPATHLEN, options[VOLOPT_ROOTPOSTEXEC].c_value, pwd, path,  name);
709
734
        }
710
735
    }
 
736
    volume->v_dperm |= volume->v_perm;
 
737
    volume->v_fperm |= volume->v_perm;
711
738
 
712
739
    initvoladouble(volume);
713
740
    volume->v_next = Volumes;
725
752
    int         c;
726
753
 
727
754
    p = buf;
728
 
    while ((EOF != ( c = getc( fp )) ) && ( size > 0 )) {
 
755
    while ((EOF != ( c = getc( fp )) ) && ( size > 1 )) {
729
756
        if ( c == '\n' || c == '\r' ) {
 
757
            if (p != buf && *(p -1) == '\\') {
 
758
                p--;
 
759
                size++;
 
760
                continue;
 
761
            }
730
762
            *p++ = '\n';
731
763
            break;
732
764
        } else {
792
824
    return 0;
793
825
}
794
826
 
 
827
static int hostaccessvol(type, volname, args, obj)
 
828
int type;
 
829
char *volname;
 
830
const char *args;
 
831
const AFPObj *obj;
 
832
{
 
833
    char buf[MAXPATHLEN + 1], *p, *b;
 
834
    DSI *dsi = obj->handle;
 
835
 
 
836
    if (!args)
 
837
        return -1;
 
838
 
 
839
    strlcpy(buf, args, sizeof(buf));
 
840
    if ((p = strtok_r(buf, ",", &b)) == NULL) /* nothing, return okay */
 
841
        return -1;
 
842
 
 
843
    while (p) {
 
844
        if (obj->proto == AFPPROTO_DSI) {
 
845
            struct in_addr mask, net;
 
846
            char *net_char, *mask_char;
 
847
            int mask_int;
 
848
 
 
849
            net_char = strtok(p, "/");
 
850
            mask_char = strtok(NULL,"/");
 
851
            if (mask_char == NULL) {
 
852
                mask_int = 32;
 
853
            } else {
 
854
                mask_int = atoi(mask_char);
 
855
            }
 
856
           
 
857
            // convert the integer netmask to a bitmask in network order
 
858
            mask.s_addr = htonl(-1 - ((1 << (32 - mask_int)) - 1));
 
859
            net.s_addr = inet_addr(net_char) & mask.s_addr;
 
860
 
 
861
            if ((dsi->client.sin_addr.s_addr & mask.s_addr) == net.s_addr) {
 
862
                    if (type == VOLOPT_DENIED_HOSTS)
 
863
                        LOG(log_info, logtype_afpd, "AFP access denied for client IP '%s' to volume '%s' by denied list",
 
864
                            inet_ntoa(dsi->client.sin_addr), volname);
 
865
                    return 1;
 
866
            }
 
867
        }
 
868
        p = strtok_r(NULL, ",", &b);
 
869
    }
 
870
    if (type == VOLOPT_ALLOWED_HOSTS)
 
871
        LOG(log_info, logtype_afpd, "AFP access denied for client IP '%s' to volume '%s', not in allowed list",
 
872
            inet_ntoa(dsi->client.sin_addr), volname);
 
873
    return 0;
 
874
}
 
875
 
795
876
static void setextmap( ext, type, creator, user)
796
877
char            *ext, *type, *creator;
797
878
int                     user;
1047
1128
               allow -> either no list (-1), or in list (1)
1048
1129
               deny -> either no list (-1), or not in list (0) */
1049
1130
            if (accessvol(options[VOLOPT_ALLOW].c_value, obj->username) &&
1050
 
                    (accessvol(options[VOLOPT_DENY].c_value, obj->username) < 1)) {
 
1131
                (accessvol(options[VOLOPT_DENY].c_value, obj->username) < 1) &&
 
1132
                hostaccessvol(VOLOPT_ALLOWED_HOSTS, volname, options[VOLOPT_ALLOWED_HOSTS].c_value, obj) &&
 
1133
                (hostaccessvol(VOLOPT_DENIED_HOSTS, volname, options[VOLOPT_DENIED_HOSTS].c_value, obj) < 1)) {
1051
1134
 
1052
1135
                /* handle read-only behaviour. semantics:
1053
1136
                 * 1) neither the rolist nor the rwlist exist -> rw
2318
2401
        LOG(log_debug, logtype_afpd,"Error writing .volinfo file: buffer too small, %s", buf);
2319
2402
 
2320
2403
 
2321
 
   if (write( fd, buf, strlen(buf)) < 0) {
 
2404
   if (write( fd, buf, strlen(buf)) < 0 || ftruncate(fd, strlen(buf)) < 0 ) {
2322
2405
       LOG(log_debug, logtype_afpd,"Error writing .volinfo file: %s", strerror(errno));
2323
 
       goto done;
2324
2406
   }
2325
 
   ftruncate(fd, strlen(buf));
2326
2407
 
2327
 
done:
2328
2408
   lock.l_type = F_UNLCK;
2329
2409
   fcntl(fd, F_SETLK, &lock);
2330
2410
   close (fd);