xref: /minix3/external/bsd/bind/dist/lib/isc/win32/fsaccess.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: fsaccess.c,v 1.5 2014/12/10 04:38:01 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2007, 2013  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 2000-2002  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: fsaccess.c,v 1.15 2007/06/19 23:47:19 tbox Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek /*
23*00b67f09SDavid van Moolenbroek  * Note that Win32 does not have the concept of files having access
24*00b67f09SDavid van Moolenbroek  * and ownership bits.  The FAT File system only has a readonly flag
25*00b67f09SDavid van Moolenbroek  * for everyone and that's all. NTFS uses ACL's which is a totally
26*00b67f09SDavid van Moolenbroek  * different concept of controlling access.
27*00b67f09SDavid van Moolenbroek  *
28*00b67f09SDavid van Moolenbroek  * This code needs to be revisited to set up proper access control for
29*00b67f09SDavid van Moolenbroek  * NTFS file systems.  Nothing can be done for FAT file systems.
30*00b67f09SDavid van Moolenbroek  */
31*00b67f09SDavid van Moolenbroek 
32*00b67f09SDavid van Moolenbroek #include <config.h>
33*00b67f09SDavid van Moolenbroek 
34*00b67f09SDavid van Moolenbroek #include <aclapi.h>
35*00b67f09SDavid van Moolenbroek 
36*00b67f09SDavid van Moolenbroek #include <sys/types.h>
37*00b67f09SDavid van Moolenbroek #include <sys/stat.h>
38*00b67f09SDavid van Moolenbroek #include <io.h>
39*00b67f09SDavid van Moolenbroek #include <errno.h>
40*00b67f09SDavid van Moolenbroek 
41*00b67f09SDavid van Moolenbroek #include <isc/file.h>
42*00b67f09SDavid van Moolenbroek #include <isc/stat.h>
43*00b67f09SDavid van Moolenbroek 
44*00b67f09SDavid van Moolenbroek #include "errno2result.h"
45*00b67f09SDavid van Moolenbroek 
46*00b67f09SDavid van Moolenbroek /*
47*00b67f09SDavid van Moolenbroek  * The OS-independent part of the API is in lib/isc.
48*00b67f09SDavid van Moolenbroek  */
49*00b67f09SDavid van Moolenbroek #include "../fsaccess.c"
50*00b67f09SDavid van Moolenbroek 
51*00b67f09SDavid van Moolenbroek /* Store the user account name locally */
52*00b67f09SDavid van Moolenbroek static char username[255] = "\0";
53*00b67f09SDavid van Moolenbroek static DWORD namelen = 0;
54*00b67f09SDavid van Moolenbroek 
55*00b67f09SDavid van Moolenbroek /*
56*00b67f09SDavid van Moolenbroek  * In order to set or retrieve access information, we need to obtain
57*00b67f09SDavid van Moolenbroek  * the File System type.  These could be UNC-type shares.
58*00b67f09SDavid van Moolenbroek  */
59*00b67f09SDavid van Moolenbroek 
60*00b67f09SDavid van Moolenbroek BOOL
is_ntfs(const char * file)61*00b67f09SDavid van Moolenbroek is_ntfs(const char * file) {
62*00b67f09SDavid van Moolenbroek 
63*00b67f09SDavid van Moolenbroek 	char drive[255];
64*00b67f09SDavid van Moolenbroek 	char FSType[20];
65*00b67f09SDavid van Moolenbroek 	char tmpbuf[256];
66*00b67f09SDavid van Moolenbroek 	char *machinename;
67*00b67f09SDavid van Moolenbroek 	char *sharename;
68*00b67f09SDavid van Moolenbroek 	char filename[1024];
69*00b67f09SDavid van Moolenbroek 
70*00b67f09SDavid van Moolenbroek 	REQUIRE(filename != NULL);
71*00b67f09SDavid van Moolenbroek 
72*00b67f09SDavid van Moolenbroek 	if (isc_file_absolutepath(file, filename,
73*00b67f09SDavid van Moolenbroek 		sizeof(filename)) != ISC_R_SUCCESS) {
74*00b67f09SDavid van Moolenbroek 		return (FALSE);
75*00b67f09SDavid van Moolenbroek 	}
76*00b67f09SDavid van Moolenbroek 
77*00b67f09SDavid van Moolenbroek 	/*
78*00b67f09SDavid van Moolenbroek 	 * Look for c:\path\... style, c:/path/... or \\computer\shar\path...
79*00b67f09SDavid van Moolenbroek 	 * the UNC style file specs
80*00b67f09SDavid van Moolenbroek 	 */
81*00b67f09SDavid van Moolenbroek 	if (isalpha(filename[0]) && filename[1] == ':' &&
82*00b67f09SDavid van Moolenbroek 		(filename[2] == '\\' || filename[2] == '/')) {
83*00b67f09SDavid van Moolenbroek 		strncpy(drive, filename, 3);
84*00b67f09SDavid van Moolenbroek 		drive[3] = '\0';
85*00b67f09SDavid van Moolenbroek 	}
86*00b67f09SDavid van Moolenbroek 
87*00b67f09SDavid van Moolenbroek 	else if ((filename[0] == '\\') && (filename[1] == '\\')) {
88*00b67f09SDavid van Moolenbroek 		/* Find the machine and share name and rebuild the UNC */
89*00b67f09SDavid van Moolenbroek 		strcpy(tmpbuf, filename);
90*00b67f09SDavid van Moolenbroek 		machinename = strtok(tmpbuf, "\\");
91*00b67f09SDavid van Moolenbroek 		sharename = strtok(NULL, "\\");
92*00b67f09SDavid van Moolenbroek 		strcpy(drive, "\\\\");
93*00b67f09SDavid van Moolenbroek 		strcat(drive, machinename);
94*00b67f09SDavid van Moolenbroek 		strcat(drive, "\\");
95*00b67f09SDavid van Moolenbroek 		strcat(drive, sharename);
96*00b67f09SDavid van Moolenbroek 		strcat(drive, "\\");
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek 	}
99*00b67f09SDavid van Moolenbroek 	else /* Not determinable */
100*00b67f09SDavid van Moolenbroek 		return (FALSE);
101*00b67f09SDavid van Moolenbroek 
102*00b67f09SDavid van Moolenbroek 	GetVolumeInformation(drive, NULL, 0, NULL, 0, NULL, FSType,
103*00b67f09SDavid van Moolenbroek 			     sizeof(FSType));
104*00b67f09SDavid van Moolenbroek 	if(strcmp(FSType,"NTFS") == 0)
105*00b67f09SDavid van Moolenbroek 		return (TRUE);
106*00b67f09SDavid van Moolenbroek 	else
107*00b67f09SDavid van Moolenbroek 		return (FALSE);
108*00b67f09SDavid van Moolenbroek }
109*00b67f09SDavid van Moolenbroek 
110*00b67f09SDavid van Moolenbroek /*
111*00b67f09SDavid van Moolenbroek  * If it's not NTFS, we assume that it is FAT and proceed
112*00b67f09SDavid van Moolenbroek  * with almost nothing to do. Only the write flag can be set or
113*00b67f09SDavid van Moolenbroek  * cleared.
114*00b67f09SDavid van Moolenbroek  */
115*00b67f09SDavid van Moolenbroek isc_result_t
FAT_fsaccess_set(const char * path,isc_fsaccess_t access)116*00b67f09SDavid van Moolenbroek FAT_fsaccess_set(const char *path, isc_fsaccess_t access) {
117*00b67f09SDavid van Moolenbroek 	int mode;
118*00b67f09SDavid van Moolenbroek 	isc_fsaccess_t bits;
119*00b67f09SDavid van Moolenbroek 
120*00b67f09SDavid van Moolenbroek 	/*
121*00b67f09SDavid van Moolenbroek 	 * Done with checking bad bits.  Set mode_t.
122*00b67f09SDavid van Moolenbroek 	 */
123*00b67f09SDavid van Moolenbroek 	mode = 0;
124*00b67f09SDavid van Moolenbroek 
125*00b67f09SDavid van Moolenbroek #define SET_AND_CLEAR1(modebit) \
126*00b67f09SDavid van Moolenbroek 	if ((access & bits) != 0) { \
127*00b67f09SDavid van Moolenbroek 		mode |= modebit; \
128*00b67f09SDavid van Moolenbroek 		access &= ~bits; \
129*00b67f09SDavid van Moolenbroek 	}
130*00b67f09SDavid van Moolenbroek #define SET_AND_CLEAR(user, group, other) \
131*00b67f09SDavid van Moolenbroek 	SET_AND_CLEAR1(user); \
132*00b67f09SDavid van Moolenbroek 	bits <<= STEP; \
133*00b67f09SDavid van Moolenbroek 	SET_AND_CLEAR1(group); \
134*00b67f09SDavid van Moolenbroek 	bits <<= STEP; \
135*00b67f09SDavid van Moolenbroek 	SET_AND_CLEAR1(other);
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek 	bits = ISC_FSACCESS_READ | ISC_FSACCESS_LISTDIRECTORY;
138*00b67f09SDavid van Moolenbroek 
139*00b67f09SDavid van Moolenbroek 	SET_AND_CLEAR(S_IRUSR, S_IRGRP, S_IROTH);
140*00b67f09SDavid van Moolenbroek 
141*00b67f09SDavid van Moolenbroek 	bits = ISC_FSACCESS_WRITE |
142*00b67f09SDavid van Moolenbroek 	       ISC_FSACCESS_CREATECHILD |
143*00b67f09SDavid van Moolenbroek 	       ISC_FSACCESS_DELETECHILD;
144*00b67f09SDavid van Moolenbroek 
145*00b67f09SDavid van Moolenbroek 	SET_AND_CLEAR(S_IWUSR, S_IWGRP, S_IWOTH);
146*00b67f09SDavid van Moolenbroek 
147*00b67f09SDavid van Moolenbroek 	INSIST(access == 0);
148*00b67f09SDavid van Moolenbroek 
149*00b67f09SDavid van Moolenbroek 	if (_chmod(path, mode) < 0)
150*00b67f09SDavid van Moolenbroek 		return (isc__errno2result(errno));
151*00b67f09SDavid van Moolenbroek 
152*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
153*00b67f09SDavid van Moolenbroek }
154*00b67f09SDavid van Moolenbroek 
155*00b67f09SDavid van Moolenbroek isc_result_t
NTFS_Access_Control(const char * filename,const char * user,int access,isc_boolean_t isdir)156*00b67f09SDavid van Moolenbroek NTFS_Access_Control(const char *filename, const char *user, int access,
157*00b67f09SDavid van Moolenbroek 		    isc_boolean_t isdir) {
158*00b67f09SDavid van Moolenbroek 	SECURITY_DESCRIPTOR sd;
159*00b67f09SDavid van Moolenbroek 	BYTE aclBuffer[1024];
160*00b67f09SDavid van Moolenbroek 	PACL pacl=(PACL)&aclBuffer;
161*00b67f09SDavid van Moolenbroek 	BYTE sidBuffer[100];
162*00b67f09SDavid van Moolenbroek 	PSID psid=(PSID) &sidBuffer;
163*00b67f09SDavid van Moolenbroek 	DWORD sidBufferSize = sizeof(sidBuffer);
164*00b67f09SDavid van Moolenbroek 	BYTE adminSidBuffer[100];
165*00b67f09SDavid van Moolenbroek 	PSID padminsid=(PSID) &adminSidBuffer;
166*00b67f09SDavid van Moolenbroek 	DWORD adminSidBufferSize = sizeof(adminSidBuffer);
167*00b67f09SDavid van Moolenbroek 	BYTE otherSidBuffer[100];
168*00b67f09SDavid van Moolenbroek 	PSID pothersid=(PSID) &otherSidBuffer;
169*00b67f09SDavid van Moolenbroek 	DWORD otherSidBufferSize = sizeof(otherSidBuffer);
170*00b67f09SDavid van Moolenbroek 	char domainBuffer[100];
171*00b67f09SDavid van Moolenbroek 	DWORD domainBufferSize = sizeof(domainBuffer);
172*00b67f09SDavid van Moolenbroek 	SID_NAME_USE snu;
173*00b67f09SDavid van Moolenbroek 	DWORD NTFSbits;
174*00b67f09SDavid van Moolenbroek 	int caccess;
175*00b67f09SDavid van Moolenbroek 
176*00b67f09SDavid van Moolenbroek 
177*00b67f09SDavid van Moolenbroek 	/* Initialize an ACL */
178*00b67f09SDavid van Moolenbroek 	if (!InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION))
179*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
180*00b67f09SDavid van Moolenbroek 	if (!InitializeAcl(pacl, sizeof(aclBuffer), ACL_REVISION))
181*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
182*00b67f09SDavid van Moolenbroek 	if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer,
183*00b67f09SDavid van Moolenbroek 			  &domainBufferSize, &snu))
184*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
185*00b67f09SDavid van Moolenbroek 	domainBufferSize = sizeof(domainBuffer);
186*00b67f09SDavid van Moolenbroek 	if (!LookupAccountName(0, "Administrators", padminsid,
187*00b67f09SDavid van Moolenbroek 		&adminSidBufferSize, domainBuffer, &domainBufferSize, &snu)) {
188*00b67f09SDavid van Moolenbroek 		(void)GetLastError();
189*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
190*00b67f09SDavid van Moolenbroek 	}
191*00b67f09SDavid van Moolenbroek 	domainBufferSize = sizeof(domainBuffer);
192*00b67f09SDavid van Moolenbroek 	if (!LookupAccountName(0, "Everyone", pothersid,
193*00b67f09SDavid van Moolenbroek 		&otherSidBufferSize, domainBuffer, &domainBufferSize, &snu)) {
194*00b67f09SDavid van Moolenbroek 		(void)GetLastError();
195*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
196*00b67f09SDavid van Moolenbroek 	}
197*00b67f09SDavid van Moolenbroek 
198*00b67f09SDavid van Moolenbroek 	caccess = access;
199*00b67f09SDavid van Moolenbroek 	/* Owner check */
200*00b67f09SDavid van Moolenbroek 
201*00b67f09SDavid van Moolenbroek 	NTFSbits = 0;
202*00b67f09SDavid van Moolenbroek 	if (caccess & ISC_FSACCESS_READ)
203*00b67f09SDavid van Moolenbroek 		NTFSbits |= FILE_GENERIC_READ;
204*00b67f09SDavid van Moolenbroek 	if (caccess & ISC_FSACCESS_WRITE)
205*00b67f09SDavid van Moolenbroek 		NTFSbits |= FILE_GENERIC_WRITE;
206*00b67f09SDavid van Moolenbroek 	if (caccess & ISC_FSACCESS_EXECUTE)
207*00b67f09SDavid van Moolenbroek 		NTFSbits |= FILE_GENERIC_EXECUTE;
208*00b67f09SDavid van Moolenbroek 
209*00b67f09SDavid van Moolenbroek 	/* For directories check the directory-specific bits */
210*00b67f09SDavid van Moolenbroek 	if (isdir == ISC_TRUE) {
211*00b67f09SDavid van Moolenbroek 		if (caccess & ISC_FSACCESS_CREATECHILD)
212*00b67f09SDavid van Moolenbroek 			NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE;
213*00b67f09SDavid van Moolenbroek 		if (caccess & ISC_FSACCESS_DELETECHILD)
214*00b67f09SDavid van Moolenbroek 			NTFSbits |= FILE_DELETE_CHILD;
215*00b67f09SDavid van Moolenbroek 		if (caccess & ISC_FSACCESS_LISTDIRECTORY)
216*00b67f09SDavid van Moolenbroek 			NTFSbits |= FILE_LIST_DIRECTORY;
217*00b67f09SDavid van Moolenbroek 		if (caccess & ISC_FSACCESS_ACCESSCHILD)
218*00b67f09SDavid van Moolenbroek 			NTFSbits |= FILE_TRAVERSE;
219*00b67f09SDavid van Moolenbroek 	}
220*00b67f09SDavid van Moolenbroek 
221*00b67f09SDavid van Moolenbroek 	if (NTFSbits == (FILE_GENERIC_READ | FILE_GENERIC_WRITE
222*00b67f09SDavid van Moolenbroek 		     | FILE_GENERIC_EXECUTE))
223*00b67f09SDavid van Moolenbroek 		     NTFSbits |= FILE_ALL_ACCESS;
224*00b67f09SDavid van Moolenbroek 	/*
225*00b67f09SDavid van Moolenbroek 	 * Owner and Administrator also get STANDARD_RIGHTS_ALL
226*00b67f09SDavid van Moolenbroek 	 * to ensure that they have full control
227*00b67f09SDavid van Moolenbroek 	 */
228*00b67f09SDavid van Moolenbroek 
229*00b67f09SDavid van Moolenbroek 	NTFSbits |= STANDARD_RIGHTS_ALL;
230*00b67f09SDavid van Moolenbroek 
231*00b67f09SDavid van Moolenbroek 	/* Add the ACE to the ACL */
232*00b67f09SDavid van Moolenbroek 	if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, psid))
233*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
234*00b67f09SDavid van Moolenbroek 	if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits, padminsid))
235*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
236*00b67f09SDavid van Moolenbroek 
237*00b67f09SDavid van Moolenbroek 	/*
238*00b67f09SDavid van Moolenbroek 	 * Group is ignored since we can be in multiple groups or no group
239*00b67f09SDavid van Moolenbroek 	 * and its meaning is not clear on Win32
240*00b67f09SDavid van Moolenbroek 	 */
241*00b67f09SDavid van Moolenbroek 
242*00b67f09SDavid van Moolenbroek 	caccess = caccess >> STEP;
243*00b67f09SDavid van Moolenbroek 
244*00b67f09SDavid van Moolenbroek 	/*
245*00b67f09SDavid van Moolenbroek 	 * Other check.  We translate this to be the same as Everyone
246*00b67f09SDavid van Moolenbroek 	 */
247*00b67f09SDavid van Moolenbroek 
248*00b67f09SDavid van Moolenbroek 	caccess = caccess >> STEP;
249*00b67f09SDavid van Moolenbroek 
250*00b67f09SDavid van Moolenbroek 	NTFSbits = 0;
251*00b67f09SDavid van Moolenbroek 	if (caccess & ISC_FSACCESS_READ)
252*00b67f09SDavid van Moolenbroek 		NTFSbits |= FILE_GENERIC_READ;
253*00b67f09SDavid van Moolenbroek 	if (caccess & ISC_FSACCESS_WRITE)
254*00b67f09SDavid van Moolenbroek 		NTFSbits |= FILE_GENERIC_WRITE;
255*00b67f09SDavid van Moolenbroek 	if (caccess & ISC_FSACCESS_EXECUTE)
256*00b67f09SDavid van Moolenbroek 		NTFSbits |= FILE_GENERIC_EXECUTE;
257*00b67f09SDavid van Moolenbroek 
258*00b67f09SDavid van Moolenbroek 	/* For directories check the directory-specific bits */
259*00b67f09SDavid van Moolenbroek 	if (isdir == TRUE) {
260*00b67f09SDavid van Moolenbroek 		if (caccess & ISC_FSACCESS_CREATECHILD)
261*00b67f09SDavid van Moolenbroek 			NTFSbits |= FILE_ADD_SUBDIRECTORY | FILE_ADD_FILE;
262*00b67f09SDavid van Moolenbroek 		if (caccess & ISC_FSACCESS_DELETECHILD)
263*00b67f09SDavid van Moolenbroek 			NTFSbits |= FILE_DELETE_CHILD;
264*00b67f09SDavid van Moolenbroek 		if (caccess & ISC_FSACCESS_LISTDIRECTORY)
265*00b67f09SDavid van Moolenbroek 			NTFSbits |= FILE_LIST_DIRECTORY;
266*00b67f09SDavid van Moolenbroek 		if (caccess & ISC_FSACCESS_ACCESSCHILD)
267*00b67f09SDavid van Moolenbroek 			NTFSbits |= FILE_TRAVERSE;
268*00b67f09SDavid van Moolenbroek 	}
269*00b67f09SDavid van Moolenbroek 	/* Add the ACE to the ACL */
270*00b67f09SDavid van Moolenbroek 	if (!AddAccessAllowedAce(pacl, ACL_REVISION, NTFSbits,
271*00b67f09SDavid van Moolenbroek 				 pothersid))
272*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
273*00b67f09SDavid van Moolenbroek 
274*00b67f09SDavid van Moolenbroek 	if (!SetSecurityDescriptorDacl(&sd, TRUE, pacl, FALSE))
275*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
276*00b67f09SDavid van Moolenbroek 	if (!SetFileSecurity(filename, DACL_SECURITY_INFORMATION, &sd)) {
277*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
278*00b67f09SDavid van Moolenbroek 	}
279*00b67f09SDavid van Moolenbroek 
280*00b67f09SDavid van Moolenbroek 	return(ISC_R_SUCCESS);
281*00b67f09SDavid van Moolenbroek }
282*00b67f09SDavid van Moolenbroek 
283*00b67f09SDavid van Moolenbroek isc_result_t
NTFS_fsaccess_set(const char * path,isc_fsaccess_t access,isc_boolean_t isdir)284*00b67f09SDavid van Moolenbroek NTFS_fsaccess_set(const char *path, isc_fsaccess_t access,
285*00b67f09SDavid van Moolenbroek 		  isc_boolean_t isdir){
286*00b67f09SDavid van Moolenbroek 
287*00b67f09SDavid van Moolenbroek 	/*
288*00b67f09SDavid van Moolenbroek 	 * For NTFS we first need to get the name of the account under
289*00b67f09SDavid van Moolenbroek 	 * which BIND is running
290*00b67f09SDavid van Moolenbroek 	 */
291*00b67f09SDavid van Moolenbroek 	if (namelen == 0) {
292*00b67f09SDavid van Moolenbroek 		namelen = sizeof(username);
293*00b67f09SDavid van Moolenbroek 		if (GetUserName(username, &namelen) == 0)
294*00b67f09SDavid van Moolenbroek 			return (ISC_R_FAILURE);
295*00b67f09SDavid van Moolenbroek 	}
296*00b67f09SDavid van Moolenbroek 	return (NTFS_Access_Control(path, username, access, isdir));
297*00b67f09SDavid van Moolenbroek }
298*00b67f09SDavid van Moolenbroek 
299*00b67f09SDavid van Moolenbroek isc_result_t
isc_fsaccess_set(const char * path,isc_fsaccess_t access)300*00b67f09SDavid van Moolenbroek isc_fsaccess_set(const char *path, isc_fsaccess_t access) {
301*00b67f09SDavid van Moolenbroek 	struct stat statb;
302*00b67f09SDavid van Moolenbroek 	isc_boolean_t is_dir = ISC_FALSE;
303*00b67f09SDavid van Moolenbroek 	isc_result_t result;
304*00b67f09SDavid van Moolenbroek 
305*00b67f09SDavid van Moolenbroek 	if (stat(path, &statb) != 0)
306*00b67f09SDavid van Moolenbroek 		return (isc__errno2result(errno));
307*00b67f09SDavid van Moolenbroek 
308*00b67f09SDavid van Moolenbroek 	if ((statb.st_mode & S_IFDIR) != 0)
309*00b67f09SDavid van Moolenbroek 		is_dir = ISC_TRUE;
310*00b67f09SDavid van Moolenbroek 	else if ((statb.st_mode & S_IFREG) == 0)
311*00b67f09SDavid van Moolenbroek 		return (ISC_R_INVALIDFILE);
312*00b67f09SDavid van Moolenbroek 
313*00b67f09SDavid van Moolenbroek 	result = check_bad_bits(access, is_dir);
314*00b67f09SDavid van Moolenbroek 	if (result != ISC_R_SUCCESS)
315*00b67f09SDavid van Moolenbroek 		return (result);
316*00b67f09SDavid van Moolenbroek 
317*00b67f09SDavid van Moolenbroek 	/*
318*00b67f09SDavid van Moolenbroek 	 * Determine if this is a FAT or NTFS disk and
319*00b67f09SDavid van Moolenbroek 	 * call the appropriate function to set the permissions
320*00b67f09SDavid van Moolenbroek 	 */
321*00b67f09SDavid van Moolenbroek 	if (is_ntfs(path))
322*00b67f09SDavid van Moolenbroek 		return (NTFS_fsaccess_set(path, access, is_dir));
323*00b67f09SDavid van Moolenbroek 	else
324*00b67f09SDavid van Moolenbroek 		return (FAT_fsaccess_set(path, access));
325*00b67f09SDavid van Moolenbroek }
326*00b67f09SDavid van Moolenbroek 
327*00b67f09SDavid van Moolenbroek isc_result_t
isc_fsaccess_changeowner(const char * filename,const char * user)328*00b67f09SDavid van Moolenbroek isc_fsaccess_changeowner(const char *filename, const char *user) {
329*00b67f09SDavid van Moolenbroek 	SECURITY_DESCRIPTOR psd;
330*00b67f09SDavid van Moolenbroek 	BYTE sidBuffer[500];
331*00b67f09SDavid van Moolenbroek 	BYTE groupBuffer[500];
332*00b67f09SDavid van Moolenbroek 	PSID psid=(PSID) &sidBuffer;
333*00b67f09SDavid van Moolenbroek 	DWORD sidBufferSize = sizeof(sidBuffer);
334*00b67f09SDavid van Moolenbroek 	char domainBuffer[100];
335*00b67f09SDavid van Moolenbroek 	DWORD domainBufferSize = sizeof(domainBuffer);
336*00b67f09SDavid van Moolenbroek 	SID_NAME_USE snu;
337*00b67f09SDavid van Moolenbroek 	PSID pSidGroup = (PSID) &groupBuffer;
338*00b67f09SDavid van Moolenbroek 	DWORD groupBufferSize = sizeof(groupBuffer);
339*00b67f09SDavid van Moolenbroek 
340*00b67f09SDavid van Moolenbroek 
341*00b67f09SDavid van Moolenbroek 	/*
342*00b67f09SDavid van Moolenbroek 	 * Determine if this is a FAT or NTFS disk and
343*00b67f09SDavid van Moolenbroek 	 * call the appropriate function to set the ownership
344*00b67f09SDavid van Moolenbroek 	 * FAT disks do not have ownership attributes so it's
345*00b67f09SDavid van Moolenbroek 	 * a noop.
346*00b67f09SDavid van Moolenbroek 	 */
347*00b67f09SDavid van Moolenbroek 	if (is_ntfs(filename) == FALSE)
348*00b67f09SDavid van Moolenbroek 		return (ISC_R_SUCCESS);
349*00b67f09SDavid van Moolenbroek 
350*00b67f09SDavid van Moolenbroek 	if (!InitializeSecurityDescriptor(&psd, SECURITY_DESCRIPTOR_REVISION))
351*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
352*00b67f09SDavid van Moolenbroek 
353*00b67f09SDavid van Moolenbroek 	if (!LookupAccountName(0, user, psid, &sidBufferSize, domainBuffer,
354*00b67f09SDavid van Moolenbroek 		&domainBufferSize, &snu))
355*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
356*00b67f09SDavid van Moolenbroek 
357*00b67f09SDavid van Moolenbroek 	/* Make sure administrators can get to it */
358*00b67f09SDavid van Moolenbroek 	domainBufferSize = sizeof(domainBuffer);
359*00b67f09SDavid van Moolenbroek 	if (!LookupAccountName(0, "Administrators", pSidGroup,
360*00b67f09SDavid van Moolenbroek 		&groupBufferSize, domainBuffer, &domainBufferSize, &snu))
361*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
362*00b67f09SDavid van Moolenbroek 
363*00b67f09SDavid van Moolenbroek 	if (!SetSecurityDescriptorOwner(&psd, psid, FALSE))
364*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
365*00b67f09SDavid van Moolenbroek 
366*00b67f09SDavid van Moolenbroek 	if (!SetSecurityDescriptorGroup(&psd, pSidGroup, FALSE))
367*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
368*00b67f09SDavid van Moolenbroek 
369*00b67f09SDavid van Moolenbroek 	if (!SetFileSecurity(filename,
370*00b67f09SDavid van Moolenbroek 		OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION,
371*00b67f09SDavid van Moolenbroek 		&psd))
372*00b67f09SDavid van Moolenbroek 		return (ISC_R_NOPERM);
373*00b67f09SDavid van Moolenbroek 
374*00b67f09SDavid van Moolenbroek 	return (ISC_R_SUCCESS);
375*00b67f09SDavid van Moolenbroek }
376*00b67f09SDavid van Moolenbroek 
377