17.00 - 17.05 - C関数定義 - Advanced SQL Engine - Teradata Database

Teradata Vantage™ - SQL外部ルーチン プログラミング

Product
Advanced SQL Engine
Teradata Database
Release Number
17.00
17.05
Published
2020年6月
Content Type
プログラミング リファレンス
Publication ID
B035-1147-170K-JPN
Language
日本語 (日本)
次に示すUDFのサンプルCコードでは、セキュリティ ポリシーを強制的に実施します。この例で使用されるポリシーは、次のとおりです。
  • INSERT操作の場合、新しい行にはセッションの機密度ラベルが含まれている必要がある。
  • UPDATE操作の場合、セッションのセキュリティ ラベルが対象行のラベルよりも上位でなければ、更新を拒否する必要がある。UPDATEが許可された場合、更新された行のラベルにはセッションのレベルとカテゴリ(セッションのカテゴリと現在行のカテゴリの組み合わせ)を含める必要がある。
  • DELETE操作の場合、機密度レベルが未分類であり、機密度カテゴリがNULLでないときには、行は削除できない。
  • SELECT操作の場合、セッションの機密度ラベルが対象行のラベルよりも上位である必要がある。
#define SQL_TEXT Latin_Text
#include <sqltypes_td.h>

typedef unsigned char byte;

// INSERT Level UDF
void InsertLevel( short int  *sess_level,
                  short int  *new_row )
{
   // Level of new row equals that of the session
   // return level to DBS
   *new_row = *sess_level;
   return;
}

// UPDATE Level UDF

void UpdateLevel( short int  *sess_level,
                  short int  *curr_row,
                  short int  *upd_row )
{
   // Session's level must be equal to or greater than row’s to allow
   // the update. If update is allowed, then the level of the updated
   // row is changed to that of the session.

   // can the session update the row?
   if (*sess_level >= *curr_row)
      // set level in updated row to session's level
      *upd_row = *sess_level;
   else
      // update is not allowed
      *upd_row = 0;
   return;
}

//DELETE Level UDF

void DeleteLevel( short int  *curr_row,
                  char       *result )
{
   // Row can only be deleted if it has a label of unclassified
   if (*curr_row == 1)
      // delete is allowed
      *result = 'T';
   else
      *result = 'F';
   return;
}

// SELECT Level UDF

void ReadLevel( short int  *sess_level,
                short int  *curr_row,
                char       *result )
{
   // Read allowed if session's level is equal to or greater than row's
   if (*sess_level >= *curr_row)
      // select is allowed
      *result = 'T';
   else
      //select is not allowed
      *result = 'F';
   return;
}

//INSERT Category UDF

void InsertCategory( byte sess_cat[],
                     byte new_row[],
                     int *indic1,
                     int *retindic)
{
   int i;

   // policy is that category for new row equals that for the session

   if (*indic1 == -1)  // null session, then null new row
      *retindic = -1;
   else  // non-null session, then new row equals session
   {
      *retindic = 0;
      for (i  =  0; i  <  8; i++)
         new_row[i] = sess_cat[i];
   }
   return;
}

// UPDATE Category UDF

void UpdateCategory( byte sess_cat[],
                     byte curr_row[],
                     byte new_row[],
                     int *indic1,
                     int *indic2,
                     int *retindic)

{

   int i;

   // Policy is that row can be updated if user's category is a
   // superset of the row's category. If the update is allowed,
   // then the category for the new row is a combination of the
   // categories of the current row plus those of the session.

   if (*indic1 == -1)  // if session’s category is null
   {
      if (*indic2 == -1) // if row’s category is null, update is allowed
      {  // both are null
         *retindic = -1;  // new row constraint is null
         return;
      }
      else
      {   // session is null and row is not, so disallow update
         *retindic = 0;
         for (i = 0; i < 8; i++)
            new_row[i] = 0;  // set return category to null for error
         return;
      }
   }
   // session’s category is not null
   *retindic = 0;  // must return a category
   if (*indic2 == -1)  // if row’s category is null, then update
                       // is allowed
      {
         for (i = 0; i < 8; i++)
            new_row[i] = sess_cat[i];  //set return category to session
         return;
      }
   // session’s category and input row’s category are not null
   for (i = 0; i < 8; i++)  // does session dominate row?
      if ((sess_cat[i] & curr_row[i]) != curr_row[i])
         // no it does not, so update is not allowed
         {
         for (i = 0; i < 8; i++)
            new_row[i] = 0;  // set return category to all zeroes
                              //for error
         return;
         }
   // update is allowed; set return category to a combination of
   // session’s and row’s categories
   for (i = 0; i < 8; i++)
      new_row[i] = sess_cat[i] | curr_row[i];  //inclusive or
   return;
}

// DELETE Category UDF

void DeleteCategory( byte curr_row[],
                     char *result,
                     int *indic1,
                     int *retindic)

{
   // Policy is that row can be deleted only if its category is null
   *retindic = 0;  // result is always not null
   if (*indic1 == -1)  // if row's category is not null
      *result = 'T';   // delete is allowed
   else
      *result = 'F';   // delete is not allowed
   return;
}

// SELECT Category UDF

void ReadCategory( byte sess_cat[],
                   byte curr_row[],
                   char *result,
                   int *indic1,
                   int *indic2,
                   int *retindic)

{
   int i;

   // Policy is that row can be selected if user's category is a
   // superset of the row's category.
   *retindic = 0; // result is always not null
   *result = 'T';
   if ((*indic1 == *indic2) && (*indic1 == -1)) // both are null
      return;  // allow select
   if (*indic2 == -1)  // row is null and session isn't
      return;  // allow select
   // both are not null
   *result = 'F';
   for (i = 0; i < 8; i++)  // does session dominate row
      // does session dominate
      if ((curr_row[i] ^ sess_cat[i]) & curr_row[i])
         return;  // no, so select is not allowed
   *result = 'T';  // yes, so allow select
   return;
}