Accessing %{client:...} in C custom module
Hi. I finaly came to idea that huntgroups are evel and found this thread http://lists.freeradius.org/pipermail/freeradius-users/2014-February/070431.... that shows a way to set a custom attribute to for a client. The problem that is left as-is that I can not see any snippet in sources showing how this custom data could be evaluated in my custom module: this attribute is not shown in radiusd: #### Loading Clients #### config load section so I am totally out of ideas. Could anybody point me to the right spot in sources or show an example? -- Boris Lytochkin Yandex NOC +7 (495) 739 70 00 ext. 7671
On Mar 1, 2016, at 10:58 AM, Boris Lytochkin <lytboris@yandex-team.ru> wrote:
I finaly came to idea that huntgroups are evel and found this thread http://lists.freeradius.org/pipermail/freeradius-users/2014-February/070431.... that shows a way to set a custom attribute to for a client.
The problem that is left as-is that I can not see any snippet in sources showing how this custom data could be evaluated in my custom module: this attribute is not shown in radiusd: #### Loading Clients #### config load section so I am totally out of ideas.
Could anybody point me to the right spot in sources or show an example?
See request->client->cs You can use the conffile.c / conffile.h API to find anything you need. Alan DeKok.
Hi,
I finaly came to idea that huntgroups are evel and found this thread http://lists.freeradius.org/pipermail/freeradius-users/2014-February/070431.... that shows a way to set a custom attribute to for a client.
they are evil/wrong - and very very performance hitting - best to use the extra client attributes.
Could anybody point me to the right spot in sources or show an example?
Alan has already provided that answer :) alan
Hi. On 01.03.2016 19:22, A.L.M.Buxey@lboro.ac.uk wrote:
Could anybody point me to the right spot in sources or show an example? Alan has already provided that answer :)
OKay, trying naive mycp = cf_pair_find(request->client->cs, "group"); results in (gdb) p *mycp $2 = {item = {next = 0xa00000038, parent = 0x8034c2330, lineno = 805314604, filename = 0x800300034 <Error reading address 0x800300034: Bad address>, type = 1919181921}, attr = 0x0, value = 0xb0000003b <Error reading address 0xb0000003b: Bad address>, op = 172, lhs_type = T_INVALID, rhs_type = 73, pass2 = 19, parsed = false} For a client defined as client TEST { ipv4addr = ... secret = ... nastype = cisco group = "8021X" } Am I missing some tiny bits to make it work as expected? There are no references for these techniques in http://wiki.freeradius.org/contributing/Modules3 sorry for asking dumb questions. :) -- Boris Lytochkin Yandex NOC +7 (495) 739 70 00 ext. 7671
On Mar 1, 2016, at 12:58 PM, Boris Lytochkin <lytboris@yandex-team.ru> wrote:
OKay, trying naive
Thinking about it helps, too.
mycp = cf_pair_find(request->client->cs, "group");
Is request a valid pointer? Is request->client a valid pointer? Is request->client->cs a valid pointer?
results in (gdb) p *mycp $2 = {item = {next = 0xa00000038, parent = 0x8034c2330, lineno = 805314604, filename = 0x800300034 <Error reading address 0x800300034: Bad address>, type = 1919181921}, attr = 0x0, value = 0xb0000003b <Error reading address 0xb0000003b: Bad address>, op = 172, lhs_type = T_INVALID, rhs_type = 73, pass2 = 19, parsed = false}
Which is garbage data. You've walked off of the end of a pointer somewhere. Programming your own module require understanding C programming.
Am I missing some tiny bits to make it work as expected?
C programming.
There are no references for these techniques in http://wiki.freeradius.org/contributing/Modules3 sorry for asking dumb questions. :)
This isn't documented because (a) we don't have time to document everything, and (b) if you're programming your own module, we expect some ability to root through the header files and figure things out. Alan DeKok.
Hi. See inline. On 02.03.2016 4:28, Alan DeKok wrote:
On Mar 1, 2016, at 12:58 PM, Boris Lytochkin <lytboris@yandex-team.ru> wrote:
OKay, trying naive Thinking about it helps, too. Alan, you would never have to mention Code of Conduct some days before in freeradius-users@ maillist if you follow it yourself. All these lunges (there are 3 "hey, stupid"s in your e-mail I am replying to) do not help to solve any of the problems. Maillists are for helping each other, not to tell other people that they are idiots from your point of view. Please ignore this message completely if you do not want to help. Thanks.
Now to the issue.
mycp = cf_pair_find(request->client->cs, "group"); Is request a valid pointer? Is request->client a valid pointer? Is request->client->cs a valid pointer? Yes they are all valid.
results in (gdb) p *mycp $2 = {item = {next = 0xa00000038, parent = 0x8034c2330, lineno = 805314604, filename = 0x800300034 <Error reading address 0x800300034: Bad address>, type = 1919181921}, attr = 0x0, value = 0xb0000003b <Error reading address 0xb0000003b: Bad address>, op = 172, lhs_type = T_INVALID, rhs_type = 73, pass2 = 19, parsed = false} Which is garbage data. You've walked off of the end of a pointer somewhere. Well, that code is couple lines below after head of postauth function head: static rlm_rcode_t CC_HINT(nonnull) XXX_postauth(void *instance, REQUEST * request) { XXX_t *data = (XXX_t *)instance; VALUE_PAIR *vp; char mac[MAC_BUF_SIZE], nas[MAX_NAME_SIZE], username[MAX_NAME_SIZE]; char huntgroup[MAX_NAME_SIZE], ext[MAX_NAME_SIZE], *p, serial[50]; u_int nasport; enum media_type media_type; pthread_t tid; process_thread_param_t *pr;
RDEBUG("rules_injector_postauth"); if (request == NULL || request->packet == NULL || request->packet->vps == NULL) { radlog(L_ERR, "XXX: request without a packet?! Return NOOP."); return RLM_MODULE_NOOP; } if ((vp = pairfind(request->packet->vps, PW_NAS_PORT)) == NULL) { radlog(L_INFO, "XXX: Could not find port number in packet. Return NOOP."); return RLM_MODULE_NOOP; } nasport = vp->vp_integer; if ((vp = pairfind(request->packet->vps, PW_NAS_IP_ADDRESS)) == NULL) { radlog(L_INFO, "XXX: Could not find nas information in packet. Return NOOP."); return RLM_MODULE_NOOP; } inet_ntoa_r(*((struct in_addr *)&vp->vp_ipaddr), nas, sizeof(nas)); RDEBUG("NAS: %s, NAS port: %u", nas, nasport); if ((vp = pairfind(request->packet->vps, PW_USER_NAME)) == NULL) { radlog(L_INFO, "XXX[%u]: Could not find User-Name attribute. (NAS: %s)", nasport, nas); return RLM_MODULE_NOOP; } vp_prints_value(username, sizeof(username), vp, FALSE); strtolower(username); if ((p = strchr(username, '@')) != NULL) { *p = '\0'; } else { /* radlog(L_INFO, "XXX (post-auth)[%u]: User-Name without '@': %s. Ignored.", nasport, username); */ RDEBUG("XXX (post-auth)[%u]: User-Name without '@'. Ignored.", nasport); return RLM_MODULE_NOOP; } CONF_PAIR *mycp; mycp = cf_pair_find(request->client->cs, "group");
This isn't documented because (a) we don't have time to document everything, and (b) if you're programming your own module, we expect some ability to root through the header files and figure things out. As we agreed in some other thread, I would send a pull-request on that so someone would not have to spend much time for digging whole FreeRADIUS sources for this purpose in future.
-- Boris Lytochkin Yandex NOC +7 (495) 739 70 00 ext. 7671
... On 02.03.2016 9:54, Boris Lytochkin wrote:
mycp = cf_pair_find(request->client->cs, "group");
Is request a valid pointer? Is request->client a valid pointer? Is request->client->cs a valid pointer? Yes they are all valid.
results in (gdb) p *mycp $2 = {item = {next = 0xa00000038, parent = 0x8034c2330, lineno = 805314604, filename = 0x800300034 <Error reading address 0x800300034: Bad address>, type = 1919181921}, attr = 0x0, value = 0xb0000003b <Error reading address 0xb0000003b: Bad address>, op = 172, lhs_type = T_INVALID, rhs_type = 73, pass2 = 19, parsed = false} Which is garbage data. You've walked off of the end of a pointer somewhere. Tried using %{client:group} in radiusd.conf: ==== server default { ... # Authorization. authorize { preprocess auth_log reply_log suffix if (%{client:group} == "8021X") { eap } .... } ==== running radiusd -X will result in ==== ... (7) if (%{client:group} == "8021X") { (7) if (%{client:group} == "8021X") -> FALSE ... ==== And I am more than sure that `group` attribute is defined for this client.
Additionally, you can not check for attribute existence: /usr/local/etc/raddb/radiusd.conf[250]: Parse error in condition /usr/local/etc/raddb/radiusd.conf[250]: (%{client:group}) { /usr/local/etc/raddb/radiusd.conf[250]: ^ Expected a module return code Is this expected? I am playing with 3.0.10. -- Boris Lytochkin Yandex NOC +7 (495) 739 70 00 ext. 7671
suffix if (%{client:group} == "8021X") { eap } .... } ==== running radiusd -X will result in ==== ... (7) if (%{client:group} == "8021X") { (7) if (%{client:group} == "8021X") -> FALSE ... ==== And I am more than sure that `group` attribute is defined for this client.
Additionally, you can not check for attribute existence: /usr/local/etc/raddb/radiusd.conf[250]: Parse error in condition /usr/local/etc/raddb/radiusd.conf[250]: (%{client:group}) { /usr/local/etc/raddb/radiusd.conf[250]: ^ Expected a module return code
Try this: if ("%{client:group}" == '8021X') { : : :-) Stefan Paetow Moonshot Industry & Research Liaison Coordinator t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Networkshop44, University of Manchester. Save the date: 22-24 March, 2016. #NWS44 Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc¹s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Collections and Janet Ltd. is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under Company No. number 2881024, VAT No. GB 197 0632 86. The registered office is: Lumen House, Library Avenue, Harwell, Didcot, Oxfordshire, OX11 0SG. T 01235 822200.
On Wed, Mar 02, 2016 at 02:19:31PM +0300, Boris Lytochkin wrote:
On 02.03.2016 13:08, Stefan Paetow wrote:
Try this:
if ("%{client:group}" == '8021X') { That works, thanks :) Will go track how this is being expanded now.
It's an xlat, so look for the xlat_register function for it. ~/git/freeradius-server/src/main$ grep xlat * | grep client mainconfig.c:static ssize_t xlat_client(UNUSED void *instance, REQUEST *request, char const *fmt, char *out, size_t outlen) mainconfig.c:static ssize_t xlat_getclient(UNUSED void *instance, REQUEST *request, char const *fmt, char *out, size_t outlen)
mainconfig.c: xlat_register("client", xlat_client, NULL, NULL); <<< mainconfig.c: xlat_register("getclient", xlat_getclient, NULL, NULL); radclient.c: * xlat expansions aren't supported here radclient.c: vp->vp_strvalue = vp->value.xlat; radclient.c: * Double quoted strings get marked up as xlat expansions, radclient.c: vp->vp_strvalue = vp->value.xlat;
look at the xlat_client function in mainconfig.c Matthew -- Matthew Newton, Ph.D. <mcn4@le.ac.uk> Systems Specialist, Infrastructure Services, I.T. Services, University of Leicester, Leicester LE1 7RH, United Kingdom For IT help contact helpdesk extn. 2253, <ithelp@le.ac.uk>
Hi. Thanks. That was it. Correct code snippet (no checks though): CONF_PAIR *mycp; mycp = cf_pair_find(request->client->cs, "group"); p = cf_pair_value(mycp); This works fine even with garbage-like cs pointer: (gdb) p *request->client->cs $3 = {item = {next = 0xa00000038, parent = 0x803496330, lineno = 805314604, filename = 0x800300034 <Error reading address 0x800300034: Bad address>, type = 1919181921}, name1 = 0x0, name2 = 0xb0000003b <Error reading address 0xb0000003b: Bad address>, name2_type = 172, children = 0x1300000049, tail = 0x135, template = 0xb0000000b, pair_tree = 0x2aa30, section_tree = 0x100000012, name2_tree = 0x2aad0, data_tree = 0x600000040, base = 0x64f0, depth = 1, variables = 0x416} (gdb) p p $4 = 0x802e58ee0 "8021X" On 02.03.2016 14:35, Matthew Newton wrote:
On Wed, Mar 02, 2016 at 02:19:31PM +0300, Boris Lytochkin wrote:
On 02.03.2016 13:08, Stefan Paetow wrote:
Try this:
if ("%{client:group}" == '8021X') { That works, thanks :) Will go track how this is being expanded now. It's an xlat, so look for the xlat_register function for it.
~/git/freeradius-server/src/main$ grep xlat * | grep client mainconfig.c:static ssize_t xlat_client(UNUSED void *instance, REQUEST *request, char const *fmt, char *out, size_t outlen) mainconfig.c:static ssize_t xlat_getclient(UNUSED void *instance, REQUEST *request, char const *fmt, char *out, size_t outlen) mainconfig.c: xlat_register("client", xlat_client, NULL, NULL); <<< mainconfig.c: xlat_register("getclient", xlat_getclient, NULL, NULL); radclient.c: * xlat expansions aren't supported here radclient.c: vp->vp_strvalue = vp->value.xlat; radclient.c: * Double quoted strings get marked up as xlat expansions, radclient.c: vp->vp_strvalue = vp->value.xlat;
look at the xlat_client function in mainconfig.c
Matthew
-- Boris Lytochkin Yandex NOC +7 (495) 739 70 00 ext. 7671
On Mar 2, 2016, at 2:52 AM, Boris Lytochkin <lytboris@yandex-team.ru> wrote:
Tried using %{client:group} in radiusd.conf: ==== server default { ... # Authorization. authorize { preprocess auth_log reply_log suffix if (%{client:group} == "8021X") {
That syntax is wrong.
==== running radiusd -X will result in ==== ... (7) if (%{client:group} == "8021X") { (7) if (%{client:group} == "8021X") -> FALSE ... ==== And I am more than sure that `group` attribute is defined for this client.
That may be so. But the syntax is wrong. See "man unlang".
Additionally, you can not check for attribute existence: /usr/local/etc/raddb/radiusd.conf[250]: Parse error in condition /usr/local/etc/raddb/radiusd.conf[250]: (%{client:group}) { /usr/local/etc/raddb/radiusd.conf[250]: ^ Expected a module return code
Is this expected? I am playing with 3.0.10.
Yes, it's expected. It's documented. String expansions are done by using double quotes around the string to be expanded. All of the documentation and examples do this. I'll add another check and a WARNING message to catch this case, and explain what's wrong about it. You MUST use quotes: if ("%{client:group}" == "8021X") { Alan DeKok
Hi. I am trying to add some information on $subj to wiki.freeradius.org and get HTTP/500 persistenly. Can anybody push this section above `Adding a reply attribute` section: ========================== Accessing RADIUS client additional attributes ----------------------------------------- Configuration for a RADIUS client defined in clients.conf can hold arbitrary-named additional attributes. These attributes may be used for various reasons, for example, to specify client's group name. These additional attributes are accessible though XLAT expansion in radiusd.conf (``"%{client:...}"``). C module can access these attributes using: ```c CONF_PAIR *mycp; const char *value; mycp = cf_pair_find(request->client->cs, "group"); value = cf_pair_value(mycp); ``` It extracts ``group`` attribute defined as client TESTCLIENT { ipv4addr = 10.0.0.2 secret = mysupersecret nastype = other group = "mygroup" } ========================== ? Thanks. On 02.03.2016 16:17, Alan DeKok wrote:
On Mar 2, 2016, at 2:52 AM, Boris Lytochkin <lytboris@yandex-team.ru> wrote:
Tried using %{client:group} in radiusd.conf: ==== server default { ... # Authorization. authorize { preprocess auth_log reply_log suffix if (%{client:group} == "8021X") { That syntax is wrong.
==== running radiusd -X will result in ==== ... (7) if (%{client:group} == "8021X") { (7) if (%{client:group} == "8021X") -> FALSE ... ==== And I am more than sure that `group` attribute is defined for this client. That may be so. But the syntax is wrong. See "man unlang".
Additionally, you can not check for attribute existence: /usr/local/etc/raddb/radiusd.conf[250]: Parse error in condition /usr/local/etc/raddb/radiusd.conf[250]: (%{client:group}) { /usr/local/etc/raddb/radiusd.conf[250]: ^ Expected a module return code
Is this expected? I am playing with 3.0.10. Yes, it's expected. It's documented.
String expansions are done by using double quotes around the string to be expanded. All of the documentation and examples do this.
I'll add another check and a WARNING message to catch this case, and explain what's wrong about it.
You MUST use quotes:
if ("%{client:group}" == "8021X") {
Alan DeKok
- List info/subscribe/unsubscribe? See http://www.freeradius.org/list/devel.html
-- Boris Lytochkin Yandex NOC +7 (495) 739 70 00 ext. 7671
I am trying to add some information on $subj to wiki.freeradius.org and get HTTP/500 persistenly.
Alan, Arran, I get the same (I'm logged in through Github). Stefan Paetow Moonshot Industry & Research Liaison Coordinator t: +44 (0)1235 822 125 gpg: 0x3FCE5142 xmpp: stefanp@jabber.dev.ja.net skype: stefan.paetow.janet jisc.ac.uk Networkshop44, University of Manchester. Save the date: 22-24 March, 2016. #NWS44 Jisc is a registered charity (number 1149740) and a company limited by guarantee which is registered in England under Company No. 5747339, VAT No. GB 197 0632 86. Jisc’s registered office is: One Castlepark, Tower Hill, Bristol, BS2 0JA. T 0203 697 5800. Jisc Collections and Janet Ltd. is a wholly owned Jisc subsidiary and a company limited by guarantee which is registered in England under Company No. number 2881024, VAT No. GB 197 0632 86. The registered office is: Lumen House, Library Avenue, Harwell, Didcot, Oxfordshire, OX11 0SG. T 01235 822200.
On 3 Mar 2016, at 09:05, Stefan Paetow <Stefan.Paetow@jisc.ac.uk> wrote:
I am trying to add some information on $subj to wiki.freeradius.org and get HTTP/500 persistenly.
Alan, Arran, I get the same (I'm logged in through Github).
What are you doing exactly? I just managed to create a new page fine... -Arran Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
Hi. On 03.03.2016 17:13, Arran Cudbard-Bell wrote:
What are you doing exactly? I just managed to create a new page fine...
I am trying to edit http://wiki.freeradius.org/contributing/Modules3 Logged in though github. -- Boris Lytochkin Yandex NOC +7 (495) 739 70 00 ext. 7671
On 3 Mar 2016, at 10:23, Boris Lytochkin <lytboris@yandex-team.ru> wrote:
Hi.
On 03.03.2016 17:13, Arran Cudbard-Bell wrote:
What are you doing exactly? I just managed to create a new page fine...
I am trying to edit http://wiki.freeradius.org/contributing/Modules3 Logged in though github.
Should be fixed now. Thanks for bringing it to our attention. -Arran Arran Cudbard-Bell <a.cudbardb@freeradius.org> FreeRADIUS development team FD31 3077 42EC 7FCD 32FE 5EE2 56CF 27F9 30A8 CAA2
On Mar 2, 2016, at 1:54 AM, Boris Lytochkin <lytboris@yandex-team.ru> wrote:
Alan, you would never have to mention Code of Conduct some days before in freeradius-users@ maillist if you follow it yourself. All these lunges (there are 3 "hey, stupid"s in your e-mail I am replying to) do not help to solve any of the problems. Maillists are for helping each other, not to tell other people that they are idiots from your point of view. Please ignore this message completely if you do not want to help. Thanks.
As I said earlier... complaining about people helping you is not acceptable. To be clear: If you're writing a module in C, it is expected that you know how to use C. You should know how to look at C header files. You should know how to debug programs. In addition, if you're writing a module... you should contribute it back to the project so that everyone else can use it, too. If you're not going to contribute it back, then it's *your* module, and *your* problem to fix.
Is request a valid pointer? Is request->client a valid pointer? Is request->client->cs a valid pointer? Yes they are all valid.
But the pointer is pointing to garbage memory. That doesn't sound like it's valid to me.
As we agreed in some other thread, I would send a pull-request on that so someone would not have to spend much time for digging whole FreeRADIUS sources for this purpose in future.
If you're going to write a proprietary module and not contribute it back... then it's *your* module. Alan DeKok.
participants (6)
-
A.L.M.Buxey@lboro.ac.uk -
Alan DeKok -
Arran Cudbard-Bell -
Boris Lytochkin -
Matthew Newton -
Stefan Paetow