i4 gcn_oper_check( GCN_MBUF *mbin, QUEUE *bchk_q ) { GCN_TUP tup; char *ptr; char *msg_in = mbin->data; i4 ival; i4 count = 0; msg_in += gcu_get_int( msg_in, &ival ); /* Flags */ msg_in += gcu_get_int( msg_in, &ival ); /* OP code */ /* ** Bedchecking is only needed for data retrieval. */ if ( ival == GCN_RET ) { msg_in += gcu_get_str( msg_in, &ptr ); /* Installation */ msg_in += gcu_get_int( msg_in, &ival ); /* Tuple count */ while( ival-- > 0 ) { msg_in += gcu_get_str( msg_in, &ptr ); /* Server class */ msg_in += gcn_get_tup( msg_in, &tup ); /* Tup mask */ /* ** Add servers of requested class to queue. */ count += gcn_bchk_class( ptr, bchk_q ); } } return( count ); }
STATUS gcn_got_auth( GCN_RESOLVE_CB *grcb, GCN_MBUF *mbin ) { char *m = mbin->data; char *end = m + mbin->len; i4 auth_type; i4 rq_count; char rtickvec[ GCN_DFLT_L_TICKVEC ][ GCN_L_TICKET ]; STATUS status; i4 i; /* ** Check for error. */ if ( mbin->type == GCA_ERROR ) { m += gcu_get_int( m, &i ); /* toss gca_l_e_element */ m += gcu_get_int( m, &status ); return( status ); } /* ** Check for valid response. */ if ( mbin->type != GCN_AUTHORIZED ) return( E_GC0144_GCN_INPW_BROKEN ); m += gcu_get_int( m, &auth_type ); m += gcu_get_int( m, &rq_count ); if ( auth_type != GCN_AUTH_TICKET ) return( E_GC0144_GCN_INPW_BROKEN ); for( i = 0; i < rq_count && i < GCN_DFLT_L_TICKVEC; i++ ) m += gcn_copy_str( m, end - m, rtickvec[ i ], GCN_L_TICKET ); status = gcn_save_rtickets( grcb->username, grcb->vnode, &rtickvec[0][0], rq_count, GCN_L_TICKET ); return( status ); }
STATUS gcn_oper_ns ( GCN_MBUF *mbin, GCN_MBUF *mbout, char *user, bool trusted ) { char *msg_in = mbin->data; char *tup_list; char *gcn_install; char *gcn_type; GCN_TUP tup; i4 opcode; i4 opflags = 0; i4 flags; i4 num_tuple; STATUS status = OK; CL_SYS_ERR sys_err; /* ** Retrieve GCN_NS_OPER message contents. */ msg_in += gcu_get_int( msg_in, &flags ); if ( trusted ) opflags |= GCN_OPFLAG_TRUST; /* Trusted */ if ( flags & GCN_PUB_FLAG ) opflags |= GCN_OPFLAG_PUB; /* Global */ if ( flags & GCN_UID_FLAG ) opflags |= GCN_OPFLAG_UID; /* Set UID */ if ( flags & GCN_MRG_FLAG ) opflags |= GCN_OPFLAG_MRG; /* Merge */ flags &= ~(GCN_MRG_FLAG | GCN_UID_FLAG); /* Remove internal flags */ msg_in += gcu_get_int( msg_in, &opcode ); msg_in += gcu_get_str( msg_in, &gcn_install ); msg_in += gcu_get_int( msg_in, &num_tuple ); if ( num_tuple > 0 ) { tup_list = msg_in; /* Tuple list needed for GCN_ADD */ msg_in += gcu_get_str( msg_in, &gcn_type ); msg_in += gcn_get_tup( msg_in, &tup ); /* Check for default server class */ if ( ! gcn_type[0] ) gcn_type = IIGCn_static.svr_type; CVupper( gcn_type ); if ( ! STcompare( gcn_type, GCN_NODE ) ) opflags |= GCN_OPFLAG_NODE; /* VNODE connection info */ else if ( ! STcompare( gcn_type, GCN_LOGIN ) ) opflags |= GCN_OPFLAG_LOGIN; /* VNODE login info */ else if ( ! STcompare( gcn_type, GCN_ATTR ) ) opflags |= GCN_OPFLAG_ATTR; /* VNODE attribute info */ else if ( ! STcompare( gcn_type, GCN_LTICKET ) || ! STcompare( gcn_type, GCN_RTICKET ) ) opflags |= GCN_OPFLAG_TICK; /* IP local/remote tickets */ else if ( ! STcompare( gcn_type, "SERVERS" ) ) opflags |= GCN_OPFLAG_SRVS; /* All registered servers */ else opflags |= GCN_OPFLAG_SRV; /* Anything else is a server */ /* ** Set user ID. IP tickets and public entries are user ** independent. In general, the client user ID is used ** (overwrites requested user ID) unless the Set UID flag ** has been specified (and client has NET_ADMIN privilege). */ if ( opflags & GCN_OPFLAG_TICK ) tup.uid = ""; else if ( opflags & GCN_OPFLAG_PUB ) tup.uid = GCN_GLOBAL_USER; else if ( ! (opflags & GCN_OPFLAG_UID) ) tup.uid = user; } /* ** Check that user has required privileges for operation requested. ** (These checks are bypassed if client is trusted.) */ if ( ! (opflags & GCN_OPFLAG_TRUST) ) { /* ** NET_ADMIN is required to access IP local/remote tickets. */ if ( opflags & GCN_OPFLAG_TICK ) status = gca_chk_priv( user, GCA_PRIV_NET_ADMIN ); /* ** NET_ADMIN is required to access another users's VNODE entry. */ if ( opflags & GCN_OPFLAG_VNODE && opflags & GCN_OPFLAG_UID ) status = gca_chk_priv( user, GCA_PRIV_NET_ADMIN ); /* ** SERVER_CONTROL is required to shutdown Name Server. */ if ( opcode == GCN_SHUTDOWN ) status = gca_chk_priv( user, GCA_PRIV_SERVER_CONTROL ); if ( status != OK ) { gcn_error( status, NULL, user, mbout ); return( status ); } } switch( opcode ) { case GCN_DEL : if ( num_tuple != 1 || opflags & GCN_OPFLAG_SRVS ) status = gcn_result( mbout, opcode, 0 ); /* Nothing to do... */ else status = gcn_op_del( mbout, user, gcn_type, &tup, opflags ); break; case GCN_ADD : if ( opflags & GCN_OPFLAG_SRVS ) status = gcn_result( mbout, opcode, 0 ); /* Nothing to do... */ else status = gcn_op_add( tup_list, mbout, user, gcn_type, &tup, num_tuple, opflags, flags ); break; case GCN_RET : if ( num_tuple != 1 ) status = gcn_result( mbout, opcode, 0 ); /* Nothing to do... */ else if ( opflags & GCN_OPFLAG_SRVS ) status = gcn_op_servers( mbout, &tup, opflags ); else status = gcn_op_get( mbout, gcn_type, &tup, opflags ); break; case GCN_SHUTDOWN: /* ** Deassign the nameserver listen logical */ GCnsid( GC_CLEAR_NSID, NULL, 0, &sys_err ); gcn_result( mbout, GCN_SHUTDOWN, 0 ); status = E_GC0152_GCN_SHUTDOWN; break; } 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 ); }