📄 valuepair.c
字号:
auth_item = auth_item->next; result = 0; goto try_again; } } /* for every entry in the check item list */ return 0; /* it matched */}/* * Compare two attributes simply. Calls paircompare. */int simplepaircmp(REQUEST *req, VALUE_PAIR *first, VALUE_PAIR *second){ return paircompare( req, first, second, NULL, NULL );}/* * Compare a Connect-Info and a Connect-Rate */static int connectcmp(void *instance, REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs){ int rate; instance = instance; check_pairs = check_pairs; /* shut the compiler up */ reply_pairs = reply_pairs; rate = atoi((char *)request->strvalue); return rate - check->lvalue;}/* * Compare a portno with a range. */static int portcmp(void *instance, REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs){ char buf[MAX_STRING_LEN]; char *s, *p; uint32_t lo, hi; uint32_t port = request->lvalue; instance = instance; check_pairs = check_pairs; /* shut the compiler up */ reply_pairs = reply_pairs; if ((strchr((char *)check->strvalue, ',') == NULL) && (strchr((char *)check->strvalue, '-') == NULL)) { return (request->lvalue - check->lvalue); } /* Same size */ strcpy(buf, (char *)check->strvalue); s = strtok(buf, ","); while (s != NULL) { if ((p = strchr(s, '-')) != NULL) p++; else p = s; lo = strtoul(s, NULL, 10); hi = strtoul(p, NULL, 10); if (lo <= port && port <= hi) { return 0; } s = strtok(NULL, ","); } return -1;}/* * Compare prefix/suffix. * * If they compare: * - if PW_STRIP_USER_NAME is present in check_pairs, * strip the username of prefix/suffix. * - if PW_STRIP_USER_NAME is not present in check_pairs, * add a PW_STRIPPED_USER_NAME to the request. */static int presufcmp(void *instance, REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs){ VALUE_PAIR *vp; char *name = (char *)request->strvalue; char rest[MAX_STRING_LEN]; int len, namelen; int ret = -1; instance = instance; reply_pairs = reply_pairs; /* shut the compiler up */#if 0 /* DEBUG */ printf("Comparing %s and %s, check->attr is %d\n", name, check->strvalue, check->attribute);#endif len = strlen((char *)check->strvalue); switch (check->attribute) { case PW_PREFIX: ret = strncmp(name, (char *)check->strvalue, len); if (ret == 0 && rest) strcpy(rest, name + len); break; case PW_SUFFIX: namelen = strlen(name); if (namelen < len) break; ret = strcmp(name + namelen - len, (char *)check->strvalue); if (ret == 0 && rest) { strNcpy(rest, name, namelen - len + 1); } break; } if (ret != 0) return ret; if ((vp = pairfind(check_pairs, PW_STRIP_USER_NAME)) != NULL) { if (vp->lvalue == 1) { /* * I don't think we want to update the User-Name * attribute in place... - atd */ strcpy((char *)request->strvalue, rest); request->length = strlen(rest); } else { return ret; } } else { if ((vp = pairfind(check_pairs, PW_STRIPPED_USER_NAME)) != NULL){ strcpy((char *)vp->strvalue, rest); vp->length = strlen(rest); } else if ((vp = paircreate(PW_STRIPPED_USER_NAME, PW_TYPE_STRING)) != NULL) { strcpy((char *)vp->strvalue, rest); vp->length = strlen(rest); pairadd(&request, vp); } /* else no memory! Die, die!: FIXME!! */ } return ret;}/* * Compare the current time to a range. */static int timecmp(void *instance, REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs){ instance = instance; request = request; /* shut the compiler up */ check_pairs = check_pairs; reply_pairs = reply_pairs; if (timestr_match((char *)check->strvalue, req ? req->timestamp : time(NULL)) >= 0) { return 0; } return -1;}/* * Matches if there is NO SUCH ATTRIBUTE as the one named * in check->strvalue. If there IS such an attribute, it * doesn't match. * * This is ugly, and definitely non-optimal. We should be * doing the lookup only ONCE, and storing the result * in check->lvalue... */static int attrcmp(void *instance, REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs){ VALUE_PAIR *pair; DICT_ATTR *dict; int attr; instance = instance; check_pairs = check_pairs; /* shut the compiler up */ reply_pairs = reply_pairs; if (check->lvalue == 0) { dict = dict_attrbyname((char *)check->strvalue); if (dict == NULL) { return -1; } attr = dict->attr; } else { attr = check->lvalue; } /* * If there's no such attribute, then return MATCH, * else FAILURE. */ pair = pairfind(request, attr); if (pair == NULL) { return 0; } return -1;}/* * Compare the expiration date. */static int expirecmp(void *instance, REQUEST *req UNUSED, VALUE_PAIR *request, VALUE_PAIR *check, VALUE_PAIR *check_pairs, VALUE_PAIR **reply_pairs){ time_t now; instance = instance; request = request; /* shut the compiler up */ check_pairs = check_pairs; reply_pairs = reply_pairs; /* * FIXME! This should be request->timestamp! */ now = time(NULL); if (now <= (signed)check->lvalue) { return 0; } return +1;}/* * Compare the request packet type. */static int packetcmp(void *instance UNUSED, REQUEST *req, VALUE_PAIR *request UNUSED, VALUE_PAIR *check, VALUE_PAIR *check_pairs UNUSED, VALUE_PAIR **reply_pairs UNUSED){ if (req->packet->code == check->lvalue) { return 0; } return 1;}/* * Compare the response packet type. */static int responsecmp(void *instance UNUSED, REQUEST *req, VALUE_PAIR *request UNUSED, VALUE_PAIR *check, VALUE_PAIR *check_pairs UNUSED, VALUE_PAIR **reply_pairs UNUSED){ if (req->reply->code == check->lvalue) { return 0; } return 1;}/* * Register server-builtin special attributes. */void pair_builtincompare_init(void){ paircompare_register(PW_NAS_PORT, -1, portcmp, NULL); paircompare_register(PW_PREFIX, PW_USER_NAME, presufcmp, NULL); paircompare_register(PW_SUFFIX, PW_USER_NAME, presufcmp, NULL); paircompare_register(PW_CONNECT_RATE, PW_CONNECT_INFO, connectcmp, NULL); paircompare_register(PW_CURRENT_TIME, 0, timecmp, NULL); paircompare_register(PW_NO_SUCH_ATTRIBUTE, 0, attrcmp, NULL); paircompare_register(PW_EXPIRATION, 0, expirecmp, NULL); paircompare_register(PW_PACKET_TYPE, 0, packetcmp, NULL); paircompare_register(PW_RESPONSE_PACKET_TYPE, 0, responsecmp, NULL);}/* * Move pairs, replacing/over-writing them, and doing xlat. *//* * Move attributes from one list to the other * if not already present. */void pairxlatmove(REQUEST *req, VALUE_PAIR **to, VALUE_PAIR **from){ VALUE_PAIR **tailto, *i, *j, *next; VALUE_PAIR *tailfrom = NULL; VALUE_PAIR *found; /* * Point "tailto" to the end of the "to" list. */ tailto = to; for(i = *to; i; i = i->next) { tailto = &i->next; } /* * Loop over the "from" list. */ for(i = *from; i; i = next) { next = i->next; /* * Don't move 'fallthrough' over. */ if (i->attribute == PW_FALL_THROUGH) { continue; } /* * We've got to xlat the string before moving * it over. */ if (i->flags.do_xlat) { int rcode; char buffer[sizeof(i->strvalue)]; i->flags.do_xlat = 0; rcode = radius_xlat(buffer, sizeof(buffer), i->strvalue, req, NULL); /* * Parse the string into a new value. */ pairparsevalue(i, buffer); } found = pairfind(*to, i->attribute); switch (i->operator) { /* * If a similar attribute is found, * delete it. */ case T_OP_SUB: /* -= */ if (found) { if (!i->strvalue[0] || (strcmp((char *)found->strvalue, (char *)i->strvalue) == 0)){ pairdelete(to, found->attribute); /* * 'tailto' may have been * deleted... */ tailto = to; for(j = *to; j; j = j->next) { tailto = &j->next; } } } tailfrom = i; continue; break; /* * Add it, if it's not already there. */ case T_OP_EQ: /* = */ if (found) { tailfrom = i; continue; /* with the loop */ } break; /* * If a similar attribute is found, * replace it with the new one. Otherwise, * add the new one to the list. */ case T_OP_SET: /* := */ if (found) { VALUE_PAIR *vp; vp = found->next; memcpy(found, i, sizeof(*found)); found->next = vp; continue; } break; /* * FIXME: Add support for <=, >=, <, > * * which will mean (for integers) * 'make the attribute the smaller, etc' */ /* * Add the new element to the list, even * if similar ones already exist. */ default: case T_OP_ADD: /* += */ break; } if (tailfrom) tailfrom->next = next; else *from = next; /* * If ALL of the 'to' attributes have been deleted, * then ensure that the 'tail' is updated to point * to the head. */ if (!*to) { tailto = to; } *tailto = i; if (i) { i->next = NULL; tailto = &i->next; } } /* loop over the 'from' list */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -