FreeBSD/contrib/bsnmp/snmpd/main.c
/*
 * Check whether access to each of var bindings in the PDU is allowed based
 * on the user credentials against the configured User groups & VACM views.
 */
Check whether access to each of var bindings in the PDU is allowed based
on the user credentials against the configured User groups & VACM views.
Check whether access to each of var bindings in the PDU is allowed based on the user credentials against the configured User groups & VACM views .
enum snmp_code
snmp_pdu_auth_access(struct snmp_pdu *pdu, int32_t *ip)
{
	const char *uname;
	int32_t suboid, smodel;
	uint32_t i;
	struct vacm_user *vuser;
	struct vacm_access *acl;
	struct vacm_context *vacmctx;
	struct vacm_view *view;
	if (SLIST_EMPTY(&vacm_contextlist) ||
	    (pdu->flags & SNMP_MSG_AUTODISCOVER) != 0)
		return (SNMP_CODE_OK);
	switch (pdu->version) {
	case SNMP_V1:
		if ((uname = comm_string(community)) == NULL)
			return (SNMP_CODE_FAILED);
		smodel = SNMP_SECMODEL_SNMPv1;
		break;
	case SNMP_V2c:
		if ((uname = comm_string(community)) == NULL)
			return (SNMP_CODE_FAILED);
		smodel = SNMP_SECMODEL_SNMPv2c;
		break;
	case SNMP_V3:
		uname = pdu->user.sec_name;
		if ((smodel = pdu->security_model) !=  SNMP_SECMODEL_USM)
			return (SNMP_CODE_FAILED);
		if (pdu->context_engine_len != snmpd_engine.engine_len ||
		    memcmp(pdu->context_engine, snmpd_engine.engine_id,
		    snmpd_engine.engine_len) != 0)
			return (SNMP_CODE_FAILED);
		break;
	default:
		abort();
	}
	SLIST_FOREACH(vuser, &vacm_userlist, vvu)
		if (strcmp(uname, vuser->secname) == 0 &&
		    vuser->sec_model == smodel)
			break;
	if (vuser == NULL || vuser->group == NULL)
		return (SNMP_CODE_FAILED);
	TAILQ_FOREACH_REVERSE(acl, &vacm_accesslist, vacm_accesslist, vva) {
		if (acl->group != vuser->group)
			continue;
		SLIST_FOREACH(vacmctx, &vacm_contextlist, vcl)
			if (memcmp(vacmctx->ctxname, acl->ctx_prefix,
			    acl->ctx_match) == 0)
				goto match;
	}
	return (SNMP_CODE_FAILED);
match:
	switch (pdu->type) {
	case SNMP_PDU_GET:
	case SNMP_PDU_GETNEXT:
	case SNMP_PDU_GETBULK:
		if ((view = acl->read_view) == NULL)
			return (SNMP_CODE_FAILED);
		break;
	case SNMP_PDU_SET:
		if ((view = acl->write_view) == NULL)
			return (SNMP_CODE_FAILED);
		break;
	case SNMP_PDU_TRAP:
	case SNMP_PDU_INFORM:
	case SNMP_PDU_TRAP2:
	case SNMP_PDU_REPORT:
		if ((view = acl->notify_view) == NULL)
			return (SNMP_CODE_FAILED);
		break;
	case SNMP_PDU_RESPONSE:
			return (SNMP_CODE_FAILED);
	default:
		abort();
	}
	for (i = 0; i < pdu->nbindings; i++) {
		suboid = asn_is_suboid(&view->subtree, &pdu->bindings[i].var);
		if ((!suboid && !view->exclude) || (suboid && view->exclude)) {
			*ip = i + 1;
			return (SNMP_CODE_FAILED);
		}
	}
	return (SNMP_CODE_OK);
}
enum snmp_code snmp_pdu_auth_access ( struct snmp_pdu * pdu , int32_t * ip ) { const char * uname ; int32_t suboid , smodel ; uint32_t i ; struct vacm_user * vuser ; struct vacm_access * acl ; struct vacm_context * vacmctx ; struct vacm_view * view ; if ( SLIST_EMPTY ( & vacm_contextlist ) || ( pdu -> flags & SNMP_MSG_AUTODISCOVER ) != 0 ) return ( SNMP_CODE_OK ) ; switch ( pdu -> version ) { case SNMP_V1 : if ( ( uname = comm_string ( community ) ) == NULL ) return ( SNMP_CODE_FAILED ) ; smodel = SNMP_SECMODEL_SNMPv1 ; break ; case SNMP_V2c : if ( ( uname = comm_string ( community ) ) == NULL ) return ( SNMP_CODE_FAILED ) ; smodel = SNMP_SECMODEL_SNMPv2c ; break ; case SNMP_V3 : uname = pdu -> user . sec_name ; if ( ( smodel = pdu -> security_model ) != SNMP_SECMODEL_USM ) return ( SNMP_CODE_FAILED ) ; if ( pdu -> context_engine_len != snmpd_engine . engine_len || memcmp ( pdu -> context_engine , snmpd_engine . engine_id , snmpd_engine . engine_len ) != 0 ) return ( SNMP_CODE_FAILED ) ; break ; default : abort ( ) ; } SLIST_FOREACH ( vuser , & vacm_userlist , vvu ) if ( strcmp ( uname , vuser -> secname ) == 0 && vuser -> sec_model == smodel ) break ; if ( vuser == NULL || vuser -> group == NULL ) return ( SNMP_CODE_FAILED ) ; TAILQ_FOREACH_REVERSE ( acl , & vacm_accesslist , vacm_accesslist , vva ) { if ( acl -> group != vuser -> group ) continue ; SLIST_FOREACH ( vacmctx , & vacm_contextlist , vcl ) if ( memcmp ( vacmctx -> ctxname , acl -> ctx_prefix , acl -> ctx_match ) == 0 ) goto match ; } return ( SNMP_CODE_FAILED ) ; match : switch ( pdu -> type ) { case SNMP_PDU_GET : case SNMP_PDU_GETNEXT : case SNMP_PDU_GETBULK : if ( ( view = acl -> read_view ) == NULL ) return ( SNMP_CODE_FAILED ) ; break ; case SNMP_PDU_SET : if ( ( view = acl -> write_view ) == NULL ) return ( SNMP_CODE_FAILED ) ; break ; case SNMP_PDU_TRAP : case SNMP_PDU_INFORM : case SNMP_PDU_TRAP2 : case SNMP_PDU_REPORT : if ( ( view = acl -> notify_view ) == NULL ) return ( SNMP_CODE_FAILED ) ; break ; case SNMP_PDU_RESPONSE : return ( SNMP_CODE_FAILED ) ; default : abort ( ) ; } for ( i = 0 ; i < pdu -> nbindings ; i ++ ) { suboid = asn_is_suboid ( & view -> subtree , & pdu -> bindings [ i ] . var ) ; if ( ( ! suboid && ! view -> exclude ) || ( suboid && view -> exclude ) ) { * ip = i + 1 ; return ( SNMP_CODE_FAILED ) ; } } return ( SNMP_CODE_OK ) ; }
Check whether access to each of var bindings in the PDU is allowed based
 on the user credentials against the configured User groups & VACM views.
Check whether access to each of var bindings in the PDU is allowed based on the user credentials against the configured User groups & VACM views .
/*
	 * At least a default context exists if the snmpd_vacm(3) module is
	 * running.
	 */ /* Compare the PDU context engine id against the agent's */ /* XXX: shteryana - recheck */ /* NOTREACHED */ /* XXX - view->mask*/