Exemplo n.º 1
0
II_EXTERN II_VOID
IIapi_loadNSColumns
( 
    IIAPI_STMTHNDL	*stmtHndl, 
    IIAPI_GETCOLPARM	*getColParm,
    IIAPI_GCN_REQ_TUPLE	*tuple 
)
{
    IIAPI_DESCRIPTOR	*descr;
    IIAPI_DATAVALUE	*value;
    API_PARSE		*parse = (API_PARSE *)stmtHndl->sh_queryText;
    char		buffer[ API_NS_MAX_LEN ];
    char		*str, *val[ 3 ];
    u_i2		len;

    IIAPI_TRACE( IIAPI_TR_VERBOSE )
	( "IIapi_loadNSColumns: %d columns starting at %d, %d total columns\n",
	  (II_LONG)stmtHndl->sh_colFetch,
	  (II_LONG)stmtHndl->sh_colIndex,
	  (II_LONG)stmtHndl->sh_colCount );

    /*
    ** Some columns are combined in the returned
    ** GCN value field.  Break out the combinded
    ** columns for reference below.  We don't
    ** expect to overflow the buffer, but just
    ** in case we truncate the input.
    */
    if ( tuple->gcn_val.gcn_l_item > (sizeof( buffer ) - 1) )
	tuple->gcn_val.gcn_value[ sizeof( buffer ) - 1 ] = EOS;
    gcu_words( tuple->gcn_val.gcn_value, buffer, val, ',', 3 );

    descr = &stmtHndl->sh_colDescriptor[ stmtHndl->sh_colIndex ];
    value = &getColParm->gc_columnData[ (getColParm->gc_rowsReturned *
					 getColParm->gc_columnCount) +
					 getColParm->gc_columnCount -
					 stmtHndl->sh_colFetch ];

    for( ; stmtHndl->sh_colFetch;
	 stmtHndl->sh_colFetch--, stmtHndl->sh_colIndex++, descr++, value++ )
    {
	/*
	** Figure out which piece of of the tuple
	** satisfies the current column depending
	** on which object type is being accessed.
	*/
	switch( parse->object )
	{
	    case API_KW_NODE :
		switch( stmtHndl->sh_colIndex )
		{
		    case 0 :		/* Type */
			str = (parse->type == API_KW_GLOBAL) ? glob_type 
							     : priv_type;	
			break;

		    case 1 :		/* Vnode */
			str = tuple->gcn_obj.gcn_value;	
			break;

		    case 2 :		/* Network address */
			str = val[0];
			break;

		    case 3 :		/* Protocol */
			str = val[1];
			break;

		    case 4 :		/* Listen address */
			str = val[2];
			break;
		}
		break;

	    case API_KW_LOGIN :
		switch( stmtHndl->sh_colIndex )
		{
		    case 0 :		/* Type */
			str = (parse->type == API_KW_GLOBAL) ? glob_type 
							     : priv_type;	
			break;

		    case 1 :		/* Vnode */
			str = tuple->gcn_obj.gcn_value;	
			break;

		    case 2 :		/* Login */
			str = val[0];
			break;
		}
		break;

	    case API_KW_ATTR :
		switch( stmtHndl->sh_colIndex )
		{
		    case 0 :		/* Type */
			str = (parse->type == API_KW_GLOBAL) ? glob_type 
							     : priv_type;	
			break;

		    case 1 :		/* Vnode */
			str = tuple->gcn_obj.gcn_value;	
			break;

		    case 2 :		/* Attribute Name */
			str = val[0];
			break;

		    case 3 :		/* Attribute Value */
			str = val[1];
			break;
		}
		break;

	    case API_KW_SERVER :
		switch( stmtHndl->sh_colIndex )
		{
		    case 0 :		/* Server type */
			str = tuple->gcn_type.gcn_value;	
			break;

		    case 1 :		/* Object */
			str = tuple->gcn_obj.gcn_value;	
			break;

		    case 2 :		/* Address */
			str = val[0];
			break;
		}
		break;
	}

	/*
	** We should always get a valid string,
	** but provide a default just in case.
	** Strings are silently truncated if too
	** long since we don't expect truncation
	** to occur (except for the type column,
	** in which case silent truncation is
	** desired).
	*/
	if ( ! str )  str = err_str;
	len = STlength( str );
	value->dv_null = FALSE;

	switch( descr->ds_dataType )
	{
	    case IIAPI_CHA_TYPE :
		len = min( len, descr->ds_length );
		value->dv_length = len;
		MEcopy( (PTR)str, len, value->dv_value );
		break;
	    
	    case IIAPI_VCH_TYPE :
		len = min( len, descr->ds_length - sizeof( len ) );
		value->dv_length = sizeof( len ) + len;
		MEcopy( (PTR)&len, sizeof( len ), value->dv_value );
		MEcopy( (PTR)str, len, 
			(PTR)((char *)value->dv_value + sizeof( len )) );
		break;

	    default :
		/*
		** Should not happen.
		*/
		value->dv_null = TRUE;
		value->dv_length = 0;
		break;
	}
    }

    return;
}
Exemplo n.º 2
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;
    }
Exemplo n.º 3
0
bool gcn_merge_rec( GCN_QUEUE *gcn_q, bool isLogin )
{
    bool add_record;
    GCN_QUEUE *merge_q;
    GCN_DB_REC0 *dst;
    QUEUE *q;

    /*
    ** Invalid records don't get added.
    */
    if (gcn_q->buf.gcn_tup_id == -1)
         return FALSE;
    if (gcn_q->buf.gcn_invalid)
         return FALSE;
    if ( !gcn_q->buf.gcn_uid[0])
         return FALSE; 
    if ( !gcn_q->buf.gcn_l_uid)
         return FALSE; 
    if ( !gcn_q->buf.gcn_obj[0])
         return FALSE; 
    if ( !gcn_q->buf.gcn_l_obj)
         return FALSE; 

    /*
    ** Assume a valid record that doesn't match.
    */
    add_record = TRUE;
    for (q = merge_qhead.q_prev; q != &merge_qhead; q = q->q_prev)
    {
        merge_q = (GCN_QUEUE *)q;

        /*
        ** EOF of merge queue reached.
        */
        if (merge_q->buf.gcn_tup_id == -1)
            break;

        /*
        ** Records marked as delete (invalid) don't get merged. Search
        ** the next record.
        */
        if (gcn_q->buf.gcn_invalid)
             continue;

        /*
        ** Compare the uid and obj values.  No match means the record can 
        ** potentially be added.  Search the next record.
        */
        if ( STbcompare( gcn_q->buf.gcn_uid, 0, merge_q->buf.gcn_uid, 0, TRUE ) )
                continue;

        if ( STbcompare( gcn_q->buf.gcn_obj, 0, merge_q->buf.gcn_obj, 0, TRUE ) )
            continue;

        /*
        ** If this is a login file, and the uid and obj (global/private and
        ** vnode name) entries match, don't merge.
        */
        if (isLogin)
            return FALSE;

        if ( gcn_q->buf.gcn_val[0] )
        {
            char        tmp1[ GCN_VAL_MAX_LEN + 1 ];
            char        tmp2[ GCN_VAL_MAX_LEN + 1 ];
            char        *pv1[ NBR_SUBFIELDS ], *pv2[ NBR_SUBFIELDS ];
            i4          v1, v2;
                
            /*
            ** Extract sub-fields.
            */
            v1 = gcu_words( gcn_q->buf.gcn_val, tmp1, pv1, ',', 
                NBR_SUBFIELDS );
            v2 = gcu_words( merge_q->buf.gcn_val, tmp2, pv2, ',', 
                NBR_SUBFIELDS );
                
            /*
            ** Limit comparison to requested number of sub-fields
            ** Make sure there are enough sub-fields for comparison.
            */
            if ( v2 > NBR_SUBFIELDS )  v2 = NBR_SUBFIELDS;
            if ( v1 < v2 )
                continue;
                
            /*
            ** Compare the sub-fields.
            */
            while( v2-- )
            {
                if ( *pv2[v2]  &&  
                    !STbcompare(pv1[v2], 0, pv2[v2], 0, TRUE) ) 
                {
                    add_record = FALSE;
                    break;
                }
            }
           
            /*
            ** Nothing matched, so search the next record.
            */
            if (add_record)
                continue;
           
            /*
            ** Everything matched.  Don't add the record and stop
            ** searching.
            */
            add_record = FALSE;
            break;
        }
    } /* for (q = merge_qhead.q_prev; q != &merge_qhead; q = q->q_prev) */

    if (verboseArg)
    {
        if (add_record)
           SIprintf("Merging vnode %s\n", gcn_q->buf.gcn_obj);
        else
           SIprintf("Vnode %s rejected for merging\n");
    }
    return add_record;
}
Exemplo n.º 4
0
STATUS gcn_recrypt( bool clustered, u_i1 *local_mask, char *gcn_val, 
    bool *v1DecryptErr, bool *writeOutput)
{
    i2 pc;
    char *pv[ 3 ];
    STATUS status = OK;
    char *p;
    char pwd[GC_L_PASSWORD];
    i2 j;
    bool printable;

    *v1DecryptErr = FALSE;

    pc = gcu_words( gcn_val, NULL, pv, ',', 3 );
    if (pc < 2 )  
        pv[1] = "";
    if (pc < 3 )  
        pv[2] = "";

    if (!STcasecmp(pv[2],"V0") || (pc < 3))
        status = gcn_decrypt( pv[0], pv[1], pwd );
    else
        status = gcn_decode( pv[0],(u_i1*)local_mask, pv[1], pwd );
    
    if (status != OK)
    {
        if (!STcasecmp(pv[2],"V1"))
            *v1DecryptErr = TRUE;
        goto end_routine;      
    }
    if (!STlength(pwd))
    {
        if (!STcasecmp(pv[2],"V1"))
            *v1DecryptErr = TRUE;
        status = FAIL;
        goto end_routine;
    }
    p = &pwd[0];
    printable = TRUE;
    for (j = 0; j < STlength(pwd); j++)
    {
        if (!CMprint(p))
        {
            printable = FALSE;
            break;
        }
        CMnext(p);
    }
    if (!printable)
    {
         if (!STcasecmp(pv[2],"V1"))
             *v1DecryptErr = TRUE;
         status = FAIL;
         goto end_routine;
    }

    if (clustered)
    {
        if (!STncasecmp("V1", pv[2], STlength(pv[2])))
            *writeOutput = TRUE;
        status = gcu_encode( pv[0], pwd, pv[1] );
        STpolycat( 5, pv[0], ",", pv[1], ",", "V0", gcn_val );
    }
    else
    {
        status = gcn_encode( pv[0],(u_i1*)local_mask, pwd, pv[1] );
        STpolycat( 5, pv[0], ",", pv[1], ",", "V1", gcn_val );
    }

end_routine:
     return status;
}
Exemplo n.º 5
0
static STATUS
gcn_op_add
( 
    char	*msg_in,
    GCN_MBUF	*mbout, 
    char	*user, 
    char	*gcn_type,
    GCN_TUP	*masktup,
    i4		num_tuple,
    i4		opflags,
    i4		srv_flags
)
{
    GCN_QUE_NAME	*nq = NULL;
    i4			row_count, tup_count;
    STATUS		status = OK;
    char		flagbuf[ 9 ];
    char		valbuf[ 65 ];
    char		*newval = valbuf;

    /*
    ** Check that user has required privileges for operation requested.
    ** (These checks are bypassed if client is trusted.)
    */
    if ( ! (opflags & GCN_OPFLAG_TRUST) )
    {
	/*
	** SERVER_CONTROL is required to add a server entry.
	*/
	if ( opflags & GCN_OPFLAG_SRV )
	    status = gca_chk_priv( user, GCA_PRIV_SERVER_CONTROL );

	/*
	** NET_ADMIN is required to add a global vnode entry.
	*/
	if ( opflags & GCN_OPFLAG_VNODE  &&  opflags & GCN_OPFLAG_PUB )
	    status = gca_chk_priv( user, GCA_PRIV_NET_ADMIN );

	if ( status != OK )
	{
	    gcn_error( status, NULL, user, mbout );
	    return( status );
	}
    }

    /* Scan name list for given service class. */
    if ( ! (nq = gcn_nq_find( gcn_type )) )
	if ( ! (opflags & GCN_OPFLAG_SRV) )
	{
	    /* Can't find class.  */
	    gcn_error( E_GC0100_GCN_SVRCLASS_NOTFOUND, NULL, gcn_type, mbout );
	    return( E_GC0100_GCN_SVRCLASS_NOTFOUND );
	}
	else  if ( ! (nq = gcn_nq_create( gcn_type )) )
	{
	    gcn_error( E_GC0121_GCN_NOMEM, NULL, gcn_type, mbout );
	    return( E_GC0121_GCN_NOMEM );
	}

    /*
    ** Matching entries are deleted prior to adding new entries.
    ** When merging, only exact duplicates are deleted.  Otherwise,
    ** matches depend on various tuple fields for different classes.
    */
    if ( nq->gcn_transient )
    {
	/*
	** Registered servers match on listen address (value).
	** UID is overloaded with formatted server flags.
	*/
	if ( ! (opflags & GCN_OPFLAG_MRG) )  masktup->obj = "";
	masktup->uid = "";
	CVlx( (long)srv_flags, flagbuf );
    }
    else if ( opflags & GCN_OPFLAG_NODE )
    {
	/*
	** VNODE connection entries match on UID and VNODE (object).
	*/
	if ( ! (opflags & GCN_OPFLAG_MRG) )  masktup->val = "";
    }
    else if ( opflags & GCN_OPFLAG_LOGIN )
    {
	/*
	** VNODE login entries match on UID and VNODE (object).
	** Multiple values (merged entries) are not permitted.
	*/
	masktup->val = "";
    }
    else if ( opflags & GCN_OPFLAG_ATTR )
    {
	/*
	** VNODE attribute entries match on UID, VNODE (object)
	** and attribute name.
	*/
	if ( ! (opflags & GCN_OPFLAG_MRG) )
	{
	    /*
	    ** Tuple value is attribute name and its value.
	    ** Build match value to only have attribute name.
	    */
	    char	*pv[2];
	    i4  	str_len = STlength( masktup->val ) + 1;

	    if ( str_len > sizeof( valbuf ) )
	    {
	    	newval = (char *)MEreqmem( 0, str_len, FALSE, NULL );
		if ( ! newval )  return( E_GC0121_GCN_NOMEM );
	    }

	    (void)gcu_words( masktup->val, newval, pv, ',', 2 );
	    str_len = STlength( pv[0] );
	    pv[0][str_len] = ',';
	    pv[0][str_len + 1] = '\0';
	    masktup->val = pv[0];
	}
    }

    if ( gcn_nq_lock( nq, TRUE ) == OK )
    {
	/*
	** First delete any overlapping tuples and 
	** report that to the user.
	*/
	status = (row_count = gcn_nq_del( nq, masktup ))
	    	 ?  gcn_result( mbout, GCN_DEL, row_count ) : OK ;

	/*
	** Insert the tuples into the name queue.
	*/
	for( row_count = tup_count = 0; 
	     status == OK  &&  tup_count < num_tuple; tup_count++ )
	{
	    GCN_TUP	tup;
	    char	buff[ 256 ];
	    char	*login = buff;

	    /* 
	    ** Get next tuple from user request. 
	    */
	    msg_in += gcu_get_str( msg_in, &gcn_type );
	    msg_in += gcn_get_tup( msg_in, &tup );

	    /*
	    ** All tuples must have the same class.
	    */
	    if ( ! gcn_type[0] )  gcn_type = IIGCn_static.svr_type;
	    CVupper( gcn_type );
	    if ( STcompare( nq->gcn_type, gcn_type ) )  continue;

	    /* 
	    ** Set user ID appropriately.
	    */
	    if ( nq->gcn_transient )
		tup.uid = flagbuf;
	    else  if ( opflags & GCN_OPFLAG_PUB )
		tup.uid = GCN_GLOBAL_USER;
	    else  if ( ! (opflags & GCN_OPFLAG_UID) )
		tup.uid = user;

	    /*
	    ** Login passwords are encrypted by the client
	    ** and must be transformed into storage format.
	    */
	    if ( opflags & GCN_OPFLAG_LOGIN )  
	    {
		/*
		** The encryption algorithm for storage produces 
		** a slightly longer string than the communication 
		** encryption.  Ensure temp buffer is large enough.  
		** 50% larger is more than sufficient for current 
		** algorithm.
		*/
		i4 len = (STlength( tup.val ) * 3) / 2;

		if ( len >= sizeof( buff ) )
		    login = (char *)MEreqmem( 0, len + 1, FALSE, NULL );

		if ( ! login )
		    status = E_GC0121_GCN_NOMEM;
		else
		{
		    transform_login( tup.val, login );
		    tup.val = login;
	        }
	    }

	    if ( status == OK ) 
	    {
		row_count += gcn_nq_add( nq, &tup );
		if ( login != buff )  MEfree( (PTR)login );
	    }
	}

	if ( status == OK )
	    status = gcn_result( mbout, GCN_ADD, row_count );
	else
	    gcn_error( status, NULL, NULL, mbout );

	gcn_nq_unlock( nq );
    }
    else
    {
	status = E_GC0134_GCN_INT_NQ_ERROR;
	gcn_error( status, NULL, NULL, mbout );
    }

    if ( newval != valbuf )  MEfree( (PTR)newval );
    return( status );
}
Exemplo n.º 6
0
static STATUS
gcn_op_get
( 
    GCN_MBUF	*mbout, 
    char	*gcn_type,
    GCN_TUP	*masktup,
    i4		opflags
)
{
    GCN_QUE_NAME	*nq;
    GCN_MBUF		*mbuf;
    char		*msg_out = NULL;
    char		*msg_post = NULL;
    char		*row_ptr = NULL;
    i4			row_count = 0;
    STATUS		status = OK;

    /*
    ** Find desired class
    */
    if ( ! (nq = gcn_nq_find( gcn_type )) )
	if ( opflags & GCN_OPFLAG_SRV )
	    return( gcn_result( mbout, GCN_RET, 0 ) );	/* No servers */
	else
	{
	    /* Can't find class.  */
	    gcn_error( E_GC0100_GCN_SVRCLASS_NOTFOUND, NULL, gcn_type, mbout );
	    return( E_GC0100_GCN_SVRCLASS_NOTFOUND );
	}

    /*
    ** User ID is not applicable for registered servers.
    */
    if ( nq->gcn_transient )  masktup->uid = "";

    if ( gcn_nq_lock( nq, FALSE ) == OK )
    {
	GCN_TUP	*tupvec[ GCN_SVR_MAX ];
	PTR	scan_cb = NULL;
	i4	i, tupcount;

	/* 
	** Call gcn_nq_scan in a loop to get a batch at a time. 
	*/
	do
	{
	    /* Load up the next entries */
	    tupcount = gcn_nq_scan( nq, masktup, &scan_cb, 
				    GCN_SVR_MAX, tupvec, NULL );

	    /* Loop through server entries */
	    for( i = 0; i < tupcount; i++ )
	    {
		GCN_TUP	*tup = tupvec[ i ];
		GCN_TUP	newtup;
		char 	buf[ 1024 ];
		char	*p = buf;
		char	tmpbuf[ 128 ];
		char	*tmp = tmpbuf;

		p += gcu_put_str( p, nq->gcn_type );
		newtup.uid = tup->uid;
		newtup.obj = tup->obj;
		newtup.val = tup->val;

		/*
		** VNODE login passwords are not exposed.
		*/
		if ( opflags & GCN_OPFLAG_LOGIN )
		{
		    char	*pv[2];
		    i4		len = STlength( tup->val ) + 1;

		    if ( len > sizeof( tmpbuf )  &&
		    	 ! (tmp = (char *)MEreqmem(0, len, FALSE, NULL)) )
		    {
			gcn_nq_unlock( nq );
			return( E_GC0121_GCN_NOMEM );
		    }

		    (void)gcu_words( tup->val, tmp, pv, ',', 2 );
		    newtup.val = pv[0];
		}

		p += gcn_put_tup( p, &newtup );
		if ( tmp != tmpbuf )  MEfree( (PTR)tmp );

		if ( msg_out  &&  (p - buf) + msg_out > msg_post )
		{
		    /*
		    ** Update the row count for this message.
		    ** We send individual messages rather than
		    ** continued messages hoping (in vain) that
		    ** the client won't need to piece message
		    ** segments back together.
		    */
		    gcu_put_int( row_ptr, row_count );
		    mbuf->used = msg_out - mbuf->data;
		    row_count = 0;
		    msg_out = NULL;
		}

		if ( ! msg_out )
		{
		    mbuf = gcn_add_mbuf( mbout, TRUE, &status );
		    if ( status != OK )
		    {
			gcn_nq_unlock( nq );
			return( status );
		    }

		    mbuf->type = GCN_RESULT;
		    msg_out = mbuf->data;
		    msg_post = mbuf->data + mbuf->len;

		    msg_out += gcu_put_int( msg_out, GCN_RET );
		    row_ptr = msg_out;
		    msg_out += gcu_put_int( msg_out, 0 );
		}
			    
		MEcopy( buf, p - buf, msg_out );
		msg_out += p - buf;
		row_count++;
	    }
	} while( tupcount == GCN_SVR_MAX );

	if ( ! msg_out )
	    status = gcn_result( mbout, GCN_RET, 0 );
	else
	{
	    (void)gcu_put_int( row_ptr, row_count );
	    mbuf->used = msg_out - mbuf->data;
	} 

	gcn_nq_unlock( nq );
    }
    else
    {
	status = E_GC0134_GCN_INT_NQ_ERROR;
	gcn_error( status, NULL, NULL, mbout );
    }

    return( status );
}
Exemplo n.º 7
0
static STATUS
transform_login( char *ibuff, char *obuff )
{
    char	*pv[ 2 ];
    char	pbuff[ 128 ], tbuff[ 128 ];
    char	*pwd, *tmp;
    i4		len;
    STATUS	status;

    /*
    ** Isolate user ID and encrypted password.
    ** Ensure output buffer is large enough.
    ** Decrypt the password.
    */
    if ( gcu_words( ibuff, NULL, pv, ',', 2 ) < 2 )  pv[1] = "";

    len = STlength( pv[1] );
    pwd = (len < sizeof( pbuff )) 
          ? pbuff : (char *)MEreqmem( 0, len + 1, FALSE, NULL );

    if ( ! pwd )
    	status = E_GC0121_GCN_NOMEM;
    else
	status = gcn_login( GCN_VLP_CLIENT, 0, FALSE, pv[0], pv[1], pwd );

    /*
    ** Re-encrypt password for storage
    */
    if ( status == OK )
    {
	/*
	** Ensure temp buffer is large enough.
	*/
	len = (STlength( pwd ) + 8) * 2;

	tmp = (len < sizeof( tbuff )) 
	      ? tbuff : (char *)MEreqmem( 0, len + 1, FALSE, NULL );

	if ( ! tmp )
	    status = E_GC0121_GCN_NOMEM;
	else
	    status = gcn_login( GCN_VLP_LOGIN, 
	    			IIGCn_static.pwd_enc_vers, 
				TRUE, pv[0], pwd, tmp );
    }

    /*
    ** Rebuild the login tuple value.
    */
    if ( status == OK )
    {
	char vers[ 32 ];

	STprintf( vers, "V%d", IIGCn_static.pwd_enc_vers );
	STpolycat( 5, pv[0], ",", tmp, ",", vers, obuff );
    }

    if ( pwd != pbuff )  MEfree( (PTR)pwd );
    if ( tmp != tbuff )  MEfree( (PTR)tmp );
    return( status );
}