}
request->client = client;
-
request->number = number++;
request->name = talloc_typed_asprintf(request, "%" PRIu64, request->number);
request->el = el;
return c;
}
+
+/** Search up a list of requests trying to locate one which has a client
+ *
+ */
+RADCLIENT *client_from_request(request_t *request)
+{
+ RADCLIENT *client;
+ request_t *parent = request;
+
+ do {
+ client = parent->client;
+ } while (!client && (parent = request->parent));
+
+ return client;
+}
RADCLIENT *client_read(char const *filename, CONF_SECTION *server_cs, bool check_dns);
+RADCLIENT *client_from_request(request_t *request);
#ifdef __cplusplus
}
#endif
*/
int request_detach(request_t *child)
{
- request_t *request = child->parent;
+ request_t *request = child->parent;
/*
* Already detached or not detachable
if (request_is_detached(child)) return 0;
if (!request_is_detachable(child)) {
- RERROR("Request is not detachable");
+ fr_strerror_const("Request is not detachable");
return -1;
}
#define request_is_external(_x) ((_x)->type == REQUEST_TYPE_EXTERNAL)
#define request_is_internal(_x) ((_x)->type == REQUEST_TYPE_INTERNAL)
#define request_is_detached(_x) ((_x)->type == REQUEST_TYPE_DETACHED)
-#define request_is_detachable(_x) ((_x)->flags.detachable == 1)
+#define request_is_detachable(_x) ((_x)->flags.detachable)
struct request_s {
#ifndef NDEBUG
case FR_SIGNAL_DETACH:
unlang_interpret_request_detach(request); /* Tell our caller that the request is being detached */
- request_detach(request); /* Finish detaching the request */
+ if (request_detach(request) < 0) RPEDEBUG("Failed detaching request");
break;
default:
* Detach the child, and insert
* it into the backlog.
*/
- if ((unlang_subrequest_lifetime_set(child) < 0) || (request_detach(request) < 0)) {
+ if ((unlang_subrequest_lifetime_set(child) < 0) || (request_detach(child) < 0)) {
+ request = child;
+ RPEDEBUG("Failed detaching request");
talloc_free(child);
RETURN_MODULE_FAIL;
return 0;
}
-int unlang_subrequest_child_push_and_detach(request_t *child)
+int unlang_subrequest_child_push_and_detach(request_t *request)
{
/*
* Ensures the child is setup correctly and adds
* it into the runnable queue of whatever owns
* the interpreter.
*/
- interpret_child_init(child);
+ interpret_child_init(request);
- if ((unlang_subrequest_lifetime_set(child) < 0) || (request_detach(child) < 0)) return -1;
+ if ((unlang_subrequest_lifetime_set(request) < 0) || (request_detach(request) < 0)) {
+ RPEDEBUG("Failed detaching request");
+ return -1;
+ }
return 0;
}
* Some non-packet expansions
*/
if (tmpl_da(vpt) == attr_client_shortname) {
- if (!request->client || !request->client->shortname) return XLAT_ACTION_DONE;
+ RADCLIENT *client = client_from_request(request);
+ if (!client || !client->shortname) return XLAT_ACTION_DONE;
MEM(value = fr_value_box_alloc_null(ctx));
- if (fr_value_box_bstrdup_buffer(ctx, value, tmpl_da(vpt), request->client->shortname, false) < 0) {
+ if (fr_value_box_bstrdup_buffer(ctx, value, tmpl_da(vpt), client->shortname, false) < 0) {
error:
talloc_free(value);
return XLAT_ACTION_FAIL;
fr_value_box_memdup(ctx, value, tmpl_da(vpt), packet->vector, sizeof(packet->vector), true);
} else if (tmpl_da(vpt) == attr_client_ip_address) {
- if (request->client) {
+ RADCLIENT *client = client_from_request(request);
+ if (client) {
MEM(value = fr_value_box_alloc_null(ctx));
- fr_value_box_ipaddr(value, NULL, &request->client->ipaddr, false); /* Enum might not match type */
+ fr_value_box_ipaddr(value, NULL, &client->ipaddr, false); /* Enum might not match type */
goto done;
}
goto src_ip_address;
/*
* Set the rest of the fields.
*/
- memcpy(&request->client, &client, sizeof(client)); /* const issues */
+ request->client = UNCONST(RADCLIENT *, client);
request->packet->socket = address->socket;
fr_socket_addr_swap(&request->reply->socket, &address->socket);
/*
* Set the rest of the fields.
*/
- memcpy(&request->client, &client, sizeof(client)); /* const issues */
+ request->client = UNCONST(RADCLIENT *, client);
request->packet->socket = address->socket;
fr_socket_addr_swap(&request->reply->socket, &address->socket);
/*
* Set the rest of the fields.
*/
- memcpy(&request->client, &client, sizeof(client)); /* const issues */
+ request->client = UNCONST(RADCLIENT *, client);
request->packet->socket = address->socket;
fr_socket_addr_swap(&request->reply->socket, &address->socket);
/*
* Set the rest of the fields.
*/
- memcpy(&request->client, &client, sizeof(client)); /* const issues */
+ request->client = UNCONST(RADCLIENT *, client);
request->packet->socket = address->socket;
fr_socket_addr_swap(&request->reply->socket, &address->socket);
/*
* Set the rest of the fields.
*/
- memcpy(&request->client, &client, sizeof(client)); /* const issues */
+ request->client = UNCONST(RADCLIENT *, client);
request->packet->socket = address->socket;
fr_socket_addr_swap(&request->reply->socket, &address->socket);
}
}
} else {
- client = request->client;
+ client = client_from_request(request);
+ if (!client) {
+ REDEBUG("No client associated with this request");
+ return RLM_MODULE_FAIL;
+ }
}
uctx.cs = client->cs;
return XLAT_ACTION_FAIL;
}
} else {
- client = request->client;
+ client = client_from_request(request);
if (!client) {
- RERROR("No client associated with this request");
- return XLAT_ACTION_FAIL;
+ REDEBUG("No client associated with this request");
+ return RLM_MODULE_FAIL;
}
}
cp = cf_pair_find(client->cs, field->vb_strvalue);
if (!cp || !(value = cf_pair_value(cp))) {
- if (strcmp(field->vb_strvalue, "shortname") == 0 && request->client->shortname) {
- value = request->client->shortname;
+ if (strcmp(field->vb_strvalue, "shortname") == 0 && client->shortname) {
+ value = client->shortname;
}
- else if (strcmp(field->vb_strvalue, "nas_type") == 0 && request->client->nas_type) {
- value = request->client->nas_type;
+ else if (strcmp(field->vb_strvalue, "nas_type") == 0 && client->nas_type) {
+ value = client->nas_type;
}
if (!value) return XLAT_ACTION_DONE;
}
*/
static unlang_action_t CC_HINT(nonnull) mod_authorize(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
{
- size_t length;
- char const *value;
- CONF_PAIR *cp;
- RADCLIENT *c;
- char buffer[2048];
+ size_t length;
+ char const *value;
+ CONF_PAIR *cp;
+ char buffer[2048];
+ RADCLIENT *client;
/*
* Ensure we're only being called from the main thread,
RETURN_MODULE_NOOP;
}
- if (!request->client || !request->client->cs) {
+ client = client_from_request(request);
+ if (!client || !client->cs) {
REDEBUG("Unknown client definition");
RETURN_MODULE_NOOP;
}
- cp = cf_pair_find(request->client->cs, "directory");
+ cp = cf_pair_find(client->cs, "directory");
if (!cp) {
REDEBUG("No directory configuration in the client");
RETURN_MODULE_NOOP;
/*
* Read the buffer and generate the client.
*/
- if (!request->client->server) RETURN_MODULE_FAIL;
+ if (!client->server) RETURN_MODULE_FAIL;
- c = client_read(buffer, request->client->server_cs, true);
- if (!c) RETURN_MODULE_FAIL;
+ client = client_read(buffer, client->server_cs, true);
+ if (!client) RETURN_MODULE_FAIL;
/*
* Replace the client. This is more than a bit of a
* hack.
*/
- request->client = c;
+ request->client = client;
RETURN_MODULE_OK;
}
rlm_opendirectory_t const *inst = talloc_get_type_abort_const(mctx->instance, rlm_opendirectory_t);
struct passwd *userdata = NULL;
int ismember = 0;
- RADCLIENT *rad_client = NULL;
+ RADCLIENT *client = NULL;
uuid_t uuid;
uuid_t guid_sacl;
uuid_t guid_nasgroup;
/* resolve client access list */
uuid_clear(guid_nasgroup);
- rad_client = request->client;
+ client = client_from_request(request);
#if 0
- if (rad_client->community[0] != '\0' ) {
+ if (client->community[0] != '\0' ) {
/*
* The "community" can be a GUID (Globally Unique ID) or
* a group name
*/
- if (uuid_parse(rad_client->community, guid_nasgroup) != 0) {
+ if (uuid_parse(client->community, guid_nasgroup) != 0) {
/* attempt to resolve the name */
- groupdata = getgrnam(rad_client->community);
+ groupdata = getgrnam(client->community);
if (!groupdata) {
- REDEBUG("The group \"%s\" does not exist on this system", rad_client->community);
+ REDEBUG("The group \"%s\" does not exist on this system", client->community);
RETURN_MODULE_FAIL;
}
err = mbr_gid_to_uuid(groupdata->gr_gid, guid_nasgroup);
if (err != 0) {
- REDEBUG("The group \"%s\" does not have a GUID", rad_client->community);
+ REDEBUG("The group \"%s\" does not have a GUID", client->community);
RETURN_MODULE_FAIL;
}
}
else
#endif
{
- if (!rad_client) {
+ if (!client) {
RDEBUG2("The client record could not be found for host %s",
fr_inet_ntoh(&request->packet->socket.inet.src_ipaddr, host_ipaddr, sizeof(host_ipaddr)));
} else {
rlm_radius_thread_t *t = talloc_get_type_abort(mctx->thread, rlm_radius_thread_t);
rlm_rcode_t rcode;
unlang_action_t ua;
+ RADCLIENT *client;
void *rctx = NULL;
RETURN_MODULE_FAIL;
}
- if (request->client->dynamic && !request->client->active) {
+ client = client_from_request(request);
+ if (client && client->dynamic && !client->active) {
REDEBUG("Cannot proxy packets which define dynamic clients");
RETURN_MODULE_FAIL;
}
char *filename = NULL;
char *expanded = NULL;
+ RADCLIENT *client;
if (request->dict != dict_radius) RETURN_MODULE_NOOP;
* originator's IP address.
*/
if (ut.nas_address == htonl(INADDR_NONE)) {
+ client = client_from_request(request);
+ if (!client) goto no_client;
+
ut.nas_address = request->packet->socket.inet.src_ipaddr.addr.v4.s_addr;
- nas = request->client->shortname;
+ nas = client->shortname;
} else if (request->packet->socket.inet.src_ipaddr.addr.v4.s_addr == ut.nas_address) { /* might be a client, might not be. */
- nas = request->client->shortname;
+ client = client_from_request(request);
+ if (!client) goto no_client;
+ nas = client->shortname;
/*
* The NAS isn't a client, it's behind
* a proxy server. In that case, just
* get the IP address.
*/
} else {
+ no_client:
nas = inet_ntop(AF_INET, &ut.nas_address, ip_name, sizeof(ip_name));
}
struct utmp ut;
time_t t;
char buf[64];
- char const *s;
+ char const *s = NULL;
int delay = 0;
int status = -1;
int nas_address = 0;
#endif
uint32_t nas_port = 0;
bool port_seen = true;
-
+ RADCLIENT *client;
/*
* No radwtmp. Don't do anything.
if (nas_address == 0) {
nas_address = request->packet->socket.inet.src_ipaddr.addr.v4.s_addr;
}
- s = request->client->shortname;
+
+ client = client_from_request(request);
+ if (client) s = client->shortname;
if (!s || s[0] == 0) s = uue(&(nas_address));
#ifdef __linux__
fr_pair_t *pair;
uint32_t port = 0; /* RFC 2865 NAS-Port is 4 bytes */
char const *tls = "";
+ RADCLIENT *client = client_from_request(request);
cli = fr_pair_find_by_da(&request->request_pairs, attr_calling_station_id);
if (request->packet->socket.inet.dst_port == 0) tls = " via proxy to virtual server";
snprintf(buf, buflen, "from client %.128s port %u%s%.128s%s",
- request->client->shortname, port,
+ client ? client->shortname : "", port,
(cli ? " cli " : ""), (cli ? cli->vp_strvalue : ""),
tls);