home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / tolkit45.zip / os2tk45 / samples / lanserv / alias32 / alias32.c next >
C/C++ Source or Header  |  1998-10-01  |  17KB  |  486 lines

  1. /****************************************************************************/
  2. /*
  3.  *    PROGRAM NAME: ALIAS32
  4.  *    ------------
  5.  *
  6.  *    What this program does: Creates an alias for a files resource;
  7.  *    creates an access control profile for the resource; shares it;
  8.  *    attempts to add a directory space limit to the resource (but
  9.  *    only if directory space limits are enabled).
  10.  *
  11.  *    SYNTAX:
  12.  *    ------
  13.  *    ALIAS32 aliasname [\\servername] resourcename
  14.  *       where:
  15.  *        - aliasname is the alias that the resource will be known by
  16.  *          (an alias cannot be longer than 8 bytes)
  17.  *        - \\servername is optional and is the name of the server
  18.  *          where the resource physically resides.  If not specified,
  19.  *          it is assumed that the resource resides on the local server.
  20.  *        - resourcename is a fully qualified path (beginning with a
  21.  *          drive letter).
  22.  *
  23.  *        Note that adding an alias via this sample program will require
  24.  *        some cleanup after the program runs: a administrator will need
  25.  *        to: delete the alias, delete the share, remove read access for
  26.  *        the USERS group from the resource that the alias represents
  27.  *        (if access for USERS did not already exist), and remove the
  28.  *        directory limit, if one was added.  These tasks may be done
  29.  *        with the following NET commands:
  30.  *        - NET ALIAS <aliasname> /DEL
  31.  *        - NET SHARE <aliasname> /DEL
  32.  *          or, if the shared resource is on a remote server,
  33.  *          NET ADMIN \\servername /C NET SHARE <aliasname> /DEL
  34.  *        - NET ACCESS <resourcename>
  35.  *          shows what users and groups have access to the resource; to
  36.  *          delete all access, use
  37.  *          NET ACCESS <resourcename> /DEL
  38.  *          To remove read-only access for the USERS group, use
  39.  *          NET ACCESS <resourcename> /REVOKE USERS
  40.  *          The NET ADMIN command can be used in conjunction with the
  41.  *          NET ACCESS command if the resource resides on a remote server.
  42.  *        - NET DASD <resourcename> /DEL
  43.  *          or
  44.  *          NET ADMIN \\servername /C NET DASD <resourcename> /DEL
  45.  *          if the resource resides on a remote server.
  46.  *
  47.  *    REQUIRED FILES:
  48.  *    --------------
  49.  *    ALIAS32.C        -  Source code for this program
  50.  *
  51.  *    REQUIRED LIBRARIES:
  52.  *    ------------------
  53.  *    NETAPI32.LIB     -  Netapi library (in \IBMLAN\NETSRC\LIB directory)
  54.  *
  55.  *    NetAPI functions used in this program:
  56.  *    -------------------------------------
  57.  *    Net32WkstaGetInfo
  58.  *    Net32ServerEnum2
  59.  *    Net32GetDCName
  60.  *    Net32AliasAdd
  61.  *    Net32AliasDel
  62.  *    Net32ShareAdd
  63.  *    Net32AccessAdd
  64.  *    Net32AccessGetInfo
  65.  *    Net32AccessSetInfo
  66.  *    Net32DASDAdd
  67.  *
  68.  *    HOW TO COMPILE THIS PROGRAM:
  69.  *    ---------------------------
  70.  *    icc /C /Gt+ /DPURE_32 alias32.c
  71.  */
  72. /****************************************************************************/
  73.  
  74. /*------- OS/2 include files -----------------------------------------------*/
  75. #define INCL_DOSMEMMGR
  76. #define INCL_DOSPROCESS
  77. #include <os2.h>
  78.  
  79. /*------- NET APIs include files -------------------------------------------*/
  80. #include <neterr.h>
  81. #include <netcons.h>
  82. #include <access.h>
  83. #include <dasd.h>
  84. #include <dcdb.h>
  85. #include <server.h>
  86. #include <shares.h>
  87. #include <wksta.h>
  88.  
  89. /*------- C include files --------------------------------------------------*/
  90. #include <stdio.h>
  91. #include <string.h>
  92.  
  93. /*------- Function declaration ---------------------------------------------*/
  94. VOID Syntax(VOID);
  95. VOID Error_Message(USHORT, PSZ);
  96.  
  97.  
  98. /*------- Main program -----------------------------------------------------*/
  99. VOID
  100. main(int argc, char *argv[])
  101. {
  102.     USHORT                      usRc = 0,
  103.                                 usCount;
  104.     ULONG                       ulBytesAvailable,
  105.                                 ulEntriesRead;
  106.     CHAR                        ServerName[UNCLEN+1];
  107.     CHAR                        DCName[UNCLEN+1];
  108.     PCHAR                       pBuffer;
  109.     BOOL                        AccessAdded = FALSE;
  110.     struct wksta_info_10       *pWkInfo;
  111.     struct alias_info_2        *pAliasInfo;
  112.     struct access_info_1       *pAccInfo;
  113.     struct access_list         *pAccList;
  114.     struct share_info_2        *pShareInfo;
  115.     struct dasd_info_0         *pDasdInfo;
  116.  
  117.  
  118.     /* There must be either 3 or 4 command line arguments */
  119.     if (argc < 3 || argc > 4)
  120.         Syntax();
  121.  
  122.     /*
  123.      * Verify that the \\servername argument begins with two backslashes,
  124.      * and that it's not too long.
  125.      */
  126.     if (argc == 4)
  127.     {
  128.         if ( *(argv[2]) != '\\' || *(argv[2]+1) != '\\' ||
  129.              strlen(argv[2]) > UNCLEN )
  130.         {
  131.             Syntax();
  132.         }
  133.         else
  134.         {
  135.             strcpy(ServerName, argv[2]);
  136.         }
  137.     }
  138.  
  139.     /* Make sure that the length of the alias name is acceptable. */
  140.     if (strlen(argv[1]) > ALIAS_LEN)
  141.         Syntax();
  142.  
  143.     /* allocate a buffer for the API calls */
  144.     usRc = DosAllocMem((PPVOID)&pBuffer,
  145.                        4096,
  146.                        PAG_WRITE | PAG_READ | PAG_COMMIT);
  147.  
  148.     if (usRc)
  149.     {
  150.         Error_Message(usRc, "DosAllocMem");
  151.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  152.     }
  153.  
  154.     /* Set the buffer to all zeroes. */
  155.     memset(pBuffer, 0, 4096);
  156.  
  157.     /*
  158.      * Get the name of the domain that we're logged on to so that the
  159.      * name of the domain controller can be determined.
  160.      */
  161.     pWkInfo = (struct wksta_info_10 *)(pBuffer + 3072);
  162.  
  163.     usRc = Net32WkstaGetInfo(NULL,
  164.                              10,                                /* level */
  165.                              (unsigned char *)pWkInfo,
  166.                              1024,
  167.                              &ulBytesAvailable);
  168.  
  169.     if (usRc)
  170.     {
  171.         Error_Message(usRc, "NetWkstaGetInfo");
  172.         (void)DosFreeMem((PVOID)pBuffer);
  173.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  174.     }
  175.  
  176.     /*
  177.      * If '\\servername' was not specified on the command line,
  178.      * use the name of the local machine as the server where the
  179.      * alias resides.
  180.      */
  181.     if (argc == 3)
  182.     {
  183.         strcpy(ServerName, "\\\\");
  184.         strcat(ServerName, pWkInfo -> wki10_computername);
  185.     }
  186.  
  187.     /*
  188.      * Get the name of the domain controller.  The return buffer is large
  189.      * enough to hold the name of only one server (since only one domain
  190.      * controller per domain is expected).  The server names returned
  191.      * by NetServerEnum2 do not begin with backslashes.
  192.      */
  193.     usRc = Net32ServerEnum2(NULL,
  194.                             0,
  195.                             DCName + 2,
  196.                             UNCLEN - 1,
  197.                             &ulEntriesRead,
  198.                             &ulBytesAvailable,
  199.                             SV_TYPE_DOMAIN_CTRL,
  200.                             pWkInfo -> wki10_logon_domain);
  201.  
  202.     if (usRc == NERR_Success && ulEntriesRead == 1)
  203.         *DCName = *(DCName + 1) = '\\';
  204.     else
  205.     {
  206.         /*
  207.          * NetServerEnum2 failed for some reason.  Try a different
  208.          * method for determining the domain controller name.
  209.          */
  210.         usRc = Net32GetDCName(NULL,
  211.                               pWkInfo -> wki10_logon_domain,
  212.                               DCName,
  213.                               UNCLEN+1);
  214.  
  215.         if (usRc)
  216.         {
  217.             Error_Message(usRc, "NetGetDCName");
  218.             (void)DosFreeMem((PVOID)pBuffer);
  219.             DosExit(EXIT_PROCESS, (ULONG)usRc);
  220.         }
  221.     }
  222.  
  223.     /*
  224.      * Set up the buffer for the call to Net32AliasAdd.
  225.      * This will be an internal files alias that is shared
  226.      * by administrator action.  The maximum number of
  227.      * simultaneous users of this alias will be 10.
  228.      */
  229.     pAliasInfo = (struct alias_info_2 *)pBuffer;
  230.  
  231.     /*
  232.      * Note that the ai2_queue, ai2_priority, and ai2_device_pool
  233.      * elements of the alias_info_2 structure do not apply to files
  234.      * aliases, so these elements are not initialized here.  Since
  235.      * the buffer has been memset to 0, these elements all have a
  236.      * value of 0.
  237.      */
  238.     strcpy(pAliasInfo -> ai2_alias, argv[1]);
  239.     pAliasInfo -> ai2_remark = "Alias created by ALIAS sample program.";
  240.     pAliasInfo -> ai2_type = ALIAS_TYPE_FILE;
  241.     pAliasInfo -> ai2_location = ALIAS_LOCATION_INTERNAL;
  242.     strcpy(pAliasInfo -> ai2_server, ServerName+2);
  243.     pAliasInfo -> ai2_mode = ALIAS_MODE_BYADMIN;
  244.     pAliasInfo -> ai2_maxuses = 10;
  245.     strcpy(pAliasInfo -> ai2_netname, argv[1]);
  246.     if (argc == 3)
  247.         pAliasInfo -> ai2_path = argv[2];
  248.     else
  249.         pAliasInfo -> ai2_path = argv[3];
  250.  
  251.     /* The Net32AliasAdd api must be remoted to the domain controller. */
  252.     usRc = Net32AliasAdd(DCName,
  253.                          2,
  254.                          (unsigned char *)pAliasInfo,
  255.                          sizeof(struct alias_info_2),
  256.                          NULL);
  257.  
  258.     if (usRc)
  259.     {
  260.         Error_Message(usRc, "Net32AliasAdd");
  261.         (void)DosFreeMem((PVOID)pBuffer);
  262.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  263.     }
  264.     else
  265.     {
  266.         printf("The alias has been added successfully.\n");
  267.     }
  268.  
  269.     /*
  270.      * Determine whether the resource currently has an
  271.      * access control profile.  Sometimes this api call
  272.      * takes a while to complete, so we post a message
  273.      * telling the user what's happening.
  274.      */
  275.     printf("Checking access control information for %s...\n",
  276.             argc == 3 ? argv[2] : argv[3]);
  277.     usRc = Net32AccessGetInfo(ServerName,
  278.                               argc == 3 ? argv[2] : argv[3],    /* resource */
  279.                               1,                                /* level    */
  280.                               pBuffer,
  281.                               4096,
  282.                               &ulBytesAvailable);
  283.  
  284.     /*
  285.      * If the resource has no acp, NERR_ResourceNotFound is returned.
  286.      */
  287.     if (usRc && usRc != NERR_ResourceNotFound)
  288.     {
  289.         Error_Message(usRc, "Net32AccessGetInfo");
  290.         (void)DosFreeMem((PVOID)pBuffer);
  291.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  292.     }
  293.  
  294.     /*
  295.      * If the resource has no access control profile, set up a
  296.      * buffer to add read only access for the group "USERS".
  297.      */
  298.     if (usRc == NERR_ResourceNotFound)
  299.     {
  300.         pAccInfo = (struct access_info_1 *)pBuffer;
  301.         pAccList = (struct access_list *)(pBuffer + sizeof(struct access_info_1));
  302.  
  303.         pAccInfo -> acc1_resource_name = argc == 3 ?
  304.             argv[2] : argv[3];
  305.         pAccInfo -> acc1_attr = 0;
  306.         pAccInfo -> acc1_count = 1;
  307.  
  308.         strcpy(pAccList -> acl_ugname, "USERS");
  309.         pAccList -> acl_access = ACCESS_READ;
  310.  
  311.         usRc = Net32AccessAdd(ServerName,
  312.                               1,
  313.                               pBuffer,
  314.                               4096);
  315.  
  316.         if (usRc)
  317.             Error_Message(usRc, "Net32AccessAdd");
  318.         else
  319.             AccessAdded = TRUE;
  320.     }
  321.     /*
  322.      * The resource has an access control profile.  Loop through the
  323.      * access_list structures to see if there's one for the group "USERS".
  324.      * If not, add read-only access for "USERS"; otherwise, do nothing.
  325.      */
  326.     else
  327.     {
  328.         usCount = ((struct access_info_1 *)pBuffer) -> acc1_count;
  329.         pAccList = (struct access_list *)(pBuffer + sizeof(struct access_info_1));
  330.  
  331.         while (usCount)
  332.         {
  333.             if (!strcmp(pAccList -> acl_ugname, "USERS"))
  334.             {
  335.                 printf("An access control entry for the group USERS already exists.\n");
  336.                 break;
  337.             }
  338.             --usCount;
  339.             ++pAccList;
  340.         }
  341.  
  342.         /*
  343.          * If the group "USERS" wasn't found among the resource's
  344.          * access control entries, add an access_list entry for
  345.          * "USERS".
  346.          */
  347.         if (usCount == 0)
  348.         {
  349.             strcpy(pAccList -> acl_ugname, "USERS");
  350.             pAccList -> acl_access = ACCESS_READ;
  351.             ((struct access_info_1 *)pBuffer) -> acc1_count += 1;
  352.  
  353.             usRc = Net32AccessSetInfo(ServerName,
  354.                                       argc == 3 ? argv[2] : argv[3],
  355.                                       1,
  356.                                       pBuffer,
  357.                                       4096,
  358.                                       PARMNUM_ALL);
  359.  
  360.             if (usRc)
  361.                 Error_Message(usRc, "Net32AccessSetInfo");
  362.             else
  363.                 AccessAdded = TRUE;
  364.         }
  365.     }
  366.  
  367.     if (usRc == NERR_Success && AccessAdded)
  368.     {
  369.         printf("Read-only access added for \"USERS\" group.\n");
  370.     }
  371.     else if (usRc)
  372.     {
  373.         printf("Deleting alias definition for %s...\n", argv[1]);
  374.         usRc = Net32AliasDel(ServerName, argv[1], 0L, NULL);
  375.         if (usRc)
  376.         {
  377.             printf("Deletion of alias %s failed.\n", argv[1]);
  378.             Error_Message(usRc, "Net32AliasDel");
  379.         }
  380.         else
  381.         {
  382.             printf("Alias %s was deleted successfully.\n", argv[1]);
  383.         }
  384.         (void)DosFreeMem((PVOID)pBuffer);
  385.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  386.     }
  387.  
  388.     /*
  389.      * Set up the buffer to get the alias shared.
  390.      */
  391.     pShareInfo = (struct share_info_2 *)pBuffer;
  392.  
  393.     strcpy(pShareInfo -> shi2_netname, argv[1]);/* Aliasname == netname */
  394.     pShareInfo -> shi2_type = STYPE_DISKTREE;
  395.     pShareInfo -> shi2_remark = "Share added by ALIAS sample program.";
  396.     pShareInfo -> shi2_max_uses = 10;
  397.     if (argc == 3)
  398.         pShareInfo -> shi2_path = argv[2];
  399.     else
  400.         pShareInfo -> shi2_path = argv[3];
  401.     *pShareInfo -> shi2_passwd = '\0';
  402.     pShareInfo -> shi2_permissions = 0;
  403.     pShareInfo -> shi2_current_uses = 0;
  404.  
  405.     usRc = Net32ShareAdd(ServerName,
  406.                          2,
  407.                          pBuffer,
  408.                          4096);
  409.  
  410.     if (usRc)
  411.     {
  412.         Error_Message(usRc, "Net32ShareAdd");
  413.         printf("Deleting alias definition for %s...\n", argv[1]);
  414.         usRc = Net32AliasDel(ServerName, argv[1], 0L, NULL);
  415.         if (usRc)
  416.         {
  417.             printf("Deletion of alias %s failed.\n", argv[1]);
  418.             Error_Message(usRc, "Net32AliasDel");
  419.         }
  420.         else
  421.         {
  422.             printf("Alias %s was deleted successfully.\n", argv[1]);
  423.         }
  424.         (void)DosFreeMem((PVOID)pBuffer);
  425.         DosExit(EXIT_PROCESS, (ULONG)usRc);
  426.     }
  427.     else
  428.     {
  429.         printf("The alias was shared successfully.\n");
  430.     }
  431.  
  432.     /*
  433.      * Finally, attempt to add a directory limit to the resource.
  434.      * We arbitrarily set the limit at 1MB and specify that alerts
  435.      * are to be generated when the directory is 90% full.
  436.      */
  437.     pDasdInfo = (struct dasd_info_0 *)pBuffer;
  438.  
  439.     pDasdInfo -> d0_resource_name = argc == 3 ? argv[2] : argv[3];
  440.     pDasdInfo -> d0_max = 1024;         /* 1024KB == 1Meg */
  441.     pDasdInfo -> d0_use = 0;
  442.     pDasdInfo -> d0_flag = DASD_VALIDATE_LIMIT_ON;
  443.     pDasdInfo -> d0_thresh = 90;
  444.     pDasdInfo -> d0_delta = 0;
  445.  
  446.     usRc = Net32DASDAdd(ServerName,
  447.                         0,
  448.                         pBuffer,
  449.                         4096);
  450.  
  451.     if (usRc == NERR_Success)
  452.     {
  453.         printf("A directory limit of 1MB was set for directory %s.\n",
  454.                 argc == 3 ? argv[2] : argv[3]);
  455.     }
  456.     else
  457.     {
  458.         Error_Message(usRc, "Net32DASDAdd");
  459.         (void)DosFreeMem((PVOID)pBuffer);
  460.     }
  461.  
  462.     DosExit(EXIT_PROCESS, (ULONG)usRc);
  463. }
  464.  
  465. /*
  466.  * Display syntax information and exit.
  467.  */
  468. VOID
  469. Syntax()
  470. {
  471.     printf("USAGE:\nThe ALIAS32 sample program adds a files alias, shares it, gives\n");
  472.     printf("the USERS group read-only access to the resource, and adds a\n");
  473.     printf("directory limit to the resource.\n\n");
  474.     printf("Syntax:\n");
  475.     printf("   ALIAS32 aliasname resourcename\n");
  476.     printf("      OR\n");
  477.     printf("   ALIAS32 aliasname \\\\servername resourcename\n");
  478.     printf(" where:\n");
  479.     printf("   - aliasname is an 8-byte name that is not currently in use.\n");
  480.     printf("   - \\\\servername specifies the server that the alias resource\n");
  481.     printf("     resides on.  If not specified, it is assumed that the alias\n");
  482.     printf("     resource resides on the local machine.\n");
  483.     printf("   - resourcename is a fully qualified path name.\n");
  484.     DosExit(EXIT_PROCESS, 1);
  485. }
  486.