]> andersk Git - openssh.git/blame - openbsd-compat/bsd-cygwin_util.c
- (djm) Sync license on openbsd-compat/bindresvport.c with OpenBSD CVS
[openssh.git] / openbsd-compat / bsd-cygwin_util.c
CommitLineData
3c62e7eb 1/*
3c62e7eb 2 * cygwin_util.c
3 *
4e51cc76 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.
3c62e7eb 14 *
4e51cc76 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.
3c62e7eb 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
0b202697 32#include "includes.h"
33
34RCSID("$Id$");
3c62e7eb 35
36#ifdef HAVE_CYGWIN
2f125ca1 37
3c62e7eb 38#include <fcntl.h>
9cd45ea4 39#include <stdlib.h>
31fb6aaf 40#include <sys/utsname.h>
9cd45ea4 41#include <sys/vfs.h>
42#include <windows.h>
43#define is_winnt (GetVersion() < 0x80000000)
3c62e7eb 44
31fb6aaf 45#define ntsec_on(c) ((c) && strstr((c),"ntsec") && !strstr((c),"nontsec"))
f00addc9 46#define ntsec_off(c) ((c) && strstr((c),"nontsec"))
31fb6aaf 47#define ntea_on(c) ((c) && strstr((c),"ntea") && !strstr((c),"nontea"))
48
58e7f038 49#if defined(open) && open == binary_open
50# undef open
51#endif
52#if defined(pipe) && open == binary_pipe
53# undef pipe
54#endif
55
9901cb37 56int
57binary_open(const char *filename, int flags, ...)
3c62e7eb 58{
58e7f038 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);
9901cb37 65 return (open(filename, flags | O_BINARY, mode));
3c62e7eb 66}
67
9901cb37 68int
69binary_pipe(int fd[2])
3c62e7eb 70{
2f125ca1 71 int ret = pipe(fd);
72
73 if (!ret) {
9901cb37 74 setmode(fd[0], O_BINARY);
75 setmode(fd[1], O_BINARY);
2f125ca1 76 }
9901cb37 77 return (ret);
9cd45ea4 78}
79
f00addc9 80#define HAS_CREATE_TOKEN 1
81#define HAS_NTSEC_BY_DEFAULT 2
82
9901cb37 83static int
84has_capability(int what)
f00addc9 85{
f00addc9 86 static int inited;
87 static int has_create_token;
88 static int has_ntsec_by_default;
89
9901cb37 90 /*
91 * has_capability() basically calls uname() and checks if
92 * specific capabilities of Cygwin can be evaluated from that.
93 * This simplifies the calling functions which only have to ask
94 * for a capability using has_capability() instead of having
95 * to figure that out by themselves.
96 */
f00addc9 97 if (!inited) {
98 struct utsname uts;
99 char *c;
100
101 if (!uname(&uts)) {
9901cb37 102 int major_high = 0, major_low = 0, minor = 0;
103 int api_major_version = 0, api_minor_version = 0;
f00addc9 104 char *c;
105
106 sscanf(uts.release, "%d.%d.%d", &major_high,
9901cb37 107 &major_low, &minor);
108 if ((c = strchr(uts.release, '(')) != NULL) {
f00addc9 109 sscanf(c + 1, "%d.%d", &api_major_version,
9901cb37 110 &api_minor_version);
111 }
f00addc9 112 if (major_high > 1 ||
113 (major_high == 1 && (major_low > 3 ||
9901cb37 114 (major_low == 3 && minor >= 2))))
f00addc9 115 has_create_token = 1;
116 if (api_major_version > 0 || api_minor_version >= 56)
117 has_ntsec_by_default = 1;
118 inited = 1;
119 }
120 }
121 switch (what) {
122 case HAS_CREATE_TOKEN:
9901cb37 123 return (has_create_token);
f00addc9 124 case HAS_NTSEC_BY_DEFAULT:
9901cb37 125 return (has_ntsec_by_default);
f00addc9 126 }
9901cb37 127 return (0);
f00addc9 128}
129
9901cb37 130int
131check_nt_auth(int pwd_authenticated, struct passwd *pw)
9cd45ea4 132{
133 /*
2f125ca1 134 * The only authentication which is able to change the user
135 * context on NT systems is the password authentication. So
136 * we deny all requsts for changing the user context if another
137 * authentication method is used.
31fb6aaf 138 *
139 * This doesn't apply to Cygwin versions >= 1.3.2 anymore which
140 * uses the undocumented NtCreateToken() call to create a user
141 * token if the process has the appropriate privileges and if
142 * CYGWIN ntsec setting is on.
2f125ca1 143 */
31fb6aaf 144 static int has_create_token = -1;
145
e9571a2c 146 if (pw == NULL)
147 return 0;
31fb6aaf 148 if (is_winnt) {
149 if (has_create_token < 0) {
31fb6aaf 150 char *cygwin = getenv("CYGWIN");
151
152 has_create_token = 0;
f00addc9 153 if (has_capability(HAS_CREATE_TOKEN) &&
154 (ntsec_on(cygwin) ||
9901cb37 155 (has_capability(HAS_NTSEC_BY_DEFAULT) &&
156 !ntsec_off(cygwin))))
f00addc9 157 has_create_token = 1;
31fb6aaf 158 }
159 if (has_create_token < 1 &&
e9571a2c 160 !pwd_authenticated && geteuid() != pw->pw_uid)
9901cb37 161 return (0);
31fb6aaf 162 }
9901cb37 163 return (1);
9cd45ea4 164}
165
9901cb37 166int
167check_ntsec(const char *filename)
9cd45ea4 168{
169 char *cygwin;
9901cb37 170 int allow_ntea = 0, allow_ntsec = 0;
9cd45ea4 171 struct statfs fsstat;
172
173 /* Windows 95/98/ME don't support file system security at all. */
174 if (!is_winnt)
9901cb37 175 return (0);
9cd45ea4 176
177 /* Evaluate current CYGWIN settings. */
31fb6aaf 178 cygwin = getenv("CYGWIN");
179 allow_ntea = ntea_on(cygwin);
f00addc9 180 allow_ntsec = ntsec_on(cygwin) ||
9901cb37 181 (has_capability(HAS_NTSEC_BY_DEFAULT) && !ntsec_off(cygwin));
9cd45ea4 182
183 /*
184 * `ntea' is an emulation of POSIX attributes. It doesn't support
185 * real file level security as ntsec on NTFS file systems does
186 * but it supports FAT filesystems. `ntea' is minimum requirement
187 * for security checks.
188 */
189 if (allow_ntea)
9901cb37 190 return (1);
9cd45ea4 191
192 /*
193 * Retrieve file system flags. In Cygwin, file system flags are
194 * copied to f_type which has no meaning in Win32 itself.
195 */
196 if (statfs(filename, &fsstat))
9901cb37 197 return (1);
9cd45ea4 198
199 /*
200 * Only file systems supporting ACLs are able to set permissions.
201 * `ntsec' is the setting in Cygwin which switches using of NTFS
202 * ACLs to support POSIX permissions on files.
203 */
204 if (fsstat.f_type & FS_PERSISTENT_ACLS)
9901cb37 205 return (allow_ntsec);
9cd45ea4 206
9901cb37 207 return (0);
3c62e7eb 208}
2f125ca1 209
9901cb37 210void
211register_9x_service(void)
ffb8d130 212{
213 HINSTANCE kerneldll;
214 DWORD (*RegisterServiceProcess)(DWORD, DWORD);
215
216 /* The service register mechanism in 9x/Me is pretty different from
217 * NT/2K/XP. In NT/2K/XP we're using a special service starter
218 * application to register and control sshd as service. This method
219 * doesn't play nicely with 9x/Me. For that reason we register here
220 * as service when running under 9x/Me. This function is only called
221 * by the child sshd when it's going to daemonize.
222 */
223 if (is_winnt)
224 return;
9901cb37 225 if (!(kerneldll = LoadLibrary("KERNEL32.DLL")))
ffb8d130 226 return;
9901cb37 227 if (!(RegisterServiceProcess = (DWORD (*)(DWORD, DWORD))
228 GetProcAddress(kerneldll, "RegisterServiceProcess")))
ffb8d130 229 return;
230 RegisterServiceProcess(0, 1);
231}
232
2f125ca1 233#endif /* HAVE_CYGWIN */
This page took 0.256208 seconds and 5 git commands to generate.