static STATUS gcn_result( GCN_MBUF *mbout, i4 opcode, i4 count ) { char *msg_out; GCN_MBUF *mbuf; STATUS status = OK; mbuf = gcn_add_mbuf( mbout, TRUE, &status ); if ( status != OK ) return( status ); mbuf->type = GCN_RESULT; msg_out = mbuf->data; msg_out += gcu_put_int( msg_out, opcode ); msg_out += gcu_put_int( msg_out, count ); mbuf->used = msg_out - mbuf->data; return( OK ); }
STATUS gcn_get_auth( GCN_RESOLVE_CB *grcb, GCN_MBUF *mbout ) { char passwd[ 20 ]; /* Need size > ((len + 8) * 2) */ char *m; GCN_MBUF *mbuf; STATUS status; i4 i; /* ** Encrypt the NOUSER password, so the local GCC can decrypt it. */ gcn_login(GCN_VLP_COMSVR, GCN_VLP_V1, TRUE, GCN_NOUSER, GCN_NOPASS, passwd); /* ** Produce the GCN2_RESOLVED message. */ if ( (status = gcn_connect_info( grcb, mbout, GCN_NOUSER, passwd, 0, NULL )) != OK ) return( status ); /* ** Prepare GCN_NS_AUTHORIZE message. */ mbuf = gcn_add_mbuf( mbout, TRUE, &status ); if ( status != OK ) return status; m = mbuf->data; m += gcu_put_int( m, GCN_AUTH_TICKET ); m += gcu_put_str( m, grcb->username ); m += gcu_put_str( m, IIGCn_static.lcl_vnode ); m += gcu_put_str( m, grcb->vnode ); m += gcu_put_int( m, IIGCn_static.ticket_cache_size ); mbuf->used = m - mbuf->data; mbuf->type = GCN_NS_AUTHORIZE; return( OK ); }
static STATUS gcn_op_servers ( GCN_MBUF *mbout, GCN_TUP *masktup, i4 opflags ) { QUEUE *q; GCN_MBUF *mbuf; char *msg_out = NULL; char *msg_post = NULL; char *row_ptr = NULL; i4 row_count = 0; STATUS status = OK; /* ** User ID is not applicable for registered servers. */ masktup->uid = ""; for( q = IIGCn_static.name_queues.q_next; q != &IIGCn_static.name_queues; q = q->q_next ) { GCN_QUE_NAME *nq = (GCN_QUE_NAME *)q; GCN_TUP *tupvec[ GCN_SVR_MAX ]; PTR scan_cb = NULL; i4 i, tupcount; /* ** Skip non-server and registry queues. ** Also, ignore errors on individual queues. */ if ( ! nq->gcn_transient ) continue; if ( ! STcompare( GCN_NS_REG, nq->gcn_type ) ) continue; if ( gcn_nq_lock( nq, FALSE ) != OK ) continue; /* ** 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; newtup.uid = tup->uid; newtup.obj = tup->obj; newtup.val = tup->val; p += gcu_put_str( p, nq->gcn_type ); p += gcn_put_tup( p, &newtup ); 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 ) 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 ); gcn_nq_unlock( nq ); } 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; } return( status ); }
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 ); }
STATUS gcn_make_auth( GCN_MBUF *mbin, GCN_MBUF *mbout, i4 prot ) { char *username; i4 rq_count; i4 auth_type; i4 i, userlen; STATUS status; GCN_MBUF *mbuf; char *msg_out; char *m, *end; char rtickvec[ GCN_DFLT_L_TICKVEC ][ GCN_L_TICKET ]; /* ** Unpack GCN_NS_AUTHORIZE message */ m = mbin->data; end = m + mbin->len; m += gcu_get_int( m, &auth_type ); m += gcu_get_int( m, &userlen ); username = m; userlen = min( userlen, end - m ); m += userlen; m += gcu_get_int( m, &i ); /* Skip */ m += min( i, end - m ); m += gcu_get_int( m, &i ); /* Skip */ m += min( i, end - m ); m += gcu_get_int( m, &rq_count ); if ( rq_count > GCN_DFLT_L_TICKVEC ) rq_count = GCN_DFLT_L_TICKVEC; if ( rq_count > IIGCn_static.ticket_cache_size ) rq_count = IIGCn_static.ticket_cache_size; /* ** Verify message. */ if ( auth_type != GCN_AUTH_TICKET ) { gcn_error( E_GC0141_GCN_INPW_NOSUPP, NULL, NULL, mbout ); return( E_GC0141_GCN_INPW_NOSUPP ); } /* ** Generate tickets */ username[ userlen ] = EOS; status = gcn_make_tickets( username, IIGCn_static.lcl_vnode, &rtickvec[0][0], rq_count, GCN_L_TICKET, prot ); if ( status != OK ) { gcn_error( status, (CL_ERR_DESC *)0, (char *)0, mbout ); return( status ); } /* ** Pack GCN_AUTHORIZED message */ mbuf = gcn_add_mbuf( mbout, TRUE, &status ); if ( status != OK ) return( status ); m = mbuf->data; m += gcu_put_int( m, auth_type ); m += gcu_put_int( m, rq_count ); for( i = 0; i < rq_count; i++ ) m += gcu_put_str( m, rtickvec[ i ] ); mbuf->used = m - mbuf->data; mbuf->type = GCN_AUTHORIZED; return( OK ); }