X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fdirectory.c;h=44d40daf1143c9cc4c4acb9ff21d53f18ebe4beb;hb=2b55a3aa77d3bcda5c36eee42c7fab6a412e106e;hp=80188046882a38f6b338f3e0a094908cfe37e94c;hpb=59c5549240b6b5d6fc378c1c2c6f6d80d1ab0911;p=netatalk.git diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 80188046..44d40daf 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -1,5 +1,5 @@ /* - * $Id: directory.c,v 1.51 2002-11-05 18:47:43 pooba53 Exp $ + * $Id: directory.c,v 1.57 2003-01-21 09:58:58 didg Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -60,6 +60,7 @@ char *strchr (), *strrchr (); #include "unix.h" struct dir *curdir; +int afp_errno; #define SENTINEL (&sentinel) static struct dir sentinel = { SENTINEL, SENTINEL, NULL, DIRTREE_COLOR_BLACK, @@ -99,9 +100,10 @@ u_int32_t did; /* check for 0 did */ - if (!did) + if (!did) { + afp_errno = AFPERR_PARAM; return NULL; - + } if ( did == DIRDID_ROOT_PARENT ) { if (!rootpar.d_did) rootpar.d_did = DIRDID_ROOT_PARENT; @@ -110,6 +112,7 @@ u_int32_t did; } dir = vol->v_root; + afp_errno = AFPERR_NOOBJ; while ( dir != SENTINEL ) { if (dir->d_did == did) return dir->d_m_name ? dir : NULL; @@ -144,7 +147,8 @@ u_int32_t did; return ret; id = did; - if ((upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) == NULL) { + if (NULL == (upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) ) { + afp_errno = AFPERR_NOOBJ; return NULL; } ptr = path + MAXPATHLEN; @@ -159,13 +163,17 @@ u_int32_t did; if (ret != NULL) { break; } - if ((upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) == NULL) + if ((upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) == NULL) { + afp_errno = AFPERR_NOOBJ; return NULL; + } mpath = utompath(vol, upath); len = strlen(mpath) + 1; pathlen += len; - if (pathlen > 255) + if (pathlen > 255) { + afp_errno = AFPERR_PARAM; return NULL; + } strcpy(ptr - len, mpath); ptr -= len; } @@ -436,7 +444,6 @@ struct dir *dir; * process. It's fixable within afpd if fnctl_lock, doable with smb and * next to impossible for nfs and local filesystem access. */ - static void dir_invalidate( vol, dir ) const struct vol *vol; struct dir *dir; @@ -811,17 +818,16 @@ char **cpath; static struct path ret; char *data, *p; - char *u; int extend = 0; int len; - int olen = 0; u_int32_t hint; u_int16_t len16; int size = 0; char sep; data = *cpath; - switch (*data) { /* path type */ + afp_errno = AFPERR_NOOBJ; + switch (ret.m_type = *data) { /* path type */ case 2: data++; len = (unsigned char) *data++; @@ -839,17 +845,17 @@ char **cpath; len = ntohs(len16); data += 2; size = 7; - sep = '/'; + sep = 0; /* '/';*/ break; } /* else it's an error */ default: + afp_errno = AFPERR_PARAM; return( NULL ); } *cpath += len + size; *path = '\0'; - u = NULL; ret.m_name = path; ret.st_errno = 0; ret.st_valid = 0; @@ -857,45 +863,29 @@ char **cpath; if ( len == 0 ) { if ( !extend && movecwd( vol, dir ) < 0 ) { /* it's tricky: - movecwd failed so dir is not there anymore. + movecwd failed some of dir path are not there anymore. FIXME Is it true with other errors? - if path == '\0' ==> the cpath parameter is that dir, - and maybe we are trying to recreate it! So we can't - fail here. - + so we remove dir from the cache */ - if ( dir->d_did == DIRDID_ROOT_PARENT) - return NULL; - cdir = dir->d_parent; + if (dir->d_did == DIRDID_ROOT_PARENT) + return NULL; + if (afp_errno == AFPERR_ACCESS) + return NULL; + dir_invalidate(vol, dir); - if (*path != '\0' || u == NULL) { - /* FIXME: if path != '\0' then extend != 0 ? - * u == NUL ==> cpath is something like: - * toto\0\0\0 - */ - return NULL; - } - if (movecwd(vol, cdir) < 0) { - printf("can't change to parent\n"); - return NULL; /* give up the whole tree is out of synch*/ - } - /* restore the previous token */ - strncpy(path, u, olen); - path[olen] = '\0'; + return NULL; } - if (!ret.st_valid || *path == '\0') { + if (*path == '\0') { ret.u_name = "."; } return &ret; } - if (!*data || *data == sep ) { + if (*data == sep ) { data++; len--; } - u = NULL; - - while ( *data && *data == sep && len > 0 ) { + while (*data == sep && len > 0 ) { if ( dir->d_parent == NULL ) { return NULL; } @@ -906,11 +896,7 @@ char **cpath; /* would this be faster with strlen + strncpy? */ p = path; - if (len > 0) { - u = data; - olen = len; - } - while ( *data && *data != sep && len > 0 ) { + while ( *data != sep && len > 0 ) { *p++ = *data++; len--; } @@ -943,8 +929,10 @@ char **cpath; /* dir is not valid anymore we delete dir from the cache and abort. */ - if ( dir->d_did != DIRDID_ROOT_PARENT) + if ( dir->d_did != DIRDID_ROOT_PARENT && + (afp_errno != AFPERR_ACCESS)) { dir_invalidate(vol, dir); + } return NULL; } cdir = extenddir( vol, dir, &ret ); @@ -955,6 +943,7 @@ char **cpath; } if ( cdir == NULL ) { + if ( len > 0 ) { return NULL; } @@ -983,6 +972,7 @@ struct dir *dir; return( 0 ); } if ( dir->d_did == DIRDID_ROOT_PARENT) { + afp_errno = AFPERR_PARAM; return( -1 ); } @@ -990,19 +980,36 @@ struct dir *dir; *p-- = '\0'; *p = '.'; for ( d = dir; d->d_parent != NULL && d != curdir; d = d->d_parent ) { - *--p = '/'; u = d->d_u_name; n = strlen( u ); + if (p -n -1 < path) { + afp_errno = AFPERR_PARAM; + return -1; + } + *--p = '/'; p -= n; strncpy( p, u, n ); } if ( d != curdir ) { - *--p = '/'; n = strlen( vol->v_path ); + if (p -n -1 < path) { + afp_errno = AFPERR_PARAM; + return -1; + } + *--p = '/'; p -= n; strncpy( p, vol->v_path, n ); } if ( chdir( p ) < 0 ) { + switch (errno) { + case EACCES: + case EPERM: + afp_errno = AFPERR_ACCESS; + break; + default: + afp_errno = AFPERR_NOOBJ; + + } return( -1 ); } curdir = dir; @@ -1266,7 +1273,7 @@ int ibuflen, *rbuflen; memcpy( &vid, ibuf, sizeof( vid )); ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { return( AFPERR_PARAM ); } @@ -1276,16 +1283,16 @@ int ibuflen, *rbuflen; memcpy( &did, ibuf, sizeof( did )); ibuf += sizeof( int ); - if (( dir = dirlookup( vol, did )) == NULL ) { - return( AFPERR_NOOBJ ); + if (NULL == ( dir = dirlookup( vol, did )) ) { + return afp_errno; } memcpy( &bitmap, ibuf, sizeof( bitmap )); bitmap = ntohs( bitmap ); ibuf += sizeof( bitmap ); - if (( path = cname( vol, dir, &ibuf )) == NULL ) { - return( AFPERR_NOOBJ ); + if (NULL == ( path = cname( vol, dir, &ibuf )) ) { + return afp_errno; } if ( *path->m_name != '\0' ) { @@ -1299,7 +1306,7 @@ int ibuflen, *rbuflen; ibuf++; } - if (( rc = setdirparams(vol, path, bitmap, ibuf )) == AFP_OK ) { + if (AFP_OK == ( rc = setdirparams(vol, path, bitmap, ibuf )) ) { setvoltime(obj, vol ); } return( rc ); @@ -1312,6 +1319,7 @@ int ibuflen, *rbuflen; */ struct path Cur_Path = { + 0, "", /* mac name */ ".", /* unix name */ 0, /* stat is not set */ @@ -1637,7 +1645,7 @@ int ibuflen, *rbuflen; memcpy( &vid, ibuf, sizeof( vid )); ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { return( AFPERR_PARAM ); } @@ -1646,19 +1654,12 @@ int ibuflen, *rbuflen; memcpy( &did, ibuf, sizeof( did )); ibuf += sizeof( did ); - if (( dir = dirlookup( vol, did )) == NULL ) { + if (NULL == ( dir = dirlookup( vol, did )) ) { return( AFPERR_NOOBJ ); } - if (( s_path = cname( vol, dir, &ibuf )) == NULL ) { - switch( errno ) { - case EACCES: - return( AFPERR_ACCESS ); - case EEXIST: /* FIXME this one is impossible? */ - return( AFPERR_EXIST ); - default: - return( AFPERR_NOOBJ ); - } + if (NULL == ( s_path = cname( vol, dir, &ibuf )) ) { + return afp_errno; } /* FIXME check done elswhere? cname was able to move curdir to it! */ if (*s_path->m_name == '\0') @@ -1740,7 +1741,7 @@ const int noadouble; int len, err; /* existence check moved to afp_moveandrename */ - if ( rename( src, dst ) < 0 ) { + if ( unix_rename( src, dst ) < 0 ) { switch ( errno ) { case ENOENT : return( AFPERR_NOOBJ ); @@ -1932,7 +1933,7 @@ int pathlen; } if ( movecwd( vol, curdir->d_parent ) < 0 ) { - return( AFPERR_NOOBJ ); + return afp_errno; } if ( rmdir(fdir->d_u_name) < 0 ) { @@ -2152,24 +2153,19 @@ int ibuflen, *rbuflen; memcpy(&vid, ibuf, sizeof(vid)); ibuf += sizeof( vid ); - if (( vol = getvolbyvid( vid )) == NULL ) { + if (NULL == ( vol = getvolbyvid( vid )) ) { return( AFPERR_PARAM ); } memcpy(&did, ibuf, sizeof(did)); ibuf += sizeof(did); - if (( parentdir = dirlookup( vol, did )) == NULL ) { - return( AFPERR_NOOBJ ); + if (NULL == ( parentdir = dirlookup( vol, did )) ) { + return afp_errno; } - if (( path = cname( vol, parentdir, &ibuf )) == NULL ) { - switch( errno ) { - case EACCES: - return( AFPERR_ACCESS ); - default: - return( AFPERR_NOOBJ ); - } + if (NULL == ( path = cname( vol, parentdir, &ibuf )) ) { + return afp_errno; } if ( *path->m_name != '\0' ) {