xdas.c

Go to the documentation of this file.
00001 /*----------------------------------------------------------------------------
00002  * Copyright (c) 2006, Novell, Inc.
00003  * All rights reserved.
00004  * 
00005  * Redistribution and use in source and binary forms, with or without 
00006  * modification, are permitted provided that the following conditions are 
00007  * met:
00008  * 
00009  *     * Redistributions of source code must retain the above copyright 
00010  *       notice, this list of conditions and the following disclaimer.
00011  *     * Redistributions in binary form must reproduce the above copyright 
00012  *       notice, this list of conditions and the following disclaimer in the 
00013  *       documentation and/or other materials provided with the distribution.
00014  *     * Neither the name of the Novell nor the names of its contributors 
00015  *       may be used to endorse or promote products derived from this 
00016  *       software without specific prior written permission.
00017  * 
00018  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00019  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00020  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
00021  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
00022  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
00023  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
00024  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
00025  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
00026  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
00027  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
00028  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00029  *--------------------------------------------------------------------------*/
00030 
00039 #include <xdas.h>
00040 
00041 #ifdef LINUX_KERNEL
00042 # include <linux/kernel.h>
00043 # include <linux/module.h>
00044 # include <linux/gfp.h>
00045 # include <linux/slab.h>
00046 # include <linux/string.h>
00047 # include <linux/audit.h>
00048 # include <linux/time.h>
00049 
00050 MODULE_LICENSE("Dual BSD/GPL");
00051 MODULE_AUTHOR("John Calcote <jcalcote@novell.com>");
00052 MODULE_DESCRIPTION("OpenXDAS Submission API for the 2.6 SUSE Linux Kernel");
00053 
00054 #endif
00055 
00056 #define XDAS_AUDIT_SERVICE 0x00000001
00057 #define XDAS_AUDIT_SUBMIT  0x00000002
00058 #define XDAS_AUDIT_IMPORT  0x00000004
00059 #define XDAS_AUDIT_CONTROL 0x00000008
00060 #define XDAS_AUDIT_READ    0x00000010
00061 
00062 #define malloc(x) kmalloc(GFP_ATOMIC,(x))
00063 #define free(x)   kfree(x)
00064 
00065 #define xdas_assert(x)     (void)0
00066 #define xdas_elemcount(x)  (sizeof(x)/sizeof(*(x)))
00067 
00068 #define ORG_FLD_COUNT      6
00069 #define INT_FLD_COUNT      3
00070 #define TGT_FLD_COUNT      6
00071 
00072 #define MAX_TIME_SOURCE    1024
00073 #define MAX_TIME_ZONE      128
00074 
00075 typedef struct xdas_session_tag
00076 {
00077 #define XDAS_SESSION_SIG   0x58444153  /* 'XDAS' */
00078    unsigned signature;
00079    unsigned security;
00080    unsigned time_uncert_int;
00081    unsigned time_uncert_ind;
00082    char time_source[MAX_TIME_SOURCE];
00083    char time_zone[MAX_TIME_ZONE];
00084    struct audit_buffer * ab;
00085    char * org_info[ORG_FLD_COUNT];
00086 } xdas_session;
00087 
00088 typedef struct xdas_record_tag
00089 {
00090 #define XDAS_RECORD_SIG    0x52435244  /* 'RCRD' */
00091    unsigned signature;
00092    unsigned record_number;
00093    unsigned event_number;
00094    unsigned outcome;
00095    unsigned time_offset;
00096    char * int_info[INT_FLD_COUNT];
00097    char * tgt_info[TGT_FLD_COUNT];
00098    char * src_ref;
00099    char * evt_info;
00100    unsigned fmtlen;
00101    char * fmt;
00102    int last_status;
00103    int fmt_cache_dirty;
00104 } xdas_record;
00105 
00106 
00107 static int __init xdas_module_init(void)
00108 {
00109    return 0;
00110 }
00111 #ifdef LINUX_KERNEL
00112 module_init(xdas_module_init);
00113 #endif
00114 
00115 static void __exit xdas_module_exit(void)
00116 {
00117 }
00118 #ifdef LINUX_KERNEL
00119 module_exit(xdas_module_exit);
00120 #endif
00121 
00122 static char * strdup(const char * s)
00123 {
00124    size_t ssz = s? strlen(s) + 1: 0;
00125    if (ssz)
00126    {
00127       char * s2 = (char *)malloc(ssz);
00128       if (s2 != 0)
00129          memcpy(s2, s, ssz);
00130       return s2;
00131    }
00132    return 0;
00133 }
00134 
00135 static xdas_session * xdas_validate_session(xdas_audit_ref_t das_ref)
00136 {
00137    xdas_session * xs = (xdas_session *)das_ref;
00138    return (xs && xs->signature == XDAS_SESSION_SIG)? xs: 0;
00139 }
00140 
00141 static void xdas_set_session_rights(xdas_session * xs)
00142 {
00143    xs->security = XDAS_AUDIT_SERVICE | XDAS_AUDIT_SUBMIT 
00144          | XDAS_AUDIT_IMPORT | XDAS_AUDIT_CONTROL | XDAS_AUDIT_READ;
00145 }
00146 
00147 static int xdas_session_has_rights(xdas_session * xs, unsigned rights)
00148 {
00149    return (xs->security & rights) == rights? 1: 0;
00150 }
00151 
00152 static int xdas_set_time_info(xdas_session * xs)
00153 {
00155    *xs->time_source = 0;
00156 
00158    *xs->time_zone = 0;
00159 
00161    xs->time_uncert_int = 0;
00162    xs->time_uncert_ind = 0;
00163    return 0;
00164 }
00165 
00166 static void xdas_exit_laf(xdas_session * xs)
00167 {
00168    if (xs->ab != 0)
00169    {
00170       audit_log_end(xs->ab);
00171       xs->ab = 0;
00172    }
00173 }
00174 
00175 static int xdas_service_connect(int * minor, xdas_session * xs)
00176 {
00177 #define XDAS_LAF_TYPE 7000 
00179    struct audit_context * ctx = 0;
00180    gfp_t gfp_mask = 0;
00181    int type = XDAS_LAF_TYPE;
00182 
00183    if ((xs->ab = audit_log_start(ctx, gfp_mask, type)) == 0)
00184       return (*minor = OXDAS_MS_UNKNOWN_ERROR), XDAS_S_FAILURE;
00185 
00186    return 0;
00187 }
00188 
00189 static void xdas_internal_terminate_session(xdas_session * xs)
00190 {
00191    xdas_exit_laf(xs);
00192    free(xs->org_info[0]);
00193    free(xs);
00194 }
00195 
00196 static size_t xdas_calc_max_record_len(xdas_session * xs, xdas_record * xr)
00197 {
00198    unsigned i;
00199    size_t fmtsz;
00200 
00201    fmtsz = 4   /* HDR: */
00202          + 5   /* <hex_4_character_zero_padded_length_in_bytes>: */
00203          + sizeof(XDAS_RECORD_VERSION)
00204                /* <decimal_record_format_version>: */
00205          + 9   /* <hex_time_offset>: */
00206          + 9   /* <hex_time_uncertainty_interval>: */
00207          + 9   /* <hex_time_uncertainty_indicator>: */
00208          + strlen(xs->time_source) + 1   
00209                /* <str_time_source>: */
00210          + strlen(xs->time_zone) + 1       
00211                /* <str_time_zone>: */
00212          + 9   /* <hex_event_number>: */
00213          + 9;  /* <hex_outcome>: */
00214 
00215    fmtsz += 4; /* ORG:
00216                 * <org_location_name>:
00217                 * <org_location_address>:
00218                 * <org_service-type>:
00219                 * <org_auth_authority>:
00220                 * <org_principal_name>:
00221                 * <org_principal_id>:
00222                 */
00223    for (i = 0; i < xdas_elemcount(xs->org_info) && xs->org_info[i]; i++)
00224       fmtsz += strlen(xs->org_info[i]) + 1;
00225    for (; i< xdas_elemcount(xs->org_info); i++)
00226       fmtsz++;
00227 
00228    fmtsz += 4; /* INT:
00229                 * <int_auth_authority>:
00230                 * <int_domain_specific_name>:
00231                 * <int_domain_specific_id>:
00232                 */
00233    for (i = 0; i < xdas_elemcount(xr->int_info) && xr->int_info[i]; i++)
00234       fmtsz += strlen(xr->int_info[i]) + 1;
00235    for (; i< xdas_elemcount(xr->int_info); i++)
00236       fmtsz++;
00237 
00238    fmtsz += 4; /* TGT:
00239                 * <tgt_location_name>:
00240                 * <tgt_location_address>:
00241                 * <tgt_service-type>:
00242                 * <tgt_auth_authority>:
00243                 * <tgt_principal_name>:
00244                 * <tgt_principal_id>:
00245                 */
00246    for (i = 0; i < xdas_elemcount(xr->tgt_info) && xr->tgt_info[i]; i++)
00247       fmtsz += strlen(xr->tgt_info[i]) + 1;
00248    for (; i< xdas_elemcount(xr->tgt_info); i++)
00249       fmtsz++;
00250 
00251    fmtsz += 4  /* SRC: */
00252          + (xr->src_ref? strlen(xr->src_ref): 0) + 1; 
00253                /* <pointer_to_source_domain>: */
00254 
00255    fmtsz +=4   /* EVT: */
00256          + (xr->evt_info? strlen(xr->evt_info): 0) + 1   
00257                /* <event_specific_information>: */
00258          + 4;  /* END\0 */
00259 
00260    return fmtsz;
00261 }
00262 
00263 static int xdas_format_record(xdas_session * xs, xdas_record * xr)
00264 {
00265    char * fmt;
00266    unsigned fmtlen, i, ccnt;
00267    size_t fmtsz = xdas_calc_max_record_len(xs, xr);
00268 
00269    /* allocate buffer for record string */
00270    if ((fmt = (char *)malloc(fmtsz)) == 0)
00271       return -1;
00272 
00273    /* HDR:
00274     * <hex_4_character_zero_padded_length_in_bytes>:
00275     * <max_16_char_version_str>:
00276     * <str_version>:
00277     * <hex_time_offset>:
00278     * <hex_time_uncertainty_interval>:
00279     * <hex_time_uncertainty_indicator>:
00280     * <str_time_source>:
00281     * <str_time_zone>:
00282     * <hex_event_number>:
00283     * <hex_outcome>:
00284     */
00285    ccnt = sprintf(fmt, "HDR:0000:" XDAS_RECORD_VERSION ":%x:%x:%x:%s:%s:%x:%x:", 
00286          xr->time_offset, xs->time_uncert_int, xs->time_uncert_ind, 
00287          xs->time_source, xs->time_zone, xr->event_number, xr->outcome);
00288 
00289    /* ORG:
00290     * <org_location_name>:
00291     * <org_location_address>:
00292     * <org_service-type>:
00293     * <org_auth_authority>:
00294     * <org_principal_name>:
00295     * <org_principal_id>:
00296     */
00297    ccnt += sprintf(fmt + ccnt, "ORG:");
00298    for (i = 0; i < xdas_elemcount(xs->org_info) && xs->org_info[i]; i++)
00299       ccnt += sprintf(fmt + ccnt, "%s:", xs->org_info[i]);
00300    for (; i < xdas_elemcount(xs->org_info); i++)
00301       fmt[ccnt++] = ':';
00302 
00303    /* INT:
00304     * <int_auth_authority>:
00305     * <int_domain_specific_name>:
00306     * <int_domain_specific_id>:
00307     */
00308    ccnt += sprintf(fmt + ccnt, "INT:");
00309    for (i = 0; i < xdas_elemcount(xr->int_info) && xr->int_info[i]; i++)
00310       ccnt += sprintf(fmt + ccnt, "%s:", xr->int_info[i]);
00311    for (; i < xdas_elemcount(xr->int_info); i++)
00312       fmt[ccnt++] = ':';
00313 
00314    /* TGT:
00315     * <tgt_location_name>:
00316     * <tgt_location_address>:
00317     * <tgt_service-type>:
00318     * <tgt_auth_authority>:
00319     * <tgt_principal_name>:
00320     * <tgt_principal_id>:
00321     */
00322    ccnt += sprintf(fmt + ccnt, "TGT:");
00323    for (i = 0; i < xdas_elemcount(xr->tgt_info) && xr->tgt_info[i]; i++)
00324       ccnt += sprintf(fmt + ccnt, "%s:", xr->tgt_info[i]);
00325    for (; i < xdas_elemcount(xr->tgt_info); i++)
00326       fmt[ccnt++] = ':';
00327 
00328    /* SRC:
00329     * <pointer_to_source_domain>:
00330     * EVT:
00331     * <event_specific_information>:
00332     * "END\0"
00333     */
00334    ccnt += sprintf(fmt + ccnt, "SRC:%s:EVT:%s:END", 
00335          xr->src_ref? xr->src_ref: "", xr->evt_info? xr->evt_info: "");
00336 
00337    /* put the record length, and replace the colon character */
00338    fmtlen = ccnt;
00339    sprintf(fmt + 4, "%04hx", (unsigned short)ccnt);
00340    fmt[4 + 4] = ':';
00341 
00342    /* is data different? */
00343    if (fmtlen == xr->fmtlen && strcmp(fmt, xr->fmt) == 0)
00344    {
00345       free(fmt);  /* no, free temp buffer, return "no change" */
00346       return 1;
00347    }
00348 
00349    /* yes, free existing, set new */
00350    free(xr->fmt);
00351    xr->fmt = fmt;
00352    xr->fmtlen = fmtlen;
00353    return 0;
00354 }
00355 
00356 static xdas_record * xdas_validate_record(xdas_audit_rec_desc_t record_ref) 
00357 {
00358    xdas_record * xr = (xdas_record *)record_ref;
00359    return (xr && xr->signature == XDAS_RECORD_SIG)? xr: 0;
00360 }
00361 
00362 static unsigned xdas_get_next_record_number(void)
00363 {
00364    static unsigned g_recnum = 0;
00365    return ++g_recnum;
00366 }
00367 
00368 static void xdas_set_record_timestamp(xdas_record * xr)
00369 {
00370 #ifdef LINUX_KERNEL
00371    unsigned long seq;
00372    do {
00373       seq = read_seqbegin(&xtime_lock);
00374       xr->time_offset = xtime.tv_sec;
00375    } while (read_seqretry(&xtime_lock, seq));
00376 #else
00377    xr->time_offset = (unsigned)time(0);
00378 #endif
00379 }
00380 
00381 static int xdas_is_valid_outcome(unsigned outcome)
00382 {
00383    switch(outcome & 0x000000FF)
00384    {
00385       case XDAS_OUT_SUCCESS:  return !(outcome & ~0x00003FFF);
00386       case XDAS_OUT_FAILURE:  return !(outcome & ~0x000FFFFF);
00387       case XDAS_OUT_DENIAL :  return !(outcome & ~0x000007FF);
00388    }
00389    return 0;   /* no outcome class matched */
00390 }
00391 
00392 static void xdas_internal_discard_record(xdas_record * xr)
00393 {
00394    free(xr->int_info[0]);
00395    free(xr->tgt_info[0]);
00396    free(xr->src_ref);
00397    free(xr->evt_info);
00398    free(xr->fmt);
00399    free(xr);
00400 }
00401 
00402 static int xdas_send_record(int * minorp, xdas_session * xs, 
00403       xdas_record * xr, int eval, int import)
00404 {
00405    int rv;
00406 
00407    /* format record to add in string and length */
00408    if ((rv = xdas_format_record(xs, xr)) < 0)
00409       return (*minorp = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00410 
00411    audit_log_format(xs->ab, "%s", xr->fmt);
00412 
00413    return XDAS_S_COMPLETE;
00414 }
00415 
00416 static char * xdas_tokenize(char * str, const char * delims, 
00417       char esc, char ** nextok)
00418 {
00419    char * thistok;
00420    if (str) 
00421       *nextok = str;
00422    thistok = *nextok;
00423    if (thistok)
00424    {
00425       while ((*nextok = strpbrk(*nextok, delims)) != 0 
00426             && *nextok != str && (*nextok)[-1] == esc) 
00427          (*nextok)++;
00428       if (*nextok != 0)
00429          *(*nextok)++ = 0;
00430    }
00431    return thistok;
00432 }
00433 
00434 static int xdas_parse_info(const char * info, char ** fields, unsigned maxflds)
00435 {
00436    unsigned i;
00437    char * info_copy, * saveptr;
00438 
00439 #define FLD_DELIMS   ":"
00440 #define ESC_CHAR     '%'
00441 
00442    /* make a working copy */
00443    if ((info_copy = strdup(info)) == 0)
00444       return -1;
00445 
00446    /* tokenize the working copy */
00447    fields[0] = xdas_tokenize(info_copy, FLD_DELIMS, ESC_CHAR, &saveptr);
00448    for (i = 1; i < maxflds && fields[i-1]; i++)
00449       fields[i] = xdas_tokenize(0, FLD_DELIMS, ESC_CHAR, &saveptr);
00450 
00451    return saveptr? -2: 0;
00452 }
00453 
00454 /*---------------------------------------------------------------------------
00455  */
00456 XDASXPC int XDASAPI xdas_initialize_session(
00457       int * minor_status,
00458       const char * org_info,
00459       xdas_audit_ref_t * das_ref)
00460 {
00461    int err;
00462    xdas_session * xs;
00463    int bit_bucket;
00464 
00465    /* check parameters */
00466    if (!minor_status)
00467       minor_status = &bit_bucket;
00468    *minor_status = 0;
00469 
00470    xdas_assert(org_info != 0);
00471    if (org_info == 0)
00472       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_ORIG_INFO;
00473 
00474    xdas_assert(das_ref != 0);
00475    if (das_ref == 0)
00476       return XDAS_S_CALL_INACCESSIBLE_WRITE | XDAS_S_INVALID_DAS_REF;
00477 
00478 #ifndef LINUX_KERNEL
00479    /* ensure xdas library is initialized */
00480    if ((err = xdas_library_init(minor_status)) != 0)
00481       return err;
00482 #endif
00483 
00484    /* create a new session structure */
00485    if ((xs = (xdas_session *)malloc(sizeof(*xs))) == 0)
00486       return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00487    memset(xs, 0, sizeof(*xs));
00488    xs->signature = XDAS_SESSION_SIG;
00489 
00490 #ifndef LINUX_KERNEL
00491    xs->s = BAD_SOCKET;
00492 #endif
00493 
00494    /* populate and check caller's rights */
00495    xdas_set_session_rights(xs);
00496    if (!xdas_session_has_rights(xs, XDAS_AUDIT_SERVICE))
00497    {
00498       xdas_internal_terminate_session(xs);
00499       return XDAS_S_AUTHORIZATION_FAILURE;
00500    }
00501 
00502    /* parse originator info */
00503    if ((err = xdas_parse_info(org_info, 
00504          xs->org_info, xdas_elemcount(xs->org_info))) < 0)
00505    {
00506       xdas_internal_terminate_session(xs);
00507       switch(err)
00508       {
00509          case -1: return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00510          case -2: return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_ORIG_INFO;
00511          default: return (*minor_status = OXDAS_MS_UNKNOWN_ERROR), XDAS_S_FAILURE;
00512       }
00513    }
00514 
00515    /* retreive system time information */
00516    if (xdas_set_time_info(xs) < 0)
00517    {
00518       xdas_internal_terminate_session(xs);
00519       return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00520    }
00521 
00522    /* establish connection with the xdas daemon/service */
00523    if ((err = xdas_service_connect(minor_status, xs)) != 0)
00524    {
00525       xdas_internal_terminate_session(xs);
00526       return err;
00527    }
00528 
00529    /* return session pointer as a handle */
00530    *das_ref = (xdas_audit_ref_t)xs;
00531 
00532    return XDAS_S_COMPLETE;
00533 }
00534 
00535 /*---------------------------------------------------------------------------
00536  */
00537 XDASXPC int XDASAPI xdas_terminate_session(
00538       int * minor_status,
00539       xdas_audit_ref_t * das_ref)
00540 {
00541    xdas_session * xs;
00542    int bit_bucket;
00543 
00544    /* check parameters */
00545    if (!minor_status)
00546       minor_status = &bit_bucket;
00547    *minor_status = 0;
00548 
00549    xdas_assert(das_ref != 0 && *das_ref != 0);
00550    if (das_ref == 0 || *das_ref == 0)
00551       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_DAS_REF;
00552 
00553    xs = xdas_validate_session(*das_ref);
00554    xdas_assert(xs != 0);
00555    if (xs == 0)
00556       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_DAS_REF;
00557 
00558    xdas_internal_terminate_session(xs);
00559    *das_ref = 0;
00560    return XDAS_S_COMPLETE;
00561 }
00562 
00563 /*---------------------------------------------------------------------------
00564  */
00565 XDASXPC int XDASAPI xdas_commit_record(
00566       int * minor_status,
00567       xdas_audit_ref_t das_ref,
00568       xdas_audit_rec_desc_t * audit_record_descriptor)
00569 {
00570    xdas_session * xs;
00571    xdas_record * xr;
00572    int rv, bit_bucket;
00573 
00574    /* check parameters */
00575    if (!minor_status)
00576       minor_status = &bit_bucket;
00577    *minor_status = 0;
00578 
00579    xdas_assert(das_ref != 0);
00580    if (das_ref == 0)
00581       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_DAS_REF;
00582 
00583    xs = xdas_validate_session(das_ref);
00584    xdas_assert(xs != 0);
00585    if (xs == 0)
00586       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_DAS_REF;
00587 
00588    if (!xdas_session_has_rights(xs, XDAS_AUDIT_SERVICE | XDAS_AUDIT_SUBMIT))
00589       return XDAS_S_AUTHORIZATION_FAILURE;
00590 
00591    xdas_assert(audit_record_descriptor != 0 && *audit_record_descriptor != 0);
00592    if (audit_record_descriptor == 0 || *audit_record_descriptor == 0)
00593       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00594 
00595    xr = xdas_validate_record(*audit_record_descriptor);
00596    xdas_assert(xr != 0);
00597    if (xr == 0)
00598       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00599 
00600    /* ensure all required event fields have at least been set */
00601    if (xr->event_number == 0 || xr->outcome == XDAS_OUT_NOT_SPECIFIED 
00602          || xr->int_info[0] == 0 || xr->tgt_info[0] == 0 || xr->evt_info == 0)
00603       return XDAS_S_INCOMPLETE_RECORD;
00604 
00605    /* timestamp record if not already set */
00606    if (xr->time_offset == 0)
00607       xdas_set_record_timestamp(xr);
00608 
00609    /* send and delete if successfully sent */
00610    if ((rv = xdas_send_record(minor_status, xs, xr, 0, 0)) == 0)
00611    {
00612       xdas_internal_discard_record(xr);
00613       *audit_record_descriptor = 0;
00614    }
00615    return rv;
00616 }
00617 
00618 /*---------------------------------------------------------------------------
00619  */
00620 XDASXPC int XDASAPI xdas_discard_record(
00621       int * minor_status,
00622       xdas_audit_ref_t das_ref,
00623       xdas_audit_rec_desc_t * audit_record_descriptor)
00624 {
00625    xdas_session * xs;
00626    xdas_record * xr;
00627    int bit_bucket;
00628 
00629    /* check parameters */
00630    if (!minor_status)
00631       minor_status = &bit_bucket;
00632    *minor_status = 0;
00633 
00634    xdas_assert(das_ref != 0);
00635    if (das_ref == 0)
00636       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_DAS_REF;
00637 
00638    xs = xdas_validate_session(das_ref);
00639    xdas_assert(xs != 0);
00640    if (xs == 0)
00641       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_DAS_REF;
00642 
00643    if (!xdas_session_has_rights(xs, XDAS_AUDIT_SERVICE | XDAS_AUDIT_SUBMIT))
00644       return XDAS_S_AUTHORIZATION_FAILURE;
00645 
00646    xdas_assert(audit_record_descriptor != 0 && *audit_record_descriptor != 0);
00647    if (audit_record_descriptor == 0 || *audit_record_descriptor == 0)
00648       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00649 
00650    xr = xdas_validate_record(*audit_record_descriptor);
00651    xdas_assert(xr != 0);
00652    if (xr == 0)
00653       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00654 
00655    xdas_internal_discard_record(xr);
00656    *audit_record_descriptor = 0;
00657    return XDAS_S_COMPLETE;
00658 }
00659 
00660 /*---------------------------------------------------------------------------
00661  */
00662 XDASXPC int XDASAPI xdas_put_event_info(
00663       int * minor_status,
00664       xdas_audit_ref_t das_ref,
00665       xdas_audit_rec_desc_t * audit_record_descriptor,
00666       unsigned event_number,
00667       unsigned outcome,
00668       const char * initiator_information,
00669       const char * target_information,
00670       const char * event_information)
00671 {
00672    xdas_session * xs;
00673    xdas_record * xr;
00674    int bit_bucket;
00675    char * int_info[xdas_elemcount(xr->int_info)];
00676    char * tgt_info[xdas_elemcount(xr->tgt_info)];
00677    char * evt_info;
00678 
00679    /* check parameters */
00680    if (!minor_status)
00681       minor_status = &bit_bucket;
00682    *minor_status = 0;
00683 
00684    xdas_assert(das_ref != 0);
00685    if (das_ref == 0)
00686       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_DAS_REF;
00687 
00688    xs = xdas_validate_session(das_ref);
00689    xdas_assert(xs != 0);
00690    if (xs == 0)
00691       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_DAS_REF;
00692 
00693    if (!xdas_session_has_rights(xs, XDAS_AUDIT_SERVICE | XDAS_AUDIT_SUBMIT))
00694       return XDAS_S_AUTHORIZATION_FAILURE;
00695 
00696    xdas_assert(audit_record_descriptor != 0 && *audit_record_descriptor != 0);
00697    if (audit_record_descriptor == 0 || *audit_record_descriptor == 0)
00698       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00699 
00700    xr = xdas_validate_record(*audit_record_descriptor);
00701    xdas_assert(xr != 0);
00702    if (xr == 0)
00703       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00704 
00705    /* initialize before attempted free (later during error cases) */
00706    int_info[0] = tgt_info[0] = evt_info = 0;
00707 
00708    /* validate outcome value if specified */
00709    if (outcome != XDAS_OUT_NOT_SPECIFIED
00710          && !xdas_is_valid_outcome(outcome))
00711       return XDAS_S_INVALID_OUTCOME;
00712 
00713    /* parse initiator info into temp array */
00714    if (initiator_information)
00715    {
00716       int rv;
00717       if ((rv = xdas_parse_info(initiator_information, 
00718             int_info, xdas_elemcount(int_info))) < 0)
00719       {
00720          switch(rv)
00721          {
00722             case -1: return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00723             case -2: return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_INITIATOR_INFO;
00724             default: return (*minor_status = OXDAS_MS_UNKNOWN_ERROR), XDAS_S_FAILURE;
00725          }
00726       }
00727    }
00728 
00729    /* parse target info into temp array */
00730    if (target_information)
00731    {
00732       int rv;
00733       if ((rv = xdas_parse_info(target_information, 
00734             tgt_info, xdas_elemcount(tgt_info))) < 0)
00735       {
00736          free(int_info[0]);
00737          switch(rv)
00738          {
00739             case -1: return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00740             case -2: return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_TARGET_INFO;
00741             default: return (*minor_status = OXDAS_MS_UNKNOWN_ERROR), XDAS_S_FAILURE;
00742          }
00743       }
00744    }
00745 
00746    /* copy event-specific info into temp pointer */
00747    if (event_information)
00748    {
00750       if ((evt_info = strdup(event_information)) == 0)
00751       {
00752          free(int_info[0]);
00753          free(tgt_info[0]);
00754          return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00755       }
00756    }
00757 
00758    /* all resources parsed and allocated - now set field values */
00759 
00760    /* overwrite original and set event number from parameter */
00761    if (event_number != 0 && event_number != xr->event_number)
00762    {
00763       xr->event_number = event_number;
00764       xr->fmt_cache_dirty = 1;
00765    }
00766 
00767    /* overwrite original and set outcome from parameter */
00768    if (outcome != XDAS_OUT_NOT_SPECIFIED && outcome != xr->outcome)
00769    {
00770       xr->outcome = outcome;
00771       xr->fmt_cache_dirty = 1;
00772    }
00773 
00774    /* free original and copy initiator info from temp array */
00775    if (initiator_information)
00776    {
00778       free(xr->int_info[0]);
00779       memcpy(xr->int_info, int_info, sizeof(xr->int_info));
00780       xr->fmt_cache_dirty = 1;
00781    }
00782 
00783    /* free original and copy target info from temp array */
00784    if (target_information)
00785    {
00787       free(xr->tgt_info[0]);
00788       memcpy(xr->tgt_info, tgt_info, sizeof(xr->tgt_info));
00789       xr->fmt_cache_dirty = 1;
00790    }
00791 
00792    /* free original and reset event info from temp pointer */
00793    if (event_information)
00794    {
00795       if (xr->evt_info && strcmp(event_information, xr->evt_info) == 0)
00796          free(evt_info);
00797       else
00798       {
00799          free(xr->evt_info);
00800          xr->evt_info = evt_info;
00801          xr->fmt_cache_dirty = 1;
00802       }
00803    }
00804 
00805 #ifndef LINUX_KERNEL
00806    /* Evaluate - if no audit required, free record */
00807    if (xr->fmt_cache_dirty)
00808    {
00809       int rv;
00810       if ((rv = xdas_send_record(
00811             minor_status, xs, xr, 1, 0)) == XDAS_S_NO_AUDIT)
00812       {
00813          xdas_internal_discard_record(xr); 
00814          *audit_record_descriptor = 0;
00815       }
00816       xr->fmt_cache_dirty = 0;
00817       return rv;
00818    }
00819    return xr->last_status;
00820 #else
00821    return XDAS_S_COMPLETE;
00822 #endif
00823 }
00824 
00825 /*---------------------------------------------------------------------------
00826  */
00827 XDASXPC int XDASAPI xdas_start_record(
00828       int * minor_status,
00829       xdas_audit_ref_t das_ref,
00830       xdas_audit_rec_desc_t * audit_record_descriptor,
00831       unsigned event_number,
00832       unsigned outcome,
00833       const char * initiator_information,
00834       const char * target_information,
00835       const char * event_information)
00836 {
00837    xdas_record * xr;
00838    xdas_session * xs;
00839    int bit_bucket, rv = XDAS_S_COMPLETE;
00840 
00841    /* check parameters */
00842    if (!minor_status)
00843       minor_status = &bit_bucket;
00844    *minor_status = 0;
00845 
00846    xdas_assert(das_ref != 0);
00847    if (das_ref == 0)
00848       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_DAS_REF;
00849 
00850    xs = xdas_validate_session(das_ref);
00851    xdas_assert(xs != 0);
00852    if (xs == 0)
00853       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_DAS_REF;
00854 
00855    if (!xdas_session_has_rights(xs, XDAS_AUDIT_SERVICE | XDAS_AUDIT_SUBMIT))
00856       return XDAS_S_AUTHORIZATION_FAILURE;
00857 
00858    xdas_assert(audit_record_descriptor != 0);
00859    if (audit_record_descriptor == 0)
00860       return XDAS_S_CALL_INACCESSIBLE_WRITE | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00861 
00862    /* create a new audit record context structure */
00863    *audit_record_descriptor = 0;
00864    if ((xr = (xdas_record *)malloc(sizeof(*xr))) == 0)
00865       return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00866    memset(xr, 0, sizeof(*xr));
00867    xr->signature = XDAS_RECORD_SIG;
00868 
00869    /* preinitialize all fields to "not set" */
00870    xr->outcome = XDAS_OUT_NOT_SPECIFIED;
00871 
00872    xr->record_number = xdas_get_next_record_number();
00873 
00874    /* set event number */
00875    if (event_number != 0)
00876       xr->event_number = event_number;
00877 
00878    /* set outcome */
00879    if (outcome != XDAS_OUT_NOT_SPECIFIED)
00880    {
00881       if (!xdas_is_valid_outcome(outcome))
00882          return XDAS_S_INVALID_OUTCOME;
00883       xr->outcome = outcome;
00884    }
00885 
00886    /* set initiator info */
00887    if (initiator_information)
00888    {
00889       if ((rv = xdas_parse_info(initiator_information, 
00890             xr->int_info, xdas_elemcount(xr->int_info))) < 0)
00891       {
00892          xdas_internal_discard_record(xr); 
00893          switch(rv)
00894          {
00895             case -1: return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00896             case -2: return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_INITIATOR_INFO;
00897             default: return (*minor_status = OXDAS_MS_UNKNOWN_ERROR), XDAS_S_FAILURE;
00898          }
00899       }
00900    }
00901 
00902    /* set target info */
00903    if (target_information)
00904    {
00905       if ((rv = xdas_parse_info(target_information, 
00906             xr->tgt_info, xdas_elemcount(xr->tgt_info))) < 0)
00907       {
00908          xdas_internal_discard_record(xr); 
00909          switch(rv)
00910          {
00911             case -1: return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00912             case -2: return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_TARGET_INFO;
00913             default: return (*minor_status = OXDAS_MS_UNKNOWN_ERROR), XDAS_S_FAILURE;
00914          }
00915       }
00916    }
00917 
00918    /* set event-specific info */
00919    if (event_information && (xr->evt_info = strdup(event_information)) == 0)
00920    {
00922       xdas_internal_discard_record(xr); 
00923       return (*minor_status = OXDAS_MS_OUT_OF_MEMORY), XDAS_S_FAILURE;
00924    }
00925    
00926 #ifndef LINUX_KERNEL
00927    /* Evaluate - if no audit return null handle, else return new record */
00928    if ((rv = xdas_send_record(minor_status, xs, xr, 1, 0)) == XDAS_S_NO_AUDIT)
00929    {
00930       xdas_internal_discard_record(xr); 
00931       xr = 0;
00932    }
00933 #endif
00934 
00935    /* return record pointer as handle */
00936    *audit_record_descriptor = (xdas_audit_rec_desc_t)xr;
00937 
00938    return rv;
00939 }
00940 
00941 /*---------------------------------------------------------------------------
00942  */
00943 XDASXPC int XDASAPI xdas_timestamp_record(
00944       int * minor_status,
00945       xdas_audit_ref_t das_ref,
00946       xdas_audit_rec_desc_t audit_record_descriptor)
00947 {
00948    xdas_session * xs;
00949    xdas_record * xr;
00950    int bit_bucket;
00951 
00952    /* check parameters */
00953    if (!minor_status)
00954       minor_status = &bit_bucket;
00955    *minor_status = 0;
00956 
00957    xdas_assert(das_ref != 0);
00958    if (das_ref == 0)
00959       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_DAS_REF;
00960 
00961    xs = xdas_validate_session(das_ref);
00962    xdas_assert(xs != 0);
00963    if (xs == 0)
00964       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_DAS_REF;
00965 
00966    if (!xdas_session_has_rights(xs, XDAS_AUDIT_SERVICE | XDAS_AUDIT_SUBMIT))
00967       return XDAS_S_AUTHORIZATION_FAILURE;
00968 
00969    xdas_assert(audit_record_descriptor != 0);
00970    if (audit_record_descriptor == 0)
00971       return XDAS_S_CALL_INACCESSIBLE_READ | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00972 
00973    xr = xdas_validate_record(audit_record_descriptor);
00974    xdas_assert(xr != 0);
00975    if (xr == 0)
00976       return XDAS_S_CALL_BAD_STRUCTURE | XDAS_S_INVALID_RECORD_DESCRIPTOR;
00977 
00978    xdas_set_record_timestamp(xr);
00979    xr->fmt_cache_dirty = 1;
00980 
00981    return XDAS_S_COMPLETE;
00982 }
00983 

Generated on Thu Aug 20 22:33:05 2009 for OpenXDAS by  doxygen 1.5.6