コード例 #1
0
static i4
line_get( char *prompt, 
	      char *def_line, i4  wild_flag, char *in_line ) 
{
	char    line[MAXLINE];
	char	ret = '\n';
	char	*p;
	i4	status = EOF;

	for(;;)
	{
		STATUS s;

		SIprintf(prompt);
		SIprintf( *def_line ? "(%s): " : ": ", def_line );

/* This is somewhat unusuall but does force the SIflush to work */
		SIflush(stdout);

	        s = ocfg_getrec( line, (i4)MAXLINE );

		if( s != OK || line[0] == '\033' )
			break;

		if (p = STindex(line, &ret, MAXLINE))
			*p = EOS;

		if( *def_line && !*line )
		{
			STcopy( def_line, in_line );
			SIprintf("\t\tDefault value: %s\n",in_line);
		}
		else
		{
			STcopy(line,in_line);
		}

	        STzapblank(in_line,in_line);

		if( !*in_line )
		{
			SIprintf("\t\tValue required, enter <ESC> to exit.\n");
			continue;
		}

		if(!STbcompare( in_line, 0, "*",0, TRUE ) )
		{
			if( !wild_flag )
			{
				SIprintf("\t\tValue required, enter <ESC> to exit.\n");
				continue;
			}
			in_line[0] = EOS;
		}

		status = OK;
		break;		/* There is valid data */
	}	/* end of FOR loop */
	return status;
}
コード例 #2
0
i4
main (int argc, char **argv) 
{
    STATUS status=OK;
    PTR drvH=NULL;
    char **list=NULL;
    ATTR_ID **attrList=NULL;
    char **defAttr=NULL;
    i4 count=0, attrCount = 0, retcount;
    i4 i;
    bool badCmdLine = FALSE, rmPkg = FALSE, has_default = FALSE, has_alt
        = FALSE, isReadOnly = FALSE, mgrSpecified = FALSE, batch = FALSE,
	def_or_alt=FALSE;
    i4 pathType = OCFG_SYS_PATH; 
    char altPath[OCFG_MAX_STRLEN] = "\0";
    char drvMgr[OCFG_MAX_STRLEN] = "\0";
    char line[MAXLINE],prompt[MAXLINE];
    char driverPath[OCFG_MAX_STRLEN];
    char *dirPath;
    char driverName[OCFG_MAX_STRLEN];
    char *ii_installation;
    char *p = NULL;
    char custName[OCFG_MAX_STRLEN];
    char etxt[512];

    ATTR_ID driverList[6] = 
    {
        { DRV_ATTR_DRIVER,          "\0" },
        { DRV_ATTR_DRIVER_ODBC_VER, DRV_STR_VERSION },
        { DRV_ATTR_DRIVER_READONLY, DRV_STR_N },
        { DRV_ATTR_DRIVER_TYPE,     DRV_STR_INGRES },
        { DRV_ATTR_VENDOR,          DRV_STR_INGRES_CORP },
        { DRV_ATTR_DONT_DLCLOSE,    DRV_STR_ONE }
    };
    int drvCount = sizeof(driverList) / sizeof(driverList[0]);

    ATTR_ID **drvList = (ATTR_ID **)MEreqmem( (u_i2) 0, 
	(u_i4)drvCount, TRUE, (STATUS *) NULL);

    for (i = 0; i < drvCount; i++)
    {
        drvList[i] = (ATTR_ID *)MEreqmem( (u_i2) 0, 
	    (u_i4)sizeof(ATTR_ID), TRUE, (STATUS *) NULL);
        drvList[i]->id = driverList[i].id;
        drvList[i]->value = (char *)MEreqmem( (u_i2) 0, 
    	    (u_i4)OCFG_MAX_STRLEN, TRUE, (STATUS *) NULL);
        STcopy(driverList[i].value, drvList[i]->value);
    }

    if ( argc > 7 )
        badCmdLine = TRUE;

    /*
    ** Parse the command line.  Reject invalid arguments.
    */
    if ( !badCmdLine && argc > 1 )
    {
	if (checkArgs("-h", argc, argv, NULL, NULL ) )
	{
	   display_help();
           PCexit(0);	
	}
	if (checkArgs("-help", argc, argv, NULL, NULL ) )
	{
	   display_help();
           PCexit(0);	
	}
        if ( checkArgs("-batch", argc, argv, NULL, NULL ) )
            batch = TRUE;
        if ( checkArgs("-rmpkg", argc, argv, NULL, NULL ) )
            rmPkg = TRUE;
        if (checkArgs("-r", argc, argv, NULL, NULL ) )
            isReadOnly = TRUE;
        if ( checkArgs("-p", argc, argv, altPath, NULL ) )
            pathType = OCFG_ALT_PATH;
        if ( checkArgs("-m", argc, argv, NULL, drvMgr ) )
			mgrSpecified = TRUE;
    }

    /*
    ** Set driver manager according to user input.  Default is unixODBC.
    */
    if (mgrSpecified && !STbcompare( drvMgr, 0, MGR_STR_CAI_PT, 0, TRUE ) )
        driverManager = MGR_VALUE_CAI_PT;
    else
	driverManager = MGR_VALUE_UNIX_ODBC;

    /*
    ** If none of the arguments are recognized, flag an error.
    */
    if ( !batch && !rmPkg && !isReadOnly && pathType != OCFG_ALT_PATH && !mgrSpecified && argc > 1)
        badCmdLine = TRUE;

    if ( badCmdLine )
    {
        display_help();
        PCexit(FAIL);
    }
    
    if ( isReadOnly )
        STcopy(DRV_STR_Y, drvList[2]->value); 
    else
        STcopy(DRV_STR_N, drvList[2]->value); 

    if ( !writeMgrFile( altPath ) )
    {
        SIprintf("Aborting due to error writing %s/files/%s\n",
           SYSTEM_LOCATION_SUBDIRECTORY, MGR_STR_FILE_NAME); 
        PCexit(FAIL);
    }
    defAttr = getDefaultInfo(); 
    if (defAttr == NULL)
    {
        SIprintf("Aborting due to error reading %s/install/%s\n",
            SYSTEM_LOCATION_VARIABLE, INFO_STR_FILE_NAME);
        PCexit(FAIL);
    }

    /*
    ** Get the path of the driver library and create the path/libname string.
    */
    NMgtAt(SYSTEM_LOCATION_VARIABLE,&dirPath);  /* usually II_SYSTEM */
    if (dirPath != NULL && *dirPath)
        STlcopy(dirPath,driverPath,sizeof(driverPath)-20-1);
    else
    {
        SIprintf("Error--%s is not defined\n",SYSTEM_LOCATION_VARIABLE);
        PCexit(FAIL);
    }
# ifdef VMS
    STcat(driverPath,"[");
    STcat(driverPath,SYSTEM_LOCATION_SUBDIRECTORY);  /* usually "ingres"  */
    STcat(driverPath,".library]");
    if ( isReadOnly )
        STcat(driverPath,defAttr[INFO_ATTR_RONLY_DRV_FNAME]);
    else
        STcat(driverPath,defAttr[INFO_ATTR_DRIVER_FILE_NAME]);
# else
    STcat(driverPath,"/");
    STcat(driverPath,SYSTEM_LOCATION_SUBDIRECTORY);  /* usually "ingres"  */
    STcat(driverPath,"/lib/");
    if ( isReadOnly )
        STcat(driverPath,defAttr[INFO_ATTR_RONLY_DRV_FNAME]);
    else
        STcat(driverPath,defAttr[INFO_ATTR_DRIVER_FILE_NAME]);
# endif /* ifdef VMS */
    STcopy(driverPath,drvList[0]->value);
    /*
    ** Initialize the cache from the odbcinst.ini file.
    */
    openConfig(NULL, pathType, altPath, &drvH, &status);
    if (status != OK)
    {
        STprintf(etxt,"Could not open from path %s.\n",
            pathType == OCFG_ALT_PATH ? altPath : "/usr/local/etc");
        display_err(etxt,status);
        PCexit(FAIL);
    }
    if (rmPkg)
    {
        delConfigEntry( drvH, defAttr[INFO_ATTR_DRIVER_NAME], &status );
        delConfigEntry( drvH, defAttr[INFO_ATTR_ALT_DRIVER_NAME], &status );
        closeConfig(drvH, &status);
        PCexit(OK);
    }
    /*
    ** Get the driver count.
    */
    retcount = listConfig( drvH, count, list, &status );
    if (status != OK)
    {
        STprintf(etxt,"Could not list drivers.\n");
        display_err(etxt,status);
        PCexit(FAIL);
    }
    count = retcount;
    if (count)
    {
        /*
        ** Get the list of recognized drivers.
        */
	list = (char **)MEreqmem( (u_i2) 0, 
	    (u_i4)(count * sizeof(char *)), TRUE, 
	    (STATUS *) NULL);
	for (i = 0; i < count; i++)
	    list[i] =  (char *)MEreqmem( (u_i2) 0, (u_i4)OCFG_MAX_STRLEN, 
	        TRUE, (STATUS *) NULL);
        listConfig( drvH, count, list, &status );
        if (status != OK)
        {
            STprintf(etxt,"Could not list drivers.\n");
            display_err(etxt,status);
            PCexit(FAIL);
        }
    }
    for (i = 0; i < count; i++)
    {
        def_or_alt = FALSE;
	if (!has_default)
	{
            has_default = STbcompare( list[i], 0, 
                defAttr[INFO_ATTR_DRIVER_NAME], 0, TRUE ) 
                   == 0 ? TRUE : FALSE;
            if (has_default)
                def_or_alt = TRUE; 
        }
        if (!has_alt)
        {
            has_alt = STbcompare( list[i], 0, 
                defAttr[INFO_ATTR_ALT_DRIVER_NAME], 0, 
                   TRUE ) == 0 ? TRUE : FALSE;
            if (has_alt)
                def_or_alt = TRUE; 
        }
        if (def_or_alt)
        {
            if ( !batch )
	    {
                STprintf(prompt,
         "\tInstallation has pre-defined version of %s.\n\tOverwrite? (Yes/No)", 
		list[i]);
                if ( line_get( prompt, "", FALSE, line ) == EOF )
                {
                    SIprintf("ODBC driver installation safely aborted\n");
                    PCexit(OK);
                }
                STzapblank(line,line);
                if ( line[0] != 'y' && line [0] != 'Y' )
                {
                    SIprintf( "%s left untouched\n", list[i] );
		    continue; 
                }
            } /* if (!batch) */
            STcopy(list[i],driverName);
            setConfigEntry( drvH, driverName, drvCount, drvList, &status );
            if (status != OK)
            {
                STprintf(etxt,"Could not write driver entry.\n");
                display_err(etxt,status);
                PCexit(FAIL);
            }
        } /* if (has_default || has_alt) */ 
        else if ( !batch )
        {
                STprintf(prompt,
         "\tInstallation has custom version of %s.\n\tDelete? (Yes/No)", 
		list[i]);
                if ( line_get( prompt, "", FALSE, line ) == EOF )
                {
                    SIprintf("ODBC driver installation safely aborted\n");
                    PCexit(OK);
                }
                STzapblank(line,line);
                if ( line[0] != 'y' && line [0] != 'Y' )
                {
                    SIprintf( "%s left untouched\n", list[i] );
                    continue;
                }
            STcopy(list[i],driverName);
            delConfigEntry( drvH, driverName, &status );
            if (status != OK)
            {
                STprintf(etxt,"Could not write driver entry.\n");
                display_err(etxt,status);
                PCexit(FAIL);
            } 
        } /* if (!batch) && !has_default */
    } /* for (count... */
    if (!has_default) 
    {
        setConfigEntry( drvH, defAttr[INFO_ATTR_DRIVER_NAME], drvCount,
	    drvList, &status );
        if (status != OK)
        {
            STprintf(etxt,"Could not write driver entry.\n");
            display_err(etxt,status);
            PCexit(FAIL);
        }
    }
    if (!has_alt) 
    {
        setConfigEntry( drvH, defAttr[INFO_ATTR_ALT_DRIVER_NAME], drvCount,
	    drvList, &status );
        if (status != OK)
        {
            STprintf(etxt,"Could not write driver entry.\n");
            display_err(etxt,status);
            PCexit(FAIL);
        }
    }
    closeConfig(drvH, &status);
    if (status != OK)
    {
        STprintf(etxt,"Could not close driver info.\n");
        display_err(etxt,status);
        PCexit(FAIL);
    }
    if (count)
    {
        for (i = 0; i < count; i++)
	    MEfree((PTR)list[i]);
        MEfree((PTR)list);
    }
    for (i = 0; i < drvCount; i++)
    {
        MEfree((PTR)drvList[i]->value);
        MEfree((PTR)drvList[i]);
    }
    MEfree((PTR)drvList);

    PCexit(OK);
}
コード例 #3
0
STATUS
gca_ns_resolve( char *target, char *user, char *password,
		char *rem_user, char *rem_pass, GCA_RQCB *rqcb )
{
#ifdef GCF_EMBEDDED_GCN

    GCA_RQNS		*ns = &rqcb->ns;
    GCN_RESOLVE_CB	*grcb;
    char		uid[ GC_USERNAME_MAX + 1 ];
    char		*puid = uid;
    char		empty[ 1 ] = { '\0' };
    STATUS		status;
    i4			i;

    /*
    ** Allocate the embedded Name Server interface control block
    ** and save it in the request control block to provide storage
    ** for the resolved values.
    */
    if ( ! rqcb->grcb  &&  ! (rqcb->grcb = gca_alloc(sizeof(GCN_RESOLVE_CB))) )
	return( E_GC0013_ASSFL_MEM );

    grcb = (GCN_RESOLVE_CB *)rqcb->grcb;

    /*
    ** Default local username and password if required.
    ** Only use the provided info if both a username and
    ** password are provided.
    */
    IDname( &puid );
    STzapblank( uid, uid );

    if ( ! user )  user = empty;
    if ( ! password )  password = empty;

    if ( ! user[0]  ||  ! password[ 0 ] )
    {
	user = uid;
	password = empty;
    }

    /*
    ** Validate username and password if attempt is
    ** made to change the user's ID.  This would
    ** normally be done in the Name Server GCA_LISTEN.
    */
    if ( user != uid  &&  STcompare( user, uid ) )
    {
	CL_ERR_DESC sys_err;
	status = GCusrpwd( user, password, &sys_err );
	if ( status != OK )  return( status );
    }

    /*
    ** Setup input parameters to Name Database interface.
    */
    STcopy( target, grcb->target );
    STcopy( user, grcb->user );

    if ( rem_user  &&  rem_pass )
    {
	/*
	** Use the requested remote username and password.
	*/
	grcb->gca_message_type = GCN_NS_2_RESOLVE;
	STcopy( rem_user, grcb->user_in ); 
	STcopy( rem_pass, grcb->passwd_in );
    }
    else
    {
	/*
	** Use the local username and password.
	*/
	grcb->gca_message_type = GCN_NS_RESOLVE;
	STcopy( user, grcb->user_in ); 
	STcopy( password, grcb->passwd_in );
    }

    /*
    ** Call embedded Name Server to resolve the target.
    */
    if ( 
	 (status = gcn_rslv_parse( grcb ))  == OK  &&
         (status = gcn_rslv_server( grcb )) == OK  &&
         (status = gcn_rslv_node( grcb ))   == OK  &&
         (status = gcn_rslv_login( grcb ))  == OK 
       )
    {

#ifdef WIN16
   	gcpasswd_prompt(grcb->user_out, grcb->passwd_out, grcb->vnode);
#endif /* WIN16 */

	/*
	** Return resolved info.  The new partner ID should
	** have the vnode removed, but still retain the server
	** class.  We use the grcb as static storage to rebuild
	** the partner ID from the dbname and class components.
	*/
	ns->svr_class = grcb->class ? grcb->class : "";
	ns->username = grcb->user_out ? grcb->user_out : "";
	ns->password = grcb->passwd_out ? grcb->passwd_out : "";
	ns->rmt_dbname = grcb->target;

	STprintf( grcb->target, "%s%s%s", 
		  grcb->dbname ? grcb->dbname : "", 
		  ns->svr_class[0] ? "/" : "", ns->svr_class );

	for( i = 0, ns->lcl_count = grcb->catl.tupc; i < ns->lcl_count; i++ )
	    ns->lcl_addr[ i ] = grcb->catl.tupv[ i ];

	for( i = 0, ns->rmt_count = grcb->catr.tupc; i < ns->rmt_count; i++ )
	{
	    char *pv[3];

	    gcu_words( grcb->catr.tupv[ i ], NULL, pv, ',', 3 );

	    ns->node[ i ] = pv[ 0 ];
	    ns->protocol[ i ] = pv[ 1 ];
	    ns->port[ i ] = pv[ 2 ];
	}
	
	if ( ! ns->lcl_count )  status = E_GC0021_NO_PARTNER;
    }
コード例 #4
0
II_EXTERN IIAPI_MSG_BUFF *
IIapi_createGCNOper( IIAPI_STMTHNDL *stmtHndl )
{
    IIAPI_MSG_BUFF	*msgBuff;
    u_i1		*msg;
    char		*str, temp[ 512 ];
    i4			val;
    IIAPI_CONNHNDL	*connHndl = IIapi_getConnHndl((IIAPI_HNDL *)stmtHndl);
    API_PARSE		*parse = (API_PARSE *)stmtHndl->sh_queryText;
    
    IIAPI_TRACE( IIAPI_TR_VERBOSE )
	( "IIapi_createGCNOper: creating GCN Oper message\n" );
    
    if ( ! connHndl )
    {
	IIAPI_TRACE( IIAPI_TR_FATAL )
	    ( "IIapi_createGCNOper: can't get connHndl from stmtHnd\n" );
	return( NULL );
    }

    if ( ! (msgBuff = IIapi_allocMsgBuffer( (IIAPI_HNDL *)connHndl )) )
	return( NULL );

    msgBuff->msgType = GCN_NS_OPER;
    msg = msgBuff->data + msgBuff->length;

    /*
    ** Set the operations flags.
    **
    ** Netutil always sets the merge flag when adding
    ** nodes, so we will too.  
    **
    ** The user ID flag is set if a username was given
    ** for IIapi_connect() but no password.  The Name
    ** Server will reject the request if current user
    ** not authorized.
    ** 
    ** The public flag is set for global values.
    **
    ** The network database flag is set for non-server
    ** requests.
    **
    ** We currently don't support the sole server flag.
    ** The merge flag is only marginally supported.
    ** These flags are mostly used for adding servers,
    ** which is currently only supported as an 
    ** undocumented feature.
    */
    val = GCN_DEF_FLAG;				/* gcn_flag */

    if ( parse->opcode == API_KW_ADD  && 
	( parse->object == API_KW_NODE || parse->object == API_KW_ATTR ) )  
	val |= GCN_MRG_FLAG;

    if ( connHndl->ch_username  &&  ! connHndl->ch_password )  
	val |= GCN_UID_FLAG;

    if ( parse->type == API_KW_GLOBAL )  val |= GCN_PUB_FLAG;
    if ( parse->object != API_KW_SERVER )  val |= GCN_NET_FLAG;

    I4ASSIGN_MACRO( val, *msg );
    msg += sizeof( i4 );
    msgBuff->length += sizeof( i4 );

    switch( parse->opcode )			/* gcn_opcode */
    {
	case API_KW_ADD :  val = GCN_ADD;  break;
	case API_KW_DEL :  val = GCN_DEL;  break;
	case API_KW_GET :  val = GCN_RET;  break;

	default :	/* This should not happen! */
	    IIAPI_TRACE( IIAPI_TR_FATAL )
		( "IIapi_createGCNOper: invalid operations code.\n" );
	    val = GCN_RET;
	    break;
    }

    I4ASSIGN_MACRO( val, *msg );
    msg += sizeof( i4 );
    msgBuff->length += sizeof( i4 );

    /*
    ** Installation ID is currently ignored.
    */
    val = STlength( install_id ) + 1;		/* gcn_install.gcn_l_item */
    I4ASSIGN_MACRO( val, *msg );
    msg += sizeof( i4 );
    msgBuff->length += sizeof( i4 );

    MEcopy( install_id, val, msg );		/* gcn_install.gcn_value */
    msg += val;
    msgBuff->length += val;

    val = 1;					/* gcn_tup_cnt */
    I4ASSIGN_MACRO( val, *msg );
    msg += sizeof( i4 );
    msgBuff->length += sizeof( i4 );

    /*
    ** Node and connection operations have fixed types
    ** defined by GCN.  For server operations, the server
    ** class is used as provided by the application.
    */
    switch( parse->object )
    {
	case API_KW_NODE :  str = GCN_NODE;	break;
	case API_KW_LOGIN : str = GCN_LOGIN;	break;
	case API_KW_ATTR :  str = GCN_ATTR;	break;

	case API_KW_SERVER :
	    str = ns_resolve_param( parse, API_FIELD_OBJ, FALSE );
	    break;

	default :	/* Should not happen! */
	    IIAPI_TRACE( IIAPI_TR_TRACE )
		( "IIapi_createGCNOper: invalid object.\n" );
	    str = empty;
	    break;
    }

    /*
    ** Build the GCN tuple.
    */
    val = STlength( str ) + 1;			/* gcn_type.gcn_l_item */
    I4ASSIGN_MACRO( val, *msg );
    msg += sizeof( i4 );
    msgBuff->length += sizeof( i4 );

    MEcopy( str, val, msg );			/* gcn_type.gcn_value */
    msg += val;
    msgBuff->length += val;

    /*
    ** Use username if specified.  This will
    ** either be the username we are connected
    ** with (if password also provided) or it
    ** will be the username for the GCN_UID_FLAG
    ** which requires special privileges for the
    ** current user.  Otherwise, we use the user
    ** ID of the current process.
    */
    if ( connHndl->ch_username )
	str = connHndl->ch_username;
    else
    {
	if ( ! uid[0] )
	{
	    IDname( &puid );
	    STzapblank( uid, uid );
	}

	str = uid;
    }

    val = STlength( str ) + 1;			/* gcn_uid.gcn_l_item */
    I4ASSIGN_MACRO( val, *msg );
    msg += sizeof( i4 );
    msgBuff->length += sizeof( i4 );

    MEcopy( str, val, msg );			/* gcn_uid.gcn_value */
    msg += val;
    msgBuff->length += val;

    str = ns_resolve_param( parse, API_FIELD_VNODE, 
			    (parse->opcode != API_KW_ADD) );

    val = STlength( str ) + 1;			/* gcn_obj.gcn_l_item */
    I4ASSIGN_MACRO( val, *msg );
    msg += sizeof( i4 );
    msgBuff->length += sizeof( i4 );

    MEcopy( str, val, msg );			/* gcn_obj.gcn_value */
    msg += val;
    msgBuff->length += val;

    /*
    ** The tuple value must be built up from various parameters 
    ** and can be function and object dependent.  Call appropriate
    ** function for the current request to process the parameters.
    **
    ** Pass in our temp buffer.  It will be used if large enough
    ** or a different buffer will be allocated and returned. Check
    ** for memory allocation failures and free the returned buffer
    ** if it is not the one passed in (after copying the value).
    */
    if ( ! (str = (*parse->parms->parms)( parse, sizeof( temp ), temp )) )
    {
	IIapi_freeMsgBuffer( msgBuff );
	return( NULL );
    }

    val = STlength( str ) + 1;			/* gcn_val.gcn_l_item */
    I4ASSIGN_MACRO( val, *msg );
    msg += sizeof( i4 );
    msgBuff->length += sizeof( i4 );

    MEcopy( str, val, msg );			/* gcn_val.gcn_value */
    msgBuff->length += val;
    if ( str != temp )  MEfree( (PTR)str );

    msgBuff->flags = IIAPI_MSG_EOD;
    return( msgBuff );
}
コード例 #5
0
ファイル: scsmntr.c プロジェクト: saqibjamil/Ingres
/*{
** Name: scs_monitor	- Implement the SCS part of the monitor task
**
** Description:
**	This routine is called ala the regular thread processing routine.
**	It parses its input, decides what to do, and returns the output.
**
**	The commmands completely interpreted here are:
**
**		set server shut	(CS_CLOSE)
**			Disallow new connections, shutdown when
**			last current session exits.
**          
**          	remove SESSION
**          	    	New improved "safe" version, acts the same
**  	    	    	as front-end exiting and dropping GCA connection.
**	
**		kill SESSION
**			Signal CS_KILL_EVENT to a user session actively
**			running a query.
**          
**	NEW:
**		set server closed
**			Disallow new regular user sessions.
**          
**		set server open
**			Reallow new regular user sessions.  Cancel
**			any pending 'set server shut' shutdown.
**
**		show server listen
**
**		crash session SESSIONID
**
**	Commands partially handled here and partially in CSmonitor are:
**
**		stop server	(CS_KILL)
**			Kill user sessions, shutdown when they're gone.
**          
**		stop server conditional (CS_COND_CLOSE)
**			Shutdown if no sessions, which never works because
**			this session always exists.
**          
**		crash server	(CS_CRASH)
**			Take the server down immediately.
**
**	All other commands are passed to CSmonitor for handling.
**
** Inputs:
**	mode				Mode of operation
**					    CS_INPUT, _OUPUT, ...
**	scb				Sessions control block to monitor
**	*command			Text of the command
**	powerful			Is this user powerful
**	output_fcn			Function to call to perform the output.
**					This routine will be called as
**					    (*output_fcn)(newline_present,
**							    length,
**							    buffer)
**					where buffer is the length character
**					output string, and newline_present
**					indicates whether a newline needs to
**					be added to the end of the string.
**
** Outputs:
**	next_mode			As above.
**	Returns:
**	    OK
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**	26-Jul-1993 (daveb)
**	    created.
**	15-Sep-1993 (daveb)
**	    ifdef out all but drop connection for now.
**	1-Nov-1993 (daveb)
**	    Match LRC proposal.  Drop becomes remove, remove becomes kill.
**      10-Nov-1993 (daveb)
**          Match approved proposal.  Kill becomes "crash session SESSIONID"
**	15-dec-93 (robf)
**          Add prototype "broadcast" message request.
**	4-mar-94 (robf)
**          Add initial security auditing to iimonitor events.
**	12-dec-1996 (canor01)
**	    Add support for sampler thread.
**	24-Apr-2003 (jenjo02)
**	    Added "kill" command to abort eligible queries
**	    while leaving the session intact, SIR 110141.
**	17-Sep-2004 (schka24)
**	    Manual fix to remove command so that it fires.
**      05-may-2005 (horda03) Bug 114453/INGSRV 3290
**          For server/session changes log the command.
**      22-may-2007 (horda03) Bug 117966
**          Log the command before calling CSmonitor, as
**          the CS could be crashing the server.
**      23-Sep-2009 (hanal04) Bug 115316
**          Added "SHOW SERVER CAPABILITIES".
*/
static STATUS
scs_monitor( i4 mode, CS_SCB *scb, i4 *nmode, char *command,
	    i4 powerful, i4 (*output_fcn)(PTR, i4, char *) )
{
    STATUS		ret_stat;
    char		buf[81];
    bool		completely_done;
    PTR			ptr_scb;
    SCD_SCB		*an_scb;
    i4                  log_cmd = 0;
    i4                  local_error;
    SCD_SCB		*my_scb = (SCD_SCB*)scb;
    
    *nmode = CS_EXCHANGE;
    completely_done = FALSE;
    ret_stat = OK;
    
    switch (mode)
    {
    case CS_INITIATE:
	*nmode = CS_INPUT;
	break;
	
    case CS_TERMINATE:
	break;
	
    case CS_INPUT:
		
	CVlower(command);
	if (STscompare("setservershut", 0, command, 0) == 0)
	{
	    /* Audit log the attempt here? */
	    if (!powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser status required to stop servers");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_FAIL,
			    I_SX274D_SET_SERVER_SHUT
			    );
	    }
	    else /* disallow regular listens, exit when last conn exits */
	    {
		Sc_main_cb->sc_listen_mask = 
		    (SC_LSN_TERM_IDLE |SC_LSN_SPECIAL_OK) ;
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Server will stop. %d. sessions remaining",
			 Sc_main_cb->sc_current_conns );
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_SUCCESS,
			    I_SX274D_SET_SERVER_SHUT
			    );
                log_cmd = 1;
	    }
	    completely_done = TRUE;
	}
	else if (STscompare("setserverclosed", 0, command, 0) == 0)
	{
	    /* Audit log the attempt here? */
	    if (!powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser status required to disable connections");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_FAIL,
			    I_SX2748_SET_SERVER_CLOSED
			    );
	    }
	    else		/* Disallow regular listens */
	    {
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_SUCCESS,
			    I_SX2748_SET_SERVER_CLOSED
			    );
		Sc_main_cb->sc_listen_mask &= (~SC_LSN_REGULAR_OK);
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "User connections now disabled" );
                log_cmd = 1;
	    }
	    completely_done = TRUE;
	}
	else if (STscompare("setserveropen", 0, command, 0) == 0)
	{
	    /* Audit log the attempt here? */
	    if (!powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser status required to enable connections");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_FAIL,
			    I_SX2749_SET_SERVER_OPEN
			    );
	    }
	    else  /* allow all listens, cancel any impending shutdown */
	    {
		Sc_main_cb->sc_listen_mask =
		    (SC_LSN_REGULAR_OK | SC_LSN_SPECIAL_OK);
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "User connections now allowed" );
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_SUCCESS,
			    I_SX2749_SET_SERVER_OPEN
			    );
                log_cmd = 1;
	    }
	    completely_done = TRUE;
	}
	else if (STncasecmp("broadcast", command, 9) == 0)
	{
	    /* Audit log the attempt here? */
	    if (!powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser status required to broadcast messages");
	    }
	    else  
	    {
		/*
		** Broadcast the message to any connected sessions
		*/
		scs_scan_scbs(scs_broadcast_mesg, (PTR)(command+10));
	    }
	    completely_done = TRUE;
	}
	else if (STscompare("stopserverconditional", 0, command, 0) == 0 ||
		 STscompare("stopserver", 0, command, 0) == 0 ||
		 STscompare("crashserver", 0, command, 0) == 0 )
	{
	    /* Audit log the attempt here? */
	    if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		scs_mon_audit((SCD_SCB*)scb, 
			powerful?
			    SXF_A_CONTROL|SXF_A_SUCCESS:
			    SXF_A_CONTROL|SXF_A_FAIL,         /* Action */
			I_SX274A_STOP_SERVER
			);
                log_cmd = powerful;
	}
        else if (STscompare("showservercapabilities", 0, command, 0) == 0)
        {
            TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%v",
                     SC_CAPABILITIES_FLAGS, Sc_main_cb->sc_capabilities );
            completely_done = TRUE;
        }
	else if (STscompare("showserverlisten", 0, command, 0) == 0)
	{
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%s", 
		     Sc_main_cb->sc_listen_mask & SC_LSN_REGULAR_OK ?
		     "OPEN" : "CLOSED" );
	    completely_done = TRUE;
	}
	else if (STscompare("showservershutdown", 0, command, 0) == 0)
	{
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1, "%s", 
		     Sc_main_cb->sc_listen_mask & SC_LSN_TERM_IDLE ?
		     "PENDING" : "OPEN" );
	    completely_done = TRUE;
	}
# ifdef NOT_SUPPORTED
	else if (STscompare("showconnections", 0, command, 0) == 0 )
	{
	    scs_scan_scbs( scs_show_func, (PTR)&powerful );
	    completely_done = TRUE;
	}
	else if (STscompare("show connection", 15, command, 15) == 0 )
	{
	    completely_done = TRUE;
	    STzapblank(command, command);
	    if (CVaxptr(command + 14, &ptr_scb) ||
		!scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) )
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Invalid connection id");
		break;
	    }
	    scs_show_func( an_scb, &powerful );
	}
# endif
	else if (STscompare("remove", 6, command, 6) == 0)
	{
	    completely_done = TRUE;
	    STzapblank(command, command);
	    if (CVaxptr(command + 6, &ptr_scb) || scb == NULL ||
		!scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) ||
		an_scb == my_scb )
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Invalid session id");
		break;
	    }
	    if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username,
		       sizeof(scb->cs_username))) && !powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser or owner status required to remove session");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			    SXF_A_CONTROL|SXF_A_FAIL,
			    I_SX274B_REMOVE_SESSION
			    );
		break;
	    }
	    if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		scs_mon_audit((SCD_SCB*)scb, 
			SXF_A_CONTROL|SXF_A_SUCCESS,
			I_SX274B_REMOVE_SESSION
			);
	    scs_remove_sess( an_scb );
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
		     "Session %p removed", an_scb);
            log_cmd = 1;
	}
	else if (STscompare("crash session", 13, command, 13) == 0)
	{
	    completely_done = TRUE;
	    STzapblank(command, command);
	    if (CVaxptr(command + 12, &ptr_scb) || scb == NULL ||
		!scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) ||
		an_scb == my_scb )
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Invalid session id");
		break;
	    }
	    if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username,
		       sizeof(scb->cs_username))) && !powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser or owner status required to crash session");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			SXF_A_CONTROL|SXF_A_FAIL,
			I_SX274C_CRASH_SESSION
			);
		break;
	    }
	    if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		scs_mon_audit((SCD_SCB*)scb, 
			SXF_A_CONTROL|SXF_A_SUCCESS,
			I_SX274C_CRASH_SESSION
			);
	    scs_crash_sess( an_scb );
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
		     "Session %p crashed", an_scb);
            log_cmd = 1;
	}
	else if (STscompare("kill", 4, command, 4) == 0)
	{
	    completely_done = TRUE;
	    STzapblank(command, command);
	    if (CVaxptr(command + 4, &ptr_scb) || scb == NULL ||
		!scs_is_user_scb( (an_scb = (SCD_SCB *)ptr_scb) ) ||
		an_scb == my_scb )
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Invalid session id");
	    }
	    else if ((MEcmp(an_scb->cs_scb.cs_username, scb->cs_username,
		       sizeof(scb->cs_username))) && !powerful)
	    {
		TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			 "Superuser or owner status required to kill query");
		if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
		    scs_mon_audit((SCD_SCB*)scb, 
			SXF_A_CONTROL|SXF_A_FAIL,
			I_SX2755_KILL_QUERY
			);
	    }
	    else switch ( an_scb->scb_sscb.sscb_qmode )
	    {
		case 0:
		    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			    "Session %p is not executing a query", an_scb);
		    break;

		/* Honor only "meaningful" types of queries: */
		case PSQ_RETRIEVE:
		case PSQ_RETINTO:
		case PSQ_APPEND:
		case PSQ_REPLACE:
		case PSQ_DELETE:
		case PSQ_COPY:
		case PSQ_MODIFY:
		case PSQ_EXECQRY:
		case PSQ_EXCURS:
		case PSQ_CALLPROC:
		case PSQ_REPCURS:
		case PSQ_RETCURS:
		case PSQ_EXEDBP:
		case PSQ_REGPROC:
		case PSQ_DDEXECPROC:
		case PSQ_CREATE:
		    if ( an_scb->scb_sscb.sscb_force_abort ||
			 an_scb->scb_sscb.sscb_interrupt )
		    {
			TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			     "Session %p query already aborting", an_scb);
		    }
		    else
		    {
			scs_kill_query( an_scb );
			if ( Sc_main_cb->sc_capabilities & SC_C_C2SECURE )
			    scs_mon_audit((SCD_SCB*)scb, 
				    SXF_A_CONTROL|SXF_A_SUCCESS,
				    I_SX2755_KILL_QUERY
				    );
			TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
				 "Session %p query killed", an_scb);
		    }
		    break;

		default:
		    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
			     "Session %p query cannot be killed", an_scb);
		    break;
	    }
	}
# ifdef NOT_SUPPORTED
	else if (STscompare("help", 0, command, 0) == 0)
	{
	    TRformat(output_fcn, 1, buf, sizeof(buf) - 1,
		     "SCS monitor commands:\nset server shut\nset server closed\nset server open\nshow server listen\nshow server shutdown\nremove SESSION\ncrash session SESSION\n\nCS monitor commands:\n");
	}
# endif
        else if (! CS_is_mt())
	    /* OS Thread version will start an OS thread in the CS */
            if ((STscompare("start sampling", 14, command, 14) == 0))
            {
                if (!powerful)
                {
                    TRformat(output_fcn, (i4 *) 1, buf, sizeof(buf)-1,
                        "Superuser status required to start sampling.", 0L);
                }
                else
                {
                    GCA_LS_PARMS        local_crb;
	            CL_ERR_DESC         errdesc;

                    local_crb.gca_status = 0;
                    local_crb.gca_assoc_id = 0;
                    local_crb.gca_size_advise = 0;
                    local_crb.gca_user_name = "<Sampler Thread>";
                    local_crb.gca_account_name = 0;
                    local_crb.gca_access_point_identifier = "NONE";
                    local_crb.gca_application_id = 0;

		    /* set up all the CS control blocks for the sampler */
	            ret_stat = CSmonitor( mode, scb, nmode, command,
				          powerful, output_fcn );

		    if ( ret_stat == OK )
                        ret_stat = CSadd_thread(CS_LIM_PRIORITY-1, (PTR) &local_crb,
                                                SCS_SSAMPLER, (CS_SID*)NULL, &errdesc);

                    if (ret_stat)
                    {
                        TRformat(output_fcn, (i4 *) 1, buf, sizeof(buf)-1,
                               "Sampling failed to start.");
                    }
                }
            }

        /* log the command before calling CSmonitor(), as the server could be left in an
        ** unknown state if the command CRASH SERVER or STOP SERVER are used
        */

        if (log_cmd)
        {
           ule_format( I_SC051E_IIMONITOR_CMD, 0, ULE_LOG, NULL, 0, 0, 0, &local_error,
                       3, STlength(command), command,
                       DB_OWN_MAXNAME, &((SCD_SCB *)scb)->scb_sscb.sscb_ics.ics_rusername,
                       sizeof(DB_TERM_NAME), &((SCD_SCB *)scb)->scb_sscb.sscb_ics.ics_terminal, 
                       0, 0);
        }

	if( !completely_done )
	    ret_stat = CSmonitor( mode, scb, nmode, command,
				 powerful, output_fcn );
	break;
	
    case CS_OUTPUT:
	break;
    }

    return( ret_stat );
}
コード例 #6
0
ファイル: scuxsvc.c プロジェクト: saqibjamil/Ingres
/*{
** Name: scu_xencode - encrypt a character string
**
** Description:
**      This function uses CI routines to encrypt a character string.
**	Since the character string is used to generate the key schedule,
**	the encryption is essentially one-way (you'd need to know the
**	password to decode the password....)  This routine was designed
**	to encrypt application_id passwords.
**
** Inputs:
**      SCU_XENCODE			the opcode to scf_call()
**      scf_cb                          control block in which is specified
**          .scf_ptr_union.scf_xpassword
**			                pointer to buffer to be encrypted
**          .scf_nbr_union.scf_xpasskey
**			                pointer to seed for key schedule
**          .scf_len_union.scf_xpwdlen
**					length of password and key seed
**
** Outputs:
**      scf_cb                          the same control block
**          .error                      the error control area
**              .err_code               E_SC_OK or ...
**					E_SC0261_XENCODE_BAD_PARM
**					E_SC0262_XENCODE_BAD_RESULT
**	Returns:
**	    E_DB_{OK, WARNING, ERROR, FATAL}
**	Exceptions:
**	    none
**
** Side Effects:
**	    none
**
** History:
**	24-mar-89 (ralph)
**          Written for terminator
**	20-may-89 (ralph)
**	    Changed encryption to use separate key
**	06-jun-89 (ralph)
**	    Fixed unix compile problems
**	06-may-1993 (ralph)
**	    DELIM_IDENT:
**	    Translate key seed to lower case prior to encryption.
**	2-Jul-1993 (daveb)
**	    prototyped.
**	14-jul-93 (ed)
**	    replacing <dbms.h> by <gl.h> <sl.h> <iicommon.h> <dbdbms.h>
**	12-Sep-2007 (drivi01)
**	    Modified scu_xencode function to fix numerous bugs.
**	    The buffers for password manipulation shouldn't exceed
**	    the size of scb_xpassword field in SCF control block,
**	    otherwise the data will be truncated.
*/
DB_STATUS
scu_xencode(SCF_CB *scf_cb, SCD_SCB *scb )
{
    STATUS	status;
    CI_KS	KS;
    char	inbuffer[DB_PASSWORD_LENGTH+1];
    char	outbuffer[DB_PASSWORD_LENGTH+1];
    char	keybuffer[DB_PASSWORD_LENGTH];
    u_i2	i2_size;
    i4		longnat_size;
    i4		nat_size;
    char	*char_ptr;

#define	PASSINIT    "hjodvwHOJHOJhodh498032&*&*#)$&*jpkshghjlg58925fjkdjkpg"

    status = E_DB_OK;
    CLRDBERR(&scf_cb->scf_error);

    /* Ensure input parameter is okay */

    if ((scf_cb->scf_len_union.scf_xpwdlen <= 0)		||
	(scf_cb->scf_len_union.scf_xpwdlen >= sizeof(inbuffer)) ||
	(scf_cb->scf_nbr_union.scf_xpasskey  == NULL)		||
	(scf_cb->scf_ptr_union.scf_xpassword == NULL))
    {
	sc0ePut(NULL, E_SC0261_XENCODE_BAD_PARM, NULL, 0);
	SETDBERR(&scf_cb->scf_error, 0, E_SC0261_XENCODE_BAD_PARM);
	return(E_DB_ERROR);
    }


    /* Copy string to input buffer */

    MEmove(scf_cb->scf_len_union.scf_xpwdlen,
		 (PTR)scf_cb->scf_ptr_union.scf_xpassword,
		 (char)'\0',
		 sizeof(inbuffer),
		 (PTR)inbuffer);

    /* Copy key to key buffer */

    MEmove(scf_cb->scf_len_union.scf_xpwdlen,
		 (PTR)scf_cb->scf_nbr_union.scf_xpasskey,
		 (char)'?',
		 sizeof(keybuffer),
		 (PTR)keybuffer);

    /* Fold the key to lower case */

    for (nat_size = sizeof(keybuffer), char_ptr = keybuffer;
	 nat_size > 0;
	 nat_size = CMbytedec(nat_size, char_ptr), char_ptr = CMnext(char_ptr))
    {
	CMtolower(char_ptr, char_ptr);
    }

	 

    /* Remove white space from input string */

    nat_size = STzapblank(inbuffer, outbuffer);

    /* Check size */

    if ((nat_size <= 0) ||
	(nat_size > sizeof(outbuffer)-1))
    {
	sc0ePut(NULL, E_SC0261_XENCODE_BAD_PARM, NULL, 0);
	SETDBERR(&scf_cb->scf_error, 0, E_SC0261_XENCODE_BAD_PARM);
	return(E_DB_ERROR);
    }

    /* Initialize input buffer to "garbage" */

    MEmove(sizeof(PASSINIT), (PTR)PASSINIT, (char)'?',
		 sizeof(inbuffer), (PTR)inbuffer);

    /* Normalize the string back into input buffer */

    MEcopy((PTR)outbuffer, nat_size, (PTR)inbuffer);

    /* Reset output buffer to blanks */

    MEfill(sizeof(outbuffer),
		 (u_char)' ',
		 (PTR)outbuffer);

    /*
    ** First, encrypt the key seed using the string to encode.
    ** Then,  encrypt the string using the encrypted seed.
    ** This is done to prevent two roles with the same password
    ** from having the same encrypted value.
    ** Note that this makes the encryption one-way, since
    ** the password must be provided to decrypt the password!
    */

    /* Generate the key schedule to encrypt the key seed */

    (VOID)CIsetkey((PTR)inbuffer, KS);

    /* Encrypt the key seed */

    longnat_size = DB_PASSWORD_LENGTH;
    (VOID)CIencode((PTR)keybuffer, longnat_size, KS, (PTR)outbuffer);

    /* Generate the second key schedule */

    (VOID)CIsetkey((PTR)keybuffer, KS);

    /* Encode the string */

	longnat_size = DB_PASSWORD_LENGTH;
    (VOID)CIencode((PTR)inbuffer, longnat_size, KS, (PTR)outbuffer);

    /* Make sure it was really encoded */

    if ((char *)STskipblank(outbuffer, (i4)sizeof(outbuffer))
		!= NULL)
    {
	/* It was; copy result to caller's area */

	i2_size = scf_cb->scf_len_union.scf_xpwdlen;
	MEmove(sizeof(outbuffer), (PTR)outbuffer, (char)' ',
		     i2_size, (PTR)scf_cb->scf_ptr_union.scf_xpassword);
    }
    else
    {
	/* The encryption did not work; return an error */

	sc0ePut(NULL, E_SC0262_XENCODE_BAD_RESULT, NULL, 0);
	SETDBERR(&scf_cb->scf_error, 0, E_SC0262_XENCODE_BAD_RESULT);
	status = E_DB_ERROR;
    }

    return(status);
}