X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=libsysio%2Fsrc%2Fnamei.c;h=7f8c1e45427df2615d8967b64fd5c9b986fe67d0;hp=c4b60727405069d844f608a81be2203250973c05;hb=e59595df1694838b8f32527e0e6806b4730f78d1;hpb=567285197e592000b7a713d65b66e27314a11c2f diff --git a/libsysio/src/namei.c b/libsysio/src/namei.c index c4b6072..7f8c1e4 100644 --- a/libsysio/src/namei.c +++ b/libsysio/src/namei.c @@ -9,7 +9,7 @@ * terms of the GNU Lesser General Public License * (see cit/LGPL or http://www.gnu.org/licenses/lgpl.html) * - * Cplant(TM) Copyright 1998-2003 Sandia Corporation. + * Cplant(TM) Copyright 1998-2006 Sandia Corporation. * Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive * license for use of this work by or on behalf of the US Government. * Export of this program may require a license from the United States @@ -41,10 +41,6 @@ * lee@sandia.gov */ -#if defined(AUTOMOUNT_FILE_NAME) && defined(__linux__) -#define _BSD_SOURCE -#endif - #include #include #include @@ -88,7 +84,8 @@ lookup(struct pnode *parent, struct qstr *name, struct pnode **pnop, struct intent *intnt, - const char *path) + const char *path, + int check_permissions) { int err; struct pnode *pno; @@ -96,9 +93,15 @@ lookup(struct pnode *parent, if (!parent->p_base->pb_ino) return -ENOTDIR; - err = _sysio_permitted(parent->p_base->pb_ino, X_OK); - if (err) - return err; + /* + * Sometimes we don't want to check permissions. At initialization + * time, for instance. + */ + if (check_permissions) { + err = _sysio_permitted(parent, X_OK); + if (err) + return err; + } /* * Short-circuit `.' and `..'; We don't cache those. @@ -151,6 +154,7 @@ lookup(struct pnode *parent, * ND_NOFOLLOW symbolic links are not followed * ND_NEGOK if terminal/leaf does not exist, return * path node (alias) anyway. + * ND_NOPERMCHECK do not check permissions */ int _sysio_path_walk(struct pnode *parent, struct nameidata *nd) @@ -182,23 +186,26 @@ _sysio_path_walk(struct pnode *parent, struct nameidata *nd) parent = nd->nd_root; } -#if DEFER_INIT_CWD +#ifdef DEFER_INIT_CWD if (!parent) { const char *icwd; - if (!_sysio_init_cwd) + if (!_sysio_init_cwd && !nd->nd_root) abort(); /* - * Finally have to set the curretn working directory. We can + * Finally have to set the current working directory. We can * not tolerate errors here or else risk leaving the process * in a very unexpected location. We abort then unless all goes * well. */ icwd = _sysio_init_cwd; _sysio_init_cwd = NULL; - if (_sysio_namei(NULL, icwd, 0, NULL, &parent) != 0 || - _sysio_p_chdir(parent) != 0) + parent = nd->nd_root; + if (!parent) + abort(); + (void )_sysio_namei(nd->nd_root, icwd, 0, NULL, &parent); + if (_sysio_p_chdir(parent) != 0) abort(); } #endif @@ -257,12 +264,14 @@ _sysio_path_walk(struct pnode *parent, struct nameidata *nd) lpath[cc] = '\0'; /* NUL term */ /* * Handle symbolic links with recursion. Yuck! + * Pass the NULL intent for recursive symlink + * except the last component. */ ND_INIT(&nameidata, (nd->nd_flags | ND_NEGOK), lpath, nd->nd_root, - nd->nd_intent); + !next.len ? nd->nd_intent : NULL); nameidata.nd_slicnt = nd->nd_slicnt + 1; err = _sysio_path_walk(nd->nd_pno->p_parent, &nameidata); @@ -292,7 +301,8 @@ _sysio_path_walk(struct pnode *parent, struct nameidata *nd) &_sysio_mount_file_name, &pno, NULL, - NULL); + NULL, + 1); if (pno) P_RELE(pno); if (!err && _sysio_automount(pno) == 0) { @@ -405,7 +415,8 @@ _sysio_path_walk(struct pnode *parent, struct nameidata *nd) (path || !next.len) ? nd->nd_intent : NULL, - (path && next.len) ? path : NULL); + (path && next.len) ? path : NULL, + !(nd->nd_flags & ND_NOPERMCHECK)); if (err) { if (err == -ENOENT && !next.len &&