/*
- * $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.
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 );
memcpy( data, &aint, sizeof( aint ));
data += sizeof( aint );
- accessmode( upath, &ma, dir , st);
*data++ = ma.ma_user;
*data++ = ma.ma_world;
int change_parent_mdate = 0;
int newdate = 0;
struct timeval tv;
+ uid_t f_uid;
+ gid_t f_gid;
#ifdef DEBUG
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.
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 */
}
/* XXX
- * here we need to switch to root
+ * here do we need to switch to root ?
*/
ad_init(&ads, vol->v_adouble);
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 */
/*
- * $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.
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
/*
- * $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
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 *));