home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Collection - Online Library - January 1996 / CKITOS2196.ISO / diskette / gg244043.dsk / unc.dsk / LS30UTIL / LS30UT.C < prev    next >
C/C++ Source or Header  |  1993-03-09  |  108KB  |  2,820 lines

  1. /*********************************************************************/
  2. /* LS30UT.C                                                          */
  3. /*                                                                   */
  4. /* This DLL provides utility functions for the IBM LAN Server 3.0    */
  5. /*                                                                   */
  6. /* These functions provided are:                                     */
  7. /*  GetDCName     Get Domain Controller Name                         */
  8. /*  CopyDirAcls   Copy Directory Access Control Profiles specified   */
  9. /*                in the source location to the destination location.*/
  10. /*                The source directory will be created if it does    */
  11. /*                not exist. Local support only                      */
  12. /*  DumpAllUsers  Dump all users defined to a binary file.           */
  13. /*  DumpUser      Dump user specified to a binary file.              */
  14. /*  InsertAllUsers From dump file restablish all user definitions,   */
  15. /*                Must supply new password.                          */
  16. /*  QueryDirAliasPath Query the path of a directory alias            */
  17. /*  MoveDirAlias  Move a directory alias to a new location           */
  18. /*                                                                   */
  19. /*  SetLogonAsn   Set logon assignment for a user                    */
  20. /*  GetLogonAsn   Get logon assignments for a user                   */
  21. /*                                                                   */
  22. /* Modified functions: REXXUTIL OS/2 2.0 Developers Toolkit sample   */
  23. /*  DropLs30utFuncs Drop all functions in LS30UT.DLL                 */
  24. /*  LoadLs30utFuncs Register all functions in LS30UT.DLL             */
  25. /*                                                                   */
  26. /* Additional functions                                              */
  27. /*  NetEnum       Enumerate some NET provided information            */
  28. /*  GetLogonAsnAcp Get logon assignment access control profiles      */
  29. /*                                                                   */
  30. /* Author: Ingolf Lindberg, ITSC Austin 1993                         */
  31. /*********************************************************************/
  32. #define INCL_32
  33.  
  34. /* Include files */
  35. #define  INCL_DOS
  36. #define  INCL_DOSFILEMGR
  37. #define  INCL_DOSMEMMGR
  38. #define  INCL_DOSNMPIPES
  39. #define  INCL_SPL
  40. #define  INCL_SPLDOSPRINT
  41. #define  INCL_ERRORS
  42. #define  INCL_REXXSAA
  43. #define  _DLL
  44. #define  _MT
  45. #include <os2.h>
  46. #include <rexxsaa.h>
  47. #include <memory.h>
  48. #include <malloc.h>
  49. #include <fcntl.h>
  50. #include <ctype.h>
  51. #include <string.h>
  52. #include <stdlib.h>
  53. #include <stdio.h>
  54. #include <conio.h>
  55.  
  56. /*********************************************************************/
  57. /* LAN Server specific header files                                  */
  58. /*********************************************************************/
  59. #include <netcons.h>
  60. #include <access.h>
  61. #include <neterr.h>
  62. #include <audit.h>
  63. #include <dcdb.h>
  64. #include <server.h>
  65.  
  66. /*********************************************************************/
  67. /*  Declare exported functions as REXX functions.                    */
  68. /*********************************************************************/
  69. RexxFunctionHandler LoadLs30utFuncs;
  70. RexxFunctionHandler DropLs30utFuncs;
  71. RexxFunctionHandler GetDCName;
  72. RexxFunctionHandler CopyDirAcls;
  73. RexxFunctionHandler DumpAllUsers;
  74. RexxFunctionHandler DumpUser;
  75. RexxFunctionHandler InsertAllUsers;
  76. RexxFunctionHandler MoveDirAlias;
  77. RexxFunctionHandler QueryDirAliasPath;
  78. RexxFunctionHandler SetLogonAsn;
  79. RexxFunctionHandler GetLogonAsn;
  80. RexxFunctionHandler NetEnum;
  81. RexxFunctionHandler GetLogonAsnAcp;
  82.  
  83. /*********************************************************************/
  84. /* Definitions used                                                  */
  85. /*********************************************************************/
  86. #define  NO_UTIL_ERROR    "0"          /* No error occurred          */
  87. #define  INVALID_ROUTINE  40           /* Raise REXX error           */
  88. #define  VALID_ROUTINE     0           /* Successful completion      */
  89. #define  MAX             256           /* Temporary buffer length    */
  90. #define  IBUF_LEN       4096           /* Input buffer length        */
  91.  
  92. #define LEVEL_0   0                    /* Information levels         */
  93. #define LEVEL_1   1
  94. #define LEVEL_2   2
  95. #define LEVEL_3   3
  96.  
  97. #define PUBDOS    1                    /* Public DOS applications    */
  98. #define PUBOS2    2                    /* Public OS/2 applications   */
  99. #define PRIVATE   4                    /* All private applications   */
  100. #define ALLAPPS   7                    /* All application types      */
  101.  
  102. #define AN_APP  100                    /* For an application         */
  103.  
  104. #ifndef NERR_AppNotFound               /* DCDB errors are missing    */
  105. #define NERR_AppNotFound 2793          /* in the header files for    */
  106. #endif                                 /* OS/2 LAN Server 3.0        */
  107. /*********************************************************************/
  108. /* Structures used including typedefs                                */
  109. /*********************************************************************/
  110.  
  111. /*********************************************************************/
  112. /* RxStemData. Structure which describes as generic stem variable    */
  113. /*********************************************************************/
  114.  
  115. typedef struct RxStemData1 {
  116.     SHVBLOCK shvb;                   /* Request block for RxVar      */
  117.     CHAR ibuf[IBUF_LEN];             /* Input buffer                 */
  118.     CHAR varname[MAX];               /* Buffer for the variable name */
  119.     CHAR stemname[MAX];              /* Buffer for the variable name */
  120.     ULONG stemlen;                   /* Length of stem               */
  121.     ULONG vlen;                      /* Length of variable value     */
  122.     ULONG count;                     /* Number of elements processed */
  123. } RXSTEMDATA1;
  124.  
  125. /*********************************************************************/
  126. /* Some useful macros                                                */
  127. /*********************************************************************/
  128.  
  129. #define BUILDRXSTRING(t, s) { \
  130.   strcpy((t)->strptr,(s));\
  131.   (t)->strlength = strlen((s)); \
  132. }
  133.  
  134. /* Handle _Seg16 offset calculation */
  135. #define GET16OFFSET(x, y) { \
  136.  x = (CHAR * _Seg16) ((ULONG) x - (ULONG) y); \
  137. }
  138.  
  139. /* Handle _Seg16 address calculation */
  140. #define GET16ADDRS(x, y) { \
  141.  x = (CHAR * _Seg16) ((ULONG) x + (ULONG) y); \
  142. }
  143.  
  144. /*********************************************************************/
  145. /* RxFncTable                                                        */
  146. /*   Array of names of the LS30UT functions. Used for registration   */
  147. /*   deregistration by SysLoadFuncs and SysDropFuncs                 */
  148. /*********************************************************************/
  149.  
  150. static PSZ  RxFncTable[] =             /* Function package list      */
  151. {
  152.        "GetDCName",                    /* Get Domain Controller Name */
  153.        "CopyDirAcls",                  /* Copy Access Controls       */
  154.        "DumpAllUsers",                 /* Dump all user structures   */
  155.        "DumpUser",                     /* Dump one user structure    */
  156.        "InsertAllUsers",               /* Insert users from file     */
  157.        "MoveDirAlias",                 /* Move directory alias       */
  158.        "QueryDirAliasPath",            /* Query alias path definition*/
  159.        "SetLogonAsn",                  /* Set Logon Assignment       */
  160.        "GetLogonAsn",                  /* Get Logon Assignments      */
  161.        "NetEnum",                      /* Enumerate NET information  */
  162.        "GetLogonAsnAcp",               /* Check assignment access    */
  163.        "DropLs30utFuncs",              /* Package drop function      */
  164.        "LoadLs30utFuncs"               /* Package load function      */
  165. };
  166.  
  167. /*********************************************************************/
  168. /* Function definitions                                              */
  169. /*********************************************************************/
  170. ULONG insertStem(RXSTEMDATA1 * rxs, UCHAR * pszString);
  171. ULONG lastInStem(RXSTEMDATA1 * rxs);
  172. ULONG getSplEnumDevice(PULONG, PSZ, RXSTEMDATA1 *, ULONG);
  173. ULONG getServerEnum2(PULONG, PSZ, RXSTEMDATA1 *, ULONG);
  174. ULONG getAppEnum(PULONG, PSZ, RXSTEMDATA1 *, ULONG);
  175. ULONG getAppEnumAcp(PULONG, PSZ, PSZ, RXSTEMDATA1 *);
  176. ULONG getLasnAliasAcp(PULONG, PSZ, PSZ, RXSTEMDATA1 *);
  177. VOID  setAcp(PSZ pszAcpBuf, USHORT usPermission);
  178. ULONG getAliasAcp(PSZ, PSZ, PSZ, RXSTEMDATA1 *, struct alias_info_2 *, PSZ, ULONG);
  179.  
  180. /*********************************************************************/
  181. /* Functions provided                                                */
  182. /*********************************************************************/
  183.  
  184. /*********************************************************************/
  185. /* Function:  LoadLs30utFuncs                                        */
  186. /*                                                                   */
  187. /* Syntax:    call SysLoadFuncs()                                    */
  188. /* Params:    none                                                   */
  189. /* Return:    null string                                            */
  190. /*********************************************************************/
  191. ULONG LoadLs30utFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
  192.                            CHAR *queuename, RXSTRING *retstr)
  193. {
  194.  INT    entries, j;                    /* # entries, counter         */
  195.  
  196.  if (numargs > 0)                      /* Check arguments            */
  197.   return INVALID_ROUTINE;
  198.  
  199.  retstr->strlength = 0;                /* Set return value           */
  200.  
  201.  entries = sizeof(RxFncTable)/sizeof(PSZ);
  202.  for (j = 0; j < entries; j++)
  203.   RexxRegisterFunctionDll(RxFncTable[j], "LS30UT", RxFncTable[j]);
  204.  
  205.  return VALID_ROUTINE;
  206.  
  207. }
  208.  
  209. /*********************************************************************/
  210. /* Function:  DropLs30utFuncs                                        */
  211. /*                                                                   */
  212. /* Syntax:    call SysDropFuncs()                                    */
  213. /* Return:    NO_UTIL_ERROR - Successful.                            */
  214. /*********************************************************************/
  215. ULONG DropLs30utFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
  216.                           CHAR *queuename, RXSTRING *retstr)
  217. {
  218.  INT     entries, j;                   /* # entries, counter         */
  219.  
  220.  if (numargs > 0)                      /* No arguments for this call */
  221.   return INVALID_ROUTINE;              /* Raise an error             */
  222.  
  223.  retstr->strlength = 0;                /* Return a null string result*/
  224.  
  225.  entries = sizeof(RxFncTable)/sizeof(PSZ);
  226.  for (j = 0; j < entries; j++)
  227.   RexxDeregisterFunction(RxFncTable[j]);
  228.  
  229.  return VALID_ROUTINE;                 /* No error on call           */
  230. }
  231.  
  232. /*********************************************************************/
  233. /* Function:  GetDCName                                              */
  234. /*                                                                   */
  235. /* Syntax:    call GetDCName()                                       */
  236. /* Params:    none                                                   */
  237. /* Return:    Combined RC and Domain Controller name if RC='0'       */
  238. /*********************************************************************/
  239. ULONG GetDCName(CHAR *name, ULONG numargs, RXSTRING args[],
  240.                     CHAR *queuename, RXSTRING *retstr)
  241. {
  242.  struct server_info_0 *srv_info_buf;
  243.  USHORT usEntriesread, usTotalentries;
  244.  USHORT usRc;
  245.  
  246.  if (numargs > 0)                      /* Is argument specified      */
  247.   return INVALID_ROUTINE;              /* Raise the error            */
  248.  
  249.  srv_info_buf = malloc ( sizeof(struct server_info_0) );
  250.  if(usRc=NetServerEnum2("",                     /* Server = local    */
  251.                         LEVEL_0,                /* level_0           */
  252.                         (char *)srv_info_buf,   /* server_info_0     */
  253.                         sizeof(struct server_info_0),
  254.                         &usEntriesread,         /* entries returned  */
  255.                         &usTotalentries,        /* total entries     */
  256.                         (long)SV_TYPE_DOMAIN_CTRL,/*domain controller*/
  257.                         "" ) )
  258.  {
  259.   sprintf(retstr->strptr, "%d", usRc);
  260.   retstr->strlength = strlen(retstr->strptr);
  261.   free(srv_info_buf);                  /* Drain used storage         */
  262.   return VALID_ROUTINE;                /* no error on call           */
  263.  }
  264.  
  265.  sprintf(retstr->strptr, "%d \\\\%s", usRc, srv_info_buf->sv0_name);
  266.  retstr->strlength = strlen(retstr->strptr);
  267.  free(srv_info_buf);
  268.  
  269.  return VALID_ROUTINE;                 /* No error on call           */
  270.  
  271. }
  272.  
  273. /*********************************************************************/
  274. /* Function:  CopyDirAcls                                            */
  275. /*                                                                   */
  276. /* Syntax:    call CopyDirAcls(source, destination)                  */
  277. /* Params:    source directory like C:\APPS                          */
  278. /*            destination directory like D:\APPS                     */
  279. /* Return:    Return code from any failing function. '0' if no error */
  280. /*********************************************************************/
  281. ULONG CopyDirAcls(CHAR *name, ULONG numargs, RXSTRING args[],
  282.                     CHAR *queuename, RXSTRING *retstr)
  283. {
  284.  INT      i;
  285.  USHORT   usBuflen     = 0;           /* Size of buffer area         */
  286.  USHORT   usTotalavail = 0;           /* Total info available        */
  287.  ULONG    ulRc;                       /* Return code                 */
  288.  PEAOP2   EABuf;                      /* Extended attribute buffer   */
  289.  BOOL     fMore;                      /* Loop flag                   */
  290.  char     * tmpPtr;                   /* Directory string pointers   */
  291.  char     * tmpPtrLast;               /*                             */
  292.  SHORT    sParmnum;                   /* All or dedicated ACL        */
  293.  struct access_info_1 *accinfo1Buf;   /* Resource info buffer        */
  294.  
  295.  if ( (numargs != 2) ||         /* Are arguments specified correctly */
  296.       !RXVALIDSTRING(args[0]) ||
  297.       !RXVALIDSTRING(args[1]) )
  298.   return INVALID_ROUTINE;                  /* raise error            */
  299.  
  300.  /* Check the presence of the Source Directory and get work size */
  301.  ulRc=NetAccessGetInfo("",              /* Local resource only */
  302.                        args[0].strptr,  /* The resource name   */
  303.                        LEVEL_1,
  304.                        NULL,
  305.                        usBuflen,
  306.                        &usTotalavail);
  307.  if( (ulRc != 0) && (ulRc != 2123) ) /* Ok or buffer to small */
  308.  {
  309.   sprintf(retstr->strptr, "%d", ulRc);
  310.   retstr->strlength = strlen(retstr->strptr);
  311.   return VALID_ROUTINE;
  312.  }
  313.  
  314.  /* There is information available, therefor continue */
  315.  ulRc = 0; /* For test after this line if condition */
  316.  /* Test for 2 chars in args[1] like E: and for 3 chars like E:\ */
  317.  if( args[1].strlength > 3 )
  318.  {
  319.   /* Try to create directory. It is ok to create or if it exists */
  320.   EABuf = 0;                   /* Indicate that no EAs are defined */
  321.   ulRc = DosCreateDir(args[1].strptr, EABuf);/*This will create any  */
  322.                                              /* first level directory*/
  323.   if( (ulRc != 0) && (ulRc != 5 ) ) /* Directory already exists */
  324.   {
  325.    /* Create sub directories */
  326.    tmpPtr = args[1].strptr + 3;  /* X:\  FIRST\SECOND */
  327.    tmpPtrLast = args[1].strptr + (strlen(args[1].strptr) - 1);
  328.    i = 3;
  329.    fMore = TRUE;
  330.    while (fMore == TRUE)
  331.    {
  332.     while ( *tmpPtr != '\\' && tmpPtr < tmpPtrLast )
  333.     {
  334.      tmpPtr++;
  335.      i++;
  336.     }
  337.     /* The Last done? */
  338.     if ( tmpPtr == tmpPtrLast)
  339.     {
  340.      ulRc = DosCreateDir(args[1].strptr, EABuf);/* Create directory*/
  341.      fMore = FALSE;
  342.     }
  343.     else
  344.     {
  345.      if ( *tmpPtr == '\\')
  346.      {
  347.       args[1].strptr[i] = '\0';
  348.       ulRc = DosCreateDir(args[1].strptr, EABuf);/* Create directory */
  349.       args[1].strptr[i] = '\\';
  350.       tmpPtr++;
  351.       i++;
  352.      } /* end if */
  353.     } /* end else */
  354.    } /* end while */
  355.   } /* end if */
  356.  
  357.   if( (ulRc != 0) && (ulRc != 5) ) /* Could not create directories */
  358.   {
  359.    sprintf(retstr->strptr, "%d", ulRc);
  360.    retstr->strlength = strlen(retstr->strptr);
  361.    return VALID_ROUTINE;
  362.   }
  363.  
  364.  } /* end if */
  365.  
  366.  /* Assume destination directory exist now, add Access Control Profiles */
  367.  usBuflen = usTotalavail;
  368.  accinfo1Buf = malloc(usBuflen);
  369.  ulRc=NetAccessGetInfo("",
  370.                        args[0].strptr,  /* The resource name   */
  371.                        LEVEL_1,
  372.                        (PCHAR) accinfo1Buf,
  373.                        usBuflen,
  374.                        &usTotalavail);
  375.  if( ulRc != 0 ) /* Return on any error now */
  376.  {
  377.   sprintf(retstr->strptr, "%d", ulRc);
  378.   free(accinfo1Buf);
  379.   retstr->strlength = strlen(retstr->strptr);
  380.   return VALID_ROUTINE;
  381.  }
  382.  
  383.  /* Set resource pointer in accinfo1Buf structure */
  384.  accinfo1Buf->acc1_resource_name = args[1].strptr;
  385.  
  386.  /* Set all information at once */
  387.  sParmnum = 0;
  388.  ulRc=NetAccessSetInfo("",
  389.                        args[1].strptr,  /* The destination resource name   */
  390.                        LEVEL_1,
  391.                        (PCHAR) accinfo1Buf,
  392.                        usBuflen,
  393.                        sParmnum);
  394.  
  395.  if(ulRc == 2222) /* No access profile exist */
  396.  {
  397.   ulRc=NetAccessAdd("",                  /* server name */
  398.                     LEVEL_1,             /* level of detail */
  399.                     (PCHAR) accinfo1Buf, /* ptr to access_info */
  400.                     usBuflen);           /* size of data structure */
  401.   }
  402.  
  403.  free(accinfo1Buf);
  404.  sprintf(retstr->strptr, "%d", ulRc);
  405.  retstr->strlength = strlen(retstr->strptr);
  406.  
  407.  return VALID_ROUTINE;                /* No error on call           */
  408.  
  409. }
  410.  
  411. /*********************************************************************/
  412. /* Function:  DumpAllUsers                                           */
  413. /*                                                                   */
  414. /* Syntax:    call DumAllUsers(server, file_name)                    */
  415. /* Params:    server from where users are uptained                   */
  416. /*            dump file name                                         */
  417. /* Return:    Return code from any failing function. '0' if no error */
  418. /*********************************************************************/
  419. ULONG DumpAllUsers(CHAR *name, ULONG numargs, RXSTRING args[],
  420.                     CHAR *queuename, RXSTRING *retstr)
  421. {
  422.  
  423.  FILE *stream;
  424.  struct user_info_0 * pUserInfo0;   /* User information, level 0 */
  425.  struct user_info_0 * pUserInfo0Org;/* User information, level 0 */
  426.  struct user_info_2 * pUserInfo2;   /* User information, level 2 */
  427.  USHORT usUserList, usBuflen;       /* Memory structure sizes    */
  428.  USHORT uswrite, usRc;
  429.  USHORT usEntriesRead, usTotalAvail; /* Number of entries read and */
  430.                                      /* the total number */
  431.  BOOL   fLoop;
  432.  INT    i;
  433.  CHAR * _Seg16 sz16Pointer;
  434.  CHAR * _Seg16 sz16MakeThunk;
  435.  ULONG  ulVal;
  436.  
  437.  if ( (numargs != 2) ||         /* Are arguments specified correctly */
  438.      !RXVALIDSTRING(args[0]) ||
  439.      !RXVALIDSTRING(args[1]) )
  440.   return INVALID_ROUTINE;     /* raise error            */
  441.  
  442.  /* Validate that file can be opened in binary+write mode */
  443.  if ( (stream = fopen(args[1].strptr, "wb+")) == NULL)
  444.  {
  445.   sprintf(retstr->strptr, "Could not open file");
  446.   retstr->strlength = strlen(retstr->strptr);
  447.   return VALID_ROUTINE;
  448.  }
  449.  
  450.  /* Prepare user information for dump action */
  451.  usUserList = 3119 * sizeof(struct user_info_0); /* Get up to seg size */
  452.  
  453.  usBuflen = sizeof(struct user_info_2) + 3 * (MAXCOMMENTSZ+1) +
  454.             2 * PATHLEN + (CNLEN+1) + MAXWORKSTATIONS * (CNLEN+1) + (21);
  455.  pUserInfo0 = malloc(usUserList);
  456.  pUserInfo2 = malloc(usBuflen);      /* For 1 user only information */
  457.  pUserInfo0Org = pUserInfo0;         /* Save origin */
  458.  
  459.  memcpy(pUserInfo2, "USERLIST\0", 9);
  460.  uswrite = fwrite(pUserInfo2, sizeof(char), 9, stream);
  461.  /* Validate that file can be opened in binary+write mode */
  462.  if ( uswrite != 9)
  463.  {
  464.   sprintf(retstr->strptr, "Could not write to file");
  465.   retstr->strlength = strlen(retstr->strptr);
  466.   free(pUserInfo0);      /* Free storage allocated */
  467.   free(pUserInfo2);
  468.   fclose(stream);
  469.   return VALID_ROUTINE;
  470.  }
  471.  
  472.  /* Enumerate users */
  473.  fLoop = TRUE;
  474.  while(fLoop == TRUE)
  475.  {
  476.   usRc = NetUserEnum(args[0].strptr,      /* The server name */
  477.                      LEVEL_0,             /* Get just the names */
  478.                      (char *) pUserInfo0, /* Place in buffer */
  479.                      usUserList,          /* The buffer size */
  480.                      &usEntriesRead,      /* Number of entries read */
  481.                      &usTotalAvail);      /* Number of entries available */
  482.  
  483.   if( (usRc != 0) && (usRc != ERROR_MORE_DATA) )
  484.   {
  485.    sprintf(retstr->strptr, "Could not enumerate users. RC = %d", usRc);
  486.    retstr->strlength = strlen(retstr->strptr);
  487.    free(pUserInfo0);
  488.    free(pUserInfo2);
  489.    fclose(stream);
  490.    return VALID_ROUTINE;
  491.   }
  492.  
  493.   /* could not get ERROR_MORE_DATA to work */
  494.   if( (usRc == 0) || (usRc == ERROR_MORE_DATA) )
  495.    fLoop = FALSE;
  496.  
  497.   for (i = 0; i < usEntriesRead; i++)
  498.   {
  499.    usRc = NetUserGetInfo(args[0].strptr,        /* server name */
  500.                          pUserInfo0->usri0_name,/* user  name  */
  501.                          LEVEL_2,               /* level of detail */
  502.                          (char *) pUserInfo2,   /* ptr to user_info_2
  503.                                                 /* data structure */
  504.                          usBuflen,              /* size of structure */
  505.                          &usTotalAvail);        /* number of bytes of */
  506.                                                 /* information available */
  507.    if(usRc != 0)
  508.    {
  509.     sprintf(retstr->strptr, "Could not get user information. RC = %d", usRc);
  510.     retstr->strlength = strlen(retstr->strptr);
  511.     free(pUserInfo0);
  512.     free(pUserInfo2);
  513.     fclose(stream);
  514.     return VALID_ROUTINE;
  515.    }
  516.  
  517.    /* The pointers in user_info_2 structure must be aligned to offsets */
  518.    /* They contain full address(16:16). Make it an offset and Thunk it!*/
  519.    sz16Pointer = (CHAR *) pUserInfo2;
  520.    /* Make offsets(16:16) within user_info_2 structure */
  521.    GET16OFFSET(pUserInfo2->usri2_home_dir,sz16Pointer);
  522.    GET16OFFSET(pUserInfo2->usri2_comment,sz16Pointer);
  523.    GET16OFFSET(pUserInfo2->usri2_script_path,sz16Pointer);
  524.    GET16OFFSET(pUserInfo2->usri2_full_name,sz16Pointer);
  525.    GET16OFFSET(pUserInfo2->usri2_usr_comment,sz16Pointer);
  526.    GET16OFFSET(pUserInfo2->usri2_parms,sz16Pointer);
  527.    GET16OFFSET(pUserInfo2->usri2_workstations,sz16Pointer);
  528.    GET16OFFSET(pUserInfo2->usri2_logon_hours,sz16Pointer);
  529.    GET16OFFSET(pUserInfo2->usri2_logon_server,sz16Pointer);
  530.  
  531.    uswrite = fwrite(pUserInfo2, sizeof(char), usBuflen, stream);
  532.    /* Validate that file can be opened in binary+write mode */
  533.    if ( uswrite != usBuflen)
  534.    {
  535.     sprintf(retstr->strptr, "Could not write user data to file");
  536.     retstr->strlength = strlen(retstr->strptr);
  537.     free(pUserInfo0);
  538.     free(pUserInfo2);
  539.     fclose(stream);
  540.     return VALID_ROUTINE;
  541.    }
  542.  
  543.    pUserInfo0++;
  544.  
  545.   } /* end for */
  546.  
  547.   pUserInfo0 = pUserInfo0Org; /* Retore old condition */
  548.  
  549.  } /* end while(fLoop == TRUE) */
  550.  
  551.  /* Every thing is done now, cleanup */
  552.  free(pUserInfo0);
  553.  free(pUserInfo2);
  554.  fclose(stream);
  555.  sprintf(retstr->strptr, "0");
  556.  retstr->strlength = strlen(retstr->strptr);
  557.  
  558.  return VALID_ROUTINE;                /* no error on call           */
  559.  
  560. }
  561.  
  562. /*********************************************************************/
  563. /* Function:  DumpUser                                               */
  564. /*                                                                   */
  565. /* Syntax:    call DumUser(server, filename, userid)                 */
  566. /* Params:    server from where users are obtained                   */
  567. /*            dump file name                                         */
  568. /*            userid to dump information about                       */
  569. /* Return:    Return code from any failing function. '0' if no error */
  570. /*********************************************************************/
  571. ULONG DumpUser(CHAR *name, ULONG numargs, RXSTRING args[],
  572.                     CHAR *queuename, RXSTRING *retstr)
  573. {
  574.  FILE *stream;
  575.  struct user_info_2 * pUserInfo2;   /* User information, level 2 */
  576.  USHORT usBuflen;                   /* Memory structure sizes    */
  577.  USHORT usread, uswrite, usRc, usTotalAvail;
  578.  ULONG  ulRc;
  579.  CHAR * _Seg16 sz16Pointer;
  580.  
  581.  if ( (numargs != 3) ||         /* Are arguments specified correctly */
  582.       !RXVALIDSTRING(args[0]) ||
  583.       !RXVALIDSTRING(args[1]) ||
  584.       !RXVALIDSTRING(args[2]) )
  585.   return INVALID_ROUTINE;     /* raise error            */
  586.  
  587.  /* Make preparations */
  588.  usBuflen = sizeof(struct user_info_2) + 3 * (MAXCOMMENTSZ+1) +
  589.             2 * PATHLEN + (CNLEN+1) + MAXWORKSTATIONS * (CNLEN+1) + (21);
  590.  pUserInfo2 = malloc(usBuflen);      /* For 1 user only information */
  591.  
  592.  /* Validate that user dump file can be opened in binary read/write mode */
  593.  if ( (stream = fopen(args[1].strptr, "rb+")) == NULL)
  594.  {
  595.   /* Create the file */
  596.   if ( (stream = fopen(args[1].strptr, "wb+")) == NULL)
  597.   {
  598.    sprintf(retstr->strptr, "Could not open file");
  599.    retstr->strlength = strlen(retstr->strptr);
  600.    free(pUserInfo2);
  601.    return VALID_ROUTINE;
  602.   }
  603.   else
  604.   {
  605.    /* Set the file values and check against "USERLIST\0" */
  606.    memcpy(pUserInfo2, "USERLIST\0", 9);
  607.    uswrite = fwrite(pUserInfo2, sizeof(char), 9, stream);
  608.    if ( uswrite != 9)
  609.    {
  610.     sprintf(retstr->strptr, "Could not write to file");
  611.     retstr->strlength = strlen(retstr->strptr);
  612.     free(pUserInfo2);
  613.     fclose(stream);
  614.     return VALID_ROUTINE;
  615.    }
  616.   }
  617.  }
  618.  
  619.  ulRc = fseek(stream, 0L, SEEK_SET);  /* Set a beginning of file */
  620.  if ( ulRc != 0)
  621.  {
  622.   sprintf(retstr->strptr, "Could not move seek pointer in user dump file");
  623.   retstr->strlength = strlen(retstr->strptr);
  624.   fclose(stream);
  625.   free(pUserInfo2);
  626.   return VALID_ROUTINE;
  627.  }
  628.  
  629.  /* Read header */
  630.  usread = fread( pUserInfo2, sizeof( char ), 9, stream );
  631.  
  632.  ulRc = memcmp(pUserInfo2, "USERLIST\0", 9);
  633.  if(ulRc != 0)
  634.  {
  635.   sprintf(retstr->strptr, "Wrong user dump file type");
  636.   retstr->strlength = strlen(retstr->strptr);
  637.   fclose(stream);
  638.   free(pUserInfo2);
  639.   return VALID_ROUTINE;
  640.  }
  641.  
  642.  /* Set seek pointer to end of file and append information */
  643.  ulRc = fseek(stream, 0L, SEEK_END);  /* Set a beginning of file */
  644.  if ( ulRc != 0)
  645.  {
  646.   sprintf(retstr->strptr, "Could not move seek pointer in user dump file");
  647.   retstr->strlength = strlen(retstr->strptr);
  648.   fclose(stream);
  649.   free(pUserInfo2);
  650.   return VALID_ROUTINE;
  651.  }
  652.  
  653.  /* Get user information */
  654.  usRc = NetUserGetInfo(args[0].strptr,        /* Server name */
  655.                          args[2].strptr,      /* User name   */
  656.                          LEVEL_2,             /* Level of detail */
  657.                          (char *) pUserInfo2, /* ptr to user_info_2 */
  658.                                               /* data structure */
  659.                          usBuflen,            /* Size of data structure */
  660.                          &usTotalAvail);      /* Number of bytes of
  661.                                               /* information available */
  662.  if(usRc != 0)
  663.  {
  664.   sprintf(retstr->strptr, "Could not get user information. RC = %d", usRc);
  665.   retstr->strlength = strlen(retstr->strptr);
  666.   free(pUserInfo2);
  667.   fclose(stream);
  668.   return VALID_ROUTINE;
  669.  }
  670.  
  671.  /* The pointers in user_info_2 structure must be aligned to offsets */
  672.  /* They contain full address(16:16). Why make it easy! */
  673.  sz16Pointer = (CHAR *) pUserInfo2;
  674.  /* Make offsets(16:16) within user_info_2 structure */
  675.  GET16OFFSET(pUserInfo2->usri2_home_dir,sz16Pointer);
  676.  GET16OFFSET(pUserInfo2->usri2_comment,sz16Pointer);
  677.  GET16OFFSET(pUserInfo2->usri2_script_path,sz16Pointer);
  678.  GET16OFFSET(pUserInfo2->usri2_full_name,sz16Pointer);
  679.  GET16OFFSET(pUserInfo2->usri2_usr_comment,sz16Pointer);
  680.  GET16OFFSET(pUserInfo2->usri2_parms,sz16Pointer);
  681.  GET16OFFSET(pUserInfo2->usri2_workstations,sz16Pointer);
  682.  GET16OFFSET(pUserInfo2->usri2_logon_hours,sz16Pointer);
  683.  GET16OFFSET(pUserInfo2->usri2_logon_server,sz16Pointer);
  684.  
  685.  uswrite = fwrite(pUserInfo2, sizeof(char), usBuflen, stream);
  686.  /* Validate that file write was ok */
  687.  if ( uswrite != usBuflen)
  688.  {
  689.   sprintf(retstr->strptr, "Could not write user data to file");
  690.   retstr->strlength = strlen(retstr->strptr);
  691.   free(pUserInfo2);
  692.   fclose(stream);
  693.   return VALID_ROUTINE;
  694.  }
  695.  
  696.  /* Every thing is done now, cleanup */
  697.  free(pUserInfo2);
  698.  fclose(stream);
  699.  sprintf(retstr->strptr, "0");
  700.  retstr->strlength = strlen(retstr->strptr);
  701.  
  702.  return VALID_ROUTINE;                /* No error on call           */
  703.  
  704. }
  705.  
  706. /*********************************************************************/
  707. /* Function:  InsertAllUsers                                         */
  708. /*                                                                   */
  709. /* Syntax:    call InsertAllUsers(server, filename, logfile, newpw)  */
  710. /* Params:    server from where users are obtained                   */
  711. /*            user dump file name                                    */
  712. /*            logfile name                                           */
  713. /*            newpw is the new password that must be supplied        */
  714. /*                                                                   */
  715. /*            If user exist nothing will be added                    */
  716. /*                                                                   */
  717. /* Return:    Return code from any failing function. '0' if no error */
  718. /*********************************************************************/
  719. ULONG InsertAllUsers(CHAR *name, ULONG numargs, RXSTRING args[],
  720.                     CHAR *queuename, RXSTRING *retstr)
  721. {
  722.  FILE *stream;
  723.  FILE *logstream;
  724.  struct user_info_2 * pUserInfo2;   /* User information, level 2 */
  725.  USHORT usBuflen;                   /* Memory structure sizes    */
  726.  USHORT usread, usRc;
  727.  ULONG  ulRc;
  728.  BOOL   fLoop;
  729.  CHAR * _Seg16 sz16Pointer;
  730.  CHAR   szBuf[80];
  731.  
  732.  if ( (numargs != 4) ||         /* Are arguments specified correctly */
  733.      !RXVALIDSTRING(args[0]) ||
  734.      !RXVALIDSTRING(args[1]) ||
  735.      !RXVALIDSTRING(args[2]) ||
  736.      !RXVALIDSTRING(args[3]) )
  737.   return INVALID_ROUTINE;     /* raise error            */
  738.  
  739.  /* Validate that user dump file can be opened in binary+read mode */
  740.  if ( (stream = fopen(args[1].strptr, "rb")) == NULL)
  741.  {
  742.   sprintf(retstr->strptr, "Could not open user file");
  743.   retstr->strlength = strlen(retstr->strptr);
  744.   return VALID_ROUTINE;
  745.  }
  746.  
  747.  /* Validate that log file can be opened in text mode */
  748.  if ( (logstream = fopen(args[2].strptr, "a")) == NULL)
  749.  {
  750.   sprintf(retstr->strptr, "Could not open log file");
  751.   retstr->strlength = strlen(retstr->strptr);
  752.   fclose(stream);
  753.   return VALID_ROUTINE;
  754.  }
  755.  
  756.  usBuflen = sizeof(struct user_info_2) + 3 * (MAXCOMMENTSZ+1) +
  757.             2 * PATHLEN + (CNLEN+1) + MAXWORKSTATIONS * (CNLEN+1) + (21);
  758.  pUserInfo2 = malloc(usBuflen);      /* For 1 user only information */
  759.  
  760.  /* Read header and test it */
  761.  usread = fread( pUserInfo2, sizeof( char ), 9, stream );
  762.  ulRc = memcmp(pUserInfo2, "USERLIST\0", 9);
  763.  if(ulRc != 0)
  764.  {
  765.   sprintf(retstr->strptr, "Wrong user dump file type");
  766.   retstr->strlength = strlen(retstr->strptr);
  767.   fclose(stream);
  768.   fclose(logstream);
  769.   free(pUserInfo2);
  770.   return VALID_ROUTINE;
  771.  }
  772.  
  773.  /* Ready to process user dump file content */
  774.  /* Set correct addresses */
  775.  sz16Pointer = (CHAR *) pUserInfo2; /* To get correct 16:16 address */
  776.  fLoop = TRUE;
  777.  while(fLoop == TRUE)
  778.  {
  779.   usread = fread( pUserInfo2, sizeof( char ), usBuflen, stream );
  780.   if(usread == usBuflen)
  781.   {
  782.    /* Make address(16:16) within user_info_2 structure */
  783.    GET16ADDRS(pUserInfo2->usri2_home_dir,sz16Pointer);
  784.    GET16ADDRS(pUserInfo2->usri2_comment,sz16Pointer);
  785.    GET16ADDRS(pUserInfo2->usri2_script_path,sz16Pointer);
  786.    GET16ADDRS(pUserInfo2->usri2_full_name,sz16Pointer);
  787.    GET16ADDRS(pUserInfo2->usri2_usr_comment,sz16Pointer);
  788.    GET16ADDRS(pUserInfo2->usri2_parms,sz16Pointer);
  789.    GET16ADDRS(pUserInfo2->usri2_workstations,sz16Pointer);
  790.    GET16ADDRS(pUserInfo2->usri2_logon_hours,sz16Pointer);
  791.    GET16ADDRS(pUserInfo2->usri2_logon_server,sz16Pointer);
  792.  
  793.    /* Set new password */
  794.    strcpy(pUserInfo2->usri2_password, args[3].strptr);
  795.    /* Add the user to the server specified. This must be a DC */
  796.    usRc = NetUserAdd(args[0].strptr,         /* Servername */
  797.                      LEVEL_2,                /* Info level 2 */
  798.                      (PCHAR) pUserInfo2,     /* User info buffer */
  799.                      usBuflen);              /* User infor buf size */
  800.    if(usRc != 0)
  801.    {
  802.     if(usRc == NERR_UserExists)
  803.     {
  804.      sprintf( szBuf, "User %s already exists. No modification performed.\n", \
  805.               pUserInfo2->usri2_name);
  806.      fwrite( szBuf, sizeof(char), strlen(szBuf), logstream);
  807.     }
  808.     else
  809.     {
  810.      sprintf( szBuf, "Error adding user %s. rc = %d\n", \
  811.               pUserInfo2->usri2_name, usRc);
  812.      fwrite( szBuf, sizeof(char), strlen(szBuf), logstream);
  813.     }
  814.    }
  815.   }
  816.   else
  817.   {
  818.    /* Determine error and break loop */
  819.    if ( ferror(stream) )
  820.    {
  821.     sprintf( szBuf,"Error reading user file\n");
  822.     fwrite( szBuf, sizeof(char), strlen(szBuf), logstream);
  823.    }
  824.    else
  825.    {
  826.     if ( feof(stream) )
  827.     {
  828.      sprintf( szBuf,"End of user dump file reached\n");
  829.      fwrite( szBuf, sizeof(char), strlen(szBuf), logstream);
  830.     }
  831.    }
  832.    fLoop = FALSE; /* Done */
  833.  
  834.   } /* end if(usread == usBuflen) */
  835.  } /* end while */
  836.  
  837.  fclose(stream);
  838.  fclose(logstream);
  839.  free(pUserInfo2);
  840.  sprintf(retstr->strptr, "0");
  841.  retstr->strlength = strlen(retstr->strptr);
  842.  return VALID_ROUTINE;     /* done */
  843.  
  844. }
  845.  
  846. /*********************************************************************/
  847. /* Function:  MoveDirAlias                                           */
  848. /*                                                                   */
  849. /* Syntax:    call MoveDirAlias(dcName, alias, newserver, newpath)   */
  850. /* Params:    dcName The domain controller name                      */
  851. /*            alias  The alias name of the alias to be moved         */
  852. /*            newserver The new server name                          */
  853. /*            newpath   The new d:\path specification                */
  854. /*                                                                   */
  855. /* Return:    Return code from any failing function. '0' if no error */
  856. /*********************************************************************/
  857. ULONG MoveDirAlias(CHAR *name, ULONG numargs, RXSTRING args[],
  858.                     CHAR *queuename, RXSTRING *retstr)
  859. {
  860.  struct alias_info_2 * pAliasInfo2; /* Alias information, level 2 */
  861.  USHORT usBuflen;                   /* Memory structure sizes    */
  862.  USHORT usBytesAvail;
  863.  USHORT usRc;
  864.  CHAR   szOrgCompName[CNLEN + 1];   /* Origional computer name */
  865.  CHAR   * pszOrgPath;               /* Original path location */
  866.  
  867.  if ( (numargs != 4) ||         /* Are arguments specified correctly */
  868.      !RXVALIDSTRING(args[0]) ||
  869.      !RXVALIDSTRING(args[1]) ||
  870.      !RXVALIDSTRING(args[2]) ||
  871.      !RXVALIDSTRING(args[3]) )
  872.   return INVALID_ROUTINE;     /* raise error            */
  873.  
  874.  /* Prepare buffer structure */
  875.  usBuflen = sizeof(struct alias_info_2) + (MAXCOMMENTSZ + 1) +  \
  876.             PATHLEN + 18 * (DEVLEN + 1);
  877.  pAliasInfo2 = malloc(usBuflen);      /* For 1 alias only information */
  878.  if (usRc = NetAliasGetInfo( args[0].strptr, /* DC name */
  879.                              args[1].strptr, /* Alias Name */
  880.                              LEVEL_2,
  881.                              (char *) pAliasInfo2,
  882.                              usBuflen,
  883.                              &usBytesAvail) )
  884.  {
  885.   /* Got an error */
  886.   sprintf(retstr->strptr, "99 Could not obtain Alias information. rc = %d", usRc);
  887.   free(pAliasInfo2);
  888.   retstr->strlength = strlen(retstr->strptr);
  889.   return VALID_ROUTINE;     /* done */
  890.  }
  891.  
  892.  if(pAliasInfo2->ai2_type != ALIAS_TYPE_FILE)
  893.  {
  894.   sprintf(retstr->strptr, "99 Not a directory alias type.");
  895.   free(pAliasInfo2);
  896.   retstr->strlength = strlen(retstr->strptr);
  897.   return VALID_ROUTINE;     /* done */
  898.  }
  899.  
  900.  usBytesAvail = 0;
  901.  /* Remove alias definition */
  902.  if (usRc = NetAliasDel( args[0].strptr, /* DC name */
  903.                          args[1].strptr, /* Alias Name */
  904.                          usBytesAvail) )
  905.  {
  906.   /* Got an error. In big trouble now. Was it deleted?? or what?? */
  907.   /* Try to add the origional again */
  908.   usRc = NetAliasAdd ( args[0].strptr,
  909.                        LEVEL_2,
  910.                        (char *) pAliasInfo2,
  911.                        usBuflen);
  912.   sprintf(retstr->strptr, "99 Alias delete failed. Recreate returned rc = %d", usRc);
  913.   retstr->strlength = strlen(retstr->strptr);
  914.   free(pAliasInfo2);
  915.   return VALID_ROUTINE;     /* done */
  916.  }
  917.  else
  918.  { /* NetAliasDel() was ok, now create it again in new location. Make a copy */
  919.   strcpy(szOrgCompName, pAliasInfo2->ai2_server);
  920.   pszOrgPath = pAliasInfo2->ai2_path;
  921.   /* Set new values */
  922.   strcpy(pAliasInfo2->ai2_server, args[2].strptr);
  923.   pAliasInfo2->ai2_path = args[3].strptr;
  924.   if( usRc = NetAliasAdd ( args[0].strptr,  /* The same DC */
  925.                            LEVEL_2,
  926.                            (char *) pAliasInfo2,
  927.                            usBuflen) )
  928.   {
  929.    /* Recreate origional if possible */
  930.    strcpy(pAliasInfo2->ai2_server, szOrgCompName);
  931.    pAliasInfo2->ai2_path = pszOrgPath;
  932.    NetAliasAdd ( args[0].strptr,
  933.                  LEVEL_2,
  934.                  (char *) pAliasInfo2,
  935.                  usBuflen);
  936.    sprintf(retstr->strptr, "99 Alias move failed");
  937.    free(pAliasInfo2);
  938.    retstr->strlength = strlen(retstr->strptr);
  939.    return VALID_ROUTINE;     /* done */
  940.   }
  941.  }
  942.  
  943.  free(pAliasInfo2);
  944.  sprintf(retstr->strptr, "0");
  945.  retstr->strlength = strlen(retstr->strptr);
  946.  
  947.  return VALID_ROUTINE;     /* done */
  948.  
  949. }
  950.  
  951. /*********************************************************************/
  952. /* Function:  QueryDirAliasPath                                      */
  953. /*                                                                   */
  954. /* Syntax:    call QueryDirAliasPath(dcName, alias)                  */
  955. /* Params:    dcName The domain controller name                      */
  956. /*            alias  The alias name of the alias to be moved         */
  957. /*                                                                   */
  958. /* Return:    Return code from any failing function. '0' if no error */
  959. /*            Need to do                                             */
  960. /*            parse value QueryDirAliasPath() with rc path           */
  961. /*********************************************************************/
  962. ULONG QueryDirAliasPath(CHAR *name, ULONG numargs, RXSTRING args[],
  963.                     CHAR *queuename, RXSTRING *retstr)
  964. {
  965.  struct alias_info_2 * pAliasInfo2; /* Alias information, level 2 */
  966.  USHORT usBuflen;                   /* Memory structure sizes    */
  967.  USHORT usBytesAvail;
  968.  USHORT usRc;
  969.  
  970.  if ( (numargs != 2) ||         /* Are arguments specified correctly */
  971.      !RXVALIDSTRING(args[0]) ||
  972.      !RXVALIDSTRING(args[1]) )
  973.   return INVALID_ROUTINE;     /* raise error            */
  974.  
  975.  usBuflen = sizeof(struct alias_info_2) + (MAXCOMMENTSZ + 1) +  \
  976.             PATHLEN + (18 * (DEVLEN + 1));
  977.  pAliasInfo2 = malloc(usBuflen);      /* For 1 user only information */
  978.  if (usRc = NetAliasGetInfo( args[0].strptr, /* DC name */
  979.                              args[1].strptr, /* Alias Name */
  980.                              LEVEL_2,
  981.                              (char *) pAliasInfo2,
  982.                              usBuflen,
  983.                              &usBytesAvail) )
  984.  {
  985.   /* Got an error */
  986.   sprintf(retstr->strptr, "99 Could not obtain Alias information. rc = %d", usRc);
  987.   retstr->strlength = strlen(retstr->strptr);
  988.   free(pAliasInfo2);
  989.   return VALID_ROUTINE;     /* done */
  990.  }
  991.  
  992.  if(pAliasInfo2->ai2_type != ALIAS_TYPE_FILE)
  993.  {
  994.   sprintf(retstr->strptr, "99 Not a directory alias type.");
  995.   retstr->strlength = strlen(retstr->strptr);
  996.   free(pAliasInfo2);
  997.   return VALID_ROUTINE;     /* done */
  998.  }
  999.  strcpy(retstr->strptr, "0 ");
  1000.  strcat(retstr->strptr,pAliasInfo2->ai2_path);
  1001.  
  1002.  retstr->strlength = strlen(retstr->strptr);
  1003.  free(pAliasInfo2);
  1004.  return VALID_ROUTINE;     /* done */
  1005.  
  1006. }
  1007.  
  1008. /*********************************************************************/
  1009. /* Function:  SetLogonAsn. Set Logon Assignment for a user           */
  1010. /*                                                                   */
  1011. /* Syntax:    call SetLogonAsn(userid, type, device, alias)          */
  1012. /* Params:    userid The userid                                      */
  1013. /*            type   Either a device assignment or application       */
  1014. /*                   Used values are 'D=' for device and 'A=' for    */
  1015. /*                   application assignment                          */
  1016. /*            device The used device. For example G:, LPT6, COM8     */
  1017. /*                   An empty specification is allowed               */
  1018. /*            alias  The alias for the device or application         */
  1019. /*                                                                   */
  1020. /* Return:    Return code from any failing function. '0' if no error */
  1021. /*********************************************************************/
  1022. ULONG SetLogonAsn(CHAR *name, ULONG numargs, RXSTRING args[],
  1023.                     CHAR *queuename, RXSTRING *retstr)
  1024. {
  1025.  struct alias_info_1 * pAliasInfo1; /* Alias information, level 1    */
  1026.  struct server_info_0 *srvInfo0;    /* Server Information 0 Buffer   */
  1027.  struct app_info_3    *pAppInfo3;   /* Appl info pointer             */
  1028.  USHORT usBuflen;                   /* Memory structure sizes        */
  1029.  USHORT usBytesAvail;
  1030.  USHORT usRc;
  1031.  UCHAR  szDcName[UNCLEN+1];         /* The Domain Controller Name    */
  1032.  INT    i;
  1033.  USHORT usEntriesread;
  1034.  USHORT usTotalentries;
  1035.  USHORT usLal_type;
  1036.  
  1037.  struct asn_info {
  1038.    struct logon_asn_info_1 *pLaiBuf;
  1039.    struct logon_asn_list *pLalBuf;
  1040.  } asnPointers;
  1041.  
  1042.  struct sel_info {
  1043.    struct app_sel_info_1 *pAsiBuf;
  1044.    struct app_sel_list *pAslBuf;
  1045.  } selPointers;
  1046.  
  1047.  if ( (numargs != 4) ||         /* Are arguments specified correctly */
  1048.      !RXVALIDSTRING(args[0]) ||
  1049.      !RXVALIDSTRING(args[1]) ||
  1050.      !RXVALIDSTRING(args[3]) )
  1051.   return INVALID_ROUTINE;       /* Raise error            */
  1052.  
  1053.  srvInfo0 = malloc(sizeof(struct server_info_0));
  1054.  if (usRc=NetServerEnum2("",                 /* server = local    */
  1055.                          LEVEL_0,            /* level_0           */
  1056.                          (char *)srvInfo0,   /* server_info_0     */
  1057.                          sizeof(struct server_info_0),
  1058.                          &usEntriesread,     /* entries returned  */
  1059.                          &usTotalentries,    /* total entries     */
  1060.                          (long)SV_TYPE_DOMAIN_CTRL , /* domain controller */
  1061.                          "" ) )
  1062.  {
  1063.   /* Error getting Domain Controller name */
  1064.   free(srvInfo0);
  1065.   sprintf(retstr->strptr, "%d Could not get Domain Controller Name", usRc);
  1066.   retstr->strlength = strlen(retstr->strptr);
  1067.   return VALID_ROUTINE;     /* done */
  1068.  }
  1069.  /* Build correct DC name */
  1070.  strcpy(szDcName, "\\\\");
  1071.  strcat(szDcName, srvInfo0->sv0_name);
  1072.  free(srvInfo0); /* Done with server information structure */
  1073.  
  1074.  /* Determine values provided. args[1].strptr is the type parameter */
  1075.  if (strnicmp(strupr(args[1].strptr), "A=", 2) == NO_ERROR)
  1076.  {
  1077.   /* An appliciation. Get the application information required */
  1078.   usBuflen = sizeof(struct app_info_3)+MAXCOMMENTSZ+PATHLEN*3+4;
  1079.   pAppInfo3 = malloc(usBuflen);
  1080.   if (usRc=NetAppGetInfo(szDcName,           /* server             */
  1081.                          NULL,               /* public application */
  1082.                          args[3].strptr,     /* application id     */
  1083.                          LEVEL_3,            /* level 3            */
  1084.                          (char *) pAppInfo3, /* buffer             */
  1085.                          usBuflen,           /* length             */
  1086.                          &usTotalentries ) ) /* total size         */
  1087.   {
  1088.    sprintf(retstr->strptr, "%d Could not get Application Information", usRc);
  1089.    free(pAppInfo3);
  1090.    retstr->strlength = strlen(retstr->strptr);
  1091.    return VALID_ROUTINE;     /* done */
  1092.   }
  1093.  
  1094.   usBuflen = sizeof(struct app_sel_info_1);
  1095.   selPointers.pAsiBuf = malloc(usBuflen);      /* For 1 user only information */
  1096.   usLal_type = pAppInfo3->app3_apptype;
  1097.  
  1098.   free(pAppInfo3);
  1099.   usBytesAvail = 0;
  1100.   usRc = NetUserGetAppSel(szDcName,             /* The DC   */
  1101.                           args[0].strptr,       /* The Userid */
  1102.                           LEVEL_1,              /* level_1  */
  1103.                           APP_ALL,              /* The type */
  1104.                           (char *) (selPointers.pAsiBuf),  /* The buffer */
  1105.                           usBuflen,             /* Size of the structure */
  1106.                           &usBytesAvail);
  1107.   free(selPointers.pAsiBuf);
  1108.   if( (usRc == ERROR_FILE_NOT_FOUND) || (usRc == ERROR_PATH_NOT_FOUND) )
  1109.   {
  1110.    /* Initiate a structure */
  1111.    if (usRc=NetUserDCDBInit(szDcName,args[0].strptr,(ULONG)NULL))
  1112.    {
  1113.     sprintf(retstr->strptr, "%d Could not initiate user DCDB information", usRc);
  1114.     retstr->strlength = strlen(retstr->strptr);
  1115.     return VALID_ROUTINE;     /* done */
  1116.    }
  1117.   }
  1118.   else
  1119.   {
  1120.    if( usRc != NERR_BufTooSmall )
  1121.    {
  1122.     sprintf(retstr->strptr, "%d Could not get user defined Applications", usRc);
  1123.     retstr->strlength = strlen(retstr->strptr);
  1124.     return VALID_ROUTINE;     /* done */
  1125.    }
  1126.   }
  1127.  
  1128.   /* We got something. Allocate the correct size, obtain information */
  1129.   usBuflen = usBytesAvail + sizeof(struct app_sel_list);
  1130.   selPointers.pAsiBuf = malloc(usBuflen); /* For 1 additional   */
  1131.   usRc = NetUserGetAppSel(szDcName,             /* The DC     */
  1132.                           args[0].strptr,       /* The Userid */
  1133.                           LEVEL_1,              /* level_1    */
  1134.                           APP_ALL,              /* All types  */
  1135.                           (char *) (selPointers.pAsiBuf),  /* The buffer */
  1136.                           usBuflen,             /* Size of the structure */
  1137.                           &usBytesAvail);
  1138.   if( usRc != 0 )
  1139.   {
  1140.    free(selPointers.pAsiBuf);
  1141.    sprintf(retstr->strptr, "%d Could not get user defined Applications", usRc);
  1142.    retstr->strlength = strlen(retstr->strptr);
  1143.    return VALID_ROUTINE;     /* done */
  1144.   }
  1145.  
  1146.   /* Get starting point */
  1147.   selPointers.pAslBuf = (struct app_sel_list *) \
  1148.   ((struct app_sel_info_1 *) selPointers.pAsiBuf + 1);
  1149.   /* This is the new one */
  1150.   selPointers.pAslBuf += selPointers.pAsiBuf->asi1_count; /* Set offset */
  1151.   selPointers.pAsiBuf->asi1_count++; /* Add one more to add */
  1152.   strcpy(selPointers.pAslBuf->asl_appname, args[3].strptr);
  1153.   selPointers.pAslBuf->asl_apptype = usLal_type; /* The type */
  1154.   /* Set the new one including the old ones */
  1155.   usRc = NetUserSetAppSel(szDcName,             /* The DC   */
  1156.                           args[0].strptr,       /* The Userid */
  1157.                           LEVEL_1,              /* level_1  */
  1158.                           (char *) (selPointers.pAsiBuf), /* The buffer */
  1159.                           usBuflen);            /* Size of the structure */
  1160.  
  1161.   free(selPointers.pAsiBuf);
  1162.   if(usRc != 0)
  1163.   {
  1164.    sprintf(retstr->strptr, "%d Could not define Application for user", usRc);
  1165.    retstr->strlength = strlen(retstr->strptr);
  1166.    return VALID_ROUTINE;     /* done */
  1167.   }
  1168.  }
  1169.  else
  1170.  {
  1171.   if (strnicmp(strupr(args[1].strptr), "D=", 2) == NO_ERROR)
  1172.   {
  1173.    /* A device, validate that the alias exist */
  1174.    usBuflen = sizeof(struct alias_info_1)+MAXCOMMENTSZ+1;
  1175.    pAliasInfo1 = malloc(usBuflen);
  1176.    if(usRc=NetAliasGetInfo(szDcName,            /* The Domain Controller*/
  1177.                            args[3].strptr,      /* The alias           */
  1178.                            LEVEL_1,             /* The level           */
  1179.                            (char *)pAliasInfo1, /* buffer pointer      */
  1180.                            usBuflen,            /* The length          */
  1181.                            &usBytesAvail) )     /* The total size      */
  1182.    {
  1183.     sprintf(retstr->strptr, "%d Could not get Alias Information", usRc);
  1184.     free(pAliasInfo1);
  1185.     retstr->strlength = strlen(retstr->strptr);
  1186.     return VALID_ROUTINE;     /* done */
  1187.    }
  1188.    /* Have valid alias information */
  1189.    if(args[2].strlength != 0)
  1190.    {
  1191.     /* args[2].strptr is the device name */
  1192.     if(strchr(args[2].strptr, ':') != NULL)
  1193.     {
  1194.      /* Got a colon, delete it */
  1195.      for (i=0; i<strlen(args[2].strptr) ;i++ ) {
  1196.       if(args[2].strptr[i] == ':')
  1197.        args[2].strptr[i] = '\0';
  1198.      }
  1199.     }
  1200.    }
  1201.    /* Determine which type of resource and ask for current count */
  1202.    usBuflen = sizeof(struct logon_asn_info_1);
  1203.    asnPointers.pLaiBuf = malloc(usBuflen);      /* For 1 user only information */
  1204.    usLal_type = pAliasInfo1->ai1_type;  /* The type */
  1205.    free(pAliasInfo1);
  1206.    usBytesAvail = 0;
  1207.    usRc = NetUserGetLogonAsn(szDcName,             /* The DC   */
  1208.                              args[0].strptr,       /* The Userid */
  1209.                              LEVEL_1,              /* level_1  */
  1210.                              7,                    /* The type */
  1211.                              (char *) (asnPointers.pLaiBuf),  /* The buffer */
  1212.                              usBuflen,             /* Size of the structure */
  1213.                              &usBytesAvail);
  1214.    free(asnPointers.pLaiBuf);
  1215.    if( (usRc == ERROR_FILE_NOT_FOUND) || (usRc == ERROR_PATH_NOT_FOUND) )
  1216.    {
  1217.     /* Initiate a structure */
  1218.     if (usRc=NetUserDCDBInit(szDcName,args[0].strptr,(ULONG)NULL))
  1219.     {
  1220.      sprintf(retstr->strptr, "%d Could not initiate user DCDB information", usRc);
  1221.      retstr->strlength = strlen(retstr->strptr);
  1222.      return VALID_ROUTINE;     /* done */
  1223.     }
  1224.    }
  1225.    else
  1226.    {
  1227.     if( usRc != NERR_BufTooSmall )
  1228.     {
  1229.      sprintf(retstr->strptr, "%d Could not get user Logon Assignment", usRc);
  1230.      retstr->strlength = strlen(retstr->strptr);
  1231.      return VALID_ROUTINE;     /* done */
  1232.     }
  1233.    }
  1234.  
  1235.    /* We got something. Allocate the correct size, obtain information */
  1236.    usBuflen = usBytesAvail + sizeof(struct logon_asn_list);
  1237.    asnPointers.pLaiBuf = malloc(usBuflen); /* For 1 additional   */
  1238.    usRc = NetUserGetLogonAsn(szDcName,             /* The DC     */
  1239.                              args[0].strptr,       /* The Userid */
  1240.                              LEVEL_1,              /* level_1    */
  1241.                              7,                    /* All types  */
  1242.                              (char *) (asnPointers.pLaiBuf),  /* The buffer */
  1243.                              usBuflen,             /* Size of the structure */
  1244.                              &usBytesAvail);
  1245.    if( usRc != 0 )
  1246.    {
  1247.     free(asnPointers.pLaiBuf);
  1248.     sprintf(retstr->strptr, "%d Could not get user Logon Assignment", usRc);
  1249.     retstr->strlength = strlen(retstr->strptr);
  1250.     return VALID_ROUTINE;     /* done */
  1251.    }
  1252.  
  1253.    /* Get starting point */
  1254.    asnPointers.pLalBuf = (struct logon_asn_list *) \
  1255.    ((struct logon_asn_info_1 *) asnPointers.pLaiBuf + 1);
  1256.    /* This is the new one */
  1257.    asnPointers.pLalBuf += asnPointers.pLaiBuf->lai1_count;
  1258.    asnPointers.pLaiBuf->lai1_count++; /* Add one */
  1259.    strcpy(asnPointers.pLalBuf->lal_alias, args[3].strptr);
  1260.    asnPointers.pLalBuf->lal_type = usLal_type; /* The type */
  1261.  
  1262.    if(args[2].strlength != 0)
  1263.     strcpy(asnPointers.pLalBuf->lal_device, args[2].strptr);
  1264.  
  1265.    /* Add User Logn assignments */
  1266.    usRc = NetUserSetLogonAsn(szDcName,             /* The DC   */
  1267.                              args[0].strptr,       /* The Userid */
  1268.                              LEVEL_1,              /* level_1  */
  1269.                              (char *) (asnPointers.pLaiBuf), /* The buffer */
  1270.                              usBuflen);            /* Size of the structure */
  1271.    free(asnPointers.pLaiBuf);
  1272.    if(usRc != 0)
  1273.    {
  1274.     sprintf(retstr->strptr, "%d Could not set user Logon Assignment", usRc);
  1275.     retstr->strlength = strlen(retstr->strptr);
  1276.     return VALID_ROUTINE;     /* done */
  1277.    }
  1278.   }
  1279.   else
  1280.   {
  1281.    sprintf(retstr->strptr, "99 Invalid Type specification");
  1282.    retstr->strlength = strlen(retstr->strptr);
  1283.    return VALID_ROUTINE;     /* done */
  1284.   }
  1285.  }
  1286.  
  1287.  BUILDRXSTRING(retstr, "0");
  1288.  return VALID_ROUTINE;     /* no error  */
  1289.  
  1290. }
  1291.  
  1292. /*********************************************************************/
  1293. /* Function:  GetLogonAsn. Get Logon Assignments for a user          */
  1294. /*                                                                   */
  1295. /* Syntax:    call GetLogonAsn(userid, asnList)                      */
  1296. /* Params:    userid The userid                                      */
  1297. /*            asnList The stem variable to hold the logon assignments*/
  1298. /*                   The following values are used:                  */
  1299. /*                                                                   */
  1300. /*                   -none- No assignments found                     */
  1301. /*                                                                   */
  1302. /*                          or                                       */
  1303. /*                                                                   */
  1304. /*                   type   Either a device assignment or application*/
  1305. /*                          Used values are 'D=' for device and 'A=' */
  1306. /*                          for application assignment               */
  1307. /*                   device The used device. For example G:, LPT6,   */
  1308. /*                          COM8. An empty specification is set to   */
  1309. /*                          blanks                                   */
  1310. /*                   alias  The alias for the device or application  */
  1311. /*                                                                   */
  1312. /* Return:    Return code from any failing function. '0' if no error */
  1313. /*********************************************************************/
  1314. ULONG GetLogonAsn(CHAR *name, ULONG numargs, RXSTRING args[],
  1315.                     CHAR *queuename, RXSTRING *retstr)
  1316. {
  1317.  struct alias_info_1 * pAliasInfo1; /* Alias information, level 1    */
  1318.  struct server_info_0 *srvInfo0;    /* Server Information 0 Buffer   */
  1319.  struct app_info_3    *pAppInfo3;   /* Appl info pointer             */
  1320.  USHORT usBuflen;                   /* Memory structure sizes        */
  1321.  USHORT usBytesAvail;
  1322.  USHORT usRc;
  1323.  ULONG  ulRc;
  1324.  UCHAR  szDcName[UNCLEN+1];         /* The Domain Controller Name    */
  1325.  UCHAR  szWorkBuf[80];              /* Working charater buffer       */
  1326.  INT    i;
  1327.  USHORT usEntriesread;
  1328.  USHORT usTotalentries;
  1329.  USHORT usLal_type;
  1330.  BOOL   fAppAsn = FALSE;
  1331.  RXSTEMDATA1 lrxs;                   /* Local REXX stem data structure*/
  1332.  
  1333.  
  1334.  struct asn_info {
  1335.    struct logon_asn_info_1 *pLaiBuf;
  1336.    struct logon_asn_list *pLalBuf;
  1337.  } asnPointers;
  1338.  
  1339.  struct sel_info {
  1340.    struct app_sel_info_1 *pAsiBuf;
  1341.    struct app_sel_list *pAslBuf;
  1342.  } selPointers;
  1343.  
  1344.  if ( (numargs != 2) ||         /* Are arguments specified correctly */
  1345.      !RXVALIDSTRING(args[0]) ||
  1346.      !RXVALIDSTRING(args[1]) )
  1347.   return INVALID_ROUTINE;       /* Raise error            */
  1348.  
  1349.  srvInfo0 = malloc(sizeof(struct server_info_0));
  1350.  if (usRc=NetServerEnum2("",                 /* server = local    */
  1351.                          LEVEL_0,            /* level_0           */
  1352.                          (char *)srvInfo0,   /* server_info_0     */
  1353.                          sizeof(struct server_info_0),
  1354.                          &usEntriesread,     /* entries returned  */
  1355.                          &usTotalentries,    /* total entries     */
  1356.                          (long)SV_TYPE_DOMAIN_CTRL , /* domain controller */
  1357.                          "" ) )
  1358.  {
  1359.   /* Error getting Domain Controller name */
  1360.   free(srvInfo0);
  1361.   sprintf(retstr->strptr, "%d Could not get Domain Controller Name", usRc);
  1362.   retstr->strlength = strlen(retstr->strptr);
  1363.   return VALID_ROUTINE;     /* done */
  1364.  }
  1365.  
  1366.  /* Build correct DC name */
  1367.  strcpy(szDcName, "\\\\");
  1368.  strcat(szDcName, srvInfo0->sv0_name);
  1369.  free(srvInfo0); /* Done with server information structure */
  1370.  
  1371.  /* Initialize stem data structure */
  1372.  lrxs.count = 0;
  1373.  strcpy(lrxs.varname, args[1].strptr);
  1374.  lrxs.stemlen = args[1].strlength;
  1375.  strupr(lrxs.varname);
  1376.  
  1377.  if(lrxs.varname[lrxs.stemlen - 1] != '.')
  1378.  {
  1379.   lrxs.varname[lrxs.stemlen] = '.';
  1380.   lrxs.varname[lrxs.stemlen + 1] = '\0';
  1381.   lrxs.stemlen++;
  1382.  }
  1383.  
  1384.  usBuflen = sizeof(struct app_sel_info_1);
  1385.  selPointers.pAsiBuf = malloc(usBuflen);
  1386.  usBytesAvail = 0;
  1387.  usRc = NetUserGetAppSel(szDcName,             /* The DC   */
  1388.                          args[0].strptr,       /* The Userid */
  1389.                          LEVEL_1,              /* level_1  */
  1390.                          APP_ALL,              /* The type */
  1391.                          (char *) (selPointers.pAsiBuf),  /* The buffer */
  1392.                          usBuflen,             /* Size of the structure */
  1393.                          &usBytesAvail);
  1394.  free(selPointers.pAsiBuf);
  1395.  
  1396.  if( (usRc == ERROR_FILE_NOT_FOUND) || (usRc == ERROR_PATH_NOT_FOUND) )
  1397.  {
  1398.   /* User has nothing defined, set ending values, and end this call */
  1399.   strcpy(szWorkBuf, "-none-");
  1400.   ulRc = insertStem(&lrxs, szWorkBuf);
  1401.   if( ulRc != VALID_ROUTINE)
  1402.     return INVALID_ROUTINE;
  1403.  
  1404.   ulRc = lastInStem(&lrxs);
  1405.   if( ulRc != VALID_ROUTINE)
  1406.     return INVALID_ROUTINE;
  1407.  
  1408.   BUILDRXSTRING(retstr, "0");
  1409.   return VALID_ROUTINE;     /* done */
  1410.  
  1411.  }
  1412.  
  1413.  /* There was information available */
  1414.  if( usRc == NERR_BufTooSmall )
  1415.  {
  1416.   /* We got something. Allocate the correct size, obtain information */
  1417.   usBuflen = usBytesAvail + sizeof(struct app_sel_list);
  1418.   selPointers.pAsiBuf = malloc(usBuflen); /* For 1 additional   */
  1419.   usRc = NetUserGetAppSel(szDcName,             /* The DC     */
  1420.                           args[0].strptr,       /* The Userid */
  1421.                           LEVEL_1,              /* level_1    */
  1422.                           APP_ALL,              /* All types  */
  1423.                           (char *) (selPointers.pAsiBuf),  /* The buffer */
  1424.                           usBuflen,             /* Size of the structure */
  1425.                           &usBytesAvail);
  1426.   if( usRc == 0 )
  1427.   {
  1428.    /* Get starting point */
  1429.    fAppAsn = TRUE;
  1430.    /* Point to the first */
  1431.    selPointers.pAslBuf = (struct app_sel_list *) \
  1432.    ((struct app_sel_info_1 *) selPointers.pAsiBuf + 1);
  1433.  
  1434.    for(i=0; i < selPointers.pAsiBuf->asi1_count; i++)
  1435.    {
  1436.     strcpy(szWorkBuf, "A= ");
  1437.     strcat(szWorkBuf, selPointers.pAslBuf->asl_appname);
  1438.     ulRc = insertStem(&lrxs, szWorkBuf);
  1439.  
  1440.     if( ulRc != VALID_ROUTINE)
  1441.     {
  1442.      free(selPointers.pAsiBuf);
  1443.      return INVALID_ROUTINE;
  1444.     }
  1445.  
  1446.     selPointers.pAslBuf++;
  1447.    }
  1448.  
  1449.    ulRc = lastInStem(&lrxs);
  1450.    if( ulRc != VALID_ROUTINE)
  1451.    {
  1452.     free(selPointers.pAsiBuf);
  1453.     return INVALID_ROUTINE;
  1454.    }
  1455.  
  1456.   }
  1457.   free(selPointers.pAsiBuf);
  1458.  }
  1459.  
  1460.  /* Logon assignments now */
  1461.  usBuflen = sizeof(struct logon_asn_info_1);
  1462.  asnPointers.pLaiBuf = malloc(usBuflen);
  1463.  usBytesAvail = 0;
  1464.  usRc = NetUserGetLogonAsn(szDcName,             /* The DC   */
  1465.                            args[0].strptr,       /* The Userid */
  1466.                            LEVEL_1,              /* level_1  */
  1467.                            7,                    /* The type */
  1468.                            (char *) (asnPointers.pLaiBuf),  /* The buffer */
  1469.                            usBuflen,             /* Size of the structure */
  1470.                            &usBytesAvail);
  1471.  free(asnPointers.pLaiBuf);
  1472.  
  1473.  /* There was information available */
  1474.  if( usRc == NERR_BufTooSmall )
  1475.  {
  1476.   /* We got something. Allocate the correct size, obtain information */
  1477.   usBuflen = usBytesAvail;
  1478.   asnPointers.pLaiBuf = malloc(usBuflen); /* For all information*/
  1479.   usRc = NetUserGetLogonAsn(szDcName,             /* The DC     */
  1480.                             args[0].strptr,       /* The Userid */
  1481.                             LEVEL_1,              /* level_1    */
  1482.                             7,                    /* All types  */
  1483.                             (char *) (asnPointers.pLaiBuf),  /* The buffer */
  1484.                             usBuflen,             /* Size of the structure */
  1485.                             &usBytesAvail);
  1486.   if( usRc != 0 )
  1487.   {
  1488.    free(asnPointers.pLaiBuf);
  1489.    if(fAppAsn == FALSE)
  1490.    {
  1491.     sprintf(retstr->strptr, "%d Could not get user Assignments", usRc);
  1492.     retstr->strlength = strlen(retstr->strptr);
  1493.     return VALID_ROUTINE;     /* done */
  1494.    }
  1495.   }
  1496.   else
  1497.   {
  1498.    /* Work on the information provided. Get starting point */
  1499.    asnPointers.pLalBuf = (struct logon_asn_list *) \
  1500.    ((struct logon_asn_info_1 *) asnPointers.pLaiBuf + 1);
  1501.    for(i=0; i < asnPointers.pLaiBuf->lai1_count; i++)
  1502.    {
  1503.     sprintf(szWorkBuf,"D=     %8s  %8s", \
  1504.                       asnPointers.pLalBuf->lal_device, \
  1505.                       asnPointers.pLalBuf->lal_alias);
  1506.  
  1507.     ulRc = insertStem(&lrxs, szWorkBuf);
  1508.     if( ulRc != VALID_ROUTINE)
  1509.     {
  1510.      free(asnPointers.pLaiBuf);
  1511.      return INVALID_ROUTINE;
  1512.     }
  1513.  
  1514.     asnPointers.pLalBuf++;
  1515.    }
  1516.  
  1517.    ulRc = lastInStem(&lrxs);
  1518.    if( ulRc != VALID_ROUTINE)
  1519.    {
  1520.     free(asnPointers.pLaiBuf);
  1521.     return INVALID_ROUTINE;
  1522.    }
  1523.  
  1524.   }
  1525.   free(selPointers.pAsiBuf);
  1526.  }
  1527.  else
  1528.  {
  1529.   if(usBytesAvail == sizeof(struct logon_asn_info_1) )
  1530.   {
  1531.    /* User has nothing defined this time, set ending values */
  1532.    if(fAppAsn == FALSE)  /* Check if application selector was set */
  1533.    {
  1534.     strcpy(szWorkBuf, "-none-");
  1535.  
  1536.     ulRc = insertStem(&lrxs, szWorkBuf);
  1537.     if( ulRc != VALID_ROUTINE)
  1538.      return INVALID_ROUTINE;
  1539.  
  1540.     ulRc = lastInStem(&lrxs);
  1541.     if( ulRc != VALID_ROUTINE)
  1542.      return INVALID_ROUTINE;
  1543.    }
  1544.  
  1545.   }
  1546.   else
  1547.   {
  1548.    if(fAppAsn == FALSE)
  1549.    {
  1550.      sprintf(retstr->strptr, "%d Could not get user Assignments", usRc);
  1551.      retstr->strlength = strlen(retstr->strptr);
  1552.      return VALID_ROUTINE;     /* done */
  1553.    }
  1554.  
  1555.   }
  1556.  
  1557.  }
  1558.  
  1559.  BUILDRXSTRING(retstr, "0");
  1560.  return VALID_ROUTINE;       /* Raise no error */
  1561.  
  1562. }
  1563.  
  1564. /*********************************************************************/
  1565. /* Function:  GetLogonAsnAcp  Get the logon assignment access control*/
  1566. /*                            profiles for applications or alias     */
  1567. /*                                                                   */
  1568. /*            External resources are not supported                   */
  1569. /*                                                                   */
  1570. /* Syntax:    GetLogonAsnAcp(user, type, stem)                       */
  1571. /* Params:    user    The userid to check                            */
  1572. /*            type    Alias type 'A=', 'D=', 'ALL'                   */
  1573. /*            stem    The REXX stem variable used to return the      */
  1574. /*                    alias specifications that do not have an       */
  1575. /*                    access control profile for the user. User and  */
  1576. /*                    groups are validated                           */
  1577. /*                                                                   */
  1578. /* Example call:  rc = GetLogonAsnAcp(USR, 'D=', 'stem.')            */
  1579. /*                                                                   */
  1580. /* Return value examples:                                            */
  1581. /*                                                                   */
  1582. /*               D=  ALIAS    RWC                                    */
  1583. /*               D=  ALIAS8   external resource                      */
  1584. /*               A=  ALIAS1   RWC                                    */
  1585. /*               A=  ALIAS2     N                                    */
  1586. /*               A=  ALIAS3     R                                    */
  1587. /*                                                                   */
  1588. /* The complete path is not displayed, only the alias name.          */
  1589. /*                                                                   */
  1590. /* Return:    Return code from any failing function. '0' if no error */
  1591. /*********************************************************************/
  1592. ULONG GetLogonAsnAcp(CHAR *name, ULONG numargs, RXSTRING args[],
  1593.                      CHAR *queuename, RXSTRING *retstr)
  1594. {
  1595.  
  1596.  RXSTEMDATA1 lrxs;                  /* Local REXX stem data structure*/
  1597.  struct server_info_0 *pSrvInfo0;   /* Pointer to server information */
  1598.  USHORT usEntriesread, usTotalentries;
  1599.  ULONG  ulRc;                       /* Return code                   */
  1600.  UCHAR  szDcName[UNCLEN+1];         /* The Domain Controller Name    */
  1601.  ULONG  ulFnRc;                     /* Function return code          */
  1602.  
  1603.  if ((numargs != 3) ||          /* Are arguments specified correctly */
  1604.      !RXVALIDSTRING(args[0]) ||
  1605.      !RXVALIDSTRING(args[1]) ||
  1606.      !RXVALIDSTRING(args[2]) )
  1607.   return INVALID_ROUTINE;       /* Raise error            */
  1608.  
  1609.  /* Initialize stem data structure */
  1610.  lrxs.count = 0;
  1611.  strcpy(lrxs.varname, args[2].strptr);
  1612.  lrxs.stemlen = args[2].strlength;
  1613.  strupr(lrxs.varname);
  1614.  
  1615.  if(lrxs.varname[lrxs.stemlen - 1] != '.')
  1616.  {
  1617.   lrxs.varname[lrxs.stemlen] = '.';
  1618.   lrxs.varname[lrxs.stemlen + 1] = '\0';
  1619.   lrxs.stemlen++;
  1620.  }
  1621.  
  1622.  /* Get domain controller machine ID */
  1623.  pSrvInfo0 = malloc( sizeof(struct server_info_0) );
  1624.  if(ulRc=NetServerEnum2("",                     /* Server name       */
  1625.                         LEVEL_0,                /* level_0           */
  1626.                         (char *)pSrvInfo0,      /* Pointer to buffer */
  1627.                         sizeof(struct server_info_0),
  1628.                         &usEntriesread,         /* Entries returned  */
  1629.                         &usTotalentries,        /* Total entries     */
  1630.                         (long)SV_TYPE_DOMAIN_CTRL,/*DC only          */
  1631.                         "" ) )
  1632.  {
  1633.   sprintf(retstr->strptr, "%d Could not obtain Domain Controller machine ID", ulRc);
  1634.   retstr->strlength = strlen(retstr->strptr);
  1635.   free(pSrvInfo0);                     /* Free used memory           */
  1636.   return VALID_ROUTINE;                /* No REXX error on call      */
  1637.  }
  1638.  
  1639.  sprintf(szDcName, "\\\\%s", pSrvInfo0->sv0_name);
  1640.  free(pSrvInfo0);
  1641.  
  1642.  /* Determine the request type */
  1643.  if (strnicmp(strupr(args[1].strptr), "ALL", 3) == NO_ERROR)
  1644.  {
  1645.   ulRc = getAppEnumAcp(&ulFnRc, szDcName, args[0].strptr, &lrxs);
  1646.   if(ulRc != VALID_ROUTINE)
  1647.    return INVALID_ROUTINE;            /* Raise error */
  1648.  
  1649.   if (ulFnRc != 0)
  1650.   {
  1651.    sprintf(retstr->strptr, "%d Could not get Application information", ulFnRc);
  1652.    retstr->strlength = strlen(retstr->strptr);
  1653.    return VALID_ROUTINE;       /* Raise no error */
  1654.   }
  1655.  
  1656.   ulRc = getLasnAliasAcp(&ulFnRc, szDcName, args[0].strptr, &lrxs);
  1657.   if(ulRc != VALID_ROUTINE)
  1658.    return INVALID_ROUTINE;            /* Raise error */
  1659.  
  1660.   if (ulFnRc != 0)
  1661.   {
  1662.    sprintf(retstr->strptr, "%d Could not get Application information", ulFnRc);
  1663.    retstr->strlength = strlen(retstr->strptr);
  1664.    return VALID_ROUTINE;       /* Raise no error */
  1665.   }
  1666.  
  1667.  }
  1668.  else
  1669.  if (strnicmp(strupr(args[1].strptr), "D=", 2) == NO_ERROR)
  1670.  {
  1671.   ulRc = getLasnAliasAcp(&ulFnRc, szDcName, args[0].strptr, &lrxs);
  1672.   if(ulRc != VALID_ROUTINE)
  1673.    return INVALID_ROUTINE;            /* Raise error */
  1674.  
  1675.   if (ulFnRc != 0)
  1676.   {
  1677.    sprintf(retstr->strptr, "%d Could not get Application information", ulFnRc);
  1678.    retstr->strlength = strlen(retstr->strptr);
  1679.    return VALID_ROUTINE;       /* Raise no error */
  1680.   }
  1681.  
  1682.  }
  1683.  else
  1684.  if (strnicmp(strupr(args[1].strptr), "A=", 2) == NO_ERROR)
  1685.  {
  1686.   ulRc = getAppEnumAcp(&ulFnRc, szDcName, args[0].strptr, &lrxs);
  1687.   if(ulRc != VALID_ROUTINE)
  1688.    return INVALID_ROUTINE;            /* Raise error */
  1689.  
  1690.   if (ulFnRc != 0)
  1691.   {
  1692.    sprintf(retstr->strptr, "%d Could not get Application information", ulFnRc);
  1693.    retstr->strlength = strlen(retstr->strptr);
  1694.    return VALID_ROUTINE;       /* Raise no error */
  1695.   }
  1696.  
  1697.  }
  1698.  
  1699.  BUILDRXSTRING(retstr, "0");
  1700.  return VALID_ROUTINE;       /* Raise no error */
  1701.  
  1702. }
  1703.  
  1704. /*********************************************************************/
  1705. /* Function:  NetEnum. Enumerate LAN Server 3.0 domain information   */
  1706. /*                                                                   */
  1707. /* Syntax:    call NetEnum(option, serverName, infoList, addInfo)    */
  1708. /* Params:    option     The item to enumerate                       */
  1709. /*                       The following options are supported         */
  1710. /*                                                                   */
  1711. /*                       option                   addInfo            */
  1712. /*                       ----------------         ---------------    */
  1713. /*                       "APPLICATIONS"           "PUBLICOS2"        */
  1714. /*                       "APPLICATIONS"           "PUBLICDOS"        */
  1715. /*                       "APPLICATIONS"           "PRIVATE"          */
  1716. /*                       "APPLICATIONS"           "ALL"              */
  1717. /*                       "PRINTDEV"               "STATUS"           */
  1718. /*                       "SERVERS"                srvType            */
  1719. /*                                                                   */
  1720. /*            serverName The server machine name. Normally this is   */
  1721. /*                       the domain controller machine id. The       */
  1722. /*                       machine name used must include \\           */
  1723. /*            infoList   The stem variable to hold the info. This    */
  1724. /*                       variable is only valid if NetEnum()         */
  1725. /*                       returns a "0" returncode.                   */
  1726. /*            addInfo    Variable or value for addtional enumerate   */
  1727. /*                       options. For default override.              */
  1728. /*                                                                   */
  1729. /* The srvType parameter must be supplied for "SERVERS"              */
  1730. /*                                                                   */
  1731. /* The addInfo parameter must be supplied for the "APPLICATIONS"     */
  1732. /* enumaration together with the domain controller machine ID.       */
  1733. /*                                                                   */
  1734. /*            The content of the infoList variable is as follows:    */
  1735. /*                                                                   */
  1736. /*            infoList.0 The number of information items             */
  1737. /*            infoList.n information item n                          */
  1738. /*                                                                   */
  1739. /* Examples:  rc= NetEnum('printdev','\\TheSrv','list.','status')    */
  1740. /*            rc= NetEnum('servers',,'srvList.', 2)                  */
  1741. /*            rc= NetEnum('applications','\\OURDC','appList.','all') */
  1742. /*                                                                   */
  1743. /* Return:    Return code from any failing function. '0' if no error */
  1744. /*********************************************************************/
  1745. ULONG NetEnum(CHAR *name, ULONG numargs, RXSTRING args[],
  1746.                     CHAR *queuename, RXSTRING *retstr)
  1747. {
  1748.  USHORT usBuflen;                   /* Memory structure sizes        */
  1749.  USHORT usBytesAvail;
  1750.  USHORT usRc;
  1751.  UCHAR  szDcName[UNCLEN+1];         /* The Domain Controller Name    */
  1752.  INT    i;
  1753.  USHORT usEntriesread;
  1754.  USHORT usTotalentries;
  1755.  USHORT usLal_type;
  1756.  ULONG  ulFnRc;                     /* Function return code          */
  1757.  ULONG  ulRc;
  1758.  
  1759.  RXSTEMDATA1 lrxs;                  /* Local REXX stem data structure*/
  1760.  ULONG       ulStatus;
  1761.  
  1762.  
  1763.  if ( !RXVALIDSTRING(args[0]) ||
  1764.      !RXVALIDSTRING(args[2]) )
  1765.   return INVALID_ROUTINE;                  /* Raise error            */
  1766.  
  1767.  /* Initialize stem data structure */
  1768.  lrxs.count = 0;
  1769.  strcpy(lrxs.varname, args[2].strptr);
  1770.  lrxs.stemlen = args[2].strlength;
  1771.  strupr(lrxs.varname);
  1772.  
  1773.  if(lrxs.varname[lrxs.stemlen - 1] != '.')
  1774.  {
  1775.   lrxs.varname[lrxs.stemlen] = '.';
  1776.   lrxs.varname[lrxs.stemlen + 1] = '\0';
  1777.   lrxs.stemlen++;
  1778.  }
  1779.  
  1780.  ulFnRc = 0;
  1781.  /* Determine what the request is and perform it */
  1782.  /* PRINTDEV ? */
  1783.  if (strnicmp(strupr(args[0].strptr), "PRINTDEV", 8) == NO_ERROR)
  1784.  {
  1785.   ulStatus = 0;
  1786.   if ( (numargs == 3) || (numargs == 4) )
  1787.   {
  1788.    if( (RXVALIDSTRING(args[3]) ) && (args[3].strlength == 6) )
  1789.    {
  1790.     if (strnicmp(strupr(args[3].strptr), "STATUS", 6) == NO_ERROR)
  1791.     {
  1792.      ulStatus = 1;  /* Do only name and status */
  1793.     }
  1794.    }
  1795.   }
  1796.  
  1797.   if( getSplEnumDevice(&ulFnRc, args[1].strptr, &lrxs, ulStatus) )
  1798.    return INVALID_ROUTINE;                 /* Raise error            */
  1799.  
  1800.   if (ulFnRc != 0)
  1801.   {
  1802.    sprintf(retstr->strptr, "%d Could not get PRINTDEV information", ulFnRc);
  1803.    retstr->strlength = strlen(retstr->strptr);
  1804.    return VALID_ROUTINE;       /* Raise no error */
  1805.   }
  1806.  }
  1807.  else
  1808.  /* SERVERS ? */
  1809.  if (strnicmp(strupr(args[0].strptr), "SERVERS", 7) == NO_ERROR)
  1810.  {
  1811.   /* The type parameter can be one or a combination of the following  */
  1812.   /* SV_TYPE_WORKSTATION     0x00000001 Workstation                   */
  1813.   /* SV_TYPE_SERVER          0x00000002 Server                        */
  1814.   /* SV_TYPE_SQLSERVER       0x00000004 SQL server                    */
  1815.   /* SV_TYPE_DOMAIN_CTRL     0x00000008 Domain controller             */
  1816.   /* SV_TYPE_DOMAIN_BAKCTRL  0x00000010 Backup domain controller      */
  1817.   /* SV_TYPE_TIME_SOURCE     0x00000020 Time server                   */
  1818.   /* SV_TYPE_AFP             0x00000040 Apple** File Protocol service */
  1819.   /* SV_TYPE_NOVELL          0x00000080 Novell** service              */
  1820.   /* SV_TYPE_ALL             0xFFFFFFFF All types of servers          */
  1821.  
  1822.   if ( !RXVALIDSTRING(args[3]))
  1823.    return INVALID_ROUTINE;                  /* Raise error            */
  1824.  
  1825.   ulRc = getServerEnum2(&ulFnRc, NULL, &lrxs, atoi(args[3].strptr) );
  1826.   if(ulRc != VALID_ROUTINE)
  1827.    return INVALID_ROUTINE;            /* Raise error */
  1828.  
  1829.   if (ulFnRc != 0)
  1830.   {
  1831.    sprintf(retstr->strptr, "%d Could not get SERVERS information", ulFnRc);
  1832.    retstr->strlength = strlen(retstr->strptr);
  1833.    return VALID_ROUTINE;       /* Raise no error */
  1834.   }
  1835.  
  1836.  }
  1837.  else
  1838.  /* APPLICATIONS */
  1839.  if (strnicmp(strupr(args[0].strptr), "APPLICATIONS", 12) == NO_ERROR)
  1840.  {
  1841.   ulStatus = ALLAPPS;
  1842.   if (numargs == 4)
  1843.   {
  1844.    if( (RXVALIDSTRING(args[1]) ) && (RXVALIDSTRING(args[3]) ) && \
  1845.         (args[1].strlength <= 17) && (args[3].strlength <= 9) )
  1846.    {
  1847.     if (strnicmp(strupr(args[3].strptr), "PUBLICDOS", 9) == NO_ERROR)
  1848.      ulStatus = PUBDOS;               /* Get public DOS applications */
  1849.  
  1850.     if (strnicmp(strupr(args[3].strptr), "PUBLICOS2", 9) == NO_ERROR)
  1851.      ulStatus = PUBOS2;               /* Get public OS/2 applications */
  1852.  
  1853.     if (strnicmp(strupr(args[3].strptr), "PRIVATE", 7) == NO_ERROR)
  1854.      ulStatus = PRIVATE;               /* Get all private applications */
  1855.  
  1856.     if (strnicmp(strupr(args[3].strptr), "ALL", 3) == NO_ERROR)
  1857.      ulStatus = ALLAPPS;               /* Get all applications */
  1858.    }
  1859.   }
  1860.   if(ulStatus == ALLAPPS)
  1861.   {
  1862.    if( getAppEnum(&ulFnRc, args[1].strptr, &lrxs, PUBDOS) )
  1863.     return INVALID_ROUTINE;            /* Raise error */
  1864.    if( getAppEnum(&ulFnRc, args[1].strptr, &lrxs, PUBOS2) )
  1865.     return INVALID_ROUTINE;            /* Raise error */
  1866.    if( getAppEnum(&ulFnRc, args[1].strptr, &lrxs, PRIVATE) )
  1867.     return INVALID_ROUTINE;            /* Raise error */
  1868.   }
  1869.   else
  1870.   {
  1871.    if( getAppEnum(&ulFnRc, args[1].strptr, &lrxs, ulStatus) )
  1872.     return INVALID_ROUTINE;            /* Raise error */
  1873.   }
  1874.  
  1875.   if (ulFnRc != 0)
  1876.   {
  1877.    sprintf(retstr->strptr, "%d Could not get APPLICATIONS information", ulFnRc);
  1878.    retstr->strlength = strlen(retstr->strptr);
  1879.    return VALID_ROUTINE;       /* Raise no error */
  1880.   }
  1881.  
  1882.  }
  1883.  
  1884.  BUILDRXSTRING(retstr, "0");
  1885.  return VALID_ROUTINE;       /* Raise no error */
  1886.  
  1887. }
  1888.  
  1889. /*********************************************************************/
  1890. /* Insert a string into available stem variable                      */
  1891. /*********************************************************************/
  1892. ULONG insertStem(RXSTEMDATA1 * rxs, UCHAR * pszString)
  1893. {
  1894.  
  1895.  if(pszString != '\0')           /* Make sure a valid string is used */
  1896.  {
  1897.   if( strlen(pszString) < IBUF_LEN)
  1898.   {
  1899.    strcpy(rxs->ibuf, pszString);
  1900.    rxs->vlen = strlen(pszString);
  1901.   }
  1902.   else
  1903.   {
  1904.    memcpy(rxs->ibuf, pszString, IBUF_LEN - 1);
  1905.    rxs->ibuf[IBUF_LEN] = '\0';
  1906.   }
  1907.  }
  1908.  else
  1909.  {
  1910.   strcpy(rxs->ibuf, "Invalid data");
  1911.   rxs->vlen = strlen("Invalid data");
  1912.  }
  1913.  
  1914.  rxs->count++;                                    /* n'th + 1 entry */
  1915.  sprintf(rxs->varname+rxs->stemlen, "%d", rxs->count);
  1916.  rxs->shvb.shvnext = NULL;          /* This is the last entry       */
  1917.  rxs->shvb.shvname.strptr = rxs->varname; /* This is the var name   */
  1918.  rxs->shvb.shvname.strlength = strlen(rxs->varname);
  1919.  rxs->shvb.shvnamelen        = strlen(rxs->varname);
  1920.  rxs->shvb.shvvalue.strptr   = rxs->ibuf; /* Set buffer address     */
  1921.  rxs->shvb.shvvalue.strlength= rxs->vlen;
  1922.  rxs->shvb.shvvaluelen       = rxs->vlen;
  1923.  rxs->shvb.shvcode           = RXSHV_SET; /* Set value request      */
  1924.  rxs->shvb.shvret            = 0;
  1925.  
  1926.  if (RexxVariablePool(&rxs->shvb) == RXSHV_BADN)
  1927.  {
  1928.   return INVALID_ROUTINE;                 /* error on non-zero      */
  1929.  }
  1930.  
  1931.  return VALID_ROUTINE;                     /* Raise no error         */
  1932.  
  1933. }
  1934.  
  1935.  
  1936. /*********************************************************************/
  1937. /* Set last stem variable                                            */
  1938. /*********************************************************************/
  1939. ULONG lastInStem(RXSTEMDATA1 * rxs)
  1940. {
  1941.  
  1942.  sprintf(rxs->ibuf, "%d", rxs->count);
  1943.  rxs->varname[rxs->stemlen] = '0';        /* 'varname.0'            */
  1944.  rxs->varname[rxs->stemlen + 1] = '\0';
  1945.  rxs->shvb.shvnext = NULL;          /* No further entries           */
  1946.  rxs->shvb.shvname.strptr = rxs->varname; /* This is the var name   */
  1947.  rxs->shvb.shvname.strlength = strlen(rxs->varname);
  1948.  rxs->shvb.shvnamelen        = strlen(rxs->varname);
  1949.  rxs->shvb.shvvalue.strptr   = rxs->ibuf; /* Set buffer address     */
  1950.  rxs->shvb.shvvalue.strlength= strlen(rxs->ibuf);
  1951.  rxs->shvb.shvvaluelen       = strlen(rxs->ibuf);
  1952.  rxs->shvb.shvcode           = RXSHV_SET; /* Set value request      */
  1953.  rxs->shvb.shvret            = 0;
  1954.  
  1955.  if (RexxVariablePool(&rxs->shvb) == RXSHV_BADN)
  1956.  {
  1957.   return INVALID_ROUTINE;                 /* error on non-zero      */
  1958.  }
  1959.  
  1960.  return VALID_ROUTINE;       /* Raise no error                      */
  1961.  
  1962. }
  1963.  
  1964. /*********************************************************************/
  1965. /* Get Spl device enumeration                                        */
  1966. /*********************************************************************/
  1967. ULONG getSplEnumDevice(PULONG ulRcode, PSZ pszSrvName,
  1968.                        RXSTEMDATA1 * rxs, ULONG ulStat)
  1969. {
  1970.  
  1971.  UCHAR  szWorkBuf[4096];            /* Working charater buffer       */
  1972.  UCHAR  szStatusBuf[80];            /* Working status buffer         */
  1973.  PBYTE  pbBuf;                      /* Pointer to buffer             */
  1974.  ULONG  ulReturned;                 /* Number of entries returned    */
  1975.  ULONG  ulTotal;                    /* Number of total entries       */
  1976.  ULONG  ulNeeded;                   /* Bytes needed to hold info     */
  1977.  ULONG  ulBufSize;                  /* Buffer size                   */
  1978.  ULONG  i;                          /* Loop variable                 */
  1979.  SPLERR splerr;                     /* rc from SplEnumDevice()       */
  1980.  PPRDINFO3 pprd3 ;                  /* Structure to hold print       */
  1981.                                     /* device information            */
  1982.  ULONG  ulRc;                       /* Temporary return code         */
  1983.  USHORT fstatus;
  1984.  
  1985.  /* Determine the size of the buffer to hold the information */
  1986.  splerr = SplEnumDevice(pszSrvName,
  1987.                         LEVEL_3,
  1988.                         pbBuf,
  1989.                         0L,                  /* Size of the buffer */
  1990.                         &ulReturned,
  1991.                         &ulTotal,
  1992.                         &ulNeeded,
  1993.                         NULL) ;              /* Reserved           */
  1994.  
  1995.  /* If ERROR_MORE_DATA or NERR_BufTooSmall continue */
  1996.  if( (splerr == ERROR_MORE_DATA) || (splerr == NERR_BufTooSmall) )
  1997.  {
  1998.   if(ulNeeded == 0)
  1999.   {
  2000.    /* Does not know the size required. Take max times ulTotal */
  2001.    ulBufSize = sizeof(PRDINFO3) + PRINTERNAME_SIZE + UNLEN + PDLEN + \
  2002.                2 * MAXCOMMENTSZ + 18 * DRIV_DEVICENAME_SIZE + 256;
  2003.    ulNeeded = ulTotal * ulBufSize;
  2004.   }
  2005.  
  2006.   pbBuf = malloc(ulNeeded);
  2007.   ulBufSize = ulNeeded ;
  2008.  
  2009.   /* Get the information available */
  2010.   splerr = SplEnumDevice(pszSrvName,
  2011.                          LEVEL_3,
  2012.                          pbBuf,
  2013.                          ulBufSize,
  2014.                          &ulReturned,
  2015.                          &ulTotal,
  2016.                          &ulNeeded,
  2017.                          NULL);
  2018.  
  2019.   /* If no errors, return the information available into stem variable */
  2020.   if(splerr == NO_ERROR)
  2021.   {
  2022.    for (i=0;i < ulReturned; i++)
  2023.    {
  2024.     pprd3 = (PPRDINFO3) pbBuf + i;      /* Point to the info structure */
  2025.     if(ulStat == 1)
  2026.     {
  2027.      sprintf(szStatusBuf, "No status available");
  2028.  
  2029.      fstatus = PRD_STATUS_MASK & pprd3->fsStatus;
  2030.  
  2031.      if( (fstatus & PRD_ACTIVE) == PRD_ACTIVE)
  2032.       sprintf(szStatusBuf, "Processing");
  2033.      if( (fstatus & PRD_PAUSED) == PRD_PAUSED)
  2034.       sprintf(szStatusBuf, "Not processing, or paused");
  2035.  
  2036.      fstatus = PRJ_DEVSTATUS & pprd3->fsStatus;
  2037.  
  2038.      if( (fstatus & PRJ_COMPLETE) == PRJ_COMPLETE)
  2039.       sprintf(szStatusBuf, "Job complete");
  2040.      if( (fstatus & PRJ_INTERV) == PRJ_INTERV)
  2041.       sprintf(szStatusBuf, "Intervention required");
  2042.      if( (fstatus & PRJ_ERROR) == PRJ_ERROR)
  2043.       sprintf(szStatusBuf, "Error occurred");
  2044.      if( (fstatus & PRJ_DESTOFFLINE) == PRJ_DESTOFFLINE)
  2045.       sprintf(szStatusBuf, "Print device offline");
  2046.      if( (fstatus & PRJ_DESTPAUSED) == PRJ_DESTPAUSED)
  2047.       sprintf(szStatusBuf, "Print device paused");
  2048.      if( (fstatus & PRJ_NOTIFY) == PRJ_NOTIFY)
  2049.       sprintf(szStatusBuf, "Raise alert");
  2050.      if( (fstatus & PRJ_DESTNOPAPER) == PRJ_DESTNOPAPER)
  2051.       sprintf(szStatusBuf, "Print device out of paper");
  2052.      if(strlen(pprd3->pszLogAddr) == 0)
  2053.      {
  2054.      sprintf(szWorkBuf, "Logical_Address: -none-   Status: %s", szStatusBuf);
  2055.      }
  2056.      else
  2057.      {
  2058.      sprintf(szWorkBuf, "Logical_Address: %8s Status: %s",
  2059.        pprd3->pszLogAddr, szStatusBuf);
  2060.      }
  2061.     }
  2062.     else
  2063.     {
  2064.      if(strlen(pprd3->pszLogAddr) == 0)
  2065.      {
  2066.      sprintf(szWorkBuf,
  2067.       "PrinterName: %s Logical_Address: -none-   Status: %X Drivers_supported: %s",
  2068.        pprd3->pszPrinterName,
  2069.        pprd3->fsStatus, pprd3->pszDrivers);
  2070.      }
  2071.      else
  2072.      {
  2073.      sprintf(szWorkBuf,
  2074.       "PrinterName: %s Logical_Address: %8s Status: %X Drivers_supported: %s",
  2075.        pprd3->pszPrinterName, pprd3->pszLogAddr,
  2076.        pprd3->fsStatus, pprd3->pszDrivers);
  2077.      }
  2078.     }
  2079.  
  2080.     ulRc = insertStem(rxs, szWorkBuf);
  2081.  
  2082.     if( ulRc != VALID_ROUTINE)
  2083.     {
  2084.      free(pbBuf);
  2085.      return INVALID_ROUTINE;
  2086.     }
  2087.  
  2088.    } /* end for */
  2089.   } /* if(splerr == NO_ERROR) */
  2090.  
  2091.   free(pbBuf);
  2092.  
  2093.  } /* end if( (splerr == ERROR_MORE_DATA) || */
  2094.  
  2095.  *ulRcode = splerr;
  2096.  
  2097.  ulRc = lastInStem(rxs);
  2098.  if( ulRc != VALID_ROUTINE)
  2099.   return INVALID_ROUTINE;
  2100.  
  2101.  return VALID_ROUTINE;                   /* OK!  */
  2102.  
  2103. }
  2104.  
  2105. /*********************************************************************/
  2106. /* Get Servers enumerated                                            */
  2107. /*********************************************************************/
  2108. ULONG getServerEnum2(PULONG ulRcode, PSZ pszDomain,
  2109.                      RXSTEMDATA1 * rxs, ULONG ulSrvType)
  2110. {
  2111.  
  2112.  ULONG  ulRc;                       /* Temporary return code         */
  2113.  PBYTE  pbBuf;                      /* Pointer to buffer             */
  2114.  USHORT usBufLen;                   /* Buffer length                 */
  2115.  USHORT usEntriesRead;              /* # entries returned in buffer  */
  2116.  USHORT usTotalEntries;             /* Total # entries               */
  2117.  ULONG  i;                          /* Loop variable                 */
  2118.  struct server_info_0 * pSrvInfo0;  /* Server info 0 pointer         */
  2119.  UCHAR  szBuf[64];                  /* Working buffer                */
  2120.  
  2121.  usBufLen = 0;
  2122.  ulRc = NetServerEnum2("", LEVEL_0, pbBuf, usBufLen, &usEntriesRead,
  2123.                        &usTotalEntries, ulSrvType, pszDomain);
  2124.  
  2125.  /* If ERROR_MORE_DATA or NERR_BufTooSmall continue */
  2126.  if( (ulRc == ERROR_MORE_DATA) || (ulRc == NERR_BufTooSmall) )
  2127.  {
  2128.   usBufLen = usTotalEntries * sizeof(struct server_info_0);
  2129.   pbBuf = malloc(usBufLen);
  2130.   ulRc = NetServerEnum2("", LEVEL_0, pbBuf, usBufLen, &usEntriesRead,
  2131.                         &usTotalEntries, ulSrvType, pszDomain);
  2132.   if(ulRc == NO_ERROR)
  2133.   {
  2134.    for (i=0;i < usEntriesRead; i++)
  2135.    {
  2136.     /* Point to the info structure */
  2137.     pSrvInfo0 = (struct server_info_0 *) pbBuf + i;
  2138.     sprintf(szBuf, "\\\\%s", pSrvInfo0->sv0_name);
  2139.  
  2140.     ulRc = insertStem(rxs, szBuf);
  2141.     if( ulRc != VALID_ROUTINE)
  2142.     {
  2143.      free(pbBuf);
  2144.      return INVALID_ROUTINE;
  2145.     }
  2146.  
  2147.    } /* end for( ;; ) */
  2148.   } /* end  if(ulRc == NO_ERROR) */
  2149.  
  2150.   free(pbBuf);
  2151.  
  2152.  }
  2153.  
  2154.  *ulRcode = ulRc;                        /* Set return value */
  2155.  
  2156.  ulRc = lastInStem(rxs);                 /* Make stem variable ready */
  2157.  if( ulRc != VALID_ROUTINE)
  2158.   return INVALID_ROUTINE;
  2159.  
  2160.  return VALID_ROUTINE;                   /* OK!  */
  2161.  
  2162. }
  2163.  
  2164. /*********************************************************************/
  2165. /* Get Applications enumerated                                       */
  2166. /*********************************************************************/
  2167. ULONG getAppEnum(PULONG ulRcode, PSZ pszDcName, RXSTEMDATA1 * rxs,
  2168.                  ULONG ulAppType)
  2169. {
  2170.  
  2171.  struct user_info_0 * pUserInfo0;   /* User information, level 0 */
  2172.  struct app_info_0  * pAppInfo0;    /* App information, level 0  */
  2173.  
  2174.  ULONG  ulRc;
  2175.  USHORT usUserList, usBuflen;       /* Memory structure sizes    */
  2176.  USHORT uswrite, usRc;
  2177.  USHORT usEntriesRead, usTotalAvail; /* Number of entries read and */
  2178.                                     /* the total number */
  2179.  PBYTE  pbBuf;                      /* Pointer to buffer             */
  2180.  INT    i, j;                       /* Loop counters */
  2181.  UCHAR  szBuf[64];                  /* Working buffer  */
  2182.  USHORT usUsrEntriesRead;           /* Number of user Ids read */
  2183.  
  2184.  switch(ulAppType)
  2185.  {
  2186.   case PUBDOS:
  2187.   case PUBOS2:
  2188.    /* Determine the number of entries */
  2189.    usBuflen = 0;
  2190.    ulRc = NetAppEnum (pszDcName, NULL, LEVEL_0, (USHORT) ulAppType,
  2191.                       pbBuf, usBuflen, &usEntriesRead, &usTotalAvail);
  2192.  
  2193.    /* If ERROR_MORE_DATA or NERR_BufTooSmall continue */
  2194.    if( (ulRc == ERROR_MORE_DATA) || (ulRc == NERR_BufTooSmall) )
  2195.    {
  2196.     /* Get the entries */
  2197.     usBuflen = usTotalAvail * sizeof(struct app_info_0);
  2198.     pbBuf = malloc(usBuflen);
  2199.     ulRc = NetAppEnum (pszDcName, NULL, LEVEL_0, (USHORT) ulAppType,
  2200.                        pbBuf, usBuflen, &usEntriesRead, &usTotalAvail);
  2201.  
  2202.     if(ulRc == NO_ERROR)
  2203.     {
  2204.      for (i=0;i < usEntriesRead; i++)
  2205.      {
  2206.       /* Point to the info structure */
  2207.       pAppInfo0 = (struct app_info_0 *) pbBuf + i;
  2208.  
  2209.       if (ulAppType == PUBDOS)
  2210.        sprintf(szBuf, "%10s  Public DOS", pAppInfo0->app0_name);
  2211.       else
  2212.        sprintf(szBuf, "%10s  Public OS/2", pAppInfo0->app0_name);
  2213.  
  2214.       ulRc = insertStem(rxs, szBuf);
  2215.       if( ulRc != VALID_ROUTINE)
  2216.       {
  2217.        free(pbBuf);
  2218.        return INVALID_ROUTINE;
  2219.       }
  2220.  
  2221.      } /* end for( ;; ) */
  2222.     } /* end  if(ulRc == NO_ERROR) */
  2223.  
  2224.     free(pbBuf);
  2225.    }
  2226.  
  2227.    break;
  2228.  
  2229.   case PRIVATE:
  2230.    /* Get a list of users */
  2231.    usUserList = 3119 * sizeof(struct user_info_0); /*Get up to seg size*/
  2232.    pUserInfo0 = malloc(usUserList);        /* Get memory */
  2233.    ulRc = NetUserEnum(pszDcName,          /* The server name */
  2234.                       LEVEL_0,             /* Get just the names */
  2235.                       (char *) pUserInfo0, /* Place in buffer */
  2236.                       usUserList,          /* The buffer size */
  2237.                       &usUsrEntriesRead,   /* Number of entries read */
  2238.                       &usTotalAvail);   /* Number of entries available */
  2239.  
  2240.    if(ulRc == 0)
  2241.    {
  2242.     /* Obtain information for each user ID found */
  2243.     usBuflen = 1024 * sizeof(struct app_info_0);
  2244.     pbBuf = malloc(usBuflen);
  2245.  
  2246.     for(i=0; i < usUsrEntriesRead; i++)
  2247.     {
  2248.      ulRc = NetAppEnum (pszDcName, pUserInfo0->usri0_name, LEVEL_0,
  2249.                         (USHORT) ulAppType, pbBuf, usBuflen,
  2250.                         &usEntriesRead, &usTotalAvail);
  2251.  
  2252.      if(ulRc == NO_ERROR)
  2253.      {
  2254.       for (j=0;j < usEntriesRead; j++)
  2255.       {
  2256.        /* Point to the info structure */
  2257.        pAppInfo0 = (struct app_info_0 *) pbBuf + j;
  2258.  
  2259.        sprintf(szBuf, "%10s  Private, UserID= %8s", \
  2260.                       pAppInfo0->app0_name, \
  2261.                       pUserInfo0->usri0_name);
  2262.  
  2263.        ulRc = insertStem(rxs, szBuf);
  2264.        if( ulRc != VALID_ROUTINE)
  2265.        {
  2266.         free(pbBuf);
  2267.         free(pUserInfo0);
  2268.         return INVALID_ROUTINE;
  2269.        }
  2270.  
  2271.       } /* end for(j ;; ) */
  2272.      } /* end  if(ulRc == NO_ERROR) */
  2273.      else
  2274.      {
  2275.       if( (ulRc != ERROR_FILE_NOT_FOUND) && (ulRc != ERROR_PATH_NOT_FOUND) )
  2276.       {
  2277.        sprintf(szBuf,"%d Error obtaining Applcation info for %8s", ulRc, pUserInfo0->usri0_name);
  2278.        ulRc = insertStem(rxs, szBuf);
  2279.        if( ulRc != VALID_ROUTINE)
  2280.        {
  2281.         free(pbBuf);
  2282.         free(pUserInfo0);
  2283.         return INVALID_ROUTINE;
  2284.        }
  2285.       }
  2286.      }
  2287.      pUserInfo0++;
  2288.     } /* end for(i=0; i < usEntriesRead; i++) */
  2289.  
  2290.     free(pUserInfo0);
  2291.  
  2292.    }
  2293.    free(pbBuf);
  2294.    break;
  2295.  
  2296.   default:
  2297.    *ulRcode = NERR_AppNotFound;
  2298.    return VALID_ROUTINE;
  2299.    break;
  2300.  }
  2301.  
  2302.  if( (ulRc == ERROR_FILE_NOT_FOUND) || (ulRc == ERROR_PATH_NOT_FOUND) )
  2303.   ulRc = 0;   /* Make a good return here */
  2304.  
  2305.  *ulRcode = ulRc;
  2306.  
  2307.  ulRc = lastInStem(rxs);                 /* Take care of stem variable */
  2308.  if( ulRc != VALID_ROUTINE)
  2309.   return INVALID_ROUTINE;
  2310.  
  2311.  return VALID_ROUTINE;                   /* OK!  */
  2312.  
  2313. }
  2314.  
  2315. /*********************************************************************/
  2316. /* Get Applications enumerated and get access control profile        */
  2317. /*********************************************************************/
  2318. ULONG getAppEnumAcp(PULONG ulRcode, PSZ pszDcName, PSZ pszUserId,
  2319.                     RXSTEMDATA1 * rxs)
  2320. {
  2321.  
  2322.  USHORT  usBuflen, usBytesAvail;
  2323.  UCHAR   szWorkBuf[80];              /* Working charater buffer       */
  2324.  UCHAR   szPathBuf[260];             /* Total path                    */
  2325.  ULONG   ulRc;
  2326.  struct  app_info_2 * pAppInfo2;
  2327.  struct  alias_info_2 * pAliasInfo2; /* Alias information, level 2 */
  2328.  INT     i;
  2329.  
  2330.  struct sel_info {
  2331.    struct app_sel_info_1 *pAsiBuf;
  2332.    struct app_sel_list *pAslBuf;
  2333.  } selPointers;
  2334.  
  2335.  usBuflen = sizeof(struct app_sel_info_1);
  2336.  selPointers.pAsiBuf = malloc(usBuflen);
  2337.  usBytesAvail = 0;
  2338.  
  2339.  ulRc = NetUserGetAppSel(pszDcName,            /* The DC   */
  2340.                          pszUserId,            /* The Userid */
  2341.                          LEVEL_1,              /* level_1  */
  2342.                          APP_ALL,              /* The type */
  2343.                          (char *) (selPointers.pAsiBuf),  /* The buffer */
  2344.                          usBuflen,             /* Size of the structure */
  2345.                          &usBytesAvail);
  2346.  free(selPointers.pAsiBuf);
  2347.  
  2348.  if( (ulRc == ERROR_FILE_NOT_FOUND) || (ulRc == ERROR_PATH_NOT_FOUND) )
  2349.  {
  2350.   /* User has nothing defined, set ending values, and end this call */
  2351.   *ulRcode = 0;
  2352.   strcpy(szWorkBuf, "A=     -none-");
  2353.   ulRc = insertStem(rxs, szWorkBuf);
  2354.   if( ulRc != VALID_ROUTINE)
  2355.     return INVALID_ROUTINE;
  2356.  
  2357.   ulRc = lastInStem(rxs);
  2358.   if( ulRc != VALID_ROUTINE)
  2359.     return INVALID_ROUTINE;
  2360.  
  2361.   return VALID_ROUTINE;     /* done */
  2362.  
  2363.  }
  2364.  
  2365.  /* There was information available */
  2366.  if( ulRc == NERR_BufTooSmall )
  2367.  {
  2368.   /* We got something. Allocate the correct size, obtain information */
  2369.   usBuflen = usBytesAvail + sizeof(struct app_sel_list);
  2370.   selPointers.pAsiBuf = malloc(usBuflen); /* For 1 additional   */
  2371.   ulRc = NetUserGetAppSel(pszDcName,             /* The DC     */
  2372.                           pszUserId,            /* The Userid */
  2373.                           LEVEL_1,              /* level_1    */
  2374.                           APP_ALL,              /* All types  */
  2375.                           (char *) (selPointers.pAsiBuf),  /* The buffer */
  2376.                           usBuflen,             /* Size of the structure */
  2377.                           &usBytesAvail);
  2378.   if( ulRc == 0 )
  2379.   {
  2380.    /* Point to the first */
  2381.    selPointers.pAslBuf = (struct app_sel_list *) \
  2382.    ((struct app_sel_info_1 *) selPointers.pAsiBuf + 1);
  2383.  
  2384.    usBuflen = sizeof(struct alias_info_2) + MAXCOMMENTSZ + \
  2385.               PATHLEN + (MAXDEVENTRIES * DEVLEN) + 128;
  2386.    pAliasInfo2 = malloc(usBuflen);
  2387.  
  2388.    usBuflen = sizeof(struct app_info_2) + MAXCOMMENTSZ + 4 * PATHLEN;
  2389.    pAppInfo2 = malloc(usBuflen);
  2390.  
  2391.    for(i=0; i < selPointers.pAsiBuf->asi1_count; i++)
  2392.    {
  2393.     /* Get each application defined and determine the ACPs */
  2394.     if(selPointers.pAslBuf->asl_apptype == APP_OS2_PRIVATE)
  2395.      ulRc = NetAppGetInfo(pszDcName, pszUserId,
  2396.                           selPointers.pAslBuf->asl_appname,
  2397.                           LEVEL_2, (char *) pAppInfo2,
  2398.                           usBuflen, &usBytesAvail);
  2399.     else
  2400.      ulRc = NetAppGetInfo(pszDcName, NULL,
  2401.                           selPointers.pAslBuf->asl_appname,
  2402.                           LEVEL_2, (char *) pAppInfo2,
  2403.                           usBuflen, &usBytesAvail);
  2404.  
  2405.     if(ulRc == 0)
  2406.     {
  2407.      /* Application path */
  2408.      if( strchr(pAppInfo2->app2_app_alias_or_drv, ':') == NULL)
  2409.      {
  2410.       /* Got an alias */
  2411.       if( pAppInfo2->app2_app_path_to_dir[0] != '\0')
  2412.        strcpy(szPathBuf, pAppInfo2->app2_app_path_to_dir);
  2413.       else
  2414.        szPathBuf[0] = '\0';
  2415.  
  2416.       ulRc=getAliasAcp(pszDcName, pAppInfo2->app2_app_alias_or_drv, \
  2417.                        pszUserId, rxs, pAliasInfo2, szPathBuf, AN_APP);
  2418.  
  2419.       if( ulRc != VALID_ROUTINE)
  2420.       {
  2421.        free(selPointers.pAsiBuf);
  2422.        free(pAliasInfo2);
  2423.        free(pAppInfo2);
  2424.        return INVALID_ROUTINE;
  2425.       }
  2426.  
  2427.      }
  2428.      else
  2429.      {
  2430.       /* Got a drive */
  2431.       sprintf(szWorkBuf,"A=     %8s Local drive", \
  2432.              selPointers.pAslBuf->asl_appname);
  2433.  
  2434.       ulRc = insertStem(rxs, szWorkBuf);
  2435.  
  2436.       if( ulRc != VALID_ROUTINE)
  2437.       {
  2438.        free(selPointers.pAsiBuf);
  2439.        free(pAliasInfo2);
  2440.        free(pAppInfo2);
  2441.        return INVALID_ROUTINE;
  2442.       }
  2443.  
  2444.      }
  2445.      /* Working directory path */
  2446.      if( strchr(pAppInfo2->app2_wrkdir_alias_or_drv, ':') == NULL)
  2447.      {
  2448.       /* Got an alias maybe */
  2449.       if ( (pAppInfo2->app2_wrkdir_alias_or_drv == NULL) || \
  2450.            (pAppInfo2->app2_wrkdir_alias_or_drv[0] == '\0') )
  2451.       {
  2452.        sprintf(szWorkBuf,"A=     %8s No working directory specified", \
  2453.               selPointers.pAslBuf->asl_appname);
  2454.  
  2455.        ulRc = insertStem(rxs, szWorkBuf);
  2456.  
  2457.        if( ulRc != VALID_ROUTINE)
  2458.        {
  2459.         free(selPointers.pAsiBuf);
  2460.         free(pAliasInfo2);
  2461.         free(pAppInfo2);
  2462.         return INVALID_ROUTINE;
  2463.        }
  2464.  
  2465.       }
  2466.       else
  2467.       {
  2468.        if( pAppInfo2->app2_wrkdir_path_to_dir[0] != '\0' )
  2469.         strcpy(szPathBuf, pAppInfo2->app2_wrkdir_path_to_dir);
  2470.        else
  2471.         szPathBuf[0] = '\0';
  2472.  
  2473.        ulRc=getAliasAcp(pszDcName, pAppInfo2->app2_wrkdir_alias_or_drv,
  2474.                         pszUserId, rxs, pAliasInfo2, szPathBuf, AN_APP);
  2475.  
  2476.        if( ulRc != VALID_ROUTINE)
  2477.        {
  2478.         free(selPointers.pAsiBuf);
  2479.         free(pAliasInfo2);
  2480.         free(pAppInfo2);
  2481.         return INVALID_ROUTINE;
  2482.        }
  2483.  
  2484.       }
  2485.  
  2486.      }
  2487.      else
  2488.      {
  2489.       /* Got a drive */
  2490.       sprintf(szWorkBuf,"A=     %8s Local drive", \
  2491.              selPointers.pAslBuf->asl_appname);
  2492.  
  2493.       ulRc = insertStem(rxs, szWorkBuf);
  2494.  
  2495.       if( ulRc != VALID_ROUTINE)
  2496.       {
  2497.        free(selPointers.pAsiBuf);
  2498.        free(pAliasInfo2);
  2499.        free(pAppInfo2);
  2500.        return INVALID_ROUTINE;
  2501.       }
  2502.  
  2503.      }
  2504.  
  2505.     } /* end if(ulRc == 0) */
  2506.  
  2507.     selPointers.pAslBuf++;
  2508.  
  2509.    } /* end for(i=0; i < selPointers.pAsiBuf->asi1_count; i++) */
  2510.  
  2511.    free(pAliasInfo2);
  2512.    free(pAppInfo2);
  2513.  
  2514.   } /* end if( usRc == 0 ) */
  2515.  
  2516.   free(selPointers.pAsiBuf);
  2517.  
  2518.  }
  2519.  
  2520.  if( (ulRc == ERROR_FILE_NOT_FOUND) || (ulRc == ERROR_PATH_NOT_FOUND) )
  2521.   ulRc = 0;   /* Make a good return here */
  2522.  
  2523.  *ulRcode = ulRc;
  2524.  
  2525.  ulRc = lastInStem(rxs);                 /* Take care of stem variable */
  2526.  if( ulRc != VALID_ROUTINE)
  2527.   return INVALID_ROUTINE;
  2528.  
  2529.  return VALID_ROUTINE;                   /* OK!  */
  2530.  
  2531. }
  2532.  
  2533. /*********************************************************************/
  2534. /* Get Alias access control profile                                  */
  2535. /*********************************************************************/
  2536. ULONG getLasnAliasAcp(PULONG ulRcode, PSZ pszDcName, PSZ pszUserId,
  2537.                       RXSTEMDATA1 * rxs)
  2538. {
  2539.  
  2540. /* struct alias_info_1 * pAliasInfo1;  Alias information, level 1    */
  2541.  struct alias_info_2 * pAliasInfo2; /* Alias information, level 2    */
  2542.  USHORT usBuflen;                   /* Memory structure sizes        */
  2543.  USHORT usBytesAvail;
  2544.  ULONG  ulRc;
  2545.  UCHAR  szWorkBuf[80];              /* Working charater buffer       */
  2546.  UCHAR  szDevBuf[128];              /* Working device buffer       */
  2547.  UCHAR  szAcpBuf[32];               /* Access control string buffer  */
  2548.  INT    i;
  2549.  USHORT usEntriesread;
  2550.  USHORT usTotalentries;
  2551.  
  2552.  struct asn_info {
  2553.    struct logon_asn_info_1 *pLaiBuf;
  2554.    struct logon_asn_list *pLalBuf;
  2555.  } asnPointers;
  2556.  
  2557.  /* Logon assignments */
  2558.  usBuflen = sizeof(struct logon_asn_info_1);
  2559.  asnPointers.pLaiBuf = malloc(usBuflen);
  2560.  usBytesAvail = 0;
  2561.  ulRc = NetUserGetLogonAsn(pszDcName,            /* The DC   */
  2562.                            pszUserId,            /* The Userid */
  2563.                            LEVEL_1,              /* level_1  */
  2564.                            7,                    /* The type */
  2565.                            (char *) (asnPointers.pLaiBuf),  /* The buffer */
  2566.                            usBuflen,             /* Size of the structure */
  2567.                            &usBytesAvail);
  2568.  free(asnPointers.pLaiBuf);
  2569.  
  2570.  /* There was information available */
  2571.  if( ulRc == NERR_BufTooSmall )
  2572.  {
  2573.   /* Allocate the correct size, obtain information */
  2574.   usBuflen = usBytesAvail;
  2575.   asnPointers.pLaiBuf = malloc(usBuflen); /* For all information*/
  2576.   ulRc = NetUserGetLogonAsn(pszDcName,             /* The DC     */
  2577.                             pszUserId,             /* The Userid */
  2578.                             LEVEL_1,              /* level_1    */
  2579.                             7,                    /* All types  */
  2580.                             (char *) (asnPointers.pLaiBuf),  /* The buffer */
  2581.                             usBuflen,             /* Size of the structure */
  2582.                             &usBytesAvail);
  2583.   if( ulRc != 0 )
  2584.   {
  2585.    free(asnPointers.pLaiBuf);
  2586.    *ulRcode = ulRc;
  2587.   }
  2588.   else
  2589.   {
  2590.    /* Work with the information provided. */
  2591.    asnPointers.pLalBuf = (struct logon_asn_list *) \
  2592.    ((struct logon_asn_info_1 *) asnPointers.pLaiBuf + 1);
  2593.    /* Get storage for alias_info_2 structure */
  2594.    usBuflen = sizeof(struct alias_info_2) + MAXCOMMENTSZ + \
  2595.               PATHLEN + (MAXDEVENTRIES * DEVLEN) + 128;
  2596.    pAliasInfo2 = malloc(usBuflen);
  2597.  
  2598.    for(i=0; i < asnPointers.pLaiBuf->lai1_count; i++)
  2599.    {
  2600.     ulRc=getAliasAcp(pszDcName, asnPointers.pLalBuf->lal_alias, \
  2601.                      pszUserId, rxs, pAliasInfo2, NULL, 0);
  2602.  
  2603.     if( ulRc != VALID_ROUTINE)
  2604.     {
  2605.      free(asnPointers.pLaiBuf);
  2606.      return INVALID_ROUTINE;
  2607.     }
  2608.     asnPointers.pLalBuf++;
  2609.  
  2610.    } /* end for(i=0; i < asnPointers.pLaiBuf->lai1_count; i++) */
  2611.  
  2612.    free(pAliasInfo2);
  2613.  
  2614.   } /* end if( ulRc != 0 ) */
  2615.  
  2616.  free(asnPointers.pLaiBuf);
  2617.  
  2618.  } /* end if( ulRc == NERR_BufTooSmall ) */
  2619.  
  2620.  if( (ulRc == ERROR_FILE_NOT_FOUND) || (ulRc == ERROR_PATH_NOT_FOUND) )
  2621.   ulRc = 0;   /* Make a good return here */
  2622.  
  2623.  *ulRcode = ulRc;
  2624.  
  2625.  ulRc = lastInStem(rxs);
  2626.  if( ulRc != VALID_ROUTINE)
  2627.   return INVALID_ROUTINE;
  2628.  
  2629.  return VALID_ROUTINE;
  2630.  
  2631. }
  2632.  
  2633. /*********************************************************************/
  2634. /* Set access control permission to a string                         */
  2635. /*********************************************************************/
  2636. VOID setAcp(PSZ pszAcpBuf, USHORT usPermission)
  2637. {
  2638.  INT i;
  2639.  
  2640.  i = 0;
  2641.  if(usPermission == ACCESS_NONE)
  2642.   pszAcpBuf[i++] = 'N';
  2643.  
  2644.  if( (usPermission & ACCESS_READ) == ACCESS_READ)
  2645.   pszAcpBuf[i++] = 'R';
  2646.  
  2647.  if( (usPermission & ACCESS_WRITE) == ACCESS_WRITE)
  2648.   pszAcpBuf[i++] = 'W';
  2649.  
  2650.  if( (usPermission & ACCESS_CREATE) == ACCESS_CREATE)
  2651.   pszAcpBuf[i++] = 'C';
  2652.  
  2653.  if( (usPermission & ACCESS_EXEC) == ACCESS_EXEC)
  2654.   pszAcpBuf[i++] = 'X';
  2655.  
  2656.  if( (usPermission & ACCESS_DELETE) == ACCESS_DELETE)
  2657.   pszAcpBuf[i++] = 'D';
  2658.  
  2659.  if( (usPermission & ACCESS_PERM) == ACCESS_PERM)
  2660.   pszAcpBuf[i++] = 'P';
  2661.  
  2662.  if (i == 0)
  2663.   strcpy(pszAcpBuf, "Not Defined");
  2664.  else
  2665.   pszAcpBuf[i] = '\0';
  2666.  
  2667. }
  2668.  
  2669. /*********************************************************************/
  2670. /* Get alias access control profile                                  */
  2671. /*********************************************************************/
  2672. ULONG getAliasAcp(PSZ pszDcName, PSZ pszAlias, PSZ pszUserId,
  2673.                   RXSTEMDATA1 * rxs, struct alias_info_2 * pAliasInfo2,
  2674.                   PSZ pszPath, ULONG ulType)
  2675.  
  2676. {
  2677.  
  2678.  USHORT usBuflen, usBytesAvail, usPermission;
  2679.  ULONG  ulRc;
  2680.  UCHAR  szWorkBuf[80];              /* Working charater buffer       */
  2681.  UCHAR  szDevBuf[128];              /* Working device buffer       */
  2682.  UCHAR  szAcpBuf[32];               /* Access control string buffer  */
  2683.  UCHAR  szPathBuf[260];             /* Path buffer                 */
  2684.  
  2685.  usBuflen = sizeof(struct alias_info_2) + MAXCOMMENTSZ + \
  2686.             PATHLEN + (MAXDEVENTRIES * DEVLEN) + 128;
  2687.  /* Obtain alias information */
  2688.  ulRc = NetAliasGetInfo(pszDcName,
  2689.                         pszAlias,
  2690.                         LEVEL_2,
  2691.                         (char *) pAliasInfo2,
  2692.                         usBuflen,
  2693.                         &usBytesAvail);
  2694.  if( ulRc != 0 )
  2695.  {
  2696.   sprintf(szWorkBuf,"D=     %8s  Error getting alias information", pszAlias);
  2697.   ulRc = insertStem(rxs, szWorkBuf);
  2698.  
  2699.   if( ulRc != VALID_ROUTINE)
  2700.    return INVALID_ROUTINE;
  2701.  
  2702.  }
  2703.  else
  2704.  {
  2705.   /* Get the location. Can be external or internal */
  2706.   if(pAliasInfo2->ai2_location != ALIAS_LOCATION_INTERNAL)
  2707.   {
  2708.    if(ulType == AN_APP)
  2709.     sprintf(szWorkBuf,"A=     %8s External resource", pszAlias);
  2710.    else
  2711.     sprintf(szWorkBuf,"D=     %8s External resource", pszAlias);
  2712.  
  2713.    ulRc = insertStem(rxs, szWorkBuf);
  2714.    if( ulRc != VALID_ROUTINE)
  2715.     return INVALID_ROUTINE;
  2716.  
  2717.   }
  2718.   else
  2719.   {
  2720.    /* Need to get the access control profile. Obtain type */
  2721.    usPermission = -1;
  2722.    if(pAliasInfo2->ai2_type == ALIAS_TYPE_FILE)
  2723.    {
  2724.  
  2725.     strcpy(szPathBuf, pAliasInfo2->ai2_path);
  2726.     if(pszPath != NULL)
  2727.      if( (pszPath[0] != '\0') && (pszPath[0] != '\\') )
  2728.       strcat(szPathBuf, pszPath);
  2729.  
  2730.     ulRc = NetAccessGetUserPerms(pAliasInfo2->ai2_server,
  2731.                                  pszUserId,             /* The Userid */
  2732.                                  szPathBuf,
  2733.                                  &usPermission);
  2734.     if(ulRc == 0)
  2735.     {
  2736.      setAcp(szAcpBuf, usPermission);
  2737.      if(ulType == AN_APP)
  2738.       sprintf(szWorkBuf,"A=     %8s  %16s", pszAlias, szAcpBuf);
  2739.      else
  2740.       sprintf(szWorkBuf,"D=     %8s  %16s", pszAlias, szAcpBuf);
  2741.     }
  2742.     else
  2743.      if(ulType == AN_APP)
  2744.       sprintf(szWorkBuf,"A=     %8s  Error obtaining ACP", pszAlias);
  2745.      else
  2746.       sprintf(szWorkBuf,"D=     %8s  Error obtaining ACP", pszAlias);
  2747.  
  2748.     ulRc = insertStem(rxs, szWorkBuf);
  2749.     if( ulRc != VALID_ROUTINE)
  2750.      return INVALID_ROUTINE;
  2751.  
  2752.    } /* end if(pAliasInfo2->ai2_type == ALIAS_TYPE_FILE) */
  2753.  
  2754.    if(pAliasInfo2->ai2_type == ALIAS_TYPE_PRINTER)
  2755.    {
  2756.     strcpy(szDevBuf, "\\PRINT\\");
  2757.     strcat(szDevBuf, pAliasInfo2->ai2_queue);
  2758.  
  2759.     ulRc = NetAccessGetUserPerms(pAliasInfo2->ai2_server,
  2760.                                  pszUserId,             /* The Userid */
  2761.                                  szDevBuf,
  2762.                                  &usPermission);
  2763.     if(ulRc == 0)
  2764.     {
  2765.      setAcp(szAcpBuf, usPermission);
  2766.      if(ulType == AN_APP)
  2767.       sprintf(szWorkBuf,"A=     %8s  %16s", pszAlias, szAcpBuf);
  2768.      else
  2769.       sprintf(szWorkBuf,"D=     %8s  %16s", pszAlias, szAcpBuf);
  2770.     }
  2771.     else
  2772.      if(ulType == AN_APP)
  2773.       sprintf(szWorkBuf,"A=     %8s  Error obtaining ACP", pszAlias);
  2774.      else
  2775.       sprintf(szWorkBuf,"D=     %8s  Error obtaining ACP", pszAlias);
  2776.  
  2777.     ulRc = insertStem(rxs, szWorkBuf);
  2778.     if( ulRc != VALID_ROUTINE)
  2779.      return INVALID_ROUTINE;
  2780.  
  2781.    } /* end if(pAliasInfo2->ai2_type == ALIAS_TYPE_PRINTER) */
  2782.  
  2783.    if(pAliasInfo2->ai2_type == ALIAS_TYPE_SERIAL)
  2784.    {
  2785.     strcpy(szDevBuf, "\\COMM\\");
  2786.     strcat(szDevBuf, pAliasInfo2->ai2_queue);
  2787.  
  2788.     ulRc = NetAccessGetUserPerms(pAliasInfo2->ai2_server,
  2789.                                  pszUserId,             /* The Userid */
  2790.                                  szDevBuf,
  2791.                                  &usPermission);
  2792.  
  2793.     if(ulRc == 0)
  2794.     {
  2795.      setAcp(szAcpBuf, usPermission);
  2796.      if(ulType == AN_APP)
  2797.       sprintf(szWorkBuf,"A=     %8s  %16s", pszAlias, szAcpBuf);
  2798.      else
  2799.       sprintf(szWorkBuf,"D=     %8s  %16s", pszAlias, szAcpBuf);
  2800.     }
  2801.     else
  2802.      if(ulType == AN_APP)
  2803.       sprintf(szWorkBuf,"A=     %8s  Error obtaining ACP", pszAlias);
  2804.      else
  2805.       sprintf(szWorkBuf,"D=     %8s  Error obtaining ACP", pszAlias);
  2806.  
  2807.     ulRc = insertStem(rxs, szWorkBuf);
  2808.     if( ulRc != VALID_ROUTINE)
  2809.      return INVALID_ROUTINE;
  2810.  
  2811.    } /* end if(pAliasInfo2->ai2_type == ALIAS_TYPE_SERIAL) */
  2812.  
  2813.   } /* end if(pAliasInfo2->ai2_location != ALIAS_LOCATION_INTERNAL) */
  2814.  
  2815.  } /* if( ulRc != 0 ) */
  2816.  
  2817.  return VALID_ROUTINE;
  2818.  
  2819. }
  2820.