From: Frank Lahm Date: Wed, 9 Jun 2010 13:59:30 +0000 (+0200) Subject: Merge from branch-2-1: umask on upriv volumes X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=1575c0ad7f67747019a3eb550d942406daa87d6e;hp=57d79bdc32c47eb988ead24623f5d42acb080297 Merge from branch-2-1: umask on upriv volumes --- diff --git a/NEWS b/NEWS index 70235ff4..64908a2f 100644 --- a/NEWS +++ b/NEWS @@ -4,7 +4,11 @@ Changes in 2.1.2 * FIX: afpd: fix for possible crash in case more then one server is configured in afpd.conf. * FIX: afpd: ExtendedAttributes in FreeBSD - +* FIX: afpd: sharing home folders corrupted the per volume umask. +* UPD: afpd: umask for home folders is no longer taken from startup umask. +* UPD: afpd: dont and permissions with parent folder when creating new + directories on "upriv" volumes. + Changes in 2.1.1 ================ diff --git a/etc/afpd/afp_dsi.c b/etc/afpd/afp_dsi.c index 1b10187a..54e5c4b6 100644 --- a/etc/afpd/afp_dsi.c +++ b/etc/afpd/afp_dsi.c @@ -74,10 +74,14 @@ static void afp_dsi_close(AFPObj *obj) * as uid 0, that's the wrong user for volume's prexec_close scripts if any, * restore our login user */ - if (seteuid( obj->uid ) < 0) { - LOG(log_error, logtype_afpd, "can't seteuid back %s", strerror(errno)); - exit(EXITERR_SYS); + if (geteuid() != obj->uid) { + if (seteuid( obj->uid ) < 0) { + LOG(log_error, logtype_afpd, "can't seteuid(%u) back %s: uid: %u, euid: %u", + obj->uid, strerror(errno), getuid(), geteuid()); + exit(EXITERR_SYS); + } } + close_all_vol(); if (obj->logout) (*obj->logout)(); diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 467bc62d..03bb0146 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -85,9 +85,24 @@ struct path Cur_Path = { /* ------------------------- appledouble mkdir afp error code. */ -static int netatalk_mkdir(const char *name) +static int netatalk_mkdir(const struct vol *vol, const char *name) { - if (ad_mkdir(name, DIRBITS | 0777) < 0) { + int ret; + struct stat st; + + if (vol->v_flags & AFPVOL_UNIX_PRIV) { + if (lstat(".", &st) < 0) + return AFPERR_MISC; + int mode = (DIRBITS & (~S_ISGID & st.st_mode)) | (0777 & ~vol->v_umask); + LOG(log_maxdebug, logtype_afpd, "netatalk_mkdir(\"%s\") {parent mode: %04o, vol umask: %04o}", + name, st.st_mode, vol->v_umask); + + ret = mkdir(name, mode); + } else { + ret = ad_mkdir(name, DIRBITS | 0777); + } + + if (ret < 0) { switch ( errno ) { case ENOENT : return( AFPERR_NOOBJ ); @@ -178,7 +193,7 @@ static int copydir(const struct vol *vol, int dirfd, char *src, char *dst) return AFPERR_PARAM; /* try to create the destination directory */ - if (AFP_OK != (err = netatalk_mkdir(dst)) ) { + if (AFP_OK != (err = netatalk_mkdir(vol, dst)) ) { closedir(dp); return err; } @@ -2086,7 +2101,7 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ upath = s_path->u_name; - if (AFP_OK != (err = netatalk_mkdir( upath))) { + if (AFP_OK != (err = netatalk_mkdir(vol, upath))) { return err; } diff --git a/etc/afpd/volume.c b/etc/afpd/volume.c index 23901150..03bc2be2 100644 --- a/etc/afpd/volume.c +++ b/etc/afpd/volume.c @@ -1,6 +1,4 @@ /* - * $Id$ - * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. */ @@ -1131,6 +1129,9 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us /* Enable some default options for all volumes */ save_options[VOLOPT_FLAGS].i_value |= AFPVOL_CACHE; save_options[VOLOPT_EA_VFS].i_value = AFPVOL_EA_AUTO; + LOG(log_maxdebug, logtype_afpd, "readvolfile: seeding default umask: %04o", + obj->options.umask); + save_options[VOLOPT_UMASK].i_value = obj->options.umask; while ( myfgets( buf, sizeof( buf ), fp ) != NULL ) { initline( strlen( buf ), buf ); @@ -1171,10 +1172,6 @@ static int readvolfile(AFPObj *obj, struct afp_volume_name *p1, char *p2, int us strcat( tmp, "/" ); strcat( tmp, p ); } - /* Tag a user's home directory with their umask. Note, this will - * be overwritten if the user actually specifies a umask: option - * for a '~' volume. */ - save_options[VOLOPT_UMASK].i_value = obj->options.save_mask; /* fall through */ case '/' :