Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Date: Thu, 24 Apr 2003 09:24:53 -0400 From: Jason Tishler Subject: Re: proftpd running on cygwin In-reply-to: To: TJ Saunders Cc: Cygwin Mail-followup-to: TJ Saunders , Cygwin Message-id: <20030424132452.GA1636@tishler.net> MIME-version: 1.0 Content-type: multipart/mixed; boundary="Boundary_(ID_IFQvdaYPORwPQ8mQZYqQag)" User-Agent: Mutt/1.4i References: <20030423203556 DOT GA504 AT tishler DOT net> --Boundary_(ID_IFQvdaYPORwPQ8mQZYqQag) Content-type: text/plain; charset=us-ascii Content-transfer-encoding: 7BIT Content-disposition: inline TJ, On Wed, Apr 23, 2003 at 07:39:13PM -0700, TJ Saunders wrote: > jason>The patch is in the following post: > jason> > jason> http://cygwin.com/ml/cygwin/2003-04/msg01918.html > jason> > jason>Please test it and then try to get it accepted into proftp CVS. I guess my posts to weren't rejected after all... :,) > Attached is your patch, updated for current CVS. The patch is pretty > much the same, with one minor addition (checking of uid 0 for > RootLogin). If this patch works for you, just let me know and I'll > commit to CVS. I checked out the latest proftpd CVS, applied your updated patch, built, and tested proftpd. The following are my observations: 1. proftpd functions properly when running under the LocalSystem user and Administrators group 2. proftpd does not function properly running under a less privileged user such as nobody by setting "User nobody" in proftpd.conf. The following error is displayed when a user attempts to log in: 5 [win] conn 756 Winmain: Cannot create window c:\home\jt\src\proftp\proftpd.exe: *** WFSO failed, Win32 error 6 Unless someone is willing to debug and fix the above problem (if possible), then my suggestion is to just document that Cygwin proftpd must run under the LocalSystem user and Administrators group. 3. proftpd displays the following non-fatal error messages when a user logs in: TISHLERJASON - error setting write fd IP_TOS: Invalid argument TISHLERJASON - error setting read fd IP_TOS: Invalid argument TISHLERJASON - error setting write fd TCP_NOPUSH: Protocol not available TISHLERJASON - error setting read fd TCP_NOPUSH: Protocol not available 4. proftpd complains about a world writable directory even in no daemon mode: TISHLERJASON (127.0.0.1[127.0.0.1]) - error: /var/log is a world writeable directory Note that Cygwin typically runs Unix daemons under a NT service wrapper called cygrunsrv which exploits options such as "--nodaemon" and handles logging. Clearly, only 1 and 2 above are related to this patch, but I wanted to log the other issues so that hopefully they can be addressed too. Please commit your patch. Thanks, Jason -- PGP/GPG Key: http://www.tishler.net/jason/pubkey.asc or key servers Fingerprint: 7A73 1405 7F2B E669 C19D 8784 1AFD E4CC ECF4 8EF6 --Boundary_(ID_IFQvdaYPORwPQ8mQZYqQag) Content-type: message/rfc822 Received: from cust_req_fwding (jason AT tishler DOT net --> jt AT tishler DOT net) by lmg.ahnet.net id <294497-25331>; Wed, 23 Apr 2003 19:53:04 -0700 Received: from mercury.gostnet.com ([207.178.3.3]) by lmg.ahnet.net with ESMTP id <293849-25332>; Wed, 23 Apr 2003 19:51:56 -0700 Received: from localhost (tj AT localhost) by mercury.gostnet.com (8.11.2/8.11.2) with ESMTP id h3O2dDZ10947 for ; Wed, 23 Apr 2003 19:39:13 -0700 Date: Wed, 23 Apr 2003 19:39:13 -0700 (PDT) From: TJ Saunders Subject: Re: proftpd running on cygwin In-reply-to: <20030423203556 DOT GA504 AT tishler DOT net> X-X-Sender: To: Jason Tishler Message-id: MIME-version: 1.0 Content-type: multipart/mixed; boundary="Boundary_(ID_A8VgWoVu44Z1AoaDBI8jFg)" X-Bogosity: No, tests=bogofilter, spamicity=0.000017, version=0.11.1.3 This message is in MIME format. The first part should be readable text, while the remaining parts are likely unreadable without MIME-aware tools. Send mail to mime AT docserver DOT cac DOT washington DOT edu for more info. --Boundary_(ID_A8VgWoVu44Z1AoaDBI8jFg) Content-type: TEXT/PLAIN; charset=US-ASCII Content-transfer-encoding: 7BIT jason>The patch is in the following post: jason> jason> http://cygwin.com/ml/cygwin/2003-04/msg01918.html jason> jason>Please test it and then try to get it accepted into proftp CVS. Attached is your patch, updated for current CVS. The patch is pretty much the same, with one minor addition (checking of uid 0 for RootLogin). If this patch works for you, just let me know and I'll commit to CVS. Cheers, TJ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To love is to place our happiness in the happiness of another. -Gottfried Wilhelm von Leibniz ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --Boundary_(ID_A8VgWoVu44Z1AoaDBI8jFg) Content-id: Content-type: TEXT/PLAIN; charset=US-ASCII; name=cygwin-root-id.patch Content-transfer-encoding: 7BIT Content-disposition: attachment; filename=cygwin-root-id.patch Content-description: Index: include/privs.h =================================================================== RCS file: /cvsroot/proftp/proftpd/include/privs.h,v retrieving revision 1.19 diff -u -r1.19 privs.h --- include/privs.h 23 Apr 2003 06:53:22 -0000 1.19 +++ include/privs.h 24 Apr 2003 02:45:36 -0000 @@ -30,6 +30,18 @@ #ifndef PR_PRIVS_H #define PR_PRIVS_H +/* Definition of root user/group IDs (non-Unix platforms may have these as + * different from 0/0). + */ + +#ifdef __CYGWIN__ +# define PR_ROOT_UID 18 +# define PR_ROOT_GID 544 +#else +# define PR_ROOT_UID 0 +# define PR_ROOT_GID 0 +#endif /* __CYGWIN__ */ + /* Macros for manipulating saved, real and effective uid for easy * switching from/to root. * @@ -75,7 +87,7 @@ # define PRIVS_SETUP(u, g) { \ log_debug(DEBUG9, "SETUP PRIVS at %s:%d", __FILE__, __LINE__); \ - if (getuid()) { \ + if (getuid() != PR_ROOT_UID) { \ session.ouid = session.uid = getuid(); \ session.gid = getgid(); \ if (setgid(session.gid)) \ @@ -91,7 +103,7 @@ if (setgid(session.gid)) \ log_pri(PR_LOG_ERR, "PRIVS_SETUP: unable to setgid(): %s", \ strerror(errno)); \ - if (setreuid(0, session.uid)) \ + if (setreuid(PR_ROOT_UID, session.uid)) \ log_pri(PR_LOG_ERR, "PRIVS_SETUP: unable to setreuid(): %s", \ strerror(errno)); \ } \ @@ -100,10 +112,10 @@ # define PRIVS_ROOT { \ log_debug(DEBUG9, "ROOT PRIVS at %s:%d", __FILE__, __LINE__); \ if (!session.disable_id_switching) { \ - if (setregid(session.gid,0)) \ + if (setregid(session.gid, PR_ROOT_GID)) \ log_pri(PR_LOG_ERR, "PRIVS_ROOT: unable to setregid(): %s", \ strerror(errno)); \ - if (setreuid(session.uid, 0)) \ + if (setreuid(session.uid, PR_ROOT_UID)) \ log_pri(PR_LOG_ERR, "PRIVS_ROOT: unable to setreuid(): %s", \ strerror(errno)); \ } else \ @@ -114,8 +126,8 @@ log_debug(DEBUG9, "USER PRIVS %d at %s:%d", (int) session.login_uid, \ __FILE__, __LINE__); \ if (!session.disable_id_switching) { \ - if (setreuid(session.uid,0)) \ - log_pri(PR_LOG_ERR, "PRIVS_USER: unable to setreuid(session.uid, 0): %s", \ + if (setreuid(session.uid, PR_ROOT_UID)) \ + log_pri(PR_LOG_ERR, "PRIVS_USER: unable to setreuid(session.uid, PR_ROOT_UID): %s", \ strerror(errno)); \ if (setreuid(session.uid, session.login_uid)) \ log_pri(PR_LOG_ERR, "PRIVS_USER: unable to setreuid(session.uid, " \ @@ -127,18 +139,18 @@ # define PRIVS_RELINQUISH { \ log_debug(DEBUG9, "RELINQUISH PRIVS at %s:%d", __FILE__, __LINE__); \ if (!session.disable_id_switching) { \ - if (getegid() != 0) { \ - if (setregid(session.gid, 0)) \ + if (getegid() != PR_ROOT_GID) { \ + if (setregid(session.gid, PR_ROOT_GID)) \ log_pri(PR_LOG_ERR, "PRIVS_RELINQUISH: unable to " \ - "setregid(session.gid, 0): %s", strerror(errno)); \ + "setregid(session.gid, PR_ROOT_GID): %s", strerror(errno)); \ } \ if (setregid(session.gid, session.gid)) \ log_pri(PR_LOG_ERR, "PRIVS_RELINQUISH: unable to setregid(session.jid, " \ "session.gid): %s", strerror(errno)); \ - if (geteuid() != 0) { \ - if (setreuid(session.uid, 0)) \ + if (geteuid() != PR_ROOT_UID) { \ + if (setreuid(session.uid, PR_ROOT_UID)) \ log_pri(PR_LOG_ERR, "PRIVS_RELINQUISH: unable to " \ - "setreuid(session.uid, 0): %s", strerror(errno)); \ + "setreuid(session.uid, PR_ROOT_UID): %s", strerror(errno)); \ } \ if (setreuid(session.uid, session.uid)) \ log_pri(PR_LOG_ERR, "PRIVS_RELINQUISH: unable to setreuid(session.uid, " \ @@ -149,8 +161,8 @@ # define PRIVS_REVOKE { \ log_debug(DEBUG9, "REVOKE PRIVS at %s:%d", __FILE__, __LINE__); \ - if (setreuid(0, 0)) \ - log_pri(PR_LOG_ERR, "PRIVS_REVOKE: unable to setreuid(0, 0): %s", \ + if (setreuid(PR_ROOT_UID, PR_ROOT_UID)) \ + log_pri(PR_LOG_ERR, "PRIVS_REVOKE: unable to setreuid(PR_ROOT_UID, PR_ROOT_UID): %s", \ strerror(errno)); \ if (setgid(session.gid)) \ log_pri(PR_LOG_ERR, "PRIVS_REVOKE: unable to setgid(): %s", \ @@ -174,7 +186,7 @@ # define PRIVS_SETUP(u, g) { \ log_debug(DEBUG9, "SETUP PRIVS at %s:%d", __FILE__, __LINE__); \ - if (getuid()) { \ + if (getuid() != PR_ROOT_UID) { \ session.ouid = session.uid = getuid(); \ session.gid = getgid(); \ if (setgid(session.gid)) \ @@ -190,7 +202,7 @@ session.ouid = getuid(); \ session.uid = (u); \ session.gid = (g); \ - if (setuid(0)) \ + if (setuid(PR_ROOT_UID)) \ log_pri(PR_LOG_ERR, "PRIVS_SETUP: unable to setuid(): %s", \ strerror(errno)); \ if (setgid((g))) \ @@ -207,10 +219,10 @@ # define PRIVS_ROOT \ if (!session.disable_id_switching) { \ log_debug(DEBUG9, "ROOT PRIVS at %s:%d", __FILE__, __LINE__); \ - if (seteuid(0)) \ + if (seteuid(PR_ROOT_UID)) \ log_pri(PR_LOG_ERR, "PRIVS_ROOT: unable to seteuid(): %s", \ strerror(errno)); \ - if (setegid(0)) \ + if (setegid(PR_ROOT_UID)) \ log_pri(PR_LOG_ERR, "PRIVS_ROOT: unable to setegid(): %s", \ strerror(errno)); \ } else \ @@ -220,14 +232,14 @@ */ # define PRIVS_USER \ if (!session.disable_id_switching) { \ - if (session.login_uid == 0) { \ + if (session.login_uid == PR_ROOT_UID) { \ log_debug(DEBUG1, "Use of PRIVS_USER before session.login_uid set " \ "in %s %d", __FILE__, __LINE__); \ } else { \ log_debug(DEBUG9, "USER PRIVS %d at %s:%d", (int) session.login_uid, \ __FILE__, __LINE__); \ - if (seteuid(0)) \ - log_pri(PR_LOG_ERR, "PRIVS_USER: unable to seteuid(0): %s", \ + if (seteuid(PR_ROOT_UID)) \ + log_pri(PR_LOG_ERR, "PRIVS_USER: unable to seteuid(PR_ROOT_UID): %s", \ strerror(errno)); \ if (seteuid(session.login_uid)) \ log_pri(PR_LOG_ERR, "PRIVS_USER: unable to seteuid(session.login_uid): " \ @@ -240,9 +252,9 @@ */ # define PRIVS_RELINQUISH \ if (!session.disable_id_switching) { \ - if (geteuid() != 0) { \ - if (seteuid(0)) \ - log_pri(PR_LOG_ERR, "PRIVS_RELINQUISH: unable to seteuid(0): %s", \ + if (geteuid() != PR_ROOT_UID) { \ + if (seteuid(PR_ROOT_UID)) \ + log_pri(PR_LOG_ERR, "PRIVS_RELINQUISH: unable to seteuid(PR_ROOT_UID): %s", \ strerror(errno)); \ } \ log_debug(DEBUG9, "RELINQUISH PRIVS at %s:%d", __FILE__, __LINE__); \ @@ -259,7 +271,7 @@ */ # define PRIVS_REVOKE { \ log_debug(DEBUG9, "REVOKE PRIVS at %s:%d", __FILE__, __LINE__); \ - if (seteuid(0)) \ + if (seteuid(PR_ROOT_UID)) \ log_pri(PR_LOG_ERR, "PRIVS_REVOKE: unable to seteuid(): %s", \ strerror(errno)); \ if (setgid(session.gid)) \ Index: modules/mod_auth.c =================================================================== RCS file: /cvsroot/proftp/proftpd/modules/mod_auth.c,v retrieving revision 1.148 diff -u -r1.148 mod_auth.c --- modules/mod_auth.c 23 Apr 2003 06:53:23 -0000 1.148 +++ modules/mod_auth.c 24 Apr 2003 02:45:36 -0000 @@ -763,7 +763,7 @@ */ pw = passwd_dup(p, pw); - if (pw->pw_uid == 0) { + if (pw->pw_uid == PR_ROOT_UID) { unsigned char *root_allow = NULL; /* If RootLogin is set to true, we allow this... even though we @@ -1012,8 +1012,8 @@ setresuid(0, 0, 0); setresgid(0, 0, 0); # else - setuid(0); - setgid(0); + setuid(PR_ROOT_UID); + setgid(PR_ROOT_GID); # endif /* __hpux */ #endif /* PR_DEVEL_COREDUMP */ @@ -1044,8 +1044,8 @@ setresuid(0, 0, 0); setresgid(0, 0, 0); # else - setuid(0); - setgid(0); + setuid(PR_ROOT_UID); + setgid(PR_ROOT_GID); # endif /* __hpux */ #endif /* PR_DEVEL_COREDUMP */ @@ -1249,8 +1249,8 @@ PRIVS_ROOT # ifndef PR_DEVEL_COREDUMP - setuid(0); - setgid(0); + setuid(PR_ROOT_UID); + setgid(PR_ROOT_GID); # endif /* PR_DEVEL_COREDUMP */ PRIVS_SETUP(pw->pw_uid, pw->pw_gid) Index: src/main.c =================================================================== RCS file: /cvsroot/proftp/proftpd/src/main.c,v retrieving revision 1.178 diff -u -r1.178 main.c --- src/main.c 23 Apr 2003 06:53:23 -0000 1.178 +++ src/main.c 24 Apr 2003 02:45:36 -0000 @@ -2615,17 +2615,16 @@ if (uid) daemon_uid = *uid; else - daemon_uid = 0; + daemon_uid = PR_ROOT_UID; if (gid) daemon_gid = *gid; else - daemon_gid = 0; + daemon_gid = PR_ROOT_GID; } - if (daemon_uid) { - /* allocate space for daemon supplemental groups - */ + if (daemon_uid != PR_ROOT_UID) { + /* Allocate space for daemon supplemental groups. */ daemon_gids = make_array(permanent_pool, 2, sizeof(gid_t)); if (auth_getgroups(permanent_pool, (const char *) get_param_ptr( --Boundary_(ID_A8VgWoVu44Z1AoaDBI8jFg)-- --Boundary_(ID_IFQvdaYPORwPQ8mQZYqQag) Content-Type: text/plain; charset=us-ascii -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/ --Boundary_(ID_IFQvdaYPORwPQ8mQZYqQag)--