1 /* 2 * cygwin_util.c 3 * 4 * Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com> 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * 26 * Created: Sat Sep 02 12:17:00 2000 cv 27 * 28 * This file contains functions for forcing opened file descriptors to 29 * binary mode on Windows systems. 30 */ 31 32 #include "includes.h" 33 34 RCSID("$Id: bsd-cygwin_util.c,v 1.8 2002/04/15 22:00:52 stevesk Exp $"); 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 38 #ifdef HAVE_CYGWIN 39 40 #include <fcntl.h> 41 #include <stdlib.h> 42 #include <sys/utsname.h> 43 #include <sys/vfs.h> 44 #include <windows.h> 45 #define is_winnt (GetVersion() < 0x80000000) 46 47 #define ntsec_on(c) ((c) && strstr((c),"ntsec") && !strstr((c),"nontsec")) 48 #define ntea_on(c) ((c) && strstr((c),"ntea") && !strstr((c),"nontea")) 49 50 #if defined(open) && open == binary_open 51 # undef open 52 #endif 53 #if defined(pipe) && open == binary_pipe 54 # undef pipe 55 #endif 56 57 int binary_open(const char *filename, int flags, ...) 58 { 59 va_list ap; 60 mode_t mode; 61 62 va_start(ap, flags); 63 mode = va_arg(ap, mode_t); 64 va_end(ap); 65 return open(filename, flags | O_BINARY, mode); 66 } 67 68 int binary_pipe(int fd[2]) 69 { 70 int ret = pipe(fd); 71 72 if (!ret) { 73 setmode (fd[0], O_BINARY); 74 setmode (fd[1], O_BINARY); 75 } 76 return ret; 77 } 78 79 int check_nt_auth(int pwd_authenticated, struct passwd *pw) 80 { 81 /* 82 * The only authentication which is able to change the user 83 * context on NT systems is the password authentication. So 84 * we deny all requsts for changing the user context if another 85 * authentication method is used. 86 * 87 * This doesn't apply to Cygwin versions >= 1.3.2 anymore which 88 * uses the undocumented NtCreateToken() call to create a user 89 * token if the process has the appropriate privileges and if 90 * CYGWIN ntsec setting is on. 91 */ 92 static int has_create_token = -1; 93 94 if (pw == NULL) 95 return 0; 96 if (is_winnt) { 97 if (has_create_token < 0) { 98 struct utsname uts; 99 int major_high = 0, major_low = 0, minor = 0; 100 char *cygwin = getenv("CYGWIN"); 101 102 has_create_token = 0; 103 if (ntsec_on(cygwin) && !uname(&uts)) { 104 sscanf(uts.release, "%d.%d.%d", 105 &major_high, &major_low, &minor); 106 if (major_high > 1 || 107 (major_high == 1 && (major_low > 3 || 108 (major_low == 3 && minor >= 2)))) 109 has_create_token = 1; 110 } 111 } 112 if (has_create_token < 1 && 113 !pwd_authenticated && geteuid() != pw->pw_uid) 114 return 0; 115 } 116 return 1; 117 } 118 119 int check_ntsec(const char *filename) 120 { 121 char *cygwin; 122 int allow_ntea = 0; 123 int allow_ntsec = 0; 124 struct statfs fsstat; 125 126 /* Windows 95/98/ME don't support file system security at all. */ 127 if (!is_winnt) 128 return 0; 129 130 /* Evaluate current CYGWIN settings. */ 131 cygwin = getenv("CYGWIN"); 132 allow_ntea = ntea_on(cygwin); 133 allow_ntsec = ntsec_on(cygwin); 134 135 /* 136 * `ntea' is an emulation of POSIX attributes. It doesn't support 137 * real file level security as ntsec on NTFS file systems does 138 * but it supports FAT filesystems. `ntea' is minimum requirement 139 * for security checks. 140 */ 141 if (allow_ntea) 142 return 1; 143 144 /* 145 * Retrieve file system flags. In Cygwin, file system flags are 146 * copied to f_type which has no meaning in Win32 itself. 147 */ 148 if (statfs(filename, &fsstat)) 149 return 1; 150 151 /* 152 * Only file systems supporting ACLs are able to set permissions. 153 * `ntsec' is the setting in Cygwin which switches using of NTFS 154 * ACLs to support POSIX permissions on files. 155 */ 156 if (fsstat.f_type & FS_PERSISTENT_ACLS) 157 return allow_ntsec; 158 159 return 0; 160 } 161 162 void register_9x_service(void) 163 { 164 HINSTANCE kerneldll; 165 DWORD (*RegisterServiceProcess)(DWORD, DWORD); 166 167 /* The service register mechanism in 9x/Me is pretty different from 168 * NT/2K/XP. In NT/2K/XP we're using a special service starter 169 * application to register and control sshd as service. This method 170 * doesn't play nicely with 9x/Me. For that reason we register here 171 * as service when running under 9x/Me. This function is only called 172 * by the child sshd when it's going to daemonize. 173 */ 174 if (is_winnt) 175 return; 176 if (! (kerneldll = LoadLibrary("KERNEL32.DLL"))) 177 return; 178 if (! (RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) 179 GetProcAddress(kerneldll, "RegisterServiceProcess"))) 180 return; 181 RegisterServiceProcess(0, 1); 182 } 183 184 #endif /* HAVE_CYGWIN */ 185