home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / lanserv / user32 / user32.c < prev    next >
C/C++ Source or Header  |  1998-10-01  |  34KB  |  1,026 lines

  1. /****************************************************************************/
  2. /*
  3.  *    PROGRAM NAME: USER32
  4.  *    ------------
  5.  *
  6.  *    What this program does:  Creates a new user; creates
  7.  *    a new alias, gives the user access to it, and makes it a
  8.  *    logon assignment for the user; creates a new group and
  9.  *    adds the user to it; creates a private application definition
  10.  *    and assigns it to the user.  Displays information about the user.
  11.  *    Deletes the user information.
  12.  *
  13.  *    SYNTAX:
  14.  *    ------
  15.  *    USER32 username
  16.  *      displays information about the user 'username'
  17.  *
  18.  *    USER32 username /add
  19.  *      adds a definition for the user 'username', adds username to
  20.  *      a new group, gives username logon and application assignments.
  21.  *
  22.  *    USER32 username /del
  23.  *      deletes the user definition for 'username'.
  24.  *
  25.  *    REQUIRED FILES:
  26.  *    --------------
  27.  *    USER32.C       -  Source code for this program
  28.  *
  29.  *    REQUIRED LIBRARIES:
  30.  *    ------------------
  31.  *    NETAPI32.LIB   -  Netapi library (in \IBMLAN\NETSRC\LIB directory)
  32.  *
  33.  *    NetAPI32 functions used in this program:
  34.  *    ---------------------------------------
  35.  *    Net32AccessAdd
  36.  *    Net32AccessGetInfo
  37.  *    Net32AccessSetInfo
  38.  *    Net32AliasAdd
  39.  *    Net32AliasDel
  40.  *    Net32AliasGetInfo
  41.  *    Net32AppAdd
  42.  *    Net32GetDCName
  43.  *    Net32GroupAdd
  44.  *    Net32GroupAddUser
  45.  *    Net32GroupDel
  46.  *    Net32GroupGetInfo
  47.  *    Net32ServerEnum2
  48.  *    Net32WkstaGetInfo
  49.  *    Net32UserAdd
  50.  *    Net32UserDCDBInit
  51.  *    Net32UserDel
  52.  *    Net32UserGetGroups
  53.  *    Net32UserGetInfo
  54.  *    Net32UserGetLogonAsn
  55.  *    Net32UserSetAppSel
  56.  *    Net32UserSetLogonAsn
  57.  *
  58.  *    HOW TO COMPILE THIS PROGRAM:
  59.  *    ---------------------------
  60.  *    icc /Gt+ /DPURE_32 user32.c
  61.  */
  62. /****************************************************************************/
  63.  
  64. /**************   Defines   *************************************************/
  65. #define    DISPLAY     0
  66. #define    ADD         1
  67. #define    DELETE      2
  68. #define    BUFFER_LEN  4096
  69. #define    INCL_DOSPROCESS
  70. #define    INCL_DOSMEMMGR
  71. #define    INCL_DOSERRORS
  72.  
  73. /**************   OS/2 include files ****************************************/
  74. #include <os2.h>
  75.  
  76. /**************   C-language include files   ********************************/
  77. #include <stdio.h>
  78. #include <string.h>
  79.  
  80. /**************   LAN Server include files   ********************************/
  81. #include <netcons.h>
  82. #include <neterr.h>
  83. #include <access.h>
  84. #include <dcdb.h>
  85. #include <server.h>
  86. #include <wksta.h>
  87.  
  88. /**************   Forward declarations of local functions   ******************/
  89. VOID Error_Message(USHORT, PSZ);
  90. VOID Syntax(VOID);
  91. VOID AddUser(char *);
  92. USHORT UserAdd(char *, char *, char *);
  93. USHORT AliasAdd(char *, char *, char *);
  94. USHORT GiveAccessToAlias(char *, char *, char *, char *);
  95. USHORT AddGroup(char *, char *, char *, char *);
  96. USHORT InitDCDBForUser(char *, char *);
  97. USHORT AddLogAsn(char *, char *, char *, char *);
  98. USHORT CreateApplication(char *, char *, char *, char *, char *);
  99. USHORT AssignAppToUser(char *, char *, char *, char *);
  100. VOID DeleteGroup(char *, char *);
  101. VOID DeleteAlias(char *, char *);
  102. VOID DeleteUser(char *, char *);
  103. VOID DisplayUserDetails(char *);
  104. VOID GetDCName(char *);
  105.  
  106. /**************   Main program   *********************************************/
  107. /*
  108.  * This function simply validates the command line arguments and
  109.  * then calls a worker function, based on command line input.
  110.  */
  111. VOID
  112. main(int argc, char *argv[])
  113. {
  114.     USHORT                 usFunction = DISPLAY;
  115.     CHAR                   pUser[UNLEN+1];
  116.  
  117.     /* Validate command line input */
  118.     if (argc < 2 || argc > 3)
  119.         Syntax();
  120.  
  121.     /* Verify that username is not too long. */
  122.     if (strlen(argv[1]) > UNLEN)
  123.         Syntax();
  124.  
  125.     /* If a command line switch was specified, it must be "/ADD" or "/DELETE" */
  126.     if (argc == 3)
  127.     {
  128.         if (!stricmp(argv[2], "/ADD"))
  129.             usFunction = ADD;
  130.         else if (!strnicmp(argv[2], "/DEL", strlen("/DEL")))
  131.             usFunction = DELETE;
  132.         else
  133.             Syntax();
  134.     }
  135.  
  136.     strcpy(pUser, argv[1]);
  137.  
  138.     /* Call the appropriate worker function. */
  139.     if (usFunction == ADD)
  140.         AddUser(pUser);
  141.     else if (usFunction == DELETE)
  142.         DeleteUser(pUser, NULL);
  143.     else
  144.         DisplayUserDetails(pUser);
  145.  
  146.      DosExit(EXIT_PROCESS, 0);
  147. }
  148.  
  149. /*
  150.  * This function takes the username specified on the command line as
  151.  * input and attempts to:
  152.  *  - Add a new definition for the username
  153.  *  - Create a new group definition, and add the user to it.
  154.  *  - Add a new files alias, "_DUMMYFA", and give the user access to it.
  155.  *  - Make the new alias a logon assignment for the user.
  156.  *  - Create a private application for the user, and assign it to the user.
  157.  *
  158.  * If any of the attempted actions fail, the previous actions are undone
  159.  * and the program ends.
  160.  */
  161. void
  162. AddUser(char *pUser)
  163. {
  164.     USHORT                     usRc;
  165.     PCHAR                      pBuffer;
  166.     CHAR                       pszDomainController[UNCLEN+1];
  167.  
  168.     /* Get the name of the domain controller for this domain. */
  169.     GetDCName(pszDomainController);
  170.  
  171.     usRc = DosAllocMem((PPVOID)&pBuffer,
  172.                        BUFFER_LEN,
  173.                        PAG_WRITE | PAG_READ | PAG_COMMIT);
  174.  
  175.     if (usRc)
  176.         Error_Message(usRc, "DosAllocMem");
  177.     else
  178.     {
  179.         memset(pBuffer, 0, BUFFER_LEN);
  180.  
  181.         /* Add a new user definition. */
  182.         if (!usRc)
  183.             usRc = UserAdd(pUser, pszDomainController, pBuffer);
  184.  
  185.         /* Create a new group, and add the user to it. */
  186.         if (!usRc)
  187.         {
  188.             printf("The user definition for \"%s\" was added successfully.\n",
  189.                     strupr(pUser));
  190.  
  191.             usRc = AddGroup(pszDomainController, pUser, "NEWGROUP", pBuffer);
  192.             if (usRc)
  193.                 DeleteUser(pUser, pszDomainController);
  194.             else
  195.                 printf("A new group, \"NEWGROUP\" was added successfully.\n");
  196.         }
  197.  
  198.         /* Attempt to create an new files alias, "_DUMMYFA". */
  199.         if (!usRc)
  200.         {
  201.             usRc = AliasAdd(pszDomainController, "_DUMMYFA", pBuffer);
  202.             if (usRc)
  203.                 DeleteUser(pUser, pszDomainController);
  204.             else
  205.                 printf("The alias \"_DUMMYFA\" was added successfully.\n");
  206.         }
  207.  
  208.         /* Give the user access to the new alias. */
  209.         if (!usRc)
  210.         {
  211.             usRc = GiveAccessToAlias(pUser,
  212.                                      pszDomainController,
  213.                                      "_DUMMYFA",
  214.                                      pBuffer);
  215.             if (usRc)
  216.             {
  217.                 DeleteUser(pUser, pszDomainController);
  218.             }
  219.         }
  220.  
  221.         /*
  222.          * Initialize the new user's domain control database area.
  223.          * This step must be done before private applications can
  224.          * be created for the user, and before any logon or application
  225.          * assignments can be made for the user.
  226.          */
  227.         if (!usRc)
  228.         {
  229.             usRc = InitDCDBForUser(pszDomainController, pUser);
  230.             if (usRc)
  231.             {
  232.                 DeleteUser(pUser, pszDomainController);
  233.             }
  234.             else
  235.                 printf("The domain control database structures for \"%s\" "\
  236.                        "were successfully created.\n", strupr(pUser));
  237.         }
  238.  
  239.         /* Add the new alias as a logon assignment. */
  240.         if (!usRc)
  241.         {
  242.             usRc = AddLogAsn(pUser, pszDomainController, "_DUMMYFA", pBuffer);
  243.             if (usRc)
  244.             {
  245.                 DeleteUser(pUser, pszDomainController);
  246.             }
  247.             else
  248.                 printf("A logon assignment for \"%s\" was added successfully.\n",
  249.                         strupr(pUser));
  250.         }
  251.  
  252.         /* Create a private application for the user. */
  253.         if (!usRc)
  254.         {
  255.             usRc = CreateApplication(pUser,
  256.                                      "DUMMYAPP",
  257.                                      "_DUMMYFA",
  258.                                      pszDomainController,
  259.                                      pBuffer);
  260.             if (usRc)
  261.             {
  262.                 DeleteUser(pUser, pszDomainController);
  263.             }
  264.             else
  265.                 printf("A private application for user \"%s\" "\
  266.                        "was created successfully.\n", strupr(pUser));
  267.         }
  268.  
  269.         /* Assign the new application to the user. */
  270.         if (!usRc)
  271.         {
  272.             usRc = AssignAppToUser(pUser, pszDomainController, "DUMMYAPP", pBuffer);
  273.             if (usRc)
  274.             {
  275.                 DeleteUser(pUser, pszDomainController);
  276.             }
  277.             else
  278.                 printf("The new private application was successfully "\
  279.                        "assigned to \"%s\".\n", strupr(pUser));
  280.         }
  281.  
  282.         /* Free the buffer. */
  283.         DosFreeMem((PVOID)pBuffer);
  284.     }
  285.  
  286.     if (usRc)
  287.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  288.  
  289.     return;
  290.  
  291. }
  292.  
  293. /*
  294.  * DeleteUser() calls the Net32UserDel API to delete a user definition.
  295.  * The Net32UserDel API will delete any domain control database structures
  296.  * associated with the user, including logon assignment information,
  297.  * application assignment information, and definitions of any private
  298.  * applications the user may have defined, as well as deleting the
  299.  * user definition from the network accounts file, NET.ACC.
  300.  *
  301.  * Note that the Net32UserDel() API not only deletes the definition
  302.  * of a user, but also:
  303.  * - deletes any existing domain control database directories and files,
  304.  *   thus deleting all of the user's logon assignments, application
  305.  *   assignments, and private application definitions.
  306.  * - deletes any access control entries for the user.
  307.  * - deletes the user from any groups he was a member of.
  308.  *
  309.  * A new group and a new alias may have been added before this routine is
  310.  * called; to clean up, the group and the alias are deleted if they exist.
  311.  */
  312. void
  313. DeleteUser(char *pszUser, char *pszDCName)
  314. {
  315.     USHORT             usRc;
  316.     CHAR               pszServer[UNCLEN+1];
  317.     CHAR               pBuffer[GNLEN+1];
  318.     ULONG              ulBytesAvailable;
  319.  
  320.     /*
  321.      * This routine is called in two instances: in one case,
  322.      * the domain controller name is known; in the other case,
  323.      * it is not known.  If it is not known, the caller passes
  324.      * in a NULL pointer so the function knows to determine
  325.      * the dc name before proceeding.
  326.      */
  327.     if (pszDCName == NULL)
  328.     {
  329.         GetDCName(pszServer);
  330.     }
  331.  
  332.     usRc = Net32UserDel(pszDCName ? pszDCName : pszServer,
  333.                         pszUser,
  334.                         NULL);
  335.  
  336.     if (usRc)
  337.         Error_Message(usRc, "Net32UserDel");
  338.     else
  339.         printf("The definition of \"%s\" was successfully deleted.\n",
  340.                strupr(pszUser));
  341.  
  342.     /* See if the group NEWGROUP exists.  If so, delete it. */
  343.     usRc = Net32GroupGetInfo(pszDCName ? pszDCName : pszServer,
  344.                              "NEWGROUP",
  345.                              0L,
  346.                              pBuffer,
  347.                              GNLEN+1,
  348.                              &ulBytesAvailable,
  349.                              0L);
  350.  
  351.     if (!usRc)
  352.         DeleteGroup("NEWGROUP", pszDCName ? pszDCName : pszServer);
  353.  
  354.     /* See if the alias _DUMMYFA exists.  If so, delete it. */
  355.     usRc = Net32AliasGetInfo(pszDCName ? pszDCName : pszServer,
  356.                              "_DUMMYFA",
  357.                              0L,
  358.                              pBuffer,
  359.                              GNLEN+1,
  360.                              &ulBytesAvailable,
  361.                              0L);
  362.  
  363.     if (!usRc)
  364.         DeleteAlias("_DUMMYFA", pszDCName ? pszDCName : pszServer);
  365.  
  366.     return;
  367. }
  368.  
  369. void
  370. DisplayUserDetails(char *pszUser)
  371. {
  372.     USHORT                      usRc,
  373.                                 usCount;
  374.     ULONG                       ulTotalEntries,
  375.                                 ulAvailable;
  376.     PCHAR                       pBuffer;
  377.     struct user_info_11        *pUserInfo;
  378.     struct group_info_0        *pGroups;
  379.     struct logon_asn_list      *pLogList;
  380.     CHAR                        pszDC[UNCLEN + 1];
  381.  
  382.     /* allocate a buffer for the Net32UserGetInfo call */
  383.     usRc = DosAllocMem((PPVOID)&pBuffer,
  384.                        4096,
  385.                        PAG_WRITE | PAG_READ | PAG_COMMIT);
  386.  
  387.     if (usRc)
  388.     {
  389.         Error_Message(usRc, "DosAllocMem");
  390.         return;
  391.     }
  392.  
  393.     /* Get the name of the domain controller. */
  394.     GetDCName(pszDC);
  395.  
  396.     /*
  397.      * We arbitrarily decide to get the amount of information available
  398.      * in the user_info_11 structure.  More information is available
  399.      * to administrators in the user_info_2 structure.
  400.      */
  401.     usRc = Net32UserGetInfo(pszDC,
  402.                             pszUser,
  403.                             11,
  404.                             pBuffer,
  405.                             4096,
  406.                             &ulAvailable,
  407.                             NULL);
  408.  
  409.     if (usRc)
  410.         Error_Message(usRc, "Net32UserGetInfo");
  411.     else
  412.     {
  413.         /* Display selected portions of the user_info_11 structure... */
  414.         pUserInfo = (struct user_info_11 *)pBuffer;
  415.         printf("Details for user %s:\n\n", pUserInfo -> usri11_name);
  416.         printf("   Comment: %s\n", pUserInfo -> usri11_comment);
  417.         printf("   User comment: %s\n", pUserInfo -> usri11_usr_comment);
  418.         printf("   Full Name: %s\n", pUserInfo -> usri11_full_name);
  419.         printf("   Privilege level: %s\n",
  420.                 pUserInfo -> usri11_priv == USER_PRIV_GUEST ? "Guest" :
  421.                 (pUserInfo -> usri11_priv == USER_PRIV_USER ? "User" :
  422.                  "Administrator"));
  423.         printf("   Home directory: %s\n", pUserInfo -> usri11_home_dir);
  424.         printf("   Preferred logon server: ");
  425.         if (!pUserInfo -> usri11_logon_server ||
  426.             *pUserInfo -> usri11_logon_server == '\0')
  427.             printf("Domain controller\n");
  428.         else if (strcmp(pUserInfo -> usri11_logon_server, "\\\\*"))
  429.             printf("Any server\n");
  430.         else
  431.             printf("%s\n", pUserInfo -> usri11_logon_server);
  432.  
  433.         /* Now, get group membership information for this user. */
  434.         usRc = Net32UserGetGroups(pszDC,
  435.                                pszUser,
  436.                                0,
  437.                                pBuffer,
  438.                                4096,
  439.                                &ulAvailable,
  440.                                &ulTotalEntries,
  441.                                NULL);
  442.  
  443.         if (usRc)
  444.             Error_Message(usRc, "Net32UserGetGroups");
  445.         else
  446.         {
  447.             /* print group memberships */
  448.             usCount = (USHORT)ulAvailable;
  449.             pGroups = (struct group_info_0 *)pBuffer;
  450.             printf("\nUser \"%s\" belongs to the following groups:\n",
  451.                     strupr(pszUser));
  452.             while (usCount)
  453.             {
  454.                 printf("\t%s\n", pGroups -> grpi0_name);
  455.                 --usCount;
  456.                 ++pGroups;
  457.             }
  458.  
  459.             /*
  460.              * print logon assignment information...get only
  461.              * assignments to files aliases.
  462.              */
  463.             usRc = Net32UserGetLogonAsn(pszDC,
  464.                                         pszUser,
  465.                                         1,
  466.                                         ALIAS_TYPE_FILE,
  467.                                         pBuffer,
  468.                                         4096,
  469.                                         &ulAvailable,
  470.                                         NULL);
  471.  
  472.             if (usRc == ERROR_PATH_NOT_FOUND)
  473.                 printf("The domain control database directory "\
  474.                        "for \"%s\" was not found.\n", strupr(pszUser));
  475.             else if (usRc)
  476.                 Error_Message(usRc, "Net32UserGetLogonAsn");
  477.             else
  478.             {
  479.                 usCount = ((struct logon_asn_info_1 *)pBuffer) -> lai1_count;
  480.                 if (usCount == 0)
  481.                     printf("\n\"%s\" has no files logon assignments.\n",
  482.                             strupr(pszUser));
  483.                 else
  484.                 {
  485.                     pLogList =
  486.                      (struct logon_asn_list *)(pBuffer + sizeof(struct logon_asn_info_1));
  487.  
  488.                     printf("\nLogon assignments for user \"%s\":\n",
  489.                            strupr(pszUser));
  490.                     while (usCount)
  491.                     {
  492.                         printf("\t%-8.8s   %-8.8s\n",
  493.                                 pLogList -> lal_alias,
  494.                                 pLogList -> lal_device);
  495.  
  496.                         ++pLogList;
  497.                         --usCount;
  498.                     }
  499.                 }
  500.             }
  501.             /*
  502.              * This routine does not display application assignment
  503.              * information.  This information can be obtained by
  504.              * a call to Net32UserGetAppSel().
  505.              */
  506.         }
  507.     }
  508.     DosFreeMem((PVOID)pBuffer);
  509.     return;
  510. }
  511.  
  512. void
  513. GetDCName(char *pszDCName)
  514. {
  515.     USHORT                 usRc;
  516.     ULONG                  ulEntriesReturned,
  517.                            ulAvailable;
  518.     PCHAR                  pBuffer;
  519.     struct wksta_info_10  *pWkstaInf;
  520.  
  521.     /* Allocate a buffer to get local requester information. */
  522.     usRc = DosAllocMem((PPVOID)&pBuffer,
  523.                        4096,
  524.                        PAG_READ | PAG_WRITE | PAG_COMMIT);
  525.  
  526.     if (usRc)
  527.         Error_Message(usRc, "DosAllocMem");
  528.  
  529.     /*
  530.      * Get the name of the domain this machine is logged onto.
  531.      */
  532.     usRc = Net32WkstaGetInfo(NULL,
  533.                              10,
  534.                              pBuffer,
  535.                              1024,
  536.                              &ulAvailable);
  537.  
  538.     if (usRc)
  539.     {
  540.         Error_Message(usRc, "Net32WkstaGetInfo");
  541.         DosFreeMem((PVOID)pBuffer);
  542.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  543.     }
  544.  
  545.     pWkstaInf = (struct wksta_info_10 *)pBuffer;
  546.  
  547.     if (!pWkstaInf -> wki10_logon_domain ||
  548.         !(*pWkstaInf -> wki10_logon_domain))
  549.     {
  550.         printf("Net32WkstaGetInfo: cannot determine logon domain.\n");
  551.         DosFreeMem((PVOID)pBuffer);
  552.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  553.     }
  554.  
  555.     /*
  556.      * Call Net32ServerEnum2 to get the name of the domain controller.
  557.      * Note that the buffer is only large enough to hold one servername,
  558.      * since only one domain controller per domain is expected.
  559.      * Net32ServerEnum2 returns a servername without leading backslashes,
  560.      * so the code must explicitly insert the backslashes in the buffer.
  561.      */
  562.     *pszDCName = *(pszDCName+1) = '\\';
  563.  
  564.     usRc = Net32ServerEnum2(NULL,
  565.                             1,
  566.                             pszDCName,
  567.                             UNCLEN - 1,
  568.                             &ulEntriesReturned,
  569.                             &ulAvailable,
  570.                             SV_TYPE_DOMAIN_CTRL,
  571.                             pWkstaInf -> wki10_logon_domain);
  572.  
  573.     /*
  574.      * If an error was returned or the number of entries
  575.      * returned is not one, try another method of finding
  576.      * the domain controller name.
  577.      */
  578.     if (usRc || ulEntriesReturned != 1)
  579.     {
  580.         usRc = Net32GetDCName(NULL,
  581.                               pWkstaInf -> wki10_logon_domain,
  582.                               pszDCName,
  583.                               UNCLEN+1);
  584.     }
  585.  
  586.     DosFreeMem((PVOID)pBuffer);
  587.  
  588.     if (usRc)
  589.     {
  590.         printf("Unable to determine domain controller name.\n");
  591.         Error_Message(usRc, "Net32GetDCName");
  592.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  593.     }
  594.  
  595.     return;
  596. }
  597.  
  598. VOID
  599. DeleteGroup(char *pszGroupName, char *pszDCName)
  600. {
  601.     USHORT             usRc;
  602.  
  603.     usRc = Net32GroupDel(pszDCName,
  604.                          pszGroupName,
  605.                          NULL);
  606.  
  607.     if (usRc)
  608.         Error_Message(usRc, "Net32GroupDel");
  609.     else
  610.         printf("The definition of group %s was deleted successfully.\n",
  611.                 pszGroupName);
  612.  
  613.     return;
  614. }
  615.  
  616. VOID
  617. DeleteAlias(char *pszAliasName, char *pszDCName)
  618. {
  619.     USHORT             usRc;
  620.  
  621.     usRc = Net32AliasDel(pszDCName,
  622.                          pszAliasName,
  623.                          0L,
  624.                          NULL);
  625.  
  626.     if (usRc)
  627.         Error_Message(usRc, "Net32AliasDel");
  628.     else
  629.         printf("The definition of alias %s was deleted successfully.\n",
  630.                 pszAliasName);
  631.  
  632.     return;
  633. }
  634.  
  635. VOID
  636. Syntax()
  637. {
  638.     printf("Usage:\n");
  639.     printf("   USER32 <username> -- displays information about <username>\n");
  640.     printf("   USER32 <username> /ADD -- adds a user definition for <username>\n");
  641.     printf("   USER32 <username> /DELETE -- deletes the defintion of <username>\n");
  642.     DosExit(EXIT_PROCESS, 1);
  643. }
  644.  
  645. USHORT
  646. UserAdd(char *pszUser, char *pszDCName, char *pBuffer)
  647. {
  648.     USHORT                      usRc;
  649.     struct user_info_2         *pUserInfo = (struct user_info_2 *)pBuffer;
  650.     CHAR                        pszHomeDir[UNCLEN + 1 + 2 + 1 + UNLEN + 1];
  651.  
  652.     /*
  653.      * Fill in the user_info_2 structure: we're creating
  654.      * a normal user with no password, and a home directory
  655.      * on the domain controller.
  656.      */
  657.     memset(pBuffer, 0, BUFFER_LEN);
  658.  
  659.     strcpy(pUserInfo -> usri2_name, pszUser);
  660.  
  661.     /* The user has no password */
  662.     *pUserInfo -> usri2_password = '\0';
  663.  
  664.     /* The user has 'normal' user privilege. */
  665.     pUserInfo -> usri2_priv = USER_PRIV_USER;
  666.  
  667.     /* set up the home directory string */
  668.     strcpy(pszHomeDir, pszDCName);
  669.     strcat(pszHomeDir, "\\C$\\");
  670.     strcat(pszHomeDir, pszUser);
  671.  
  672.     /*
  673.      * The user's home directory is the C:\<username> directory,
  674.      * on the domain controller.
  675.      */
  676.     pUserInfo -> usri2_home_dir = pszHomeDir;
  677.  
  678.     pUserInfo -> usri2_comment =
  679.     pUserInfo -> usri2_usr_comment = "userid added by USER sample program";
  680.  
  681.     /* A password is not required for this user. */
  682.     pUserInfo -> usri2_flags = UF_SCRIPT | UF_PASSWD_NOTREQD;
  683.     pUserInfo -> usri2_full_name = "This isn't a real user!";
  684.  
  685.     /* The user's account never expires. */
  686.     pUserInfo -> usri2_acct_expires = TIMEQ_FOREVER;
  687.  
  688.     /* Any server can validate this user's logon. */
  689.     pUserInfo -> usri2_logon_server = "\\\\*";
  690.  
  691.     usRc = Net32UserAdd(pszDCName,
  692.                         2,
  693.                         pBuffer,
  694.                         BUFFER_LEN,
  695.                         NULL);
  696.  
  697.     if (usRc)
  698.         Error_Message(usRc, "Net32UserAdd");
  699.  
  700.     return(usRc);
  701. }
  702.  
  703. USHORT
  704. AddGroup(PCHAR pszDCName, PCHAR pszUserName, PCHAR pszGroupName, PCHAR pBuffer)
  705. {
  706.     USHORT                 usRc;
  707.  
  708.     memset(pBuffer, 0, sizeof(struct group_info_0));
  709.     strcpy(pBuffer, pszGroupName);
  710.  
  711.     usRc = Net32GroupAdd(pszDCName,
  712.                          0,
  713.                          pBuffer,
  714.                          sizeof(struct group_info_0),
  715.                          NULL);
  716.  
  717.     if (usRc)
  718.         Error_Message(usRc, "Net32GroupAdd");
  719.  
  720.     /* If the group was added successfully, add the user to the new group. */
  721.     if (!usRc)
  722.     {
  723.         usRc = Net32GroupAddUser(pszDCName,
  724.                                  pszGroupName,
  725.                                  pszUserName,
  726.                                  NULL);
  727.         if (usRc)
  728.             Error_Message(usRc, "Net32GroupAddUser");
  729.     }
  730.  
  731.     return(usRc);
  732. }
  733.  
  734. USHORT
  735. AliasAdd(char *pszDCName, char *pszAliasName, char *pBuffer)
  736. {
  737.     USHORT                      usRc;
  738.     struct alias_info_2        *pAlias = (struct alias_info_2 *)pBuffer;
  739.  
  740.     /*
  741.      * Set the alias_info_2 structure to zero.
  742.      */
  743.     memset(pAlias, 0, sizeof(struct alias_info_2));
  744.  
  745.     strcpy(pAlias -> ai2_alias, pszAliasName);
  746.     pAlias -> ai2_remark = "Alias added by USER sample program.";
  747.     pAlias -> ai2_type = ALIAS_TYPE_FILE;
  748.     pAlias -> ai2_location = ALIAS_LOCATION_INTERNAL;
  749.     strcpy(pAlias -> ai2_server, pszDCName + 2);
  750.     pAlias -> ai2_mode = ALIAS_MODE_BYADMIN;
  751.     pAlias -> ai2_maxuses = 10;
  752.     strcpy(pAlias -> ai2_netname, pszAliasName);
  753.     pAlias -> ai2_path = "C:\\OS2\\APPS";
  754.  
  755.     usRc = Net32AliasAdd(pszDCName,
  756.                          2,
  757.                          pBuffer,
  758.                          BUFFER_LEN,
  759.                          NULL);
  760.  
  761.     if (usRc)
  762.         Error_Message(usRc, "Net32AliasAdd");
  763.  
  764.     return(usRc);
  765. }
  766.  
  767. USHORT
  768. GiveAccessToAlias(char *pszUser,
  769.                   char *pszDCName,
  770.                   char *pszAliasName,
  771.                   char *pBuffer)
  772. {
  773.     USHORT                      usRc;
  774.     ULONG                       ulBytesAvailable;
  775.     CHAR                        szServer[UNCLEN + 1];
  776.     PCHAR                       pszPath;
  777.     struct alias_info_2        *pAliasInfo;
  778.     struct access_list         *pAccessList;
  779.     struct access_info_1       *pAccInfo;
  780.  
  781.     /* Determine the server and resource associated with the alias. */
  782.     usRc = Net32AliasGetInfo(pszDCName,
  783.                              pszAliasName,
  784.                              2,
  785.                              pBuffer + (BUFFER_LEN/2),
  786.                              BUFFER_LEN/2,
  787.                              &ulBytesAvailable,
  788.                              NULL);
  789.  
  790.     if (usRc)
  791.         Error_Message(usRc, "Net32AliasGetInfo");
  792.  
  793.     if (!usRc)
  794.     {
  795.         pAliasInfo = (struct alias_info_2 *)(pBuffer + (BUFFER_LEN/2));
  796.         pszPath = pAliasInfo -> ai2_path;
  797.         *szServer = *(szServer+1) = '\\';
  798.         strcpy(szServer+2, pAliasInfo -> ai2_server);
  799.  
  800.         /* Now an access control profile can be created for the resource. */
  801.         /* First, see if access control for the resource already exists.  */
  802.         usRc = Net32AccessGetInfo(szServer,
  803.                                   pszPath,
  804.                                   1,
  805.                                   pBuffer,
  806.                                   BUFFER_LEN,
  807.                                   &ulBytesAvailable);
  808.  
  809.         if (usRc && usRc != NERR_ResourceNotFound)
  810.             Error_Message(usRc, "Net32AccessGetInfo");
  811.         else
  812.         {
  813.             pAccessList =
  814.                 (struct access_list *)(pBuffer + sizeof(struct access_info_1));
  815.  
  816.             if (usRc == NERR_ResourceNotFound)
  817.             {
  818.                 pAccInfo = (struct access_info_1 *)pBuffer;
  819.                 pAccInfo -> acc1_resource_name = pszPath;
  820.                 pAccInfo -> acc1_attr = 0;
  821.                 pAccInfo -> acc1_count = 1;
  822.                 strcpy(pAccessList -> acl_ugname, pszUser);
  823.                 pAccessList -> acl_access = ACCESS_READ;
  824.  
  825.                 usRc = Net32AccessAdd(szServer,
  826.                                       1,
  827.                                       pBuffer,
  828.                                       BUFFER_LEN);
  829.  
  830.                 if (usRc)
  831.                     Error_Message(usRc, "Net32AccessAdd");
  832.             }
  833.             else
  834.             {
  835.                 /*
  836.                  * Add an access_list structure for the user.
  837.                  * We will assume that there is no access control
  838.                  * entry for this user, since he was just added.
  839.                  * Point past the last access_list structure,
  840.                  * fill in values for this user, and update the count
  841.                  * of access control entries.
  842.                  */
  843.                 pAccessList += ((struct access_info_1 *)pBuffer) -> acc1_count;
  844.                 strcpy(pAccessList -> acl_ugname, pszUser);
  845.                 pAccessList -> acl_access = ACCESS_READ;
  846.                 ++(((struct access_info_1 *)pBuffer) -> acc1_count);
  847.  
  848.                 usRc = Net32AccessSetInfo(szServer,
  849.                                           pszPath,
  850.                                           1,
  851.                                           pBuffer,
  852.                                           BUFFER_LEN,
  853.                                           PARMNUM_ALL);
  854.  
  855.                 if (usRc)
  856.                     Error_Message(usRc, "Net32AccessSetInfo");
  857.             }
  858.         }
  859.     }
  860.     return(usRc);
  861. }
  862.  
  863. USHORT
  864. InitDCDBForUser(char *pszDCName, char *pszUser)
  865. {
  866.     USHORT              usRc;
  867.  
  868.     /*
  869.      * The following function initializes the domain control
  870.      * database directories and structures for the specified user.
  871.      * If any database files already exist, their contents
  872.      * are lost.
  873.      */
  874.     usRc = Net32UserDCDBInit(pszDCName,
  875.                              pszUser,
  876.                              0L,                /* reserved, must be zero */
  877.                              NULL);
  878.  
  879.     if (usRc)
  880.         Error_Message(usRc, "Net32UserDCDBInit");
  881.  
  882.     return(usRc);
  883. }
  884.  
  885. /*
  886.  * This routine shows how to add a single logon assignment for
  887.  * a user.
  888.  */
  889. USHORT
  890. AddLogAsn(char *pszUser, char *pszDCName, char *pszAlias, char *pBuffer)
  891. {
  892.     USHORT                      usRc;
  893.     ULONG                       ulBytesAvailable;
  894.     struct logon_asn_list      *pLogList;
  895.     struct logon_asn_info_1    *pLogInfo;
  896.  
  897.     /* First, get the user's current assignments, of ALL alias types. */
  898.     usRc = Net32UserGetLogonAsn(pszDCName,
  899.                                 pszUser,
  900.                                 1,
  901.                                 ALIAS_TYPE_FILE | ALIAS_TYPE_PRINTER | ALIAS_TYPE_SERIAL,
  902.                                 pBuffer,
  903.                                 BUFFER_LEN,
  904.                                 &ulBytesAvailable,
  905.                                 NULL);
  906.  
  907.     if (usRc)
  908.         Error_Message(usRc, "Net32UserGetLogonAsn");
  909.     else
  910.     {
  911.         pLogInfo = (struct logon_asn_info_1 *)pBuffer;
  912.         pLogList =
  913.           (struct logon_asn_list *)(pBuffer + sizeof(struct logon_asn_info_1));
  914.         pLogList += pLogInfo -> lai1_count;
  915.         strcpy(pLogList -> lal_alias, pszAlias);
  916.         pLogList -> lal_type = ALIAS_TYPE_FILE;
  917.         strcpy(pLogList -> lal_device, "M:");
  918.  
  919.         pLogInfo -> lai1_reserved = 0;
  920.         ++(pLogInfo -> lai1_count);
  921.  
  922.         usRc = Net32UserSetLogonAsn(pszDCName,
  923.                                     pszUser,
  924.                                     1,
  925.                                     pBuffer,
  926.                                     BUFFER_LEN,
  927.                                     NULL);
  928.  
  929.         if (usRc)
  930.             Error_Message(usRc, "Net32UserSetLogonAsn");
  931.     }
  932.     return(usRc);
  933. }
  934.  
  935. USHORT
  936. CreateApplication(char *pszUser,
  937.                   char *pszAppName,
  938.                   char *pszAliasName,
  939.                   char *pszDCName,
  940.                   char *pBuffer)
  941. {
  942.     USHORT                      usRc;
  943.     struct app_info_3          *pAppInfo;
  944.  
  945.     /*
  946.      * Set up the app_info_3 structure.
  947.      * A private application for the user is being created;
  948.      * it resides remotely, on the resource created earlier
  949.      * by the AliasAdd() routine.  It is an OS/2 private PM
  950.      * application.  Note that the application program does
  951.      * not have to be installed at the time that the application
  952.      * definition is created.
  953.      */
  954.     pAppInfo = (struct app_info_3 *)pBuffer;
  955.  
  956.     strcpy(pAppInfo -> app3_name, pszAppName);
  957.     pAppInfo -> app3_remark = "App created by USER sample program.";
  958.     pAppInfo -> app3_command = "PMSEEK";
  959.     pAppInfo -> app3_command_parms = "";
  960.     strcpy(pAppInfo -> app3_app_alias_or_drv, pszAliasName);
  961.     pAppInfo -> app3_app_drive = '\0';
  962.     pAppInfo -> app3_app_path_to_dir = "\\";
  963.     *pAppInfo -> app3_wrkdir_alias_or_drv = '\0';
  964.     pAppInfo -> app3_wrkdir_drive = '\0';
  965.     pAppInfo -> app3_wrkdir_path_to_dir = "";
  966.     pAppInfo -> app3_prompt = 0;
  967.     pAppInfo -> app3_interface = APP_PM;
  968.     pAppInfo -> app3_apptype = APP_OS2_PRIVATE;
  969.     pAppInfo -> app3_res_count = 0;
  970.  
  971.     usRc = Net32AppAdd(pszDCName,
  972.                        pszUser,
  973.                        3,
  974.                        pBuffer,
  975.                        BUFFER_LEN,
  976.                        NULL);
  977.  
  978.     if (usRc)
  979.         Error_Message(usRc, "Net32AppAdd");
  980.  
  981.     return(usRc);
  982. }
  983.  
  984. USHORT
  985. AssignAppToUser(char *pszUser, char *pszDCName, char *pszAppName, char *pBuffer)
  986. {
  987.     USHORT                      usRc;
  988.     struct app_sel_info_1      *pAppInfo;
  989.     struct app_sel_list        *pAppList;
  990.  
  991.     /*
  992.      * In this routine, we assume that the user has no applications
  993.      * assigned to him and just do a SetAppSel operation.  This is
  994.      * a fairly safe assumption, since the user definition was just
  995.      * created and his domain database was just initialized.  However,
  996.      * note that the Net32UserSetAppSel operation is absolute; whatever
  997.      * applications are in the input buffer become the applications
  998.      * assigned to the user.  If the user had any app assignments previous
  999.      * to the Net32UserSetAppSel call, they would be lost.  To preserve
  1000.      * existing app assignments, a call to Net32UserGetAppSel() should precede
  1001.      * the call to Net32UserSetAppSel().  Refer to AddLogAsn() for an example
  1002.      * of how to preserve a user's current assignments.
  1003.      */
  1004.     pAppInfo = (struct app_sel_info_1 *)pBuffer;
  1005.     pAppList = (struct app_sel_list *)(pBuffer + sizeof(struct app_sel_info_1));
  1006.  
  1007.     pAppInfo -> asi1_reserved = 0;
  1008.     pAppInfo -> asi1_count = 1;
  1009.  
  1010.     strcpy(pAppList -> asl_appname, pszAppName);
  1011.     pAppList -> asl_apptype = APP_OS2_PRIVATE;
  1012.     pAppList -> asl_reserved = 0;
  1013.  
  1014.     usRc = Net32UserSetAppSel(pszDCName,
  1015.                               pszUser,
  1016.                               1,
  1017.                               pBuffer,
  1018.                               BUFFER_LEN,
  1019.                               NULL);
  1020.  
  1021.     if (usRc)
  1022.         Error_Message(usRc, "Net32UserSetAppSel");
  1023.  
  1024.     return(usRc);
  1025. }
  1026.