From 40d96a4604aee6831230e2ab4abb17ba9247891e Mon Sep 17 00:00:00 2001 From: didg Date: Sun, 28 Feb 2010 22:29:15 +0000 Subject: [PATCH] previous commit 'lchdir: use chdir + getcwd' was only testing for symlink outside the volume's root directory, hopefully this one is correct --- etc/afpd/catsearch.c | 2 +- etc/afpd/directory.c | 7 +++---- include/atalk/util.h | 5 ++--- libatalk/util/unix.c | 50 ++++++++++++++++++++++++++++++++++++++------ 4 files changed, 50 insertions(+), 14 deletions(-) diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 97069c87..a1e96dfc 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -542,7 +542,7 @@ static int catsearch(struct vol *vol, struct dir *dir, while ((cidx = reducestack()) != -1) { cached = 1; - error = lchdir(vol, dstack[cidx].path); + error = lchdir(dstack[cidx].path); if (!error && dirpos == NULL) { dirpos = opendir("."); diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 9238cd18..8e41298f 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -1,5 +1,5 @@ /* - * $Id: directory.c,v 1.136 2010-02-28 17:02:49 didg Exp $ + * $Id: directory.c,v 1.137 2010-02-28 22:29:15 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -1553,8 +1553,7 @@ int movecwd(struct vol *vol, struct dir *dir) } p = path + sizeof(path) - 1; - *p-- = '\0'; - *p = '.'; + *p = '\0'; for ( d = dir; d->d_parent != NULL && d != curdir; d = d->d_parent ) { u = d->d_u_name; if (!u) { @@ -1581,7 +1580,7 @@ int movecwd(struct vol *vol, struct dir *dir) p -= n; memcpy( p, vol->v_path, n ); } - if ( (ret = lchdir(vol, p )) != 0 ) { + if ( (ret = lchdir(p )) != 0 ) { LOG(log_debug, logtype_afpd, "movecwd('%s'): ret:%d, %u/%s", p, ret, errno, strerror(errno)); if (ret == 1) { diff --git a/include/atalk/util.h b/include/atalk/util.h index 0106db2f..0d1f59ae 100644 --- a/include/atalk/util.h +++ b/include/atalk/util.h @@ -1,5 +1,5 @@ /* - * $Id: util.h,v 1.20 2010-02-28 17:02:49 didg Exp $ + * $Id: util.h,v 1.21 2010-02-28 22:29:16 didg Exp $ */ /*! @@ -22,7 +22,6 @@ #endif /* HAVE_UNISTD_H */ #include #include -#include /* exit error codes */ #define EXITERR_CLNT 1 /* client related error */ @@ -122,6 +121,6 @@ extern int compare_ip(const struct sockaddr *sa1, const struct sockaddr *sa2); *****************************************************************/ extern const char *getcwdpath(void); -extern int lchdir(struct vol *vol, const char *dir); +extern int lchdir(const char *dir); #endif /* _ATALK_UTIL_H */ diff --git a/libatalk/util/unix.c b/libatalk/util/unix.c index 9fd11e61..6231a037 100644 --- a/libatalk/util/unix.c +++ b/libatalk/util/unix.c @@ -1,5 +1,5 @@ /* - $Id: unix.c,v 1.5 2010-02-28 17:02:49 didg Exp $ + $Id: unix.c,v 1.6 2010-02-28 22:29:16 didg Exp $ Copyright (c) 2010 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -64,10 +63,22 @@ const char *getcwdpath(void) * * @returns 1 if a path element is a symlink, 0 otherwise, -1 on syserror */ -int lchdir(struct vol *vol, const char *dir) +int lchdir(const char *dir) { char buf[MAXPATHLEN+1]; + char cwd[MAXPATHLEN+1]; + char *test; + int i; + /* + dir is a canonical path (without "../" "./" "//" ) + but may end with a / + */ + *cwd = 0; + if (*dir != '/') { + if (getcwd(cwd, MAXPATHLEN) == NULL) + return -1; + } if (chdir(dir) != 0) return -1; @@ -83,11 +94,38 @@ int lchdir(struct vol *vol, const char *dir) if (getcwd(buf, MAXPATHLEN) == NULL) return 1; - for (int i = 0; vol->v_path[i]; i++) { - if (buf[i] != vol->v_path[i]) { + i = 0; + if (*cwd) { + /* relative path requested, + * Same directory? + */ + for (; cwd[i]; i++) { + if (buf[i] != cwd[i]) + return 1; + } + if (buf[i]) { + if (buf[i] != '/') + return 1; + i++; + } + } + + test = &buf[i]; + for (i = 0; test[i]; i++) { + if (test[i] != dir[i]) { return 1; } } - + /* trailing '/' ? */ + if (!dir[i]) + return 0; + + if (dir[i] != '/') + return 1; + + i++; + if (dir[i]) + return 1; + return 0; } -- 2.39.2