From f05ac9452b2f60773adcc8adefc117e145052fb6 Mon Sep 17 00:00:00 2001 From: didg Date: Tue, 7 Dec 2004 03:23:48 +0000 Subject: [PATCH] Check for DENY READ in FPCopyFile. --- etc/afpd/directory.c | 4 +-- etc/afpd/file.c | 60 +++++++++++++++++++++----------------- etc/afpd/file.h | 4 +-- etc/afpd/fork.c | 6 ++-- etc/afpd/fork.h | 4 ++- etc/afpd/ofork.c | 20 ++++++++++++- libatalk/adouble/ad_lock.c | 13 ++++++--- 7 files changed, 73 insertions(+), 38 deletions(-) diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index e22c7c94..80050643 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -1,5 +1,5 @@ /* - * $Id: directory.c,v 1.71.2.4.2.15.2.2 2004-12-07 02:58:10 didg Exp $ + * $Id: directory.c,v 1.71.2.4.2.15.2.3 2004-12-07 03:23:48 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -786,7 +786,7 @@ static int copydir(const struct vol *vol, char *src, char *dst) if (S_ISDIR(st.st_mode)) { if (AFP_OK != (err = copydir(vol, spath, dpath))) goto copydir_done; - } else if (AFP_OK != (err = copyfile(vol, vol, spath, dpath, NULL))) { + } else if (AFP_OK != (err = copyfile(vol, vol, spath, dpath, NULL, NULL))) { goto copydir_done; } else { diff --git a/etc/afpd/file.c b/etc/afpd/file.c index 09502efa..bf7f6efa 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1,5 +1,5 @@ /* - * $Id: file.c,v 1.92.2.2.2.31.2.4 2004-12-07 02:58:09 didg Exp $ + * $Id: file.c,v 1.92.2.2.2.31.2.5 2004-12-07 03:23:49 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -805,12 +805,8 @@ int setfilparams(struct vol *vol, #endif /* DEBUG */ upath = path->u_name; - if ((of = of_findname(path))) { - adp = of->of_ad; - } else { - ad_init(&ad, vol->v_adouble); - adp = &ad; - } + adp = of_ad(vol, path, &ad); + if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) { return AFPERR_ACCESS; @@ -1051,7 +1047,7 @@ struct adouble *adp; /* FIXME warning in syslog so admin'd know there's a conflict ?*/ return AFPERR_OLOCK; /* little lie */ } - if (AFP_OK != ( rc = copyfile(vol, vol, src, dst, newname )) ) { + if (AFP_OK != ( rc = copyfile(vol, vol, src, dst, newname, NULL )) ) { /* on error copyfile delete dest */ return( rc ); } @@ -1211,6 +1207,9 @@ int ibuflen, *rbuflen; int err, retvalue = AFP_OK; u_int16_t svid, dvid; + struct adouble ad, *adp; + int denyreadset; + #ifdef DEBUG LOG(log_info, logtype_afpd, "begin afp_copyfile:"); #endif /* DEBUG */ @@ -1248,11 +1247,20 @@ int ibuflen, *rbuflen; * and locks need to stay coherent. as a result, * we just balk if the file is opened already. */ - newname = obj->newtmp; - strcpy( newname, s_path->m_name ); + adp = of_ad(s_vol, s_path, &ad); - if (of_findname(s_path)) + if (ad_open(s_path->u_name , ADFLAGS_DF |ADFLAGS_HF | ADFLAGS_NOHF, O_RDONLY, 0, adp) < 0) { return AFPERR_DENYCONF; + } + denyreadset = (getforkmode(adp, ADEID_DFORK, AD_FILELOCK_DENY_RD) != 0 || + getforkmode(adp, ADEID_RFORK, AD_FILELOCK_DENY_RD) != 0 ); + ad_close( adp, ADFLAGS_DF |ADFLAGS_HF ); + if (denyreadset) { + return AFPERR_DENYCONF; + } + + newname = obj->newtmp; + strcpy( newname, s_path->m_name ); p = ctoupath( s_vol, curdir, newname ); if (!p) { @@ -1290,7 +1298,7 @@ int ibuflen, *rbuflen; if (NULL == (upath = mtoupath(d_vol, newname, curdir->d_did, utf8_encoding()))) { return( AFPERR_PARAM ); } - if ( (err = copyfile(s_vol, d_vol, p, upath , newname)) < 0 ) { + if ( (err = copyfile(s_vol, d_vol, p, upath , newname, adp)) < 0 ) { return err; } curdir->offcnt++; @@ -1394,9 +1402,10 @@ static int copy_fd(int dfd, int sfd) * if newname is NULL (from directory.c) we don't want to copy ressource fork. * because we are doing it elsewhere. */ -int copyfile(s_vol, d_vol, src, dst, newname ) +int copyfile(s_vol, d_vol, src, dst, newname, adp ) const struct vol *s_vol, *d_vol; char *src, *dst, *newname; +struct adouble *adp; { struct adouble ads, add; int err = 0; @@ -1409,42 +1418,45 @@ char *src, *dst, *newname; LOG(log_info, logtype_afpd, "begin copyfile:"); #endif /* DEBUG */ - ad_init(&ads, s_vol->v_adouble); + if (adp == NULL) { + ad_init(&ads, s_vol->v_adouble); + adp = &ads; + } ad_init(&add, d_vol->v_adouble); adflags = ADFLAGS_DF; if (newname) { adflags |= ADFLAGS_HF; } - if (ad_open(src , adflags | ADFLAGS_NOHF, O_RDONLY, 0, &ads) < 0) { + if (ad_open(src , adflags | ADFLAGS_NOHF, O_RDONLY, 0, adp) < 0) { ret_err = errno; goto done; } - if (ad_hfileno(&ads) == -1) { + if (ad_hfileno(adp) == -1) { /* no resource fork, don't create one for dst file */ adflags &= ~ADFLAGS_HF; } if (ad_open(dst , adflags | noadouble, O_RDWR|O_CREAT|O_EXCL, 0666, &add) < 0) { ret_err = errno; - ad_close( &ads, adflags ); + ad_close( adp, adflags ); if (EEXIST != ret_err) { deletefile(d_vol, dst, 0); goto done; } return AFPERR_EXIST; } - if (ad_hfileno(&ads) == -1 || 0 == (err = copy_fd(ad_hfileno(&add), ad_hfileno(&ads)))){ + if (ad_hfileno(adp) == -1 || 0 == (err = copy_fd(ad_hfileno(&add), ad_hfileno(adp)))){ /* copy the data fork */ - err = copy_fd(ad_dfileno(&add), ad_dfileno(&ads)); + err = copy_fd(ad_dfileno(&add), ad_dfileno(adp)); } /* Now, reopen destination file */ if (err < 0) { ret_err = errno; } - ad_close( &ads, adflags ); + ad_close( adp, adflags ); if (ad_close( &add, adflags ) <0) { deletefile(d_vol, dst, 0); @@ -1729,18 +1741,14 @@ reenumerate_id(const struct vol *vol, char *name, cnid_t did) #if AD_VERSION > AD_VERSION1 if (aint != CNID_INVALID && !S_ISDIR(path.st.st_mode)) { - struct ofork *of; +// struct ofork *of; struct adouble ad, *adp; path.st_errno = 0; path.st_valid = 1; path.u_name = de->d_name; - if (!(of = of_findname(&path))) { - ad_init(&ad, vol->v_adouble); - adp = &ad; - } else - adp = of->of_ad; + adp = of_ad(vol, &path, &ad); if ( ad_open( de->d_name, ADFLAGS_HF, O_RDWR, 0, adp ) < 0 ) { continue; diff --git a/etc/afpd/file.h b/etc/afpd/file.h index dc0ddb83..157e7163 100644 --- a/etc/afpd/file.h +++ b/etc/afpd/file.h @@ -1,5 +1,5 @@ /* - * $Id: file.h,v 1.16.2.2.2.3.2.1 2004-12-07 02:58:09 didg Exp $ + * $Id: file.h,v 1.16.2.2.2.3.2.2 2004-12-07 03:23:49 didg Exp $ * * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. @@ -130,7 +130,7 @@ extern int getfilparams __P((struct vol *, u_int16_t, struct path *, extern int setfilparams __P((struct vol *, struct path *, u_int16_t, char *)); extern int renamefile __P((const struct vol *, char *, char *, char *, struct adouble *)); -extern int copyfile __P((const struct vol *, const struct vol *, char *, char *, char *)); +extern int copyfile __P((const struct vol *, const struct vol *, char *, char *, char *, struct adouble *)); extern int deletefile __P((const struct vol *, char *, int)); extern void *get_finderinfo __P((const char *, struct adouble *, void *)); diff --git a/etc/afpd/fork.c b/etc/afpd/fork.c index ab7ba4e8..1255496a 100644 --- a/etc/afpd/fork.c +++ b/etc/afpd/fork.c @@ -1,5 +1,5 @@ /* - * $Id: fork.c,v 1.51.2.2.2.10.2.1 2004-10-30 22:42:06 didg Exp $ + * $Id: fork.c,v 1.51.2.2.2.10.2.2 2004-12-07 03:23:49 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -178,11 +178,13 @@ static int setforkmode(struct adouble *adp, int eid, int ofrefnum, int what) /* ------------------------- */ -static int getforkmode(struct adouble *adp, int eid, int what) +int getforkmode(struct adouble *adp, int eid, int what) { return ad_testlock(adp, eid, what); } +/* ------------------------- +*/ static int fork_setmode(struct adouble *adp, int eid, int access, int ofrefnum) { int ret; diff --git a/etc/afpd/fork.h b/etc/afpd/fork.h index 2611a1ba..4c711b5c 100644 --- a/etc/afpd/fork.h +++ b/etc/afpd/fork.h @@ -1,5 +1,5 @@ /* - * $Id: fork.h,v 1.8.6.2 2004-05-10 18:40:32 didg Exp $ + * $Id: fork.h,v 1.8.6.2.2.1 2004-12-07 03:23:51 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -69,8 +69,10 @@ extern int of_flush __P((const struct vol *)); extern void of_pforkdesc __P((FILE *)); extern int of_stat __P((struct path *)); extern int of_statdir __P((const struct vol *vol, struct path *)); +extern struct adouble *of_ad __P((const struct vol *, struct path *, struct adouble *)); /* in fork.c */ extern int flushfork __P((struct ofork *)); +extern int getforkmode __P((struct adouble *, int , int )); /* FP functions */ extern int afp_openfork __P((AFPObj *, char *, int, char *, int *)); diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index 1d39b266..17b5ae59 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -1,5 +1,5 @@ /* - * $Id: ofork.c,v 1.20.6.6 2004-05-10 18:40:32 didg Exp $ + * $Id: ofork.c,v 1.20.6.6.2.1 2004-12-07 03:23:51 didg Exp $ * * Copyright (c) 1996 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -372,3 +372,21 @@ struct ofork *of; free( of ); } + +/* ---------------------- + +*/ +struct adouble *of_ad(const struct vol *vol, struct path *path, struct adouble *ad) +{ + struct ofork *of; + struct adouble *adp; + + if ((of = of_findname(path))) { + adp = of->of_ad; + } else { + ad_init(ad, vol->v_adouble); + adp = ad; + } + return adp; +} + diff --git a/libatalk/adouble/ad_lock.c b/libatalk/adouble/ad_lock.c index 0cb1968d..a5d00e9c 100644 --- a/libatalk/adouble/ad_lock.c +++ b/libatalk/adouble/ad_lock.c @@ -1,5 +1,5 @@ /* - * $Id: ad_lock.c,v 1.11.6.4 2004-05-08 22:37:46 didg Exp $ + * $Id: ad_lock.c,v 1.11.6.4.2.1 2004-12-07 03:24:38 didg Exp $ * * Copyright (c) 1998,1999 Adrian Sun (asun@zoology.washington.edu) * All Rights Reserved. See COPYRIGHT for more information. @@ -403,9 +403,14 @@ int ad_testlock(struct adouble *ad, int eid, const off_t off) if ((ad_hfileno(ad) != -1)) { adf = &ad->ad_hf; lock.l_start = df2off(off); - } - } else { /* rfork */ - adf = &ad->ad_hf; + } + } + else { /* rfork */ + if ((ad_hfileno(ad) == -1)) { + /* there's no resource fork. return no lock */ + return 0; + } + adf = &ad->ad_hf; lock.l_start = hf2off(off); } -- 2.39.2