]> arthur.barton.de Git - netatalk.git/commitdiff
fpexchangefile keep owner and file mode.
authordidg <didg>
Fri, 12 Mar 2004 13:03:18 +0000 (13:03 +0000)
committerdidg <didg>
Fri, 12 Mar 2004 13:03:18 +0000 (13:03 +0000)
etc/afpd/file.c
etc/afpd/unix.c
etc/afpd/unix.h

index ac408bc2c8a1c630060663787a0ed03783de8cc6..137fb659e9f50ce9165dfdd0486648ec264d6b4c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: file.c,v 1.92.2.2.2.21 2004-03-12 02:21:19 didg Exp $
+ * $Id: file.c,v 1.92.2.2.2.22 2004-03-12 13:03:18 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -455,6 +455,9 @@ int getmetadata(struct vol *vol,
             data += sizeof( aint );
             break;
         case FILPBIT_UNIXPR :
+            /* accessmode may change st_mode with ACLs */
+            accessmode( upath, &ma, dir , st);
+
             aint = htonl(st->st_uid);
             memcpy( data, &aint, sizeof( aint ));
             data += sizeof( aint );
@@ -466,7 +469,6 @@ int getmetadata(struct vol *vol,
             memcpy( data, &aint, sizeof( aint ));
             data += sizeof( aint );
 
-            accessmode( upath, &ma, dir , st);
 
             *data++ = ma.ma_user;
             *data++ = ma.ma_world;
@@ -771,6 +773,8 @@ int setfilparams(struct vol *vol,
     int                 change_parent_mdate = 0;
     int                 newdate = 0;
     struct timeval      tv;
+    uid_t              f_uid;
+    gid_t              f_gid;
 
 
 #ifdef DEBUG
@@ -861,16 +865,20 @@ int setfilparams(struct vol *vol,
             break;
 
         case FILPBIT_UNIXPR :
-           /* Skip the UIG/GID, no way to set them from OSX clients */
+            change_mdate = 1;
+            change_parent_mdate = 1;
+
+            memcpy( &aint, buf, sizeof( aint ));
+            f_uid = ntohl (aint);
             buf += sizeof( aint );
+            memcpy( &aint, buf, sizeof( aint ));
+            f_gid = ntohl (aint);
             buf += sizeof( aint );
+            setfilowner(vol, f_uid, f_gid, path);
 
-            change_mdate = 1;
-            change_parent_mdate = 1;
             memcpy( &aint, buf, sizeof( aint ));
             buf += sizeof( aint );
             aint = ntohl (aint);
-
             setfilunixmode(vol, path, aint);
             break;
             /* Client needs to set the ProDOS file info for this file.
@@ -1885,6 +1893,9 @@ int               ibuflen, *rbuflen;
     u_int32_t          sid, did;
     u_int16_t          vid;
 
+    uid_t              uid;
+    gid_t              gid;
+
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "begin afp_exchangefiles:");
 #endif /* DEBUG */
@@ -1922,7 +1933,7 @@ int               ibuflen, *rbuflen;
     }
 
     /* XXX 
-     * here we need to switch to root 
+     * here do we need to switch to root ?
     */
 
     ad_init(&ads, vol->v_adouble);
@@ -2041,6 +2052,43 @@ int              ibuflen, *rbuflen;
        ad_flush( addp, ADFLAGS_HF );
        ad_close(addp, ADFLAGS_HF);
     }
+
+    /* change perms, src gets dest perm and vice versa */
+
+    uid = geteuid();
+    gid = getegid();
+    if (seteuid(0)) {
+        LOG(log_error, logtype_afpd, "seteuid failed %s", strerror(errno));
+        return AFP_OK; /* ignore error */
+    }
+
+    /*
+     * we need to exchange ACL entries as well
+     */
+    /* exchange_acls(vol, p, upath); */
+
+    path->st = srcst;
+    path->st_valid = 1;
+    path->st_errno = 0;
+    path->m_name = NULL;
+    path->u_name = upath;
+
+    setfilunixmode(vol, path, destst.st_mode);
+    setfilowner(vol, destst.st_uid, destst.st_gid, path);
+
+    path->st = destst;
+    path->st_valid = 1;
+    path->st_errno = 0;
+    path->u_name = p;
+
+    setfilunixmode(vol, path, srcst.st_mode);
+    setfilowner(vol, srcst.st_uid, srcst.st_gid, path);
+
+    if ( setegid(gid) < 0 || seteuid(uid) < 0) {
+        LOG(log_error, logtype_afpd, "can't seteuid back %s", strerror(errno));
+        exit(1);
+    }
+
 #ifdef DEBUG
     LOG(log_info, logtype_afpd, "ending afp_exchangefiles:");
 #endif /* DEBUG */
index e07b305b327a3e708b08f9b1bf82b7a5137442ca..2caa90b9a2b4b90b1dc693c497874235b5485f20 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: unix.c,v 1.43.2.1.2.4 2004-03-11 02:02:03 didg Exp $
+ * $Id: unix.c,v 1.43.2.1.2.5 2004-03-12 13:03:19 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved.  See COPYRIGHT.
@@ -586,6 +586,45 @@ const gid_t        gid;
     return( 0 );
 }
 
+/* ----------------------------- */
+int setfilowner(vol, uid, gid, path)
+const struct vol *vol;
+const uid_t    uid;
+const gid_t    gid;
+struct path* path;
+{
+    struct stat st;
+    char  *ad_p;
+
+    if (!path->st_valid) {
+        of_stat(path);
+    }
+
+    if (path->st_errno) {
+        return -1;
+    }
+
+    if ( chown( path->u_name, uid, gid ) < 0 && errno != EPERM ) {
+        LOG(log_debug, logtype_afpd, "setfilowner: chown %d/%d %s: %s",
+            uid, gid, path->u_name, strerror(errno) );
+       return -1;
+    }
+
+    ad_p = vol->ad_path( path->u_name, ADFLAGS_HF );
+
+    if ( stat( ad_p, &st ) < 0 ) {
+       /* ignore */
+        return 0;
+    }
+    if ( chown( ad_p, uid, gid ) < 0 &&
+            errno != EPERM ) {
+        LOG(log_debug, logtype_afpd, "setfilowner: chown %d/%d %s: %s",
+            uid, gid, ad_p, strerror(errno) );
+        return -1;
+    }
+    return 0;
+}
+
 
 /* --------------------------------- 
  * uid/gid == 0 need to be handled as special cases. they really mean
index 25ed2da2f7dd2d176a87c9004fb889cc80625e43..2c4cf8d03eb0a8be1040e27522fbc5abef1aa2f2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: unix.h,v 1.12.2.1.2.3 2004-03-11 02:02:03 didg Exp $
+ * $Id: unix.h,v 1.12.2.1.2.4 2004-03-12 13:03:19 didg Exp $
  */
 
 #ifndef AFPD_UNIX_H
@@ -223,6 +223,7 @@ extern int setdeskowner     __P((const uid_t, const gid_t));
 extern int setdirowner      __P((const struct vol *, const uid_t, const gid_t));
 extern int setfilmode       __P((char *, mode_t , struct stat *));
 extern int setfilunixmode   __P((const struct vol *, struct path*, const mode_t));
+extern int setfilowner      __P((const struct vol *, const uid_t, const gid_t, struct path*));
 extern int unix_rename      __P((const char *oldpath, const char *newpath));
 
 extern void accessmode      __P((char *, struct maccess *, struct dir *, struct stat *));