int performAction( inStruct Sentries ) { int status; int c, i, j; int uFlag = 0;; char tmpStr[100]; ruleExecInfo_t rei; char action[100]; char *t1; char *args[MAX_NUM_OF_ARGS_IN_ACTION]; char configDirEV[200]; char retestflagEV[200]; char reloopbackflagEV[200]; char ruleSet[RULE_SET_DEF_LENGTH]; hrtime_t ht1, ht2, ht3; bzero( &rei, sizeof( ruleExecInfo_t ) ); /* June 17. 2009 */ /* sprintf(configDirEV,"irodsConfigDir=/scratch/s1/sekar/irods/RODS/server/config"); sprintf(configDirEV,"irodsConfigDir=/misc/www/projects/srb-secure/cgi-bin"); putenv(configDirEV); */ sprintf( retestflagEV, "RETESTFLAG=%i", HTML_TEST_1 ); putenv( retestflagEV ); sprintf( reloopbackflagEV, "RELOOPBACKFLAG=%i", LOOP_BACK_1 ); putenv( reloopbackflagEV ); fprintf( stdout, "Content-type: text/html%c%c", 10, 10 ); fflush( stdout ); fprintf( stdout, "<HTML>\n<HEAD>\n<TITLE>iRODS Rule Administration</TITLE>\n</HEAD>\n<BODY bgcolor=#FFFFFF>\n" ); fprintf( stdout, "<CENTER> <B><FONT COLOR=#FF0000>iRODS Rule Application</FONT></B></CENTER>\n" ); fflush( stdout ); rei.doi = mallocAndZero( sizeof( dataObjInfo_t ) ); rei.uoip = mallocAndZero( sizeof( userInfo_t ) ); rei.uoic = mallocAndZero( sizeof( userInfo_t ) ); rei.coi = mallocAndZero( sizeof( collInfo_t ) ); rei.uoio = mallocAndZero( sizeof( userInfo_t ) ); rei.next = NULL; strcpy( rei.doi->objPath, "" ); strcpy( rei.doi->rescName, "" ); strcpy( rei.doi->dataType, "" ); strcpy( rei.uoic->authInfo.host, "" ); rei.doi->dataSize = 100; rei.condInputData = NULL; rei.rsComm = NULL; strcpy( ruleSet, "" ); for ( i = 0; i <= Sentries->m; i++ ) { if ( !strcmp( Sentries->entries[i].name, "action" ) ) { strcpy( action, Sentries->entries[i].val ); fprintf( stdout, "<FONT COLOR=#0000FF>Action:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "objPath" ) ) { strcpy( rei.doi->objPath, Sentries->entries[i].val ); fprintf( stdout, "<FONT COLOR=#0000FF>$objPath:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "rescName" ) ) { strcpy( rei.doi->rescName, Sentries->entries[i].val ); fprintf( stdout, "<FONT COLOR=#0000FF>$rescName:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "dataSize" ) ) { rei.doi->dataSize = atol( Sentries->entries[i].val ); fprintf( stdout, "<FONT COLOR=#0000FF>$dataSize:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "dataType" ) ) { strcpy( rei.doi->dataType, Sentries->entries[i].val ); fprintf( stdout, "<FONT COLOR=#0000FF>$dataType:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "dataOwner" ) ) { strcpy( rei.doi->dataOwnerName, Sentries->entries[i].val ); if ( ( t1 = strstr( rei.doi->dataOwnerName, "|" ) ) != NULL ) { *t1 = '\0'; strcpy( rei.doi->dataOwnerZone, ( char * )( t1 + 1 ) ); } else { strcpy( rei.doi->dataOwnerZone, "" ); } fprintf( stdout, "<FONT COLOR=#0000FF>$dataOwner:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "dataUser" ) ) { strcpy( rei.uoic->userName, Sentries->entries[i].val ); if ( ( t1 = strstr( rei.uoic->userName, "|" ) ) != NULL ) { *t1 = '\0'; strcpy( rei.uoic->rodsZone, ( char * )( t1 + 1 ) ); } else { strcpy( rei.uoic->rodsZone, "" ); } fprintf( stdout, "<FONT COLOR=#0000FF>$dataUser:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "dataAccess" ) ) { strcpy( rei.doi->dataAccess, Sentries->entries[i].val ); fprintf( stdout, "<FONT COLOR=#0000FF>$dataAccess:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "hostClient" ) ) { strcpy( rei.uoic->authInfo.host, Sentries->entries[i].val ); fprintf( stdout, "<FONT COLOR=#0000FF>$hostClient:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "proxyUser" ) ) { strcpy( rei.uoip->userName, Sentries->entries[i].val ); if ( ( t1 = strstr( rei.uoip->userName, "|" ) ) != NULL ) { *t1 = '\0'; strcpy( rei.uoip->rodsZone, ( char * )( t1 + 1 ) ); } else { strcpy( rei.uoio->rodsZone, "" ); } fprintf( stdout, "<FONT COLOR=#0000FF>$otherUser:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "otherUser" ) ) { strcpy( rei.uoic->userName, Sentries->entries[i].val ); if ( ( t1 = strstr( rei.uoio->userName, "|" ) ) != NULL ) { *t1 = '\0'; strcpy( rei.uoio->rodsZone, ( char * )( t1 + 1 ) ); } else { strcpy( rei.uoio->rodsZone, "" ); } fprintf( stdout, "<FONT COLOR=#0000FF>$otherUser:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "otherUserType" ) ) { strcpy( rei.uoio->userType, Sentries->entries[i].val ); fprintf( stdout, "<FONT COLOR=#0000FF>$otherUserType:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "ruleSet" ) ) { if ( strlen( Sentries->entries[i].val ) > 0 ) { if ( ruleSet[0] != '\0' ) { strcat( ruleSet, "," ); } rstrcat( ruleSet, Sentries->entries[i].val, 999 ); } } else if ( !strcmp( Sentries->entries[i].name, "retestflag" ) ) { sprintf( retestflagEV, "RETESTFLAG=%s", Sentries->entries[i].val ); putenv( retestflagEV ); fprintf( stdout, "<FONT COLOR=#0000FF>Trace Status</FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val ); } else if ( !strcmp( Sentries->entries[i].name, "configDir" ) ) { if ( strlen( Sentries->entries[i].val ) > 0 ) { snprintf( configDirEV, 199, "irodsConfigDir=%s", Sentries->entries[i].val ); } else { sprintf( configDirEV, "irodsConfigDir=%s", MY_SERVER_CONFIG_DIR ); } putenv( configDirEV ); } /* else if (!strcmp(Sentries->entries[i].name,"")){ strcpy(,Sentries->entries[i].val); fprintf(stdout,"<FONT COLOR=#0000FF></FONT> <FONT COLOR=#FF0000>%s</FONT><BR>\n", Sentries->entries[i].val); } */ } fprintf( stdout, "<FONT COLOR=#0000FF>Rule Set:</FONT> <FONT COLOR=#FF0000>%s</FONT><BR><HR>\n", ruleSet ); strcpy( rei.ruleSet, ruleSet ); /* fprintf(stdout,"<PRE>\n");fflush(stdout);*/ ht1 = gethrtime(); initRuleStruct( NULL, ruleSet, "core", "core" ); ht2 = gethrtime(); /*** i = applyRule(action, args, 0, &rei, SAVE_REI); ***/ i = applyRuleArgPA( action, args, 0, NULL, &rei, SAVE_REI ); ht3 = gethrtime(); if ( reTestFlag == COMMAND_TEST_1 || reTestFlag == COMMAND_TEST_MSI ) { fprintf( stdout, "Rule Initialization Time = %.2f millisecs\n", ( float )( ht2 - ht1 ) / 1000000 ); fprintf( stdout, "Rule Execution Time = %.2f millisecs\n", ( float )( ht3 - ht1 ) / 1000000 ); } if ( reTestFlag == HTML_TEST_1 || reTestFlag == HTML_TEST_MSI ) { fprintf( stdout, "<BR>Rule Initialization Time = %.2f millisecs<BR>\n", ( float )( ht2 - ht1 ) / 1000000 ); fprintf( stdout, "Rule Execution Time = %.2f millisecs<BR>\n", ( float )( ht3 - ht1 ) / 1000000 ); } if ( i != 0 ) { rodsLogError( LOG_ERROR, i, "<BR>Rule Application Failed:" ); /* fprintf(stdout,"</PRE>\n</body>\n</HTML>\n");*/ return -1; } /* fprintf(stdout,"</PRE>\n</body>\n</HTML>\n");*/ return 0; }
int igsiServersideAuth() { int status; #if defined(GSI_AUTH) char clientName[500]; genQueryInp_t genQueryInp; genQueryOut_t *genQueryOut; char condition1[MAX_NAME_LEN]; char condition2[MAX_NAME_LEN]; char *tResult; int privLevel; int clientPrivLevel; int noNameMode; int statusRule; #ifdef GSI_DEBUG char *getVar; getVar = getenv( "X509_CERT_DIR" ); if ( getVar != NULL ) { printf( "X509_CERT_DIR:%s\n", getVar ); } #endif gsiAuthReqStatus = 1; status = igsiEstablishContextServerside( rsComm, clientName, 500 ); #ifdef GSI_DEBUG if ( status == 0 ) { printf( "clientName:%s\n", clientName ); } #endif memset( &genQueryInp, 0, sizeof( genQueryInp_t ) ); noNameMode = 0; if ( strlen( rsComm->clientUser.userName ) > 0 ) { /* regular mode */ snprintf( condition1, MAX_NAME_LEN, "='%s'", clientName ); addInxVal( &genQueryInp.sqlCondInp, COL_USER_DN, condition1 ); snprintf( condition2, MAX_NAME_LEN, "='%s'", rsComm->clientUser.userName ); addInxVal( &genQueryInp.sqlCondInp, COL_USER_NAME, condition2 ); addInxIval( &genQueryInp.selectInp, COL_USER_ID, 1 ); addInxIval( &genQueryInp.selectInp, COL_USER_TYPE, 1 ); addInxIval( &genQueryInp.selectInp, COL_USER_ZONE, 1 ); genQueryInp.maxRows = 2; status = rsGenQuery( rsComm, &genQueryInp, &genQueryOut ); } else { /* The client isn't providing the rodsUserName so query on just the DN. If it returns just one row, set the clientUser to the returned irods user name. */ noNameMode = 1; memset( &genQueryInp, 0, sizeof( genQueryInp_t ) ); snprintf( condition1, MAX_NAME_LEN, "='%s'", clientName ); addInxVal( &genQueryInp.sqlCondInp, COL_USER_DN, condition1 ); addInxIval( &genQueryInp.selectInp, COL_USER_ID, 1 ); addInxIval( &genQueryInp.selectInp, COL_USER_TYPE, 1 ); addInxIval( &genQueryInp.selectInp, COL_USER_NAME, 1 ); addInxIval( &genQueryInp.selectInp, COL_USER_ZONE, 1 ); genQueryInp.maxRows = 2; status = rsGenQuery( rsComm, &genQueryInp, &genQueryOut ); if ( status == CAT_NO_ROWS_FOUND ) { /* not found */ /* execute the rule acGetUserByDN. By default this is a no-op but at some sites can be configured to run a process to determine a user by DN (for VO support) or possibly create the user. The stdout of the process is the irodsUserName to use. The corresponding rule would be something like this: acGetUserByDN(*arg,*OUT)||msiExecCmd(t,"*arg",null,null,null,*OUT)|nop */ ruleExecInfo_t rei; char *args[2]; msParamArray_t *myMsParamArray; msParamArray_t myInOutParamArray; memset( ( char* )&rei, 0, sizeof( rei ) ); rei.rsComm = rsComm; rei.uoic = &rsComm->clientUser; rei.uoip = &rsComm->proxyUser; args[0] = clientName; char out[200] = "*cmdOutput"; args[1] = out; rei.inOutMsParamArray = myInOutParamArray; myMsParamArray = ( msParamArray_t * ) malloc( sizeof( msParamArray_t ) ); memset( myMsParamArray, 0, sizeof( msParamArray_t ) ); statusRule = applyRuleArgPA( "acGetUserByDN", args, 2, myMsParamArray, &rei, NO_SAVE_REI ); #ifdef GSI_DEBUG printf( "acGetUserByDN status=%d\n", statusRule ); int i; for ( i = 0; i < myMsParamArray->len; i++ ) { char *r; msParam_t *myP; myP = myMsParamArray->msParam[i]; r = myP->label; printf( "l1=%s\n", r ); } #endif /* Try the query again, whether or not the rule succeeded, to see if the user has been added. */ memset( &genQueryInp, 0, sizeof( genQueryInp_t ) ); snprintf( condition1, MAX_NAME_LEN, "='%s'", clientName ); addInxVal( &genQueryInp.sqlCondInp, COL_USER_DN, condition1 ); addInxIval( &genQueryInp.selectInp, COL_USER_ID, 1 ); addInxIval( &genQueryInp.selectInp, COL_USER_TYPE, 1 ); addInxIval( &genQueryInp.selectInp, COL_USER_NAME, 1 ); addInxIval( &genQueryInp.selectInp, COL_USER_ZONE, 1 ); genQueryInp.maxRows = 2; status = rsGenQuery( rsComm, &genQueryInp, &genQueryOut ); } if ( status == 0 ) { char *myBuf; strncpy( rsComm->clientUser.userName, genQueryOut->sqlResult[2].value, NAME_LEN ); strncpy( rsComm->proxyUser.userName, genQueryOut->sqlResult[2].value, NAME_LEN ); strncpy( rsComm->clientUser.rodsZone, genQueryOut->sqlResult[3].value, NAME_LEN ); strncpy( rsComm->proxyUser.rodsZone, genQueryOut->sqlResult[3].value, NAME_LEN ); myBuf = ( char * )malloc( NAME_LEN * 2 ); snprintf( myBuf, NAME_LEN * 2, "%s=%s", SP_CLIENT_USER, rsComm->clientUser.userName ); putenv( myBuf ); free( myBuf ); // JMC cppcheck - leak } } if ( status == CAT_NO_ROWS_FOUND || genQueryOut == NULL ) { status = GSI_DN_DOES_NOT_MATCH_USER; rodsLog( LOG_NOTICE, "igsiServersideAuth: DN mismatch, user=%s, Certificate DN=%s, status=%d", rsComm->clientUser.userName, clientName, status ); snprintf( gsiAuthReqErrorMsg, sizeof gsiAuthReqErrorMsg, "igsiServersideAuth: DN mismatch, user=%s, Certificate DN=%s, status=%d", rsComm->clientUser.userName, clientName, status ); gsiAuthReqError = status; return status; } if ( status < 0 ) { rodsLog( LOG_NOTICE, "igsiServersideAuth: rsGenQuery failed, status = %d", status ); snprintf( gsiAuthReqErrorMsg, sizeof gsiAuthReqErrorMsg, "igsiServersideAuth: rsGenQuery failed, status = %d", status ); gsiAuthReqError = status; return status; } if ( noNameMode == 0 ) { if ( genQueryOut == NULL || genQueryOut->rowCnt < 1 ) { gsiAuthReqError = GSI_NO_MATCHING_DN_FOUND; return GSI_NO_MATCHING_DN_FOUND; } if ( genQueryOut->rowCnt > 1 ) { gsiAuthReqError = GSI_MULTIPLE_MATCHING_DN_FOUND; return GSI_MULTIPLE_MATCHING_DN_FOUND; } if ( genQueryOut->attriCnt != 3 ) { gsiAuthReqError = GSI_QUERY_INTERNAL_ERROR; return GSI_QUERY_INTERNAL_ERROR; } } else { if ( genQueryOut == NULL || genQueryOut->rowCnt < 1 ) { gsiAuthReqError = GSI_NO_MATCHING_DN_FOUND; return GSI_NO_MATCHING_DN_FOUND; } if ( genQueryOut->rowCnt > 1 ) { gsiAuthReqError = GSI_MULTIPLE_MATCHING_DN_FOUND; return GSI_MULTIPLE_MATCHING_DN_FOUND; } if ( genQueryOut->attriCnt != 4 ) { gsiAuthReqError = GSI_QUERY_INTERNAL_ERROR; return GSI_QUERY_INTERNAL_ERROR; } } #ifdef GSI_DEBUG printf( "Results=%d\n", genQueryOut->rowCnt ); #endif tResult = genQueryOut->sqlResult[0].value; #ifdef GSI_DEBUG printf( "0:%s\n", tResult ); #endif tResult = genQueryOut->sqlResult[1].value; #ifdef GSI_DEBUG printf( "1:%s\n", tResult ); #endif privLevel = LOCAL_USER_AUTH; clientPrivLevel = LOCAL_USER_AUTH; if ( strcmp( tResult, "rodsadmin" ) == 0 ) { privLevel = LOCAL_PRIV_USER_AUTH; clientPrivLevel = LOCAL_PRIV_USER_AUTH; } status = chkProxyUserPriv( rsComm, privLevel ); if ( status < 0 ) { return status; } rsComm->proxyUser.authInfo.authFlag = privLevel; rsComm->clientUser.authInfo.authFlag = clientPrivLevel; if ( noNameMode ) { /* We didn't before, but now have an irodsUserName */ int status2, status3; rodsServerHost_t *rodsServerHost = NULL; status2 = getAndConnRcatHost( rsComm, MASTER_RCAT, rsComm->myEnv.rodsZone, &rodsServerHost ); if ( status2 >= 0 && rodsServerHost->localFlag == REMOTE_HOST && rodsServerHost->conn != NULL ) { /* If the IES is remote */ status3 = rcDisconnect( rodsServerHost->conn ); /* disconnect*/ /* And clear out the connection information so getAndConnRcatHost will reconnect. This may leak some memory but only happens at most once in an agent: */ rodsServerHost->conn = NULL; /* And reconnect (with irodsUserName here and in the IES): */ status3 = getAndConnRcatHost( rsComm, MASTER_RCAT, rsComm->myEnv.rodsZone, &rodsServerHost ); if ( status3 ) { rodsLog( LOG_ERROR, "igsiServersideAuth failed in getAndConnRcatHost, status = %d", status3 ); return status3; } } } return status; #else status = GSI_NOT_BUILT_INTO_SERVER; rodsLog( LOG_ERROR, "igsiServersideAuth failed GSI_NOT_BUILT_INTO_SERVER, status = %d", status ); return status; #endif }