bsd-cygwin_util.c revision 98937
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 34RCSID("$Id: bsd-cygwin_util.c,v 1.8 2002/04/15 22:00:52 stevesk Exp $"); 35 36#ifdef HAVE_CYGWIN 37 38#include <fcntl.h> 39#include <stdlib.h> 40#include <sys/utsname.h> 41#include <sys/vfs.h> 42#include <windows.h> 43#define is_winnt (GetVersion() < 0x80000000) 44 45#define ntsec_on(c) ((c) && strstr((c),"ntsec") && !strstr((c),"nontsec")) 46#define ntea_on(c) ((c) && strstr((c),"ntea") && !strstr((c),"nontea")) 47 48#if defined(open) && open == binary_open 49# undef open 50#endif 51#if defined(pipe) && open == binary_pipe 52# undef pipe 53#endif 54 55int binary_open(const char *filename, int flags, ...) 56{ 57 va_list ap; 58 mode_t mode; 59 60 va_start(ap, flags); 61 mode = va_arg(ap, mode_t); 62 va_end(ap); 63 return open(filename, flags | O_BINARY, mode); 64} 65 66int binary_pipe(int fd[2]) 67{ 68 int ret = pipe(fd); 69 70 if (!ret) { 71 setmode (fd[0], O_BINARY); 72 setmode (fd[1], O_BINARY); 73 } 74 return ret; 75} 76 77int check_nt_auth(int pwd_authenticated, struct passwd *pw) 78{ 79 /* 80 * The only authentication which is able to change the user 81 * context on NT systems is the password authentication. So 82 * we deny all requsts for changing the user context if another 83 * authentication method is used. 84 * 85 * This doesn't apply to Cygwin versions >= 1.3.2 anymore which 86 * uses the undocumented NtCreateToken() call to create a user 87 * token if the process has the appropriate privileges and if 88 * CYGWIN ntsec setting is on. 89 */ 90 static int has_create_token = -1; 91 92 if (pw == NULL) 93 return 0; 94 if (is_winnt) { 95 if (has_create_token < 0) { 96 struct utsname uts; 97 int major_high = 0, major_low = 0, minor = 0; 98 char *cygwin = getenv("CYGWIN"); 99 100 has_create_token = 0; 101 if (ntsec_on(cygwin) && !uname(&uts)) { 102 sscanf(uts.release, "%d.%d.%d", 103 &major_high, &major_low, &minor); 104 if (major_high > 1 || 105 (major_high == 1 && (major_low > 3 || 106 (major_low == 3 && minor >= 2)))) 107 has_create_token = 1; 108 } 109 } 110 if (has_create_token < 1 && 111 !pwd_authenticated && geteuid() != pw->pw_uid) 112 return 0; 113 } 114 return 1; 115} 116 117int check_ntsec(const char *filename) 118{ 119 char *cygwin; 120 int allow_ntea = 0; 121 int allow_ntsec = 0; 122 struct statfs fsstat; 123 124 /* Windows 95/98/ME don't support file system security at all. */ 125 if (!is_winnt) 126 return 0; 127 128 /* Evaluate current CYGWIN settings. */ 129 cygwin = getenv("CYGWIN"); 130 allow_ntea = ntea_on(cygwin); 131 allow_ntsec = ntsec_on(cygwin); 132 133 /* 134 * `ntea' is an emulation of POSIX attributes. It doesn't support 135 * real file level security as ntsec on NTFS file systems does 136 * but it supports FAT filesystems. `ntea' is minimum requirement 137 * for security checks. 138 */ 139 if (allow_ntea) 140 return 1; 141 142 /* 143 * Retrieve file system flags. In Cygwin, file system flags are 144 * copied to f_type which has no meaning in Win32 itself. 145 */ 146 if (statfs(filename, &fsstat)) 147 return 1; 148 149 /* 150 * Only file systems supporting ACLs are able to set permissions. 151 * `ntsec' is the setting in Cygwin which switches using of NTFS 152 * ACLs to support POSIX permissions on files. 153 */ 154 if (fsstat.f_type & FS_PERSISTENT_ACLS) 155 return allow_ntsec; 156 157 return 0; 158} 159 160void register_9x_service(void) 161{ 162 HINSTANCE kerneldll; 163 DWORD (*RegisterServiceProcess)(DWORD, DWORD); 164 165 /* The service register mechanism in 9x/Me is pretty different from 166 * NT/2K/XP. In NT/2K/XP we're using a special service starter 167 * application to register and control sshd as service. This method 168 * doesn't play nicely with 9x/Me. For that reason we register here 169 * as service when running under 9x/Me. This function is only called 170 * by the child sshd when it's going to daemonize. 171 */ 172 if (is_winnt) 173 return; 174 if (! (kerneldll = LoadLibrary("KERNEL32.DLL"))) 175 return; 176 if (! (RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) 177 GetProcAddress(kerneldll, "RegisterServiceProcess"))) 178 return; 179 RegisterServiceProcess(0, 1); 180} 181 182#endif /* HAVE_CYGWIN */ 183