]> arthur.barton.de Git - netatalk.git/commitdiff
AFP3.x add unix privilege (new volume option upriv), fix double click and utf8
authordidg <didg>
Thu, 5 Jun 2003 09:17:07 +0000 (09:17 +0000)
committerdidg <didg>
Thu, 5 Jun 2003 09:17:07 +0000 (09:17 +0000)
name. Björn Fernhomberg and me.

12 files changed:
config/AppleVolumes.default
etc/afpd/desktop.c
etc/afpd/directory.c
etc/afpd/directory.h
etc/afpd/file.c
etc/afpd/file.h
etc/afpd/filedir.c
etc/afpd/fork.c
etc/afpd/unix.c
etc/afpd/unix.h
etc/afpd/volume.c
etc/afpd/volume.h

index 3777e65c773eb0f74e43c9d799d07482a42df199..fd146a1eff0a61a0ee63bd769113554e4085213f 100644 (file)
 # limitsize           -> limit disk size reporting to 2GB. this is
 #                        here for older macintoshes using newer
 #                        appleshare clients. yucko.
+# nofileid            -> don't advertise createfileid, resolveid, deleteid 
+#                        calls
+# upriv               -> use unix privilege.
 #
 # codepage:filename   -> load filename from nls directory.
 # dbpath:path         -> store the database stuff in the following path.
 # password:password   -> set a volume password (8 characters max)
-# nofileid            -> don't advertise createfileid, resolveid, deleteid 
-#                        calls
 #
 # The "~" below indicates that Home directories are visible by default.
 # If you do not wish to have people accessing their Home directories,
index 7e614581a0c6c60a8c875e910b2ab58813276c3b..c6a3e9173b078adf126ecdfb53d82426fdd5a63e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: desktop.c,v 1.28 2003-05-07 13:23:53 didg Exp $
+ * $Id: desktop.c,v 1.29 2003-06-05 09:17:10 didg Exp $
  *
  * See COPYRIGHT.
  *
@@ -1042,7 +1042,7 @@ int               ibuflen, *rbuflen;
     clen = min( clen, 199 );
 
     upath = path->u_name;
-    if (check_access(upath, OPENACC_WR ) < 0) {
+    if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
 
@@ -1178,7 +1178,7 @@ int               ibuflen, *rbuflen;
     }
 
     upath = s_path->u_name;
-    if (check_access(upath, OPENACC_WR ) < 0) {
+    if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
 
index 7f6660bba3140183afc6c0de018aec9e27aac829..e52c44537bc1543498a277a5df883995dbfde4aa 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.c,v 1.74 2003-05-20 14:46:50 didg Exp $
+ * $Id: directory.c,v 1.75 2003-06-05 09:17:11 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -164,6 +164,9 @@ struct dir *dir;
 /* -----------------------------------------
  * if did is not in the cache resolve it with cnid 
  * 
+ * FIXME
+ * OSX call it with bogus id, ie file ID not folder ID,
+ * and we are really bad in this case.
  */
 struct dir *
             dirlookup( vol, did )
@@ -1216,6 +1219,20 @@ char *p;
     return 0;
 }
 
+/* --------------------- */
+int file_access(struct path *path, int mode)
+{
+struct maccess ma;
+
+    accessmode(path->u_name, &ma, curdir, &path->st);
+    if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE))
+        return -1;
+    if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD))
+        return -1;
+    return 0;
+
+}
+
 /* ------------------------------ 
    (".", curdir)
    (name, dir) with curdir:name == dir, from afp_enumerate
@@ -1403,6 +1420,28 @@ int getdirparams(const struct vol *vol,
             }
             break;
 
+        case DIRPBIT_UNIXPR :
+            aint = htonl(st->st_uid);
+            memcpy( data, &aint, sizeof( aint ));
+            data += sizeof( aint );
+            aint = htonl(st->st_gid);
+            memcpy( data, &aint, sizeof( aint ));
+            data += sizeof( aint );
+       
+           aint = st->st_mode;
+           aint = htonl ( aint & ~S_ISGID );  /* Remove SGID, OSX doesn't like it ... */
+           memcpy( data, &aint, sizeof( aint ));
+           data += sizeof( aint );
+
+            accessmode( upath, &ma, dir , st);
+
+            *data++ = ma.ma_user;
+            *data++ = ma.ma_world;
+            *data++ = ma.ma_group;
+            *data++ = ma.ma_owner;
+            break;
+
+
         default :
             if ( isad ) {
                 ad_close( &ad, ADFLAGS_HF );
@@ -1776,6 +1815,56 @@ int setdirparams(const struct vol *vol,
                 buf += 6;
                 break;
             }
+
+       case DIRPBIT_UNIXPR :
+           /* Skip UID and GID for now, there seems to be now way to set them from an OSX client anyway */
+            buf += sizeof( aint );
+            buf += sizeof( aint );
+
+            change_mdate = 1;
+            change_parent_mdate = 1;
+            memcpy( &aint, buf, sizeof( aint ));
+            buf += sizeof( aint );
+           aint = ntohl (aint);
+            if (curdir->d_did == DIRDID_ROOT)
+                setdeskmode( aint );
+#if 0 /* don't error if we can't set the desktop mode */
+            switch ( errno ) {
+            case EPERM :
+            case EACCES :
+                err = AFPERR_ACCESS;
+                goto setdirparam_done;
+            case EROFS :
+                err = AFPERR_VLOCK;
+                goto setdirparam_done;
+            default :
+                LOG(log_error, logtype_afpd, "setdirparam: setdeskmode: %s",
+                    strerror(errno) );
+                break;
+                err = AFPERR_PARAM;
+                goto setdirparam_done;
+            }
+#endif /* 0 */
+
+            if ( setdirunixmode( aint, vol_noadouble(vol),
+                         (vol->v_flags & AFPVOL_DROPBOX)) < 0 ) {
+                switch ( errno ) {
+                case EPERM :
+                case EACCES :
+                    err = AFPERR_ACCESS;
+                    goto setdirparam_done;
+                case EROFS :
+                    err = AFPERR_VLOCK;
+                    goto setdirparam_done;
+                default :
+                    LOG(log_error, logtype_afpd, "setdirparam: setdirmode: %s",
+                        strerror(errno) );
+                    err = AFPERR_PARAM;
+                    goto setdirparam_done;
+                }
+            }
+            break;
+
         default :
             err = AFPERR_BITMAP;
             goto setdirparam_done;
index fff173ca8d1e2eb80a112e5b03879e6c1b60bd41..4cb1891b094a38d94103d17b5b55428a251eafc4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: directory.h,v 1.15 2003-05-20 14:46:50 didg Exp $
+ * $Id: directory.h,v 1.16 2003-06-05 09:17:11 didg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
@@ -137,6 +137,7 @@ extern int path_isadir(struct path *o_path);
 #define DIRPBIT_GID    11
 #define DIRPBIT_ACCESS 12
 #define DIRPBIT_PDINFO  13         /* ProDOS Info */
+#define DIRPBIT_UNIXPR  15
 
 /* directory attribute bits (see file.h for other bits) */
 #define ATTRBIT_EXPFOLDER   (1 << 1) /* shared point */
@@ -206,6 +207,7 @@ typedef int (*dir_loop)(struct dirent *, char *, void *);
 extern int  for_each_dirent __P((const struct vol *, char *, dir_loop , void *));
 
 extern int  check_access __P((char *name , int mode));
+extern int file_access   __P((struct path *path, int mode));
 
 extern int netatalk_unlink __P((const char *name));
 
index 2c340836b6a8f0778a8b1b92931c96822b823ce1..0cdeed19efbfc6b06ab33839b9b1f983d0eff3fb 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.93 2003-06-02 06:54:22 didg Exp $
+ * $Id: file.c,v 1.94 2003-06-05 09:17:11 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -143,7 +143,7 @@ char *set_name(const struct vol *vol, char *data, char *name, u_int32_t utf8)
         if (aint > 255)  /* FIXME safeguard, anyway if no ascii char it's game over*/
            aint = 255;
 
-        utf8 = htonl(utf8);
+        utf8 = 0;         /* htonl(utf8) */
         memcpy(data, &utf8, sizeof(utf8));
         data += sizeof(utf8);
         
@@ -263,6 +263,7 @@ int getmetadata(struct vol *vol,
     u_char              achar, fdType[4];
     u_int32_t           utf8 = 0;
     struct stat         *st;
+    struct maccess     ma;
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "begin getmetadata:");
 #endif /* DEBUG */
@@ -461,6 +462,26 @@ int getmetadata(struct vol *vol,
             memcpy(data, &aint, sizeof( aint ));
             data += sizeof( aint );
             break;
+        case FILPBIT_UNIXPR :
+            aint = htonl(st->st_uid);
+            memcpy( data, &aint, sizeof( aint ));
+            data += sizeof( aint );
+            aint = htonl(st->st_gid);
+            memcpy( data, &aint, sizeof( aint ));
+            data += sizeof( aint );
+
+            aint = htonl(st->st_mode);
+            memcpy( data, &aint, sizeof( aint ));
+            data += sizeof( aint );
+
+            accessmode( upath, &ma, dir , st);
+
+            *data++ = ma.ma_user;
+            *data++ = ma.ma_world;
+            *data++ = ma.ma_group;
+            *data++ = ma.ma_owner;
+            break;
+
         default :
             return( AFPERR_BITMAP );
         }
@@ -770,7 +791,7 @@ int setfilparams(struct vol *vol,
         adp = &ad;
     }
 
-    if (check_access(upath, OPENACC_WR ) < 0) {
+    if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
         return AFPERR_ACCESS;
     }
 
@@ -872,6 +893,19 @@ int setfilparams(struct vol *vol,
                 break;
             }
             /* fallthrough */
+        case FILPBIT_UNIXPR :
+           /* Skip the UIG/GID, no way to set them from OSX clients */
+            buf += sizeof( aint );
+            buf += sizeof( aint );
+
+            change_mdate = 1;
+            change_parent_mdate = 1;
+            memcpy( &aint, buf, sizeof( aint ));
+            buf += sizeof( aint );
+            aint = ntohl (aint);
+
+            setfilemode(path, aint);
+            break;
         default :
             err = AFPERR_BITMAP;
             goto setfilparam_done;
index f97ce03b4ac6ff2d93f1b66cd7b7c16d2c260c1d..ed6b1a93b5612780162852ca1eba97b5fef3afc5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.h,v 1.16 2003-03-09 19:55:34 didg Exp $
+ * $Id: file.h,v 1.17 2003-06-05 09:17:11 didg Exp $
  *
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
  * All Rights Reserved.
@@ -52,6 +52,7 @@ extern const u_char   ufinderi[];
 #define FILPBIT_EXTDFLEN 11
 #define FILPBIT_PDINFO   13    /* ProDOS Info/ UTF8 name */
 #define FILPBIT_EXTRFLEN 14
+#define FILPBIT_UNIXPR   15
 
 /* attribute bits. (d) = directory attribute bit as well. */
 #define ATTRBIT_INVISIBLE (1<<0)  /* invisible (d) */
index 22c0d7878d1f2bb75761c319383788a93c6a375b..d068182c96b424a32812ce0d669b163c791f1edd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: filedir.c,v 1.46 2003-05-03 20:03:13 didg Exp $
+ * $Id: filedir.c,v 1.47 2003-06-05 09:17:11 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -752,7 +752,8 @@ int         ibuflen, *rbuflen;
         }
         else
 #endif /* DROPKLUDGE */
-            if (!isdir) {
+            /* if unix priv don't try to match perm with dest folder */
+            if (!isdir && !vol_unix_priv(vol)) {
                 int  admode = ad_mode("", 0777);
 
                 setfilmode(upath, admode, NULL);
index ddc01fb31c2a7bd5ffea9391901d0e872b9d3573..b9bc22a44d5448110b4b935936ca41eb2cda680f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: fork.c,v 1.51 2003-03-15 01:34:35 didg Exp $
+ * $Id: fork.c,v 1.52 2003-06-05 09:17:11 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -329,8 +329,15 @@ int                ibuflen, *rbuflen;
     }
     /* FIXME should we check it first ? */
     upath = s_path->u_name;
-    if (check_access(upath, access ) < 0) {
-        return AFPERR_ACCESS;
+    if (!vol_unix_priv(vol)) {
+        if (check_access(upath, access ) < 0) {
+            return AFPERR_ACCESS;
+        }
+    }
+    else {
+        if (file_access(s_path, access ) < 0) {
+            return AFPERR_ACCESS;
+        }
     }
 
     st   = &s_path->st;
index 72b634e63898c9465b951ee98ccbd9673298e65a..2d4c4518b3ddeae5bc16f957533b77b59d5fd074 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: unix.c,v 1.43 2003-03-09 19:55:35 didg Exp $
+ * $Id: unix.c,v 1.44 2003-06-05 09:17:12 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -22,7 +22,6 @@
 #include <limits.h>
 #include <atalk/adouble.h>
 #include <atalk/afp.h>
-
 /* STDC check */
 #if STDC_HEADERS
 #include <string.h>
@@ -45,6 +44,7 @@ char *strchr (), *strrchr ();
 #include "directory.h"
 #include "volume.h"
 #include "unix.h"
+#include "fork.h"
 
 /*
  * Get the free space on a partition.
@@ -107,10 +107,10 @@ mode_t    bits;
 
     mbits = 0;
 
-    mbits |= ( bits & ( S_IREAD >> 6 )) ? (AR_UREAD | AR_USEARCH) : 0;
+    mbits |= ( bits & ( S_IREAD >> 6 ))  ? AR_UREAD  : 0;
     mbits |= ( bits & ( S_IWRITE >> 6 )) ? AR_UWRITE : 0;
-    /* Do we really need this?
-        mbits |= ( bits & ( S_IEXEC >> 6) ) ? AR_USEARCH : 0; */
+    /* Do we really need this? */
+    mbits |= ( bits & ( S_IEXEC >> 6) ) ? AR_USEARCH : 0;
 
     return( mbits );
 }
@@ -363,6 +363,26 @@ const mode_t       mode;
     return( 0 );
 }
 
+/* --------------------- */
+int setfilemode (path, mode)
+struct path* path;
+mode_t mode;
+{
+    if (!path->st_valid) {
+        of_stat(path);
+    }
+
+    if (path->st_errno) {
+        return -1;
+    }
+        
+    if (setfilmode( path->u_name, mode, &path->st) < 0)
+        return -1;
+    /* we need to set write perm if read set for resource fork */
+    return setfilmode(ad_path( path->u_name, ADFLAGS_HF ), ad_hf_mode(mode), &path->st);
+}
+
+/* --------------------- */
 int setfilmode(name, mode, st)
 char * name;
 mode_t mode;
@@ -384,6 +404,21 @@ mode_t mask = S_IRUSR |S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH;
    return 0;
 }
 
+/* --------------------- */
+int setdirunixmode( mode, noadouble, dropbox )
+const mode_t mode;
+const int noadouble;
+const int dropbox;
+{
+    if ( stickydirmode(".AppleDouble", DIRBITS | mode, dropbox) < 0 && !noadouble)
+        return  -1 ;
+
+    if ( stickydirmode(".", DIRBITS | mode, dropbox) < 0 )
+        return -1;
+    return 0;
+}
+
+/* --------------------- */
 int setdirmode( mode, noadouble, dropbox )
 const mode_t mode;
 const int noadouble;
index 3eba6c471b38fa5b292de546aeea935de47c8035..21b4854f2c051b5ca73115d61093ef23313dc340 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: unix.h,v 1.12 2003-01-07 15:55:22 rlewczuk Exp $
+ * $Id: unix.h,v 1.13 2003-06-05 09:17:12 didg Exp $
  */
 
 #ifndef AFPD_UNIX_H
@@ -98,15 +98,17 @@ extern int uquota_getvolspace __P((const struct vol *, VolSpace *, VolSpace *,
 
 extern struct afp_options default_options;
 
-extern int gmem         __P((const gid_t));
-extern int setdeskmode  __P((const mode_t));
-extern int setdirmode   __P((const mode_t, const int, const int));
-extern int setdeskowner __P((const uid_t, const gid_t));
-extern int setdirowner  __P((const uid_t, const gid_t, const int));
-extern int setfilmode   __P((char *, mode_t , struct stat *));
-extern int unix_rename  __P((const char *oldpath, const char *newpath));
-
-extern void accessmode  __P((char *, struct maccess *, struct dir *, struct stat *));
+extern int gmem            __P((const gid_t));
+extern int setdeskmode      __P((const mode_t));
+extern int setdirunixmode   __P((const mode_t, const int, const int));
+extern int setdirmode       __P((const mode_t, const int, const int));
+extern int setdeskowner     __P((const uid_t, const gid_t));
+extern int setdirowner      __P((const uid_t, const gid_t, const int));
+extern int setfilmode       __P((char *, mode_t , struct stat *));
+extern int setfilemode      __P((struct path*, const mode_t));
+extern int unix_rename      __P((const char *oldpath, const char *newpath));
+
+extern void accessmode      __P((char *, struct maccess *, struct dir *, struct stat *));
 
 #ifdef AFS     
     #define accessmode afsmode
index 3feae8427ae5902270555f851657b5731fe6ed00..bfc4715c69d4e05ab3aa1068fdee96e7b908958a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.c,v 1.52 2003-05-21 01:32:47 didg Exp $
+ * $Id: volume.c,v 1.53 2003-06-05 09:17:12 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -381,6 +381,8 @@ static void volset(struct vol_option *options, char *volname, int vlen,
                 options[VOLOPT_FLAGS].i_value |= AFPVOL_NOFILEID;
             else if (strcasecmp(p, "utf8") == 0)
                 options[VOLOPT_FLAGS].i_value |= AFPVOL_UTF8;
+            else if (strcasecmp(p, "upriv") == 0)
+                options[VOLOPT_FLAGS].i_value |= AFPVOL_UNIX_PRIV;
 
             p = strtok(NULL, ",");
         }
@@ -996,6 +998,8 @@ int         *buflen;
             ashort |= VOLPBIT_ATTR_CATSEARCH;
             if (afp_version >= 30) {
                 ashort |= VOLPBIT_ATTR_UTF8;
+               if (vol->v_flags & AFPVOL_UNIX_PRIV)
+                   ashort |= VOLPBIT_ATTR_UNIXPRIV;
             }
             ashort = htons(ashort);
             memcpy(data, &ashort, sizeof( ashort ));
@@ -1144,7 +1148,8 @@ int       ibuflen, *rbuflen;
            completely worked this out, but it's related to booting
            from the server.  Support for that function is a ways
            off.. <shirsch@ibm.net> */
-        *data++ |= (volume->v_flags & AFPVOL_A2VOL) ? AFPSRVR_CONFIGINFO : 0;
+        *data |= (volume->v_flags & AFPVOL_A2VOL) ? AFPSRVR_CONFIGINFO : 0;
+        *data++ |= 0; /* UNIX PRIVS BIT ..., OSX doesn't seem to use it, so we don't either */
         len = strlen( volume->v_name );
         *data++ = len;
         memcpy(data, volume->v_name, len );
index 6c4e49d9d97153ff82ac543ce1ecc8276563e39d..2f29f236cf1630c2aa229a3e03e8687ede85c8d1 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: volume.h,v 1.19 2003-03-09 20:37:27 didg Exp $
+ * $Id: volume.h,v 1.20 2003-06-05 09:17:12 didg Exp $
  *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -109,6 +109,7 @@ this is going away. */
 #define AFPVOL_DROPBOX   (1 << 14)  /* dropkludge dropbox support */
 #define AFPVOL_NOFILEID  (1 << 15)  /* don't advertise createid resolveid and deleteid calls */
 #define AFPVOL_UTF8      (1 << 16)  /* unix name are in UTF8 */
+#define AFPVOL_UNIX_PRIV (1 << 17)  /* support unix privileges */
 
 /* FPGetSrvrParms options */
 #define AFPSRVR_CONFIGINFO     (1 << 0)
@@ -169,6 +170,7 @@ int wincheck(const struct vol *vol, const char *path);
 #define vol_utf8(vol) (0)
 #define utf8_encoding() (0)
 #endif
+#define vol_unix_priv(vol) (afp_version >= 30 && ((vol)->v_flags & AFPVOL_UNIX_PRIV))
 
 extern struct vol      *getvolbyvid __P((const u_int16_t));
 extern int              ustatfs_getvolspace __P((const struct vol *,