/* Radius implementation for the dictionary_find callback The return value is: 0, if the name is found 1, if the name isn't found -1, if an error occured */ int rad_find(aaa_conn* rh, aaa_map *map, int flag) { DICT_ATTR *attr_result; DICT_VALUE *val_result; DICT_VENDOR *vend_result; if (!rh) { LM_ERR("invalid aaa connection argument\n"); return -1; } if (!map) { LM_ERR("invalid argument\n"); return -1; } switch (flag) { case AAA_DICT_FIND_VAL: val_result = rc_dict_findval(rh, map->name); if (val_result) { map->value = val_result->value; return 0; } return 1; case AAA_DICT_FIND_ATTR: attr_result = rc_dict_findattr(rh, map->name); if (attr_result) { map->value = attr_result->value; map->type = attr_result->type; return 0; } return 1; case AAA_DICT_FIND_VEND: vend_result = rc_dict_findvend(rh, map->name); if (vend_result) { map->value = vend_result->vendorpec; return 0; } return 1; } LM_ERR("failure\n"); return -1; }
/** Parses the buffer to extract the attribute-value pairs * * @param rh a handle to parsed configuration. * @param buffer the buffer to be parsed. * @param first_pair an allocated array of values. * @return 0 on successful parse of attribute-value pair, or -1 on syntax (or other) error detected. */ int rc_avpair_parse (rc_handle const *rh, char const *buffer, VALUE_PAIR **first_pair) { int mode; char attrstr[AUTH_ID_LEN]; char valstr[AUTH_STRING_LEN + 1], *p; DICT_ATTR *attr = NULL; DICT_VALUE *dval; VALUE_PAIR *pair; VALUE_PAIR *link; struct tm *tm; time_t timeval; mode = PARSE_MODE_NAME; while (*buffer != '\n' && *buffer != '\0') { if (*buffer == ' ' || *buffer == '\t') { buffer++; continue; } switch (mode) { case PARSE_MODE_NAME: /* Attribute Name */ rc_fieldcpy (attrstr, &buffer, " \t\n=,", sizeof(attrstr)); if ((attr = rc_dict_findattr (rh, attrstr)) == NULL) { rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = NULL; } return -1; } mode = PARSE_MODE_EQUAL; break; case PARSE_MODE_EQUAL: /* Equal sign */ if (*buffer == '=') { mode = PARSE_MODE_VALUE; buffer++; } else { rc_log(LOG_ERR, "rc_avpair_parse: missing or misplaced equal sign"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = NULL; } return -1; } break; case PARSE_MODE_VALUE: /* Value */ rc_fieldcpy (valstr, &buffer, " \t\n,", sizeof(valstr)); if ((pair = malloc (sizeof (VALUE_PAIR))) == NULL) { rc_log(LOG_CRIT, "rc_avpair_parse: out of memory"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = NULL; } return -1; } strcpy (pair->name, attr->name); pair->attribute = attr->value; pair->type = attr->type; switch (pair->type) { case PW_TYPE_STRING: strcpy (pair->strvalue, valstr); pair->lvalue = (uint32_t)strlen(valstr); break; case PW_TYPE_INTEGER: if (isdigit (*valstr)) { pair->lvalue = atoi (valstr); } else { if ((dval = rc_dict_findval (rh, valstr)) == NULL) { rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute value: %s", valstr); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = NULL; } free (pair); return -1; } else { pair->lvalue = dval->value; } } break; case PW_TYPE_IPADDR: if (inet_pton(AF_INET, valstr, &pair->lvalue) == 0) { rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv4 address %s", valstr); free(pair); return -1; } pair->lvalue = ntohl(pair->lvalue); break; case PW_TYPE_IPV6ADDR: if (inet_pton(AF_INET6, valstr, pair->strvalue) == 0) { rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 address %s", valstr); free(pair); return -1; } pair->lvalue = 16; break; case PW_TYPE_IPV6PREFIX: p = strchr(valstr, '/'); if (p == NULL) { rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr); free(pair); return -1; } *p = 0; p++; pair->strvalue[0] = 0; pair->strvalue[1] = atoi(p); if (inet_pton(AF_INET6, valstr, pair->strvalue+2) == 0) { rc_log(LOG_ERR, "rc_avpair_parse: invalid IPv6 prefix %s", valstr); free(pair); return -1; } pair->lvalue = 2+16; break; case PW_TYPE_DATE: timeval = time (0); tm = localtime (&timeval); tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; rc_str2tm (valstr, tm); #ifdef TIMELOCAL pair->lvalue = (uint32_t) timelocal (tm); #else /* TIMELOCAL */ pair->lvalue = (uint32_t) mktime (tm); #endif /* TIMELOCAL */ break; default: rc_log(LOG_ERR, "rc_avpair_parse: unknown attribute type %d", pair->type); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = NULL; } free (pair); return -1; } /* XXX: Fix up Digest-Attributes */ switch (pair->attribute) { case PW_DIGEST_REALM: case PW_DIGEST_NONCE: case PW_DIGEST_METHOD: case PW_DIGEST_URI: case PW_DIGEST_QOP: case PW_DIGEST_ALGORITHM: case PW_DIGEST_BODY_DIGEST: case PW_DIGEST_CNONCE: case PW_DIGEST_NONCE_COUNT: case PW_DIGEST_USER_NAME: /* overlapping! */ if (pair->lvalue > AUTH_STRING_LEN - 2) pair->lvalue = AUTH_STRING_LEN - 2; memmove(&pair->strvalue[2], &pair->strvalue[0], pair->lvalue); pair->strvalue[0] = pair->attribute - PW_DIGEST_REALM + 1; pair->lvalue += 2; pair->strvalue[1] = pair->lvalue; pair->strvalue[pair->lvalue] = '\0'; pair->attribute = PW_DIGEST_ATTRIBUTES; } pair->next = NULL; if (*first_pair == NULL) { *first_pair = pair; } else { link = *first_pair; while (link->next != NULL) { link = link->next; } link->next = pair; } mode = PARSE_MODE_NAME; break; default: mode = PARSE_MODE_NAME; break; } } return 0; }
int rc_avpair_parse (char *buffer, VALUE_PAIR **first_pair) { int mode; char attrstr[AUTH_ID_LEN]; char valstr[AUTH_ID_LEN]; DICT_ATTR *attr = NULL; DICT_VALUE *dval; VALUE_PAIR *pair; VALUE_PAIR *link; struct tm *tm; time_t timeval; mode = PARSE_MODE_NAME; while (*buffer != '\n' && *buffer != '\0') { if (*buffer == ' ' || *buffer == '\t') { buffer++; continue; } switch (mode) { case PARSE_MODE_NAME: /* Attribute Name */ rc_fieldcpy (attrstr, &buffer); if ((attr = rc_dict_findattr (attrstr)) == (DICT_ATTR *) NULL) { error("rc_avpair_parse: unknown attribute"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } mode = PARSE_MODE_EQUAL; break; case PARSE_MODE_EQUAL: /* Equal sign */ if (*buffer == '=') { mode = PARSE_MODE_VALUE; buffer++; } else { error("rc_avpair_parse: missing or misplaced equal sign"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } break; case PARSE_MODE_VALUE: /* Value */ rc_fieldcpy (valstr, &buffer); if ((pair = (VALUE_PAIR *) malloc (sizeof (VALUE_PAIR))) == (VALUE_PAIR *) NULL) { novm("rc_avpair_parse"); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } return (-1); } strcpy (pair->name, attr->name); pair->attribute = attr->value; pair->type = attr->type; pair->vendorcode = attr->vendorcode; switch (pair->type) { case PW_TYPE_STRING: strcpy ((char *)pair->strvalue, valstr); pair->lvalue = strlen(valstr); break; case PW_TYPE_INTEGER: if (isdigit (*valstr)) { pair->lvalue = atoi (valstr); } else { if ((dval = rc_dict_findval (valstr)) == (DICT_VALUE *) NULL) { error("rc_avpair_parse: unknown attribute value: %s", valstr); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } free (pair); return (-1); } else { pair->lvalue = dval->value; } } break; case PW_TYPE_IPADDR: pair->lvalue = rc_get_ipaddr(valstr); break; case PW_TYPE_DATE: timeval = time (0); tm = localtime (&timeval); tm->tm_hour = 0; tm->tm_min = 0; tm->tm_sec = 0; rc_str2tm (valstr, tm); #ifdef TIMELOCAL pair->lvalue = (UINT4) timelocal (tm); #else /* TIMELOCAL */ pair->lvalue = (UINT4) mktime (tm); #endif /* TIMELOCAL */ break; default: error("rc_avpair_parse: unknown attribute type %d", pair->type); if (*first_pair) { rc_avpair_free(*first_pair); *first_pair = (VALUE_PAIR *) NULL; } free (pair); return (-1); } pair->next = (VALUE_PAIR *) NULL; if (*first_pair == (VALUE_PAIR *) NULL) { *first_pair = pair; } else { link = *first_pair; while (link->next != (VALUE_PAIR *) NULL) { link = link->next; } link->next = pair; } mode = PARSE_MODE_NAME; break; default: mode = PARSE_MODE_NAME; break; } } return (0); }