Example: ILE C program for creating roles and profiles for your Coprocessor

Change this IBM i ILE C program example to suit your needs for creating a role or a profile for your Coprocessor.

Note: Read the Code license and disclaimer information for important legal information.

If you choose to use this program example, change it to suit your specific needs. For security reasons, IBM recommends that you individualize these program examples rather than using the default values provided.

/*-------------------------------------------------------------------*/
/*  CRTROLEPRF                                                       */
/*                                                                   */
/*  Sample program to create roles and profiles in the           */
/*  cryptographic adapter.                                           */
/*                                                                   */
/*                                                                   */
/*  COPYRIGHT 5769-SS1 (C) IBM CORP. 1999, 2007                      */
/*                                                                   */
/*  This material contains programming source code for your          */
/*  consideration.  These examples have not been thoroughly          */
/*  tested under all conditions.  IBM, therefore, cannot             */
/*  guarantee or imply reliability, serviceability, or function      */
/*  of these program.  All programs contained herein are             */
/*  provided to you "AS IS".  THE IMPLIED WARRANTIES OF              */
/*  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE         */
/*  ARE EXPRESSLY DISCLAIMED.  IBM provides no program services for  */
/*  these programs and files.                                        */
/*                                                                   */
/*                                                                   */
/* Note: Input format is more fully described in Chapter 2 of        */
/*       IBM  CCA Basic Services Reference and Guide                 */
/*       (SC31-8609) publication.                                    */
/*                                                                   */
/* Parameters:                                                       */
/*   none.                                                           */
/*                                                                   */
/* Example:                                                          */
/*   CALL PGM(CRTROLEPRF)                                            */
/*                                                                   */
/* Use these commands to compile this program on the system:         */
/* CRTCMOD MODULE(CRTROLEPRF) SRCFILE(SAMPLE)                        */
/* CRTPGM  PGM(CRTROLEPRF) MODULE(CRTROLEPRF)                        */
/*         BNDSRVPGM(QCCA/CSUAACI QCCA/CSNBOWH)                      */
/*                                                                   */
/* Note: Authority to the CSUAACI and CSNBOWH service programs       */
/*       in the QCCA library is assumed.                             */
/*                                                                   */
/* The Common Cryptographic Architecture (CCA) verbs used are        */
/* Access_Control_Initialization (CSUAACI) and                       */
/* One_Way_Hash (CSNBOWH).                                           */
/*                                                                   */
/* Note: This program assumes the device you want to use is          */
/*       already identified either by defaulting to the CRP01        */
/*       device or has been explicitly named using the               */
/*       Cryptographic_Resource_Allocate verb. Also this             */
/*       device must be varied on and you must be authorized         */
/*       to use this device description.                             */
/*                                                                   */
/* Note: Before running this program, the clock in the  must be  */
/*       set using Cryptographic_Facility_Control (CSUACFC) in order */
/*       to be able to logon afterwards.                             */
/*                                                                   */
/*-------------------------------------------------------------------*/

#include "csucincl.h"      /* header file for CCA Cryptographic
                              Service Provider                       */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void main(int argc, char *argv[]) {

/*-------------------------------------------------------------------*/
/* standard return codes                                             */
/*-------------------------------------------------------------------*/

#define ERROR    -1
#define OK        0
#define WARNING   4

/*-------------------------------------------------------------------*/
/* Variables used for parameters on CCA APIs                         */
/*-------------------------------------------------------------------*/
  long return_code;
  long reason_code;
  long exit_data_length;
  char exit_data[2];
  char rule_array[4][8];
  long rule_array_count;
  long verb_data1_length;
  long verb_data2_length;
  long hash_length;
  long text_length;
  char *text;
  char chaining_vector[128];
  long chaining_vector_length;

/*-------------------------------------------------------------------*/
/* Definitions for profiles                                          */
/*-------------------------------------------------------------------*/
 typedef struct
    {
     char        version[2];           /* Profile structure version  */
     short       length;               /* length of structure        */
     char        comment[20];          /* Description                */
     short       checksum;
     char        logon_failure_count;
     char        reserved;
     char        userid[8];            /* Name for this profile      */
     char        role[8];              /* Role that profile uses     */
     short       act_year;             /* Activation date - year     */
     char        act_month;            /* Activation date - month    */
     char        act_day;              /* Activation date - day      */
     short       exp_year;             /* Expiration date - year     */
     char        exp_month;            /* Expiration date - month    */
     char        exp_day;              /* Expiration date - day      */
     short       total_auth_data_length;
     short       field_type;
     short       auth_data_length_1;
     short       mechanism;            /* Authentication mechanism   */
     short       strength;             /* Strength of mechanism      */
     short       mech_exp_year;        /* Mechanism expiration - year*/
     char        mech_exp_month;       /* Mech. expiration - month   */
     char        mech_exp_day;         /* Mechansim expiration - day */
     char        attributes[4];
     char        auth_data[20];        /* Secret data                */
    } profile_T;

 typedef struct
    {
     long        number;               /* Number profiles in struct  */
     long        reserved;
     profile_T   profile[3];
    } aggregate_profile;

 aggregate_profile * verb_data1;       /* Aggregate structure for    */
                                       /* defining profiles          */

/*-------------------------------------------------------------------*/
/* Definitions for roles                                             */
/*-------------------------------------------------------------------*/
 /*--------------------------------------------------------------*/
 /* Default role - access control points list -                  */
 /*                authorized to everything EXCEPT:              */
 /*   0x0018 - Load 1st part of Master Key                       */
 /*   0x0019 - Combine Master Key Parts                          */
 /*   0x001A - Set Master Key                                    */
 /*   0x0020 - Generate Random Master Key                        */
 /*   0x0032 - Clear New Master Key Register                     */
 /*   0x0033 - Clear Old Master Key Register                     */
 /*   0x0053 - Load 1st part of PKA Master Key                   */
 /*   0x0054 - Combine PKA Master Key Parts                      */
 /*   0x0057 - Set PKA Master Key                                */
 /*   0x0060 - Clear New PKA Master Key Register                 */
 /*   0x0061 - Clear Old PKA Master Key Register                 */
 /*   0x0110 - Set Clock                                         */
 /*   0x0111 - Reinitialize device                               */
 /*   0x0112 - Initialize access control system                  */
 /*   0x0113 - Change user profile expiration date               */
 /*   0x0114 - Change authentication data (eg. passphrase)       */
 /*   0x0115 - Reset password failure count                      */
 /*   0x0116 - Read Public Access Control Information            */
 /*   0x0117 - Delete user profile                               */
 /*   0x0118 - Delete role                                       */
 /*   0x0119 - Load Function Control Vector                      */
 /*   0x011A - Clear Function Control Vector                     */
 /*   0x011B - Force User Logoff                                 */
 /*   0x0200 - Register PKA Public Key Hash                      */
 /*   0x0201 - Register PKA Public Key, with cloning             */
 /*   0x0202 - Register PKA Public Key                           */
 /*   0x0203 - Delete Retained Key                               */
 /*   0x0204 - PKA Clone Key Generate                            */
 /*   0x0211 - 0x21F - Clone information - obtain 1-15           */
 /*--------------------------------------------------------------*/
 /* For access control points  0x01 - 0x127  */
 char default_bitmap[] =
     { 0x00, 0x03, 0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00,
       0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
       0x00, 0x0A, 0x80, 0x00, 0x88, 0x2F, 0x71, 0x10,
       0x10, 0x04, 0x03, 0x31, 0x80, 0x00, 0x00, 0x00,
       0xFF, 0x7F, 0x40, 0x6B, 0x80};

 /* For access control points  0x200 - 0x23F  */
 char default2_bitmap[] =
     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0x0F };

 /*--------------------------------------------------------------*/
 /* role #1 - authorized to same as default plus also            */
 /*           authorized to:                                     */
 /*   0x0018 - Load 1st part of Master Key                       */
 /*   0x0020 - Generate Random Master Key                        */
 /*   0x0032 - Clear New Master Key Register                     */
 /*   0x0053 - Load 1st part of PKA Master Key                   */
 /*   0x0060 - Clear New PKA Master Key Register                 */
 /*   0x0119 - Load Function Control Vector                      */
 /*   0x0201 - Register PKA Public Key, with cloning             */
 /*   0x0202 - Register PKA Public Key                           */
 /*   0x0203 - Delete Retained Key                               */
 /*   0x0204 - PKA Clone Key Generate                            */
 /*   0x0211 - 0x215 - Clone information - obtain 1-5            */
 /*   0x0221 - 0x225 - Clone information - install 1-5           */
 /*--------------------------------------------------------------*/
 char role1_bitmap[] =
     { 0x00, 0x03, 0xF0, 0x9D, 0x80, 0x00, 0x20, 0x00,
       0x80, 0x00, 0x10, 0x00, 0x80, 0x00, 0x00, 0x00,
       0x00, 0x0A, 0x80, 0x00, 0x88, 0x1F, 0x71, 0x10,
       0x10, 0x04, 0x03, 0x11, 0x80, 0x00, 0x00, 0x00,
       0xFF, 0x7F, 0x00, 0x4F, 0x80};
 char role1_bitmap2[] =
     { 0x78, 0x00, 0x7C, 0x00, 0x7C, 0x00, 0xE6, 0x0F };

 /*--------------------------------------------------------------*/
 /* role #2 - authorized to same as default plus also            */
 /*           authorized to:                                     */
 /*   0x0019 - Combine Master Key Parts                          */
 /*   0x001A - Set Master Key                                    */
 /*   0x0033 - Clear Old Master Key Register                     */
 /*   0x0054 - Combine PKA Master Key Parts                      */
 /*   0x0057 - Set PKA Master Key                                */
 /*   0x0061 - Clear Old Master Key Register                     */
 /*   0x011A - Clear Function Control Vector                     */
 /*   0x0200 - Register PKA Public Key Hash                      */
 /*   0x0201 - Register PKA Public Key, with cloning             */
 /*   0x0203 - Delete Retained Key                               */
 /*   0x0204 - PKA Clone Key Generate                            */
 /*   0x0216 - 0x21A - Clone information - obtain 6-10           */
 /*   0x0226 - 0x22A - Clone information - install 6-10          */
 /*--------------------------------------------------------------*/
 char role2_bitmap[] =
     { 0x00, 0x03, 0xF0, 0x7D, 0x80, 0x00, 0x10, 0x00,
       0x80, 0x00, 0x09, 0x00, 0x40, 0x00, 0x00, 0x00,
       0x00, 0x0A, 0x80, 0x00, 0x88, 0x1F, 0x71, 0x10,
       0x10, 0x04, 0x03, 0x31, 0x80, 0x00, 0x00, 0x00,
       0xFF, 0x7F, 0x00, 0x2F, 0x80};
 char role2_bitmap2[] =
     { 0xD8, 0x00, 0x03, 0xE0, 0x03, 0xE0, 0xE6, 0x0F };

 /*--------------------------------------------------------------*/
 /* role #3 - authorized to same as default plus also            */
 /*           authorized to:                                     */
 /*   0x0110 - Set Clock                                         */
 /*   0x0111 - Reinitialize device                               */
 /*   0x0112 - Initialize access control system                  */
 /*   0x0113 - Change user profile expiration date               */
 /*   0x0114 - Change authentication data (eg. passphrase)       */
 /*   0x0115 - Reset password failure count                      */
 /*   0x0116 - Read Public Access Control Information            */
 /*   0x0117 - Delete user profile                               */
 /*   0x0118 - Delete role                                       */
 /*   0x011B - Force User Logoff                                 */
 /*   0x0200 - Register PKA Public Key Hash                      */
 /*   0x0201 - Register PKA Public Key, with cloning             */
 /*   0x0203 - Delete Retained Key                               */
 /*   0x0204 - PKA Clone Key Generate                            */
 /*   0x021B - 0x21F - Clone information - obtain 11-15          */
 /*   0x022B - 0x22F - Clone information - install 11-15         */
 /*--------------------------------------------------------------*/
 char role3_bitmap[] =
     { 0x00, 0x03, 0xF0, 0x1D, 0x00, 0x00, 0x00, 0x00,
       0x80, 0x00, 0x00, 0x00, 0xC0, 0x00, 0x00, 0x00,
       0x00, 0x0A, 0x80, 0x00, 0x88, 0x1F, 0x71, 0x10,
       0x10, 0x04, 0x03, 0x31, 0x80, 0x00, 0x00, 0x00,
       0xFF, 0x7F, 0xFF, 0x9F, 0x80};
 char role3_bitmap2[] =
     { 0xD8, 0x00, 0x00, 0x1F, 0x00, 0x1F, 0xE6, 0x0F };

 /*--------------------------------------------------------------*/
 /* Structures for defining the access control points in a role  */
 /*--------------------------------------------------------------*/
 struct access_control_points_header
   {
    short        number_segments;       /* Number of segments of */
                                        /* the access points map */
    short        reserved;
   } access_control_points_header;

 struct access_control_points_segment_header
     {
       short     start_bit;             /* Starting bit in this  */
                                        /* segment.              */
       short     end_bit;               /* Ending bit            */
       short     number_bytes;          /* Number of bytes in    */
                                        /* this segment          */
       short     reserved;
   } access_control_points_segment_header;

 /*--------------------------------------------------------------*/
 /* Structure for defining a role                                */
 /*--------------------------------------------------------------*/
 struct role_header
    {
     char                     version[2];
     short                    length;
     char                     comment[20];
     short                    checksum;
     short                    reserved1;
     char                     role[8];
     short                    auth_strength;
     short                    lower_time;
     short                    upper_time;
     char                     valid_days_of_week;
     char                     reserved2;
    } role_header;

 /*--------------------------------------------------------------*/
 /* Structure for defining aggregate roles                       */
 /*--------------------------------------------------------------*/
 struct aggregate_role_header
    {
     long        number;
     long        reserved;
    } aggregate_role_header;

 char * verb_data2;


 char * work_ptr;
 char *bitmap1, *bitmap2;
 int i;                      /* Loop counter                     */

 /*--------------------------------------------------------------*/
 /* >>>>>>>> Start of code <<<<<<<<<<<<<<<<<<                    */
 /*--------------------------------------------------------------*/
 /*--------------------------------------------------------------*/
 /* Allocate storage for the aggregate role structure            */
 /*--------------------------------------------------------------*/
 verb_data2 = malloc(sizeof(aggregate_role_header) +
                     sizeof(role_header) * 3 +
                     sizeof(access_control_points_header) * 3 +
                     sizeof(access_control_points_segment_header)
                     * 6  +  /* 3 roles * 2 segments each */
                     sizeof(default_bitmap) * 3 +
                     sizeof(default2_bitmap) * 3);

 work_ptr = verb_data2;             /* Set working pointer to
                                    start of verb data 2 storage */

 aggregate_role_header.number = 3;  /* Define/replace 3 roles    */
 aggregate_role_header.reserved = 0;
                                    /* Copy header into verb data
                                       2 storage.                */
 memcpy(work_ptr,(void*)&aggregate_role_header,
        sizeof(aggregate_role_header));

                                    /* Adjust work pointer to point
                                       after header.             */
 work_ptr += sizeof(aggregate_role_header);

 /*--------------------------------------------------------------*/
 /* Fill in the fields of the role definitions.                  */
 /*  Each role is version 1, has authentication strength of 0,   */
 /*  has valid time from 12:00 Midnight (0) to 23:59 (x173B),    */
 /*  is valid every day of the week. (xFE is 7 bits set),        */
 /*  has one access control points segment that starts at bit 0  */
 /*  and goes to bit x11F, and has 20 spaces for a comment.      */
 /*--------------------------------------------------------------*/
   role_header.version[0]                  = 1;
   role_header.version[1]                  = 0;
   role_header.length                      = sizeof(role_header) +
                     sizeof(access_control_points_header)  +
                 2 * sizeof(access_control_points_segment_header) +
                  sizeof(default_bitmap) + sizeof(default2_bitmap);
   role_header.checksum                    = 0;
   role_header.reserved1                   = 0;
   role_header.auth_strength               = 0;
   role_header.lower_time                  = 0;
   role_header.upper_time                  = 0x173B;
   role_header.valid_days_of_week          = 0xFE;
   role_header.reserved2                   = 0;
   memset(role_header.comment,' ', 20);

   access_control_points_header.number_segments = 2;
   access_control_points_header.reserved        = 0;
   access_control_points_segment_header.reserved     = 0;

 for (i=0; i<3; i++)
 {
   switch (i) {
           /*------------------------------------------------*/
           /* Set name for ROLE1                             */
           /*------------------------------------------------*/
     case 0:
        memcpy(role_header.role, "ROLE1   ", 8);
        bitmap1 = role1_bitmap;
        bitmap2 = role1_bitmap2;

        break;

           /*------------------------------------------------*/
           /* Set name for ROLE2                             */
           /*------------------------------------------------*/
     case 1:
        memcpy(role_header.role, "ROLE2   ", 8);
        bitmap1 = role2_bitmap;
        bitmap2 = role2_bitmap2;
        break;

           /*------------------------------------------------*/
           /* Set name for ROLE3                             */
           /*------------------------------------------------*/
     case 2:
        memcpy(role_header.role, "ROLE3   ", 8);
        bitmap1 = role3_bitmap;
        bitmap2 = role3_bitmap2;
    }

   /*---------------------------------------------------*/
   /* Copy role header                                  */
   /*---------------------------------------------------*/
   memcpy(work_ptr,(void*)&role_header, sizeof(role_header));

                                    /* Adjust work pointer to
                                       point after role header. */
   work_ptr += sizeof(role_header);

   /*---------------------------------------------------*/
   /* Copy access control points header                 */
   /*---------------------------------------------------*/
   memcpy(work_ptr,
          (void *)&access_control_points_header,
          sizeof(access_control_points_header));

                                    /* Adjust work pointer to
                                       point after header.  */
   work_ptr += sizeof(access_control_points_header);

   /*---------------------------------------------------*/
   /* Copy access control points segment 1              */
   /*---------------------------------------------------*/
   access_control_points_segment_header.start_bit   = 0;
   access_control_points_segment_header.end_bit   = 0x127;
   access_control_points_segment_header.number_bytes =
                                            sizeof(default_bitmap);
   memcpy(work_ptr,
          (void *)&access_control_points_segment_header,
          sizeof(access_control_points_segment_header));

                                    /* Adjust work pointer to
                                       point after header.  */
   work_ptr += sizeof(access_control_points_segment_header);

   /*---------------------------------------------------*/
   /* Copy access control points segment 1 bitmap       */
   /*---------------------------------------------------*/
   memcpy(work_ptr, bitmap1, sizeof(default_bitmap));

                                    /* Adjust work pointer to
                                       point after bitmap.  */
   work_ptr += sizeof(default_bitmap);

   /*---------------------------------------------------*/
   /* Copy access control points segment 2              */
   /*---------------------------------------------------*/
   access_control_points_segment_header.start_bit   = 0x200;
   access_control_points_segment_header.end_bit   = 0x23F;
   access_control_points_segment_header.number_bytes =
                                            sizeof(default2_bitmap);

   memcpy(work_ptr,
          (void *)&access_control_points_segment_header,
          sizeof(access_control_points_segment_header));

                                    /* Adjust work pointer to
                                       point after header.  */
   work_ptr += sizeof(access_control_points_segment_header);

   /*---------------------------------------------------*/
   /* Copy access control points segment 2 bitmap       */
   /*---------------------------------------------------*/
   memcpy(work_ptr, bitmap2, sizeof(default2_bitmap));

                                    /* Adjust work pointer to
                                       point after bitmap.  */
   work_ptr += sizeof(default2_bitmap);
 }


 /*---------------------------------------------------------------*/
 /* Allocate storage for aggregate profile structure              */
 /*---------------------------------------------------------------*/
 verb_data1 = malloc(sizeof(aggregate_profile));

 verb_data1->number    = 3;     /* Define 3 profiles              */
 verb_data1->reserved  = 0;

 /*---------------------------------------------------------------*/
 /* Each profile:                                                 */
 /*  will be version 1,                                           */
 /*  have an activation date of 1/1/2013,                         */
 /*  have an expiration date of 6/30/2020,                        */
 /*  use passphrase hashed with SHA1 for the mechanism (0x0001),  */
 /*  will be renewable  (attributes = 0x8000)                     */
 /*  and has 20 spaces for a comment                              */
 /*---------------------------------------------------------------*/
 for (i=0; i<3; i++)
  {
   verb_data1->profile[i].length                 = sizeof(profile_T);
   verb_data1->profile[i].version[0]             = 1;
   verb_data1->profile[i].version[1]             = 0;
   verb_data1->profile[i].checksum               = 0;
   verb_data1->profile[i].logon_failure_count    = 0;
   verb_data1->profile[i].reserved               = 0;
   verb_data1->profile[i].act_year               = 2013;
   verb_data1->profile[i].act_month              = 1;
   verb_data1->profile[i].act_day                = 1;
   verb_data1->profile[i].exp_year               = 2020;
   verb_data1->profile[i].exp_month              = 6;
   verb_data1->profile[i].exp_day                = 30;
   verb_data1->profile[i].total_auth_data_length = 0x24;
   verb_data1->profile[i].field_type             = 0x0001;
   verb_data1->profile[i].auth_data_length_1     = 0x20;
   verb_data1->profile[i].mechanism              = 0x0001;
   verb_data1->profile[i].strength               = 0;
   verb_data1->profile[i].mech_exp_year          = 2020;
   verb_data1->profile[i].mech_exp_month         = 6;
   verb_data1->profile[i].mech_exp_day           = 30;
   verb_data1->profile[i].attributes[0]          = 0x80;
   verb_data1->profile[i].attributes[1]          = 0;
   verb_data1->profile[i].attributes[2]          = 0;
   verb_data1->profile[i].attributes[3]          = 0;

   memset(verb_data1->profile[i].comment, ' ', 20);

   memcpy(rule_array, "SHA-1   ", 8);
   rule_array_count        = 1;
   chaining_vector_length  = 128;
   hash_length             = 20;

   switch (i) {
         /*-------------------------------------------*/
         /* Set name, role, passphrase of profile 1   */
         /*-------------------------------------------*/
    case 0:
      memcpy(verb_data1->profile[i].userid,"SECOFR1 ",8);
      memcpy(verb_data1->profile[i].role, "ROLE1   ",8);
      text_length = 10;
      text        = "Is it safe";
      break;
         /*-------------------------------------------*/
         /* Set name, role, passphrase of profile 2   */
         /*-------------------------------------------*/
    case 1:
      memcpy(verb_data1->profile[i].userid,"SECOFR2 ",8);
      memcpy(verb_data1->profile[i].role, "ROLE2   ",8);
      text_length = 18;
      text        = "I think it is safe";
      break;
         /*-------------------------------------------*/
         /* Set name, role, passphrase of profile 3   */
         /*-------------------------------------------*/
    case 2:
      memcpy(verb_data1->profile[i].userid,"SECOFR3 ",8);
      memcpy(verb_data1->profile[i].role, "ROLE3   ",8);
      text_length = 12;
      text        = "Is what safe";
   }

   /*-------------------------------------------------*/
   /* Call One_Way_Hash to hash the pass-phrase       */
   /*-------------------------------------------------*/
   CSNBOWH( &return_code,
            &reason_code,
            &exit_data_length,
            exit_data,
            &rule_array_count,
            (char*)rule_array,
            &text_length,
            text,
            &chaining_vector_length,
            chaining_vector,
            &hash_length,
            verb_data1->profile[i].auth_data);
  }

 /*------------------------------------------------------*/
 /* Call Access_Control_Initialize (CSUAACI) to create   */
 /* the roles and profiles.                              */
 /*------------------------------------------------------*/
 rule_array_count = 2;
 memcpy(rule_array, "INIT-AC REPLACE ", 16);
 verb_data1_length = sizeof(aggregate_profile);
 verb_data2_length = sizeof(aggregate_role_header) +
                     sizeof(role_header) * 3 +
                     sizeof(access_control_points_header) * 3 +
                     sizeof(access_control_points_segment_header)
                     * 6  +  /* 3 roles * 2 segments each */
                     sizeof(default_bitmap) * 3 +
                     sizeof(default2_bitmap) * 3;

 CSUAACI( &return_code,
          &reason_code,
          &exit_data_length,
          exit_data,
          &rule_array_count,
          (char *)rule_array,
          (long *) &verb_data1_length,
          (char *) verb_data1,
          (long *) &verb_data2_length,
          (char *) verb_data2);

 if (return_code > WARNING)
    printf("Access_Control_Initialize failed.  Return/reason codes: \
%d/%d\n",return_code, reason_code);
 else
    printf("The new roles and profiles were successfully created\n");

 /*----------------------------------------------------------*/
 /* The Access_Control_Initialize SAPI verb needs to be      */
 /* called one more time to replace the DEFAULT role so that */
 /* a user that does not log on is not able to change any    */
 /* settings in the .                                    */
 /*----------------------------------------------------------*/
 work_ptr = verb_data2;             /* Set working pointer to
                                    start of verb data 2 storage */

 aggregate_role_header.number = 1;  /* Define/replace 1 roles    */
 aggregate_role_header.reserved = 0;
 memcpy(work_ptr,(void*)&aggregate_role_header,
        sizeof(aggregate_role_header));

                                    /* Adjust work pointer to
                                       point after header.  */
 work_ptr += sizeof(aggregate_role_header);

 /*--------------------------------------------------------------*/
 /* Fill in the fields of the role definitions.                  */
 /*  Each role is version 1, has authentication strength of 0,   */
 /*  has valid time from 12:00 Midnight (0) to 23:59 (x173B),    */
 /*  is valid every day of the week. (xFE is 7 bits set),        */
 /*  has one access control points segment that starts at bit 0  */
 /*  and goes to bit x11F, and has 20 spaces for a comment.      */
 /*--------------------------------------------------------------*/
 role_header.version[0]                  = 1;
 role_header.version[1]                  = 0;
 role_header.length                      = sizeof(role_header) +
                     sizeof(access_control_points_header)  +
                 2 * sizeof(access_control_points_segment_header) +
                  sizeof(default_bitmap) + sizeof(default2_bitmap);
 role_header.checksum                    = 0;
 role_header.reserved1                   = 0;
 role_header.auth_strength               = 0;
 role_header.lower_time                  = 0;
 role_header.upper_time                  = 0x173B;
 role_header.valid_days_of_week          = 0xFE;
 role_header.reserved2                   = 0;
 memset(role_header.comment,' ', 20);

 access_control_points_header.number_segments = 2;
 access_control_points_header.reserved        = 0;
 access_control_points_segment_header.reserved     = 0;

                                   /* DEFAULT role id must be in  */
                                   /* ASCII representation.       */
 memcpy(role_header.role, "\x44\x45\x46\x41\x55\x4C\x54\x20", 8);
 bitmap1 = default_bitmap;
 bitmap2 = default2_bitmap;

 /*---------------------------------------------------*/
 /* Copy role header                                  */
 /*---------------------------------------------------*/
 memcpy(work_ptr,(void*)&role_header, sizeof(role_header));

                                    /* Adjust work pointer to
                                       point after header.  */
 work_ptr += sizeof(role_header);

 /*---------------------------------------------------*/
 /* Copy access control points header                 */
 /*---------------------------------------------------*/
 memcpy(work_ptr,
          (void *)&access_control_points_header,
          sizeof(access_control_points_header));

                                    /* Adjust work pointer to
                                       point after header.  */
 work_ptr += sizeof(access_control_points_header);

 /*---------------------------------------------------*/
 /* Copy access control points segment 1              */
 /*---------------------------------------------------*/
 access_control_points_segment_header.start_bit   = 0;
 access_control_points_segment_header.end_bit   = 0x127;
 access_control_points_segment_header.number_bytes =
                                            sizeof(default_bitmap);
 memcpy(work_ptr,
          (void *)&access_control_points_segment_header,
          sizeof(access_control_points_segment_header));

                                    /* Adjust work pointer to
                                       point after header.  */
 work_ptr += sizeof(access_control_points_segment_header);

 /*---------------------------------------------------*/
 /* Copy access control points segment 1 bitmap       */
 /*---------------------------------------------------*/
 memcpy(work_ptr, bitmap1, sizeof(default_bitmap));

                                    /* Adjust work pointer to
                                       point after bitmap.  */
 work_ptr += sizeof(default_bitmap);

 /*---------------------------------------------------*/
 /* Copy access control points segment 2              */
 /*---------------------------------------------------*/
 access_control_points_segment_header.start_bit   = 0x200;
 access_control_points_segment_header.end_bit   = 0x23F;
 access_control_points_segment_header.number_bytes =
                                            sizeof(default2_bitmap);

 memcpy(work_ptr,
          (void *)&access_control_points_segment_header,
          sizeof(access_control_points_segment_header));

                                    /* Adjust work pointer to
                                       point after header.  */
 work_ptr += sizeof(access_control_points_segment_header);

 /*---------------------------------------------------*/
 /* Copy access control points segment 2 bitmap       */
 /*---------------------------------------------------*/
 memcpy(work_ptr, bitmap2, sizeof(default2_bitmap));

 rule_array_count = 2;
 memcpy(rule_array, "INIT-AC REPLACE ", 16);
 verb_data1_length = 0;
 verb_data2_length = sizeof(aggregate_role_header) +
                     sizeof(role_header)  +
                     sizeof(access_control_points_header)  +
                     sizeof(access_control_points_segment_header)
                     * 2  +
                     sizeof(default_bitmap)  +
                     sizeof(default2_bitmap);

 CSUAACI( &return_code,
          &reason_code,
          &exit_data_length,
          exit_data,
          &rule_array_count,
          (char *)rule_array,
          (long *) &verb_data1_length,
          (char *) verb_data1,
          (long *) &verb_data2_length,
          (char *) verb_data2);

 if (return_code > 4)
  printf("The default role was not replaced.  Return/reason code:\
        %d/%d\n",return_code, reason_code);
 else
  printf("The default role was successfully updated.\n");
}