183d2307dSDag-Erling Smørgrav /* 283d2307dSDag-Erling Smørgrav * cygwin_util.c 383d2307dSDag-Erling Smørgrav * 483d2307dSDag-Erling Smørgrav * Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com> 583d2307dSDag-Erling Smørgrav * 683d2307dSDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 783d2307dSDag-Erling Smørgrav * modification, are permitted provided that the following conditions 883d2307dSDag-Erling Smørgrav * are met: 983d2307dSDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 1083d2307dSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 1183d2307dSDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 1283d2307dSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 1383d2307dSDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 1483d2307dSDag-Erling Smørgrav * 1583d2307dSDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1683d2307dSDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1783d2307dSDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1883d2307dSDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1983d2307dSDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2083d2307dSDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2183d2307dSDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2283d2307dSDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2383d2307dSDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2483d2307dSDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2583d2307dSDag-Erling Smørgrav * 2683d2307dSDag-Erling Smørgrav * Created: Sat Sep 02 12:17:00 2000 cv 2783d2307dSDag-Erling Smørgrav * 2883d2307dSDag-Erling Smørgrav * This file contains functions for forcing opened file descriptors to 2983d2307dSDag-Erling Smørgrav * binary mode on Windows systems. 3083d2307dSDag-Erling Smørgrav */ 3183d2307dSDag-Erling Smørgrav 3283d2307dSDag-Erling Smørgrav #include "includes.h" 3383d2307dSDag-Erling Smørgrav 3483d2307dSDag-Erling Smørgrav RCSID("$Id: bsd-cygwin_util.c,v 1.8 2002/04/15 22:00:52 stevesk Exp $"); 3583d2307dSDag-Erling Smørgrav 3683d2307dSDag-Erling Smørgrav #ifdef HAVE_CYGWIN 3783d2307dSDag-Erling Smørgrav 3883d2307dSDag-Erling Smørgrav #include <fcntl.h> 3983d2307dSDag-Erling Smørgrav #include <stdlib.h> 4083d2307dSDag-Erling Smørgrav #include <sys/utsname.h> 4183d2307dSDag-Erling Smørgrav #include <sys/vfs.h> 4283d2307dSDag-Erling Smørgrav #include <windows.h> 4383d2307dSDag-Erling Smørgrav #define is_winnt (GetVersion() < 0x80000000) 4483d2307dSDag-Erling Smørgrav 4583d2307dSDag-Erling Smørgrav #define ntsec_on(c) ((c) && strstr((c),"ntsec") && !strstr((c),"nontsec")) 4683d2307dSDag-Erling Smørgrav #define ntea_on(c) ((c) && strstr((c),"ntea") && !strstr((c),"nontea")) 4783d2307dSDag-Erling Smørgrav 4883d2307dSDag-Erling Smørgrav #if defined(open) && open == binary_open 4983d2307dSDag-Erling Smørgrav # undef open 5083d2307dSDag-Erling Smørgrav #endif 5183d2307dSDag-Erling Smørgrav #if defined(pipe) && open == binary_pipe 5283d2307dSDag-Erling Smørgrav # undef pipe 5383d2307dSDag-Erling Smørgrav #endif 5483d2307dSDag-Erling Smørgrav 5583d2307dSDag-Erling Smørgrav int binary_open(const char *filename, int flags, ...) 5683d2307dSDag-Erling Smørgrav { 5783d2307dSDag-Erling Smørgrav va_list ap; 5883d2307dSDag-Erling Smørgrav mode_t mode; 5983d2307dSDag-Erling Smørgrav 6083d2307dSDag-Erling Smørgrav va_start(ap, flags); 6183d2307dSDag-Erling Smørgrav mode = va_arg(ap, mode_t); 6283d2307dSDag-Erling Smørgrav va_end(ap); 6383d2307dSDag-Erling Smørgrav return open(filename, flags | O_BINARY, mode); 6483d2307dSDag-Erling Smørgrav } 6583d2307dSDag-Erling Smørgrav 6683d2307dSDag-Erling Smørgrav int binary_pipe(int fd[2]) 6783d2307dSDag-Erling Smørgrav { 6883d2307dSDag-Erling Smørgrav int ret = pipe(fd); 6983d2307dSDag-Erling Smørgrav 7083d2307dSDag-Erling Smørgrav if (!ret) { 7183d2307dSDag-Erling Smørgrav setmode (fd[0], O_BINARY); 7283d2307dSDag-Erling Smørgrav setmode (fd[1], O_BINARY); 7383d2307dSDag-Erling Smørgrav } 7483d2307dSDag-Erling Smørgrav return ret; 7583d2307dSDag-Erling Smørgrav } 7683d2307dSDag-Erling Smørgrav 7783d2307dSDag-Erling Smørgrav int check_nt_auth(int pwd_authenticated, struct passwd *pw) 7883d2307dSDag-Erling Smørgrav { 7983d2307dSDag-Erling Smørgrav /* 8083d2307dSDag-Erling Smørgrav * The only authentication which is able to change the user 8183d2307dSDag-Erling Smørgrav * context on NT systems is the password authentication. So 8283d2307dSDag-Erling Smørgrav * we deny all requsts for changing the user context if another 8383d2307dSDag-Erling Smørgrav * authentication method is used. 8483d2307dSDag-Erling Smørgrav * 8583d2307dSDag-Erling Smørgrav * This doesn't apply to Cygwin versions >= 1.3.2 anymore which 8683d2307dSDag-Erling Smørgrav * uses the undocumented NtCreateToken() call to create a user 8783d2307dSDag-Erling Smørgrav * token if the process has the appropriate privileges and if 8883d2307dSDag-Erling Smørgrav * CYGWIN ntsec setting is on. 8983d2307dSDag-Erling Smørgrav */ 9083d2307dSDag-Erling Smørgrav static int has_create_token = -1; 9183d2307dSDag-Erling Smørgrav 9283d2307dSDag-Erling Smørgrav if (pw == NULL) 9383d2307dSDag-Erling Smørgrav return 0; 9483d2307dSDag-Erling Smørgrav if (is_winnt) { 9583d2307dSDag-Erling Smørgrav if (has_create_token < 0) { 9683d2307dSDag-Erling Smørgrav struct utsname uts; 9783d2307dSDag-Erling Smørgrav int major_high = 0, major_low = 0, minor = 0; 9883d2307dSDag-Erling Smørgrav char *cygwin = getenv("CYGWIN"); 9983d2307dSDag-Erling Smørgrav 10083d2307dSDag-Erling Smørgrav has_create_token = 0; 10183d2307dSDag-Erling Smørgrav if (ntsec_on(cygwin) && !uname(&uts)) { 10283d2307dSDag-Erling Smørgrav sscanf(uts.release, "%d.%d.%d", 10383d2307dSDag-Erling Smørgrav &major_high, &major_low, &minor); 10483d2307dSDag-Erling Smørgrav if (major_high > 1 || 10583d2307dSDag-Erling Smørgrav (major_high == 1 && (major_low > 3 || 10683d2307dSDag-Erling Smørgrav (major_low == 3 && minor >= 2)))) 10783d2307dSDag-Erling Smørgrav has_create_token = 1; 10883d2307dSDag-Erling Smørgrav } 10983d2307dSDag-Erling Smørgrav } 11083d2307dSDag-Erling Smørgrav if (has_create_token < 1 && 11183d2307dSDag-Erling Smørgrav !pwd_authenticated && geteuid() != pw->pw_uid) 11283d2307dSDag-Erling Smørgrav return 0; 11383d2307dSDag-Erling Smørgrav } 11483d2307dSDag-Erling Smørgrav return 1; 11583d2307dSDag-Erling Smørgrav } 11683d2307dSDag-Erling Smørgrav 11783d2307dSDag-Erling Smørgrav int check_ntsec(const char *filename) 11883d2307dSDag-Erling Smørgrav { 11983d2307dSDag-Erling Smørgrav char *cygwin; 12083d2307dSDag-Erling Smørgrav int allow_ntea = 0; 12183d2307dSDag-Erling Smørgrav int allow_ntsec = 0; 12283d2307dSDag-Erling Smørgrav struct statfs fsstat; 12383d2307dSDag-Erling Smørgrav 12483d2307dSDag-Erling Smørgrav /* Windows 95/98/ME don't support file system security at all. */ 12583d2307dSDag-Erling Smørgrav if (!is_winnt) 12683d2307dSDag-Erling Smørgrav return 0; 12783d2307dSDag-Erling Smørgrav 12883d2307dSDag-Erling Smørgrav /* Evaluate current CYGWIN settings. */ 12983d2307dSDag-Erling Smørgrav cygwin = getenv("CYGWIN"); 13083d2307dSDag-Erling Smørgrav allow_ntea = ntea_on(cygwin); 13183d2307dSDag-Erling Smørgrav allow_ntsec = ntsec_on(cygwin); 13283d2307dSDag-Erling Smørgrav 13383d2307dSDag-Erling Smørgrav /* 13483d2307dSDag-Erling Smørgrav * `ntea' is an emulation of POSIX attributes. It doesn't support 13583d2307dSDag-Erling Smørgrav * real file level security as ntsec on NTFS file systems does 13683d2307dSDag-Erling Smørgrav * but it supports FAT filesystems. `ntea' is minimum requirement 13783d2307dSDag-Erling Smørgrav * for security checks. 13883d2307dSDag-Erling Smørgrav */ 13983d2307dSDag-Erling Smørgrav if (allow_ntea) 14083d2307dSDag-Erling Smørgrav return 1; 14183d2307dSDag-Erling Smørgrav 14283d2307dSDag-Erling Smørgrav /* 14383d2307dSDag-Erling Smørgrav * Retrieve file system flags. In Cygwin, file system flags are 14483d2307dSDag-Erling Smørgrav * copied to f_type which has no meaning in Win32 itself. 14583d2307dSDag-Erling Smørgrav */ 14683d2307dSDag-Erling Smørgrav if (statfs(filename, &fsstat)) 14783d2307dSDag-Erling Smørgrav return 1; 14883d2307dSDag-Erling Smørgrav 14983d2307dSDag-Erling Smørgrav /* 15083d2307dSDag-Erling Smørgrav * Only file systems supporting ACLs are able to set permissions. 15183d2307dSDag-Erling Smørgrav * `ntsec' is the setting in Cygwin which switches using of NTFS 15283d2307dSDag-Erling Smørgrav * ACLs to support POSIX permissions on files. 15383d2307dSDag-Erling Smørgrav */ 15483d2307dSDag-Erling Smørgrav if (fsstat.f_type & FS_PERSISTENT_ACLS) 15583d2307dSDag-Erling Smørgrav return allow_ntsec; 15683d2307dSDag-Erling Smørgrav 15783d2307dSDag-Erling Smørgrav return 0; 15883d2307dSDag-Erling Smørgrav } 15983d2307dSDag-Erling Smørgrav 16083d2307dSDag-Erling Smørgrav void register_9x_service(void) 16183d2307dSDag-Erling Smørgrav { 16283d2307dSDag-Erling Smørgrav HINSTANCE kerneldll; 16383d2307dSDag-Erling Smørgrav DWORD (*RegisterServiceProcess)(DWORD, DWORD); 16483d2307dSDag-Erling Smørgrav 16583d2307dSDag-Erling Smørgrav /* The service register mechanism in 9x/Me is pretty different from 16683d2307dSDag-Erling Smørgrav * NT/2K/XP. In NT/2K/XP we're using a special service starter 16783d2307dSDag-Erling Smørgrav * application to register and control sshd as service. This method 16883d2307dSDag-Erling Smørgrav * doesn't play nicely with 9x/Me. For that reason we register here 16983d2307dSDag-Erling Smørgrav * as service when running under 9x/Me. This function is only called 17083d2307dSDag-Erling Smørgrav * by the child sshd when it's going to daemonize. 17183d2307dSDag-Erling Smørgrav */ 17283d2307dSDag-Erling Smørgrav if (is_winnt) 17383d2307dSDag-Erling Smørgrav return; 17483d2307dSDag-Erling Smørgrav if (! (kerneldll = LoadLibrary("KERNEL32.DLL"))) 17583d2307dSDag-Erling Smørgrav return; 17683d2307dSDag-Erling Smørgrav if (! (RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) 17783d2307dSDag-Erling Smørgrav GetProcAddress(kerneldll, "RegisterServiceProcess"))) 17883d2307dSDag-Erling Smørgrav return; 17983d2307dSDag-Erling Smørgrav RegisterServiceProcess(0, 1); 18083d2307dSDag-Erling Smørgrav } 18183d2307dSDag-Erling Smørgrav 18283d2307dSDag-Erling Smørgrav #endif /* HAVE_CYGWIN */ 183