home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / dsstlkt5.zip / dssos2tk / dss / DSSAPPLY.C < prev    next >
Text File  |  1998-05-08  |  59KB  |  1,996 lines

  1. /*************************************************************************
  2. *
  3. * LAST EDIT:   960301
  4. *
  5. * PROLOG...
  6. *
  7. * FILE_ID: dssapply.c
  8. *
  9. * parms    dssapply   <filename.ext>  [ cellname, realmname, servername ]
  10. *            arg[1]   = filename.ext ( response filename.ext )
  11. *
  12. * Note: This file is a DSS sample program for propagating ACL definitions generated via DSS administration.
  13. *       It is based on dssapply (a program used internally to test the APPLY function).
  14. *
  15. *---------------------------------------------------------------------------
  16. *
  17. * END_PROLOG
  18. *
  19. *
  20. * CHANGE_HISTORY
  21. *
  22. *
  23. * END_HISTORY
  24. *
  25. \*************************************************************************/
  26.  
  27. #define     VER_DATE    "v1.08 - 03/12/96"
  28.  
  29. #define     DSSAPPLY_NO_NAME_AND_UUID_STRINGS   100
  30. #define     DSSAPPLY_NAME_NOT_USER              101
  31.  
  32.  
  33. // OS/2 Toolkit headers
  34. //
  35. #define INCL_DOSFILEMGR
  36. #define INCL_BASE
  37.  
  38. #include    <os2.h>
  39.  
  40. // C/C++ headers
  41. //
  42.  
  43. #include    <stdio.h>
  44. #include    <stdlib.h>
  45. #include    <memory.h>
  46. #include    <stdarg.h>
  47. #include    <string.h>
  48. #include    <assert.h>
  49.  
  50. // DCE headers
  51. //
  52. #define _DCE_PROTO_
  53. #include    <dce/dce.h>
  54. #include    <dce/id_base.h>
  55. #include    <dce/id_epac.h>
  56. #include    <dce/aclbase.h>
  57.  
  58. #include    <dce/dbif.h>
  59. #include    <dce/aclif.h>
  60. #include    <dce/binding.h>
  61.  
  62. #include    <dce/daclif.h>
  63. #include    <dce/pgo.h>
  64. #include    <dce/uuid.h>
  65. #include    <dce/rpc.h>
  66. #include    <dce/rpcexc.h>
  67. #include    <dce/idlbase.h>
  68. #include    <dce/secidmap.h>
  69. //#include    <dce/sec_login.h>
  70.  
  71. // XPG/4 headers
  72. //
  73. #include    <nl_types.h>
  74. #include    <locale.h>
  75.  
  76. // LS headers
  77. //
  78. #include    <netcons.h>
  79. #include    <neterr.h>
  80. #include    <errlog.h>
  81. #include    <server.h>
  82.  
  83. #define     ANY_32_BIT
  84. #include    <access.h>
  85.  
  86.  
  87. // LSE headers
  88. //
  89.  
  90. #include    "apply.h"
  91. #include    "aclmrdef.h"             // acl_mgr_def.h  8.3 format  //
  92.  
  93.  
  94.  
  95. //#include    <netlib32.h>
  96. //#include    <error_log.h>
  97. //#include    <lseaclmg.h>
  98. //#include    <acl_mgr_db.h>
  99. //#include    <acl_mgr.h>
  100. //#include    <sec_cred_internal.h>
  101. //#include    <ctype.h>
  102. //
  103. // apply headers
  104. //
  105. //#include    <apply_msg.h>
  106. //#include    <dsserr.h>
  107.  
  108. // my includes
  109. //
  110. #define FUNCT_RETURN    56
  111. #define ABORT           55
  112. #define ENTRY_ILLEGAL   9999
  113.  
  114.  
  115. // determine_user_group return
  116. #define NAME_IS_USER                100
  117. #define NAME_IS_GROUP               101
  118. #define NAME_NOT_USER_OR_GROUP      200
  119.  
  120.  
  121. // local definitions
  122. //
  123. // macro definitions
  124. #define STAT_CHK_PRINTF(st,str) \
  125.     { if(st!=error_status_ok) printf("**%s\n",str); }
  126.  
  127. // private function definitions
  128. void
  129. init_globals(
  130.     void
  131. ) ;
  132.  
  133. static error_status_t
  134. read_input_file(
  135.     FILE *fin
  136. ) ;
  137.  
  138. void
  139. bld_id_to_repl(
  140.     id_to_replace_t *   itr_p ,
  141.     boolean32           itr_is_user ,
  142.     boolean32           itr_old_local ,
  143.     char *              id_old_name ,
  144.     char *              id_old_uuid ,
  145.     boolean32           itr_new_local ,
  146.     char *              id_new_name ,
  147.     char *              id_new_uuid ,
  148.     error_status_t *    fn_err
  149. ) ;
  150.  
  151. void
  152. bld_sec_acl_entry(
  153.     sec_acl_entry_t *   sae_p,              // where to build it
  154.     long int            perms ,
  155.     sec_acl_entry_type_t   sec_acl_entry_type ,
  156.     char *              sec_id_uuid,        // ptr to uuid, char format
  157.     char *              sec_id_name,        // ptr to name
  158.     char *              sec_rl_id_uuid,     // ptr to realm uuid name
  159.     char *              sec_rl_id_name,     // ptr to realm name
  160.     error_status_t *    fn_err
  161. ) ;
  162.  
  163. void
  164. get_login_PAC(
  165.     sec_id_pac_t *,
  166.     error_status_t *
  167. ) ;
  168.  
  169. void
  170. init_itr(
  171.     id_to_replace_t *  itr_p
  172. ) ;
  173.  
  174. void
  175. init_sec_acl(
  176.     sec_acl_t *         sa_p,
  177.     unsigned32          num_sec_acl_entries ,
  178.     sec_acl_entry_t *   sae_p ,
  179.     error_status_t *    f_stat
  180. ) ;
  181.  
  182. void
  183. init_sec_acl_entries(
  184.     sec_acl_entry_t *   sae_p,
  185.     unsigned32          num ,
  186.     error_status_t *    f_stat
  187. ) ;
  188.  
  189.  
  190. boolean32
  191. is_server_installed(
  192.     error_status_t *    f_stat
  193. ) ;
  194.  
  195. void
  196. det_sec_acl_entry_type(
  197.     char *                  saet_cptr ,
  198.     sec_acl_entry_type_t *  saet_p,
  199.     error_status_t *        dseat_stat
  200. ) ;
  201.  
  202.  
  203. unsigned32
  204. parse_perms(
  205.     char *  perms_ptr
  206. ) ;
  207.  
  208.  
  209. BOOL
  210. connect_to_server(
  211.     handle_t    *pHandle,
  212.     const char  *pszCell,
  213.     const char  *pszRealm,
  214.     const char  *pszServer
  215. ) ;
  216.  
  217. error_status_t
  218. STAT_CHK(
  219.     error_status_t      status_to_check ,
  220.     char *              log_text ,
  221.     unsigned32          action
  222. );
  223.  
  224.  
  225. void
  226. parse_apply_err(
  227.     unsigned32          err_code ,
  228.     unsigned char * *   perr_text ,
  229.     error_status_t *    pStatus
  230. ) ;
  231.  
  232. //-------   local defines
  233.  
  234. #define MAX_ERRORS      1024
  235. #define UUID_NAME_LEN   40
  236.  
  237. #define CDS_BINDING_LOCATION     "/.:/subsys/realms/root/servers/S1"
  238.  
  239. //------------------------------------------------------------------------
  240. // var declarations
  241. //------------------------------------------------------------------------
  242.  
  243. // enum type of call
  244. typedef enum {
  245.     MANIPULATE_APPLY ,
  246.     MANIPULATE_ENTRIES ,
  247.     REPLACE_APPLY
  248. } CALL_TYPE ;
  249.  
  250. // input file DATA vars
  251. CALL_TYPE           call_type ;
  252.  
  253. char *              res_glbl_name=NULL ;
  254. char *              cell_name=NULL ;
  255. char *              realm_name=NULL;
  256. char *              server_name=NULL ;
  257.  
  258. char                sec_mgr_uuid_text[UUID_NAME_LEN] ;
  259.  
  260. #ifdef              DEBUG
  261. boolean32           debug=TRUE;
  262. #else
  263. boolean32           debug=FALSE;
  264. #endif
  265.  
  266. boolean32           tolerance= APPLY_TOLERANCE_LOW;
  267. boolean32           recursion=FALSE ;
  268.  
  269. boolean32           itr_old_local=TRUE ;
  270. boolean32           itr_new_local=TRUE ;
  271.  
  272. unsigned32          action ;
  273. unsigned32          max_errors=MAX_ERRORS ;
  274. unsigned32          num_errors=0 ;
  275.  
  276. unsigned32          num_manip_entries=0 ;
  277. unsigned32          manip_entry_num=0 ;
  278.  
  279. unsigned32          num_sec_acl_entries=0 ;
  280. unsigned32          sec_acl_entry_num=0 ;
  281.  
  282. unsigned32          sec_acl_entry ;
  283. unsigned32          sec_entry_type ;
  284.  
  285. error_entry_t *     err_buf_p=NULL ;
  286.  
  287. uuid_t              sec_mgr_uuid ;      // uuid_from_string(sec_mgr_uuid_text)
  288.  
  289. sec_id_t            default_realm ;
  290. sec_acl_type_t      sec_acl_type ;
  291.  
  292. ent_entries_to_manipulate_t *   pEntEntries=NULL ;
  293.  
  294. sec_acl_list_t      sec_acl_list ;
  295. sec_acl_t           sec_acl ;       // only 1 sec_acl_t in dce1.1
  296. sec_acl_entry_t *   sae_p ;
  297.  
  298. FILE                *fin ;
  299.  
  300. // data structures for parsing *.inp file
  301. struct APPLY_TXT {
  302.     char    *txtdata ;
  303.     int     txtix ;
  304. } ;
  305.  
  306.  
  307. // the following are the text strings recognized by the parser
  308. // don't change numbering, these are used later by a switch!!
  309. struct APPLY_TXT prmtext[] = {
  310.  
  311.     {"call_type",           1 },
  312.     {"action",              2 },
  313.     {"tolerance",           3 },
  314.     {"recursion",           4 },
  315.     {"res_global_name",     5 },
  316.     {"sec_mgr_uuid" ,       6 },
  317.     {"sec_acl_type",        7 },
  318.  
  319.     {"sec_def_realm_name",  8 },
  320.     {"sec_def_realm_uuid",  9 },
  321.  
  322.     {"num_manip_entries",  10 },
  323.     {"manip_entry_num",    11 },
  324.     {"max_errors",         12 },
  325.  
  326.     {"cell_name",          15 },
  327.     {"realm_name",         16 },
  328.     {"server_name",        17 },
  329.  
  330.     {"itr_old_name" ,      20 },
  331.     {"itr_old_uuid" ,      21 },
  332.     {"itr_new_name" ,      22 },
  333.     {"itr_new_uuid" ,      23 },
  334.     {"itr_old_local" ,     24 },
  335.     {"itr_new_local" ,     25 },
  336.  
  337.     {"num_sec_acl_entries", 30 },
  338.     {"sec_acl_entry_num",  31 },
  339.     {"sec_acl_entry_type", 32 },         // sec_acl_entry_type_t
  340.  
  341.     {"sec_acl_perms" ,     39 },
  342.  
  343.     {"sec_acl_id.name" ,   40 },
  344.     {"sec_acl_id.uuid" ,   41 },
  345.     {"sec_acl_rl.name" ,   42 },
  346.     {"sec_acl_rl.uuid" ,   43 },
  347.  
  348.     {"itr_entry_end" ,     50 },          // for itr
  349.     {"sec_acl_entry_end" , 52 },
  350.  
  351.     { NULL,                 0 },          // list terminator
  352. } ;
  353.  
  354.  
  355. // options for action:
  356. // note that order is important; long strings with valid subsets
  357. // must come first if list is searched linearly
  358. struct APPLY_TXT actext[] = {
  359.     { "rename_user",       ENTRY_RENAME_USER },
  360.     { "rename_group",      ENTRY_RENAME_GROUP },
  361.     { "modify_add_or_create",  ENTRY_MODIFY_ADD_OR_CREATE },
  362.     { "modify_add",        ENTRY_MODIFY_ADD },
  363.     { "delete",            ENTRY_DELETE },
  364.     { "modify_delete",     ENTRY_MODIFY_DELETE },
  365.     { "replace_or_create", ENTRY_REPLACE_OR_CREATE },
  366.     { "replace",           ENTRY_REPLACE },
  367.     { "create",            ENTRY_CREATE },
  368.     { "unsupported",       ENTRY_CREATE | ENTRY_REPLACE },
  369.     { NULL              ,  0 },  // list terminator
  370. } ;
  371.  
  372.  
  373. //***********************    main     *****************************
  374. void
  375. main( int argc, char *argv[] )
  376. {
  377.     char *          c_ptr ;
  378.     char            user_in[80] ;
  379.     char            f_name[CCHMAXPATH] ;
  380.     char *          pe_text=NULL ;
  381.  
  382.     boolean         server_ready ;
  383.  
  384.     int             j ;
  385.  
  386.     error_status_t  status = rpc_s_ok ;
  387.     error_status_t  ent_acl_status ;
  388.  
  389.     unsigned long       ulRC, ulBytes ;
  390.  
  391.     sec_login_handle_t   login_context;
  392.  
  393.     handle_t        rpc_handle;
  394.  
  395.     // initialize pgm
  396.     printf("\nStarting DSSAPPLY: %s\n\n", VER_DATE ) ;
  397.  
  398.  
  399.     if( debug ) printf(" argc=%d\n", argc ) ;
  400.  
  401.  
  402.     // check command line args
  403.     if( argc < 2 )
  404.     {
  405.         printf("\aSyntax = DSSAPPLY input_filename [cellname, realmname, servername]\n\n") ;
  406.         printf("Input File not found!! \n");
  407.         printf("The Input File is used to specify the data elements supplied to the 2\n") ;
  408.         printf(" apply API functions: \n") ;
  409.         printf("   ent_acl_replace_apply(), and \n");
  410.         printf("   ent_acl_manipulate_apply() \n\n");
  411.         printf("Instructions and examples for creating a DSSAPPLY Input File can be \n") ;
  412.         printf("found in the accompanying file called DSSAPPLY.INP.\n") ;
  413.         exit(1) ;
  414.     }
  415.  
  416.     // initializations
  417.     init_globals() ;
  418.  
  419.     // check for any command line args
  420.     if( argc > 4 )      // assume: DSSApply responsefile  cell realm server
  421.     {
  422.         cell_name   = strdup( argv[2] ) ;
  423.         realm_name  = strdup( argv[3] ) ;
  424.         server_name = strdup( argv[4] ) ;
  425.  
  426.         if( debug )
  427.         {
  428.             printf("\n Command Line Parameters are: \n" ) ;
  429.             printf(" cell = %s\n",   cell_name ) ;
  430.             printf(" realm = %s\n",  realm_name ) ;
  431.             printf(" server = %s\n", server_name ) ;
  432.         }
  433.     }
  434.  
  435.     // deal with input file
  436.     c_ptr = strcpy( f_name, argv[1] ) ;
  437.  
  438.     fin = fopen( f_name , "r" ) ;
  439.     if( !fin )
  440.     {
  441.         printf("\n**\aUnable to OPEN %s! Exiting!\n", f_name ) ;
  442.         exit( 1 ) ;
  443.     }
  444.  
  445.     // get & process input data
  446.     status = read_input_file( fin ) ;
  447.  
  448.     if( !status )
  449.     {
  450.         // error reading input file
  451.         printf("\n**Errors Reading Input File!!" ) ;
  452.         printf("\n Continue Processing? ( Y/N ): \n" ) ;
  453.  
  454.         gets( user_in ) ;
  455.         strupr( user_in ) ;
  456.         if( user_in[0] != 'Y' )
  457.             exit(1) ;
  458.     }
  459.  
  460.     // establish server rpc connection
  461.     server_ready = connect_to_server(
  462.         &rpc_handle,
  463.         cell_name ,
  464.         realm_name ,
  465.         server_name ) ;
  466.  
  467.     if( !server_ready )
  468.     {
  469.         printf("\n**Unable to connect to server..." ) ;
  470.         printf("\nDo You Wish to Continue?? ( Y/N ) :" ) ;
  471.         _flushall() ;
  472.  
  473.         gets(user_in) ;
  474.         if( toupper( user_in[0] ) != 'Y' )
  475.             exit(40) ;
  476.     }
  477.  
  478.     //******   here we go !!  ***********
  479.     num_errors = 0 ;
  480.     ent_acl_status = rpc_s_ok ;
  481.  
  482.     TRY
  483.     {
  484.         // get current context
  485.         sec_login_get_current_context(
  486.             &login_context,
  487.             &status);
  488.  
  489.         if( status == error_status_ok )
  490.         {
  491.             rpc_binding_set_auth_info(
  492.                 rpc_handle,
  493.                 server_name,
  494.                 rpc_c_protect_level_pkt_integ,
  495.                 rpc_c_authn_dce_secret,
  496.                 (rpc_auth_identity_handle_t) login_context,
  497.                 rpc_c_authz_dce,
  498.                 &status);
  499.  
  500.             if( status == error_status_ok )
  501.             {
  502.  
  503.                 switch( call_type )
  504.                 {
  505.                 case MANIPULATE_APPLY :
  506.                     printf("\n  Calling ent_acl_manipulate_apply()..\n" ) ;
  507.  
  508.                     ent_acl_manipulate_apply(
  509.                         rpc_handle ,
  510.                         res_glbl_name ,
  511.                         sec_acl_type ,
  512. //                      ( ent_entries_to_manipulate_t * ) &ent_entries ,
  513.                         pEntEntries ,
  514.                         tolerance ,
  515.                         recursion ,
  516.                         max_errors ,
  517.                         err_buf_p ,
  518.                         &num_errors ,
  519.                         &ent_acl_status ) ;
  520.  
  521.                     printf("\n ent_acl_manipulate_apply complete " ) ;
  522.  
  523.                     break ;
  524.  
  525.                 case REPLACE_APPLY :
  526.                     printf("\n  Calling ent_acl_replace_apply()..\n" ) ;
  527.  
  528.                     ent_acl_replace_apply(
  529.                         rpc_handle ,
  530.                         res_glbl_name ,
  531.                         sec_acl_type ,
  532.                         &sec_acl_list ,
  533.                         tolerance ,
  534.                         recursion ,
  535.                         max_errors ,
  536.                         err_buf_p ,
  537.                         &num_errors ,
  538.                         &ent_acl_status ) ;
  539.  
  540.                     printf("\n ent_acl_replace_apply complete" ) ;
  541.  
  542.                     break;
  543.                 }
  544.  
  545.                 printf(" call Done!" ) ;
  546.                 printf(" Return Status=%u", ent_acl_status ) ;
  547.  
  548.                 if( ent_acl_status == error_status_ok )
  549.                     printf(" - No Errors!\n" ) ;
  550.                 else
  551.                 {
  552.                    printf(" *** Error(s)!! ***" ) ;
  553.  
  554.                    parse_apply_err(
  555.                       ent_acl_status,
  556.                       &pe_text ,
  557.                       &status ) ;
  558.  
  559.                    if( status == error_status_ok )
  560.                    {
  561.                       if( pe_text )
  562.                           printf( "\n** %s\n", pe_text ) ;
  563.                    }
  564.                    else
  565.                    {
  566.                       printf( "\n**parse_apply_err() Error! Code=%u\n", status ) ;
  567.                       printf( ", Unable to Get Error Text!\n") ;
  568.                    }
  569.                 }
  570.  
  571.                 printf("\nNumber of Error Buffer Entries=%d",num_errors ) ;
  572.                 if( num_errors > 0 )
  573.                 {
  574.                     printf(", Error Display follows..\n" ) ;
  575.  
  576.                     // display error buffer
  577.                     for ( j=0; j < num_errors; j++ )
  578.                     {
  579.                        printf("\nError Entry #%d: Error Code = %u ( %08lx Hex )",
  580.                j, (err_buf_p+j)->error_code, (err_buf_p+j)->error_code ) ;
  581.  
  582.                        parse_apply_err(
  583.                           (err_buf_p+j)->error_code,
  584.                           &pe_text ,
  585.                           &status ) ;
  586.  
  587.                        if( status == error_status_ok )
  588.                        {
  589.                           if( pe_text )
  590.                               printf( "\n** %s", pe_text ) ;
  591.                        }
  592.                        else
  593.                        {
  594.                           printf( "\n**parse_apply_err() Error! Code=%u\n", status ) ;
  595.                           printf( ", Unable to Get Error Text!\n") ;
  596.                        }
  597.  
  598.                        printf("\nError Object: %s" , (err_buf_p+j)->resource_name);
  599.  
  600.                        if( (err_buf_p+j)->resource_name )
  601.                           rpc_sm_client_free(
  602.                              (err_buf_p+j)->resource_name,
  603.                              &status ) ;
  604.                     }
  605.                 }
  606.                 printf( "\n" ) ;
  607.  
  608.             } // if( binding set info ok )
  609.  
  610.         } // if current context ok
  611.         else
  612.         {
  613.             printf("\n\a**Unable to Get Login Context! \n" ) ;
  614.         }
  615.     }
  616.     CATCH_ALL
  617.     {
  618.        // Random exception...
  619.        //
  620.        switch(exc_ctx.cur_exception.kind)
  621.        {
  622.        case exc_kind_status_c:
  623.           printf("\nAdditional exceptions status = %u\n", exc_ctx.cur_exception.status.status);
  624.           break;
  625.        case exc_kind_address_c:
  626.           printf("\n**Additional exceptions address = %X\n",
  627.                   exc_ctx.cur_exception.address.address);
  628.           break;
  629.        }
  630.     }
  631.     ENDTRY
  632.  
  633.     // free up any storage
  634.     if( err_buf_p )
  635.         free( err_buf_p ) ;
  636.     if( pEntEntries )
  637.         free( pEntEntries ) ;
  638.     if( sae_p )
  639.         free( sae_p ) ;
  640.  
  641.     if( cell_name )
  642.         free( cell_name ) ;
  643.     if( realm_name )
  644.         free( realm_name ) ;
  645.     if( server_name )
  646.         free( server_name ) ;
  647.  
  648.     printf("\n*** DSSAPPLY Complete!! ***\n" ) ;
  649.  
  650. } // main()
  651.  
  652.  
  653. /**************************************************************************
  654. *
  655. * read_input_file()
  656. *
  657. * this function reads the input file and builds data for the Apply calls
  658. *
  659. \*************************************************************************/
  660. static error_status_t
  661. read_input_file(
  662.     FILE *  fin
  663. )
  664. {
  665. #define FGETS_NUM_TO_READ 160
  666.  
  667.     char *              read_result ;
  668.     char *              sec_def_rl_name ;
  669.     char *              cptr ;
  670.  
  671.     char                buf[ FGETS_NUM_TO_READ+1 ] ;
  672.     char                lcb[ FGETS_NUM_TO_READ+1 ] ;
  673.     char                sec_def_rl_idtext[UUID_NAME_LEN] ;
  674.  
  675.     boolean32           keep_looking ;
  676.     boolean32           sec_acl_t_ok ;
  677.     boolean32           eetm_t_ok ;
  678.  
  679.     unsigned32          manip_entry_num_old ;
  680.     unsigned32          sec_acl_entry_num_old ;
  681.     unsigned32          size ;
  682.  
  683.     int                 j, cnt1, cnt2 ;
  684.     int                 ix, ferr_cnt ;
  685.  
  686.     error_status_t      f_stat ;
  687.  
  688.     // parms for bld_utr call
  689.     id_to_replace_t     id_to_repl ;
  690.     char *              itr_old_name ;
  691.     char *              itr_old_uuid_text ;
  692.     char *              itr_new_name ;
  693.     char *              itr_new_uuid_text ;
  694.  
  695.     // parms for bld_sec_acl
  696.     long int            inp_perms ;
  697.  
  698.     char *              sec_id_name;
  699.     char *              sec_id_uuid_text;
  700.     char *              sec_rl_name;
  701.     char *              sec_rl_uuid_text;
  702.  
  703.     sec_acl_entry_type_t    sec_acl_entry_type ;
  704.  
  705.     id_to_replace_t *   itr_p ;
  706.  
  707.     ent_entry_to_manipulate_t *     eetm_p ;
  708.  
  709.     struct  APPLY_TXT   *pt ;        // array of primary keywords
  710.     struct  APPLY_TXT   *at ;        // array of action  keywords
  711.  
  712.     if( debug )
  713.         printf("Read_Input_File():..\n" ) ;
  714.  
  715.     sec_acl_t_ok = FALSE ;
  716.     eetm_t_ok = FALSE ;
  717.     ferr_cnt = 0 ;
  718.  
  719.     while( !feof( fin ) )
  720.     {
  721.         for( cnt1=0; cnt1< FGETS_NUM_TO_READ; cnt1++ )
  722.             buf[ cnt1 ] = '\0' ;
  723.  
  724. //      printf("DB: fgets()\n" ) ;
  725.  
  726.         read_result = fgets( buf, FGETS_NUM_TO_READ, fin ) ;
  727.  
  728.         if( !read_result )
  729.         {
  730.             if( feof(fin))
  731.                 break ;
  732.  
  733.             if( ferror( fin ) )
  734.                 printf("** Input File Error at #%d!!\n",++ferr_cnt ) ;
  735.             continue ;
  736.         }
  737.  
  738.         if( strstr( buf, "rem " ) || strstr( buf, "REM " ) )
  739.         {
  740.             printf( "Remark:%s", &buf[3] ) ;  // '\n' should terminate
  741.             continue ;
  742.         }
  743.  
  744.         // filter comments, etc.
  745.         switch( buf[0] )
  746.         {
  747.             case '*' :
  748.             case '/' :
  749.             case '#' :
  750.             case '%' :
  751.             case ';' :
  752.             case '\n' :
  753.             case '\0' :
  754.             continue ;    // loops back to top of while to get more
  755.                           // break ;
  756.         }
  757.  
  758.         // kill any '\n'
  759.         for( j=0; j<strlen( buf ); j++ )
  760.             if( buf[j] == '\n' )
  761.                 buf[j]  = '\0' ;
  762.  
  763.         strcpy( lcb, buf ) ;
  764.         strlwr( lcb ) ;
  765.         ix = 0 ;
  766.  
  767.         // skip any leading white space
  768.         while( buf[ix] == ' ' && buf[ix] != '\0' )
  769.             ix++ ;
  770.  
  771.         if( buf[ix] == '\0' )
  772.             continue ;
  773.  
  774.         pt = prmtext ;          // set ptr
  775.  
  776.         keep_looking = TRUE ;
  777.         // search for primary keywords
  778.         while( ( pt->txtdata != '\0' ) && keep_looking )
  779.         {
  780.             // search for input keyword - note all is in lower case!!
  781.             if( strstr( buf+ix, pt->txtdata ) )
  782.             {
  783.                 keep_looking = FALSE ;  // got a match
  784.  
  785.                 // adjust current ptr to parm if applicable
  786.                 switch( pt->txtix )
  787.                 {
  788.                 case 50 :        // these have no parms
  789.                 case 52 :
  790.                     break ;
  791.  
  792.                 default :       // process to start of 2nd parm
  793.                     // skip to blank
  794.                     while( buf[ix] != ' ' && buf[ix] != '\0' && buf[ix] != '\n' )
  795.                         ix++ ;
  796.                     // skip to beginning of 2nd token
  797.                     while( buf[ix] == ' '  && buf[ix] != '\0' &&
  798.                            buf[ix] != '\n' )
  799.                         ix++ ;
  800.                     // ix now pts to 2nd token, or eol
  801.                     if( buf[ix] == '\0' || buf[ix] == '\n' )
  802.                         continue ;      // oops!!
  803.                  break ;
  804.                 }
  805.  
  806.                 // process data item - note that illegal parms needed for errs
  807.                 switch( pt->txtix )
  808.                 {
  809.                 case 1 :        // apply call type
  810.                     if( !strncmp( lcb+ix, "manip", 5 ) )
  811.                         call_type = MANIPULATE_APPLY ;
  812.                     else if( !strncmp( lcb+ix, "repl", 4 ) )
  813.                         call_type = REPLACE_APPLY ;
  814.                     else
  815.                     {
  816.                         printf("\n**\aUnknown Call TYPE!! Processing Halted..\n");
  817.                         printf("\nBuf=%s\n",buf);
  818.                     }
  819.                     break ;
  820.  
  821.                 case 2 :  // search for action code
  822.                     action = ENTRY_ILLEGAL ;
  823.                     at = actext ;  // set ptr to start of array
  824.  
  825.                     cptr = lcb+ix ;
  826.  
  827.                     while( at->txtdata != '\0' )
  828.                     {
  829.                         if( !strncmp( cptr, at->txtdata, strlen(at->txtdata) ) )
  830.                         {
  831.                             action = at->txtix ;  // action enums
  832.                             break ;  // successful exit from while
  833.                         }
  834.                         else
  835.                             at++ ;
  836.                     }
  837.                     if( action == ENTRY_ILLEGAL )
  838.                         printf("\n\a**Action Code NOT Found!!") ;
  839.                     break ;
  840.  
  841.                 case 3 :        // tolerance
  842.                     tolerance = APPLY_TOLERANCE_LOW;
  843.                     if( !strncmp( lcb+ix, "yes", 3 ) )
  844.                         tolerance = APPLY_TOLERANCE_MED;
  845.                     break ;
  846.  
  847.                 case 4 :        // recursion
  848.                     recursion = FALSE ;
  849.                     if( !strncmp( lcb+ix, "yes", 3 ) )
  850.                         recursion = TRUE ;
  851.                     break ;
  852.  
  853.                 case 5 :    // resource global name
  854.                     res_glbl_name = strdup( buf+ix ) ;
  855.                     break ;
  856.  
  857.                 case 6 :    // sec_mgr_uuid
  858.                     strcpy( sec_mgr_uuid_text , buf+ix ) ;
  859.                     break ;
  860.  
  861.                 case 7 :    // sec_acl_type ( obj, def_obj, def_cont )
  862.                     switch( lcb[ix] )
  863.                     {
  864.                         case 'o' :
  865.                             sec_acl_type = sec_acl_type_object ;
  866.                             break ;
  867.  
  868.                         case 'd' :
  869.                             switch( lcb[ix+4] )
  870.                             {
  871.                                 case 'o' :
  872.                             sec_acl_type = sec_acl_type_default_object ;
  873.                                     break ;
  874.                                 case 'c' :
  875.                             sec_acl_type = sec_acl_type_default_container ;
  876.                                     break ;
  877.                             }
  878.                             break ;
  879.  
  880.                         default :  // error case
  881.                             sec_acl_type = sec_acl_type_default_container |
  882.                                            sec_acl_type_default_object ;
  883.                             break ;
  884.                     }
  885.                     break ;
  886.  
  887.                 case 8 : // sec_def_realm_name ( optional )
  888.                     default_realm.name = strdup( buf+ix ) ;
  889.                     break ;
  890.  
  891.                 case 9 : // sec_def_realm_uuid ( optional )
  892.                     uuid_from_string( buf+ix, &default_realm.uuid, &f_stat ) ;
  893.                     STAT_CHK_PRINTF( f_stat,
  894.                         "uuid_from_string(&default_realm.uuid) Error!") ;
  895.                     break ;
  896.  
  897.                 case 10 : // num_manip_entries
  898.                     // get storage for manip_entries
  899.                     sscanf( buf+ix, "%d", &num_manip_entries ) ;
  900.  
  901.                     // get storage for ent_entries block
  902.                 size = sizeof(ent_entries_to_manipulate_t) +
  903.                        sizeof(ent_entry_to_manipulate_t) * (num_manip_entries-1) ;
  904.  
  905.                 pEntEntries = malloc( size ) ;
  906. /***
  907.                     if( pEntEntries == NULL )
  908.     printf( "\n**Unable to malloc() for %d ent_entries!\n",num_manip_entries ) ;
  909.                     else
  910.                     {
  911. **/
  912.                         eetm_t_ok = TRUE ;
  913. //                  }
  914.                     break ;
  915.  
  916.                 case 11 : // manip_entry_num; starts manip data gathering
  917.                     action = ENTRY_ILLEGAL ;
  918.                     itr_old_name      = NULL ;
  919.                     itr_old_uuid_text = NULL ;
  920.                     itr_old_local     = TRUE ;
  921.                     itr_new_name      = NULL ;
  922.                     itr_new_uuid_text = NULL ;
  923.                     itr_new_local     = TRUE ;
  924.  
  925.                     sec_acl_entry_type = sec_acl_e_type_extended ;
  926.                     sec_id_name      = NULL ;
  927.                     sec_id_uuid_text = NULL ;
  928.                     sec_rl_name      = NULL ;
  929.                     sec_rl_uuid_text = NULL ;
  930.                     inp_perms = 0 ;
  931.  
  932.                     manip_entry_num_old = manip_entry_num ;
  933.                     sscanf( buf+ix, "%d", &manip_entry_num ) ;
  934.                     if( manip_entry_num > num_manip_entries )
  935.                         manip_entry_num = manip_entry_num_old ;
  936.                     break ;
  937.  
  938.                 case 12 : // max_errors
  939.                     sscanf( buf+ix, "%d", &max_errors ) ;
  940.                     break ;
  941.  
  942.                 case 15 :    // cell name
  943.                     if( cell_name )
  944.                         free( cell_name ) ;
  945.                     cell_name = strdup( buf+ix ) ;
  946.                     break ;
  947.  
  948.                 case 16 :    // realm name
  949.                     realm_name = strdup( buf+ix ) ;
  950.                     break ;
  951.  
  952.                 case 17 :    // server name
  953.                     server_name = strdup( buf+ix ) ;
  954.                     break ;
  955.  
  956.                 case 20 : // itr_old_name
  957.                     itr_old_name = strdup( buf+ix ) ;
  958.                     break ;
  959.  
  960.                 case 21 : // itr_old_uuid
  961.                     itr_old_uuid_text = strdup( buf+ix ) ;
  962.                     break ;
  963.  
  964.                 case 22 : // itr_new_name
  965.                     itr_new_name = strdup( buf+ix ) ;
  966.                     break ;
  967.  
  968.                 case 23 : // itr_new_uuid
  969.                     itr_new_uuid_text = strdup( buf+ix ) ;
  970.                     break ;
  971.  
  972.                 case 24 : // itr_old_local
  973.                     if( !strncmp( lcb+ix, "true", 4 ) )
  974.                         itr_old_local = TRUE ;
  975.                     else if( !strncmp( lcb+ix, "false", 5 ) )
  976.                         itr_old_local = FALSE ;
  977.                     break ;
  978.  
  979.                 case 25 : // itr_new_local
  980.                     if( !strncmp( lcb+ix, "true", 4 ) )
  981.                         itr_new_local = TRUE ;
  982.                     else if( !strncmp( lcb+ix, "false", 5 ) )
  983.                         itr_new_local = FALSE ;
  984.                     break ;
  985.  
  986.                 case 30 : // num_sec_acl_entries - this assumes replace only
  987.                     sscanf( buf+ix, "%d", &num_sec_acl_entries ) ;
  988.  
  989.                     // get storage block for sec_acl_entry_t block
  990.                     sae_p = (sec_acl_entry_t *)
  991.                         malloc( num_sec_acl_entries * sizeof(sec_acl_entry_t) ) ;
  992. /***
  993.                     if( sae_p == NULL )
  994.     printf( "\n**Unable to malloc() for %d sec_acl_entries!\n",num_sec_acl_entries ) ;
  995.                     else
  996. ****/
  997.                     {
  998.                         // initialize sec_acl_list_t, etc.
  999.                         sec_acl_list.num_acls = 1 ;
  1000.                         sec_acl_list.sec_acls[0] = &sec_acl ;
  1001.  
  1002.                         init_sec_acl(
  1003.                             &sec_acl ,
  1004.                             num_sec_acl_entries,
  1005.                             sae_p,
  1006.                             &f_stat ) ;
  1007.  
  1008.                         init_sec_acl_entries(
  1009.                             sae_p ,
  1010.                             num_sec_acl_entries,
  1011.                             &f_stat ) ;
  1012.                         sec_acl_t_ok = TRUE ;
  1013.                     }
  1014.                     break ;
  1015.  
  1016.                 case 31 : // sec_acl_entry_num; starts sec_acl data input
  1017.                     sec_acl_entry_type = sec_acl_e_type_extended ;
  1018.                     sec_id_name      = NULL ;
  1019.                     sec_id_uuid_text = NULL ;
  1020.                     sec_rl_name      = NULL ;
  1021.                     sec_rl_uuid_text = NULL ;
  1022.                     inp_perms = 0 ;
  1023.  
  1024.                     sec_acl_entry_num_old = sec_acl_entry_num ;
  1025.                     sscanf( buf+ix, "%d", &sec_acl_entry_num ) ;
  1026.                     if( sec_acl_entry_num <= num_sec_acl_entries )
  1027.                     {
  1028.                         action = ENTRY_ILLEGAL ;
  1029.                     }
  1030.                     else
  1031.                         sec_acl_entry_num = sec_acl_entry_num_old ;
  1032.                     break ;
  1033.  
  1034.                 case 32 : // sec_acl_entry_type_t
  1035.                     det_sec_acl_entry_type(
  1036.                         lcb+ix ,
  1037.                         &sec_acl_entry_type ,
  1038.                         &f_stat ) ;
  1039.                     break ;
  1040.  
  1041.                 case 39 : // sec_acl_perms
  1042.                     inp_perms = parse_perms( lcb+ix ) ;
  1043.                     break ;
  1044.  
  1045.                 case 40 : // sec_acl_id.name
  1046.                     sec_id_name = strdup( buf+ix ) ;
  1047.                     break ;
  1048.  
  1049.                 case 41 : // sec_acl_id.uuid
  1050.                     sec_id_uuid_text = strdup( buf+ix ) ;
  1051.                     break ;
  1052.  
  1053.                 case 42 : // sec_acl_rl.name
  1054.                     sec_rl_name = strdup( buf+ix ) ;
  1055.                     break ;
  1056.  
  1057.                 case 43 : // sec_acl_rl.uuid
  1058.                     sec_rl_uuid_text = strdup( buf+ix ) ;
  1059.                     break ;
  1060.  
  1061.                 case 50 : // itr entry_end; build itr structure
  1062.                     if( eetm_t_ok )
  1063.                     {
  1064.      pEntEntries->entries_to_change_list[manip_entry_num-1].action = action ;
  1065.  
  1066.                         switch( action )
  1067.                         {
  1068.                             case ENTRY_RENAME_USER :
  1069.         init_itr( &pEntEntries->entries_to_change_list[manip_entry_num-1].target.user ) ;
  1070.  
  1071.                             bld_id_to_repl(
  1072.         &pEntEntries->entries_to_change_list[manip_entry_num-1].target.user,
  1073.                                 TRUE ,
  1074.                                 itr_old_local ,
  1075.                                 itr_old_name ,
  1076.                                 itr_old_uuid_text ,
  1077.                                 itr_new_local ,
  1078.                                 itr_new_name ,
  1079.                                 itr_new_uuid_text ,
  1080.                                 &f_stat ) ;
  1081.                             break ;
  1082.  
  1083.                             case ENTRY_RENAME_GROUP :
  1084.         init_itr( &pEntEntries->entries_to_change_list[manip_entry_num-1].target.group ) ;
  1085.  
  1086.                             bld_id_to_repl(
  1087.         &pEntEntries->entries_to_change_list[manip_entry_num-1].target.group,
  1088.                                 FALSE ,
  1089.                                 itr_old_local ,
  1090.                                 itr_old_name ,
  1091.                                 itr_old_uuid_text ,
  1092.                                 itr_new_local ,
  1093.                                 itr_new_name ,
  1094.                                 itr_new_uuid_text ,
  1095.                                 &f_stat ) ;
  1096.                             break ;
  1097.  
  1098.                             default :
  1099.                                 // invalid action for itr build!!
  1100.                             break ;
  1101.                         }
  1102.                     }
  1103.                     break ;
  1104.  
  1105.                 case 52 : // sec_acl_entry_end
  1106.                     switch( call_type )
  1107.                     {
  1108.                         case REPLACE_APPLY :
  1109.                             if( sec_acl_t_ok )
  1110.                             {
  1111.                                 bld_sec_acl_entry(
  1112.                                     sae_p + ( sec_acl_entry_num-1 ),
  1113.                                     inp_perms ,
  1114.                                     sec_acl_entry_type ,
  1115.                                     sec_id_uuid_text,
  1116.                                     sec_id_name,
  1117.                                     sec_rl_uuid_text,
  1118.                                     sec_rl_name,
  1119.                                     &f_stat ) ;
  1120.  
  1121.                                 STAT_CHK_PRINTF(f_stat,"Error Blding SEC Entry!");
  1122.                             }
  1123.  
  1124.                             break ;
  1125.  
  1126.                         case MANIPULATE_APPLY :
  1127.                             if( eetm_t_ok )
  1128.                             {
  1129.         pEntEntries->entries_to_change_list[manip_entry_num-1].action = action ;
  1130.  
  1131.                             init_sec_acl_entries(
  1132.         &pEntEntries->entries_to_change_list[manip_entry_num-1].target.sec_acl,
  1133.                                 1 ,
  1134.                                 &f_stat ) ;
  1135.  
  1136.                             bld_sec_acl_entry(
  1137.         &pEntEntries->entries_to_change_list[manip_entry_num-1].target.sec_acl,
  1138.                                 inp_perms ,
  1139.                                 sec_acl_entry_type ,
  1140.                                 sec_id_uuid_text,
  1141.                                 sec_id_name,
  1142.                                 sec_rl_uuid_text,
  1143.                                 sec_rl_name,
  1144.                                 &f_stat ) ;
  1145.  
  1146.                             STAT_CHK_PRINTF(f_stat,"Error Blding SEC Entry!");
  1147.                             }
  1148.  
  1149.                             break ;
  1150.  
  1151.                         default :
  1152.                             break ;
  1153.  
  1154.                     }
  1155.                     break ;
  1156.  
  1157.                 default :
  1158.                 printf("\n**Error in read_input_file(): Unknown switch(pt->txtix)=%d!\n",
  1159.                                 pt->txtix);
  1160.                     break ;
  1161.  
  1162.                 } // switch( pt->txtix )
  1163.  
  1164.             }
  1165.             else
  1166.                 pt++ ;
  1167.  
  1168.         } // while
  1169.  
  1170.     } // while !eof()
  1171.  
  1172.     fclose( fin ) ;
  1173.  
  1174.     printf("\nFile Read Successful Completion!\n" ) ;
  1175.  
  1176.     // allocate error buffer
  1177.     err_buf_p = (error_entry_t *) malloc( max_errors * sizeof(error_entry_t) ) ;
  1178.  
  1179. /***
  1180.     // assertions
  1181.     assert( err_buf_p ) ;
  1182.     assert( res_glbl_name ) ;
  1183.  
  1184.     assert( cell_name ) ;
  1185.     assert( realm_name ) ;
  1186.     assert( server_name ) ;
  1187. ***/
  1188.     // setup for proper call
  1189.  
  1190.     switch( call_type )
  1191.     {
  1192.     case MANIPULATE_APPLY :
  1193.         pEntEntries->num_entries_to_change  = num_manip_entries ;
  1194.         break ;
  1195.  
  1196.     case REPLACE_APPLY :
  1197.         // sec_acl initialization done by init_sec_acl()
  1198.         break;
  1199.     }
  1200.  
  1201.     return TRUE ;
  1202.  
  1203. } // read_input_file
  1204.  
  1205.  
  1206. /**************************************************************************
  1207. *
  1208. * bld_sec_acl_entry() - Build sec_acl_entry in sec_acl_entry_t structure
  1209. *
  1210. * note:     if sec_id_uuid & sec_id_name are both null, then error
  1211. *           likewise for realm.
  1212. *           if sec_id_uuid is null, then use pgo stuff to get uuid
  1213. *           if sec_rl_id_uuid is null, then use ?? to get uuid
  1214. *
  1215. \*************************************************************************/
  1216. void
  1217. bld_sec_acl_entry(
  1218.     sec_acl_entry_t *   sae_p,              // where to build it
  1219.     long int            perms ,
  1220.     sec_acl_entry_type_t   sec_acl_entry_type ,
  1221.     char *              sec_id_uuid,        // ptr to uuid, char string
  1222.     char *              sec_id_name,        // ptr to name
  1223.     char *              sec_rl_id_uuid,     // ptr to realm uuid char string
  1224.     char *              sec_rl_id_name,     // ptr to realm name
  1225.     error_status_t *    pStatus
  1226. )
  1227. {
  1228.     error_status_t  c_stat ;
  1229.  
  1230.     int             usr_grp_status ;
  1231.     uuid_t          nil_uuid ;
  1232.  
  1233.     *pStatus = error_status_ok ;
  1234.  
  1235.     sae_p->perms = perms ;
  1236.     sae_p->entry_info.entry_type = sec_acl_entry_type ;
  1237.  
  1238.     switch( sae_p->entry_info.entry_type )
  1239.     {
  1240.     case sec_acl_e_type_extended :
  1241.         // punt this for now !!
  1242.         sae_p->entry_info.tagged_union.extended_info = NULL ;
  1243.         return ;
  1244. //      break ;
  1245.  
  1246.     case sec_acl_e_type_user_obj :       // all done for these
  1247.     case sec_acl_e_type_group_obj :
  1248.     case sec_acl_e_type_other_obj :
  1249.     case sec_acl_e_type_mask_obj :
  1250.     case sec_acl_e_type_unauthenticated :
  1251.     case sec_acl_e_type_any_other :
  1252.     case sec_acl_e_type_user_obj_deleg :
  1253.     case sec_acl_e_type_group_obj_deleg :
  1254.     case sec_acl_e_type_other_obj_deleg :
  1255.     case sec_acl_e_type_any_other_deleg :
  1256.         return ;
  1257. //      break ;
  1258.  
  1259.     default :
  1260.         break ;
  1261.     }
  1262.  
  1263.     // get a nil uuid
  1264.     uuid_create_nil( &nil_uuid, pStatus );
  1265.     STAT_CHK_PRINTF( *pStatus,"uuid_create_nil() Failure!") ;
  1266.  
  1267.     // check for name or uuid
  1268.     if( sec_id_uuid == NULL && sec_id_name == NULL )
  1269.     {
  1270.         *pStatus = DSSAPPLY_NO_NAME_AND_UUID_STRINGS ;
  1271.         return ;
  1272.     }
  1273.  
  1274.     switch( sae_p->entry_info.entry_type )
  1275.     {
  1276.     case sec_acl_e_type_foreign_user :
  1277.     case sec_acl_e_type_foreign_group :
  1278.     case sec_acl_e_type_for_user_deleg :
  1279.     case sec_acl_e_type_for_group_deleg :
  1280.         if( sec_rl_id_uuid == NULL && sec_rl_id_name == NULL )
  1281.         {
  1282.             *pStatus = DSSAPPLY_NO_NAME_AND_UUID_STRINGS ;
  1283.             return ;
  1284.         }
  1285.         break ;
  1286.  
  1287.     default :
  1288.         break ;
  1289.     }
  1290.  
  1291.     switch( sae_p->entry_info.entry_type )
  1292.     {
  1293.     case sec_acl_e_type_user :          // sec_id_t    id
  1294.     case sec_acl_e_type_group :
  1295.     case sec_acl_e_type_foreign_other :
  1296.     case sec_acl_e_type_user_deleg :
  1297.     case sec_acl_e_type_group_deleg :
  1298.     case sec_acl_e_type_for_other_deleg :
  1299.         if( sec_id_uuid )
  1300.         {
  1301.             uuid_from_string( sec_id_uuid,
  1302.                 &sae_p->entry_info.tagged_union.id.uuid, &c_stat ) ;
  1303.             STAT_CHK_PRINTF( c_stat,
  1304.                 "uuid_from_string(&sae_p->entry_info.id.uuid) Error!") ;
  1305.         }
  1306.         else
  1307.             sae_p->entry_info.tagged_union.id.uuid = nil_uuid ;
  1308.  
  1309.         if ( sec_id_name != NULL )
  1310.             sae_p->entry_info.tagged_union.id.name = sec_id_name ;
  1311.         break ;
  1312.  
  1313.     case sec_acl_e_type_foreign_user :  // sec_id_foreign_t  foreign_id
  1314.     case sec_acl_e_type_foreign_group :
  1315.     case sec_acl_e_type_for_user_deleg :
  1316.     case sec_acl_e_type_for_group_deleg :
  1317.  
  1318.         if( sec_id_uuid )
  1319.         {
  1320.             uuid_from_string( sec_id_uuid,
  1321.                 &sae_p->entry_info.tagged_union.foreign_id.id.uuid, &c_stat ) ;
  1322.             STAT_CHK_PRINTF( c_stat,
  1323.                 "uuid_from_string(&sae_p->entry_info.foreign_id.id.uuid) Error!") ;
  1324.         }
  1325.         else
  1326.             sae_p->entry_info.tagged_union.id.uuid = nil_uuid ;
  1327.  
  1328.         if ( sec_id_name != NULL )
  1329.             sae_p->entry_info.tagged_union.foreign_id.id.name=sec_id_name;
  1330.  
  1331.         if( sec_rl_id_uuid )
  1332.         {
  1333.             uuid_from_string( sec_rl_id_uuid,
  1334.                 &sae_p->entry_info.tagged_union.foreign_id.realm.uuid, &c_stat ) ;
  1335.             STAT_CHK_PRINTF( c_stat,
  1336.                 "uuid_from_string(&sae_p->entry_info.foreign_id.realm.uuid) Error!") ;
  1337.         }
  1338.         else
  1339.             sae_p->entry_info.tagged_union.foreign_id.realm.uuid = nil_uuid ;
  1340.  
  1341.         if ( sec_rl_id_name != NULL )
  1342.             sae_p->entry_info.tagged_union.foreign_id.realm.name=sec_rl_id_name;
  1343.         break ;
  1344.  
  1345.     default :
  1346.         break ;
  1347.  
  1348.     } //switch
  1349.  
  1350.     *pStatus = error_status_ok ;
  1351.  
  1352.     return ;
  1353.  
  1354. } // bld_sec_acl_entry()
  1355.  
  1356.  
  1357. /**************************************************************************
  1358. *
  1359. * det_sec_acl_entry_type()
  1360. *
  1361. * note:
  1362. *
  1363. \*************************************************************************/
  1364. void
  1365. det_sec_acl_entry_type(
  1366.     char *                 saet_cptr ,      // sec_acl_entry_type text
  1367.     sec_acl_entry_type_t * saet_p,          // sec_acl_entry_type num
  1368. //  sec_acl_entry_class_t *  pSae_class,    // sec_acl_entry class
  1369.     error_status_t *       dsaet_stat
  1370. )
  1371. {
  1372.     // note that order is important for substring descrimination
  1373.     if( !strncmp( saet_cptr, "user_obj_deleg", 14 ) )
  1374.         *saet_p = sec_acl_e_type_user_obj_deleg  ;
  1375.     else if( !strncmp( saet_cptr, "user_obj", 8 ) )
  1376.         *saet_p = sec_acl_e_type_user_obj ;
  1377.     else if( !strncmp( saet_cptr, "user_deleg", 10 ) )
  1378.         *saet_p = sec_acl_e_type_user_deleg ;
  1379.     else if( !strncmp( saet_cptr, "user", 4 ) )
  1380.         *saet_p = sec_acl_e_type_user ;
  1381.  
  1382.     else if( !strncmp( saet_cptr, "group_obj_deleg", 15 ) )
  1383.         *saet_p = sec_acl_e_type_group_obj_deleg ;
  1384.     else if( !strncmp( saet_cptr, "group_obj", 9 ) )
  1385.         *saet_p = sec_acl_e_type_group_obj ;
  1386.     else if( !strncmp( saet_cptr, "group_deleg", 11 ) )
  1387.         *saet_p = sec_acl_e_type_group_deleg ;
  1388.     else if( !strncmp( saet_cptr, "group", 5 ) )
  1389.         *saet_p = sec_acl_e_type_group ;
  1390.  
  1391.     else if( !strncmp( saet_cptr, "other_obj_deleg", 15 ) )
  1392.         *saet_p = sec_acl_e_type_other_obj_deleg ;
  1393.     else if( !strncmp( saet_cptr, "other_obj", 9 ) )
  1394.         *saet_p = sec_acl_e_type_other_obj ;
  1395.  
  1396.     else if( !strncmp( saet_cptr, "any_other_deleg", 15 ) )
  1397.         *saet_p = sec_acl_e_type_any_other_deleg ;
  1398.     else if( !strncmp( saet_cptr, "any_other", 9 ) )
  1399.         *saet_p = sec_acl_e_type_any_other ;
  1400.  
  1401.     else if( !strncmp( saet_cptr, "for_user_deleg", 14 ) )
  1402.         *saet_p = sec_acl_e_type_for_user_deleg ;
  1403.     else if( !strncmp( saet_cptr, "foreign_user", 12 ) )
  1404.         *saet_p = sec_acl_e_type_foreign_user ;
  1405.  
  1406.     else if( !strncmp( saet_cptr, "foreign_other", 13 ) )
  1407.         *saet_p = sec_acl_e_type_foreign_other ;
  1408.     else if( !strncmp( saet_cptr, "for_other_deleg", 15 ) )
  1409.         *saet_p = sec_acl_e_type_for_other_deleg ;
  1410.  
  1411.     else if( !strncmp( saet_cptr, "for_group_deleg", 15 ) )
  1412.         *saet_p = sec_acl_e_type_for_group_deleg ;
  1413.     else if( !strncmp( saet_cptr, "foreign_group", 13 ) )
  1414.         *saet_p = sec_acl_e_type_foreign_group ;
  1415.  
  1416.     else if( !strncmp( saet_cptr, "extended", 8 ) )
  1417.         *saet_p = sec_acl_e_type_extended ;
  1418.     else if( !strncmp( saet_cptr, "mask_obj", 8 ) )
  1419.         *saet_p = sec_acl_e_type_mask_obj ;
  1420.     else if( !strncmp( saet_cptr, "unauthenticated", 15 ) )
  1421.         *saet_p = sec_acl_e_type_unauthenticated ;
  1422.     else
  1423.     {
  1424.         *dsaet_stat = ~error_status_ok ;   // none found
  1425.         *saet_p = sec_acl_e_type_unauthenticated |  // gen illegal
  1426.                   sec_acl_e_type_mask_obj ;
  1427.     }
  1428.  
  1429.     return ;
  1430.  
  1431. } // det_sec_acl_entry_type()
  1432.  
  1433.  
  1434. /**************************************************************************
  1435. *
  1436. * parse_perms()
  1437. *
  1438. * note:     as of 951201, new mappings will occur:
  1439. *
  1440. *               a -> w
  1441. *               c -> i
  1442. *               l -> r
  1443. *               p -> c
  1444. *
  1445. \*************************************************************************/
  1446. unsigned32
  1447. parse_perms(
  1448.     char *  perms_ptr
  1449. )
  1450. {
  1451.     int         j ;
  1452.     unsigned32  new_perms ;
  1453.  
  1454.     new_perms = 0 ;
  1455.  
  1456.     if( !strncmp( perms_ptr, "none", 4 ) )
  1457.         return 0 ;
  1458.  
  1459.     // locate & copy permissions
  1460.     if( *perms_ptr != '\0' )
  1461.     {
  1462.         // parse permissions
  1463.         for( j=0; *(perms_ptr+j) != '\0' ; j++ )
  1464.         {
  1465.             switch( *(perms_ptr+j) )
  1466.             {
  1467.                 case '\n' :
  1468.                 case ':' :
  1469.                 case ' ' :
  1470.                     break ;
  1471.                 case 'c' :
  1472.                 case 'C' :
  1473. //                  new_perms |= sec_acl_perm_create ;
  1474.                     new_perms |= sec_acl_perm_control ;
  1475.                     break ;
  1476.                 case 'd' :
  1477.                 case 'D' :
  1478.                     new_perms |= sec_acl_perm_delete ;
  1479.                     break ;
  1480.                 case 'i' :
  1481.                 case 'I' :
  1482.                     new_perms |= sec_acl_perm_insert ;
  1483.                     break ;
  1484.                 case 'r' :
  1485.                 case 'R' :
  1486.                     new_perms |= sec_acl_perm_read ;
  1487.                     break ;
  1488.                 case 't' :
  1489.                 case 'T' :
  1490.                     new_perms |= sec_acl_perm_test ;
  1491.                     break ;
  1492.                 case 'w' :
  1493.                 case 'W' :
  1494.                     new_perms |= sec_acl_perm_write ;
  1495.                     break ;
  1496.                 case 'x' :
  1497.                 case 'X' :
  1498.                     new_perms |= sec_acl_perm_execute ;
  1499.                     break ;
  1500.                 case 'z' :  // set an invalid permission
  1501.                 case 'Z' :
  1502.                     printf("\n**Invalid Permission=Z being Set!" ) ;
  1503.                     new_perms |= sec_acl_perm_attribute ;
  1504.                     break ;
  1505.                 default :
  1506.                     printf("\n**Invalid Permission='%c' in Perms='%s' NOT Set!\n",
  1507.                             *(perms_ptr+j), perms_ptr ) ;
  1508.  
  1509.             } // switch
  1510.  
  1511.         } // for
  1512.  
  1513.     } // if
  1514.  
  1515.     return( new_perms ) ;
  1516.  
  1517. } // parse_perms()
  1518.  
  1519.  
  1520. /**************************************************************************
  1521. *
  1522. * bld_id_to_repl()
  1523. *
  1524. \*************************************************************************/
  1525. void
  1526. bld_id_to_repl(
  1527.     id_to_replace_t *   itr_p ,
  1528.     boolean32           itr_is_user ,          // user or group
  1529.     boolean32           itr_old_local ,
  1530.     char *              id_old_name ,
  1531.     char *              id_old_uuid ,
  1532.     boolean32           itr_new_local ,
  1533.     char *              id_new_name ,
  1534.     char *              id_new_uuid ,
  1535.     error_status_t *    pStatus
  1536. )
  1537. {
  1538.     uuid_t      nil_uuid ;
  1539.     int         usr_grp_status ;
  1540.  
  1541.     uuid_create_nil( &nil_uuid, pStatus );
  1542.     STAT_CHK_PRINTF( *pStatus,"uuid_create_nil() Failure!") ;
  1543.  
  1544.     if( (id_old_name == NULL && id_old_uuid == NULL) ||
  1545.         (id_new_name == NULL && id_new_uuid == NULL) )
  1546.     {
  1547.         *pStatus = DSSAPPLY_NO_NAME_AND_UUID_STRINGS ;
  1548.         return ;
  1549.     }
  1550.  
  1551.     itr_p->fOldIsLocal = itr_old_local ;
  1552.     if( itr_old_local )
  1553.     {
  1554.         itr_p->old_id.local.name = id_old_name ;
  1555.         if( id_old_uuid )
  1556.         {
  1557.             uuid_from_string( id_old_uuid, &itr_p->old_id.local.uuid, pStatus )  ;
  1558.             STAT_CHK_PRINTF( *pStatus,"uuid_from_string(id_old_uuid) Failure!") ;
  1559.         }
  1560.         else
  1561.             itr_p->old_id.local.uuid = nil_uuid ;
  1562.     }
  1563.     else
  1564.     {
  1565.         itr_p->old_id.foreign.id.name = id_old_name ;
  1566.         if( id_old_uuid )
  1567.         {
  1568.             uuid_from_string( id_old_uuid, &itr_p->old_id.foreign.id.uuid, pStatus )  ;
  1569.             STAT_CHK_PRINTF( *pStatus,"uuid_from_string(id_old_uuid) Failure!") ;
  1570.         }
  1571.         else
  1572.             itr_p->old_id.foreign.id.uuid = nil_uuid ;
  1573.     }
  1574.  
  1575.     itr_p->fNewIsLocal = itr_new_local ;
  1576.     if( itr_new_local )
  1577.     {
  1578.         itr_p->new_id.local.name = id_new_name ;
  1579.         if( id_new_uuid )
  1580.         {
  1581.             uuid_from_string( id_new_uuid, &itr_p->new_id.local.uuid, pStatus )  ;
  1582.             STAT_CHK_PRINTF( *pStatus,"uuid_from_string(id_new_uuid) Failure!") ;
  1583.         }
  1584.         else
  1585.             itr_p->new_id.local.uuid = nil_uuid ;
  1586.     }
  1587.     else
  1588.     {
  1589.         itr_p->new_id.foreign.id.name = id_new_name ;
  1590.         if( id_new_uuid )
  1591.         {
  1592.             uuid_from_string( id_new_uuid, &itr_p->new_id.foreign.id.uuid, pStatus )  ;
  1593.             STAT_CHK_PRINTF( *pStatus,"uuid_from_string(id_new_uuid) Failure!") ;
  1594.         }
  1595.         else
  1596.             itr_p->new_id.foreign.id.uuid = nil_uuid ;
  1597.     }
  1598.  
  1599.     *pStatus = error_status_ok ;
  1600.  
  1601.     return ;
  1602.  
  1603. } // bld_id_to_repl()
  1604.  
  1605.  
  1606. /**************************************************************************
  1607. *
  1608. * init_globals()
  1609. *
  1610. \*************************************************************************/
  1611. void
  1612. init_globals( void )
  1613. {
  1614.     int             j ;
  1615.     error_status_t  Status ;
  1616.  
  1617.     sec_id_pac_t    PAC ;
  1618.  
  1619.     num_errors = 0 ;
  1620.  
  1621.     num_sec_acl_entries = 0 ;
  1622.  
  1623.     sec_acl_type       = sec_acl_type_object ;
  1624.  
  1625.     // reset pointers
  1626.  
  1627.     pEntEntries     = NULL ;
  1628.     sae_p           = NULL ;
  1629.     err_buf_p       = NULL ;
  1630.  
  1631.     // initialize arrays
  1632.     for( j=0; j< UUID_NAME_LEN; j++ )
  1633.         sec_mgr_uuid_text[ j ] = '\0' ;
  1634.  
  1635.     // create sec_acl_manager_type uuid
  1636.     strcpy( sec_mgr_uuid_text, DIR_ACL_MGR ) ;     // from acl_mgr_def.h
  1637.     uuid_from_string( sec_mgr_uuid_text, &sec_mgr_uuid, &Status ) ;
  1638.     STAT_CHK_PRINTF( Status, "uuid_from_String(sec_mgr_uuid) Failed!\n" ) ;
  1639.  
  1640.     // get default realm
  1641.     get_login_PAC(
  1642.         &PAC,
  1643.         &Status ) ;
  1644.     if( Status != error_status_ok )
  1645.     {
  1646.         printf("\n**\aget_login_PAC() Error!!\n" ) ;
  1647.         DosExit(0,0);
  1648.     }
  1649.     else
  1650.         default_realm = PAC.realm ;
  1651.  
  1652. } // init_globals()
  1653.  
  1654.  
  1655. /**************************************************************************
  1656. *
  1657. * init_itr() - initialize itr structure
  1658. *
  1659. \*************************************************************************/
  1660. void
  1661. init_itr(
  1662.     id_to_replace_t *  itr_p
  1663. )
  1664. {
  1665.  
  1666. } // init_itr()
  1667.  
  1668.  
  1669. /**************************************************************************
  1670. *
  1671. * init_sec_acl() - initialize sec_acl[]
  1672. *
  1673. * note: there is assumed to be only on sec_acl_t in a sec_acl_list
  1674. *
  1675. \*************************************************************************/
  1676. void
  1677. init_sec_acl(
  1678.     sec_acl_t *         sa_p ,          // ptr to sec_acl_t to initialize
  1679.     unsigned32          num_sec_acl_entriess ,
  1680.     sec_acl_entry_t *   sae_p ,
  1681.     error_status_t *    isa_stat
  1682. )
  1683. {
  1684.     // create default realm data
  1685. /*****
  1686.     // note will later use default realm data from login pac
  1687.     uuid_create_nil( &( sa_p->default_realm.uuid ), isa_stat );
  1688.     STAT_CHK_PRINTF( *isa_stat,"uuid_create_nil() Failure!") ;
  1689.  
  1690.     sa_p->default_realm.name = NULL ;
  1691. *******/
  1692.     sa_p->default_realm = default_realm ;
  1693.  
  1694.     sa_p->sec_acl_manager_type = sec_mgr_uuid ;
  1695.  
  1696.     sa_p->num_entries = num_sec_acl_entries ;
  1697.     sa_p->sec_acl_entries = sae_p ;
  1698.  
  1699. } // init_sec_acl()
  1700.  
  1701.  
  1702. /**************************************************************************
  1703. *
  1704. * init_sec_acl_entries() - initialize sec_acl_entries[]
  1705. *
  1706. \*************************************************************************/
  1707. void
  1708. init_sec_acl_entries(
  1709.     sec_acl_entry_t *   sae_p ,              // ptr to sec_acl_
  1710.     unsigned32          num_sec_acl_entries ,
  1711.     error_status_t *    isae_stat
  1712. )
  1713. {
  1714.     int             j ;
  1715.  
  1716.     for( j=0; j<num_sec_acl_entries; j++ )
  1717.     {
  1718.         ( sae_p+j )->perms = 0 ;
  1719.  
  1720.         ( sae_p+j )->entry_info.entry_type = sec_acl_e_type_foreign_user ;
  1721.  
  1722.         uuid_create_nil( &( ( sae_p+j )->
  1723.                 entry_info.tagged_union.foreign_id.id.uuid), isae_stat );
  1724.         STAT_CHK_PRINTF( *isae_stat,"uuid_create_nil() failure!") ;
  1725.  
  1726.         ( sae_p+j )->entry_info.tagged_union.foreign_id.id.name = NULL ;
  1727.  
  1728.         uuid_create_nil( &( ( sae_p+j )->
  1729.                 entry_info.tagged_union.foreign_id.realm.uuid), isae_stat );
  1730.         STAT_CHK_PRINTF( *isae_stat,"uuid_create_nil() failure!") ;
  1731.  
  1732.         ( sae_p+j )->entry_info.tagged_union.foreign_id.realm.name = NULL ;
  1733.  
  1734.         ( sae_p+j )->entry_info.entry_type = sec_acl_e_type_extended ;
  1735.     }
  1736.  
  1737.     return ;
  1738.  
  1739. } // init_sec_acl_entries()
  1740.  
  1741.  
  1742.  
  1743. /**************************************************************************
  1744. *
  1745. *   parse_apply_err()
  1746. *
  1747. \*************************************************************************/
  1748. void
  1749. parse_apply_err(
  1750.     unsigned long       ulMsgID,
  1751.     unsigned char * *   ppErr_Text ,
  1752.     error_status_t *    pStatus
  1753. )
  1754. {
  1755.  
  1756.  
  1757.  
  1758.    char           szError[512];
  1759.    unsigned long  ulMsgLen=0;
  1760.    APIRET         apiRC=0;
  1761.  
  1762.    // Get OS/2 message text...
  1763.    //
  1764.    apiRC = DosGetMessage(NULL, 0, szError, sizeof(szError), ulMsgID,
  1765.                                  "dss.msg", &ulMsgLen);
  1766.  
  1767.    if (apiRC == NO_ERROR || apiRC == ERROR_MR_MSG_TOO_LONG)
  1768.    {
  1769.  
  1770.       szError[ulMsgLen-2] = '\0';
  1771.       printf("\n ** ERROR **\n %s \n", szError);
  1772.    }
  1773.    else
  1774.    {
  1775.       // Something went wrong getting the message text.  At least
  1776.       // show the message number...
  1777.       //
  1778.       printf("Can't get DSS.MSG file (%d).  \n", ulMsgID );
  1779.    }
  1780.  
  1781.    *pStatus = error_status_ok ;
  1782.  
  1783.    return;
  1784.  
  1785. } // parse_apply_err()
  1786.  
  1787.  
  1788. /**************************************************************************
  1789. *
  1790. *   get_login_PAC()
  1791. *
  1792. \*************************************************************************/
  1793. void
  1794. get_login_PAC(
  1795.     sec_id_pac_t *  PAC,
  1796.     error_status_t * st
  1797. )
  1798. {
  1799.     error_status_t          stat ;
  1800.  
  1801.     sec_login_net_info_t    net_info, *net_info_p ;
  1802.  
  1803.     sec_login_handle_t      login_context ;
  1804.  
  1805.     if( debug )
  1806.         printf("\n  sec_login_get_current_context().." ) ;
  1807.  
  1808.     sec_login_get_current_context(
  1809.         &login_context,
  1810.         &stat ) ;
  1811.  
  1812.     if( stat != error_status_ok )
  1813.     {
  1814.         printf("\n** sec_login_get_current_context() Error! " ) ;
  1815.         *st = ~error_status_ok ;
  1816.         return ;
  1817.     }
  1818.     else {
  1819.            sec_login_certify_identity(login_context,&stat);
  1820.            if( stat!=error_status_ok) {
  1821.                                        *st = ~error_status_ok ;
  1822.                                        return;
  1823.                                       }
  1824.            if( debug )
  1825.                    printf(" Done! " ) ;
  1826.  
  1827.          }
  1828.  
  1829.  
  1830.     net_info_p = NULL ;         // to keep compiler happy
  1831.  
  1832.     if( debug )
  1833.        printf("\n  sec_login_inquire_net_info().." ) ;
  1834.     sec_login_inquire_net_info(
  1835.         login_context,
  1836.         &net_info,         // call allocates storage
  1837.         &stat ) ;
  1838.  
  1839.     if( stat != error_status_ok )
  1840.     {
  1841.         printf("\n** sec_login_inquire_net_info() Error! " ) ;
  1842.         *st = ~error_status_ok ;
  1843.         return ;
  1844.     }
  1845.     else
  1846.         if( debug )
  1847.             printf(" Done! " ) ;
  1848.  
  1849.     if( debug )
  1850.         printf("\n Login PAC Retrieved OK. ") ;
  1851.  
  1852.     net_info_p = &net_info;
  1853.  
  1854.     *PAC = net_info_p->pac ;
  1855.  
  1856.     sec_login_free_net_info( net_info_p ) ;
  1857.  
  1858.     *st = error_status_ok ;
  1859.  
  1860. } // get_login_PAC()
  1861.  
  1862.  
  1863.  
  1864. /**************************************************************************
  1865. *
  1866. * make_uuid_string()
  1867. * input  = uuid(12345678-c761-11ce-8b50-10005a7b953d)\n
  1868. * output = 12345678-c761-11ce-8b50-10005a7b953d
  1869. *
  1870. \*************************************************************************/
  1871. void
  1872. make_uuid_string(
  1873.     char *      str
  1874. )
  1875. {
  1876.     char *  cptr ;
  1877.     int     j ;
  1878.  
  1879.     while( *str++ != '(' ) ;
  1880.  
  1881.     cptr = str ;
  1882.  
  1883.     j = 0 ;
  1884.     while( *( str + j ) != ')' )
  1885.         j++ ;
  1886.  
  1887.     *( str + j ) = '\0' ;
  1888.  
  1889.     return ;
  1890.  
  1891. } // make_uuid_string()
  1892.  
  1893.  
  1894. /***************************************************************************
  1895.  
  1896.     the following code from applyc.cpp
  1897.  
  1898. ***************************************************************************/
  1899.  
  1900. /*------------------------------------------------------------------------
  1901. **
  1902. ** connect_to_server
  1903. **
  1904. **------------------------------------------------------------------------
  1905. */
  1906. BOOL
  1907. connect_to_server(
  1908.     handle_t    *pHandle,
  1909.     const char  *pszCell,
  1910.     const char  *pszRealm,
  1911.     const char  *pszServer
  1912. )
  1913. {
  1914.    char                 szCDSBindingLocation[1000];
  1915.    rpc_ns_handle_t      import_context;
  1916.    unsigned32           status = rpc_s_ok;
  1917.  
  1918.    sprintf(szCDSBindingLocation, "/.../%s/subsys/realms/%s/servers/%s",
  1919.             pszCell, pszRealm, pszServer);
  1920.  
  1921.    if( debug )
  1922.        printf("\nCDS Binding Loc=%s",szCDSBindingLocation ) ;
  1923.  
  1924.    // Begin the binding import loop.
  1925.    //
  1926.    rpc_ns_binding_import_begin(
  1927.        rpc_c_ns_syntax_default,
  1928.        (unsigned char *)szCDSBindingLocation,
  1929.        apply_v1_0_c_ifspec,
  1930.        NULL,
  1931.        &import_context,
  1932.        &status);
  1933.  
  1934.    if (status == rpc_s_ok)
  1935.    {
  1936.       // Import the first (and only) server...
  1937.       //
  1938.       rpc_ns_binding_import_next(
  1939.          import_context,
  1940.          pHandle,
  1941.          &status);
  1942.  
  1943.       // Delete the import context.
  1944.       //
  1945.       if (status == rpc_s_ok)
  1946.       {
  1947.          rpc_ns_binding_import_done(
  1948.             &import_context,
  1949.             &status);
  1950.  
  1951.          if (status != rpc_s_ok)
  1952.             printf("\n**rpc_ns_binding_import_done() Failed!\n");
  1953.       }
  1954.       else
  1955.          printf("\n**rpc_ns_binding_import_next() Failed!\n");
  1956.    }
  1957.    else
  1958.       printf("\n**rpc_ns_binding_import_begin() Failed\n");
  1959.  
  1960.    return (status == rpc_s_ok);
  1961. }
  1962.  
  1963.  
  1964. /****************************************************************************\
  1965. *
  1966. * function:   STAT_CHK()
  1967. *
  1968. * synopsis:
  1969. *
  1970. * note:
  1971. *
  1972. \***************************************************************************/
  1973. error_status_t
  1974. STAT_CHK(
  1975.     error_status_t      status_to_check ,
  1976.     char *              log_text ,
  1977.     unsigned32          action
  1978. )
  1979. {
  1980.     if( status_to_check != error_status_ok )
  1981.     {
  1982. //        LogError( &status_to_check, log_text ) ;
  1983.  
  1984.         if( action == ABORT )
  1985.             exit( status_to_check ) ;
  1986.     }
  1987.  
  1988.     return( status_to_check ) ;
  1989.  
  1990. } // STAT_CHK()
  1991.  
  1992.  
  1993.  
  1994.  
  1995. //**************************  end of DSSAPPLY.C  *************************
  1996.