X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Ffiledir.c;h=1478299e262d297946cf9eed86434e6589c7d6b9;hb=6d60f95c388da5f8f901d67e0018cf4896e6c6dc;hp=be7056a796ab9c0729d1b8d4307c54ca5f3818d8;hpb=e83a5199e4f35ceea335dc3075b23e8d983e7642;p=netatalk.git diff --git a/etc/afpd/filedir.c b/etc/afpd/filedir.c index be7056a7..1478299e 100644 --- a/etc/afpd/filedir.c +++ b/etc/afpd/filedir.c @@ -9,24 +9,7 @@ #include #include -/* STDC check */ -#if STDC_HEADERS #include -#else /* STDC_HEADERS */ -#ifndef HAVE_STRCHR -#define strchr index -#define strrchr index -#endif /* HAVE_STRCHR */ -char *strchr (), *strrchr (); -#ifndef HAVE_MEMCPY -#define memcpy(d,s,n) bcopy ((s), (d), (n)) -#define memmove(d,s,n) bcopy ((s), (d), (n)) -#endif /* ! HAVE_MEMCPY */ -#endif /* STDC_HEADERS */ - -#ifdef HAVE_STRINGS_H -#include -#endif #include #include @@ -51,87 +34,6 @@ char *strchr (), *strrchr (); #include "filedir.h" #include "unix.h" -#ifdef DROPKLUDGE -int matchfile2dirperms( -/* Since it's kinda' big; I decided against an - inline function */ - char *upath, - struct vol *vol, - int did) -/* The below code changes the way file ownership is determined in the name of - fixing dropboxes. It has known security problem. See the netatalk FAQ for - more information */ -{ - struct stat st, sb; - struct dir *dir; - char *adpath; - uid_t uid; - int ret = AFP_OK; -#ifdef DEBUG - LOG(log_debug9, logtype_afpd, "begin matchfile2dirperms:"); -#endif - - if (stat(upath, &st ) < 0) { - LOG(log_error, logtype_afpd, "Could not stat %s: %s", upath, strerror(errno)); - return AFPERR_NOOBJ ; - } - - adpath = vol->vfs->ad_path( upath, ADFLAGS_HF ); - /* FIXME dirsearch doesn't move cwd to did ! */ - if (( dir = dirlookup( vol, did )) == NULL ) { - LOG(log_error, logtype_afpd, "matchfile2dirperms: Unable to get directory info."); - ret = AFPERR_NOOBJ; - } - else if (stat(".", &sb) < 0) { - LOG(log_error, logtype_afpd, - "matchfile2dirperms: Error checking directory \"%s\": %s", - dir->d_m_name, strerror(errno)); - ret = AFPERR_NOOBJ; - } - else { - uid=geteuid(); - if ( uid != sb.st_uid ) - { - seteuid(0); - if (lchown(upath, sb.st_uid, sb.st_gid) < 0) - { - LOG(log_error, logtype_afpd, - "matchfile2dirperms(%s): Error changing owner/gid: %s", - upath, strerror(errno)); - ret = AFPERR_ACCESS; - } - else if ((!S_ISLNK(st->st_mode)) && (chmod(upath,(st.st_mode&~default_options.umask)| S_IRGRP| S_IROTH) < 0)) - { - LOG(log_error, logtype_afpd, - "matchfile2dirperms(%s): Error adding file read permissions: %s", - upath, strerror(errno)); - ret = AFPERR_ACCESS; - } - else if (lchown(adpath, sb.st_uid, sb.st_gid) < 0) - { - LOG(log_error, logtype_afpd, - "matchfile2dirperms(%s): Error changing AppleDouble owner/gid: %s", - adpath, strerror(errno)); - ret = AFPERR_ACCESS; - } - else if (chmod(adpath, (st.st_mode&~default_options.umask)| S_IRGRP| S_IROTH) < 0) - { - LOG(log_error, logtype_afpd, - "matchfile2dirperms(%s): Error adding AD file read permissions: %s", - adpath, strerror(errno)); - ret = AFPERR_ACCESS; - } - seteuid(uid); - } - } /* end else if stat success */ - -#ifdef DEBUG - LOG(log_debug9, logtype_afpd, "end matchfile2dirperms:"); -#endif - return ret; -} -#endif - int afp_getfildirparams(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, size_t *rbuflen) { struct stat *st; @@ -328,7 +230,7 @@ static int moveandrename(const struct vol *vol, char *newname, int isdir) { - char *p; + char *oldunixname = NULL; char *upath; int rc; struct stat *st, nst; @@ -340,48 +242,52 @@ static int moveandrename(const struct vol *vol, cnid_t id; int cwd_fd = -1; + LOG(log_debug, logtype_afpd, + "moveandrename: [\"%s\"/\"%s\"] -> \"%s\"", + cfrombstr(sdir->d_u_name), oldname, newname); + ad_init(&ad, vol->v_adouble, vol->v_ad_options); adp = &ad; adflags = 0; if (!isdir) { - if ((p = mtoupath(vol, oldname, sdir->d_did, utf8_encoding())) == NULL) + if ((oldunixname = strdup(mtoupath(vol, oldname, sdir->d_did, utf8_encoding()))) == NULL) return AFPERR_PARAM; /* can't convert */ + id = cnid_get(vol->v_cdb, sdir->d_did, oldunixname, strlen(oldunixname)); -#ifndef HAVE_RENAMEAT +#ifndef HAVE_ATFUNCS /* Need full path */ - id = cnid_get(vol->v_cdb, sdir->d_did, p, strlen(p)); - p = ctoupath( vol, sdir, oldname ); - if (!p) + free(oldunixname); + if ((oldunixname = strdup(ctoupath(vol, sdir, oldname))) == NULL) return AFPERR_PARAM; /* pathname too long */ -#endif /* HAVE_RENAMEAT */ +#endif /* HAVE_ATFUNCS */ path.st_valid = 0; - path.u_name = p; -#ifdef HAVE_RENAMEAT + path.u_name = oldunixname; + +#ifdef HAVE_ATFUNCS opened = of_findnameat(sdir_fd, &path); #else opened = of_findname(&path); -#endif /* HAVE_RENAMEAT */ +#endif /* HAVE_ATFUNCS */ + if (opened) { /* reuse struct adouble so it won't break locks */ adp = opened->of_ad; } } else { id = sdir->d_did; /* we already have the CNID */ - p = ctoupath( vol, dirlookup(vol, sdir->d_pdid), oldname ); - if (!p) { + if ((oldunixname = strdup(ctoupath( vol, dirlookup(vol, sdir->d_pdid), oldname))) == NULL) return AFPERR_PARAM; - } adflags = ADFLAGS_DIR; } /* - * p now points to either + * oldunixname now points to either * a) full pathname of the source fs object (if renameat is not available) * b) the oldname (renameat is available) * we are in the dest folder so we need to use - * a) p for ad_open + * a) oldunixname for ad_open * b) fchdir sdir_fd before eg ad_open or use *at functions where appropiate */ @@ -393,10 +299,11 @@ static int moveandrename(const struct vol *vol, goto exit; } } - if (!ad_metadata(p, adflags, adp)) { + if (!ad_metadata(oldunixname, adflags, adp)) { u_int16_t bshort; ad_getattr(adp, &bshort); + ad_close_metadata( adp); if ((bshort & htons(ATTRBIT_NORENAME))) { rc = AFPERR_OLOCK; @@ -429,7 +336,7 @@ static int moveandrename(const struct vol *vol, } if (stat(upath, st) == 0 || caseenumerate(vol, &path, curdir) == 0) { - if (!stat(p, &nst) && !(nst.st_dev == st->st_dev && nst.st_ino == st->st_ino) ) { + if (!stat(oldunixname, &nst) && !(nst.st_dev == st->st_dev && nst.st_ino == st->st_ino) ) { /* not the same file */ rc = AFPERR_EXIST; goto exit; @@ -447,12 +354,12 @@ static int moveandrename(const struct vol *vol, if (of_findname(&path)) { rc = AFPERR_EXIST; /* was AFPERR_BUSY; */ } else { - rc = renamefile(vol, sdir_fd, p, upath, newname, adp ); + rc = renamefile(vol, sdir_fd, oldunixname, upath, newname, adp ); if (rc == AFP_OK) of_rename(vol, opened, sdir, oldname, curdir, newname); } } else { - rc = renamedir(vol, sdir_fd, p, upath, sdir, curdir, newname); + rc = renamedir(vol, sdir_fd, oldunixname, upath, sdir, curdir, newname); } if ( rc == AFP_OK && id ) { /* renaming may have moved the file/dir across a filesystem */ @@ -468,6 +375,13 @@ static int moveandrename(const struct vol *vol, (void)dir_remove(vol, cacheddir); } + /* Fixup adouble info */ + if (!ad_metadata(upath, adflags, adp)) { + ad_setid(adp, st->st_dev, st->st_ino, id, curdir->d_did, vol->v_stamp); + ad_flush(adp); + ad_close_metadata(adp); + } + /* fix up the catalog entry */ cnid_update(vol->v_cdb, id, st, curdir->d_did, upath, strlen(upath)); } @@ -475,6 +389,8 @@ static int moveandrename(const struct vol *vol, exit: if (cwd_fd != -1) close(cwd_fd); + if (oldunixname) + free(oldunixname); return rc; } @@ -665,9 +581,6 @@ int afp_moveandrename(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U int plen; u_int16_t vid; int rc; -#ifdef DROPKLUDGE - int retvalue; -#endif /* DROPKLUDGE */ int sdir_fd = -1; @@ -712,7 +625,7 @@ int afp_moveandrename(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U memcpy(oldname, cfrombstr(sdir->d_m_name), blength(sdir->d_m_name) + 1); } -#ifdef HAVE_RENAMEAT +#ifdef HAVE_ATFUNCS if ((sdir_fd = open(".", O_RDONLY)) == -1) return AFPERR_MISC; #endif @@ -756,28 +669,18 @@ int afp_moveandrename(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U } curdir->offcnt++; sdir->offcnt--; -#ifdef DROPKLUDGE - if (vol->v_flags & AFPVOL_DROPBOX) { - /* FIXME did is not always the source id */ - if ((retvalue=matchfile2dirperms (upath, vol, did)) != AFP_OK) { - rc = retvalue; - goto exit; - } - } - else -#endif /* DROPKLUDGE */ - /* if unix priv don't try to match perm with dest folder */ - if (!isdir && !vol_unix_priv(vol)) { - int admode = ad_mode("", 0777) | vol->v_fperm; + /* if unix priv don't try to match perm with dest folder */ + if (!isdir && !vol_unix_priv(vol)) { + int admode = ad_mode("", 0777) | vol->v_fperm; - setfilmode(upath, admode, NULL, vol->v_umask); - vol->vfs->vfs_setfilmode(vol, upath, admode, NULL); - } + setfilmode(upath, admode, NULL, vol->v_umask); + vol->vfs->vfs_setfilmode(vol, upath, admode, NULL); + } setvoltime(obj, vol ); } exit: -#ifdef HAVE_RENAMEAT +#ifdef HAVE_ATFUNCS if (sdir_fd != -1) close(sdir_fd); #endif