os2acl.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
  3. See the accompanying file LICENSE, version 2000-Apr-09 or later
  4. (the contents of which are also included in zip.h) for terms of use.
  5. If, for some reason, all these files are missing, the Info-ZIP license
  6. also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
  7. */
  8. /* os2acl.c - access to OS/2 (LAN Server) ACLs
  9. *
  10. * Author: Kai Uwe Rommel <rommel@ars.de>
  11. * Created: Mon Aug 08 1994
  12. *
  13. */
  14. /*
  15. * supported 32-bit compilers:
  16. * - emx+gcc
  17. * - IBM C Set++ 2.1 or newer
  18. * - Watcom C/C++ 10.0 or newer
  19. *
  20. * supported 16-bit compilers:
  21. * - MS C 6.00A
  22. * - Watcom C/C++ 10.0 or newer
  23. *
  24. * supported OS/2 LAN environments:
  25. * - IBM LAN Server/Requester 3.0, 4.0 and 5.0 (Warp Server)
  26. * - IBM Peer 1.0 (Warp Connect)
  27. */
  28. #ifdef KUR
  29. static char *rcsid =
  30. "$Id: os2acl.c,v 1.3 1996/04/03 19:18:27 rommel Exp rommel $";
  31. static char *rcsrev = "$Revision: 1.3 $";
  32. #endif
  33. /*
  34. * $Log: os2acl.c,v $
  35. * Revision 1.3 1996/04/03 19:18:27 rommel
  36. * minor fixes
  37. *
  38. * Revision 1.2 1996/03/30 22:03:52 rommel
  39. * avoid frequent dynamic allocation for every call
  40. * streamlined code
  41. *
  42. * Revision 1.1 1996/03/30 09:35:00 rommel
  43. * Initial revision
  44. *
  45. */
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <ctype.h>
  50. #include <malloc.h>
  51. #define INCL_NOPM
  52. #define INCL_DOS
  53. #define INCL_DOSERRORS
  54. #include <os2.h>
  55. #include "os2/os2acl.h"
  56. #define UNLEN 20
  57. #if defined(__WATCOMC__) && defined(__386__) && !defined(__32BIT__)
  58. #define __32BIT__
  59. #endif
  60. #ifdef __32BIT__
  61. typedef ULONG U_INT;
  62. #ifdef __EMX__
  63. #define PSTR16 _far16ptr
  64. #define PTR16(x) _emx_32to16(x)
  65. #else /* other 32-bit */
  66. #define PSTR16 PCHAR16
  67. #define PTR16(x) ((PCHAR16)(x))
  68. #endif
  69. #else /* 16-bit */
  70. typedef USHORT U_INT;
  71. #define PSTR16 PSZ
  72. #define PTR16(x) (x)
  73. #endif
  74. typedef struct access_list
  75. {
  76. char acl_ugname[UNLEN+1];
  77. char acl_pad;
  78. USHORT acl_access;
  79. }
  80. ACCLIST;
  81. typedef struct access_info
  82. {
  83. PSTR16 acc_resource_name;
  84. USHORT acc_attr;
  85. USHORT acc_count;
  86. }
  87. ACCINFO;
  88. static ACCINFO *ai;
  89. static char *path, *data;
  90. #ifdef __32BIT__
  91. #ifdef __EMX__
  92. static USHORT (APIENTRY *_NetAccessGetInfo)(PSZ pszServer, PSZ pszResource,
  93. USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail);
  94. static USHORT (APIENTRY *_NetAccessSetInfo)(PSZ pszServer, PSZ pszResource,
  95. USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum);
  96. static USHORT (APIENTRY *_NetAccessAdd)(PSZ pszServer,
  97. USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer);
  98. USHORT NetAccessGetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel,
  99. PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail)
  100. {
  101. return (USHORT)
  102. (_THUNK_PROLOG (4+4+2+4+2+4);
  103. _THUNK_FLAT (pszServer);
  104. _THUNK_FLAT (pszResource);
  105. _THUNK_SHORT (sLevel);
  106. _THUNK_FLAT (pbBuffer);
  107. _THUNK_SHORT (cbBuffer);
  108. _THUNK_FLAT (pcbTotalAvail);
  109. _THUNK_CALLI (_emx_32to16(_NetAccessGetInfo)));
  110. }
  111. USHORT NetAccessSetInfo(PSZ pszServer, PSZ pszResource, USHORT sLevel,
  112. PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum)
  113. {
  114. return (USHORT)
  115. (_THUNK_PROLOG (4+4+2+4+2+2);
  116. _THUNK_FLAT (pszServer);
  117. _THUNK_FLAT (pszResource);
  118. _THUNK_SHORT (sLevel);
  119. _THUNK_FLAT (pbBuffer);
  120. _THUNK_SHORT (cbBuffer);
  121. _THUNK_SHORT (sParmNum);
  122. _THUNK_CALLI (_emx_32to16(_NetAccessSetInfo)));
  123. }
  124. USHORT NetAccessAdd(PSZ pszServer, USHORT sLevel,
  125. PVOID pbBuffer, USHORT cbBuffer)
  126. {
  127. return (USHORT)
  128. (_THUNK_PROLOG (4+2+4+2);
  129. _THUNK_FLAT (pszServer);
  130. _THUNK_SHORT (sLevel);
  131. _THUNK_FLAT (pbBuffer);
  132. _THUNK_SHORT (cbBuffer);
  133. _THUNK_CALLI (_emx_32to16(_NetAccessAdd)));
  134. }
  135. #else /* other 32-bit */
  136. APIRET16 (* APIENTRY16 NetAccessGetInfo)(PCHAR16 pszServer, PCHAR16 pszResource,
  137. USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, PVOID16 pcbTotalAvail);
  138. APIRET16 (* APIENTRY16 NetAccessSetInfo)(PCHAR16 pszServer, PCHAR16 pszResource,
  139. USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer, USHORT sParmNum);
  140. APIRET16 (* APIENTRY16 NetAccessAdd)(PCHAR16 pszServer,
  141. USHORT sLevel, PVOID16 pbBuffer, USHORT cbBuffer);
  142. #define _NetAccessGetInfo NetAccessGetInfo
  143. #define _NetAccessSetInfo NetAccessSetInfo
  144. #define _NetAccessAdd NetAccessAdd
  145. #if !defined(__IBMC__) || !defined(__TILED__)
  146. #define _tmalloc malloc
  147. #define _tfree free
  148. #endif
  149. #endif
  150. #else /* 16-bit */
  151. USHORT (APIENTRY *NetAccessGetInfo)(PSZ pszServer, PSZ pszResource,
  152. USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, PUSHORT pcbTotalAvail);
  153. USHORT (APIENTRY *NetAccessSetInfo)(PSZ pszServer, PSZ pszResource,
  154. USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer, USHORT sParmNum);
  155. USHORT (APIENTRY *NetAccessAdd)(PSZ pszServer,
  156. USHORT sLevel, PVOID pbBuffer, USHORT cbBuffer);
  157. #define _NetAccessGetInfo NetAccessGetInfo
  158. #define _NetAccessSetInfo NetAccessSetInfo
  159. #define _NetAccessAdd NetAccessAdd
  160. #define _tmalloc malloc
  161. #define _tfree free
  162. #define DosQueryProcAddr(handle, ord, name, funcptr) \
  163. DosGetProcAddr(handle, name, funcptr)
  164. #define DosQueryCurrentDir DosQCurDir
  165. #define DosQueryCurrentDisk DosQCurDisk
  166. #endif
  167. static BOOL acl_init(void)
  168. {
  169. static BOOL initialized, netapi_avail;
  170. HMODULE netapi;
  171. char buf[256];
  172. if (initialized)
  173. return netapi_avail;
  174. initialized = TRUE;
  175. if (DosLoadModule(buf, sizeof(buf), "NETAPI", &netapi))
  176. return FALSE;
  177. if (DosQueryProcAddr(netapi, 0, "NETACCESSGETINFO", (PFN *) &_NetAccessGetInfo) ||
  178. DosQueryProcAddr(netapi, 0, "NETACCESSSETINFO", (PFN *) &_NetAccessSetInfo) ||
  179. DosQueryProcAddr(netapi, 0, "NETACCESSADD", (PFN *) &_NetAccessAdd))
  180. return FALSE;
  181. #if defined(__WATCOMC__) && defined(__386__)
  182. NetAccessGetInfo = (PVOID) (ULONG) (PVOID16) NetAccessGetInfo;
  183. NetAccessSetInfo = (PVOID) (ULONG) (PVOID16) NetAccessSetInfo;
  184. NetAccessAdd = (PVOID) (ULONG) (PVOID16) NetAccessAdd;
  185. #endif
  186. if ((path = _tmalloc(CCHMAXPATH)) == NULL)
  187. return FALSE;
  188. if ((data = _tmalloc(ACL_BUFFERSIZE)) == NULL)
  189. return FALSE;
  190. if ((ai = _tmalloc(sizeof(ACCINFO))) == NULL)
  191. return -1;
  192. netapi_avail = TRUE;
  193. return netapi_avail;
  194. }
  195. static void acl_mkpath(char *buffer, const char *source)
  196. {
  197. char *ptr;
  198. static char cwd[CCHMAXPATH];
  199. static U_INT cwdlen;
  200. U_INT cdrive;
  201. ULONG drivemap;
  202. if (isalpha((int)source[0]) && source[1] == ':')
  203. buffer[0] = 0; /* fully qualified names */
  204. else
  205. {
  206. if (cwd[0] == 0)
  207. {
  208. DosQueryCurrentDisk(&cdrive, &drivemap);
  209. cwd[0] = (char)(cdrive + '@');
  210. cwd[1] = ':';
  211. cwd[2] = '\\';
  212. cwdlen = sizeof(cwd) - 3;
  213. DosQueryCurrentDir(0, cwd + 3, &cwdlen);
  214. cwdlen = strlen(cwd);
  215. }
  216. if (source[0] == '/' || source[0] == '\\')
  217. {
  218. if (source[1] == '/' || source[1] == '\\')
  219. buffer[0] = 0; /* UNC names */
  220. else
  221. {
  222. strncpy(buffer, cwd, 2);
  223. buffer[2] = 0;
  224. }
  225. }
  226. else
  227. {
  228. strcpy(buffer, cwd);
  229. if (cwd[cwdlen - 1] != '\\' && cwd[cwdlen - 1] != '/')
  230. strcat(buffer, "/");
  231. }
  232. }
  233. strcat(buffer, source);
  234. for (ptr = buffer; *ptr; ptr++)
  235. if (*ptr == '/')
  236. *ptr = '\\';
  237. if (ptr[-1] == '\\')
  238. ptr[-1] = 0;
  239. strupr(buffer);
  240. }
  241. static int acl_bin2text(char *data, char *text)
  242. {
  243. ACCINFO *ai;
  244. ACCLIST *al;
  245. U_INT cnt, offs;
  246. ai = (ACCINFO *) data;
  247. al = (ACCLIST *) (data + sizeof(ACCINFO));
  248. offs = sprintf(text, "ACL1:%X,%d\n",
  249. ai -> acc_attr, ai -> acc_count);
  250. for (cnt = 0; cnt < ai -> acc_count; cnt++)
  251. offs += sprintf(text + offs, "%s,%X\n",
  252. al[cnt].acl_ugname, al[cnt].acl_access);
  253. return strlen(text);
  254. }
  255. int acl_get(char *server, const char *resource, char *buffer)
  256. {
  257. USHORT datalen;
  258. PSZ srv = NULL;
  259. int rc;
  260. if (!acl_init())
  261. return -1;
  262. if (server)
  263. srv = server;
  264. acl_mkpath(path, resource);
  265. datalen = 0;
  266. rc = NetAccessGetInfo(srv, path, 1, data, ACL_BUFFERSIZE, &datalen);
  267. if (rc == 0)
  268. acl_bin2text(data, buffer);
  269. return rc;
  270. }
  271. static int acl_text2bin(char *data, char *text, char *path)
  272. {
  273. ACCINFO *ai;
  274. ACCLIST *al;
  275. char *ptr, *ptr2;
  276. U_INT cnt;
  277. ai = (ACCINFO *) data;
  278. ai -> acc_resource_name = PTR16(path);
  279. if (sscanf(text, "ACL1:%hX,%hd",
  280. &ai -> acc_attr, &ai -> acc_count) != 2)
  281. return ERROR_INVALID_PARAMETER;
  282. al = (ACCLIST *) (data + sizeof(ACCINFO));
  283. ptr = strchr(text, '\n') + 1;
  284. for (cnt = 0; cnt < ai -> acc_count; cnt++)
  285. {
  286. ptr2 = strchr(ptr, ',');
  287. strncpy(al[cnt].acl_ugname, ptr, ptr2 - ptr);
  288. al[cnt].acl_ugname[ptr2 - ptr] = 0;
  289. sscanf(ptr2 + 1, "%hx", &al[cnt].acl_access);
  290. ptr = strchr(ptr, '\n') + 1;
  291. }
  292. return sizeof(ACCINFO) + ai -> acc_count * sizeof(ACCLIST);
  293. }
  294. int acl_set(char *server, const char *resource, char *buffer)
  295. {
  296. USHORT datalen;
  297. PSZ srv = NULL;
  298. if (!acl_init())
  299. return -1;
  300. if (server)
  301. srv = server;
  302. acl_mkpath(path, resource);
  303. ai -> acc_resource_name = PTR16(path);
  304. ai -> acc_attr = 0;
  305. ai -> acc_count = 0;
  306. NetAccessAdd(srv, 1, ai, sizeof(ACCINFO));
  307. /* Ignore any errors, most probably because ACL already exists. */
  308. /* In any such case, try updating the existing ACL. */
  309. datalen = acl_text2bin(data, buffer, path);
  310. return NetAccessSetInfo(srv, path, 1, data, datalen, 0);
  311. }
  312. /* end of os2acl.c */