summaryrefslogtreecommitdiffstats
path: root/openbsd-compat/bsd-cygwin_util.c
blob: 87f36c0cbcbdbf0c4329dd422b11b04f94c70eee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
 *
 * cygwin_util.c
 *
 * Author: Corinna Vinschen <vinschen@cygnus.com>
 *
 * Copyright (c) 2000 Corinna Vinschen <vinschen@cygnus.com>, Duisburg, Germany
 *                    All rights reserved
 *
 * Created: Sat Sep 02 12:17:00 2000 cv
 *
 * This file contains functions for forcing opened file descriptors to
 * binary mode on Windows systems.
 */

#include "includes.h"

RCSID("$Id: bsd-cygwin_util.c,v 1.5 2001/07/18 16:19:49 mouring Exp $");

#ifdef HAVE_CYGWIN

#include <fcntl.h>
#include <stdlib.h>
#include <sys/utsname.h>
#include <sys/vfs.h>
#include <windows.h>
#define is_winnt       (GetVersion() < 0x80000000)

#define ntsec_on(c)	((c) && strstr((c),"ntsec") && !strstr((c),"nontsec"))
#define ntea_on(c)	((c) && strstr((c),"ntea") && !strstr((c),"nontea"))

#if defined(open) && open == binary_open
# undef open
#endif
#if defined(pipe) && open == binary_pipe
# undef pipe
#endif

int binary_open(const char *filename, int flags, ...)
{
	va_list ap;
	mode_t mode;
	
	va_start(ap, flags);
	mode = va_arg(ap, mode_t);
	va_end(ap);
	return open(filename, flags | O_BINARY, mode);
}

int binary_pipe(int fd[2])
{
	int ret = pipe(fd);

	if (!ret) {
		setmode (fd[0], O_BINARY);
		setmode (fd[1], O_BINARY);
	}
	return ret;
}

int check_nt_auth(int pwd_authenticated, uid_t uid)
{
	/*
	* The only authentication which is able to change the user
	* context on NT systems is the password authentication. So
	* we deny all requsts for changing the user context if another
	* authentication method is used.
	*
	* This doesn't apply to Cygwin versions >= 1.3.2 anymore which
	* uses the undocumented NtCreateToken() call to create a user
	* token if the process has the appropriate privileges and if
	* CYGWIN ntsec setting is on.
	*/
	static int has_create_token = -1;

	if (is_winnt) {
		if (has_create_token < 0) {
			struct utsname uts;
		        int major_high = 0, major_low = 0, minor = 0;
			char *cygwin = getenv("CYGWIN");

			has_create_token = 0;
			if (ntsec_on(cygwin) && !uname(&uts)) {
				sscanf(uts.release, "%d.%d.%d",
				       &major_high, &major_low, &minor);
				if (major_high > 1 ||
				    (major_high == 1 && (major_low > 3 ||
				     (major_low == 3 && minor >= 2))))
					has_create_token = 1;
			}
		}
		if (has_create_token < 1 &&
		    !pwd_authenticated && geteuid() != uid)
			return 0;
	}
	return 1;
}

int check_ntsec(const char *filename)
{
	char *cygwin;
	int allow_ntea = 0;
	int allow_ntsec = 0;
	struct statfs fsstat;

	/* Windows 95/98/ME don't support file system security at all. */
	if (!is_winnt)
		return 0;

	/* Evaluate current CYGWIN settings. */
	cygwin = getenv("CYGWIN");
	allow_ntea = ntea_on(cygwin);
	allow_ntsec = ntsec_on(cygwin);

	/*
	 * `ntea' is an emulation of POSIX attributes. It doesn't support
	 * real file level security as ntsec on NTFS file systems does
	 * but it supports FAT filesystems. `ntea' is minimum requirement
	 * for security checks.
	 */
	if (allow_ntea)
		return 1;

	/*
	 * Retrieve file system flags. In Cygwin, file system flags are
	 * copied to f_type which has no meaning in Win32 itself.
	 */
	if (statfs(filename, &fsstat))
		return 1;

	/*
	 * Only file systems supporting ACLs are able to set permissions.
	 * `ntsec' is the setting in Cygwin which switches using of NTFS
	 * ACLs to support POSIX permissions on files.
	 */
	if (fsstat.f_type & FS_PERSISTENT_ACLS)
		return allow_ntsec;

	return 0;
}

#endif /* HAVE_CYGWIN */