(dorewrite): Do modattrs even if addattrs fails. Do modattrs before
authorlinus <linus>
Wed, 31 Mar 2010 13:43:10 +0000 (13:43 +0000)
committerlinus <linus@e88ac4ed-0b26-0410-9574-a7f39faa03bf>
Wed, 31 Mar 2010 13:43:10 +0000 (13:43 +0000)
addattrs though.
(addvendorattr): New function, doing aobut the same as addvendorattr()
did.  Used by extractattr() too.
(extractattr): Add vendor field too (vendor:name:val).
(addrewrite): Handle "addvattrs" too -- AddVendorAttributes.
(confrewrite_cb): Add "addVendorAttribute".

git-svn-id: https://svn.testnett.uninett.no/radsecproxy/trunk@546 e88ac4ed-0b26-0410-9574-a7f39faa03bf

radsecproxy.c

index c058ac7..09adf63 100644 (file)
@@ -1092,15 +1092,21 @@ int dorewritemod(struct radmsg *msg, struct list *modattrs) {
 }
 
 int dorewrite(struct radmsg *msg, struct rewrite *rewrite) {
-    if (!rewrite)
+    int rv = 1;                        /* Success.  */
+
+    if (rewrite)
        return 1;
+
     if (rewrite->removeattrs || rewrite->removevendorattrs)
        dorewriterm(msg, rewrite->removeattrs, rewrite->removevendorattrs);
-    if (rewrite->addattrs && !dorewriteadd(msg, rewrite->addattrs))
-       return 0;
-    if (rewrite->modattrs && !dorewritemod(msg, rewrite->modattrs))
-       return 0;
-    return 1;
+    if (rewrite->modattrs)
+       if (!dorewritemod(msg, rewrite->modattrs))
+           rv = 0;
+    if (rewrite->addattrs)
+       if (!dorewriteadd(msg, rewrite->addattrs))
+           rv = 0;
+
+    return rv;
 }
 
 int rewriteusername(struct request *rq, struct tlv *attr) {
@@ -1116,23 +1122,37 @@ int rewriteusername(struct request *rq, struct tlv *attr) {
     return 1;
 }
 
-int addvendorattr(struct radmsg *msg, uint32_t vendor, struct tlv *attr) {
-    struct tlv *vattr;
+static struct tlv *
+makevendortlv(uint32_t vendor, const struct tlv *attr)
+{
+    struct tlv *newtlv = NULL;
     uint8_t l, *v;
 
     l = attr->l + 6;
     v = malloc(l);
     if (v) {
-       vendor = htonl(vendor);
+       vendor = htonl(vendor & 0x00ffffff); /* MSB=0 according to RFC 2865. */
        memcpy(v, &vendor, 4);
        tlv2buf(v + 4, attr);
        v[5] += 2;
-       vattr = maketlv(RAD_Attr_Vendor_Specific, l, v);
-       if (vattr && radmsg_add(msg, vattr))
-           return 1;
+       newtlv = maketlv(RAD_Attr_Vendor_Specific, l, v);
+       if (newtlv == NULL)
+           free(v);
+    }
+    return newtlv;
+}
+
+int addvendorattr(struct radmsg *msg, uint32_t vendor, struct tlv *attr) {
+    struct tlv *vattr;
+
+    vattr = makevendortlv(vendor, attr);
+    if (!vattr)
+       return 0;
+    if (!radmsg_add(msg, vattr)) {
        freetlv(vattr);
+       return 0;
     }
-    return 0;
+    return 1;
 }
 
 void addttlattr(struct radmsg *msg, uint32_t *attrtype, uint8_t addttl) {
@@ -2281,13 +2301,18 @@ uint8_t attrname2val(char *attrname) {
     return val > 0 && val < 256 ? val : 0;
 }
 
+/* ATTRNAME is on the form vendor[:type].
+   If only vendor is found, TYPE is set to 256 and 1 is returned.
+   If type is >= 256, 1 is returned.
+   Otherwise, 0 is returned.
+*/
 /* should accept both names and numeric values, only numeric right now */
 int vattrname2val(char *attrname, uint32_t *vendor, uint32_t *type) {
     char *s;
 
     *vendor = atoi(attrname);
     s = strchr(attrname, ':');
-    if (!s) {
+    if (!s) {                  /* Only vendor was found.  */
        *type = 256;
        return 1;
     }
@@ -2298,19 +2323,31 @@ int vattrname2val(char *attrname, uint32_t *vendor, uint32_t *type) {
 /* should accept both names and numeric values, only numeric right now */
 struct tlv *extractattr(char *nameval) {
     int len, name = 0;
-    char *s;
+    int vendor = 0;        /* Vendor 0 is reserved, see RFC 1700.  */
+    char *s, *s2;
     struct tlv *a;
 
     s = strchr(nameval, ':');
     name = atoi(nameval);
-    if (!s || name < 1 || name > 255)
+    if (!s)
        return NULL;
     len = strlen(s + 1);
     if (len > 253)
        return NULL;
+
+    s2 = strchr(s + 1, ':');
+    if (s2) {           /* Two ':' means we have vendor:name:val.  */
+       vendor = name;
+       name = atoi(s2 + 1);
+       s = s2;
+    }
+
+    if (name < 1 || name > 255)
+       return NULL;
     a = malloc(sizeof(struct tlv));
     if (!a)
        return NULL;
+
     a->v = (uint8_t *)stringcopy(s + 1, 0);
     if (!a->v) {
        free(a);
@@ -2318,6 +2355,10 @@ struct tlv *extractattr(char *nameval) {
     }
     a->t = name;
     a->l = len;
+
+    if (vendor)
+       a = makevendortlv(vendor, a);
+
     return a;
 }
 
@@ -2390,7 +2431,8 @@ struct rewrite *getrewrite(char *alt1, char *alt2) {
     return NULL;
 }
 
-void addrewrite(char *value, char **rmattrs, char **rmvattrs, char **addattrs, char **modattrs) {
+void addrewrite(char *value, char **rmattrs, char **rmvattrs, char **addattrs, char **addvattrs, char **modattrs)
+{
     struct rewrite *rewrite = NULL;
     int i, n;
     uint8_t *rma = NULL;
@@ -2439,6 +2481,21 @@ void addrewrite(char *value, char **rmattrs, char **rmvattrs, char **addattrs, c
        freegconfmstr(addattrs);
     }
 
+    if (addvattrs) {
+       if (!adda)
+           adda = list_create();
+       if (!adda)
+           debugx(1, DBG_ERR, "malloc failed");
+       for (i = 0; addvattrs[i]; i++) {
+           a = extractattr(addvattrs[i]);
+           if (!a)
+               debugx(1, DBG_ERR, "addrewrite: invalid attribute %s", addvattrs[i]);
+           if (!list_push(adda, a))
+               debugx(1, DBG_ERR, "malloc failed");
+       }
+       freegconfmstr(addvattrs);
+    }
+
     if (modattrs) {
        moda = list_create();
        if (!moda)
@@ -2917,7 +2974,9 @@ int confrealm_cb(struct gconffile **cf, void *arg, char *block, char *opt, char
 }
 
 int confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, char *val) {
-    char **rmattrs = NULL, **rmvattrs = NULL, **addattrs = NULL, **modattrs = NULL;
+    char **rmattrs = NULL, **rmvattrs = NULL;
+    char **addattrs = NULL, **addvattrs = NULL;
+    char **modattrs = NULL;
 
     debug(DBG_DBG, "confrewrite_cb called for %s", block);
 
@@ -2925,11 +2984,12 @@ int confrewrite_cb(struct gconffile **cf, void *arg, char *block, char *opt, cha
                          "removeAttribute", CONF_MSTR, &rmattrs,
                          "removeVendorAttribute", CONF_MSTR, &rmvattrs,
                          "addAttribute", CONF_MSTR, &addattrs,
+                         "addVendorAttribute", CONF_MSTR, &addvattrs,
                          "modifyAttribute", CONF_MSTR, &modattrs,
                          NULL
            ))
        debugx(1, DBG_ERR, "configuration error");
-    addrewrite(val, rmattrs, rmvattrs, addattrs, modattrs);
+    addrewrite(val, rmattrs, rmvattrs, addattrs, addvattrs, modattrs);
     return 1;
 }