183d2307dSDag-Erling Smørgrav /* 283d2307dSDag-Erling Smørgrav * Copyright (c) 2000, 2001, Corinna Vinschen <vinschen@cygnus.com> 383d2307dSDag-Erling Smørgrav * 483d2307dSDag-Erling Smørgrav * Redistribution and use in source and binary forms, with or without 583d2307dSDag-Erling Smørgrav * modification, are permitted provided that the following conditions 683d2307dSDag-Erling Smørgrav * are met: 783d2307dSDag-Erling Smørgrav * 1. Redistributions of source code must retain the above copyright 883d2307dSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer. 983d2307dSDag-Erling Smørgrav * 2. Redistributions in binary form must reproduce the above copyright 1083d2307dSDag-Erling Smørgrav * notice, this list of conditions and the following disclaimer in the 1183d2307dSDag-Erling Smørgrav * documentation and/or other materials provided with the distribution. 1283d2307dSDag-Erling Smørgrav * 1383d2307dSDag-Erling Smørgrav * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1483d2307dSDag-Erling Smørgrav * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1583d2307dSDag-Erling Smørgrav * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1683d2307dSDag-Erling Smørgrav * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1783d2307dSDag-Erling Smørgrav * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1883d2307dSDag-Erling Smørgrav * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1983d2307dSDag-Erling Smørgrav * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2083d2307dSDag-Erling Smørgrav * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2183d2307dSDag-Erling Smørgrav * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2283d2307dSDag-Erling Smørgrav * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2383d2307dSDag-Erling Smørgrav * 2483d2307dSDag-Erling Smørgrav * Created: Sat Sep 02 12:17:00 2000 cv 2583d2307dSDag-Erling Smørgrav * 2683d2307dSDag-Erling Smørgrav * This file contains functions for forcing opened file descriptors to 2783d2307dSDag-Erling Smørgrav * binary mode on Windows systems. 2883d2307dSDag-Erling Smørgrav */ 2983d2307dSDag-Erling Smørgrav 3083d2307dSDag-Erling Smørgrav #include "includes.h" 3183d2307dSDag-Erling Smørgrav 3283d2307dSDag-Erling Smørgrav #ifdef HAVE_CYGWIN 3383d2307dSDag-Erling Smørgrav 3483d2307dSDag-Erling Smørgrav #if defined(open) && open == binary_open 3583d2307dSDag-Erling Smørgrav # undef open 3683d2307dSDag-Erling Smørgrav #endif 3783d2307dSDag-Erling Smørgrav #if defined(pipe) && open == binary_pipe 3883d2307dSDag-Erling Smørgrav # undef pipe 3983d2307dSDag-Erling Smørgrav #endif 4083d2307dSDag-Erling Smørgrav 41761efaa7SDag-Erling Smørgrav #include <sys/types.h> 42761efaa7SDag-Erling Smørgrav #include <sys/stat.h> 43761efaa7SDag-Erling Smørgrav #include <sys/utsname.h> 44761efaa7SDag-Erling Smørgrav #include <sys/vfs.h> 45761efaa7SDag-Erling Smørgrav 46761efaa7SDag-Erling Smørgrav #include <fcntl.h> 47761efaa7SDag-Erling Smørgrav #include <stdlib.h> 48761efaa7SDag-Erling Smørgrav #include <unistd.h> 49761efaa7SDag-Erling Smørgrav #include <windows.h> 50761efaa7SDag-Erling Smørgrav 51761efaa7SDag-Erling Smørgrav #include "xmalloc.h" 52761efaa7SDag-Erling Smørgrav #define is_winnt (GetVersion() < 0x80000000) 53761efaa7SDag-Erling Smørgrav 54761efaa7SDag-Erling Smørgrav #define ntsec_on(c) ((c) && strstr((c),"ntsec") && !strstr((c),"nontsec")) 55761efaa7SDag-Erling Smørgrav #define ntsec_off(c) ((c) && strstr((c),"nontsec")) 56761efaa7SDag-Erling Smørgrav #define ntea_on(c) ((c) && strstr((c),"ntea") && !strstr((c),"nontea")) 57761efaa7SDag-Erling Smørgrav 58d95e11bfSDag-Erling Smørgrav int 59d95e11bfSDag-Erling Smørgrav binary_open(const char *filename, int flags, ...) 6083d2307dSDag-Erling Smørgrav { 6183d2307dSDag-Erling Smørgrav va_list ap; 6283d2307dSDag-Erling Smørgrav mode_t mode; 6383d2307dSDag-Erling Smørgrav 6483d2307dSDag-Erling Smørgrav va_start(ap, flags); 6583d2307dSDag-Erling Smørgrav mode = va_arg(ap, mode_t); 6683d2307dSDag-Erling Smørgrav va_end(ap); 67d95e11bfSDag-Erling Smørgrav return (open(filename, flags | O_BINARY, mode)); 6883d2307dSDag-Erling Smørgrav } 6983d2307dSDag-Erling Smørgrav 70d95e11bfSDag-Erling Smørgrav int 71d95e11bfSDag-Erling Smørgrav binary_pipe(int fd[2]) 7283d2307dSDag-Erling Smørgrav { 7383d2307dSDag-Erling Smørgrav int ret = pipe(fd); 7483d2307dSDag-Erling Smørgrav 7583d2307dSDag-Erling Smørgrav if (!ret) { 7683d2307dSDag-Erling Smørgrav setmode(fd[0], O_BINARY); 7783d2307dSDag-Erling Smørgrav setmode(fd[1], O_BINARY); 7883d2307dSDag-Erling Smørgrav } 79d95e11bfSDag-Erling Smørgrav return (ret); 8083d2307dSDag-Erling Smørgrav } 8183d2307dSDag-Erling Smørgrav 82d0c8c0bcSDag-Erling Smørgrav #define HAS_CREATE_TOKEN 1 83d0c8c0bcSDag-Erling Smørgrav #define HAS_NTSEC_BY_DEFAULT 2 8452028650SDag-Erling Smørgrav #define HAS_CREATE_TOKEN_WO_NTSEC 3 85d0c8c0bcSDag-Erling Smørgrav 86d95e11bfSDag-Erling Smørgrav static int 87d95e11bfSDag-Erling Smørgrav has_capability(int what) 88d0c8c0bcSDag-Erling Smørgrav { 89d0c8c0bcSDag-Erling Smørgrav static int inited; 90d0c8c0bcSDag-Erling Smørgrav static int has_create_token; 91d0c8c0bcSDag-Erling Smørgrav static int has_ntsec_by_default; 9252028650SDag-Erling Smørgrav static int has_create_token_wo_ntsec; 93d0c8c0bcSDag-Erling Smørgrav 94d95e11bfSDag-Erling Smørgrav /* 95d95e11bfSDag-Erling Smørgrav * has_capability() basically calls uname() and checks if 96d95e11bfSDag-Erling Smørgrav * specific capabilities of Cygwin can be evaluated from that. 97d95e11bfSDag-Erling Smørgrav * This simplifies the calling functions which only have to ask 98d95e11bfSDag-Erling Smørgrav * for a capability using has_capability() instead of having 99d95e11bfSDag-Erling Smørgrav * to figure that out by themselves. 100d95e11bfSDag-Erling Smørgrav */ 101d0c8c0bcSDag-Erling Smørgrav if (!inited) { 102d0c8c0bcSDag-Erling Smørgrav struct utsname uts; 103d0c8c0bcSDag-Erling Smørgrav 104d0c8c0bcSDag-Erling Smørgrav if (!uname(&uts)) { 105d95e11bfSDag-Erling Smørgrav int major_high = 0, major_low = 0, minor = 0; 106d95e11bfSDag-Erling Smørgrav int api_major_version = 0, api_minor_version = 0; 107d0c8c0bcSDag-Erling Smørgrav char *c; 108d0c8c0bcSDag-Erling Smørgrav 109d0c8c0bcSDag-Erling Smørgrav sscanf(uts.release, "%d.%d.%d", &major_high, 110d0c8c0bcSDag-Erling Smørgrav &major_low, &minor); 111d95e11bfSDag-Erling Smørgrav if ((c = strchr(uts.release, '(')) != NULL) { 112d0c8c0bcSDag-Erling Smørgrav sscanf(c + 1, "%d.%d", &api_major_version, 113d0c8c0bcSDag-Erling Smørgrav &api_minor_version); 114d95e11bfSDag-Erling Smørgrav } 115d0c8c0bcSDag-Erling Smørgrav if (major_high > 1 || 116d0c8c0bcSDag-Erling Smørgrav (major_high == 1 && (major_low > 3 || 117d0c8c0bcSDag-Erling Smørgrav (major_low == 3 && minor >= 2)))) 118d0c8c0bcSDag-Erling Smørgrav has_create_token = 1; 119d0c8c0bcSDag-Erling Smørgrav if (api_major_version > 0 || api_minor_version >= 56) 120d0c8c0bcSDag-Erling Smørgrav has_ntsec_by_default = 1; 12152028650SDag-Erling Smørgrav if (major_high > 1 || 12252028650SDag-Erling Smørgrav (major_high == 1 && major_low >= 5)) 12352028650SDag-Erling Smørgrav has_create_token_wo_ntsec = 1; 124d0c8c0bcSDag-Erling Smørgrav inited = 1; 125d0c8c0bcSDag-Erling Smørgrav } 126d0c8c0bcSDag-Erling Smørgrav } 127d0c8c0bcSDag-Erling Smørgrav switch (what) { 128d0c8c0bcSDag-Erling Smørgrav case HAS_CREATE_TOKEN: 129d95e11bfSDag-Erling Smørgrav return (has_create_token); 130d0c8c0bcSDag-Erling Smørgrav case HAS_NTSEC_BY_DEFAULT: 131d95e11bfSDag-Erling Smørgrav return (has_ntsec_by_default); 13252028650SDag-Erling Smørgrav case HAS_CREATE_TOKEN_WO_NTSEC: 13352028650SDag-Erling Smørgrav return (has_create_token_wo_ntsec); 134d0c8c0bcSDag-Erling Smørgrav } 135d95e11bfSDag-Erling Smørgrav return (0); 136d0c8c0bcSDag-Erling Smørgrav } 137d0c8c0bcSDag-Erling Smørgrav 138d95e11bfSDag-Erling Smørgrav int 139d95e11bfSDag-Erling Smørgrav check_nt_auth(int pwd_authenticated, struct passwd *pw) 14083d2307dSDag-Erling Smørgrav { 14183d2307dSDag-Erling Smørgrav /* 14283d2307dSDag-Erling Smørgrav * The only authentication which is able to change the user 14383d2307dSDag-Erling Smørgrav * context on NT systems is the password authentication. So 14483d2307dSDag-Erling Smørgrav * we deny all requsts for changing the user context if another 14583d2307dSDag-Erling Smørgrav * authentication method is used. 14683d2307dSDag-Erling Smørgrav * 14783d2307dSDag-Erling Smørgrav * This doesn't apply to Cygwin versions >= 1.3.2 anymore which 14883d2307dSDag-Erling Smørgrav * uses the undocumented NtCreateToken() call to create a user 14983d2307dSDag-Erling Smørgrav * token if the process has the appropriate privileges and if 15083d2307dSDag-Erling Smørgrav * CYGWIN ntsec setting is on. 15183d2307dSDag-Erling Smørgrav */ 15283d2307dSDag-Erling Smørgrav static int has_create_token = -1; 15383d2307dSDag-Erling Smørgrav 15483d2307dSDag-Erling Smørgrav if (pw == NULL) 15583d2307dSDag-Erling Smørgrav return 0; 15683d2307dSDag-Erling Smørgrav if (is_winnt) { 15783d2307dSDag-Erling Smørgrav if (has_create_token < 0) { 15883d2307dSDag-Erling Smørgrav char *cygwin = getenv("CYGWIN"); 15983d2307dSDag-Erling Smørgrav 16083d2307dSDag-Erling Smørgrav has_create_token = 0; 161d0c8c0bcSDag-Erling Smørgrav if (has_capability(HAS_CREATE_TOKEN) && 162d0c8c0bcSDag-Erling Smørgrav (ntsec_on(cygwin) || 163d0c8c0bcSDag-Erling Smørgrav (has_capability(HAS_NTSEC_BY_DEFAULT) && 16452028650SDag-Erling Smørgrav !ntsec_off(cygwin)) || 16552028650SDag-Erling Smørgrav has_capability(HAS_CREATE_TOKEN_WO_NTSEC))) 16683d2307dSDag-Erling Smørgrav has_create_token = 1; 16783d2307dSDag-Erling Smørgrav } 16883d2307dSDag-Erling Smørgrav if (has_create_token < 1 && 16983d2307dSDag-Erling Smørgrav !pwd_authenticated && geteuid() != pw->pw_uid) 170d95e11bfSDag-Erling Smørgrav return (0); 17183d2307dSDag-Erling Smørgrav } 172d95e11bfSDag-Erling Smørgrav return (1); 17383d2307dSDag-Erling Smørgrav } 17483d2307dSDag-Erling Smørgrav 175d95e11bfSDag-Erling Smørgrav int 176d95e11bfSDag-Erling Smørgrav check_ntsec(const char *filename) 17783d2307dSDag-Erling Smørgrav { 178d4af9e69SDag-Erling Smørgrav return (pathconf(filename, _PC_POSIX_PERMISSIONS)); 17983d2307dSDag-Erling Smørgrav } 18083d2307dSDag-Erling Smørgrav 181d95e11bfSDag-Erling Smørgrav void 182d95e11bfSDag-Erling Smørgrav register_9x_service(void) 18383d2307dSDag-Erling Smørgrav { 18483d2307dSDag-Erling Smørgrav HINSTANCE kerneldll; 18583d2307dSDag-Erling Smørgrav DWORD (*RegisterServiceProcess)(DWORD, DWORD); 18683d2307dSDag-Erling Smørgrav 18783d2307dSDag-Erling Smørgrav /* The service register mechanism in 9x/Me is pretty different from 18883d2307dSDag-Erling Smørgrav * NT/2K/XP. In NT/2K/XP we're using a special service starter 18983d2307dSDag-Erling Smørgrav * application to register and control sshd as service. This method 19083d2307dSDag-Erling Smørgrav * doesn't play nicely with 9x/Me. For that reason we register here 19183d2307dSDag-Erling Smørgrav * as service when running under 9x/Me. This function is only called 19283d2307dSDag-Erling Smørgrav * by the child sshd when it's going to daemonize. 19383d2307dSDag-Erling Smørgrav */ 19483d2307dSDag-Erling Smørgrav if (is_winnt) 19583d2307dSDag-Erling Smørgrav return; 19683d2307dSDag-Erling Smørgrav if (!(kerneldll = LoadLibrary("KERNEL32.DLL"))) 19783d2307dSDag-Erling Smørgrav return; 19883d2307dSDag-Erling Smørgrav if (!(RegisterServiceProcess = (DWORD (*)(DWORD, DWORD)) 19983d2307dSDag-Erling Smørgrav GetProcAddress(kerneldll, "RegisterServiceProcess"))) 20083d2307dSDag-Erling Smørgrav return; 20183d2307dSDag-Erling Smørgrav RegisterServiceProcess(0, 1); 20283d2307dSDag-Erling Smørgrav } 20383d2307dSDag-Erling Smørgrav 2045e8dbd04SDag-Erling Smørgrav #define NL(x) x, (sizeof (x) - 1) 2055e8dbd04SDag-Erling Smørgrav #define WENV_SIZ (sizeof (wenv_arr) / sizeof (wenv_arr[0])) 2065e8dbd04SDag-Erling Smørgrav 2075e8dbd04SDag-Erling Smørgrav static struct wenv { 2085e8dbd04SDag-Erling Smørgrav const char *name; 2095e8dbd04SDag-Erling Smørgrav size_t namelen; 2105e8dbd04SDag-Erling Smørgrav } wenv_arr[] = { 2115e8dbd04SDag-Erling Smørgrav { NL("ALLUSERSPROFILE=") }, 2125e8dbd04SDag-Erling Smørgrav { NL("COMMONPROGRAMFILES=") }, 2135e8dbd04SDag-Erling Smørgrav { NL("COMPUTERNAME=") }, 2145e8dbd04SDag-Erling Smørgrav { NL("COMSPEC=") }, 2154518870cSDag-Erling Smørgrav { NL("CYGWIN=") }, 2165e8dbd04SDag-Erling Smørgrav { NL("NUMBER_OF_PROCESSORS=") }, 2175e8dbd04SDag-Erling Smørgrav { NL("OS=") }, 2185e8dbd04SDag-Erling Smørgrav { NL("PATH=") }, 2195e8dbd04SDag-Erling Smørgrav { NL("PATHEXT=") }, 2205e8dbd04SDag-Erling Smørgrav { NL("PROCESSOR_ARCHITECTURE=") }, 2215e8dbd04SDag-Erling Smørgrav { NL("PROCESSOR_IDENTIFIER=") }, 2225e8dbd04SDag-Erling Smørgrav { NL("PROCESSOR_LEVEL=") }, 2235e8dbd04SDag-Erling Smørgrav { NL("PROCESSOR_REVISION=") }, 2245e8dbd04SDag-Erling Smørgrav { NL("PROGRAMFILES=") }, 2255e8dbd04SDag-Erling Smørgrav { NL("SYSTEMDRIVE=") }, 2265e8dbd04SDag-Erling Smørgrav { NL("SYSTEMROOT=") }, 2275e8dbd04SDag-Erling Smørgrav { NL("TMP=") }, 2285e8dbd04SDag-Erling Smørgrav { NL("TEMP=") }, 2294518870cSDag-Erling Smørgrav { NL("WINDIR=") } 2305e8dbd04SDag-Erling Smørgrav }; 2315e8dbd04SDag-Erling Smørgrav 2325e8dbd04SDag-Erling Smørgrav char ** 2335e8dbd04SDag-Erling Smørgrav fetch_windows_environment(void) 2345e8dbd04SDag-Erling Smørgrav { 2355e8dbd04SDag-Erling Smørgrav char **e, **p; 236761efaa7SDag-Erling Smørgrav unsigned int i, idx = 0; 2375e8dbd04SDag-Erling Smørgrav 238761efaa7SDag-Erling Smørgrav p = xcalloc(WENV_SIZ + 1, sizeof(char *)); 2395e8dbd04SDag-Erling Smørgrav for (e = environ; *e != NULL; ++e) { 2405e8dbd04SDag-Erling Smørgrav for (i = 0; i < WENV_SIZ; ++i) { 2415e8dbd04SDag-Erling Smørgrav if (!strncmp(*e, wenv_arr[i].name, wenv_arr[i].namelen)) 2425e8dbd04SDag-Erling Smørgrav p[idx++] = *e; 2435e8dbd04SDag-Erling Smørgrav } 2445e8dbd04SDag-Erling Smørgrav } 2455e8dbd04SDag-Erling Smørgrav p[idx] = NULL; 2465e8dbd04SDag-Erling Smørgrav return p; 2475e8dbd04SDag-Erling Smørgrav } 2485e8dbd04SDag-Erling Smørgrav 2495e8dbd04SDag-Erling Smørgrav void 2505e8dbd04SDag-Erling Smørgrav free_windows_environment(char **p) 2515e8dbd04SDag-Erling Smørgrav { 2525e8dbd04SDag-Erling Smørgrav xfree(p); 2535e8dbd04SDag-Erling Smørgrav } 2545e8dbd04SDag-Erling Smørgrav 25583d2307dSDag-Erling Smørgrav #endif /* HAVE_CYGWIN */ 256