/* ** Name: scs_check_external_password ** ** Description: ** Check the external password for a role ** ** Inputs: ** scb - SCB ** ** authname - Role/User name being checked ** ** password - Role/User password ** ** auth_role - TRUE if authenticating a role ** ** Returns: ** E_DB_OK - Access is allowed ** ** E_DB_WARN - Access is denied ** ** E_DB_ERROR - Failure determining access ** ** History: ** 9-mar-94 (robf) ** Created ** 11-mar-94 (robf) ** Distinguish between access disallowed and some other ** error. Add SCF activity in case auth. server take a while ** 15-mar-94 (robf) ** Rework to allow for user or role authentication, add ** parameter auth_role. Make routine external, ** name scs_check_external_password, and move to scseauth.c ** 22-mar-1996 (stial01) ** Cast length passed to sc0m_allocate to i4. ** 16-jul-96 (stephenb) ** Add effective user to parameter list and pass to authentication ** server (fix primarily for ICE authentication, but useful ** information for the user anyway). ** 16-Nov-1998 (jenjo02) ** When suspending on BIO read, use CS_BIOR_MASK. */ DB_STATUS scs_check_external_password ( SCD_SCB *scb, DB_OWN_NAME *authname, DB_OWN_NAME *e_authname, DB_PASSWORD *password, bool auth_role ) { DB_STATUS status = E_DB_WARN; STATUS cl_stat; STATUS local_status; char pmname[64]; char *pmvalue; char target[64]; GCA_FS_PARMS fs_parms; SCS_REBUFF *re_buff = NULL; char *work_buff; i4 resume = 0; CS_SID sid; PTR save_data_area; char *q; char *gcmvalue; i4 error_index; i4 error_status; char *act_string; char blank_string[32] = ""; for (;;) { if (auth_role) act_string = "Validating external role password"; else act_string = "Validating external user password"; MEcopy((PTR)act_string, STlength(act_string), scb->scb_sscb.sscb_ics.ics_act1); scb->scb_sscb.sscb_ics.ics_l_act1 = (i4)STlength(act_string); /* ** Find the authentication mechanism for this role */ if (auth_role) { STprintf(pmname, "ii.$.secure.role_auth.%*s", scs_trimwhite(sizeof(*authname), (char*)authname), (char*)authname); } else { STprintf(pmname, "ii.$.secure.user_auth.%*s", scs_trimwhite(sizeof(*authname), (char*)authname), (char*)authname); } cl_stat = PMget(pmname, &pmvalue); if (cl_stat != OK) { sc0e_put(E_SC035A_EXTPWD_NO_AUTH_MECH, 0, 1, scs_trimwhite(sizeof(*authname), (char*)authname), (PTR)authname, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0 ); status = E_DB_ERROR; break; } /* ** Now we know the target mechanism, set up target destination ** ** Legal values are either 'value' which maps to value/authsvr ** or @value which is sent untranslated. */ if (*pmvalue != '@') STprintf(target,"%s/authsvr",pmvalue); else STprintf(target,"%s", pmvalue+1); /* ** Allocate buffer for processing the request */ status = sc0m_allocate(SCU_MZERO_MASK, (i4)sizeof(SCS_REBUFF), DB_SCF_ID, (PTR)SCS_MEM, SCRE_TAG, (PTR*)&re_buff); if (status != E_DB_OK) { /* sc0m_allocate puts error codes in return status */ sc0e_0_put(status, 0); status = E_DB_ERROR; break; } work_buff = re_buff->work_buff; gcmvalue = re_buff->gcmvalue; CSget_sid(&sid); save_data_area = work_buff; /* ** Build the fastselect request */ fs_parms.gca_user_name = NULL; fs_parms.gca_password = NULL; fs_parms.gca_account_name = NULL; fs_parms.gca_completion = cep_complete; fs_parms.gca_closure = NULL; fs_parms.gca_peer_protocol = GCA_PROTOCOL_LEVEL_61; fs_parms.gca_partner_name = target; fs_parms.gca_modifiers = GCA_RQ_GCM; fs_parms.gca_buffer = work_buff; fs_parms.gca_b_length = RQ_BUFF_SIZE; fs_parms.gca_message_type = GCM_SET; q = save_data_area; q += sizeof(i4); /* Past error_status */ q += sizeof(i4); /* Past error_index */ q += sizeof(i4); /* Past future[0] */ q += sizeof(i4); /* Past future[1] */ q += gcm_put_int(q, -1);/* Client perms */ q += gcm_put_int(q, 1); /* Row count */ q += gcm_put_int(q, 1); /* Element count */ if (auth_role) q += gcm_put_str(q, "exp.scf.auth_server.role_authenticate"); /* Class id */ else q += gcm_put_str(q, "exp.scf.auth_server.user_authenticate"); /* Class id */ q += gcm_put_str(q, "0"); /* Instance */ /* ** Now build the value. ** This consists of: ** Role: ** flag - 4 byte integer, currently 0 ** real user - 32 byte blank-padded ** effective user - 32 byte blank-padded ** role - 32 byte blank-padded ** password - 24 byte blank-padded ** User: ** flag - 4 byte integer, currently 1 ** real user - 32 byte blank-padded ** effective user - 32 byte blank-padded ** password - 24 byte blank-padded ** These are all padded into a single GCM value. ** Note: This assumes no NULL values in any of the fields. */ if (auth_role) { STprintf(gcmvalue,"%-4.4s%32.32s%32.32s%32.32s%-24.24s", "0", (char*)&scb->scb_sscb.sscb_ics.ics_rusername, e_authname ? (char*)e_authname : blank_string, (char*)authname, (char*)password); } else { STprintf(gcmvalue,"%-4.4s%32.32s%32.32s%-24.24s", "1", (char*)authname, e_authname ? (char*)e_authname : blank_string, (char*)password); } q += gcm_put_str(q, gcmvalue ); /* Value */ fs_parms.gca_msg_length = (i4)(q - save_data_area); break; } /* ** Now do the fastselect */ resume = 0; if (status == E_DB_OK) do { cl_stat = IIGCa_call(GCA_FASTSELECT, (GCA_PARMLIST *)&fs_parms, GCA_ASYNC_FLAG | GCA_ALT_EXIT | resume, (PTR)CS_find_scb(sid), (i4) -1, &local_status); if (cl_stat != OK) { sc0e_0_put(cl_stat, 0); sc0e_0_put(E_SC0357_EXTPWD_GCA_FASTSELECT, 0); status = E_DB_ERROR; break; } else { /* wait for completion routine to wake us */ cl_stat = CSsuspend(CS_BIOR_MASK, 0, 0); if (cl_stat != OK) { sc0e_0_put(cl_stat, 0); sc0e_0_put(E_SC0356_EXTPWD_GCA_CSSUSPEND, 0); status = E_DB_ERROR; resume = 0; break; } else /* completion handler called */ { switch ( cl_stat = fs_parms.gca_status ) { case OK: resume = 0; break; case E_GCFFFE_INCOMPLETE: resume = GCA_RESUME; break; case E_GC0032_NO_PEER: case E_GC0138_GCN_NO_SERVER: case E_GC0139_GCN_NO_DBMS: resume = 0; sc0e_put(E_SC0355_EXTPWD_GCA_NOPEER, 0, 2, scs_trimwhite(sizeof(*authname), (char*)authname), (PTR)authname, (i4)STlength(target), (PTR)target, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0, 0, (PTR)0 ); status = E_DB_ERROR; break; default: resume = 0; sc0e_0_put(cl_stat, 0); sc0e_0_put(E_SC0354_EXTPWD_GCA_COMPLETION, 0); status = E_DB_ERROR; break; } } } } while( resume != 0 ); /* ** Check if select worked OK, if not skip to the end */ if (status == E_DB_OK) { /* ** Got result of fastselect, so unpack and see what happened */ q = save_data_area; q += gcm_get_int(q, &error_status); q += gcm_get_int(q, &error_index); if (error_status != 0) { if (error_index == -1) { sc0e_0_put(error_status, 0); sc0e_0_put(E_SC0359_EXTPWD_GCM_ERROR, 0); status = E_DB_ERROR; } else { /* Access is denied */ status = E_DB_WARN; } } else { /* Access is allowed */ status = E_DB_OK; } } /* Reset activity */ scb->scb_sscb.sscb_ics.ics_l_act1 = 0; /* ** Free buffer if allocated */ if (re_buff) { if (sc0m_deallocate(0, (PTR *) &re_buff) != E_DB_OK) { sc0e_0_put(status, 0); } } return(status); }
STATUS gcn_bedcheck( VOID ) { GCA_FS_PARMS fast; STATUS status; CL_ERR_DESC sys_err; char gcn_addr[ GCA_SERVER_ID_LNG + 1 ]; static char msg_buff[ GCA_FS_MAX_DATA ]; char obj_buffer [ 32 ]; char *p, *var; i4 len, server_flags; char gca_partner_name[] = "/IINMSVR"; /* ** We can bail out early if Name Server ** ID has not been globally registered. */ status = GCnsid( GC_FIND_NSID, gcn_addr, sizeof( gcn_addr ), &sys_err ); if ( status == GC_NM_SRVR_ID_ERR ) return( E_GC0126_GCN_NO_GCN ); /* ** Roll up GCM_GET message. */ p = msg_buff; /* point to start of message data */ p += sizeof( i4 ); /* bump past error_status */ p += sizeof( i4 ); /* bump past error_index */ p += sizeof( i4 ); /* bump past future[0] */ p += sizeof( i4 ); /* bump past future[1] */ p += gcm_put_int( p, -1 ); /* set client_perms */ p += gcm_put_int( p, 1 ); /* set row_count */ p += gcm_put_int( p, 1 ); /* set element_count */ p += gcm_put_str( p, GCA_MIB_CLIENT_FLAGS ); /* classid */ p += gcm_put_str( p, "" ); /* instance */ p += gcm_put_str( p, "" ); /* value */ p += gcm_put_int( p, 0 ); /* perms */ /* ** Issue GCA_FASTSELECT. */ MEfill( sizeof( fast ), '\0', (PTR)&fast ); fast.gca_partner_name = gca_partner_name; fast.gca_modifiers = GCA_RQ_GCM; fast.gca_peer_protocol = GCA_PROTOCOL_LEVEL_62; fast.gca_buffer = msg_buff; fast.gca_b_length = sizeof( msg_buff ); fast.gca_message_type = GCM_GETNEXT; fast.gca_msg_length = p - msg_buff; gca_call( &gcn_gca_cb, GCA_FASTSELECT, (GCA_PARMLIST *)&fast, GCA_SYNC_FLAG, NULL, -1, &status ); if ( status == OK && fast.gca_status != OK ) status = fast.gca_status; /* ** If we can't probe it, we'll just ** have to assume it is a GCN. */ if ( status == E_GC003F_PM_NOPERM ) status = OK; else if ( status == OK ) { /* ** Unroll GCM msg. */ p = msg_buff; p += gcm_get_int( p, &status ); /* ** if GCM GET succeeded, test server flags. */ if ( status == OK ) { p += sizeof( i4 ); /* bump past element_count */ p += sizeof( i4 ); /* bump past error_index */ p += sizeof( i4 ); /* bump past future[0] */ p += sizeof( i4 ); /* bump past future[1] */ p += sizeof( i4 ); /* bump past client_perms */ p += sizeof( i4 ); /* bump past row_count */ p += gcm_get_str( p, &var, &len ); /* skip classid */ p += gcm_get_str( p, &var, &len ); /* skip instance */ p += gcm_get_str( p, &var, &len ); /* get value */ MEcopy( var, len, obj_buffer ); obj_buffer[ len ] = '\0'; CVan( obj_buffer, &server_flags ); if ( ! (server_flags & GCA_RG_IINMSVR) ) status = E_GC0126_GCN_NO_GCN; } } return( status ); }