X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=etc%2Fafpd%2Fvolume.c;h=53a0bc23ee4c123fd106dc4058e729cf05edf03a;hb=85e784fb876d3cc1e907b49421a15a40ba9adf98;hp=79ac3396ff715bcb10539cb33113b55f035b441e;hpb=c5d365a2deb1a9bbd472a12a71fd927e9a409b45;p=netatalk.git diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 79ac3396..53a0bc23 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -1,5 +1,5 @@ /* - * $Id: volume.c,v 1.51.2.7.2.33.2.2 2004-12-10 13:33:34 didg Exp $ + * $Id: volume.c,v 1.51.2.7.2.33.2.19 2009-01-28 05:37:58 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -114,12 +114,14 @@ m=u -> map both ways #define VOLOPT_FORCEUID 19 /* force uid for username x */ #define VOLOPT_FORCEGID 20 /* force gid for group x */ -#define VOLOPT_UMASK 21 -#else -#define VOLOPT_UMASK 19 #endif /* FORCE_UIDGID */ -#define VOLOPT_MAX (VOLOPT_UMASK +1) +#define VOLOPT_UMASK 21 +#define VOLOPT_DPERM 22 /* dperm default directories perms */ +#define VOLOPT_FPERM 23 /* dperm default files perms */ +#define VOLOPT_DFLTPERM 24 /* perm */ + +#define VOLOPT_MAX (VOLOPT_DFLTPERM +1) #define VOLOPT_NUM (VOLOPT_MAX + 1) @@ -169,6 +171,8 @@ static const _vol_opt_name vol_opt_names[] = { * maybe because it will be mounted later in preexec */ {AFPVOL_UNIX_PRIV, "UNIXPRIV"}, /* support unix privileges */ {AFPVOL_NODEV, "NODEV"}, /* always use 0 for device number in cnid calls */ + {AFPVOL_EILSEQ, "ILLEGALSEQ"}, /* encode illegal sequence */ + {AFPVOL_CACHE, "CACHEID"}, /* Use adouble v2 CNID caching, default don't use it */ {0, NULL} }; @@ -183,7 +187,7 @@ static const _vol_opt_name vol_opt_casefold[] = { static void handle_special_folders (const struct vol *); static int savevoloptions (const struct vol *); -static __inline__ void volfree(struct vol_option *options, +static void volfree(struct vol_option *options, const struct vol_option *save) { int i; @@ -242,7 +246,7 @@ static char *volxlate(AFPObj *obj, char *dest, size_t destlen, return ret; /* first part of the path. just forward to the next variable. */ - len = MIN(p - src, destlen); + len = MIN((size_t)(p - src), destlen); if (len > 0) { destlen -= len; dest += len; @@ -338,7 +342,7 @@ static char *volxlate(AFPObj *obj, char *dest, size_t destlen, /* stuff up to next $ */ src = p + 2; p = strchr(src, '$'); - len = p ? MIN(p - src, destlen) : destlen; + len = p ? MIN((size_t)(p - src), destlen) : destlen; if (len > 0) { strncpy(dest, src, len); dest += len; @@ -449,6 +453,8 @@ static void volset(struct vol_option *options, struct vol_option *save, options[VOLOPT_FLAGS].i_value |= AFPVOL_NOHEX; else if (strcasecmp(p, "usedots") == 0) options[VOLOPT_FLAGS].i_value |= AFPVOL_USEDOTS; + else if (strcasecmp(p, "invisibledots") == 0) + options[VOLOPT_FLAGS].i_value |= AFPVOL_USEDOTS | AFPVOL_INV_DOTS; else if (strcasecmp(p, "limitsize") == 0) options[VOLOPT_FLAGS].i_value |= AFPVOL_LIMITSIZE; /* support for either "dropbox" or "dropkludge" */ @@ -468,6 +474,10 @@ static void volset(struct vol_option *options, struct vol_option *save, options[VOLOPT_FLAGS].i_value |= AFPVOL_UNIX_PRIV; else if (strcasecmp(p, "nodev") == 0) options[VOLOPT_FLAGS].i_value |= AFPVOL_NODEV; + else if (strcasecmp(p, "illegalseq") == 0) + options[VOLOPT_FLAGS].i_value |= AFPVOL_EILSEQ; + else if (strcasecmp(p, "cachecnid") == 0) + options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE; p = strtok(NULL, ","); } @@ -476,7 +486,13 @@ static void volset(struct vol_option *options, struct vol_option *save, setoption(options, save, VOLOPT_DBPATH, val); } else if (optionok(tmp, "umask:", val)) { - options[VOLOPT_UMASK].i_value = (int)strtol(val, (char **)NULL, 8); + options[VOLOPT_UMASK].i_value = (int)strtol(val +1, NULL, 8); + } else if (optionok(tmp, "perm:", val)) { + options[VOLOPT_DFLTPERM].i_value = (int)strtol(val+1, NULL, 8); + } else if (optionok(tmp, "dperm:", val)) { + options[VOLOPT_DPERM].i_value = (int)strtol(val+1, NULL, 8); + } else if (optionok(tmp, "fperm:", val)) { + options[VOLOPT_FPERM].i_value = (int)strtol(val+1, NULL, 8); } else if (optionok(tmp, "mapchars:",val)) { setoption(options, save, VOLOPT_MAPCHARS, val); @@ -528,12 +544,16 @@ static void showvol(const ucs2_t *name) */ static int validupath_adouble(const struct vol *vol, const char *name) { - return (vol->v_flags & AFPVOL_USEDOTS) ? strncasecmp(name,".Apple", 6) && strcasecmp(name, ".Parent") + return (vol->v_flags & AFPVOL_USEDOTS) ? + strcasecmp(name,".AppleDB") && + strcasecmp(name,".AppleDouble") && + strcasecmp(name,".AppleDesktop") && + strcasecmp(name,".Parent") : name[0] != '.'; } /* ----------------- */ -static int validupath_osx(const struct vol *vol, const char *name) +static int validupath_osx(const struct vol *vol _U_, const char *name) { return strncasecmp(name,".Apple", 6) && strncasecmp(name,"._", 2); } @@ -628,6 +648,16 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, /* shift in some flags */ volume->v_flags = options[VOLOPT_FLAGS].i_value; + volume->v_ad_options = 0; + if ((volume->v_flags & AFPVOL_NODEV)) + volume->v_ad_options |= ADVOL_NODEV; + if ((volume->v_flags & AFPVOL_CACHE)) + volume->v_ad_options |= ADVOL_CACHE; + if ((volume->v_flags & AFPVOL_UNIX_PRIV)) + volume->v_ad_options |= ADVOL_UNIXPRIV; + if ((volume->v_flags & AFPVOL_INV_DOTS)) + volume->v_ad_options |= ADVOL_INVDOTS; + if (options[VOLOPT_PASSWORD].c_value) volume->v_password = strdup(options[VOLOPT_PASSWORD].c_value); @@ -649,6 +679,11 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, if (options[VOLOPT_UMASK].i_value) volume->v_umask = (mode_t)options[VOLOPT_UMASK].i_value; + if (options[VOLOPT_DPERM].i_value) + + if (options[VOLOPT_DFLTPERM].i_value) + volume->v_perm = (mode_t)options[VOLOPT_DFLTPERM].i_value; + if (options[VOLOPT_ADOUBLE].i_value) volume->v_adouble = options[VOLOPT_ADOUBLE].i_value; else @@ -682,6 +717,8 @@ static int creatvol(AFPObj *obj, struct passwd *pwd, volume->v_root_postexec = volxlate(obj, NULL, MAXPATHLEN, options[VOLOPT_ROOTPOSTEXEC].c_value, pwd, path, name); } } + volume->v_dperm |= volume->v_perm; + volume->v_fperm |= volume->v_perm; initvoladouble(volume); volume->v_next = Volumes; @@ -699,7 +736,7 @@ FILE *fp; int c; p = buf; - while ((EOF != ( c = getc( fp )) ) && ( size > 0 )) { + while ((EOF != ( c = getc( fp )) ) && ( size > 1 )) { if ( c == '\n' || c == '\r' ) { *p++ = '\n'; break; @@ -1227,7 +1264,7 @@ int *buflen; * For MacOS8.x support we need to create the * .Parent file here if it doesn't exist. */ - ad_init(&ad, vol->v_adouble); + ad_init(&ad, vol->v_adouble, vol->v_ad_options); if ( ad_open( vol->v_path, vol_noadouble(vol) | ADFLAGS_HF|ADFLAGS_DIR, O_RDWR | O_CREAT, 0666, &ad) < 0 ) { @@ -1390,7 +1427,8 @@ int *buflen; if ( nameoff ) { ashort = htons( data - buf ); memcpy(nameoff, &ashort, sizeof( ashort )); - aint = ucs2_to_charset( (utf8_encoding()?CH_UTF8_MAC:vol->v_maccharset), vol->v_name, data+1, 255); + /* name is always in mac charset, FIXME mangle if length > 27 char */ + aint = ucs2_to_charset( vol->v_maccharset, vol->v_name, data+1, 255); if ( aint <= 0 ) { *buflen = 0; return AFPERR_MISC; @@ -1407,7 +1445,7 @@ int *buflen; } /* ------------------------- */ -int static stat_vol(u_int16_t bitmap, struct vol *vol, char *rbuf, int *rbuflen) +static int stat_vol(u_int16_t bitmap, struct vol *vol, char *rbuf, int *rbuflen) { struct stat st; int buflen, ret; @@ -1491,8 +1529,8 @@ void load_volumes(AFPObj *obj) /* ------------------------------- */ int afp_getsrvrparms(obj, ibuf, ibuflen, rbuf, rbuflen ) AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +char *ibuf _U_, *rbuf; +int ibuflen _U_, *rbuflen; { struct timeval tv; struct stat st; @@ -1507,6 +1545,8 @@ int ibuflen, *rbuflen; data = rbuf + 5; for ( vcnt = 0, volume = Volumes; volume; volume = volume->v_next ) { if (!(volume->v_flags & AFPVOL_NOSTAT)) { + struct maccess ma; + if ( stat( volume->v_path, &st ) < 0 ) { LOG(log_info, logtype_afpd, "afp_getsrvrparms(%s): stat: %s", volume->v_path, strerror(errno) ); @@ -1515,6 +1555,10 @@ int ibuflen, *rbuflen; if (!S_ISDIR(st.st_mode)) { continue; /* not a dir */ } + accessmode(volume->v_path, &ma, NULL, &st); + if ((ma.ma_user & (AR_UREAD | AR_USEARCH)) != (AR_UREAD | AR_USEARCH)) { + continue; /* no r-x access */ + } } if (volume->v_hide) { continue; /* config file changed but the volume was mounted */ @@ -1562,7 +1606,7 @@ int ibuflen, *rbuflen; int afp_openvol(obj, ibuf, ibuflen, rbuf, rbuflen ) AFPObj *obj; char *ibuf, *rbuf; -int ibuflen, *rbuflen; +int ibuflen _U_, *rbuflen; { struct stat st; char *volname; @@ -1824,7 +1868,7 @@ void close_all_vol(void) struct vol *ovol; curdir = NULL; for ( ovol = Volumes; ovol; ovol = ovol->v_next ) { - if ( ovol->v_flags & AFPVOL_OPEN ) { + if ( (ovol->v_flags & AFPVOL_OPEN) ) { ovol->v_flags &= ~AFPVOL_OPEN; closevol(ovol); } @@ -1833,9 +1877,9 @@ void close_all_vol(void) /* ------------------------- */ int afp_closevol(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +AFPObj *obj _U_; +char *ibuf, *rbuf _U_; +int ibuflen _U_, *rbuflen; { struct vol *vol, *ovol; u_int16_t vid; @@ -1849,7 +1893,7 @@ int ibuflen, *rbuflen; vol->v_flags &= ~AFPVOL_OPEN; for ( ovol = Volumes; ovol; ovol = ovol->v_next ) { - if ( ovol->v_flags & AFPVOL_OPEN ) { + if ( (ovol->v_flags & AFPVOL_OPEN) ) { break; } } @@ -1988,9 +2032,9 @@ struct vol *vol; /* ------------------------- */ int afp_getvolparams(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; +AFPObj *obj _U_; char *ibuf, *rbuf; -int ibuflen, *rbuflen; +int ibuflen _U_, *rbuflen; { struct vol *vol; u_int16_t vid, bitmap; @@ -2011,9 +2055,9 @@ int ibuflen, *rbuflen; /* ------------------------- */ int afp_setvolparams(obj, ibuf, ibuflen, rbuf, rbuflen ) -AFPObj *obj; -char *ibuf, *rbuf; -int ibuflen, *rbuflen; +AFPObj *obj _U_; +char *ibuf, *rbuf _U_; +int ibuflen _U_, *rbuflen; { struct adouble ad; struct vol *vol; @@ -2033,14 +2077,14 @@ int ibuflen, *rbuflen; return( AFPERR_PARAM ); } - if (vol->v_flags & AFPVOL_RO) + if ((vol->v_flags & AFPVOL_RO)) return AFPERR_VLOCK; /* we can only set the backup date. */ if (bitmap != (1 << VOLPBIT_BDATE)) return AFPERR_BITMAP; - ad_init(&ad, vol->v_adouble); + ad_init(&ad, vol->v_adouble, vol->v_ad_options); if ( ad_open( vol->v_path, ADFLAGS_HF|ADFLAGS_DIR, O_RDWR, 0666, &ad) < 0 ) { if (errno == EROFS) @@ -2136,7 +2180,7 @@ static int create_special_folder (const struct vol *vol, const struct _special_f if ( !ret && folder->hide) { /* Hide it */ - ad_init(&ad, vol->v_adouble); + ad_init(&ad, vol->v_adouble, vol->v_ad_options); if (ad_open( p, vol_noadouble(vol) | ADFLAGS_HF|ADFLAGS_DIR, O_RDWR|O_CREAT, 0666, &ad) < 0) { free (p); @@ -2154,14 +2198,14 @@ static int create_special_folder (const struct vol *vol, const struct _special_f ad_getattr(&ad, &attr); attr |= htons( ntohs( attr ) | ATTRBIT_INVISIBLE ); ad_setattr(&ad, attr); -#if 0 + /* do the same with the finder info */ if (ad_entry(&ad, ADEID_FINDERI)) { memcpy(&attr, ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, sizeof(attr)); attr |= htons(FINDERINFO_INVISIBLE); memcpy(ad_entry(&ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,&attr, sizeof(attr)); } -#endif + ad_flush( &ad, ADFLAGS_HF ); ad_close( &ad, ADFLAGS_HF ); } @@ -2174,7 +2218,7 @@ static void handle_special_folders (const struct vol * vol) { const _special_folder *p = &special_folders[0]; - if (vol->v_flags & AFPVOL_RO) + if ((vol->v_flags & AFPVOL_RO)) return; for (; p->name != NULL; p++) { @@ -2262,7 +2306,7 @@ static int savevoloptions (const struct vol *vol) /* volume flags */ strcpy(item, "VOLUME_OPTS:"); for (;op->name; op++) { - if ( vol->v_flags & op->option ) { + if ( (vol->v_flags & op->option) ) { strlcat(item, op->name, sizeof(item)); strlcat(item, " ", sizeof(item)); } @@ -2273,7 +2317,7 @@ static int savevoloptions (const struct vol *vol) /* casefold flags */ strcpy(item, "VOLCASEFOLD:"); for (;cf->name; cf++) { - if ( vol->v_casefold & cf->option ) { + if ( (vol->v_casefold & cf->option) ) { strlcat(item, cf->name, sizeof(item)); strlcat(item, " ", sizeof(item)); } @@ -2285,13 +2329,10 @@ static int savevoloptions (const struct vol *vol) LOG(log_debug, logtype_afpd,"Error writing .volinfo file: buffer too small, %s", buf); - if (write( fd, buf, strlen(buf)) < 0) { + if (write( fd, buf, strlen(buf)) < 0 || ftruncate(fd, strlen(buf)) < 0 ) { LOG(log_debug, logtype_afpd,"Error writing .volinfo file: %s", strerror(errno)); - goto done; } - ftruncate(fd, strlen(buf)); -done: lock.l_type = F_UNLCK; fcntl(fd, F_SETLK, &lock); close (fd);