Пример #1
0
/* #define SERVER_DEBUG 1   */
int
main( int, char ** ) {

    int status;
    rsComm_t rsComm;
    char *tmpStr;

    ProcessType = AGENT_PT;

    // capture server properties
    irods::server_properties& props = irods::server_properties::getInstance();
    irods::error result = props.capture_if_needed();
    if ( !result.ok() ) {
        irods::log( PASSMSG( "failed to read server configuration", result ) );
    }

#ifdef windows_platform
    iRODSNtAgentInit( argc, argv );
#endif

#ifndef windows_platform
    signal( SIGINT, signalExit );
    signal( SIGHUP, signalExit );
    signal( SIGTERM, signalExit );
    /* set to SIG_DFL as recommended by andy.salnikov so that system()
     * call returns real values instead of 1 */
    signal( SIGCHLD, SIG_DFL );
    signal( SIGUSR1, signalExit );
    signal( SIGPIPE, SIG_IGN );

    // register irods signal handlers
    register_handlers();
#endif

#ifndef windows_platform
#ifdef SERVER_DEBUG
    if ( isPath( "/tmp/rodsdebug" ) ) {
        sleep( 20 );
    }
#endif
#endif

    memset( &rsComm, 0, sizeof( rsComm ) );
    rsComm.thread_ctx = ( thread_context* )malloc( sizeof( thread_context ) );

    status = initRsCommWithStartupPack( &rsComm, NULL );

    // =-=-=-=-=-=-=-
    // manufacture a network object for comms
    irods::network_object_ptr net_obj;
    irods::error ret = irods::network_factory( &rsComm, net_obj );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
    }

    if ( status < 0 ) {
        sendVersion( net_obj, status, 0, NULL, 0 );
        cleanupAndExit( status );
    }

    /* Handle option to log sql commands */
    tmpStr = getenv( SP_LOG_SQL );
    if ( tmpStr != NULL ) {
#ifdef SYSLOG
        int j = atoi( tmpStr );
        rodsLogSqlReq( j );
#else
        rodsLogSqlReq( 1 );
#endif
    }

    /* Set the logging level */
    tmpStr = getenv( SP_LOG_LEVEL );
    if ( tmpStr != NULL ) {
        int i;
        i = atoi( tmpStr );
        rodsLogLevel( i );
    }
    else {
        rodsLogLevel( LOG_NOTICE ); /* default */
    }

#ifdef SYSLOG
    /* Open a connection to syslog */
    openlog( "rodsAgent", LOG_ODELAY | LOG_PID, LOG_DAEMON );
#endif
    status = getRodsEnv( &rsComm.myEnv );

    if ( status < 0 ) {
        rodsLog( LOG_ERROR, "agentMain :: getRodsEnv failed" );
        sendVersion( net_obj, SYS_AGENT_INIT_ERR, 0, NULL, 0 );
        cleanupAndExit( status );
    }

    ret = setRECacheSaltFromEnv();
    if ( !ret.ok() ) {
        rodsLog( LOG_ERROR, "rodsAgent::main: Failed to set RE cache mutex name\n%s", ret.result().c_str() );
        exit( 1 );
    }

    // =-=-=-=-=-=-=-
    // load server side pluggable api entries
    irods::api_entry_table&  RsApiTable   = irods::get_server_api_table();
    irods::pack_entry_table& ApiPackTable = irods::get_pack_table();
    ret = irods::init_api_table(
              RsApiTable,
              ApiPackTable,
              false );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return 1;
    }

    // =-=-=-=-=-=-=-
    // load client side pluggable api entries
    irods::api_entry_table&  RcApiTable = irods::get_client_api_table();
    ret = irods::init_api_table(
              RcApiTable,
              ApiPackTable,
              true );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return 1;
    }




#if RODS_CAT
    if ( strstr( rsComm.myEnv.rodsDebug, "CAT" ) != NULL ) {
        chlDebug( rsComm.myEnv.rodsDebug );
    }
#endif

    status = initAgent( RULE_ENGINE_TRY_CACHE, &rsComm );

    if ( status < 0 ) {
        rodsLog( LOG_ERROR, "agentMain :: initAgent failed: %d", status );
        sendVersion( net_obj, SYS_AGENT_INIT_ERR, 0, NULL, 0 );
        cleanupAndExit( status );
    }

    /* move configConnectControl behind initAgent for now. need zoneName if
     * the user does not specify one in the input */
    initConnectControl();

    if ( rsComm.clientUser.userName[0] != '\0' ) {
        status = chkAllowedUser( rsComm.clientUser.userName,
                                 rsComm.clientUser.rodsZone );

        if ( status < 0 ) {
            sendVersion( net_obj, status, 0, NULL, 0 );
            cleanupAndExit( status );
        }
    }

    // =-=-=-=-=-=-=-
    // handle negotiations with the client regarding TLS if requested
    // this scope block makes valgrind happy
    {
        std::string neg_results;
        ret = irods::client_server_negotiation_for_server( net_obj, neg_results );
        if ( !ret.ok() || neg_results == irods::CS_NEG_FAILURE ) {
            irods::log( PASS( ret ) );
            // =-=-=-=-=-=-=-
            // send a 'we failed to negotiate' message here??
            // or use the error stack rule engine thingie
            irods::log( PASS( ret ) );
            sendVersion( net_obj, SYS_AGENT_INIT_ERR, 0, NULL, 0 );
            cleanupAndExit( ret.code() );

        }
        else {
            // =-=-=-=-=-=-=-
            // copy negotiation results to comm for action by network objects
            snprintf( rsComm.negotiation_results, sizeof( rsComm.negotiation_results ), "%s", neg_results.c_str() );
            //rsComm.ssl_do_accept = 1;

        }
    }

    /* send the server version and atatus as part of the protocol. Put
     * rsComm.reconnPort as the status */
    ret = sendVersion( net_obj, status, rsComm.reconnPort,
                       rsComm.reconnAddr, rsComm.cookie );

    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        sendVersion( net_obj, SYS_AGENT_INIT_ERR, 0, NULL, 0 );
        cleanupAndExit( status );
    }

    logAgentProc( &rsComm );

    // call initialization for network plugin as negotiated
    irods::network_object_ptr new_net_obj;
    ret = irods::network_factory( &rsComm, new_net_obj );
    if ( !ret.ok() ) {
        return ret.code();
    }

    ret = sockAgentStart( new_net_obj );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return ret.code();
    }

    new_net_obj->to_server( &rsComm );
    status = agentMain( &rsComm );

    // call initialization for network plugin as negotiated
    ret = sockAgentStop( new_net_obj );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        return ret.code();
    }

    new_net_obj->to_server( &rsComm );
    cleanup();
    free( rsComm.thread_ctx );
    free( rsComm.auth_scheme );
    rodsLog( LOG_NOTICE, "Agent exiting with status = %d", status );
    return status;
}
Пример #2
0
int
l3CreateByObjInfo( rsComm_t *rsComm, dataObjInp_t *dataObjInp,
                   dataObjInfo_t *dataObjInfo ) {
    int l3descInx;

    int retryCnt = 0;
    int chkType = 0; // JMC - backport 4774

    // =-=-=-=-=-=-=-
    // extract the host location from the resource hierarchy
    std::string location;
    irods::error ret = irods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
    if ( !ret.ok() ) {
        irods::log( PASSMSG( "l3CreateByObjInfo - failed in get_loc_for_hier_String", ret ) );
        return -1;
    }


    fileCreateInp_t fileCreateInp;
    memset( &fileCreateInp, 0, sizeof( fileCreateInp ) );
    rstrcpy( fileCreateInp.resc_name_, location.c_str(),      MAX_NAME_LEN );
    rstrcpy( fileCreateInp.resc_hier_, dataObjInfo->rescHier, MAX_NAME_LEN );
    rstrcpy( fileCreateInp.objPath,    dataObjInfo->objPath,  MAX_NAME_LEN );
    rstrcpy( fileCreateInp.addr.hostAddr, location.c_str(), NAME_LEN );

    rstrcpy( fileCreateInp.fileName, dataObjInfo->filePath, MAX_NAME_LEN );
    fileCreateInp.mode = getFileMode( dataObjInp );
    // =-=-=-=-=-=-=-
    // JMC - backport 4774
    chkType = getchkPathPerm( rsComm, dataObjInp, dataObjInfo );
    copyFilesystemMetadata( &dataObjInfo->condInput,
                            &fileCreateInp.condInput );
    if ( chkType == DISALLOW_PATH_REG ) {
        return PATH_REG_NOT_ALLOWED;
    }
    else if ( chkType == NO_CHK_PATH_PERM ) {
        fileCreateInp.otherFlags |= NO_CHK_PERM_FLAG;  // JMC - backport 4758
    }
    rstrcpy( fileCreateInp.in_pdmo, dataObjInfo->in_pdmo, MAX_NAME_LEN );

    // =-=-=-=-=-=-=-
    std::string prev_resc_hier = fileCreateInp.resc_hier_;
    l3descInx = rsFileCreate( rsComm, &fileCreateInp );

    // update the dataObjInfo with the potential changes made by the resource - hcj
    rstrcpy( dataObjInfo->rescHier, fileCreateInp.resc_hier_, MAX_NAME_LEN );
    rstrcpy( dataObjInfo->filePath, fileCreateInp.fileName, MAX_NAME_LEN );

    /* file already exists ? */
    while ( l3descInx <= 2 && retryCnt < 100 &&
            getErrno( l3descInx ) == EEXIST ) {
        if ( resolveDupFilePath( rsComm, dataObjInfo, dataObjInp ) < 0 ) {
            break;
        }
        rstrcpy( fileCreateInp.fileName, dataObjInfo->filePath, MAX_NAME_LEN );
        l3descInx = rsFileCreate( rsComm, &fileCreateInp );
        // update the dataObjInfo with the potential changes made by the resource - hcj
        rstrcpy( dataObjInfo->rescHier, fileCreateInp.resc_hier_, MAX_NAME_LEN );
        rstrcpy( dataObjInfo->filePath, fileCreateInp.fileName, MAX_NAME_LEN );
        retryCnt ++;
    }
    return ( l3descInx );
}
Пример #3
0
int
rsQuerySpecColl( rsComm_t *rsComm, dataObjInp_t *dataObjInp,
                 genQueryOut_t **genQueryOut ) {

    int specCollInx;
    int status;
    int continueFlag;   /* continue query */
    int remoteFlag;
    rodsServerHost_t *rodsServerHost;
    remoteFlag = getAndConnRcatHost( rsComm, SLAVE_RCAT, dataObjInp->objPath,
                                     &rodsServerHost );

    if ( remoteFlag < 0 ) {
        return remoteFlag;
    }
    else if ( remoteFlag == REMOTE_HOST ) {
        status = rcQuerySpecColl( rodsServerHost->conn, dataObjInp,
                                  genQueryOut );
        return status;
    }

    // =-=-=-=-=-=-=-
    // working on the "home zone", determine if we need to redirect to a different
    // server in this zone for this operation.  if there is a RESC_HIER_STR_KW then
    // we know that the redirection decision has already been made
    std::string hier;
    char* hier_kw = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
    if ( NULL == hier_kw ) {
        irods::error ret = irods::resolve_resource_hierarchy( irods::OPEN_OPERATION, rsComm,
                           dataObjInp, hier );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << "failed for [";
            msg << dataObjInp->objPath << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
            return ret.code();
        }

        // =-=-=-=-=-=-=-
        // we resolved the redirect and have a host, set the hier str for subsequent
        // api calls, etc.
        addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );

    }

    if ( ( specCollInx = dataObjInp->openFlags ) <= 0 ) {
        specCollInx = openSpecColl( rsComm, dataObjInp, -1 );
        if ( specCollInx < 0 ) {
            rodsLog( LOG_NOTICE,
                     "rsQuerySpecColl: openSpecColl error for %s, status = %d",
                     dataObjInp->objPath, specCollInx );
            return specCollInx;
        }
        continueFlag = 0;
    }
    else {
        continueFlag = 1;
    }

    initOutForQuerySpecColl( genQueryOut );

    status = _rsQuerySpecColl( rsComm, specCollInx, dataObjInp,
                               *genQueryOut, continueFlag );

    if ( status < 0 ) {
        freeGenQueryOut( genQueryOut );
    }
    return status;
}
Пример #4
0
int
l3FilePutSingleBuf( rsComm_t *rsComm, int l1descInx, bytesBuf_t *dataObjInpBBuf ) {
    dataObjInfo_t *dataObjInfo;
    fileOpenInp_t filePutInp;
    int bytesWritten;
    dataObjInp_t *dataObjInp;
    int retryCnt = 0;
    int chkType = 0; // JMC - backport 4774

    dataObjInfo = L1desc[l1descInx].dataObjInfo;
    dataObjInp = L1desc[l1descInx].dataObjInp;

    // =-=-=-=-=-=-=-
    // extract the host location from the resource hierarchy
    std::string location;
    irods::error ret = irods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
    if ( !ret.ok() ) {
        irods::log( PASSMSG( "l3FilePutSingleBuf - failed in get_loc_for_hier_string", ret ) );
        return -1;
    }

    if ( getStructFileType( dataObjInfo->specColl ) >= 0 ) {
        subFile_t subFile;

        memset( &subFile, 0, sizeof( subFile ) );
        rstrcpy( subFile.subFilePath, dataObjInfo->subPath, MAX_NAME_LEN );
        rstrcpy( subFile.addr.hostAddr, location.c_str(), NAME_LEN );
        subFile.specColl = dataObjInfo->specColl;
        subFile.mode = getFileMode( dataObjInp );
        subFile.flags = O_WRONLY | dataObjInp->openFlags;

        if ( ( L1desc[l1descInx].replStatus & OPEN_EXISTING_COPY ) != 0 ) {
            subFile.flags |= FORCE_FLAG;
        }

        bytesWritten = rsSubStructFilePut( rsComm, &subFile, dataObjInpBBuf );
        return bytesWritten;


    } // struct file type >= 0

    std::string prev_resc_hier;
    memset( &filePutInp, 0, sizeof( filePutInp ) );
    rstrcpy( filePutInp.resc_hier_, dataObjInfo->rescHier, MAX_NAME_LEN );
    rstrcpy( filePutInp.objPath, dataObjInp->objPath, MAX_NAME_LEN );
    if ( ( L1desc[l1descInx].replStatus & OPEN_EXISTING_COPY ) != 0 ) {
        filePutInp.otherFlags |= FORCE_FLAG;
    }

    rstrcpy( filePutInp.addr.hostAddr, location.c_str(), NAME_LEN );
    rstrcpy( filePutInp.fileName, dataObjInfo->filePath, MAX_NAME_LEN );
    filePutInp.mode = getFileMode( dataObjInp );

    filePutInp.flags = O_WRONLY | dataObjInp->openFlags;
    rstrcpy( filePutInp.in_pdmo, L1desc[l1descInx].in_pdmo, MAX_NAME_LEN );
    // kv pasthru
    copyKeyVal(
        &dataObjInfo->condInput,
        &filePutInp.condInput );

    // =-=-=-=-=-=-=-
    // JMC - backport 4774
    chkType = getchkPathPerm( rsComm, L1desc[l1descInx].dataObjInp, L1desc[l1descInx].dataObjInfo );

    if ( chkType == DISALLOW_PATH_REG ) {
        clearKeyVal( &filePutInp.condInput );
        return PATH_REG_NOT_ALLOWED;
    }
    else if ( chkType == NO_CHK_PATH_PERM ) {
        // =-=-=-=-=-=-=-
        filePutInp.otherFlags |= NO_CHK_PERM_FLAG; // JMC - backport 4758
    }

    filePutOut_t* put_out = 0;
    prev_resc_hier = filePutInp.resc_hier_;
    bytesWritten = rsFilePut( rsComm, &filePutInp, dataObjInpBBuf, &put_out );

    // update the dataObjInfo with the potential changes made by the resource - hcj
    rstrcpy( dataObjInfo->rescHier, filePutInp.resc_hier_, MAX_NAME_LEN );
    if ( put_out ) {
        rstrcpy( dataObjInfo->filePath, put_out->file_name, MAX_NAME_LEN );
        free( put_out );
    }

    /* file already exists ? */
    while ( bytesWritten < 0 && retryCnt < 10 &&
            ( filePutInp.otherFlags & FORCE_FLAG ) == 0 &&
            getErrno( bytesWritten ) == EEXIST ) {

        if ( resolveDupFilePath( rsComm, dataObjInfo, dataObjInp ) < 0 ) {
            break;
        }
        rstrcpy( filePutInp.fileName, dataObjInfo->filePath, MAX_NAME_LEN );


        filePutOut_t* put_out = 0;
        bytesWritten = rsFilePut( rsComm, &filePutInp, dataObjInpBBuf, &put_out );
        // update the dataObjInfo with the potential changes made by the resource - hcj
        rstrcpy( dataObjInfo->rescHier, filePutInp.resc_hier_, MAX_NAME_LEN );
        if ( put_out ) {
            rstrcpy( dataObjInfo->filePath, put_out->file_name, MAX_NAME_LEN );
            free( put_out );
        }
        retryCnt ++;
    } // while
    clearKeyVal( &filePutInp.condInput );
    return bytesWritten;

} // l3FilePutSingleBuf
Пример #5
0
int
rsDataObjRsync( rsComm_t *rsComm, dataObjInp_t *dataObjInp,
                msParamArray_t **outParamArray ) {
    int status;
    char *rsyncMode;
    char *remoteZoneOpr;
    int remoteFlag;
    rodsServerHost_t *rodsServerHost;
    specCollCache_t *specCollCache = NULL;

    *outParamArray = NULL;
    if ( dataObjInp == NULL ) {
        rodsLog( LOG_ERROR, "rsDataObjRsync error. NULL input" );
        return SYS_INTERNAL_NULL_INPUT_ERR;
    }

    rsyncMode = getValByKey( &dataObjInp->condInput, RSYNC_MODE_KW );
    if ( rsyncMode == NULL ) {
        rodsLog( LOG_ERROR,
                 "rsDataObjRsync: RSYNC_MODE_KW input is missing" );
        return USER_RSYNC_NO_MODE_INPUT_ERR;
    }

    if ( strcmp( rsyncMode, LOCAL_TO_IRODS ) == 0 ) {
        remoteZoneOpr = REMOTE_CREATE;
    }
    else {
        remoteZoneOpr = REMOTE_OPEN;
    }

    resolveLinkedPath( rsComm, dataObjInp->objPath, &specCollCache,
                       &dataObjInp->condInput );
    if ( strcmp( rsyncMode, IRODS_TO_IRODS ) == 0 ) {
        if ( isLocalZone( dataObjInp->objPath ) == 0 ) {
            dataObjInp_t myDataObjInp;
            char *destObjPath;
            /* source in a remote zone. try dest */
            destObjPath = getValByKey( &dataObjInp->condInput,
                                       RSYNC_DEST_PATH_KW );
            if ( destObjPath == NULL ) {
                rodsLog( LOG_ERROR,
                         "rsDataObjRsync: RSYNC_DEST_PATH_KW input is missing for %s",
                         dataObjInp->objPath );
                return USER_RSYNC_NO_MODE_INPUT_ERR;
            }
            myDataObjInp = *dataObjInp;
            remoteZoneOpr = REMOTE_CREATE;
            rstrcpy( myDataObjInp.objPath, destObjPath, MAX_NAME_LEN );
            remoteFlag = getAndConnRemoteZone( rsComm, &myDataObjInp,
                                               &rodsServerHost, remoteZoneOpr );
        }
        else {
            remoteFlag = getAndConnRemoteZone( rsComm, dataObjInp,
                                               &rodsServerHost, remoteZoneOpr );
        }
    }
    else {
        remoteFlag = getAndConnRemoteZone( rsComm, dataObjInp, &rodsServerHost,
                                           remoteZoneOpr );
    }

    // =-=-=-=-=-=-=-
    // determine the resource hierarchy if one is not provided
    if ( getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW ) == NULL ) {
        std::string       hier;
        irods::error ret = irods::resolve_resource_hierarchy( irods::OPEN_OPERATION,
                           rsComm, dataObjInp, hier );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << __FUNCTION__;
            msg << " :: failed in irods::resolve_resource_hierarchy for [";
            msg << dataObjInp->objPath << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
            return ret.code();
        }

        // =-=-=-=-=-=-=-
        // we resolved the redirect and have a host, set the hier str for subsequent
        // api calls, etc.
        addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );

    } // if keyword




    if ( remoteFlag < 0 ) {
        return remoteFlag;
    }
    else if ( remoteFlag == REMOTE_HOST ) {

        status = _rcDataObjRsync( rodsServerHost->conn, dataObjInp,
                                  outParamArray );
        return status;
    }

    if ( strcmp( rsyncMode, IRODS_TO_LOCAL ) == 0 ) {
        status = rsRsyncFileToData( rsComm, dataObjInp );
    }
    else if ( strcmp( rsyncMode, LOCAL_TO_IRODS ) == 0 ) {
        status = rsRsyncDataToFile( rsComm, dataObjInp );
    }
    else if ( strcmp( rsyncMode, IRODS_TO_IRODS ) == 0 ) {
        status = rsRsyncDataToData( rsComm, dataObjInp );
    }
    else {
        rodsLog( LOG_ERROR,
                 "rsDataObjRsync: rsyncMode %s  not supported" );
        return USER_RSYNC_NO_MODE_INPUT_ERR;
    }

    return status;
}
        error resolve_from_property( std::string   _prop,    // property key
                                     value_type    _value,   // property value
                                     resource_ptr& _resc ) { // outgoing resource variable
            // =-=-=-=-=-=-=-
            // simple flag to state a resource matching the prop and value is found
            bool found = false;

            // =-=-=-=-=-=-=-
            // quick check on the resource table
            if ( resources_.empty() ) {
                return ERROR( SYS_INVALID_INPUT_PARAM, "empty resource table" );
            }

            // =-=-=-=-=-=-=-
            // iterate through the map and search for our path
            lookup_table< resource_ptr >::iterator itr = resources_.begin();
            for ( ; itr != resources_.end(); ++itr ) {
                // =-=-=-=-=-=-=-
                // query resource for the property value
                value_type value = NULL;
                error ret = itr->second->get_property< value_type >( _prop, value );

                // =-=-=-=-=-=-=-
                // if we get a good parameter
                if ( ret.ok() ) {
                    // =-=-=-=-=-=-=-
                    // compare incoming value and stored value, assumes that the
                    // values support the comparison operator
                    if ( _value == value ) {
                        // =-=-=-=-=-=-=-
                        // if we get a match, cache the resource pointer
                        // in the given out variable and bail
                        found = true;
                        _resc = itr->second;
                        break;
                    }
                }
                else {
                    std::stringstream msg;
                    msg << "resource_manager::resolve_from_property - ";
                    msg << "failed to get vault parameter from resource";
                    irods::error err = PASSMSG( msg.str(), ret );

                }

            } // for itr

            // =-=-=-=-=-=-=-
            // did we find a resource and is the ptr valid?
            if ( true == found && _resc.get() ) {
                return SUCCESS();
            }
            else {
                std::stringstream msg;
                msg << "failed to find resource for property [";
                msg << _prop;
                msg << "] and value [";
                msg << _value;
                msg << "]";
                return ERROR( SYS_RESC_DOES_NOT_EXIST, msg.str() );
            }

        } // resolve_from_property
Пример #7
0
int
rsStructFileBundle( rsComm_t *rsComm,
                    structFileExtAndRegInp_t *structFileBundleInp ) {
    int status;
    rodsServerHost_t *rodsServerHost;
    int remoteFlag;
    dataObjInp_t dataObjInp;


    memset( &dataObjInp, 0, sizeof( dataObjInp ) );
    rstrcpy( dataObjInp.objPath, structFileBundleInp->objPath,
             MAX_NAME_LEN );

    remoteFlag = getAndConnRemoteZone( rsComm, &dataObjInp, &rodsServerHost,
                                       REMOTE_CREATE );

    if ( remoteFlag < 0 ) {
        return remoteFlag;
    }
    else if ( remoteFlag == REMOTE_HOST ) {
        status = rcStructFileBundle( rodsServerHost->conn,
                                     structFileBundleInp );
        return status;
    }

    // =-=-=-=-=-=-=-
    // working on the "home zone", determine if we need to redirect to a different
    // server in this zone for this operation.  if there is a RESC_HIER_STR_KW then
    // we know that the redirection decision has already been made
    std::string       hier;
    int               local = LOCAL_HOST;
    rodsServerHost_t* host  =  0;
    dataObjInp_t      data_inp;
    bzero( &data_inp, sizeof( data_inp ) );
    rstrcpy( data_inp.objPath, structFileBundleInp->objPath, MAX_NAME_LEN );
    copyKeyValPairStruct( &structFileBundleInp->condInput, &data_inp.condInput );
    if ( getValByKey( &structFileBundleInp->condInput, RESC_HIER_STR_KW ) == NULL ) {
        irods::error ret = irods::resource_redirect( irods::CREATE_OPERATION, rsComm,
                           &data_inp, hier, host, local );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << "rsStructFileBundle :: failed in irods::resource_redirect for [";
            msg << &data_inp.objPath << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
            return ret.code();
        }

        // =-=-=-=-=-=-=-
        // we resolved the redirect and have a host, set the hier str for subsequent
        // api calls, etc.
        addKeyVal( &structFileBundleInp->condInput, RESC_HIER_STR_KW, hier.c_str() );

    } // if keyword

    if ( LOCAL_HOST == local ) {
        status = _rsStructFileBundle( rsComm, structFileBundleInp );
    }
    else {
        status = rcStructFileBundle( host->conn, structFileBundleInp );
    } // else remote host


    return status;
}
Пример #8
0
    /// =-=-=-=-=-=-=-
    /// @brief find the next valid child resource for create operation
    irods::error get_next_valid_child_resource(
        irods::plugin_property_map& _prop_map,
        irods::resource_child_map&  _cmap,
        irods::resource_ptr&        _resc ) {
        // =-=-=-=-=-=-=-
        // counter and flag
        int child_ctr   = 0;
        bool   child_found = false;

        // =-=-=-=-=-=-=-
        // while we have not found a child and have not
        // exhausted all the children in the map
        while ( !child_found &&
                child_ctr < _cmap.size() ) {
            // =-=-=-=-=-=-=-
            // increment child counter
            child_ctr++;

            // =-=-=-=-=-=-=-
            // get the next_child property
            std::string next_child;
            irods::error err = _prop_map.get< std::string >( NEXT_CHILD_PROP, next_child );
            if ( !err.ok() ) {
                return PASSMSG( "round_robin_redirect - get property for 'next_child' failed.", err );

            }

            // =-=-=-=-=-=-=-
            // get the next_child resource
            if ( !_cmap.has_entry( next_child ) ) {
                std::stringstream msg;
                msg << "child map has no child by name [";
                msg << next_child << "]";
                return PASSMSG( msg.str(), err );

            }

            // =-=-=-=-=-=-=-
            // request our child resource to test it
            irods::resource_ptr resc = _cmap[ next_child ].second;

            // =-=-=-=-=-=-=-
            // get the resource's status
            int resc_status = 0;
            err = resc->get_property<int>( irods::RESOURCE_STATUS, resc_status );
            if ( !err.ok() ) {
                return PASSMSG( "failed to get property", err );

            }

            // =-=-=-=-=-=-=-
            // determine if the resource is up and available
            if ( INT_RESC_STATUS_DOWN != resc_status ) {
                // =-=-=-=-=-=-=-
                // we found a valid child, set out variable
                _resc = resc;
                child_found = true;

            }
            else {
                // =-=-=-=-=-=-=-
                // update the next_child as we do not have a valid child yet
                err = update_next_child_resource( _prop_map );
                if ( !err.ok() ) {
                    return PASSMSG( "update_next_child_resource failed", err );

                }

            }

        } // while

        // =-=-=-=-=-=-=-
        // return appropriately
        if ( child_found ) {
            return SUCCESS();

        }
        else {
            return ERROR( NO_NEXT_RESC_FOUND, "no valid child found" );

        }

    } // get_next_valid_child_resource
Пример #9
0
/// =-=-=-=-=-=-=-
/// @brief function which manages the TLS and Auth negotiations with the client
    error client_server_negotiation_for_client(
        irods::network_object_ptr _ptr,
        std::string&              _result ) {

        // =-=-=-=-=-=-=-
        // we requested a negotiation, wait for the response from CS_NEG_SVR_1_MSG
        boost::shared_ptr< cs_neg_t > cs_neg;
        error err = read_client_server_negotiation_message( _ptr, cs_neg );
        if ( !err.ok() ) {
            return PASS( err );
        }

        // =-=-=-=-=-=-=-
        // get the server requested policy
        std::string svr_policy( cs_neg->result_ );
        if ( svr_policy.empty() || cs_neg->status_ != CS_NEG_STATUS_SUCCESS ) {
            std::stringstream msg;
            msg << "invalid result [" << cs_neg->result_ << "]  or status: " << cs_neg->status_;
            return ERROR( -1, msg.str() );
        }

        // =-=-=-=-=-=-=-
        // get the irods environment so we can compare the
        // policy in the .irodsEnv file
        rodsEnv rods_env;
        int status = getRodsEnv( &rods_env );
        if ( status < 0 ) {
            return ERROR( status, "failed in getRodsEnv" );
        }

        // =-=-=-=-=-=-=-
        // if the policy is empty, then default to DONT_CARE
        std::string cli_policy( rods_env.rodsClientServerPolicy );
        if ( cli_policy.empty() ) {
            cli_policy = CS_NEG_DONT_CARE;

        }

        // =-=-=-=-=-=-=-
        // perform the negotiation
        client_server_negotiations_context negotiate;
        std::string result;
        error neg_err = negotiate( cli_policy, svr_policy, result );

        // =-=-=-=-=-=-=-
        // aggregate the error stack if necessary
        error ret = SUCCESS();
        if ( !neg_err.ok() ) {
            ret = PASSMSG( "failed in negotiation context", neg_err );
        }

        // =-=-=-=-=-=-=-
        // handle failure - send a failure msg back to client
        if ( !err.ok() || CS_NEG_FAILURE == result ) {
            // =-=-=-=-=-=-=-
            // send CS_NEG_CLI_1_MSG, failure message to the server
            cs_neg_t send_cs_neg;
            send_cs_neg.status_ = CS_NEG_STATUS_FAILURE;
            strncpy( send_cs_neg.result_, CS_NEG_FAILURE.c_str(), MAX_NAME_LEN );
            error send_err = send_client_server_negotiation_message(
                                 _ptr,
                                 send_cs_neg );
            if ( !send_err.ok() ) {
                ret = PASSMSG( "failed to send CS_NEG_CLI1_MSG Failure Messsage", send_err );
            }

            std::stringstream msg;
            msg << "client-server negoations failed for server request [";
            msg << svr_policy << "] and client request [" << cli_policy << "]";
            ret = PASSMSG( msg.str(), ret );
            return ret;
        }

        // =-=-=-=-=-=-=-
        // send CS_NEG_CLI_1_MSG, success message to the server with our choice
        cs_neg_t send_cs_neg;
        send_cs_neg.status_ = CS_NEG_STATUS_SUCCESS;
        strncpy( send_cs_neg.result_, result.c_str(), MAX_NAME_LEN );
        err = send_client_server_negotiation_message(
                  _ptr,
                  send_cs_neg );
        if ( !err.ok() ) {
            return PASSMSG( "failed to send CS_NEG_CLI_1_MSG Success Message", err );
        }

        // =-=-=-=-=-=-=-
        // set the out variable and return
        _result = result;

        return SUCCESS();

    } // client_server_negotiation_for_client
Пример #10
0
    /// =-=-=-=-=-=-=-
    /// @brief find the next valid child resource for create operation
    irods::error get_next_valid_child_resource(
        irods::resource_plugin_context& _ctx,
        const std::string*              _opr,
        const std::string*              _curr_host,
        irods::hierarchy_parser*        _out_parser,
        float*                          _out_vote ) {

        // =-=-=-=-=-=-=-
        // counter and flag
        int  child_ctr   = 0;
        bool child_found = false;

        // =-=-=-=-=-=-=-
        // while we have not found a child and have not
        // exhausted all the children in the map
        while ( !child_found &&
                child_ctr < _ctx.child_map().size() ) {
            // =-=-=-=-=-=-=-
            // increment child counter
            child_ctr++;

            // =-=-=-=-=-=-=-
            // get the next_child property
            std::string next_child;
            irods::error err = _ctx.prop_map().get< std::string >(
                                   NEXT_CHILD_PROP,
                                   next_child );
            if ( !err.ok() ) {
                return PASSMSG( "get property for 'next_child' failed.", err );

            }

            // =-=-=-=-=-=-=-
            // get the next_child resource
            if ( !_ctx.child_map().has_entry( next_child ) ) {
                std::stringstream msg;
                msg << "child map has no child by name [";
                msg << next_child << "]";
                return PASSMSG( msg.str(), err );

            }

            // =-=-=-=-=-=-=-
            // request our child resource to test it
            irods::resource_ptr resc = _ctx.child_map()[ next_child ].second;

            // =-=-=-=-=-=-=-
            // get the resource's status
            int resc_status = 0;
            err = resc->get_property<int>( irods::RESOURCE_STATUS, resc_status );
            if ( !err.ok() ) {
                return PASSMSG( "failed to get property", err );

            }

            // =-=-=-=-=-=-=-
            // forward the 'put' redirect to the appropriate child
            err = resc->call < const std::string*,
                const std::string*,
                irods::hierarchy_parser*,
                float* > (
                        _ctx.comm(),
                        irods::RESOURCE_OP_RESOLVE_RESC_HIER,
                        _ctx.fco(),
                        _opr,
                        _curr_host,
                        _out_parser,
                        _out_vote );
            if ( !err.ok() ) {
                rodsLog(
                        LOG_ERROR,
                        "forward of put redirect failed" );
                continue;

            }

            if( *_out_vote > 0 ) {
                // =-=-=-=-=-=-=-
                // we found a valid child, set out variable
                child_found = true;
            }
            else {
                // =-=-=-=-=-=-=-
                // update the next_child as we do not have a valid child yet
                err = update_next_child_resource( _ctx.prop_map() );
                if ( !err.ok() ) {
                    return PASSMSG( "update_next_child_resource failed", err );
                }
            }

        } // while

        // =-=-=-=-=-=-=-
        // return appropriately
        if ( child_found ) {
            return SUCCESS();
        }
        else {
            return ERROR(
                       NO_NEXT_RESC_FOUND,
                       "no valid child found" );
        }

    } // get_next_valid_child_resource
Пример #11
0
    /// =-=-=-=-=-=-=-
    /// @brief used to allow the resource to determine which host
    ///        should provide the requested operation
    irods::error round_robin_redirect(
        irods::resource_plugin_context& _ctx,
        const std::string*               _opr,
        const std::string*               _curr_host,
        irods::hierarchy_parser*        _out_parser,
        float*                           _out_vote ) {
        // =-=-=-=-=-=-=-
        // check incoming parameters
        irods::error err = round_robin_check_params< irods::file_object >( _ctx );
        if ( !err.ok() ) {
            return PASSMSG( "round_robin_redirect - bad resource context", err );
        }
        if ( !_opr ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null operation" );
        }
        if ( !_curr_host ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null host" );
        }
        if ( !_out_parser ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null outgoing hier parser" );
        }
        if ( !_out_vote ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "round_robin_redirect - null outgoing vote" );
        }

        // =-=-=-=-=-=-=-
        // get the object's hier string
        irods::file_object_ptr file_obj = boost::dynamic_pointer_cast< irods::file_object >( _ctx.fco() );
        std::string hier = file_obj->resc_hier( );

        // =-=-=-=-=-=-=-
        // get the object's hier string
        std::string name;
        err = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name );
        if ( !err.ok() ) {
            return PASSMSG( "failed to get property 'name'.", err );
        }

        // =-=-=-=-=-=-=-
        // add ourselves into the hierarch before calling child resources
        _out_parser->add_child( name );

        // =-=-=-=-=-=-=-
        // test the operation to determine which choices to make
        if ( irods::OPEN_OPERATION  == ( *_opr )  ||
             irods::WRITE_OPERATION == ( *_opr ) ) {
            // =-=-=-=-=-=-=-
            // get the next child pointer in the hierarchy, given our name and the hier string
            irods::resource_ptr resc;
            err = get_next_child_for_open_or_write( 
                      name, 
                      file_obj, 
                      _ctx.child_map(), 
                      resc );
            if ( !err.ok() ) {
                (*_out_vote) = 0.0;
                return PASS( err );
            }

            // =-=-=-=-=-=-=-
            // forward the redirect call to the child for assertion of the whole operation,
            // there may be more than a leaf beneath us
            return resc->call < const std::string*,
                   const std::string*,
                   irods::hierarchy_parser*,
                   float* > (
                       _ctx.comm(),
                       irods::RESOURCE_OP_RESOLVE_RESC_HIER,
                       _ctx.fco(),
                       _opr,
                       _curr_host,
                       _out_parser,
                       _out_vote );

            std::string hier;
            _out_parser->str( hier );
            rodsLog( 
                LOG_DEBUG,
                "open :: resc hier [%s] vote [%f]",
                hier.c_str(),
                _out_vote );

        }
        else if ( irods::CREATE_OPERATION == ( *_opr ) ) {
            // =-=-=-=-=-=-=-
            // get the next available child resource
            irods::resource_ptr resc;
            irods::error err = get_next_valid_child_resource(
                                   _ctx.prop_map(),
                                   _ctx.child_map(),
                                   resc );
            if ( !err.ok() ) {
                return PASS( err );

            }

            // =-=-=-=-=-=-=-
            // forward the 'put' redirect to the appropriate child
            err = resc->call < const std::string*,
            const std::string*,
            irods::hierarchy_parser*,
            float* > (
                _ctx.comm(),
                irods::RESOURCE_OP_RESOLVE_RESC_HIER,
                _ctx.fco(),
                _opr,
                _curr_host,
                _out_parser,
                _out_vote );
            if ( !err.ok() ) {
                return PASSMSG( "forward of put redirect failed", err );

            }

            std::string hier;
            _out_parser->str( hier );
            rodsLog( 
                LOG_DEBUG,
                "round robin - create :: resc hier [%s] vote [%f]",
                hier.c_str(),
                _out_vote );

            std::string new_hier;
            _out_parser->str( new_hier );

            // =-=-=-=-=-=-=-
            // update the next_child appropriately as the above succeeded
            err = update_next_child_resource( _ctx.prop_map() );
            if ( !err.ok() ) {
                return PASSMSG( "update_next_child_resource failed", err );

            }

            return SUCCESS();
        }

        // =-=-=-=-=-=-=-
        // must have been passed a bad operation
        std::stringstream msg;
        msg << "round_robin_redirect - operation not supported [";
        msg << ( *_opr ) << "]";
        return ERROR( -1, msg.str() );

    } // round_robin_redirect
Пример #12
0
    /// =-=-=-=-=-=-=-
    /// @brief interface to notify of a file modification
    irods::error round_robin_file_modified(
        irods::resource_plugin_context& _ctx ) {
        // =-=-=-=-=-=-=-
        // get the child resc to call
        irods::resource_ptr resc;
        irods::error err = round_robin_get_resc_for_call< irods::file_object >( _ctx, resc );
        if ( !err.ok() ) {
            return PASS( err );
        }

        // =-=-=-=-=-=-=-
        // call modified on the child
        err = resc->call( _ctx.comm(), irods::RESOURCE_OP_MODIFIED, _ctx.fco() );
        if ( !err.ok() ) {
            return PASS( err );
        }

        // =-=-=-=-=-=-=-
        // get the operation property, if it is a create op then we need
        // to update the next child in the context string
        std::string operation;
        err = _ctx.prop_map().get< std::string >(
                  OPERATION_PROP,
                  operation );
        if( err.ok() && irods::CREATE_OPERATION == operation ) {
            // =-=-=-=-=-=-=-
            // update the next_child appropriately as the above succeeded
            err = update_next_child_resource( _ctx.prop_map() );
            if ( !err.ok() ) {
                return PASSMSG( "update_next_child_resource failed", err );
            }

            // =-=-=-=-=-=-=-
            // if file modified is successful then we will update the next
            // child in the round robin within the database
            std::string name;
            _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, name );

            std::string next_child;
            _ctx.prop_map().get< std::string >( NEXT_CHILD_PROP, next_child );

            setRoundRobinContextInp_t inp;
            snprintf(
                inp.resc_name_,
                sizeof( inp.resc_name_ ),
                "%s", name.c_str() );
            snprintf(
                inp.context_,
                sizeof( inp.context_ ),
                "%s", next_child.c_str() );
            int status = irods::server_api_call(
                             SET_RR_CTX_AN,
                             _ctx.comm(),
                             &inp,
                             NULL,
                             ( void** ) NULL,
                             NULL );

            if ( status < 0 ) {
                std::stringstream msg;
                msg << "failed to update round robin context for [";
                msg << name << "] with context [" << next_child << "]";
                return ERROR(
                           status,
                           msg.str() );
            }

        } // if get prop

        return SUCCESS();

    } // round_robin_file_modified
Пример #13
0
// =-=-=-=-=-=-=-
// local implementation of put
int _rsFilePut(
    rsComm_t*         _comm,
    fileOpenInp_t*    _put_inp,
    bytesBuf_t*       _put_bbuf,
    rodsServerHost_t* _server_host,
    filePutOut_t**    _put_out ) {
    int fd = 0;

    // =-=-=-=-=-=-=-
    // NOTE:: this test does not seem to work for i86 solaris
    if ( ( _put_inp->otherFlags & FORCE_FLAG ) != 0 ) {
        // =-=-=-=-=-=-=-
        // create one if it does not exist */
        _put_inp->flags |= O_CREAT;
        fd = _rsFileOpen( _comm, _put_inp );

    }
    else {
        fileCreateOut_t* _out = 0;
        fd = _rsFileCreate( _comm, _put_inp, _server_host, &_out );

    } // else

    // =-=-=-=-=-=-=-
    // log, error if any
    if ( fd < 0 ) {
        if ( getErrno( fd ) == EEXIST ) {
            rodsLog( LOG_DEBUG1,
                     "_rsFilePut: filePut for %s, status = %d",
                     _put_inp->fileName, fd );
        }
        else if ( fd != DIRECT_ARCHIVE_ACCESS ) {
            rodsLog( LOG_DEBUG,
                     "_rsFilePut: filePut for %s, status = %d",
                     _put_inp->fileName, fd );
        }
        return ( fd );
    }

    // =-=-=-=-=-=-=-
    // call write for resource plugin
    irods::file_object_ptr file_obj(
        new irods::file_object(
            _comm,
            _put_inp->objPath,
            _put_inp->fileName,
            _put_inp->resc_hier_,
            fd, 0, 0 ) );
    file_obj->in_pdmo( _put_inp->in_pdmo );
    file_obj->cond_input( _put_inp->condInput );

    irods::error write_err = fileWrite( _comm,
                                        file_obj,
                                        _put_bbuf->buf,
                                        _put_bbuf->len );
    int write_code = write_err.code();
    // =-=-=-=-=-=-=-
    // log errors, if any
    if ( write_code != _put_bbuf->len ) {
        if ( write_code >= 0 ) {
            std::stringstream msg;
            msg << "fileWrite failed for [";
            msg << _put_inp->fileName;
            msg << "] towrite [";
            msg << _put_bbuf->len;
            msg << "] written [";
            msg << write_code << "]";
            irods::error err = PASSMSG( msg.str(), write_err );
            irods::log( err );
            write_code = SYS_COPY_LEN_ERR;
        }
        else {
            std::stringstream msg;
            msg << "fileWrite failed for [";
            msg << _put_inp->fileName;
            msg << "]";
            irods::error err = PASSMSG( msg.str(), write_err );
            irods::log( err );
        }
    }

    // =-=-=-=-=-=-=-
    // close up after ourselves
    irods::error close_err = fileClose( _comm,
                                        file_obj );
    if ( !close_err.ok() ) {
        irods::error err = PASSMSG( "error on close", close_err );
        irods::log( err );
    }

    // =-=-=-=-=-=-=-
    // percolate possible change in phy path up
    ( *_put_out ) = ( filePutOut_t* ) malloc( sizeof( filePutOut_t ) );
    strncpy(
        ( *_put_out )->file_name,
        file_obj->physical_path().c_str(),
        MAX_NAME_LEN );

    // =-=-=-=-=-=-=-
    // return 'write_err code' as this includes this implementation
    // assumes we are returning the size of the file 'put' via fileWrite
    return write_code;

} // _rsFilePut
Пример #14
0
int _rsFileGet(
    rsComm_t*      _comm,
    fileOpenInp_t* _get_inp,
    bytesBuf_t*    _get_buf ) {

    int fd;
    int len;

    len = _get_inp->dataSize;
    fd  = _rsFileOpen( _comm, _get_inp );

    if ( fd < 0 ) {
        rodsLog( LOG_NOTICE,
                 "_rsFileGet: fileGet for %s, status = %d",
                 _get_inp->fileName, fd );
        return fd;
    }

    if ( _get_buf->buf == NULL ) {
        _get_buf->buf = malloc( len );
    }

    irods::file_object_ptr file_obj(
        new irods::file_object(
            _comm,
            _get_inp->objPath,
            _get_inp->fileName,
            _get_inp->resc_hier_,
            fd,
            _get_inp->mode,
            _get_inp->flags ) );

    // =-=-=-=-=-=-=-
    // pass condInput
    file_obj->cond_input( _get_inp->condInput );

    irods::error read_err = fileRead( _comm,
                                      file_obj,
                                      _get_buf->buf,
                                      len );
    int bytes_read = read_err.code();
    if ( bytes_read != len ) {
        if ( bytes_read >= 0 ) {

            _get_buf->len = bytes_read;

        }
        else {
            std::stringstream msg;
            msg << "fileRead failed for [";
            msg << _get_inp->fileName;
            msg << "]";
            irods::error ret_err = PASSMSG( msg.str(), read_err );
            irods::log( ret_err );
        }
    }
    else {
        _get_buf->len = bytes_read;
    }

    // =-=-=-=-=-=-=-
    // call resource plugin close
    irods::error close_err = fileClose( _comm,
                                        file_obj );
    if ( !close_err.ok() ) {
        irods::error err = PASSMSG( "error on close", close_err );
        irods::log( err );
    }

    return bytes_read;

} // _rsFileGet
Пример #15
0
// =-=-=-=-=-=-=-
// given a list of resource names from a rule, make some decisions
// about which resource should be set to default and used.  store
// that information in the rescGrpInfo structure
// NOTE :: this is a reimplementation of setDefaultResc in resource.c but
//      :: with the composite resource spin
    error set_default_resource( rsComm_t*          _comm,
                                const std::string& _resc_list,
                                const std::string& _option,
                                keyValPair_t*      _cond_input,
                                std::string&       _resc_name ) {
        // =-=-=-=-=-=-=
        // quick error check
        if ( _resc_list.empty() && NULL == _cond_input ) {
            return ERROR( USER_NO_RESC_INPUT_ERR, "no user input" );
        }

        // =-=-=-=-=-=-=-
        // resource name passed in via conditional input
        std::string cond_input_resc;

        // =-=-=-=-=-=-=-
        // if the resource list is not "null" and the forced flag is set
        // then zero out the conditional input as it is to be ignored
        if ( "null"   != _resc_list &&
                "forced" == _option    &&
                _comm->proxyUser.authInfo.authFlag < LOCAL_PRIV_USER_AUTH ) {
            _cond_input = NULL;
        }
        else if ( _cond_input ) {
            char* name = NULL;
            if ( ( name = getValByKey( _cond_input, BACKUP_RESC_NAME_KW ) ) == NULL &&
                    ( name = getValByKey( _cond_input, DEST_RESC_NAME_KW ) ) == NULL &&
                    ( name = getValByKey( _cond_input, DEF_RESC_NAME_KW ) ) == NULL &&
                    ( name = getValByKey( _cond_input, RESC_NAME_KW ) ) == NULL ) {
                // =-=-=-=-=-=-=-
                // no conditional input resource
            }
            else {
                cond_input_resc = name;
                boost::trim(cond_input_resc);
            }

        } // else if

        // =-=-=-=-=-=-=-
        // split the list into a vector of strings using a % delimiter
        std::vector< std::string > resources;
        string_tokenize( _resc_list, "%", resources );

        // =-=-=-=-=-=-=-
        // pick a good resource which is available out of the list,
        // NOTE :: the legacy code picks a random one first then scans
        //      :: for a valid one if the random resource is down.  i just
        //      :: scan for one.  i don't think this would break anything...
        std::string default_resc_name;

        std::vector< std::string >::iterator itr = resources.begin();
        for ( ; itr != resources.end(); ++itr ) {
            error resc_err = is_hier_live( *itr );
            if ( resc_err.ok() ) {
                // live resource found
                default_resc_name = *itr;
            }
            else {
                irods::log( resc_err );
            }

        } // for itr

        // =-=-=-=-=-=-=-
        // determine that we might need a 'preferred' resource
        if ( "preferred" == _option && !cond_input_resc.empty() ) {
            // =-=-=-=-=-=-=-
            // determine if the resource is live
            error resc_err = is_hier_live( cond_input_resc );
            if ( resc_err.ok() ) {
                // =-=-=-=-=-=-=-
                // we found a live one, we're good to go
                _resc_name = cond_input_resc;
                return SUCCESS();
            }

        }
        else if ( "forced" == _option && _comm->clientUser.authInfo.authFlag < LOCAL_PRIV_USER_AUTH ) {
            // stick with the default found above, its forced.
            _resc_name = default_resc_name;
            return SUCCESS();

        }
        else {
            // =-=-=-=-=-=-=-
            // try the conditional input string, if not go back to the default resource
            error resc_err = is_hier_live( cond_input_resc );
            if ( resc_err.ok() ) {
                // =-=-=-=-=-=-=-
                // we found a live one, go!
                _resc_name = cond_input_resc;
                return SUCCESS();

            }
            else {
                // =-=-=-=-=-=-=-
                // otherwise go back to the old, default we had before
                error resc_err = is_hier_live( default_resc_name );
                if ( resc_err.ok() ) {
                    _resc_name = default_resc_name;
                    return SUCCESS();

                }
                else {
                    std::stringstream msg;
                    msg << "set_default_resource - failed to find default resource for list [";
                    msg << _resc_list;
                    msg << "] and option [";
                    msg << _option;
                    msg << "]";
                    return PASSMSG( msg.str(), resc_err );
                }

            } // else

        } // else


        // =-=-=-=-=-=-=-
        // should not reach here
        std::stringstream msg;
        msg << "should not reach here for list [";
        msg << _resc_list;
        msg << "] and option [";
        msg << _option;
        msg << "]";
        return ERROR( CAT_NO_ROWS_FOUND, msg.str() );

    } // set_default_resource
Пример #16
0
/// =-=-=-=-=-=-=-
/// @brief function which sends the negotiation message
    error read_client_server_negotiation_message(
        irods::network_object_ptr      _ptr,
        boost::shared_ptr< cs_neg_t >&  _cs_neg_msg ) {
        // =-=-=-=-=-=-=-
        // read the message header
        struct timeval tv;
        tv.tv_sec = READ_VERSION_TOUT_SEC;
        tv.tv_usec = 0;

        msgHeader_t msg_header;
        irods::error ret = readMsgHeader( _ptr, &msg_header, &tv );
        if ( !ret.ok() ) {
            return PASSMSG( "read message header failed", ret );
        }

        // =-=-=-=-=-=-=-
        // read the message body
        bytesBuf_t struct_buf, data_buf, error_buf;
        memset( &data_buf, 0, sizeof( bytesBuf_t ) );
        ret = readMsgBody(
                  _ptr,
                  &msg_header,
                  &struct_buf,
                  &data_buf,
                  &error_buf,
                  XML_PROT, 0 );
        if ( !ret.ok() ) {
            return PASS( ret );

        }

        // =-=-=-=-=-=-=-
        // check that we did in fact get the right type of message
        if ( strcmp( msg_header.type, RODS_CS_NEG_T ) != 0 ) {
            // =-=-=-=-=-=-=-
            // trap potential case where server does not support
            // advanced negotiation.  a version msg would be sent
            // back instead.
            if ( strcmp( msg_header.type, RODS_VERSION_T ) == 0 ) {
                // =-=-=-=-=-=-=-
                // unpack the version struct to check the status
                version_t* version = 0;
                int status = unpackStruct(
                                 struct_buf.buf,
                                 ( void ** )( static_cast<void *>( &version ) ),
                                 "Version_PI",
                                 RodsPackTable,
                                 XML_PROT );

                if ( struct_buf.buf ) {
                    free( struct_buf.buf );
                }
                if ( data_buf.buf ) {
                    free( data_buf.buf );
                }
                if ( error_buf.buf ) {
                    free( error_buf.buf );
                }

                if ( status < 0 ) {
                    rodsLog( LOG_ERROR, "read_client_server_negotiation_message :: unpackStruct FAILED" );
                    return ERROR( status, "unpackStruct failed" );

                }

                if ( version->status < 0 ) {
                    rodsLog( LOG_ERROR, "read_client_server_negotiation_message :: received error message %d", version->status );
                    return ERROR( version->status, "negotiation failed" );

                }
                else {
                    // =-=-=-=-=-=-=-
                    // if no negoation is allowed then provide a readable
                    // error for the client
                    std::stringstream msg;
                    msg << "received [" << msg_header.type << "] ";
                    msg << "but expected [" << RODS_CS_NEG_T << "]\n\n";
                    msg << "\t*** Advanced negotiation is enabled in this iRODS environment   ***\n";
                    msg << "\t*** which is most likely not supported by the server.           ***\n";
                    msg << "\t*** Comment out irodsClientServerNegotiation in the irodsEnv    ***\n";
                    msg << "\t*** file to disable.                                            ***\n";
                    return ERROR( ADVANCED_NEGOTIATION_NOT_SUPPORTED, msg.str() );
                }

            }
            else {
                // =-=-=-=-=-=-=-
                // something entirely unexpected happened
                std::stringstream msg;
                msg << "wrong message type [" << msg_header.type << "] ";
                msg << "expected [" << RODS_CS_NEG_T << "]";
                return ERROR( SYS_HEADER_TYPE_LEN_ERR, msg.str() );
            }
        }

        // =-=-=-=-=-=-=-
        // check that we did not get any data with the message
        if ( msg_header.bsLen != 0 ) {
            if ( data_buf.buf != NULL ) {
                free( data_buf.buf );
            }
            rodsLog( LOG_NOTICE,
                     "read_client_server_negotiation_message: msg_header.bsLen = %d is not 0",
                     msg_header.bsLen );
        }

        // =-=-=-=-=-=-=-
        // check that we did not get anything in the error buffer
        if ( msg_header.errorLen != 0 ) {
            if ( error_buf.buf ) {
                free( error_buf.buf );
            }
            rodsLog( LOG_NOTICE,
                     "read_client_server_negotiation_message: msg_header.errorLen = %d is not 0",
                     msg_header.errorLen );
        }

        // =-=-=-=-=-=-=-
        // check that we did get an appropriately sized message
        if ( msg_header.msgLen > ( int ) sizeof( irods::cs_neg_t ) * 2 ||
                msg_header.msgLen <= 0 ) {
            if ( struct_buf.buf != NULL ) {
                free( struct_buf.buf );
            }
            std::stringstream msg;
            msg << "message length is invalid: " << msg_header.msgLen << " vs " << sizeof( irods::cs_neg_t );
            return ERROR( SYS_HEADER_READ_LEN_ERR, msg.str() );
        }

        // =-=-=-=-=-=-=-
        // do an unpack into our out variable using the xml protocol
        cs_neg_t* tmp_cs_neg = 0;
        int status = unpackStruct( struct_buf.buf,
                                   ( void ** )( static_cast<void *>( &tmp_cs_neg ) ),
                                   "CS_NEG_PI",
                                   RodsPackTable,
                                   XML_PROT );
        free( struct_buf.buf );
        if ( status < 0 ) {
            rodsLog( LOG_ERROR, "read_client_server_negotiation_message :: unpackStruct FAILED" );
            return ERROR( status, "unpackStruct failed" );

        }

        _cs_neg_msg.reset( tmp_cs_neg, free );

        // =-=-=-=-=-=-=-
        // win!!!111one
        return SUCCESS();

    } // read_client_server_negotiation_message
Пример #17
0
int
main( int argc, char **argv ) {
    int c;
    int runMode = SERVER;
    int flagval = 0;
    char *logDir = NULL;
    char *tmpStr;
    int logFd;

    ProcessType = XMSG_SERVER_PT;

    // capture server properties
    irods::error result = irods::server_properties::getInstance().capture();
    if ( !result.ok() ) {
        irods::log( PASSMSG( "failed to read server configuration", result ) );
    }

#ifndef _WIN32
    signal( SIGINT, signalExit );
    signal( SIGHUP, signalExit );
    signal( SIGTERM, signalExit );
    signal( SIGUSR1, signalExit );
    signal( SIGPIPE, rsPipeSignalHandler );
#endif

    /* Handle option to log sql commands */
    tmpStr = getenv( SP_LOG_SQL );
    if ( tmpStr != NULL ) {
        rodsLogSqlReq( 1 );
    }

    /* Set the logging level */
    tmpStr = getenv( SP_LOG_LEVEL );
    if ( tmpStr != NULL ) {
        int i;
        i = atoi( tmpStr );
        rodsLogLevel( i );
    }
    else {
        rodsLogLevel( LOG_NOTICE ); /* default */
    }

    while ( ( c = getopt( argc, argv, "sSc:vD:" ) ) != EOF ) {
        switch ( c ) {
        case 's':
            runMode = SINGLE_PASS;
            break;
        case 'S':
            runMode = STANDALONE_SERVER;
            break;
        case 'v':   /* verbose */
            flagval |= v_FLAG;
            break;
        case 'c':
            loopCnt = atoi( optarg );
            break;
        case 'D':   /* user specified a log directory */
            logDir = strdup( optarg );
            break;
        default:
            usage( argv[0] );
            exit( 1 );
        }
    }

    if ( ( logFd = logFileOpen( runMode, logDir, XMSG_SVR_LOGFILE ) ) < 0 ) {
        exit( 1 );
    }

    irods::error ret = setRECacheSaltFromEnv();
    if ( !ret.ok() ) {
        rodsLog( LOG_ERROR, "irodsXmsgServer::main: Failed to set RE cache mutex name\n%s", ret.result().c_str() );
        exit( 1 );
    }

    daemonize( runMode, logFd );

    xmsgServerMain();
    sleep( 5 );
    exit( 0 );
}
Пример #18
0
int fileChksum(
    rsComm_t* rsComm,
    char*     objPath,
    char*     fileName,
    char*     rescHier,
    char*     orig_chksum,
    char*     chksumStr ) {
    // =-=-=-=-=-=-=-
    // capture server hashing settings
    std::string svr_hash_scheme;
    irods::error ret = irods::get_server_property< std::string >(
                           DEFAULT_HASH_SCHEME_KW,
                           svr_hash_scheme );
    std::string hash_scheme( irods::MD5_NAME );
    if ( ret.ok() ) {
        hash_scheme = svr_hash_scheme;
    }

    // make sure the read parameter is lowercased
    std::transform(
        hash_scheme.begin(),
        hash_scheme.end(),
        hash_scheme.begin(),
        ::tolower );

    std::string svr_hash_policy;
    ret = irods::get_server_property< std::string >(
              MATCH_HASH_POLICY_KW,
              svr_hash_policy );
    std::string hash_policy;
    if ( ret.ok() ) {
        hash_policy = svr_hash_policy;
    }

    // =-=-=-=-=-=-=-
    // extract scheme from checksum string
    std::string chkstr_scheme;
    if ( orig_chksum ) {
        ret = irods::get_hash_scheme_from_checksum(
                  orig_chksum,
                  chkstr_scheme );
        if ( !ret.ok() ) {
            //irods::log( PASS( ret ) );
        }
    }

    // =-=-=-=-=-=-=-
    // check the hash scheme against the policy
    // if necessary
    std::string final_scheme( hash_scheme );
    if ( !chkstr_scheme.empty() ) {
        if ( !hash_policy.empty() ) {
            if ( irods::STRICT_HASH_POLICY == hash_policy ) {
                if ( hash_scheme != chkstr_scheme ) {
                    return USER_HASH_TYPE_MISMATCH;
                }
            }
        }
        final_scheme = chkstr_scheme;
    }

    rodsLog(
        LOG_DEBUG,
        "fileChksum :: final_scheme [%s]  chkstr_scheme [%s]  svr_hash_policy [%s]  hash_policy [%s]",
        final_scheme.c_str(),
        chkstr_scheme.c_str(),
        svr_hash_policy.c_str(),
        hash_policy.c_str() );

    // =-=-=-=-=-=-=-
    // call resource plugin to open file
    irods::file_object_ptr file_obj(
        new irods::file_object(
            rsComm,
            objPath,
            fileName,
            rescHier,
            -1, 0, O_RDONLY ) ); // FIXME :: hack until this is better abstracted - JMC
    ret = fileOpen( rsComm, file_obj );
    if ( !ret.ok() ) {
        int status = UNIX_FILE_OPEN_ERR - errno;
        if ( ret.code() != DIRECT_ARCHIVE_ACCESS ) {
            std::stringstream msg;
            msg << "fileOpen failed for [";
            msg << fileName;
            msg << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
        }
        else {
            status = ret.code();
        }
        return status;
    }

    // =-=-=-=-=-=-=-
    // create a hasher object and init given a scheme
    // if it is unsupported then default to md5
    irods::Hasher hasher;
    ret = irods::getHasher( final_scheme, hasher );
    if ( !ret.ok() ) {
        irods::log( PASS( ret ) );
        irods::getHasher( irods::MD5_NAME, hasher );
    }

    // =-=-=-=-=-=-=-
    // do an inital read of the file
    char buffer[SVR_MD5_BUF_SZ];
    irods::error read_err = fileRead(
                                rsComm,
                                file_obj,
                                buffer,
                                SVR_MD5_BUF_SZ );
    if (!read_err.ok()) {
        std::stringstream msg;
        msg << __FUNCTION__;
        msg << " - Failed to read buffer from file: \"";
        msg << fileName;
        msg << "\"";
        irods::error result = PASSMSG( msg.str(), read_err );
        irods::log( result );
        return result.code();
    }
    int bytes_read = read_err.code();

    // =-=-=-=-=-=-=-
    // loop and update while there are still bytes to be read
    while ( read_err.ok() && bytes_read > 0 ) {
        // =-=-=-=-=-=-=-
        // update hasher
        hasher.update( std::string( buffer, bytes_read ) );

        // =-=-=-=-=-=-=-
        // read some more
        read_err = fileRead( rsComm, file_obj, buffer, SVR_MD5_BUF_SZ );
        if ( read_err.ok() ) {
            bytes_read = read_err.code();
        }
        else {
            std::stringstream msg;
            msg << __FUNCTION__;
            msg << " - Failed to read buffer from file: \"";
            msg << fileName;
            msg << "\"";
            irods::error result = PASSMSG( msg.str(), read_err );
            irods::log( result );
            return result.code();
        }

    } // while

    // =-=-=-=-=-=-=-
    // close out the file
    ret = fileClose( rsComm, file_obj );
    if ( !ret.ok() ) {
        irods::error err = PASSMSG( "error on close", ret );
        irods::log( err );
    }

    // =-=-=-=-=-=-=-
    // extract the digest from the hasher object
    // and copy to outgoing string
    std::string digest;
    hasher.digest( digest );
    strncpy( chksumStr, digest.c_str(), NAME_LEN );

    return 0;

}
Пример #19
0
int
getNumThreads( rsComm_t *rsComm, rodsLong_t dataSize, int inpNumThr,
               keyValPair_t *condInput, char *destRescHier, char *srcRescHier, int oprType ) {
    ruleExecInfo_t rei;
    dataObjInp_t doinp;
    int status;
    int numDestThr = -1;
    int numSrcThr = -1;


    if ( inpNumThr == NO_THREADING ) {
        return 0;
    }

    if ( dataSize < 0 ) {
        return 0;
    }

    if ( dataSize <= MIN_SZ_FOR_PARA_TRAN ) {
        if ( inpNumThr > 0 ) {
            inpNumThr = 1;
        }
        else {
            return 0;
        }
    }

    if ( getValByKey( condInput, NO_PARA_OP_KW ) != NULL ) {
        /* client specify no para opr */
        return 1;
    }

    memset( &doinp, 0, sizeof( doinp ) );
    doinp.numThreads = inpNumThr;

    doinp.dataSize = dataSize;
    doinp.oprType = oprType;

    initReiWithDataObjInp( &rei, rsComm, &doinp );

    if (destRescHier && strlen(destRescHier)) {

        // get resource (hierarchy) location
        std::string location;
        irods::error ret = irods::get_loc_for_hier_string( destRescHier, location );
        if ( !ret.ok() ) {
            irods::log( PASSMSG( "getNumThreads - failed in get_loc_for_hier_string", ret ) );
            return -1;
        }

        irods::hierarchy_parser parser;
        parser.set_string( destRescHier );

        std::string last_resc;
        parser.last_resc( last_resc );

        irods::error err = irods::is_resc_live( last_resc.c_str() );
        if ( err.ok() ) {
            status = applyRule( "acSetNumThreads", NULL, &rei, NO_SAVE_REI );

            if ( status < 0 ) {
                rodsLog( LOG_ERROR,
                         "getNumThreads: acGetNumThreads error, status = %d",
                         status );
            }
            else {
                numDestThr = rei.status;
                if ( numDestThr == 0 ) {
                    return 0;
                }
                else if ( numDestThr == 1 && srcRescHier == NULL &&
                          isLocalHost( location.c_str() ) ) {
                    /* one thread and resource on local host */
                    return 0;
                }
            }
        }
    }

    if (destRescHier && strlen(destRescHier) && srcRescHier && strlen(srcRescHier)) {
        if ( numDestThr > 0 && strcmp( destRescHier, srcRescHier ) == 0 ) {
            return numDestThr;
        }

        // get resource (hierarchy) location
        std::string location;
        irods::error ret = irods::get_loc_for_hier_string( destRescHier, location );
        if ( !ret.ok() ) {
            irods::log( PASSMSG( "getNumThreads - failed in get_loc_for_hier_string", ret ) );
            return -1;
        }

        irods::hierarchy_parser parser;
        parser.set_string( srcRescHier );

        std::string last_resc;
        parser.last_resc( last_resc );

        irods::error err = irods::is_resc_live( last_resc.c_str() );

        if ( err.ok() ) {
            status = applyRule( "acSetNumThreads", NULL, &rei, NO_SAVE_REI );
            if ( status < 0 ) {
                rodsLog( LOG_ERROR,
                         "getNumThreads: acGetNumThreads error, status = %d",
                         status );
            }
            else {
                numSrcThr = rei.status;
                if ( numSrcThr == 0 ) {
                    return 0;
                }
            }
        }
    }

    if ( numDestThr > 0 ) {
        if ( getValByKey( condInput, RBUDP_TRANSFER_KW ) != NULL ) {
            return 1;
        }
        else {
            return numDestThr;
        }
    }
    if ( numSrcThr > 0 ) {
        if ( getValByKey( condInput, RBUDP_TRANSFER_KW ) != NULL ) {
            return 1;
        }
        else {
            return numSrcThr;
        }
    }
    /* should not be here. do one with no resource */
    status = applyRule( "acSetNumThreads", NULL, &rei, NO_SAVE_REI );
    if ( status < 0 ) {
        rodsLog( LOG_ERROR,
                 "getNumThreads: acGetNumThreads error, status = %d",
                 status );
        return 0;
    }
    else {
        if ( rei.status > 0 ) {
            return rei.status;
        }
        else {
            return 0;
        }
    }
}
Пример #20
0
int _call_file_modified_for_modification(
    rsComm_t*         rsComm,
    modDataObjMeta_t* modDataObjMetaInp ) {
    int status = 0;
    dataObjInfo_t *dataObjInfo;
    keyValPair_t *regParam;
    ruleExecInfo_t rei2;

    memset( ( char* )&rei2, 0, sizeof( ruleExecInfo_t ) );
    rei2.rsComm = rsComm;
    rei2.uoic = &rsComm->clientUser;
    rei2.uoip = &rsComm->proxyUser;
    rei2.doi = modDataObjMetaInp->dataObjInfo;
    rei2.condInputData = modDataObjMetaInp->regParam;
    regParam = modDataObjMetaInp->regParam;
    dataObjInfo = modDataObjMetaInp->dataObjInfo;

    if ( regParam->len == 0 ) {
        return 0;
    }

    if ( getValByKey( regParam, ALL_KW ) != NULL ) {
        /* all copies */
        dataObjInfo_t *dataObjInfoHead = NULL;
        dataObjInfo_t *tmpDataObjInfo;
        dataObjInp_t dataObjInp;

        bzero( &dataObjInp, sizeof( dataObjInp ) );
        rstrcpy( dataObjInp.objPath, dataObjInfo->objPath, MAX_NAME_LEN );
        status = getDataObjInfoIncSpecColl( rsComm, &dataObjInp, &dataObjInfoHead );

        if ( status < 0 )  {
            rodsLog( LOG_NOTICE, "%s - Failed to get data objects.", __FUNCTION__ );
            return status;
        }
        tmpDataObjInfo = dataObjInfoHead;
        while ( tmpDataObjInfo != NULL ) {
            if ( tmpDataObjInfo->specColl != NULL ) {
                break;
            }

            irods::file_object_ptr file_obj(
                new irods::file_object(
                    rsComm,
                    tmpDataObjInfo ) );

            char* admin_kw = getValByKey( regParam, ADMIN_KW );
            if ( admin_kw != NULL ) {
                addKeyVal( (keyValPair_t*)&file_obj->cond_input(), ADMIN_KW, "" );
            }

            char* pdmo_kw = getValByKey( regParam, IN_PDMO_KW );
            if ( pdmo_kw != NULL ) {
                file_obj->in_pdmo( pdmo_kw );

            }

            irods::error ret = fileModified( rsComm, file_obj );
            if ( !ret.ok() ) {
                std::stringstream msg;
                msg << __FUNCTION__;
                msg << " - Failed to signal resource that the data object \"";
                msg << tmpDataObjInfo->objPath;
                msg << " was modified.";
                ret = PASSMSG( msg.str(), ret );
                irods::log( ret );
                status = ret.code();
            }

            tmpDataObjInfo = tmpDataObjInfo->next;
        }
        freeAllDataObjInfo( dataObjInfoHead );
    }
    else {
        irods::file_object_ptr file_obj(
            new irods::file_object(
                rsComm,
                dataObjInfo ) );

        char* admin_kw = getValByKey( regParam, ADMIN_KW );
        if ( admin_kw != NULL ) {
            addKeyVal( (keyValPair_t*)&file_obj->cond_input(), ADMIN_KW, "" );
        }

        char* pdmo_kw = getValByKey( regParam, IN_PDMO_KW );
        if ( pdmo_kw != NULL ) {
            file_obj->in_pdmo( pdmo_kw );
        }
        irods::error ret = fileModified( rsComm, file_obj );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << __FUNCTION__;
            msg << " - Failed to signal the resource that the data object \"";
            msg << dataObjInfo->objPath;
            msg << "\" was modified.";
            ret = PASSMSG( msg.str(), ret );
            irods::log( ret );
            status = ret.code();
        }

    }

    return status;

}
Пример #21
0
    // =-=-=-=-=-=-=-
    // unixRedirectPlugin - used to allow the resource to determine which host
    //                      should provide the requested operation
    irods::error passthru_redirect_plugin(
        irods::resource_plugin_context& _ctx,
        const std::string*                  _opr,
        const std::string*                  _curr_host,
        irods::hierarchy_parser*           _out_parser,
        float*                              _out_vote ) {
        // =-=-=-=-=-=-=-
        // check incoming parameters
        irods::error result = SUCCESS();
        irods::error ret = passthru_check_params( _ctx );
        if ( !ret.ok() ) {
            result = PASSMSG( "passthru_redirect_plugin - invalid resource context.", ret );
        }
        if ( !_opr ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "passthru_redirect_plugin - null operation" );
        }
        if ( !_curr_host ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "passthru_redirect_plugin - null operation" );
        }
        if ( !_out_parser ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "passthru_redirect_plugin - null outgoing hier parser" );
        }
        if ( !_out_vote ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "passthru_redirect_plugin - null outgoing vote" );
        }

        // =-=-=-=-=-=-=-
        // get the name of this resource
        std::string resc_name;
        ret = _ctx.prop_map().get< std::string >( irods::RESOURCE_NAME, resc_name );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << "passthru_redirect_plugin - failed in get property for name";
            return ERROR( -1, msg.str() );
        }

        // =-=-=-=-=-=-=-
        // add ourselves to the hierarchy parser by default
        _out_parser->add_child( resc_name );

        irods::resource_ptr resc;
        ret = passthru_get_first_child_resc( _ctx.child_map(), resc );
        if ( !ret.ok() ) {
            return PASSMSG( "passthru_redirect_plugin - failed getting the first child resource pointer.", ret );
        }

        irods::error final_ret = resc->call <
                                 const std::string*,
                                 const std::string*,
                                 irods::hierarchy_parser*,
                                 float* > (
                                     _ctx.comm(),
                                     irods::RESOURCE_OP_RESOLVE_RESC_HIER,
                                     _ctx.fco(),
                                     _opr,
                                     _curr_host,
                                     _out_parser,
                                     _out_vote );
        double orig_vote = *_out_vote;
        if ( irods::OPEN_OPERATION == ( *_opr ) &&
                _ctx.prop_map().has_entry( READ_WEIGHT_KW ) ) {
            double read_weight = 1.0;
            ret = _ctx.prop_map().get<double>(
                      READ_WEIGHT_KW,
                      read_weight );
            if ( !ret.ok() ) {
                irods::log( PASS( ret ) );

            }
            else {
                ( *_out_vote ) *= read_weight;

            }

        }
        else if ( ( irods::CREATE_OPERATION == ( *_opr ) ||
                    irods::WRITE_OPERATION == ( *_opr ) ) &&
                  _ctx.prop_map().has_entry( WRITE_WEIGHT_KW ) ) {
            double write_weight = 1.0;
            ret = _ctx.prop_map().get<double>(
                      WRITE_WEIGHT_KW,
                      write_weight );
            if ( !ret.ok() ) {
                irods::log( PASS( ret ) );

            }
            else {
                ( *_out_vote ) *= write_weight;

            }
        }

        rodsLog(
            LOG_DEBUG,
            "passthru_redirect_plugin - [%s] : %f - %f",
            _opr->c_str(),
            orig_vote,
            *_out_vote );

        return final_ret;

    } // passthru_redirect_plugin
Пример #22
0
int
rsDataObjPhymv( rsComm_t *rsComm, dataObjInp_t *dataObjInp,
                transferStat_t **transStat ) {
    int status = 0;
    dataObjInfo_t *dataObjInfoHead = NULL;
    dataObjInfo_t *oldDataObjInfoHead = NULL;
    ruleExecInfo_t rei;
    int multiCopyFlag = 0;
    char *accessPerm = NULL;
    int remoteFlag = 0;
    rodsServerHost_t *rodsServerHost = NULL;
    specCollCache_t *specCollCache = NULL;
    std::string resc_name;

    resolveLinkedPath( rsComm, dataObjInp->objPath, &specCollCache,
                       &dataObjInp->condInput );
    remoteFlag = getAndConnRemoteZone( rsComm, dataObjInp, &rodsServerHost,
                                       REMOTE_OPEN );

    if ( remoteFlag < 0 ) {
        return remoteFlag;
    }
    else if ( remoteFlag == REMOTE_HOST ) {
        status = _rcDataObjPhymv( rodsServerHost->conn, dataObjInp,
                                  transStat );
        return status;
    }

    char* dest_resc = getValByKey( &dataObjInp->condInput, DEST_RESC_NAME_KW );
    if ( dest_resc ) {
        std::string dest_hier; 
        irods::error ret = resolve_hierarchy_for_resc_from_cond_input(
                               rsComm,
                               dest_resc,
                               dest_hier );
        if( !ret.ok() ) {
            irods::log( PASS( ret ) );
            return ret.code();
        }
        addKeyVal(
            &dataObjInp->condInput,
            DEST_RESC_HIER_STR_KW,
            dest_hier.c_str() );
    }

    // =-=-=-=-=-=-=-
    // determine hierarchy string
	char* dest_hier_kw = getValByKey( &dataObjInp->condInput, DEST_RESC_HIER_STR_KW );
    if ( NULL == dest_hier_kw || 0 == strlen(dest_hier_kw) ) {
        std::string       hier;
        irods::error ret = irods::resolve_resource_hierarchy(
			irods::CREATE_OPERATION,
			rsComm,
			dataObjInp,
			hier );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << __FUNCTION__;
            msg << " :: failed in irods::resolve_resource_hierarchy for [";
            msg << dataObjInp->objPath << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
            return ret.code();
        }

        // =-=-=-=-=-=-=-
        // we resolved the redirect and have a host, set the hier str for subsequent
        // api calls, etc.
        addKeyVal(
		    &dataObjInp->condInput,
			DEST_RESC_HIER_STR_KW,
			hier.c_str() );
    } // if keyword

    char* src_resc = getValByKey( &dataObjInp->condInput, RESC_NAME_KW );
    if ( src_resc ) {
        std::string src_hier; 
        irods::error ret = resolve_hierarchy_for_resc_from_cond_input(
                               rsComm,
                               src_resc,
                               src_hier );
        if( !ret.ok() ) {
            irods::log( PASS( ret ) );
            return ret.code();
        }
        addKeyVal(
            &dataObjInp->condInput,
            RESC_HIER_STR_KW,
            src_hier.c_str() );
    }

    // =-=-=-=-=-=-=-
    // determine hierarchy string
	char* resc_hier_kw = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
    if ( NULL == resc_hier_kw || 0 == strlen(resc_hier_kw) ) {
        std::string       hier;
        irods::error ret = irods::resolve_resource_hierarchy(
		                       irods::OPEN_OPERATION,
							   rsComm,
                               dataObjInp,
							   hier );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << __FUNCTION__;
            msg << " :: failed in irods::resolve_resource_hierarchy for [";
            msg << dataObjInp->objPath << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
            return ret.code();
        }

        // =-=-=-=-=-=-=-
        // we resolved the redirect and have a host, set the hier str for subsequent
        // api calls, etc.
        addKeyVal(
		    &dataObjInp->condInput,
			RESC_HIER_STR_KW,
			hier.c_str() );
    } // if keyword

    *transStat = ( transferStat_t* )malloc( sizeof( transferStat_t ) );
    memset( *transStat, 0, sizeof( transferStat_t ) );

    if( getValByKey( &dataObjInp->condInput, ADMIN_KW ) != NULL ) {
        if ( rsComm->clientUser.authInfo.authFlag < LOCAL_PRIV_USER_AUTH ) {
            return CAT_INSUFFICIENT_PRIVILEGE_LEVEL;
        }
        accessPerm = NULL;
    }
    else {
        accessPerm = ACCESS_DELETE_OBJECT;
    }

    // query rcat for resource info and sort it
    status = getRescForCreate(
	             rsComm,
				 dataObjInp,
				 resc_name );
    if( status < 0 ) {
        return status;
    }
    initReiWithDataObjInp(
	    &rei,
		rsComm,
		dataObjInp );
    status = applyRule(
	             "acSetMultiReplPerResc",
				 NULL,
				 &rei,
				 NO_SAVE_REI );
    if ( strcmp( rei.statusStr, MULTI_COPIES_PER_RESC ) == 0 ) {
        multiCopyFlag = 1;
    }
    else {
        multiCopyFlag = 0;
    }

    // query rcat for dataObjInfo and sort it
    status = getDataObjInfo(
	             rsComm,
				 dataObjInp,
				 &dataObjInfoHead,
                 accessPerm, 1 );

    if ( status < 0 ) {
        rodsLog(
		    LOG_NOTICE,
            "rsDataObjPhymv: getDataObjInfo for %s",
			dataObjInp->objPath );
        return status;
    }

    irods::error ret = test_source_replica_for_write_permissions(
	                       rsComm,
	                       dataObjInfoHead );
	if( !ret.ok() ) {
        irods::log( PASS( ret ) );
		return ret.code();
	}

    status = resolveInfoForPhymv(
	             &dataObjInfoHead,
				 &oldDataObjInfoHead,
				 resc_name,
				 &dataObjInp->condInput,
				 multiCopyFlag );
    if ( status < 0 ) {
        freeAllDataObjInfo( dataObjInfoHead );
        freeAllDataObjInfo( oldDataObjInfoHead );
        if ( status == CAT_NO_ROWS_FOUND ) {
            return 0;
        }
        else {
            return status;
        }
    }
    status = _rsDataObjPhymv(
	             rsComm,
				 dataObjInp,
				 dataObjInfoHead,
				 resc_name.c_str(),
                 *transStat,
				 multiCopyFlag );

    freeAllDataObjInfo( dataObjInfoHead );
    freeAllDataObjInfo( oldDataObjInfoHead );

    return status;
}
Пример #23
0
int
rsDataObjPut( rsComm_t *rsComm, dataObjInp_t *dataObjInp,
              bytesBuf_t *dataObjInpBBuf, portalOprOut_t **portalOprOut ) {
    int status;
    int status2;
    int remoteFlag;
    rodsServerHost_t *rodsServerHost;
    specCollCache_t *specCollCache = NULL;

    resolveLinkedPath( rsComm, dataObjInp->objPath, &specCollCache,
                       &dataObjInp->condInput );
    remoteFlag = getAndConnRemoteZone( rsComm, dataObjInp, &rodsServerHost,
                                       REMOTE_CREATE );

    if ( const char* acl_string = getValByKey( &dataObjInp->condInput, ACL_INCLUDED_KW ) ) {
        try {
            irods::deserialize_acl( acl_string );
        }
        catch ( const irods::exception& e ) {
            rodsLog( LOG_ERROR, "%s", e.what() );
            return e.code();
        }
    }
    if ( const char* metadata_string = getValByKey( &dataObjInp->condInput, METADATA_INCLUDED_KW ) ) {
        try {
            irods::deserialize_metadata( metadata_string );
        }
        catch ( const irods::exception& e ) {
            rodsLog( LOG_ERROR, "%s", e.what() );
            return e.code();
        }
    }

    if ( remoteFlag < 0 ) {
        return remoteFlag;
    }
    else if ( remoteFlag == LOCAL_HOST ) {
        // =-=-=-=-=-=-=-
        // working on the "home zone", determine if we need to redirect to a different
        // server in this zone for this operation.  if there is a RESC_HIER_STR_KW then
        // we know that the redirection decision has already been made
        std::string       hier;
        if ( getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW ) == NULL ) {
            irods::error ret = irods::resolve_resource_hierarchy(
                                   irods::CREATE_OPERATION, rsComm,
                                   dataObjInp, hier );
            if ( !ret.ok() ) {
                std::stringstream msg;
                msg << __FUNCTION__;
                msg << " :: failed in irods::irods::resolve_resource_hierarchy for [";
                msg << dataObjInp->objPath << "]";
                irods::log( PASSMSG( msg.str(), ret ) );
                return ret.code();
            }
            // =-=-=-=-=-=-=-
            // we resolved the redirect and have a host, set the hier str for subsequent
            // api calls, etc.
            addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );

        } // if keyword

        status2 = applyRuleForPostProcForWrite( rsComm, dataObjInpBBuf,
                                                dataObjInp->objPath );
        if ( status2 < 0 ) {
            return ( status2 );
        }

        dataObjInp->openFlags = O_RDWR;
        status = _rsDataObjPut( rsComm, dataObjInp, dataObjInpBBuf,
                                portalOprOut );
    }
    else {
        int l1descInx;
        status = _rcDataObjPut( rodsServerHost->conn, dataObjInp,
                                dataObjInpBBuf, portalOprOut );
        if ( status < 0 ||
                getValByKey( &dataObjInp->condInput, DATA_INCLUDED_KW ) != NULL ) {
            return status;
        }
        else {
            /* have to allocate a local l1descInx to keep track of things
             * since the file is in remote zone. It sets remoteL1descInx,
             * oprType = REMOTE_ZONE_OPR and remoteZoneHost so that
             * rsComplete knows what to do */
            l1descInx = allocAndSetL1descForZoneOpr(
                            ( *portalOprOut )->l1descInx, dataObjInp, rodsServerHost, NULL );
            if ( l1descInx < 0 ) {
                return l1descInx;
            }
            ( *portalOprOut )->l1descInx = l1descInx;
            return status;
        }
    }

    return status;
}
Пример #24
0
// =-=-=-=-=-=-=-
// local function which handles removing directories via the resource plugin
int _rsFileRmdir(
    rsComm_t*       _comm,
    fileRmdirInp_t* _rmdir_inp ) {

    irods::collection_object_ptr coll_obj(
        new irods::collection_object(
            _rmdir_inp->dirName,
            _rmdir_inp->rescHier,
            0, 0 ) );

    if ( ( _rmdir_inp->flags & RMDIR_RECUR ) != 0 ) {
        // FIXME :: revisit this after moving to First class Objects
        // recursive. This is a very dangerous operation. curently
        // it is only used to remove cache directory of structured
        // files
        struct rodsDirent* myFileDirent = 0;

        // if it is not a cache dir, return an error as we only do this
        // for cache dirs at the moment.
        if ( strstr( _rmdir_inp->dirName, CACHE_DIR_STR ) == NULL ) {
            rodsLog( LOG_ERROR, "_rsFileRmdir: recursive rm of non cachedir path %s",
                     _rmdir_inp->dirName );
            return SYS_INVALID_FILE_PATH;
        }

        // call opendir via resource plugin
        irods::error opendir_err = fileOpendir( _comm, coll_obj );

        // log an error, if any
        if ( !opendir_err.ok() ) {
            std::stringstream msg;
            msg << "fileOpendir failed for [";
            msg << _rmdir_inp->dirName;
            msg << "]";
            irods::error err = PASSMSG( msg.str(), opendir_err );
            irods::log( err );
            return opendir_err.code();
        }

        // read the directory via resource plugin and either handle files or recurse into another directory
        irods::error readdir_err = fileReaddir( _comm, coll_obj, &myFileDirent );
        while ( readdir_err.ok() && 0 == readdir_err.code() ) {
            struct stat statbuf;
            char myPath[MAX_NAME_LEN];

            // handle relative paths
            if ( strcmp( myFileDirent->d_name, "." ) == 0 ||
                    strcmp( myFileDirent->d_name, ".." ) == 0 ) {
                readdir_err = fileReaddir( _comm, coll_obj, &myFileDirent );
                continue;
            }

            // cache path name
            snprintf( myPath, MAX_NAME_LEN, "%s/%s", &_rmdir_inp->dirName[0], &myFileDirent->d_name[0] );

            // =-=-=-=-=-=-=-
            // call stat via resource plugin, handle errors
            irods::collection_object_ptr myPath_obj(
                new irods::collection_object(
                    myPath,
                    _rmdir_inp->rescHier,
                    0, 0 ) );
            irods::error stat_err = fileStat( _comm, myPath_obj, &statbuf );
            if ( !stat_err.ok() ) {
                std::stringstream msg;
                msg << "fileStat failed for [";
                msg << myPath;
                msg << "]";
                irods::error log_err = PASSMSG( msg.str(), stat_err );
                irods::log( log_err );

                // call closedir via resource plugin, handle errors
                irods::error closedir_err = fileClosedir( _comm, myPath_obj );
                if ( !closedir_err.ok() ) {
                    std::stringstream msg;
                    msg << "fileClosedir for [";
                    msg << myPath;
                    msg << "]";
                    irods::error log_err = PASSMSG( msg.str(), closedir_err );
                    irods::log( log_err );
                }

                return stat_err.code();

            }  // if !stat_err.ok()

            // filter based on stat results: file, dir, or error
            int status = 0;
            if ( ( statbuf.st_mode & S_IFREG ) != 0 ) {
                // handle case where file is found
                irods::error unlink_err = fileUnlink( _comm, myPath_obj );
                status = unlink_err.code();
                if ( !unlink_err.ok() ) {
                    irods::error log_err = PASSMSG( "error during unlink.", unlink_err );
                    irods::log( log_err );
                }
            }
            else if ( ( statbuf.st_mode & S_IFDIR ) != 0 ) {
                // handle case where directory is found
                fileRmdirInp_t myRmdirInp;
                memset( &myRmdirInp, 0, sizeof( myRmdirInp ) );

                myRmdirInp.flags    = _rmdir_inp->flags;
                rstrcpy( myRmdirInp.dirName, myPath, MAX_NAME_LEN );
                rstrcpy( myRmdirInp.rescHier, _rmdir_inp->rescHier, MAX_NAME_LEN );

                // RECURSE - call _rsFileRmdir on this new found directory
                status = _rsFileRmdir( _comm, &myRmdirInp );

            }
            else {
                status = SYS_INVALID_FILE_PATH;
                rodsLog( LOG_NOTICE, "_rsFileRmdir:  for %s, status = %d", myPath, status );
            }

            // handle error condition on the above three cases
            if ( status < 0 ) {
                rodsLog( LOG_NOTICE, "_rsFileRmdir:  rm of %s failed, status = %d", myPath, status );

                // call closedir via resource plugin, handle errors
                irods::error closedir_err = fileClosedir( _comm, myPath_obj );
                if ( !closedir_err.ok() ) {
                    std::stringstream msg;
                    msg << "fileClosedir failed for [";
                    msg << myPath;
                    msg << "]";
                    irods::error log_err = PASSMSG( msg.str(), closedir_err );
                    irods::log( log_err );
                }

                return status;

            } // if status < 0

            // =-=-=-=-=-=-=-
            // continue readdir via resource plugin
            readdir_err = fileReaddir( _comm, coll_obj, &myFileDirent );

        } // while

        // =-=-=-=-=-=-=-
        // call closedir via resource plugin, handle errors
        irods::error closedir_err = fileClosedir( _comm, coll_obj );
        if ( !closedir_err.ok() ) {
            std::stringstream msg;
            msg << "fileClosedir failed for [";
            msg << _rmdir_inp->dirName;
            msg << "]";
            irods::error log_err = PASSMSG( msg.str(), closedir_err );
            irods::log( log_err );
        }

    } // if RMDIR_RECUR ( recursive delete )

    // =-=-=-=-=-=-=-
    // make the call to rmdir via the resource plugin
    irods::error rmdir_err = fileRmdir( _comm, coll_obj );
    if ( !rmdir_err.ok() ) {
        std::stringstream msg;
        msg << "fileRmdir failed for [";
        msg << _rmdir_inp->dirName;
        msg << "]";
        irods::error err = PASSMSG( msg.str(), rmdir_err );
        irods::log( err );
    }

    return rmdir_err.code();

} // _rsFileRmdir
Пример #25
0
int
rsDataObjCreate( rsComm_t *rsComm, dataObjInp_t *dataObjInp ) {
    int l1descInx;
    int status;
    rodsObjStat_t *rodsObjStatOut = NULL;
    int remoteFlag;
    rodsServerHost_t *rodsServerHost;
    specCollCache_t *specCollCache = NULL;
    char *lockType = NULL; // JMC - backport 4604
    int lockFd = -1; // JMC - backport 4604

    resolveLinkedPath( rsComm, dataObjInp->objPath, &specCollCache,
                       &dataObjInp->condInput );
    remoteFlag = getAndConnRemoteZone( rsComm, dataObjInp, &rodsServerHost,
                                       REMOTE_CREATE );
    if ( remoteFlag < 0 ) {
        return ( remoteFlag );
    }
    else if ( remoteFlag == REMOTE_HOST ) {
        openStat_t *openStat = NULL;
        addKeyVal( &dataObjInp->condInput, CROSS_ZONE_CREATE_KW, "" );
        status = rcDataObjCreateAndStat( rodsServerHost->conn, dataObjInp, &openStat );

        /* rm it to avoid confusion */
        rmKeyVal( &dataObjInp->condInput, CROSS_ZONE_CREATE_KW );
        if ( status < 0 ) {
            return status;
        }
        l1descInx = allocAndSetL1descForZoneOpr( status, dataObjInp, rodsServerHost, openStat );

        if ( openStat != NULL ) {
            free( openStat );
        }
        return ( l1descInx );
    }

    // =-=-=-=-=-=-=-
    // working on the "home zone", determine if we need to redirect to a different
    // server in this zone for this operation.  if there is a RESC_HIER_STR_KW then
    // we know that the redirection decision has already been made
    char* resc_hier = getValByKey( &dataObjInp->condInput, RESC_HIER_STR_KW );
    if ( NULL == resc_hier ) {
        std::string       hier;
        irods::error ret = irods::resolve_resource_hierarchy( irods::CREATE_OPERATION, rsComm,
                           dataObjInp, hier );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << "failed in irods::resolve_resource_hierarchy for [";
            msg << dataObjInp->objPath << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
            return ret.code();
        }

        // =-=-=-=-=-=-=-
        // we resolved the redirect and have a host, set the hier str for subsequent
        // api calls, etc.
        addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );

    } // if keyword

    // =-=-=-=-=-=-=-
    // JMC - backport 4604
    lockType = getValByKey( &dataObjInp->condInput, LOCK_TYPE_KW );
    if ( lockType != NULL ) {
        lockFd = rsDataObjLock( rsComm, dataObjInp );
        if ( lockFd >= 0 ) {
            /* rm it so it won't be done again causing deadlock */
            rmKeyVal( &dataObjInp->condInput, LOCK_TYPE_KW );
        }
        else {
            rodsLogError( LOG_ERROR, lockFd,
                          "rsDataObjCreate: rsDataObjLock error for %s. lockType = %s",
                          dataObjInp->objPath, lockType );
            return lockFd;
        }
    }

    // =-=-=-=-=-=-=-
    // Gets here means local zone operation stat dataObj
    addKeyVal( &dataObjInp->condInput, SEL_OBJ_TYPE_KW, "dataObj" );

    status = rsObjStat( rsComm, dataObjInp, &rodsObjStatOut );

    if ( rodsObjStatOut != NULL && rodsObjStatOut->objType == COLL_OBJ_T ) {
        if ( lockFd >= 0 ) {
            rsDataObjUnlock( rsComm, dataObjInp, lockFd );    // JMC - backport 4604
        }
        return ( USER_INPUT_PATH_ERR );
    }

    if ( rodsObjStatOut                      != NULL &&
            rodsObjStatOut->specColl            != NULL &&
            rodsObjStatOut->specColl->collClass == LINKED_COLL ) {
        /*  should not be here because if has been translated */
        if ( lockFd >= 0 ) {
            rsDataObjUnlock( rsComm, dataObjInp, lockFd ); // JMC - backport 4604
        }

        return SYS_COLL_LINK_PATH_ERR;
    }


    if ( rodsObjStatOut  == NULL                     ||
            ( rodsObjStatOut->objType  == UNKNOWN_OBJ_T &&
              rodsObjStatOut->specColl == NULL ) ) {
        /* does not exist. have to create one */
        /* use L1desc[l1descInx].replStatus & OPEN_EXISTING_COPY instead */
        /* newly created. take out FORCE_FLAG since it could be used by put */
        /* rmKeyVal (&dataObjInp->condInput, FORCE_FLAG_KW); */
        l1descInx = _rsDataObjCreate( rsComm, dataObjInp );

    }
    else if ( rodsObjStatOut->specColl != NULL &&
              rodsObjStatOut->objType == UNKNOWN_OBJ_T ) {

        /* newly created. take out FORCE_FLAG since it could be used by put */
        /* rmKeyVal (&dataObjInp->condInput, FORCE_FLAG_KW); */
        l1descInx = specCollSubCreate( rsComm, dataObjInp );
    }
    else {

        /* dataObj exist */
        if ( getValByKey( &dataObjInp->condInput, FORCE_FLAG_KW ) != NULL ) {
            dataObjInp->openFlags |= O_TRUNC | O_RDWR;

            // =-=-=-=-=-=-=-
            // re-determine the resource hierarchy since this is an open instead of a create
            std::string       hier;
            irods::error ret = irods::resolve_resource_hierarchy( irods::WRITE_OPERATION,
                               rsComm, dataObjInp, hier );
            if ( !ret.ok() ) {
                std::stringstream msg;
                msg << __FUNCTION__;
                msg << " :: failed in irods::resolve_resource_hierarchy for [";
                msg << dataObjInp->objPath << "]";
                irods::log( PASSMSG( msg.str(), ret ) );
                return ret.code();
            }

            // =-=-=-=-=-=-=-
            // we resolved the redirect and have a host, set the hier str for subsequent
            // api calls, etc.
            addKeyVal( &dataObjInp->condInput, RESC_HIER_STR_KW, hier.c_str() );
            std::string top_resc;
            irods::hierarchy_parser parser;
            parser.set_string( hier );
            parser.first_resc( top_resc );
            addKeyVal( &dataObjInp->condInput, DEST_RESC_NAME_KW, top_resc.c_str() );
            l1descInx = _rsDataObjOpen( rsComm, dataObjInp );

        }
        else {
            l1descInx = OVERWRITE_WITHOUT_FORCE_FLAG;
        }
    }

    if ( rodsObjStatOut != NULL ) {
        freeRodsObjStat( rodsObjStatOut );
    }

    // =-=-=-=-=-=-=-
    // JMC - backport 4604
    if ( lockFd >= 0 ) {
        if ( l1descInx >= 0 ) {
            L1desc[l1descInx].lockFd = lockFd;
        }
        else {
            rsDataObjUnlock( rsComm, dataObjInp, lockFd );
        }
    }

    // =-=-=-=-=-=-=-
    return ( l1descInx );
}
/// =-=-=-=-=-=-=-
/// @brief function which manages the TLS and Auth negotiations with the client
    error client_server_negotiation_for_server(
        irods::network_object_ptr _ptr,
        std::string&               _result ) {
        // =-=-=-=-=-=-=-
        // manufacture an rei for the applyRule
        ruleExecInfo_t rei;
        memset( ( char* )&rei, 0, sizeof( ruleExecInfo_t ) );

        // =-=-=-=-=-=-=-
        // if it is, then call the pre PEP and get the result
        msParamArray_t params;
        memset( &params, 0, sizeof( params ) );
        int status = applyRuleUpdateParams(
                         "acPreConnect(*OUT)",
                         &params,
                         &rei,
                         NO_SAVE_REI );
        if ( 0 != status ) {
            return ERROR( status, "failed in call to applyRuleUpdateParams" );
        }

        // =-=-=-=-=-=-=-
        // extract the value from the outgoing param to pass out to the operation
        char* rule_result_ptr = 0;
        msParam_t* out_ms_param = getMsParamByLabel( &params, "*OUT" );
        if ( out_ms_param ) {
            rule_result_ptr = reinterpret_cast< char* >( out_ms_param->inOutStruct );

        }
        else {
            return ERROR( SYS_INVALID_INPUT_PARAM, "null out parameter" );

        }

        if ( !rule_result_ptr ) {
            return ERROR( SYS_INVALID_INPUT_PARAM, "rule_result is null" );

        }

        std::string rule_result( rule_result_ptr );
        clearMsParamArray( &params, 0 );

        // =-=-=-=-=-=-=-
        // check to see if a negoation was requested
        if ( !do_client_server_negotiation_for_server() ) {
            // =-=-=-=-=-=-=-
            // if it was not but we require SSL then error out
            if ( CS_NEG_REQUIRE == rule_result ) {
                std::stringstream msg;
                msg << "SSL is required by the server but not requested by the client";
                return ERROR( SYS_INVALID_INPUT_PARAM, msg.str() );

            }
            else {
                // =-=-=-=-=-=-=-
                // a negotiation was not requested, bail
                return SUCCESS();
            }

        }

        // =-=-=-=-=-=-=-
        // pass the PEP result to the client, send CS_NEG_SVR_1_MSG
        irods::cs_neg_t cs_neg;
        cs_neg.status_ = CS_NEG_STATUS_SUCCESS;
        strncpy( cs_neg.result_, rule_result.c_str(), MAX_NAME_LEN );
        error err = send_client_server_negotiation_message( _ptr, cs_neg );
        if ( !err.ok() ) {
            std::stringstream msg;
            msg << "failed with PEP value of [" << rule_result << "]";
            return PASSMSG( msg.str(), err );
        }

        // =-=-=-=-=-=-=-
        // get the response from CS_NEG_CLI_1_MSG
        boost::shared_ptr< cs_neg_t > read_cs_neg;
        err = read_client_server_negotiation_message( _ptr, read_cs_neg );
        if ( !err.ok() ) {
            return PASS( err );
        }

        // =-=-=-=-=-=-=-
        // get the result from the key val pair
        if ( strlen( read_cs_neg->result_ ) != 0 ) {
            irods::kvp_map_t kvp;
            err = irods::parse_kvp_string( 
                      read_cs_neg->result_, 
                      kvp );
            if( err.ok() ) {

                 // =-=-=-=-=-=-=-
                 // extract the signed SID
                 if ( kvp.find( CS_NEG_SID_KW ) != kvp.end() ) {
                    std::string svr_sid = kvp[ CS_NEG_SID_KW ];
                    if( !svr_sid.empty() ) {
                        // =-=-=-=-=-=-=-
                        // get our SID to compare
                        server_properties& props = server_properties::getInstance();
                        err = props.capture_if_needed();
                        if( !err.ok() ) {
                            return PASS( err );
                        }

                        // =-=-=-=-=-=-=-
                        // sign local SID
                        std::string signed_sid;
                        err = sign_server_sid(
                                signed_sid );
                        if( !err.ok() ) {
                            return PASS( err );
                        }

                        // =-=-=-=-=-=-=-
                        // check SID against our SID
                        if( svr_sid != signed_sid ) {
                            rodsLog(
                                LOG_ERROR,
                                "client-server negotiation SID mismatch [%s] vs [%s]",
                                svr_sid.c_str(),
                                signed_sid.c_str() );
                        } else {
                            // =-=-=-=-=-=-=-
                            // store property that states this is an Agent-Agent connection
                            props.set_property< std::string >( AGENT_CONN_KW, svr_sid );
                        }

                    } // if sid is not empty
                    else {
                        rodsLog( LOG_ERROR, "client_server_negotiation_for_server - sent SID is empty" );
                    }
                 }

                 // =-=-=-=-=-=-=-
                 // check to see if the result string has the SSL negotiation results
                 _result = kvp[ CS_NEG_RESULT_KW ];
                 if( _result.empty() ) {
                    return ERROR(
                            UNMATCHED_KEY_OR_INDEX,
                            "SSL result string missing from response" );
                 }

            } else {
                 // =-=-=-=-=-=-=-
                 // support 4.0 client-server negotiation which did not
                 // use key-val pairs
                 _result = read_cs_neg->result_;

             }

        } // if result strlen > 0 

        // =-=-=-=-=-=-=-
        // if the response is favorable, return success
        if ( CS_NEG_STATUS_SUCCESS == read_cs_neg->status_ ) {
            return SUCCESS();
        }

        // =-=-=-=-=-=-=-
        // else, return a failure
        return ERROR( -1, "failure detected from client" );

    } // client_server_negotiation_for_server
Пример #27
0
int
rsDataObjLseek( rsComm_t *rsComm, openedDataObjInp_t *dataObjLseekInp,
                fileLseekOut_t **dataObjLseekOut ) {
    int status;
    int l1descInx, l3descInx;
    int rescTypeInx;
    dataObjInfo_t *dataObjInfo;

    l1descInx = dataObjLseekInp->l1descInx;

    if ( l1descInx <= 2 || l1descInx >= NUM_L1_DESC ) {
        rodsLog( LOG_NOTICE,
                 "rsDataObjLseek: l1descInx %d out of range",
                 l1descInx );
        return ( SYS_FILE_DESC_OUT_OF_RANGE );
    }
    if ( L1desc[l1descInx].inuseFlag != FD_INUSE ) {
        return BAD_INPUT_DESC_INDEX;
    }
    if ( L1desc[l1descInx].remoteZoneHost != NULL ) {
        /* cross zone operation */
        dataObjLseekInp->l1descInx = L1desc[l1descInx].remoteL1descInx;
        status = rcDataObjLseek( L1desc[l1descInx].remoteZoneHost->conn,
                                 dataObjLseekInp, dataObjLseekOut );
        dataObjLseekInp->l1descInx = l1descInx;
        return status;
    }

    l3descInx = L1desc[l1descInx].l3descInx;

    if ( l3descInx <= 2 ) {
        rodsLog( LOG_NOTICE,
                 "rsDataObjLseek: l3descInx %d out of range",
                 l3descInx );
        return ( SYS_FILE_DESC_OUT_OF_RANGE );
    }

    dataObjInfo = L1desc[l1descInx].dataObjInfo;

    // =-=-=-=-=-=-=-
    // extract the host location from the resource hierarchy
    std::string location;
    irods::error ret = irods::get_loc_for_hier_string( dataObjInfo->rescHier, location );
    if ( !ret.ok() ) {
        irods::log( PASSMSG( "rsDataObjLseek - failed in get_loc_for_hier_String", ret ) );
        return -1;
    }


    if ( getStructFileType( dataObjInfo->specColl ) >= 0 ) {
        subStructFileLseekInp_t subStructFileLseekInp;
        memset( &subStructFileLseekInp, 0, sizeof( subStructFileLseekInp ) );
        subStructFileLseekInp.type = dataObjInfo->specColl->type;
        subStructFileLseekInp.fd = L1desc[l1descInx].l3descInx;
        subStructFileLseekInp.offset = dataObjLseekInp->offset;
        subStructFileLseekInp.whence = dataObjLseekInp->whence;
        rstrcpy( subStructFileLseekInp.addr.hostAddr,
                 location.c_str(),
                 NAME_LEN );
        rstrcpy( subStructFileLseekInp.resc_hier,
                 dataObjInfo->rescHier,
                 NAME_LEN );
        status = rsSubStructFileLseek( rsComm, &subStructFileLseekInp, dataObjLseekOut );
    }
    else {
        *dataObjLseekOut = ( fileLseekOut_t* )malloc( sizeof( fileLseekOut_t ) );
        memset( *dataObjLseekOut, 0, sizeof( fileLseekOut_t ) );
        rescTypeInx = dataObjInfo->rescInfo->rescTypeInx;

        ( *dataObjLseekOut )->offset = _l3Lseek( rsComm, rescTypeInx, l3descInx,
                                       dataObjLseekInp->offset, dataObjLseekInp->whence );

        if ( ( *dataObjLseekOut )->offset >= 0 ) {
            status = 0;
        }
        else {
            status = ( *dataObjLseekOut )->offset;
        }
    }

    return ( status );
}
Пример #28
0
 error set_property( const std::string& _key, const T& _val ) {
     error ret = properties_.set< T >( _key, _val );
     return PASSMSG( "resource::set_property", ret );
 } // set_property
Пример #29
0
int
rsPhyBundleColl( rsComm_t*                 rsComm,
                 structFileExtAndRegInp_t* phyBundleCollInp ) {
    int               status         = -1;
    specCollCache_t*  specCollCache  = 0;
    char*             destRescName   = 0;

    resolveLinkedPath( rsComm, phyBundleCollInp->objPath, &specCollCache,
                       &phyBundleCollInp->condInput );

    resolveLinkedPath( rsComm, phyBundleCollInp->collection,
                       &specCollCache, NULL );

    if ( ( destRescName = getValByKey( &phyBundleCollInp->condInput,
                                       DEST_RESC_NAME_KW ) ) == NULL ) {
        return USER_NO_RESC_INPUT_ERR;
    }

    if ( isLocalZone( phyBundleCollInp->collection ) == 0 ) {
        /* can only do local zone */
        return SYS_INVALID_ZONE_NAME;
    }

    // =-=-=-=-=-=-=-
    // working on the "home zone", determine if we need to redirect to a different
    // server in this zone for this operation.  if there is a RESC_HIER_STR_KW then
    // we know that the redirection decision has already been made
    dataObjInp_t      data_inp;
    bzero( &data_inp, sizeof( data_inp ) );
    rstrcpy( data_inp.objPath, phyBundleCollInp->objPath, MAX_NAME_LEN );
    bzero( &data_inp.condInput, sizeof( data_inp.condInput ) );
    addKeyVal( &data_inp.condInput, DEST_RESC_NAME_KW, destRescName );

    std::string       hier;
    char* hier_kw = getValByKey( &phyBundleCollInp->condInput, RESC_HIER_STR_KW );
    if ( hier_kw == NULL ) {
        irods::error ret = irods::resolve_resource_hierarchy( irods::CREATE_OPERATION, rsComm,
                           &data_inp, hier );
        if ( !ret.ok() ) {
            std::stringstream msg;
            msg << "failed in irods::resolve_resource_hierarchy for [";
            msg << data_inp.objPath << "]";
            irods::log( PASSMSG( msg.str(), ret ) );
            return ret.code();
        }

        // =-=-=-=-=-=-=-
        // we resolved the redirect and have a host, set the hier str for subsequent
        // api calls, etc.
        addKeyVal( &phyBundleCollInp->condInput, RESC_HIER_STR_KW, hier.c_str() );

    }
    else {
        hier = hier_kw;

    }

    // =-=-=-=-=-=-=-
    // extract the host location from the resource hierarchy
    std::string location;
    irods::error ret = irods::get_loc_for_hier_string( hier, location );
    if ( !ret.ok() ) {
        irods::log( PASSMSG( "rsPhyBundleColl - failed in get_loc_for_hier_string", ret ) );
        return -1;
    }



    rodsHostAddr_t rescAddr;
    bzero( &rescAddr, sizeof( rescAddr ) );

    rstrcpy( rescAddr.hostAddr, location.c_str(), NAME_LEN );
    rodsServerHost_t* rodsServerHost = 0;
    int remoteFlag = resolveHost( &rescAddr, &rodsServerHost );



    if ( remoteFlag == LOCAL_HOST ) {
        status = _rsPhyBundleColl( rsComm, phyBundleCollInp, destRescName );
    }
    else if ( remoteFlag == REMOTE_HOST ) {
        status = remotePhyBundleColl( rsComm, phyBundleCollInp, rodsServerHost );
    }
    else if ( remoteFlag < 0 ) {
        status = remoteFlag;
    }


    return status;
}
Пример #30
0
int agentMain(
    rsComm_t *rsComm ) {
    if ( !rsComm ) {
        return SYS_INTERNAL_NULL_INPUT_ERR;

    }

    int status = 0;

    // =-=-=-=-=-=-=-
    // capture server properties
    irods::server_properties& props = irods::server_properties::getInstance();
    irods::error result = props.capture_if_needed();
    if ( !result.ok() ) {
        irods::log( PASSMSG( "failed to read server configuration", result ) );
    }

    // =-=-=-=-=-=-=-
    // compiler backwards compatibility hack
    // see header file for more details
    irods::dynamic_cast_hack();

    while ( result.ok() && status >= 0 ) {

        // set default to the native auth scheme here.
        if ( rsComm->auth_scheme == NULL ) {
            rsComm->auth_scheme = strdup( "native" );
        }
        // construct an auth object based on the scheme specified in the comm
        irods::auth_object_ptr auth_obj;
        irods::error ret = irods::auth_factory( rsComm->auth_scheme, &rsComm->rError, auth_obj );
        if ( ( result = ASSERT_PASS( ret, "Failed to factory an auth object for scheme: \"%s\".", rsComm->auth_scheme ) ).ok() ) {

            irods::plugin_ptr ptr;
            ret = auth_obj->resolve( irods::AUTH_INTERFACE, ptr );
            if ( ( result = ASSERT_PASS( ret, "Failed to resolve the auth plugin for scheme: \"%s\".",
                                         rsComm->auth_scheme ) ).ok() ) {

                irods::auth_ptr auth_plugin = boost::dynamic_pointer_cast< irods::auth >( ptr );

                // Call agent start
                char* foo = "";
                ret = auth_plugin->call < const char* > ( rsComm, irods::AUTH_AGENT_START, auth_obj, foo );
                result = ASSERT_PASS( ret, "Failed during auth plugin agent start for scheme: \"%s\".", rsComm->auth_scheme );
            }

            // =-=-=-=-=-=-=-
            // add the user info to the server properties for
            // reach by the operation wrapper for access by the
            // dynamic policy enforcement points
            set_rule_engine_globals( rsComm, props );
        }

        if ( result.ok() ) {
            if ( rsComm->ssl_do_accept ) {
                status = sslAccept( rsComm );
                if ( status < 0 ) {
                    rodsLog( LOG_ERROR, "sslAccept failed in agentMain with status %d", status );
                }
                rsComm->ssl_do_accept = 0;
            }
            if ( rsComm->ssl_do_shutdown ) {
                status = sslShutdown( rsComm );
                if ( status < 0 ) {
                    rodsLog( LOG_ERROR, "sslShutdown failed in agentMain with status %d", status );
                }
                rsComm->ssl_do_shutdown = 0;
            }

            status = readAndProcClientMsg( rsComm, READ_HEADER_TIMEOUT );
            if ( status < 0 ) {
                if ( status == DISCONN_STATUS ) {
                    status = 0;
                    break;
                }
            }
        }
    }

    if ( !result.ok() ) {
        irods::log( result );
        status = result.code();
        return status;
    }

    // =-=-=-=-=-=-=-
    // determine if we even need to connect, break the
    // infinite reconnect loop.
    if ( !resc_mgr.need_maintenance_operations() ) {
        return status;
    }

    // =-=-=-=-=-=-=-
    // find the icat host
    rodsServerHost_t *rodsServerHost = 0;
    status = getRcatHost( MASTER_RCAT, 0, &rodsServerHost );
    if ( status < 0 ) {
        irods::log( ERROR( status, "getRcatHost failed." ) );
        return status;
    }

    // =-=-=-=-=-=-=-
    // connect to the icat host
    status = svrToSvrConnect( rsComm, rodsServerHost );
    if ( status < 0 ) {
        irods::log( ERROR( status, "svrToSvrConnect failed." ) );
        return status;
    }

    // =-=-=-=-=-=-=-
    // call post disconnect maintenance operations before exit
    status = resc_mgr.call_maintenance_operations( rodsServerHost->conn );

    return status;
}