home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip531.zip / os2 / os2acl.c < prev    next >
C/C++ Source or Header  |  1997-03-01  |  9KB  |  379 lines

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