]> arthur.barton.de Git - netatalk.git/commitdiff
1. Respect the kFPDeleteInhibitBit attribute
authorjmarcus <jmarcus>
Sun, 24 Mar 2002 17:43:39 +0000 (17:43 +0000)
committerjmarcus <jmarcus>
Sun, 24 Mar 2002 17:43:39 +0000 (17:43 +0000)
2. Fix a problem where deep aliases would cause resolveid to fail

Submitted by: didier <dgautheron@magic.fr>
MFH after: 1.5.3 is released

etc/afpd/directory.c
etc/afpd/directory.h
etc/afpd/file.c
etc/afpd/file.h
etc/afpd/filedir.c
include/atalk/cnid.h
libatalk/cnid/cnid_resolve.c

index 414ca4358093a56f239c394a618aec8a1aacfb11..46e4872d265d5a765f5ec788642a7a6557169a42 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.c,v 1.28 2002-03-24 01:23:40 sibaz Exp $
+ * $Id: directory.c,v 1.29 2002-03-24 17:43:39 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -120,7 +120,67 @@ u_int32_t  did;
     return NULL;
 }
 
+/* -----------------------------------------
+ * if did is not in the cache resolve it with cnid 
+ * 
+ */
+struct dir *
+            dirlookup( vol, did )
+            const struct vol   *vol;
+u_int32_t      did;
+{
+#ifdef CNID_DB
+    struct dir *ret;
+    char               *upath;
+    u_int32_t  id;
+    static char                path[MAXPATHLEN + 1];
+    int len;
+    int pathlen;
+    char *ptr;
+    static char buffer[12 + MAXPATHLEN + 1];
+    int buflen = 12 + MAXPATHLEN + 1;
+
+    ret = dirsearch(vol, did);
+    if (ret != NULL)
+        return ret;
+
+    id = did;
+    if ((upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) == NULL) {
+        return NULL;
+    }
+    ptr = path + MAXPATHLEN;
+    len = strlen(upath);
+    pathlen = len;          /* no 0 in the last part */
+    len++;
+    strcpy(ptr - len, upath);
+    ptr -= len;
+    while (1) {
+        ret = dirsearch(vol,id);
+        if (ret != NULL) {
+            break;
+        }
+        if ((upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) == NULL)
+            return NULL;
+        len = strlen(upath) + 1;
+        pathlen += len;
+        if (pathlen > 255)
+            return NULL;
+        strcpy(ptr - len, upath);
+        ptr -= len;
+    }
+    /* fill the cache */
+    ptr--;
+    *ptr = (unsigned char)pathlen;
+    ptr--;
+    *ptr = 2;
+    /* cname is not efficient */
+    if (cname( vol, ret, &ptr ) == NULL )
+        return NULL;
+#endif
+    return dirsearch(vol, did);
+}
 
+/* --------------------------- */
 /* rotate the tree to the left */
 static void dir_leftrotate(vol, dir)
 struct vol *vol;
@@ -1607,6 +1667,8 @@ int pathlen;
     struct stat st;
     struct dir *fdir;
     DIR *dp;
+    struct adouble     ad;
+    u_int16_t          ashort;
 #ifdef FORCE_UIDGID
     uidgidset          *uidgid;
 
@@ -1628,6 +1690,19 @@ int pathlen;
     set_uidgid  ( vol );
 #endif /* FORCE_UIDGID */
 
+    if ( ad_open( ".", ADFLAGS_HF|ADFLAGS_DIR, O_RDONLY,
+                  DIRBITS | 0777, &ad) == 0 ) {
+
+        ad_getattr(&ad, &ashort);
+        ad_close( &ad, ADFLAGS_HF );
+        if ((ashort & htons(ATTRBIT_NODELETE))) {
+#ifdef FORCE_UIDGID
+            restore_uidgid ( &uidgid );
+#endif /* FORCE_UIDGID */
+            return  AFPERR_OLOCK;
+        }
+    }
+
     /* delete stray .AppleDouble files. this happens to get .Parent files
        as well. */
     if ((dp = opendir(".AppleDouble"))) {
index c4770fbd36f378a1dcc388bee776ee40664bb68d..6a1629767ffd55968a13a3f354455bcf6d325e9c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.h,v 1.3 2001-12-03 05:03:38 jmarcus Exp $
+ * $Id: directory.h,v 1.4 2002-03-24 17:43:39 jmarcus Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
@@ -146,6 +146,7 @@ struct maccess {
 extern struct dir       *dirnew __P((const int));
 extern void             dirfree __P((struct dir *));
 extern struct dir      *dirsearch __P((const struct vol *, u_int32_t));
+extern struct dir      *dirlookup __P((const struct vol *, u_int32_t));
 extern struct dir      *adddir __P((struct vol *, struct dir *, char *,
                                                int, char *, int, struct stat *));
 extern struct dir       *dirinsert __P((struct vol *, struct dir *));
index 17029e0ba74f22a7508101592b16687e23ebf7d0..5341b687379754faa3e1c3e7ec2bbb417fe4efb4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.42 2002-03-24 01:23:40 sibaz Exp $
+ * $Id: file.c,v 1.43 2002-03-24 17:43:39 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -789,10 +789,10 @@ const int         noadouble;
             return AFPERR_VLOCK;
         case EXDEV :                   /* Cross device move -- try copy */
             if (( rc = copyfile(src, dst, newname, noadouble )) != AFP_OK ) {
-                deletefile( dst );
+                deletefile( dst, 0 );
                 return( rc );
             }
-            return deletefile( src );
+            return deletefile( src, 0);
         default :
             return( AFPERR_PARAM );
         }
@@ -1171,8 +1171,14 @@ copydata_done:
 }
 
 
-int deletefile( file )
+/* -----------------------------------
+   checkAttrib:   1 check kFPDeleteInhibitBit 
+   ie deletfile called from afp_delete
+   
+*/
+int deletefile( file, checkAttrib )
 char           *file;
+int         checkAttrib;
 {
     struct adouble     ad;
     int                        adflags, err = AFP_OK;
@@ -1233,6 +1239,18 @@ char             *file;
         }
         break; /* from the while */
     }
+    /*
+     * Does kFPDeleteInhibitBit (bit 8) set?
+     */
+    if (checkAttrib && (adflags & ADFLAGS_HF)) {
+        u_int16_t   bshort;
+
+        ad_getattr(&ad, &bshort);
+        if ((bshort & htons(ATTRBIT_NODELETE))) {
+            ad_close( &ad, adflags );
+            return(AFPERR_OLOCK);
+        }
+    }
 
     if ((adflags & ADFLAGS_HF) &&
             (ad_tmplock(&ad, ADEID_RFORK, locktype, 0, 0) < 0 )) {
@@ -1406,6 +1424,9 @@ int               ibuflen, *rbuflen;
     cnid_t             id;
     u_int16_t          vid, bitmap;
 
+    static char buffer[12 + MAXPATHLEN + 1];
+    int len = 12 + MAXPATHLEN + 1;
+
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "begin afp_resolveid:");
 #endif /* DEBUG */
@@ -1423,11 +1444,11 @@ int             ibuflen, *rbuflen;
     memcpy(&id, ibuf, sizeof( id ));
     ibuf += sizeof(id);
 
-    if ((upath = cnid_resolve(vol->v_db, &id)) == NULL) {
+    if ((upath = cnid_resolve(vol->v_db, &id, buffer, len)) == NULL) {
         return AFPERR_BADID;
     }
 
-    if (( dir = dirsearch( vol, id )) == NULL ) {
+    if (( dir = dirlookup( vol, id )) == NULL ) {
         return( AFPERR_PARAM );
     }
 
@@ -1477,6 +1498,8 @@ int               ibuflen, *rbuflen;
     cnid_t             id;
     cnid_t             fileid;
     u_short            vid;
+    static char buffer[12 + MAXPATHLEN + 1];
+    int len = 12 + MAXPATHLEN + 1;
 
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "begin afp_deleteid:");
@@ -1498,12 +1521,12 @@ int             ibuflen, *rbuflen;
     memcpy(&id, ibuf, sizeof( id ));
     ibuf += sizeof(id);
     fileid = id;
-    
-    if ((upath = cnid_resolve(vol->v_db, &id)) == NULL) {
+
+    if ((upath = cnid_resolve(vol->v_db, &id, buffer, len)) == NULL) {
         return AFPERR_NOID;
     }
 
-    if (( dir = dirsearch( vol, id )) == NULL ) {
+    if (( dir = dirlookup( vol, id )) == NULL ) {
         return( AFPERR_PARAM );
     }
 
@@ -1728,7 +1751,7 @@ int               ibuflen, *rbuflen;
 
     /* all this stuff is so that we can unwind a failed operation
      * properly. */
-
+err_temp_to_dest:
     /* rename dest to temp */
     renamefile(upath, temp, temp, vol_noadouble(vol));
     of_rename(vol, curdir, upath, curdir, temp);
index a6af6bb857c6a9ea53710df2aa3e923466e60b4e..738682b85b3fb4b7bf9cc9b193325951bbca1fb4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.h,v 1.5 2002-03-13 19:29:17 srittau Exp $
+ * $Id: file.h,v 1.6 2002-03-24 17:43:39 jmarcus Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
@@ -79,7 +79,7 @@ extern int getfilparams __P((struct vol *, u_int16_t, char *,
 extern int setfilparams __P((struct vol *, char *, u_int16_t, char *));
 extern int renamefile   __P((char *, char *, char *, const int));
 extern int copyfile     __P((char *, char *, char *, const int));
-extern int deletefile   __P((char *));
+extern int deletefile   __P((char *, int));
 
 /* FP functions */
 extern int      afp_exchangefiles __P((AFPObj *, char *, int, char *, int *));
index 50f4c4f0a1904178560190a7727c7a55e8713cb6..230802bcbf89359ea796bc38d3ee216608a0e65b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: filedir.c,v 1.25 2002-03-24 01:23:40 sibaz Exp $
+ * $Id: filedir.c,v 1.26 2002-03-24 17:43:39 jmarcus Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -179,7 +179,7 @@ int         ibuflen, *rbuflen;
     memcpy( &did, ibuf, sizeof( did ));
     ibuf += sizeof( did );
 
-    if (( dir = dirsearch( vol, did )) == NULL ) {
+    if (( dir = dirlookup( vol, did )) == NULL ) {
         return( AFPERR_NOOBJ );
     }
 
@@ -526,7 +526,7 @@ int         ibuflen, *rbuflen;
         rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
     } else if (of_findname(vol, curdir, path)) {
         rc = AFPERR_BUSY;
-    } else if ((rc = deletefile( upath = mtoupath(vol, path ))) == AFP_OK) {
+    } else if ((rc = deletefile( upath = mtoupath(vol, path ), 1)) == AFP_OK) {
 #ifdef CNID_DB /* get rid of entry */
         cnid_t id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
         cnid_delete(vol->v_db, id);
index 43ac5006aa6eb0b7730524a00f961a8b97291ff3..d96e8a858053a602f3f2602ca968f03e4019e146 100644 (file)
@@ -34,7 +34,7 @@ extern cnid_t cnid_add __P((void *, const struct stat *, const cnid_t,
 
 /* cnid_get.c */
 extern cnid_t cnid_get __P((void *, const cnid_t, const char *, const int)); 
-extern char *cnid_resolve __P((void *, cnid_t *)); 
+extern char *cnid_resolve __P((void *, cnid_t *, void *, u_int32_t )); 
 extern cnid_t cnid_lookup __P((void *, const struct stat *, const cnid_t,
                               const char *, const int));
 
index 5a115abaa8bef382a72741b2ea0e806af7358391..c542a4ed31e4a00b2b0cc64d61d4c6d5b96d3b74 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: cnid_resolve.c,v 1.11 2002-01-19 21:42:08 jmarcus Exp $
+ * $Id: cnid_resolve.c,v 1.12 2002-03-24 17:43:42 jmarcus Exp $
  */
 
 #ifdef HAVE_CONFIG_H
@@ -22,7 +22,7 @@
 #include "cnid_private.h"
 
 /* Return the did/name pair corresponding to a CNID. */
-char *cnid_resolve(void *CNID, cnid_t *id) {
+char *cnid_resolve(void *CNID, cnid_t *id, void *buffer, u_int32_t len) {
     CNID_private *db;
     DBT key, data;
     int rc;
@@ -34,6 +34,10 @@ char *cnid_resolve(void *CNID, cnid_t *id) {
     memset(&key, 0, sizeof(key));
     memset(&data, 0, sizeof(data));
 
+    data.data = buffer;
+    data.ulen = len;
+    data.flags = DB_DBT_USERMEM;
+
     key.data = id;
     key.size = sizeof(cnid_t);
     while ((rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0))) {