Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

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