예제 #1
0
static CMPIStatus
initialize(CMPIClassMI * mi, CMPIContext *ctx)
{

  CMPIStatus      st;
  char           *p,
                  c;

  /*
   * to set params, in providerRegister add line: parameters: -c10 -r15 
   */
  static struct option const long_options[] = {
    {"base-class-cache", required_argument, 0, 'c'},
    {"resolved-class-cache", required_argument, 0, 'r'},
    {0, 0, 0, 0}
  };
  char            msg[] =
      "--- Invalid classProviderSf parameter -%c %s ignored \n";
  CMPIData        parms =
      ctx->ft->getEntry(ctx, "sfcbProviderParameters", &st);

  if (st.rc == 0) {
    argv =
        buildArgList((char *) parms.value.string->hdl, "classProviderSf",
                     &argc);
    mlogf(M_INFO, M_SHOW, "--- %s parameters: %s\n", argv[0],
          (char *) parms.value.string->hdl);
    while ((c = getopt_long(argc, argv, "c:r:", long_options, 0)) != -1) {
      switch (c) {
      case 0:
        break;
      case 'c':
        if (isdigit(*optarg))
          cSize = strtol(optarg, &p, 0);
        else
          mlogf(M_INFO, M_SHOW, msg, c, optarg);
        break;
      case 'r':
        if (isdigit(*optarg))
          rSize = strtol(optarg, &p, 0);
        else
          mlogf(M_INFO, M_SHOW, msg, c, optarg);
        break;
      default:
        mlogf(M_INFO, M_SHOW, msg, c, optarg);
      }
    }
  } else {
  }

  // CJB if (nsHt==NULL) nsHt=buildClassRegisters();
  CMReturn(CMPI_RC_OK);
}
예제 #2
0
static char    *
keyType(CMPIType type)
{
  switch (type) {
  case CMPI_chars:
  case CMPI_string:
  case CMPI_dateTime:
    return "string";
  case CMPI_sint64:
  case CMPI_uint64:
  case CMPI_sint32:
  case CMPI_uint32:
  case CMPI_sint16:
  case CMPI_uint16:
  case CMPI_uint8:
  case CMPI_sint8:
    return "numeric";
  case CMPI_boolean:
    return "boolean";
  case CMPI_ref:
    return "*";
  }
  mlogf(M_ERROR, M_SHOW, "%s(%d): invalid key data type %d %x\n", __FILE__,
        __LINE__, (int) type, (int) type);
  SFCB_ASM("int $3");
  abort();
  return "*??*";
}
예제 #3
0
int ipfix_ssl_setup_server_ctx( SSL_CTX **ssl_ctx,
                                SSL_METHOD *method,
                                ipfix_ssl_opts_t *ssl_details )
{
    SSL_CTX *ctx;

    if ( ipfix_ssl_setup_ctx( &ctx, method?method:SSLv23_method(),
                              ssl_details ) <0 ) {
        return -1;
    }

    SSL_CTX_set_verify( ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,
                        ipfix_ssl_verify_callback );
    SSL_CTX_set_verify_depth( ctx, 4 );
    SSL_CTX_set_options( ctx, SSL_OP_ALL | SSL_OP_NO_SSLv2 |
                         SSL_OP_SINGLE_DH_USE);
    if (!dh512 || !dh1024) {
        init_dhparams();
    }
    SSL_CTX_set_tmp_dh_callback( ctx, ipfix_ssl_tmp_dh_callback );
    if (SSL_CTX_set_cipher_list( ctx, CIPHER_LIST) != 1) {
        mlogf( 0, "[ipfix] error setting cipher list (no valid ciphers)");
        goto err;
    }

    *ssl_ctx = ctx;
    return 0;

 err:
    SSL_CTX_free( ctx );
    return -1;
}
예제 #4
0
int ipfix_ssl_setup_client_ctx( SSL_CTX **ssl_ctx,
                                SSL_METHOD *method,
                                ipfix_ssl_opts_t *ssl_details )
{
    SSL_CTX *ctx;

    if ( ipfix_ssl_setup_ctx( &ctx, method?method:SSLv23_method(),
                              ssl_details ) <0 )
        return -1;

    SSL_CTX_set_verify( ctx, SSL_VERIFY_PEER,
                        ipfix_ssl_verify_callback);
    SSL_CTX_set_verify_depth( ctx, 4);
    SSL_CTX_set_options( ctx, SSL_OP_ALL|SSL_OP_NO_SSLv2);
    if (SSL_CTX_set_cipher_list( ctx, CIPHER_LIST) != 1) {
        mlogf( 0, "[ipfix] Error setting cipher list (no valid ciphers)");
        goto err;
    }

    *ssl_ctx = ctx;
    return 0;

 err:
    SSL_CTX_free( ctx );
    return -1;
}
예제 #5
0
static ClassRegister *
getNsReg(const CMPIObjectPath * ref, int *rc)
{
  char           *ns;
  CMPIString     *nsi = CMGetNameSpace(ref, NULL);
  ClassRegister  *cReg;
  *rc = 0;

  pthread_once(&nsHt_once, nsHt_init);

  if (nsHt == NULL) {
    mlogf(M_ERROR, M_SHOW,
          "--- ClassProvider: namespace hash table not initialized\n");
    *rc = 1;
    return NULL;
  }

  if (nsi && nsi->hdl) {
    ns = (char *) nsi->hdl;
    if (strcasecmp(ns, "root/pg_interop") == 0)
      cReg = nsHt->ft->get(nsHt, "root/interop");
    else
      cReg = nsHt->ft->get(nsHt, ns);
    return cReg;
  }

  *rc = 1;
  return NULL;
}
예제 #6
0
void
handleSSLerror(const char *file, int lineno, const char *msg)
{
  mlogf(M_ERROR, M_SHOW, "\n*** %s:%i %s -- exiting\n", file, lineno, msg);
#ifdef SFCB_DEBUG
  ERR_print_errors_fp(stderr);
#endif
  exit(-1);
}
예제 #7
0
static int addProviderToHT(ProviderInfo *info, UtilHashTable *ht)
{
    ProviderInfo *checkDummy;
    /* first we add the provider to the providerRegister with the classname
     * as a key*/
	
    checkDummy = ht->ft->get(ht, info->className);
    if(checkDummy) {
    /* Another provider is in the register, but the newly found
     * wants to serve the same class - so we do not add it to the
     * register but append it to the one already found or to its master*/
        if (strcmp(checkDummy->providerName, info->providerName) == 0) {
	    if (checkDummy->type != info->type) {
	        mlogf(M_ERROR,M_SHOW,"--- Conflicting registration types for class %s, provider %s\n", info->className, info->providerName);
		return 1;
	    }
	    /* FIXME: check location, user, group, parms, unload */
	    /* classname and provider name match, now check for namespace */
	    int idx = 0;
	    while (checkDummy->ns[idx]) {
	        if (strcmp(checkDummy->ns[idx], info->ns[0]) == 0) {
		    /* double registration - discard */
		    freeInfoPtr(info);
		    return 0;
		}
		++idx;
	    }
	    /* additional namespace for existing classname and provider name */
            mlogf(M_INFO,M_SHOW,"--- Collating namespaces for registration of class %s, provider %s; consider single providerRegister entry\n", info->className, info->providerName);
	    checkDummy->ns=(char**)realloc(checkDummy->ns,sizeof(char*)*(idx+2));
	    checkDummy->ns[idx] = strdup(info->ns[0]);
	    checkDummy->ns[++idx] = NULL;
	    freeInfoPtr(info);
        } else {
            /* add info to the nIR linked list */
            info->nextInRegister = checkDummy->nextInRegister;
            checkDummy->nextInRegister = info;
        }
    } else {
        ht->ft->put(ht, info->className, info);
    }
    return 0;
}
예제 #8
0
파일: result.c 프로젝트: zaneb/sblim-sfcb
static CMPIStatus __rft_returnData(const CMPIResult * result,
                                   const CMPIValue * val, CMPIType type)
{
//   NativeResult *r = (NativeResult*) result;

   if (type==CMPI_ref) {
      mlogf(M_ERROR,M_SHOW,"--- CMPIResult does not yet support returning references\n");
      abort();   
   }
   
   return returnData(result,val,type);
}
예제 #9
0
int ipfix_ssl_verify_callback(int ok, X509_STORE_CTX *store)
{
    char data[256];

    if (!ok)
    {
        X509 *cert = X509_STORE_CTX_get_current_cert(store);
        int  depth = X509_STORE_CTX_get_error_depth(store);
        int  err = X509_STORE_CTX_get_error(store);

        mlogf( 1, "[%s] Error with certificate at depth: %i\n",
               __func__, depth);
        X509_NAME_oneline( X509_get_issuer_name(cert), data, 256);
        mlogf( 1, "  issuer   = %s\n", data);
        X509_NAME_oneline( X509_get_subject_name(cert), data, 256);
        mlogf( 1, "  subject  = %s\n", data);
        mlogf( 1, "  err %i:%s\n", err, X509_verify_cert_error_string(err));
    }

    return ok;
}
예제 #10
0
파일: probe.c 프로젝트: JammyStuff/libipfix
/* name       : prog_init
 * parameters : none, global parameters
 * description: some program initialisation
 * returns    : 0 if ok, -1 on error
 * remarks    : 
 */
int prog_init ( void )
{
    /* daemon
     */
    if ( (g_par.flags&PROBE_DAEMON) && (daemon ( 0, 0 ) < 0) ) {
        errorf ( "[%s] failed to run as daemon!\n\n", g_par.progname );
        return -1;
    }
#if 0
    if ( chdir ( "/tmp" ) <0 )
        mlogf( 0, "[%s] ERROR cannot change working dir: %s\n", 
               g_par.progname, strerror(errno) );
#endif

    /* open logfile
     */
    mlog_set_vlevel( g_par.vlevel );
    if ( g_par.logfile )
        (void) mlog_open( g_par.logfile, NULL );

    mlogf( 1, "\nIPFIX probe (%s)\n\n", __DATE__ );

    /* signal handler */
    signal( SIGKILL, exit_func );
    signal( SIGTERM, exit_func );
    signal( SIGINT,  exit_func );

    /* init exporter */
    if ( export_init( &g_probe ) <0 ) {
        return -1;
    }

    /* init pcap sniffing
     */
    if ( input_init( &g_probe, g_par.flags ) <0 ) {
        return -1;
    }

    return 0;
}
예제 #11
0
static int ipfix_ssl_setup_ctx( SSL_CTX **ssl_ctx,
                                SSL_METHOD *method,
                                ipfix_ssl_opts_t *ssl_details )
{
    SSL_CTX *ctx;
    char buffer[PATH_MAX];

    if ( ((ctx=SSL_CTX_new(method)) ==NULL )
         || (SSL_CTX_load_verify_locations( ctx, ssl_details->cafile,
                                            ssl_details->cadir ) != 1)) {
        mlogf( 0, "[ipfix] error loading ca file and/or directory "
               "(cwd=%s,file=%s): %s\n", getcwd(buffer, sizeof(buffer)),
               ssl_details->cafile, strerror(errno) );
        goto err;
    }

    if ( SSL_CTX_set_default_verify_paths(ctx) != 1) {
        mlogf( 0, "[ipfix] error loading default CA file and/or dir\n");
        goto err;
    }

    if ( SSL_CTX_use_certificate_chain_file(ctx, ssl_details->certfile) != 1) {
        mlogf( 0, "[ipfix] error loading certificate from file");
        goto err;
    }

    if ( SSL_CTX_use_PrivateKey_file( ctx, ssl_details->keyfile,
                                      SSL_FILETYPE_PEM ) != 1) {
        mlogf( 0, "[ipfix] Error loading private key from file: %s\n",
               ssl_details->keyfile );
        goto err;
    }

    *ssl_ctx = ctx;
    return 0;

 err:
    SSL_CTX_free( ctx );
    return -1;
}
예제 #12
0
파일: probe.c 프로젝트: JammyStuff/libipfix
/* name       : cb_dispatch
 * remarks    : 
 */
void cb_dispatch( int fd, int mask, void *data )
{
    probe_t *p = (probe_t*)data;

    switch ( pcap_dispatch( p->pcap, p->cnt, cb_packet, data ) ) {
      case -1:
          mlogf( 0, "[%s] pcap_dispatch: %s\n", 
                 p->device, pcap_geterr(p->pcap));
          break;
      case 0:
          if ( g_par.flags & PROBE_OFFLINE ) {
              mlogf( 1, "[%s] end of file detected, break ...\n", 
                     p->device );
              mpoll_break();
          }
          break;;
      default:
          return;
    }

    return;
}
예제 #13
0
int ipfix_export_trecord_db( ipfixs_node_t *s, ipfixt_node_t *t, void *arg )
{
    ipfixe_data_db_t *data = (ipfixe_data_db_t*)arg;
    char             *func = "export_trecord_db";

    if ( !data->mysql )
        return -1;

    /** build tablename
     */
    strcpy( t->tablename, "" );
    t->message_snr = s->last_message_snr-1; /*!!*/
    if ( ipfix_db_get_tablename( data->mysql, t->tablename, MAXTABLENAMELEN, 
                                 &(t->template_id), t->ipfixt, 1 ) <0 ) {
        /** todo!
         */
        mlogf( 1, "[%s] cannot build table name for template %d\n", 
               func, t->ipfixt->tid );
    }
    mlogf( 4, "[%s] template %d use table %s\n", 
           func, t->ipfixt->tid, t->tablename );
    return 0;
}
예제 #14
0
static void outf( FILE *fp, char fmt[], ... )
{
    va_list args;

    va_start( args, fmt );
    (void) vsprintf(tmpbuf, fmt, args );
    va_end( args );

    if ( fp ) {
        fprintf( fp, "%s", tmpbuf );
    }
    else {
        mlogf( 0, "%s", tmpbuf );
    }
}
예제 #15
0
int ipfix_export_newsrc_db( ipfixs_node_t *s, void *arg ) 
{
    ipfixe_data_db_t *data = (ipfixe_data_db_t*)arg;
    int32_t          exporter_id =0;

    if ( !data->mysql ) {
        errno = EINVAL;
        return -1;
    }

    snprintf( query, MAXQUERYLEN, 
              "SELECT %s FROM %s WHERE %s='%u' AND %s='%s'", 
              IPFIX_DB_EXP_ID, IPFIX_DB_EXPORTERS, IPFIX_DB_EXP_ODID, s->odid,
              IPFIX_DB_EXP_ADDR, ipfix_col_input_get_ident( s->input ) );
    if ( ipfix_db_get_int( data->mysql, query, &exporter_id ) !=0 ) {
        mlogf( 0, "[export_newsrc_db] query(%s) failed!\n", query );
        return -1;
    }

    if ( exporter_id == 0 ) {
        snprintf( query, MAXQUERYLEN, 
                  "INSERT INTO %s SET %s='%u', %s='%s', %s='-'", 
                  IPFIX_DB_EXPORTERS, IPFIX_DB_EXP_ODID, s->odid,
                  IPFIX_DB_EXP_ADDR, ipfix_col_input_get_ident( s->input ),
                  IPFIX_DB_EXP_DESCR );
        if ( mysql_query( data->mysql, query ) !=0 ) {
            mlogf( 0, "[export_newmsg_db] mysql_query(%s) failed: %s\n", 
                   query, mysql_error(data->mysql) );
            return -1;
        }
        exporter_id = (int32_t)mysql_insert_id( data->mysql );
    }

    s->exporterid = (unsigned int)exporter_id;
    return 0;
}
예제 #16
0
파일: probe.c 프로젝트: JammyStuff/libipfix
/* name       : exit_func
 */
void exit_func ( int signo )
{
    if ( signo )
        mlogf( 0, "\n[%s] Got signo %d. Bye.\n\n", g_par.progname, signo );

    /* export flows
     */
    (void)export_ipflows( &g_probe, time(NULL), 1 );

    /** clean up
     */
    mlogf( 1, "[%s] clean up.\n", g_par.progname );
    mpoll_fdrm( g_probe.fd );
    if ( g_par.filter ) {
        free( g_par.filter );
#ifdef HAVE_PCAP_FREECODE
        pcap_freecode( &(g_probe.fprg) );
#endif
    }
    pcap_close( g_probe.pcap );

    ipfix_delete_template( g_probe.ipfix, g_probe.templ );
    ipfix_delete_template( g_probe.ipfix, g_probe.templ6 );
    ipfix_close( g_probe.ipfix );
    ipfix_cleanup();

    if ( g_probe.device )
        free( g_probe.device );

    if ( export_tid )
        mpoll_timerrm( export_tid );

    flow_close( g_probe.ipflows );
    mlog_close();
    exit(0);
}
예제 #17
0
static UtilHashTable *
gatherNameSpaces(char *dn, UtilHashTable * ns, int first)
{
  DIR            *dir,
                 *dir_test;
  struct dirent  *de;
  char           *n = NULL;
  int             l;
  ClassRegister  *cr;

  if (ns == NULL) {
    ns = UtilFactory->newHashTable(61,
                                   UtilHashTable_charKey |
                                   UtilHashTable_ignoreKeyCase);
    nsBaseLen = strlen(dn) + 1;
  }

  dir = opendir(dn);
  if (dir)
    while ((de = readdir(dir)) != NULL) {
      if (strcmp(de->d_name, ".") == 0)
        continue;
      if (strcmp(de->d_name, "..") == 0)
        continue;
      l = strlen(dn) + strlen(de->d_name) + 4;
      n = (char *) malloc(l + 8);
      strcpy(n, dn);
      strcat(n, "/");
      strcat(n, de->d_name);
      dir_test = opendir(n);
      if (dir_test == NULL) {
        free(n);
        continue;
      }
      closedir(dir_test);
      cr = newClassRegister(n);
      if (cr) {
        ns->ft->put(ns, strdup(n + nsBaseLen), cr);
        gatherNameSpaces(n, ns, 0);
      }
      free(n);
  } else if (first) {
    mlogf(M_ERROR, M_SHOW, "--- Repository %s not found\n", dn);
  }
  closedir(dir);
  return ns;
}
예제 #18
0
static char    *
dataType(CMPIType type)
{
  switch (type & ~CMPI_ARRAY) {
  case CMPI_chars:
  case CMPI_string:
    return "string";
  case CMPI_sint64:
    return "sint64";
  case CMPI_uint64:
    return "uint64";
  case CMPI_sint32:
    return "sint32";
  case CMPI_uint32:
    return "uint32";
  case CMPI_sint16:
    return "sint16";
  case CMPI_uint16:
    return "uint16";
  case CMPI_uint8:
    return "uint8";
  case CMPI_sint8:
    return "sint8";
  case CMPI_boolean:
    return "boolean";
  case CMPI_char16:
    return "char16";
  case CMPI_real32:
    return "real32";
  case CMPI_real64:
    return "real64";
  case CMPI_dateTime:
    return "datetime";
  case CMPI_ref:
    return "*";
  case CMPI_instance:
    return "%";
  }
  mlogf(M_ERROR, M_SHOW, "%s(%d): invalid data type %d %x\n", __FILE__,
        __LINE__, (int) type, (int) type);
  SFCB_ASM("int $3");
  abort();
  return "*??*";
}
예제 #19
0
int ipfix_export_newmsg_db( ipfixs_node_t *s, ipfix_hdr_t *hdr, void *arg )
{
    ipfixe_data_db_t *data = (ipfixe_data_db_t*)arg;

    if ( data->mysql ) {
        snprintf( query, MAXQUERYLEN, 
                  "INSERT INTO %s SET %s='%u', %s='%lu'", 
                  IPFIX_DB_MESSAGETABLE,
                  IPFIX_DB_MSGT_EXPID, s->exporterid, IPFIX_DB_MSGT_TIME, 
                  (hdr->version==IPFIX_VERSION_NF9)?
                  (u_long)hdr->u.nf9.unixtime:(u_long)hdr->u.ipfix.exporttime );

        if ( mysql_query( data->mysql, query ) !=0 ) {
            mlogf( 0, "[export_newmsg_db] mysql_query(%s) failed: %s\n", 
                   query, mysql_error(data->mysql) );
            return -1;
        }
        s->last_msgid = (unsigned int) mysql_insert_id( data->mysql );
    }

    return 0;
}
예제 #20
0
파일: subcond.c 프로젝트: zaneb/sblim-sfcb
static CMPIPredicate* __eft_getPredicateAt
              (const CMPISubCond* cond, unsigned int index, CMPIStatus* rc)
{
   NativeSubCond *c = (NativeSubCond *)cond;
   CMPIValuePtr pvp={NULL,0};
   CMPIPredicate *pr=NULL;
   CMPICount count=0;
   CMPIStatus irc={CMPI_RC_ERR_NOT_FOUND,NULL};
   CMPIArray *conds=(CMPIArray*)c->cond.ptr;
   
   if (conds) {
      count=CMGetArrayCount(conds,NULL);
      if (index<count) pvp=CMGetArrayElementAt(conds,index,&irc).value.dataPtr;
   }
   else {
      mlogf(M_ERROR,M_SHOW,"### getPredicateAt, no conds\n");
   }
   if (rc) *rc=irc;
   
   if (pvp.ptr) pr=TrackedCMPIPredicate(pvp,&irc);
   
   return pr;
}              
예제 #21
0
void           *
getBlob(const char *ns, const char *cls, const char *id, int *len)
{
  int             keyl =
      strlen(ns) + strlen(cls) + strlen(id) + strlen(BASE);
  BlobIndex      *bi;
  char           *buf;
  int             rc = 0;

  // checking for qualifiers should be case-insensitive
  short           ignorecase = (strcmp("qualifiers", cls)) ? 0 : 1;

  rc = getIndex(ns, cls, keyl + 64, 0, &bi);

  if (rc) {
    if (indxLocateCase(bi, id, ignorecase)) {
      bi->fd = fopen(bi->fnd, "rb");
      if (bi->fd == NULL) {
        fdHandleError(bi);
        char           *emsg = strerror(errno);
        mlogf(M_ERROR, M_SHOW, "Repository error: %s\n", emsg);
        exit(5);
      }
      fseek(bi->fd, bi->bofs, SEEK_SET);
      buf = malloc(bi->blen + 8);
      fread(buf, bi->blen, 1, bi->fd);
      if (len)
        *len = bi->blen;
      buf[bi->blen] = 0;
      freeBlobIndex(&bi, 1);
      return (void *) buf;
    }
  }
  freeBlobIndex(&bi, 1);
  return NULL;
}
예제 #22
0
int ipfix_ssl_init_con( SSL *con )
{
    extern FILE *mlog_fp; // todo: see if this is working
    int i;
    char *str;
    long verify_error;
    char buf[100];

    if ((i=SSL_accept(con)) <= 0) {
        if (BIO_sock_should_retry(i)) {
            mlogf( 0, "[ipfix_ssl_init] DELAY\n");
            return -1;
        }

        mlogf( 0, "[ipfix_ssl_init] ERROR\n");
        verify_error=SSL_get_verify_result( con );
        if (verify_error != X509_V_OK) {
            mlogf( 0, "[ipfix_ssl_init] verify error: %s\n",
                   X509_verify_cert_error_string(verify_error));
        }
        else
            ERR_print_errors_fp( mlog_fp );

        return -1;
    }

    if ( 1 <= mlog_get_vlevel() ) {
        PEM_write_SSL_SESSION( mlog_fp, SSL_get_session(con));

        if ( SSL_get_shared_ciphers(con, buf, sizeof buf) != NULL) {
            mlogf( 3, "[ipfix] Shared ciphers:%s\n", buf);
        }
        str=(char*)SSL_CIPHER_get_name( SSL_get_current_cipher(con) );
        mlogf( 3,  "[ipfix] CIPHER is %s\n",(str != NULL)?str:"(NONE)");
        if (SSL_ctrl(con,SSL_CTRL_GET_FLAGS,0,NULL) &
            TLS1_FLAGS_TLS_PADDING_BUG) {
            mlogf( 1, "[ipfix] Peer has incorrect TLSv1 block padding\n");
        }
    }

    return 0;
}
예제 #23
0
static ClassRegister *
newClassRegister(ClassSchema * cs, const char *ns)
{
  ClassRegister  *cr = malloc(sizeof(*cr) + sizeof(ClassBase));
  ClassBase      *cb = (ClassBase *) (cr + 1);
  long            s,
                  total = 0;
  ClObjectHdr    *hdr;
  ClVersionRecord *vrp = (ClVersionRecord *) cs->versionRecord;
  ClassDir       *cd = cs->classes;
  int             first = 1;

  cr->hdl = cb;
  cr->ft = ClassRegisterFT;
  cr->vr = vrp;
  cr->assocs = cr->topAssocs = 0;

  cb->ht = UtilFactory->newHashTable(61,
                                     UtilHashTable_charKey |
                                     UtilHashTable_ignoreKeyCase);
  MRWInit(&cb->mrwLock);
  cr->fn = strdup(ns);

  if (vrp && vrp->size == sizeof(ClVersionRecord) << 24
      && vrp->type == HDR_Version) {
    mlogf(M_ERROR, M_SHOW,
          "--- %s is in wrong endian format - namespace skipped\n", ns);
    return NULL;
  }

  while (cd && cd->hdr) {
    CMPIConstClass *cc = NULL;
    char           *cn;

    hdr = cd->hdr;
    if (hdr->type != HDR_Class) {
      mlogf(M_ERROR, M_SHOW,
            "--- %s contains non-class record(s) - namespace skipped\n",
            ns);
      return NULL;
    }

    s = hdr->size;

    if (first) {
      int             v = -1;
      first = 0;
      if (ClVerifyObjImplLevel(cr->vr))
        continue;
      if (cr->vr)
        v = cr->vr->objImplLevel;
      mlogf(M_ERROR, M_SHOW,
            "--- %s contains unsupported object implementation format (%d) - namespace skipped\n",
            ns, v);
      return NULL;
    }

    cc = NEW(CMPIConstClass);
    cc->hdl = hdr;
    cc->ft = CMPIConstClassFT;
    cc->ft->relocate(cc);
    cn = (char *) cc->ft->getCharClassName(cc);
    if (strncmp(cn, "DMY_", 4) != 0) {
      total += s;
      cb->ht->ft->put(cb->ht, cn, cc);
      if (cc->ft->isAssociation(cc)) {
        cr->assocs++;
        if (cc->ft->getCharSuperClassName(cc) == NULL)
          cr->topAssocs++;
      }
    } else {
      mlogf(M_ERROR, M_SHOW,
            "--- %s contains invalid record(s) - namespace skipped\n", ns);
      return NULL;
    }
    first = 0;
    cd += 1;
  }

  if (cr->vr) {
    mlogf(M_INFO, M_SHOW,
          "--- ClassProvider for %s (%d.%d-%d) using %ld bytes\n", ns,
          cr->vr->version, cr->vr->level, cr->vr->objImplLevel, total);
  } else
    mlogf(M_INFO, M_SHOW,
          "--- ClassProvider for %s (no-version) using %ld bytes\n", ns,
          total);

  buildInheritanceTable(cr);

  return cr;
}
예제 #24
0
ProviderRegister *newProviderRegister()
{
   FILE *in;
   char *dir,*provuser = NULL;
   char fin[1024], *stmt = NULL;
   ProviderInfo *info = NULL;
   int err = 0, n = 0, i;
   CntlVals rv;
   int id=0;
   int provSFCB,provuid=-1;
   int interopFound=0;
   struct passwd *passwd;

   ProviderRegister *br = (ProviderRegister *) malloc(sizeof(ProviderRegister) +
                                                      sizeof(ProviderBase));
   ProviderBase *bb = (ProviderBase *) (br + 1);
   
   setupControl(configfile);
   
   // Get/check provider user info
   if (getControlBool("providerDefaultUserSFCB",&provSFCB)) {
     provSFCB = 1;
   } 
   if (provSFCB) {
     // This indicates that we should use the SFCB user by default
     provuid = -1;
   } else {
      if (getControlChars("providerDefaultUser",&provuser)) {
        provuid = -1;
      } else {
        errno=0;
        passwd=getpwnam(provuser);
        if (passwd) {
            provuid=passwd->pw_uid;
        } else {
            mlogf(M_ERROR,M_SHOW,"--- Couldn't find username %s requested in SFCB config file. Errno: %d\n",provuser,errno);
            err=1;
        }
      }
    }


   if (getControlChars("registrationDir",&dir)) {
     dir = "/var/lib/sfcb/registration";
   }

   strcpy(fin, dir);
   strcat(fin, "/providerRegister");
   in = fopen(fin, "r");
   if (in == NULL) 
      mlogf(M_ERROR,M_SHOW, "--- %s not found\n", fin);
      
   else {

      br->hdl = bb;
      br->ft = ProviderRegisterFT;
      bb->fn = strdup(fin);
      bb->ht = UtilFactory->newHashTable(61,
                  UtilHashTable_charKey | UtilHashTable_ignoreKeyCase);

      while (fgets(fin, 1024, in)) {
         n++;
         if (stmt) free(stmt);
         stmt = strdup(fin);
         switch (cntlParseStmt(fin, &rv)) {
         case 0:
            mlogf(M_ERROR,M_SHOW,"--- registration statement not recognized: \n\t%d: %s\n", n,stmt);
            err = 1;
            break;
         case 1:
            if (info) {
               if (classProvInfoPtr==NULL) {
                  if (strcmp(info->className,"$ClassProvider$")==0) classProvInfoPtr=info;
               }   
               else if (defaultProvInfoPtr==NULL) {
                  if (strcmp(info->className,"$DefaultProvider$")==0) defaultProvInfoPtr=info;
               }   
               else if (interOpProvInfoPtr==NULL) {
                  if (strcmp(info->className,"$InterOpProvider$")==0) {
                     if (exFlags & 2) interOpProvInfoPtr=info;
                     else interopFound=1;
                  }   
               }               
               else if (qualiProvInfoPtr==NULL) {
                  if (strcmp(info->className,"$QualifierProvider$")==0) qualiProvInfoPtr=info;
               }
               err = addProviderToHT(info, ((ProviderBase *) br->hdl)->ht);
	       if (err)
		  break;
            }
            info = (ProviderInfo *) calloc(1, sizeof(ProviderInfo));
            info->className = strdup(rv.id);
            info->id= ++id;
            // Set the default provider uid
            info->uid=provuid;
            if (!provSFCB)
               info->user=strdup(provuser);
            break;
         case 2:
            if (strcmp(rv.id, "provider") == 0)
               info->providerName = strdup(cntlGetVal(&rv));
            else if (strcmp(rv.id, "location") == 0)
               info->location = strdup(cntlGetVal(&rv));
            else if (strcmp(rv.id, "parameters") == 0) {
               info->parms = strdup(cntlGetStr(&rv));
               for (i=strlen(info->parms); i>0 && info->parms[i]<=' '; i--) {
                   info->parms[i]=0;
               }
            }
            else if (strcmp(rv.id, "user") == 0) {
               info->user = strdup(cntlGetVal(&rv));
               errno=0;
               passwd=getpwnam(info->user);
               if (passwd) {
                  info->uid=passwd->pw_uid;
               } else {
                  mlogf(M_ERROR,M_SHOW,"--- Couldn't find username %s requested in providerRegister. Errno: %d\n",info->user,errno);
                  err = 1;
                  break;
               }
            }
            else if (strcmp(rv.id, "group") == 0)
               info->group = strdup(cntlGetVal(&rv));
            else if (strcmp(rv.id, "unload") == 0) {
               char *u;
               info->unload = 0;
               while ((u = cntlGetVal(&rv)) != NULL) {
                  if (strcmp(u, "never") == 0) {
                     info->unload =-1;
                  }   
                  else {
                     mlogf(M_ERROR,M_SHOW,"--- invalid unload specification: \n\t%d: %s\n", n, stmt);
                     err = 1;
                  }
               }   
            }   
            else if (strcmp(rv.id, "type") == 0) {
               char *t;
               info->type = 0;
               while ((t = cntlGetVal(&rv)) != NULL) {
                  if (strcmp(t, "instance") == 0)
                     info->type |= INSTANCE_PROVIDER;
                  else if (strcmp(t, "association") == 0)
                     info->type |= ASSOCIATION_PROVIDER;
                  else if (strcmp(t, "method") == 0)
                     info->type |= METHOD_PROVIDER;
                  else if (strcmp(t, "indication") == 0)
                     info->type |= INDICATION_PROVIDER;
                  else if (strcmp(t, "class") == 0)
                     info->type |= CLASS_PROVIDER;
                  else if (strcmp(t, "property") == 0)
                     info->type |= PROPERTY_PROVIDER; 
                  else if (strcmp(t, "qualifier") == 0)
                     info->type |= QUALIFIER_PROVIDER;                     
                  else {
                     mlogf(M_ERROR,M_SHOW,"--- invalid type specification: \n\t%d: %s\n", n, stmt);
                     err = 1;
                  }
               }
            }
            else if (strcmp(rv.id, "namespace") == 0) {
               int max=1,next=0;
               char *t;
               info->ns=(char**)malloc(sizeof(char*)*(max+1));
               while ((t = cntlGetVal(&rv)) != NULL) {
                  if (next==max) {
                     max++;
                     info->ns=(char**)realloc(info->ns,sizeof(char*)*(max+1));
                  }
                  info->ns[next]=strdup(t);
                  info->ns[++next]=NULL;
               }
            }
            else {
               mlogf(M_ERROR,M_SHOW,"--- invalid registration statement: \n\t%d: %s\n", n, stmt);
               err = 1;
            }
            break;
         case 3:
            break;
         }
	 if (err)
	    break;
      }

      if (info) {
	if (err == 0) {
	  err = addProviderToHT(info, ((ProviderBase *) br->hdl)->ht);
        }
	else {
	  freeInfoPtr(info);
	}
      }
   }
   if (in) {
     fclose(in);
   }
   
   if (classProvInfoPtr==NULL) {
      mlogf(M_ERROR,M_SHOW,"--- Class provider definition not found - sfcbd will terminate\n");
      err=1;
   }
   
   if (defaultProvInfoPtr==NULL) 
      mlogf(M_INFO,M_SHOW,"--- Default provider definition not found - no instance repository available\n");

   if (qualiProvInfoPtr==NULL) 
      mlogf(M_INFO,M_SHOW,"--- Qualifier provider definition not found - no qualifier support available\n");
   
   if (interOpProvInfoPtr==NULL) {
      if (exFlags & 2 && interopFound==0)
         mlogf(M_INFO,M_SHOW,"--- InterOp provider definition not found - no InterOp support available\n");
      else if (interopFound)    
         mlogf(M_INFO,M_SHOW,"--- InterOp provider definition found but not started - no InterOp support available\n");
      interOpProvInfoPtr=&forceNotFound;
   }   
   
   if (err) {
      mlogf(M_ERROR,M_SHOW,"--- Broker terminated because of previous error(s)\n");
      exit(5);
   }
   if (stmt) free(stmt);
   return br;
}
예제 #25
0
static ClassRegister *
newClassRegister(char *fname, char *ns)
{
  ClassRegister  *cr =
      (ClassRegister *) malloc(sizeof(ClassRegister) + sizeof(ClassBase));
  ClassBase      *cb = (ClassBase *) (cr + 1);
  FILE           *in;
  char            fin[1024];
  long            s,
                  total = 0;
  ClObjectHdr     hdr;
  ClVersionRecord *vrp = (ClVersionRecord *) & hdr;
  int             vRec = 0,
      first = 1;

  cr->hdl = cb;
  // cr->ft = ClassRegisterFT;
  cr->vr = NULL;
  cr->assocs = cr->topAssocs = 0;

  strcpy(fin, fname);
  strcat(fin, "/classSchemas");
  fprintf(stderr, "Opening %s\n", fname);
  in = fopen(fin, "r");

  if (in == NULL) {
    fprintf(stderr, "-*- classSchema directory %s not found\n", fname);
    return NULL;
  }

  cr->fn = strdup(fin);
  cb->ht = UtilFactory->newHashTable(61,
                                     UtilHashTable_charKey |
                                     UtilHashTable_ignoreKeyCase);
  MRWInit(&cb->mrwLock);

  while ((s = fread(&hdr, 1, sizeof(hdr), in)) == sizeof(hdr)) {
    CMPIConstClass *cc = NULL;
    char           *buf = NULL;
    char           *cn;

    if (first) {
      if (vrp->size == sizeof(ClVersionRecord) && vrp->type == HDR_Version)
        vRec = 1;
      else if (vrp->size == sizeof(ClVersionRecord) << 24
               && vrp->type == HDR_Version) {
        mlogf(M_ERROR, M_SHOW, "--- %s is in wrong endian format\n", fin);
        fclose(in);
        return NULL;
      }
    }

    if (vRec == 0 && hdr.type != HDR_Class) {
      mlogf(M_ERROR, M_SHOW, "--- %s contains non-class record(s)\n", fin);
      fclose(in);
      return NULL;
    }

    buf = (char *) malloc(hdr.size);
    if (buf == NULL) {
      mlogf(M_ERROR, M_SHOW,
            "--- %s contains record(s) that are too long\n", fin);
      fclose(in);
      return NULL;
    }

    s = hdr.size;
    *((ClObjectHdr *) buf) = hdr;

    if (fread(buf + sizeof(hdr), 1, hdr.size - sizeof(hdr), in) ==
        hdr.size - sizeof(hdr)) {
      if (vRec) {
        cr->vr = (ClVersionRecord *) buf;
        vrp = NEW(ClVersionRecord);
        memcpy(vrp, cr->vr, sizeof(ClVersionRecord));
        if (strcmp(cr->vr->id, "sfcb-rep")) {
          mlogf(M_ERROR, M_SHOW,
                "--- %s contains invalid version record - directory skipped\n",
                fin);
          fclose(in);
          free(cr);
          free(buf);
          free(vrp);
          return NULL;
        }
        vRec = 0;
      } else {
        vrp = NULL;
      }

      if (first) {
        int             v = -1;
        first = 0;
        if (ClVerifyObjImplLevel(vrp))
          continue;
        if (vrp)
          v = vrp->objImplLevel;
        mlogf(M_ERROR, M_SHOW,
              "--- %s contains unsupported object implementation format (%d) - directory skipped\n",
              fin, v);
        fclose(in);
        free(cr);
        free(buf);
        if (vrp) {
          free(vrp);
        }
        return NULL;
      }

      cc = NEW(CMPIConstClass);
      cc->hdl = buf;
      cc->ft = CMPIConstClassFT;
      cc->ft->relocate(cc);
      cn = (char *) cc->ft->getCharClassName(cc);
      if (strncmp(cn, "DMY_", 4) != 0) {

        total += s;
        cb->ht->ft->put(cb->ht, cn, cc);
        if (cc->ft->isAssociation(cc)) {
          cr->assocs++;
          if (cc->ft->getCharSuperClassName(cc) == NULL)
            cr->topAssocs++;
        }
      }
    } else {
      mlogf(M_ERROR, M_SHOW,
            "--- %s contains invalid record(s) - directory skipped\n",
            fin);
      fclose(in);
      free(cr);
      free(buf);
      return NULL;
    }
  }

  fclose(in);

  if (cr->vr) {
    mlogf(M_INFO, M_SHOW,
          "--- ClassProvider for %s (%d.%d) using %ld bytes\n", fname,
          cr->vr->version, cr->vr->level, total);
  } else
    mlogf(M_INFO, M_SHOW,
          "--- ClassProvider for %s (no-version) using %ld bytes\n", fname,
          total);

  buildClassSource(cr, ns);

  return cr;
}
예제 #26
0
int ipfix_export_drecord_db( ipfixs_node_t      *s,
                             ipfixt_node_t      *t,
                             ipfix_datarecord_t *d,
                             void               *arg )
{
    ipfixe_data_db_t *data = (ipfixe_data_db_t*)arg;
    char             *func = "export_drecord_db";
    int              i, nbytes, binary_f=0;

    if ( !data->mysql )
        return -1;

    /* write data set into database
     * todo: log error if query buffer is too small
     */
    snprintf( query, MAXQUERYLEN, 
              "INSERT INTO %s SET %s='%u'", 
              t->tablename, IPFIX_DB_DT_MSGID, s->last_msgid );
    nbytes = strlen(query);
    for ( i=0; i<t->ipfixt->nfields; i++ ) {
#ifdef IENAME_COLUMNS
        nbytes += snprintf( query+nbytes, sizeof(query)-nbytes, ", %s='",
                            t->ipfixt->fields[i].elem->ft->name );
#else
        nbytes += snprintf( query+nbytes, sizeof(query)-nbytes,
                            ", " IPFIX_DB_COLUMNNAME_FORMAT "='",
                            t->ipfixt->fields[i].elem->ft->eno,
                            t->ipfixt->fields[i].elem->ft->ftype );
#endif
        if ( nbytes >= sizeof(query) )
            goto err;

        if ( t->ipfixt->fields[i].elem->ft->coding == IPFIX_CODING_BYTES ) {
            if ( ((d->lens[i]*2)+2) < (sizeof(query)-nbytes) ) {  
                nbytes += mysql_real_escape_string( data->mysql, query+nbytes, 
                                                    d->addrs[i], d->lens[i] );
                binary_f++;
            }
        }
        else {
            nbytes += t->ipfixt->fields[i].elem->snprint( query+nbytes, 
                                                          sizeof(query)-nbytes, 
                                                          d->addrs[i],
                                                          d->lens[i] );
        }
        if ( (nbytes+1) >= sizeof(query) )
            goto err;
        nbytes += snprintf( query+nbytes, sizeof(query)-nbytes, "'" );
    }
    mlogf( 4, "[%s] query: %s\n", func, query );
    if ( mysql_real_query( data->mysql, query, nbytes ) !=0 ) {
        mlogf( 0, "[%s] mysql_query(%s) failed: %s\n", 
               func, binary_f?"":query, mysql_error(data->mysql) );
        return -1;
    }

    /** insert template id into mapping table (if not already done)
     */
    if ( t->message_snr != s->last_message_snr ) {
        snprintf( query, MAXQUERYLEN, 
                  "INSERT INTO %s SET %s=%u, %s=%u ", 
                  IPFIX_DB_MAPPINGTABLE, IPFIX_DB_MT_MSGID,
                  s->last_msgid, IPFIX_DB_MT_TMPLID, t->template_id );
        mlogf( 4, "[%s] query: %s\n", func, query );
        if ( mysql_query( data->mysql, query ) !=0 ) {
            mlogf( 0, "[%s] mysql_query(%s) failed: %s\n", 
                   func, query, mysql_error(data->mysql) );
            return -1;
        }

        /** mark that message uses this template
         */
        t->message_snr = s->last_message_snr;
    }

    return 0;

 err:
    return -1;
}
예제 #27
0
static ClassRegister *
newClassRegister(char *fname)
{
  ClassRegister  *cr = (ClassRegister *) calloc(1,
                                                sizeof(ClassRegister) +
                                                sizeof(ClassBase));
  ClassBase      *cb = (ClassBase *) (cr + 1);
  char            fin[1024];
  long            s,
                  total = 0;
  ClObjectHdr     hdr;
  ClVersionRecord *vrp = (ClVersionRecord *) & hdr;
  int             vRec = 0,
      first = 1;

  z_off_t         pos = 0;
  ClassRecord    *crec;

  cr->hdl = cb;
  cr->ft = ClassRegisterFT;
  cr->vr = NULL;
  cr->assocs = cr->topAssocs = 0;

  strcpy(fin, fname);
  strcat(fin, "/classSchemas");
  cr->f = gzopen(fin, "r");
  if (cr->f == NULL) {
    strcat(fin, ".gz");
    cr->f = gzopen(fin, "r");
  }

  cb->ht = UtilFactory->newHashTable(61,
                                     UtilHashTable_charKey |
                                     UtilHashTable_ignoreKeyCase);
  cb->it =
      UtilFactory->newHashTable(61,
                                UtilHashTable_charKey |
                                UtilHashTable_ignoreKeyCase);
  MRWInit(&cb->mrwLock);

  if (cr->f == NULL)
    return cr;

  cr->fn = strdup(fin);
  cr->vr = NULL;
  pos = gztell(cr->f);

  while ((s = gzread(cr->f, &hdr, sizeof(hdr))) == sizeof(hdr)) {
    CMPIConstClass *cc = NULL;
    char           *buf = NULL;
    const char     *cn,
                   *pn;

    if (first) {
      if (vrp->size == sizeof(ClVersionRecord) && vrp->type == HDR_Version)
        vRec = 1;
      else if (vrp->size == sizeof(ClVersionRecord) << 24
               && vrp->type == HDR_Version) {
        mlogf(M_ERROR, M_SHOW,
              "--- %s is in wrong endian format - directory skipped\n",
              fin);
        return NULL;
      }
    }

    if (vRec == 0 && hdr.type != HDR_Class
        && hdr.type != HDR_IncompleteClass) {
      mlogf(M_ERROR, M_SHOW,
            "--- %s contains non-class record(s) - directory skipped %d\n",
            fin, hdr.type);
      return NULL;
    }

    buf = (char *) malloc(hdr.size);
    if (buf == NULL) {
      mlogf(M_ERROR, M_SHOW,
            "--- %s contains record(s) that are too long - directory skipped\n",
            fin);
      return NULL;
    }

    s = hdr.size;
    *((ClObjectHdr *) buf) = hdr;

    if (gzread(cr->f, buf + sizeof(hdr), hdr.size - sizeof(hdr)) ==
        hdr.size - sizeof(hdr)) {
      if (vRec) {
        cr->vr = (ClVersionRecord *) buf;
        if (strcmp(cr->vr->id, "sfcb-rep")) {
          mlogf(M_ERROR, M_SHOW,
                "--- %s contains invalid version record - directory skipped\n",
                fin);
          return NULL;
        }
        pos = gztell(cr->f);
        vRec = 0;
      }

      if (first) {
        int             v = -1;
        first = 0;
        if (ClVerifyObjImplLevel(cr->vr))
          continue;
        if (cr->vr)
          v = cr->vr->objImplLevel;
        mlogf(M_ERROR, M_SHOW,
              "--- %s contains unsupported object implementation format (%d) - directory skipped\n",
              fin, v);
        return NULL;
      }

      cc = NEW(CMPIConstClass);
      cc->hdl = buf;
      cc->ft = CMPIConstClassFT;
      cc->ft->relocate(cc);
      cn = (char *) cc->ft->getCharClassName(cc);

      if (strncmp(cn, "DMY_", 4) != 0) {
        total += sizeof(ClassRecord);
        crec = (ClassRecord *) calloc(1, sizeof(ClassRecord));

        if ((pn = cc->ft->getCharSuperClassName(cc))) {
          crec->parent = strdup(pn);
        }
        crec->position = pos;
        crec->length = s;
        cr->ft->putClass(cr, strdup(cn), crec);

        if (cc->ft->isAssociation(cc)) {
          crec->flags |= CREC_isAssociation;
          cr->assocs++;
          if (pn == NULL)
            cr->topAssocs++;
        }
      }
      first = 0;
    } else {
      mlogf(M_ERROR, M_SHOW,
            "--- %s contains invalid record(s) - directory skipped\n",
            fin);
      return NULL;
    }
    pos = gztell(cr->f);
    free(buf);
    free(cc);
  }

  if (cr->vr) {
    mlogf(M_INFO, M_SHOW,
          "--- Caching ClassProviderSf for %s (%d.%d-%d) using %ld bytes\n",
          fin, cr->vr->version, cr->vr->level, cr->vr->objImplLevel,
          total);
  } else
    mlogf(M_INFO, M_SHOW,
          "--- Caching ClassProviderSf for %s (no-version) using %ld bytes\n",
          fin, total);

  buildInheritanceTable(cr);

  return cr;
}
예제 #28
0
static CMPIStatus
ClassProviderInvokeMethod(CMPIMethodMI * mi,
                          const CMPIContext *ctx,
                          const CMPIResult *rslt,
                          const CMPIObjectPath * ref,
                          const char *methodName,
                          const CMPIArgs * in, CMPIArgs * out)
{
  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIArray      *ar;
  int             rc;
  ClassRegister  *cReg;

  _SFCB_ENTER(TRACE_PROVIDERS, "ClassProviderInvokeMethod");

  cReg = getNsReg(ref, &rc);
  if (cReg == NULL) {
    CMPIStatus      st = { CMPI_RC_ERR_INVALID_NAMESPACE, NULL };
    _SFCB_RETURN(st);
  }

  if (strcasecmp(methodName, "getchildren") == 0) {
    CMPIData        cn = CMGetArg(in, "class", NULL);
    _SFCB_TRACE(1, ("--- getchildren %s", (char *) cn.value.string->hdl));

    cReg->ft->wLock(cReg);

    if (cn.type == CMPI_string && cn.value.string && cn.value.string->hdl) {
      char           *child;
      int             l = 0,
          i = 0;
      UtilList       *ul =
          getChildren(cReg, (char *) cn.value.string->hdl);
      if (ul)
        l = ul->ft->size(ul);
      ar = CMNewArray(_broker, l, CMPI_string, NULL);
      if (ul)
        for (child = (char *) ul->ft->getFirst(ul); child; child = (char *)
             ul->ft->getNext(ul)) {
          CMSetArrayElementAt(ar, i++, child, CMPI_chars);
        }
      st = CMAddArg(out, "children", &ar, CMPI_stringA);
    } else {
    }

    cReg->ft->wUnLock(cReg);

  }

  else if (strcasecmp(methodName, "getallchildren") == 0) {
    int             ignprov = 0;
    CMPIStatus      st;
    CMPIData        cn = CMGetArg(in, "class", &st);

    cReg->ft->wLock(cReg);

    if (st.rc != CMPI_RC_OK) {
      cn = CMGetArg(in, "classignoreprov", NULL);
      ignprov = 1;
    }
    _SFCB_TRACE(1,
                ("--- getallchildren %s", (char *) cn.value.string->hdl));
    if (cn.type == CMPI_string && cn.value.string && cn.value.string->hdl) {
      int             n = 0,
          i = 0;
      loopOnChildCount(cReg, (char *) cn.value.string->hdl, &n, ignprov);
      _SFCB_TRACE(1, ("--- count %d", n));
      ar = CMNewArray(_broker, n, CMPI_string, NULL);
      if (n) {
        _SFCB_TRACE(1, ("--- loop %s", (char *) cn.value.string->hdl));
        loopOnChildChars(cReg, (char *) cn.value.string->hdl, ar, &i,
                         ignprov);
      }
      st = CMAddArg(out, "children", &ar, CMPI_stringA);
    } else {
    }

    cReg->ft->wUnLock(cReg);
  }

  else if (strcasecmp(methodName, "getassocs") == 0) {
    ar = CMNewArray(_broker, cReg->topAssocs, CMPI_string, NULL);
    ClassBase      *cb = (ClassBase *) (cReg + 1);
    UtilHashTable  *ct = cb->ht;
    HashTableIterator *i;
    char           *cn;
    ClassRecord    *crec;
    int             n;

    cReg->ft->wLock(cReg);

    for (n = 0, i = ct->ft->getFirst(ct, (void **) &cn, (void **) &crec);
         i; i = ct->ft->getNext(ct, i, (void **) &cn, (void **) &crec)) {
      if (crec->flags & CREC_isAssociation && crec->parent == NULL) {
        /*
         * add top-level association class 
         */
        CMSetArrayElementAt(ar, n++, cn, CMPI_chars);
      }
    }
    CMAddArg(out, "assocs", &ar, CMPI_stringA);

    cReg->ft->wUnLock(cReg);
  }

  else if (strcasecmp(methodName, "ischild") == 0) {
    char           *parent = (char *) CMGetClassName(ref, NULL)->hdl;
    char           *chldn =
        (char *) CMGetArg(in, "child", NULL).value.string->hdl;
    st.rc = traverseChildren(cReg, parent, chldn);
  }

  else if (strcasecmp(methodName, "_startup") == 0) {

    /* let providerMgr know that we're odne init'ing  */
    semRelease(sfcbSem,INIT_CLASS_PROV_ID);

    st.rc = CMPI_RC_OK;
  }

  else {
    mlogf(M_ERROR, M_SHOW,
          "--- ClassProvider: Invalid invokeMethod request %s\n",
          methodName);
    st.rc = CMPI_RC_ERR_METHOD_NOT_FOUND;
  }
  _SFCB_RETURN(st);
}
예제 #29
0
CMPIStatus
IndCIMXMLHandlerInvokeMethod(CMPIMethodMI * mi,
                             const CMPIContext *ctx,
                             const CMPIResult *rslt,
                             const CMPIObjectPath * ref,
                             const char *methodName,
                             const CMPIArgs * in, CMPIArgs * out)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "IndCIMXMLHandlerInvokeMethod");

  CMPIStatus      st = { CMPI_RC_OK, NULL };
  CMPIStatus      circ = { CMPI_RC_OK, NULL };
  struct timeval tv;
  struct timezone tz;
  static unsigned int indID=1;


  if (interOpNameSpace(ref, &st) == 0)
    _SFCB_RETURN(st);

  if (strcasecmp(methodName, "_deliver") == 0) {

    // On the first indication, check if reliable indications are enabled.
    if (RIEnabled == -1) {
      CMPIObjectPath *op=CMNewObjectPath(_broker,"root/interop","CIM_IndicationService",NULL);
      CMPIEnumeration *isenm = _broker->bft->enumerateInstances(_broker, ctx, op, NULL, NULL);
      CMPIData isinst=CMGetNext(isenm,NULL);
      CMPIData mc=CMGetProperty(isinst.value.inst,"DeliveryRetryAttempts",NULL);
      RIEnabled=mc.value.uint16;
    }

    CMPIInstance *indo=CMGetArg(in,"indication",NULL).value.inst;
    CMPIInstance *ind=CMClone(indo,NULL);
    CMPIContext    *ctxLocal=NULL;
    CMPIObjectPath *iop=NULL,*subop=NULL;
    CMPIInstance *sub=NULL;

    if (RIEnabled) {
      ctxLocal = prepareUpcall((CMPIContext *) ctx);
      // Set the indication sequence values
      iop=CMGetObjectPath(ind,NULL);
      CMAddKey(iop,"SFCB_IndicationID",&indID,CMPI_uint32);
      CMSetProperty(ind,"SFCB_IndicationID",&indID,CMPI_uint32);
      // Prevent this property from showing up in the indication
      filterFlagProperty(ind, "SFCB_IndicationID");
      sub=CMGetArg(in,"subscription",NULL).value.inst;
      CMPIData handler=CMGetProperty(sub, "Handler", &st);
      CMPIObjectPath *hop=handler.value.ref;
      CMPIInstance *hdlr=CBGetInstance(_broker, ctxLocal, hop, NULL, &st);

      // Build the complete sequence context
      // Get the stub from the handler
      CMPIString *context = CMGetProperty(hdlr, "SequenceContext", &st).value.string;
      // and add the sfcb start time
      char *cstr=malloc( (strlen(context->ft->getCharPtr(context,NULL)) + strlen(sfcBrokerStart) + 1) * sizeof(char));
      sprintf(cstr,"%s%s",context->ft->getCharPtr(context,NULL),sfcBrokerStart);
      context = sfcb_native_new_CMPIString(cstr, NULL, 0); 
      // and put it in the indication
      CMSetProperty(ind, "SequenceContext", &context, CMPI_string);
      free(cstr);
      CMRelease(context);

      // Get the proper sequence number
      CMPIValue lastseq = CMGetProperty(hdlr, "LastSequenceNumber", &st).value;
      lastseq.sint64++;
      // Handle wrapping of the signed int
      if (lastseq.sint64 < 0) lastseq.sint64=0;
      // Update the last used number in the handler
      CMSetProperty(hdlr, "LastSequenceNumber", &lastseq.sint64, CMPI_sint64);
      CBModifyInstance(_broker, ctxLocal, hop, hdlr, NULL);
      // And the indication
      CMSetProperty(ind, "SequenceNumber", &lastseq, CMPI_sint64);
    }

    // Now send the indication
    st = deliverInd(ref, in, ind);
    if (st.rc != 0) {
      if (RIEnabled){
        _SFCB_TRACE(1,("--- Indication delivery failed, adding to retry queue"));
        // Indication delivery failed, send to retry queue
        // build an element
        RTElement      *element;
        element = (RTElement *) malloc(sizeof(*element));
        element->ref=ref->ft->clone(ref,NULL);
        // Get the OP of the subscription and indication
        subop=CMGetObjectPath(sub,NULL);
        element->sub=subop->ft->clone(subop,NULL);
        element->ind=iop->ft->clone(iop,NULL);
        // Store other attrs
        element->instanceID=indID;
        element->count=0;
        gettimeofday(&tv, &tz);
        element->lasttry=tv.tv_sec;
        // Push the indication to the repo
        CBCreateInstance(_broker, ctxLocal, iop, ind, &circ);
        if (circ.rc != 0) {
            mlogf(M_ERROR,M_SHOW,"Pushing indication instance to repository failed, rc:%d\n",circ.rc);
        }
        indID++;
        // Add it to the retry queue
        enqRetry(element,ctx,1);
        // And launch the thread if it isn't already running
        pthread_attr_init(&tattr);
        pthread_attr_setdetachstate(&tattr, PTHREAD_CREATE_DETACHED);
        if (retryRunning == 0) {
          retryRunning = 1;
          _SFCB_TRACE(1,("--- Starting retryExport thread"));
          CMPIContext    *pctx = native_clone_CMPIContext(ctx);
          pthread_create(&t, &tattr, &retryExport, (void *) pctx);
        }
        CMRelease(ctxLocal);
      }
    }
    CMRelease(ind);
  }
  else {
    printf("--- ClassProvider: Invalid request %s\n", methodName);
    st.rc = CMPI_RC_ERR_METHOD_NOT_FOUND;
  }

  _SFCB_RETURN(st);
}
예제 #30
0
void           *
retryExport(void *lctx)
{
  _SFCB_ENTER(TRACE_INDPROVIDER, "retryExport");

  CMPIObjectPath *ref;
  CMPIArgs       *in;
  CMPIInstance   *sub;
  CMPIContext    *ctx = (CMPIContext *) lctx;
  CMPIContext    *ctxLocal;
  RTElement      *cur,
                 *purge;
  struct timeval  tv;
  struct timezone tz;
  int             rint,
                  maxcount,
                  ract,
                  rtint;
  CMPIUint64      sfc = 0;
  CMPIObjectPath *op;
  CMPIEnumeration *isenm = NULL;

  //Setup signal handlers
  struct sigaction sa;
  sa.sa_handler = handle_sig_retry;
  sa.sa_flags = 0;
  sigemptyset(&sa.sa_mask);
  sigaction(SIGUSR2, &sa, NULL);

  CMPIStatus      st = { CMPI_RC_OK, NULL };

  ctxLocal = prepareUpcall(ctx);

  // Get the retry params from IndService
  op = CMNewObjectPath(_broker, "root/interop", "CIM_IndicationService",
                       NULL);
  isenm = _broker->bft->enumerateInstances(_broker, ctx, op, NULL, NULL);
  CMPIData        isinst = CMGetNext(isenm, NULL);
  CMPIData        mc =
      CMGetProperty(isinst.value.inst, "DeliveryRetryAttempts", NULL);
  CMPIData        ri =
      CMGetProperty(isinst.value.inst, "DeliveryRetryInterval", NULL);
  CMPIData        ra =
      CMGetProperty(isinst.value.inst, "SubscriptionRemovalAction", NULL);
  CMPIData        rti =
      CMGetProperty(isinst.value.inst, "SubscriptionRemovalTimeInterval",
                    NULL);
  maxcount = mc.value.uint16;   // Number of times to retry delivery
  rint = ri.value.uint32;       // Interval between retries
  rtint = rti.value.uint32;     // Time to allow sub to keep failing until 
  ract = ra.value.uint16;       // ... this action is taken

  // Now, run the queue
  sleep(5); //Prevent deadlock on startup when localmode is used.
  pthread_mutex_lock(&RQlock);
  cur = RQhead;
  while (RQhead != NULL) {
    if(retryShutdown) break; // Provider shutdown
    ref = cur->ref;
    // Build the CMPIArgs that deliverInd needs
    CMPIInstance *iinst=internalProviderGetInstance(cur->ind,&st);
    if (st.rc != 0 ) {
      mlogf(M_ERROR,M_SHOW,"Failed to retrieve indication instance from repository, rc:%d\n",st.rc);
      purge=cur;
      cur=cur->next;
      dqRetry(ctx,purge);
      continue;
    }
    in=CMNewArgs(_broker,NULL);
    CMAddArg(in,"indication",&iinst,CMPI_instance);
    sub=internalProviderGetInstance(cur->sub,&st);
    if (st.rc == CMPI_RC_ERR_NOT_FOUND) {
      // sub got deleted, purge this indication and move on
      _SFCB_TRACE(1,("--- Subscription for indication gone, deleting indication."));
      purge = cur;
      cur = cur->next;
      dqRetry(ctx,purge);
    } else {
      // Still valid, retry
      gettimeofday(&tv, &tz);
      if ((cur->lasttry + rint) > tv.tv_sec) {
        _SFCB_TRACE(1,("--- sleeping."));
        // no retries are ready, release the lock
        // and sleep for an interval, then relock
        pthread_mutex_unlock(&RQlock);
        sleep(rint);
        if(retryShutdown) break; // Provider shutdown
        pthread_mutex_lock(&RQlock);
      }
      st = deliverInd(ref, in, iinst);
      if ((st.rc == 0) || (cur->count >= maxcount - 1)) {
        // either it worked, or we maxed out on retries
        // If it succeeded, clear the failtime
        if (st.rc == 0) {
          _SFCB_TRACE(1,("--- Indication succeeded."));
          sfc = 0;
          CMSetProperty(sub, "DeliveryFailureTime", &sfc, CMPI_uint64);
          CBModifyInstance(_broker, ctxLocal, cur->sub, sub, NULL);
        }
        // remove from queue in either case
        _SFCB_TRACE(1,("--- Indication removed."));
        purge = cur;
        cur = cur->next;
        dqRetry(ctx,purge);
      } else {
        // still failing, leave on queue 
        _SFCB_TRACE(1,("--- Indication still failing."));
        cur->count++;
        gettimeofday(&tv, &tz);
        cur->lasttry = tv.tv_sec;

        CMPIInstance * indele=internalProviderGetInstance(cur->SFCBIndEle,&st);
        CMSetProperty(indele,"LastDelivery",&cur->lasttry,CMPI_sint32);
        CMSetProperty(indele,"RetryCount",&cur->count,CMPI_uint32);
        CBModifyInstance(_broker, ctxLocal, cur->SFCBIndEle, indele, NULL);

        CMPIData        sfcp =
            CMGetProperty(sub, "DeliveryFailureTime", NULL);
        sfc = sfcp.value.uint64;
        if (sfc == 0) {
          // if the time isn't set, this is the first failure
          sfc = tv.tv_sec;
          CMSetProperty(sub, "DeliveryFailureTime", &sfc, CMPI_uint64);
          CBModifyInstance(_broker, ctxLocal, cur->sub, sub, NULL);
          cur = cur->next;
        } else if (sfc + rtint < tv.tv_sec) {
          // Exceeded subscription removal threshold, if action is:
          // 2, delete the sub; 3, disable the sub; otherwise, nothing
          if (ract == 2) {
            _SFCB_TRACE(1,("--- Subscription threshold reached, deleting."));
            CBDeleteInstance(_broker, ctx, cur->sub);
            purge = cur;
            cur = cur->next;
            dqRetry(ctx,purge);
          } else if (ract == 3) {
            // Set sub state to disable(4)
            _SFCB_TRACE(1,("--- Subscription threshold reached, disable."));
            CMPIUint16      sst = 4;
            CMSetProperty(sub, "SubscriptionState", &sst, CMPI_uint16);
            CBModifyInstance(_broker, ctx, cur->sub, sub, NULL);
            purge = cur;
            cur = cur->next;
            dqRetry(ctx,purge);
          }
        } else {
          cur = cur->next;
        }
      }
    }
  }
  // Queue went dry, cleanup and exit
  _SFCB_TRACE(1,("--- Indication retry queue empty, thread exitting."));
  pthread_mutex_unlock(&RQlock);
  retryRunning = 0;
  CMRelease(ctxLocal);
  CMRelease(ctx);
  _SFCB_RETURN(NULL);
}