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