Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

448 lines
18 KiB

  1. /*
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. admin.h
  5. Abstract:
  6. This module contains admin interface for server service. All data
  7. strucutures anc constants shared between the AFP service and the
  8. AFP server service will be contained in this file.
  9. Author:
  10. Jameel Hyder (microsoft!jameelh)
  11. Revision History:
  12. 25 Apr 1992 JameelH Initial Version
  13. 2 Sept 1992 NarenG Added structure to pass security information
  14. between the service and the server.
  15. 1 Feb 1993 SueA Added structure to pass evenlog infomation
  16. from the server to the service.
  17. --*/
  18. #ifndef _ADMIN_
  19. #define _ADMIN_
  20. #include <lmcons.h> // Need DNLEN and LM20_UNLEN
  21. #include <crypt.h> // Need LM_OWF_PASSWORD_LENGTH
  22. #include <ntsam.h>
  23. #include <ntsamp.h>
  24. #include <nbtioctl.h> // DNS_MAX_NAME_LENGTH
  25. #define AFP_API_BASE 1000
  26. #define AFP_CC(_request_, _Method_) CTL_CODE(FILE_DEVICE_NETWORK, \
  27. _request_ + AFP_API_BASE, \
  28. _Method_, FILE_ANY_ACCESS)
  29. #define AFP_CC_BASE(ControlCode) ((((ControlCode) >> 2) - AFP_API_BASE) & 0xFF)
  30. #define AFP_CC_METHOD(ControlCode) ((ControlCode) & 0x03)
  31. // Do not change this table without also changing the table in SERVER\FSD.C
  32. #define CC_BASE_SERVICE_START 0x01
  33. #define CC_BASE_SERVICE_STOP 0x02
  34. #define CC_BASE_SERVICE_PAUSE 0x03
  35. #define CC_BASE_SERVICE_CONTINUE 0x04
  36. #define CC_BASE_GET_STATISTICS 0x05
  37. #define CC_BASE_GET_STATISTICS_EX 0x06
  38. #define CC_BASE_CLEAR_STATISTICS 0x07
  39. #define CC_BASE_GET_PROF_COUNTERS 0x08
  40. #define CC_BASE_CLEAR_PROF_COUNTERS 0x09
  41. #define CC_BASE_SERVER_ADD_SID_OFFSETS 0x0A
  42. #define CC_BASE_SERVER_GET_INFO 0x0B
  43. #define CC_BASE_SERVER_SET_INFO 0x0C
  44. #define CC_BASE_SERVER_ADD_ETC 0x0D
  45. #define CC_BASE_SERVER_SET_ETC 0x0E
  46. #define CC_BASE_SERVER_DELETE_ETC 0x0F
  47. #define CC_BASE_SERVER_ADD_ICON 0x10
  48. #define CC_BASE_VOLUME_ADD 0x11
  49. #define CC_BASE_VOLUME_DELETE 0x12
  50. #define CC_BASE_VOLUME_GET_INFO 0x13
  51. #define CC_BASE_VOLUME_SET_INFO 0x14
  52. #define CC_BASE_VOLUME_ENUM 0x15
  53. #define CC_BASE_SESSION_ENUM 0x16
  54. #define CC_BASE_SESSION_CLOSE 0x17
  55. #define CC_BASE_CONNECTION_ENUM 0x18
  56. #define CC_BASE_CONNECTION_CLOSE 0x19
  57. #define CC_BASE_DIRECTORY_GET_INFO 0x1A
  58. #define CC_BASE_DIRECTORY_SET_INFO 0x1B
  59. #define CC_BASE_FORK_ENUM 0x1C
  60. #define CC_BASE_FORK_CLOSE 0x1D
  61. #define CC_BASE_MESSAGE_SEND 0x1E
  62. #define CC_BASE_FINDER_SET 0x1F
  63. #define CC_BASE_GET_FSD_COMMAND 0x20
  64. #define CC_BASE_MAX 0x21
  65. #define OP_SERVICE_START AFP_CC(CC_BASE_SERVICE_START, METHOD_BUFFERED)
  66. #define OP_SERVICE_STOP AFP_CC(CC_BASE_SERVICE_STOP, METHOD_BUFFERED)
  67. #define OP_SERVICE_PAUSE AFP_CC(CC_BASE_SERVICE_PAUSE, METHOD_BUFFERED)
  68. #define OP_SERVICE_CONTINUE AFP_CC(CC_BASE_SERVICE_CONTINUE,METHOD_BUFFERED)
  69. #define OP_GET_STATISTICS AFP_CC(CC_BASE_GET_STATISTICS,METHOD_IN_DIRECT)
  70. #define OP_GET_STATISTICS_EX AFP_CC(CC_BASE_GET_STATISTICS_EX,METHOD_IN_DIRECT)
  71. #define OP_CLEAR_STATISTICS AFP_CC(CC_BASE_CLEAR_STATISTICS,METHOD_BUFFERED)
  72. #define OP_GET_PROF_COUNTERS AFP_CC(CC_BASE_GET_PROF_COUNTERS,METHOD_IN_DIRECT)
  73. #define OP_CLEAR_PROF_COUNTERS AFP_CC(CC_BASE_CLEAR_PROF_COUNTERS,METHOD_BUFFERED)
  74. #define OP_SERVER_ADD_SID_OFFSETS AFP_CC(CC_BASE_SERVER_ADD_SID_OFFSETS,METHOD_BUFFERED)
  75. #define OP_SERVER_GET_INFO AFP_CC(CC_BASE_SERVER_GET_INFO,METHOD_IN_DIRECT)
  76. #define OP_SERVER_SET_INFO AFP_CC(CC_BASE_SERVER_SET_INFO,METHOD_BUFFERED)
  77. #define OP_SERVER_ADD_ETC AFP_CC(CC_BASE_SERVER_ADD_ETC,METHOD_BUFFERED)
  78. #define OP_SERVER_SET_ETC AFP_CC(CC_BASE_SERVER_SET_ETC,METHOD_BUFFERED)
  79. #define OP_SERVER_DELETE_ETC AFP_CC(CC_BASE_SERVER_DELETE_ETC,METHOD_BUFFERED)
  80. #define OP_SERVER_ADD_ICON AFP_CC(CC_BASE_SERVER_ADD_ICON,METHOD_BUFFERED)
  81. #define OP_VOLUME_ADD AFP_CC(CC_BASE_VOLUME_ADD,METHOD_BUFFERED)
  82. #define OP_VOLUME_DELETE AFP_CC(CC_BASE_VOLUME_DELETE,METHOD_BUFFERED)
  83. #define OP_VOLUME_GET_INFO AFP_CC(CC_BASE_VOLUME_GET_INFO,METHOD_IN_DIRECT)
  84. #define OP_VOLUME_SET_INFO AFP_CC(CC_BASE_VOLUME_SET_INFO,METHOD_BUFFERED)
  85. #define OP_VOLUME_ENUM AFP_CC(CC_BASE_VOLUME_ENUM,METHOD_IN_DIRECT)
  86. #define OP_SESSION_ENUM AFP_CC(CC_BASE_SESSION_ENUM,METHOD_IN_DIRECT)
  87. #define OP_SESSION_CLOSE AFP_CC(CC_BASE_SESSION_CLOSE,METHOD_BUFFERED)
  88. #define OP_CONNECTION_ENUM AFP_CC(CC_BASE_CONNECTION_ENUM,METHOD_IN_DIRECT)
  89. #define OP_CONNECTION_CLOSE AFP_CC(CC_BASE_CONNECTION_CLOSE,METHOD_BUFFERED)
  90. #define OP_DIRECTORY_GET_INFO AFP_CC(CC_BASE_DIRECTORY_GET_INFO,METHOD_IN_DIRECT)
  91. #define OP_DIRECTORY_SET_INFO AFP_CC(CC_BASE_DIRECTORY_SET_INFO,METHOD_BUFFERED)
  92. #define OP_FORK_ENUM AFP_CC(CC_BASE_FORK_ENUM,METHOD_IN_DIRECT)
  93. #define OP_FORK_CLOSE AFP_CC(CC_BASE_FORK_CLOSE,METHOD_BUFFERED)
  94. #define OP_MESSAGE_SEND AFP_CC(CC_BASE_MESSAGE_SEND,METHOD_BUFFERED)
  95. #define OP_FINDER_SET AFP_CC(CC_BASE_FINDER_SET,METHOD_BUFFERED)
  96. #define OP_GET_FSD_COMMAND AFP_CC(CC_BASE_GET_FSD_COMMAND,METHOD_BUFFERED)
  97. #define POINTER_TO_OFFSET(val,start) \
  98. (val) = ((val) == NULL) ? NULL : (PVOID)( (PCHAR)(val) - (ULONG_PTR)(start) )
  99. #define OFFSET_TO_POINTER(val,start) \
  100. (val) = ((val) == NULL) ? NULL : (PVOID)( (PCHAR)(val) + (ULONG_PTR)(start) )
  101. #define AFPSERVER_DEVICE_NAME TEXT("\\Device\\MacFile")
  102. #define AFPSERVER_REGISTRY_KEY TEXT("\\Registry\\Machine\\System\\CurrentControlSet\\Services\\MacSrv")
  103. #define AFPSERVER_VOLUME_ICON_FILE { L'I', L'C', L'O', L'N', 0xF00D, 0000 }
  104. // Number of wchars in above string, including terminating null
  105. #define AFPSERVER_VOLUME_ICON_FILE_SIZE 6
  106. #define AFPSERVER_RESOURCE_STREAM L":AFP_Resource"
  107. // The following data structures are used exclusively by the
  108. // user-mode/kernel-mode interface.
  109. typedef enum _AFP_SID_TYPE
  110. {
  111. AFP_SID_TYPE_DOMAIN,
  112. AFP_SID_TYPE_PRIMARY_DOMAIN,
  113. AFP_SID_TYPE_WELL_KNOWN,
  114. AFP_SID_TYPE_LOGON
  115. } AFP_SID_TYPE;
  116. typedef struct _AFP_SID_OFFSET
  117. {
  118. DWORD Offset;
  119. AFP_SID_TYPE SidType;
  120. PBYTE pSid; // Actually an Offset from the
  121. // beginning of this structure.
  122. } AFP_SID_OFFSET, *PAFP_SID_OFFSET;
  123. // Packet used to add the SID/OFFSET pairs
  124. typedef struct _AFP_SID_OFFSET_DESC
  125. {
  126. ULONG CountOfSidOffsets; // Number of Sid-Offset pairs
  127. ULONG QuadAlignDummy1;
  128. AFP_SID_OFFSET SidOffsetPairs[1];
  129. }AFP_SID_OFFSET_DESC, *PAFP_SID_OFFSET_DESC;
  130. // Packet used by ServerEtcSet and ServerEtcDelete.
  131. typedef struct _EtcMapInfo2
  132. {
  133. UCHAR etc_type[AFP_TYPE_LEN];
  134. UCHAR etc_creator[AFP_CREATOR_LEN];
  135. WCHAR etc_extension[AFP_EXTENSION_LEN+1];
  136. } ETCMAPINFO2, *PETCMAPINFO2;
  137. // once passed by Service, this is used by Server internally
  138. typedef struct _EtcMapInfo
  139. {
  140. UCHAR etc_type[AFP_TYPE_LEN];
  141. UCHAR etc_creator[AFP_CREATOR_LEN];
  142. UCHAR etc_extension[AFP_EXTENSION_LEN+1]; // extension in ANSI
  143. } ETCMAPINFO, *PETCMAPINFO;
  144. typedef struct _SrvIconInfo
  145. {
  146. UCHAR icon_type[AFP_TYPE_LEN];
  147. UCHAR icon_creator[AFP_CREATOR_LEN];
  148. DWORD icon_icontype;
  149. DWORD icon_length;
  150. // Icon data follows
  151. } SRVICONINFO, *PSRVICONINFO;
  152. // Packet used by ServerEtcAdd.
  153. typedef struct _ServerEtcPacket
  154. {
  155. DWORD retc_NumEtcMaps; // Number of type creator mappings
  156. ETCMAPINFO2 retc_EtcMaps[1]; // List of Etc mappings
  157. } SRVETCPKT, *PSRVETCPKT;
  158. // The following is the generic enumerate request packet.
  159. typedef struct _EnumRequestPacket
  160. {
  161. DWORD erqp_Index; // Starting index from which the
  162. // enum should start. 0 => beginning
  163. DWORD erqp_Filter; // AFP_FILTER_ON_VOLUME_ID
  164. // or AFP_FILTER_ON_SESSION_ID
  165. DWORD erqp_ID; // Volume ID or sessions ID.
  166. DWORD QuadAlignDummy; // Quad Word Alignment enforcement
  167. } ENUMREQPKT, *PENUMREQPKT;
  168. // The following is the generic enumerate response packet.
  169. typedef struct _EnumResponsePacket
  170. {
  171. DWORD ersp_cTotEnts; // Total number of available entries
  172. DWORD ersp_cInBuf; // Number of entries in buffer union
  173. DWORD ersp_hResume; // Index of the first entry that will be
  174. // read on the subsequent call. Valid only
  175. // if the return code is AFPERR_MORE_DATA.
  176. DWORD QuadAlignDummy; // Quad Word Alignment enforcement
  177. // Will contain an array of AFP_FILE_INFO, AFP_SESSION_INFO,
  178. // AFP_CONNECTION_INFO or AFP_VOLUME_INFO structures.
  179. } ENUMRESPPKT, *PENUMRESPPKT;
  180. // The following is the generic set info. request packet.
  181. typedef struct _SetInfoRequestPacket
  182. {
  183. DWORD sirqp_parmnum; // Mask of bits representing fields
  184. DWORD dwAlignDummy; // For QWORD alignment
  185. // Will be followed by AFP_VOLUME_INFO or AFP_DIRECTORY_INFO structure
  186. } SETINFOREQPKT, *PSETINFOREQPKT;
  187. // The following data structures are used to send security information
  188. // from the service down to the server; or to send eventlog information from
  189. // the server up to the service.
  190. #define MAX_FSD_CMD_SIZE 4096
  191. #define NUM_SECURITY_UTILITY_THREADS 4
  192. typedef enum _AFP_FSD_CMD_ID
  193. {
  194. AFP_FSD_CMD_NAME_TO_SID,
  195. AFP_FSD_CMD_SID_TO_NAME,
  196. AFP_FSD_CMD_CHANGE_PASSWORD,
  197. AFP_FSD_CMD_LOG_EVENT,
  198. AFP_FSD_CMD_TERMINATE_THREAD
  199. } AFP_FSD_CMD_ID;
  200. // These used to live in afpconst.h, but now the service needs some of these
  201. // to do the native AppleUam stuff
  202. //
  203. // UAMs strings and values
  204. #define AFP_NUM_UAMS 7
  205. #define NO_USER_AUTHENT 0
  206. #define NO_USER_AUTHENT_NAME "No User Authent"
  207. #define CLEAR_TEXT_AUTHENT 1
  208. #define CLEAR_TEXT_AUTHENT_NAME "ClearTxt Passwrd"
  209. #define CUSTOM_UAM_V1 2
  210. #define CUSTOM_UAM_NAME_V1 "Microsoft V1.0"
  211. #define CUSTOM_UAM_V2 3
  212. #define CUSTOM_UAM_NAME_V2 "MS2.0"
  213. #define CUSTOM_UAM_V3 4
  214. #define CUSTOM_UAM_NAME_V3 "MS3.0"
  215. #define RANDNUM_EXCHANGE 5
  216. #define RANDNUM_EXCHANGE_NAME "Randnum Exchange"
  217. #define TWOWAY_EXCHANGE 6
  218. #define TWOWAY_EXCHANGE_NAME "2-Way Randnum exchange"
  219. // how many bytes of response comes back
  220. #define RANDNUM_RESP_LEN 8
  221. #define TWOWAY_RESP_LEN 16
  222. // this define stolen from ntsam.h
  223. #define SAM_MAX_PASSWORD_LENGTH (256)
  224. #define SFM_CHANGE_PASSWORD_SIGNATURE "ChP" // 4 bytes including NULL
  225. typedef struct _SFM_PASSWORD_CHANGE_MESSAGE_HEADER
  226. {
  227. UCHAR Signature[sizeof(SFM_CHANGE_PASSWORD_SIGNATURE)];
  228. ULONG cbMessage;
  229. ULONG Version;
  230. } SFM_PASSWORD_CHANGE_MESSAGE_HEADER, * PSFM_PASSWORD_CHANGE_MESSAGE_HEADER;
  231. typedef struct _SFM_PASSWORD_CHANGE_MESSAGE_1_SHORT
  232. {
  233. UCHAR Signature[sizeof(SFM_CHANGE_PASSWORD_SIGNATURE)];
  234. ULONG cbMessage; // sizeof(SFM_PASSWORD_CHANGE_MESSAGE_1_SHORT) including signature
  235. ULONG Version; // version 1 without LM
  236. UCHAR NewPasswordEncryptedWithOldNt[sizeof(SAMPR_ENCRYPTED_USER_PASSWORD) / 2];
  237. ENCRYPTED_NT_OWF_PASSWORD OldNtOwfPasswordEncryptedWithNewNt;
  238. } SFM_PASSWORD_CHANGE_MESSAGE_1_SHORT, * PSFM_PASSWORD_CHANGE_MESSAGE_1_SHORT;
  239. typedef struct _SFM_PASSWORD_CHANGE_MESSAGE_1
  240. {
  241. UCHAR Signature[sizeof(SFM_CHANGE_PASSWORD_SIGNATURE)];
  242. ULONG cbMessage; // sizeof(SFM_PASSWORD_CHANGE_MESSAGE_1) including signature
  243. ULONG Version; // version 1 without LM
  244. SAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldNt;
  245. ENCRYPTED_NT_OWF_PASSWORD OldNtOwfPasswordEncryptedWithNewNt;
  246. } SFM_PASSWORD_CHANGE_MESSAGE_1, * PSFM_PASSWORD_CHANGE_MESSAGE_1;
  247. typedef struct _SFM_PASSWORD_CHANGE_MESSAGE_2
  248. {
  249. UCHAR Signature[sizeof(SFM_CHANGE_PASSWORD_SIGNATURE)];
  250. ULONG cbMessage; // sizeof(SFM_PASSWORD_CHANGE_MESSAGE_2) including signature
  251. ULONG Version; // version 2 with LM
  252. SAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldNt;
  253. ENCRYPTED_NT_OWF_PASSWORD OldNtOwfPasswordEncryptedWithNewNt;
  254. SAMPR_ENCRYPTED_USER_PASSWORD NewPasswordEncryptedWithOldLm;
  255. ENCRYPTED_LM_OWF_PASSWORD OldLmOwfPasswordEncryptedWithNewLmOrNt;
  256. } SFM_PASSWORD_CHANGE_MESSAGE_2, * PSFM_PASSWORD_CHANGE_MESSAGE_2;
  257. typedef struct _SFM_PASSWORD_CHANGE_MESSAGE
  258. {
  259. union
  260. {
  261. SFM_PASSWORD_CHANGE_MESSAGE_HEADER h;
  262. SFM_PASSWORD_CHANGE_MESSAGE_1 m1;
  263. SFM_PASSWORD_CHANGE_MESSAGE_2 m2;
  264. };
  265. } SFM_PASSWORD_CHANGE_MESSAGE, * PSFM_PASSWORD_CHANGE_MESSAGE;
  266. typedef struct _AFP_PASSWORD_CHANGE_NT
  267. {
  268. SFM_PASSWORD_CHANGE_MESSAGE Ciphers;
  269. } AFP_PASSWORD_CHANGE_NT, * PAFP_PASSWORD_CHANGE_NT;
  270. typedef struct _AFP_PASSWORD_DESC
  271. {
  272. ULONG AuthentMode;
  273. union
  274. {
  275. AFP_PASSWORD_CHANGE_NT NtEncryptedBuff;
  276. struct _AFP_PASSWORD_BUFF_LM
  277. {
  278. BYTE OldPassword[LM_OWF_PASSWORD_LENGTH + 2];
  279. BYTE NewPassword[(SAM_MAX_PASSWORD_LENGTH * 2) + 4];
  280. DWORD OldPasswordLen;
  281. DWORD NewPasswordLen;
  282. BYTE bPasswordLength;
  283. };
  284. };
  285. //
  286. // allow longer names in NTLMv2
  287. //
  288. WCHAR DomainName[DNS_MAX_NAME_LENGTH + 4]; // allow DNS name
  289. WCHAR UserName[UNLEN + 1];
  290. #if 0
  291. WCHAR DomainName[DNLEN + 1];
  292. WCHAR UserName[LM20_UNLEN + 1];
  293. #endif 0
  294. } AFP_PASSWORD_DESC, *PAFP_PASSWORD_DESC;
  295. typedef struct _AFP_EVENTLOG_DESC
  296. {
  297. DWORD MsgID;
  298. USHORT EventType;
  299. USHORT StringCount;
  300. DWORD DumpDataLen;
  301. DWORD QuadAlignDummy; // Quad Word Alignment enforcement
  302. PVOID pDumpData;
  303. LPWSTR * ppStrings;
  304. // Pointer to an array of string pointers that will follow the DumpData.
  305. } AFP_EVENTLOG_DESC, *PAFP_EVENTLOG_DESC;
  306. typedef struct _AFP_FSD_CMD_HEADER
  307. {
  308. AFP_FSD_CMD_ID FsdCommand;
  309. ULONG ntStatus;
  310. DWORD dwId;
  311. DWORD QuadAlignDummy; // Quad Word Alignment enforcement
  312. } AFP_FSD_CMD_HEADER, *PAFP_FSD_CMD_HEADER;
  313. typedef struct _AFP_FSD_CMD_PKT
  314. {
  315. AFP_FSD_CMD_HEADER Header;
  316. union
  317. {
  318. BYTE Sid[1];
  319. BYTE Name[1];
  320. AFP_PASSWORD_DESC Password;
  321. AFP_EVENTLOG_DESC Eventlog;
  322. } Data;
  323. } AFP_FSD_CMD_PKT, *PAFP_FSD_CMD_PKT;
  324. // The following definitions and macros are used both by the service as well as the
  325. // server. DO NOT CHANGE THIS w/o LOOKING at both the uses.
  326. // Directory Access Permissions
  327. #define DIR_ACCESS_SEARCH 0x01 // See Folders
  328. #define DIR_ACCESS_READ 0x02 // See Files
  329. #define DIR_ACCESS_WRITE 0x04 // Make Changes
  330. #define DIR_ACCESS_OWNER 0x80 // Only for user
  331. // if he has owner rights
  332. #define DIR_ACCESS_ALL (DIR_ACCESS_READ | \
  333. DIR_ACCESS_SEARCH | \
  334. DIR_ACCESS_WRITE)
  335. #define OWNER_RIGHTS_SHIFT 0
  336. #define GROUP_RIGHTS_SHIFT 8
  337. #define WORLD_RIGHTS_SHIFT 16
  338. #define USER_RIGHTS_SHIFT 24
  339. #define AFP_READ_ACCESS (READ_CONTROL | \
  340. FILE_READ_ATTRIBUTES | \
  341. FILE_TRAVERSE | \
  342. FILE_LIST_DIRECTORY | \
  343. FILE_READ_EA)
  344. #define AFP_WRITE_ACCESS (FILE_ADD_FILE | \
  345. FILE_ADD_SUBDIRECTORY| \
  346. FILE_WRITE_ATTRIBUTES| \
  347. FILE_WRITE_EA | \
  348. DELETE)
  349. #define AFP_OWNER_ACCESS (WRITE_DAC | \
  350. WRITE_OWNER)
  351. #define AFP_MIN_ACCESS (FILE_READ_ATTRIBUTES | \
  352. READ_CONTROL)
  353. #define AfpAccessMaskToAfpPermissions(Rights, Mask, Type) \
  354. if ((Type) == ACCESS_ALLOWED_ACE_TYPE) \
  355. { \
  356. if (((Mask) & AFP_READ_ACCESS) == AFP_READ_ACCESS) \
  357. (Rights) |= (DIR_ACCESS_READ | DIR_ACCESS_SEARCH); \
  358. if (((Mask) & AFP_WRITE_ACCESS) == AFP_WRITE_ACCESS) \
  359. (Rights) |= DIR_ACCESS_WRITE; \
  360. } \
  361. else \
  362. { \
  363. ASSERT((Type) == ACCESS_DENIED_ACE_TYPE); \
  364. if ((Mask) & AFP_READ_ACCESS) \
  365. (Rights) &= ~(DIR_ACCESS_READ | DIR_ACCESS_SEARCH); \
  366. if ((Mask) & AFP_WRITE_ACCESS) \
  367. (Rights) &= ~DIR_ACCESS_WRITE; \
  368. }
  369. #endif // _ADMIN_