Ejemplo n.º 1
0
Client * client_new(Window win)
{
    Client *c;
    long supplied;
    Atom win_type;

    XGetWindowAttributes(display, win, &attr);

    if (attr.override_redirect) return NULL;
    if (c = client_find(win)) return NULL;

    c = malloc(sizeof *c);
    c->next = head;
    head = c;

    c->win = win;

    c->name = ewmh_get_text(c, WM_NAME);
    c->geom.x = attr.x;
    c->geom.y = 16;
    c->geom.w = attr.width;
    c->geom.h = attr.height;

    XGetWMNormalHints(display, c->win, &c->size, &supplied);
    XGetTransientForHint(display, c->win, &c->trans);

    return c;
}
Ejemplo n.º 2
0
/*
 *	Xlat for %{getclient:<ipaddr>.foo}
 */
static ssize_t xlat_getclient(UNUSED void *instance, REQUEST *request, char const *fmt, char *out, size_t outlen)
{
	char const *value = NULL;
	char buffer[INET6_ADDRSTRLEN], *q;
	char const *p = fmt;
	fr_ipaddr_t ip;
	CONF_PAIR *cp;
	RADCLIENT *client = NULL;

	if (!fmt || !out || (outlen < 1)) return 0;

	q = strrchr(p, '.');
	if (!q || (q == p) || (((size_t)(q - p)) > sizeof(buffer))) {
		REDEBUG("Invalid client string");
		goto error;
	}

	strlcpy(buffer, p, (q + 1) - p);
	memset(&ip, 0, sizeof(ip));

	if (ip_ptonx(buffer, &ip) <= 0) {
		REDEBUG("\"%s\" is not a valid IPv4 or IPv6 address", buffer);
		goto error;
	}

	fmt = q + 1;

	client = client_find(NULL, &ip, IPPROTO_IP);
	if (!client) {
		RDEBUG("No client found with IP \"%s\"", buffer);
		*out = '\0';
		return 0;
	}

	cp = cf_pair_find(client->cs, fmt);
	if (!cp || !(value = cf_pair_value(cp))) {
		if (strcmp(fmt, "shortname") == 0) {
			strlcpy(out, request->client->shortname, outlen);
			return strlen(out);
		}
		RDEBUG("Client does not contain config item \"%s\"", fmt);
		*out = '\0';
		return 0;
	}

	strlcpy(out, value, outlen);
	return strlen(out);

error:
	*out = '\0';
	return -1;
}
Ejemplo n.º 3
0
static const char *getsecret(uint32_t server)
{
	RADCLIENT *cl;

	cl = client_find(server);
	if (cl == NULL) {
		char buf[32];
		radlog(L_ERR|L_CONS, "No clients entry for %s",
		       ip_ntoa(buf,server));
		exit(1);
	}
	return (const char *)cl->secret;
}
Ejemplo n.º 4
0
static void db_discovery_evt_handler(ble_db_discovery_evt_t * p_evt)
{
    // Find the client using the connection handle.
    client_t * p_client;
    uint32_t   index;
    bool       is_valid_srv_found = false;

    index = client_find(p_evt->conn_handle);
    p_client = &m_client[index];
   
    if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
    {
        uint8_t i;

        for (i = 0; i < p_evt->params.discovered_db.char_count; i++)
        {
            ble_db_discovery_char_t * p_characteristic;

            p_characteristic = &(p_evt->params.discovered_db.charateristics[i]);

            //See if this is the Ms. Pacman service
            if ((p_characteristic->characteristic.uuid.uuid == BLE_MS_PACMAN_CHARACTERISTIC_UUID)
                &&
                (p_characteristic->characteristic.uuid.type == m_base_uuid_type_ms_pacman))
            {
                // Characteristic found. Store the information needed and break.

                p_client->char_index = i;
                break;
            }
            //See if this is the Nunchuck service
            else if ((p_characteristic->characteristic.uuid.uuid == BLE_NUNCHUCK_CHARACTERISTIC_UUID)
                &&
                (p_characteristic->characteristic.uuid.type == m_base_uuid_type_nunchuck))
            {
                // Characteristic found. Store the information needed and break.

                p_client->char_index = i;
                is_valid_srv_found   = true;
                break;
            }
        }
    }

    //Only enable notifications if it is the Nunchuck characteristic
    if (is_valid_srv_found)
    {
        // Enable notification. Maybe don't do this??
        notif_enable(p_client);
    }
}
Ejemplo n.º 5
0
/*
 *	Xlat for %{client:[<ipaddr>.]foo}
 */
static ssize_t xlat_client(TALLOC_CTX *ctx, char **out, UNUSED size_t outlen,
			   UNUSED void const *mod_inst, UNUSED void const *xlat_inst,
			   REQUEST *request, char const *fmt)
{
	char const	*value = NULL;
	char		buffer[INET6_ADDRSTRLEN], *q;
	char const	*p = fmt;
	fr_ipaddr_t	ip;
	CONF_PAIR	*cp;
	RADCLIENT	*client = NULL;

	*out = NULL;

	q = strrchr(p, '.');
	if (q) {
		strlcpy(buffer, p, (q + 1) - p);
		if (fr_inet_pton(&ip, buffer, -1, AF_UNSPEC, false, true) < 0) goto request_client;

		p = q + 1;

		client = client_find(NULL, &ip, IPPROTO_IP);
		if (!client) {
			RDEBUG("No client found with IP \"%s\"", buffer);
			return 0;
		}
	} else {
	request_client:
		client = request->client;
		if (!client) {
			RERROR("No client associated with this request");

			return -1;
		}
	}

	cp = cf_pair_find(client->cs, p);
	if (!cp || !(value = cf_pair_value(cp))) {
		if (strcmp(fmt, "shortname") == 0 && request->client->shortname) {
			value = request->client->shortname;
		}
		else if (strcmp(fmt, "nas_type") == 0 && request->client->nas_type) {
			value = request->client->nas_type;
		}
		if (!value) return 0;
	}

	*out = talloc_typed_strdup(ctx, value);
	return talloc_array_length(*out) - 1;
}
Ejemplo n.º 6
0
Code_t
client_register(ZNotice_t *notice,
		struct in_addr *host,
		Client **client_p,
		int wantdefaults)
{
    Client *client;

    /* chain the client's host onto this server's host list */

    zdbug((LOG_DEBUG, "client_register: adding %s at %s/%d",
	   notice->z_sender, inet_ntoa(*host), ntohs(notice->z_port)));

    if (!notice->z_port)
	return ZSRV_BADSUBPORT;

    *client_p = client = client_find(host, notice->z_port);
    if (!client) {
	*client_p = client = (Client *) malloc(sizeof(Client));
	if (!client)
	    return ENOMEM;
	memset(&client->addr, 0, sizeof(struct sockaddr_in));
#ifdef HAVE_KRB5
        client->session_keyblock = NULL;
#else
#ifdef HAVE_KRB4
	memset(&client->session_key, 0, sizeof(client->session_key));
#endif
#endif
	client->last_send = 0;
	client->last_ack = NOW;
	client->addr.sin_family = AF_INET;
	client->addr.sin_addr.s_addr = host->s_addr;
	client->addr.sin_port = notice->z_port;
	client->subs = NULL;
	client->realm = NULL;
	client->principal = make_string(notice->z_sender, 0);
	Client_insert(&client_bucket[INET_HASH(&client->addr.sin_addr,
					       notice->z_port)], client);
    }

    /* Add default subscriptions only if this is not resulting from a brain
     * dump, AND this request wants defaults. */
    if (!bdumping && wantdefaults)
	return subscr_def_subs(client);
    else
	return ZERR_NONE;
}
Ejemplo n.º 7
0
int duplicate(struct params *p, struct ieee80211_frame *wh, int rc)
{
	struct client *c;
	int s;

	if (!frame_type(wh, IEEE80211_FC0_TYPE_DATA,
			IEEE80211_FC0_SUBTYPE_DATA))
		return 0;

	s = seqno(wh);

	c = client_find(p, wh->i_addr2);
	if (!c) {
		c = malloc(sizeof(*c));
		if (!c)
			err(1, "malloc()");

		memset(c, 0, sizeof(*c));
		memcpy(c->mac, wh->i_addr2, 6);

		c->seq = s-1;
		client_insert(p, c);
	}

	if (wh->i_fc[1] & IEEE80211_FC1_RETRY) {
		if ( (s <= c->seq) && ((c->seq - s ) < 5)) {
#if 0
			printf("Dup seq %d prev %d\n",
			       s, c->seq);
#endif
			return 1;
		}	
	}	

#if 0
	do {
		char mac[3*6];

		mac2str(mac, c->mac);
		printf("%s seq %d prev %d\n", mac, s, c->seq);
	} while (0);
#endif
	
	c->seq = s;
	return 0;
}
Ejemplo n.º 8
0
static void db_discovery_evt_handler(ble_db_discovery_evt_t * p_evt)
{
    // Find the client using the connection handle.
    client_t * p_client;
    uint32_t   index;
    bool       is_valid_srv_found = false;

    index = client_find(p_evt->conn_handle);
    p_client = &m_client[index];

    if (p_evt->evt_type == BLE_DB_DISCOVERY_COMPLETE)
    {
        uint8_t i;

        for (i = 0; i < p_evt->params.discovered_db.char_count; i++)
        {
            ble_gatt_db_char_t * p_characteristic;

            p_characteristic = &(p_evt->params.discovered_db.charateristics[i]);

            if ((p_characteristic->characteristic.uuid.uuid == MULTILINK_PERIPHERAL_CHAR_UUID)
                &&
                (p_characteristic->characteristic.uuid.type == m_base_uuid_type))
            {
                // Characteristic found. Store the information needed and break.

                p_client->char_index = i;
                is_valid_srv_found   = true;
                break;
            }
        }
    }

    if (is_valid_srv_found)
    {
        // Enable notification.
        notif_enable(p_client);
    }
    else
    {
        p_client->state = STATE_ERROR;
    }
}
Ejemplo n.º 9
0
void workspace_client_moveto_bindable(XEvent *xevent, arglist *args)
{
    unsigned int ws;
    client_t *client;

    client = client_find(event_window(xevent));
    if (args != NULL && args->arglist_arg->type_type == INTEGER) {
        ws = args->arglist_arg->type_value.intval;
    } else {
        fprintf(stderr, "AHWM: type error\n"); /* can't happen */
        return;
    }
    if (client == NULL) {
        fprintf(stderr,
                "AHWM: can't move client to workspace %d, can't find client\n",
                ws);
        return;
    }
    workspace_client_moveto(client, ws);
}
Ejemplo n.º 10
0
void client_handling_ble_evt_handler(ble_evt_t * p_ble_evt)
{
    client_t * p_client = NULL;

    uint32_t index = client_find(p_ble_evt->evt.gattc_evt.conn_handle);
    if (index != MAX_CLIENTS)
    {
       p_client = &m_client[index];
    }

    switch (p_ble_evt->header.evt_id)
    {
        case BLE_GATTC_EVT_WRITE_RSP:
            if ((p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_AUTHENTICATION) ||
                (p_ble_evt->evt.gattc_evt.gatt_status == BLE_GATT_STATUS_ATTERR_INSUF_ENCRYPTION))
            {
                uint32_t err_code = dm_security_setup_req(&p_client->handle);
                APP_ERROR_CHECK(err_code);

            }
            on_evt_write_rsp(p_ble_evt, p_client);
            break;

        case BLE_GATTC_EVT_HVX:
            on_evt_hvx(p_ble_evt, p_client, index);
            break;

        case BLE_GATTC_EVT_TIMEOUT:
            on_evt_timeout(p_ble_evt, p_client);
            break;

        default:
            break;
    }


    if (p_client != NULL)
    {
        ble_db_discovery_on_ble_evt(&(p_client->srv_db), p_ble_evt);
    }
}
Ejemplo n.º 11
0
void
screen_updatestackingorder(struct screen_ctx *sc)
{
	Window			*wins, w0, w1;
	struct client_ctx	*cc;
	unsigned int		 nwins, i, s;

	if (!XQueryTree(X_Dpy, sc->rootwin, &w0, &w1, &wins, &nwins))
		return;

	for (s = 0, i = 0; i < nwins; i++) {
		/* Skip hidden windows */
		if ((cc = client_find(wins[i])) == NULL ||
		    cc->flags & CLIENT_HIDDEN)
			continue;

		cc->stackingorder = s++;
	}

	XFree(wins);
}
Ejemplo n.º 12
0
/** Add a client to a RADCLIENT_LIST
 *
 * @param clients list to add client to, may be NULL if global client list is being used.
 * @param client to add.
 * @return true on success, false on failure.
 */
bool client_add(RADCLIENT_LIST *clients, RADCLIENT *client)
{
	RADCLIENT *old;
	char buffer[INET6_ADDRSTRLEN + 3];

	if (!client) return false;

	/*
	 *	Hack to fixup wildcard clients
	 *
	 *	If the IP is all zeros, with a 32 or 128 bit netmask
	 *	assume the user meant to configure 0.0.0.0/0 instead
	 *	of 0.0.0.0/32 - which would require the src IP of
	 *	the client to be all zeros.
	 */
	if (fr_inaddr_any(&client->ipaddr) == 1) switch (client->ipaddr.af) {
	case AF_INET:
		if (client->ipaddr.prefix == 32) client->ipaddr.prefix = 0;
		break;

	case AF_INET6:
		if (client->ipaddr.prefix == 128) client->ipaddr.prefix = 0;
		break;

	default:
		rad_assert(0);
	}

	fr_ntop(buffer, sizeof(buffer), &client->ipaddr);
	DEBUG3("Adding client %s (%s) to prefix tree %i", buffer, client->longname, client->ipaddr.prefix);

	/*
	 *	If the client also defines a server, do that now.
	 */
	if (client->defines_coa_server) if (!realm_home_server_add(client->coa_server)) return false;

	/*
	 *	If "clients" is NULL, it means add to the global list,
	 *	unless we're trying to add it to a virtual server...
	 */
	if (!clients) {
		if (client->server != NULL) {
			CONF_SECTION *cs;

			cs = cf_section_sub_find_name2(main_config.config, "server", client->server);
			if (!cs) {
				ERROR("Failed to find virtual server %s", client->server);
				return false;
			}

			/*
			 *	If the client list already exists, use that.
			 *	Otherwise, create a new client list.
			 */
			clients = cf_data_find(cs, "clients");
			if (!clients) {
				clients = client_list_init(cs);
				if (!clients) {
					ERROR("Out of memory");
					return false;
				}

				if (cf_data_add(cs, "clients", clients, (void (*)(void *)) client_list_free) < 0) {
					ERROR("Failed to associate clients with virtual server %s", client->server);
					client_list_free(clients);
					return false;
				}
			}

		} else {
			/*
			 *	Initialize the global list, if not done already.
			 */
			if (!root_clients) {
				root_clients = client_list_init(NULL);
				if (!root_clients) return false;
			}
			clients = root_clients;
		}
	}

	/*
	 *	Create a tree for it.
	 */
	if (!clients->trees[client->ipaddr.prefix]) {
		clients->trees[client->ipaddr.prefix] = rbtree_create(clients, client_ipaddr_cmp, NULL, 0);
		if (!clients->trees[client->ipaddr.prefix]) {
			return false;
		}
	}

#define namecmp(a) ((!old->a && !client->a) || (old->a && client->a && (strcmp(old->a, client->a) == 0)))

	/*
	 *	Cannot insert the same client twice.
	 */
	old = rbtree_finddata(clients->trees[client->ipaddr.prefix], client);
	if (old) {
		/*
		 *	If it's a complete duplicate, then free the new
		 *	one, and return "OK".
		 */
		if ((fr_ipaddr_cmp(&old->ipaddr, &client->ipaddr) == 0) &&
		    (old->ipaddr.prefix == client->ipaddr.prefix) &&
		    namecmp(longname) && namecmp(secret) &&
		    namecmp(shortname) && namecmp(nas_type) &&
		    namecmp(login) && namecmp(password) && namecmp(server) &&
#ifdef WITH_DYNAMIC_CLIENTS
		    (old->lifetime == client->lifetime) &&
		    namecmp(client_server) &&
#endif
#ifdef WITH_COA
		    namecmp(coa_name) &&
		    (old->coa_server == client->coa_server) &&
		    (old->coa_pool == client->coa_pool) &&
#endif
		    (old->message_authenticator == client->message_authenticator)) {
			WARN("Ignoring duplicate client %s", client->longname);
			client_free(client);
			return true;
		}

		ERROR("Failed to add duplicate client %s", client->shortname);
		return false;
	}
#undef namecmp

	/*
	 *	Other error adding client: likely is fatal.
	 */
	if (!rbtree_insert(clients->trees[client->ipaddr.prefix], client)) {
		return false;
	}

#ifdef WITH_STATS
	if (!tree_num) {
		tree_num = rbtree_create(clients, client_num_cmp, NULL, 0);
	}

#ifdef WITH_DYNAMIC_CLIENTS
	/*
	 *	More catching of clients added by rlm_sql.
	 *
	 *	The sql modules sets the dynamic flag BEFORE calling
	 *	us.  The client_afrom_request() function sets it AFTER
	 *	calling us.
	 */
	if (client->dynamic && (client->lifetime == 0)) {
		RADCLIENT *network;

		/*
		 *	If there IS an enclosing network,
		 *	inherit the lifetime from it.
		 */
		network = client_find(clients, &client->ipaddr, client->proto);
		if (network) {
			client->lifetime = network->lifetime;
		}
	}
#endif

	client->number = tree_num_max;
	tree_num_max++;
	if (tree_num) rbtree_insert(tree_num, client);
#endif

	if (client->ipaddr.prefix < clients->min_prefix) {
		clients->min_prefix = client->ipaddr.prefix;
	}

	(void) talloc_steal(clients, client); /* reparent it */

	return true;
}
Ejemplo n.º 13
0
/*
 *	Add a client to the tree.
 */
int client_add(RADCLIENT_LIST *clients, RADCLIENT *client)
{
	RADCLIENT *old;
	char buffer[INET6_ADDRSTRLEN + 3];

	if (!client) {
		return 0;
	}

	/*
	 *	Hack to fixup wildcard clients
	 */
	if (is_wildcard(&client->ipaddr)) client->ipaddr.prefix = 0;

	fr_ntop(buffer, sizeof(buffer), &client->ipaddr);
	DEBUG3("Adding client %s (%s) to prefix tree %i", buffer, client->longname, client->ipaddr.prefix);

	/*
	 *	If "clients" is NULL, it means add to the global list.
	 */
	if (!clients) {
		/*
		 *	Initialize it, if not done already.
		 */
		if (!root_clients) {
			root_clients = clients_init(NULL);
			if (!root_clients) return 0;
		}
		clients = root_clients;
	}

	/*
	 *	Create a tree for it.
	 */
	if (!clients->trees[client->ipaddr.prefix]) {
		clients->trees[client->ipaddr.prefix] = rbtree_create(client_ipaddr_cmp, NULL, 0);
		if (!clients->trees[client->ipaddr.prefix]) {
			return 0;
		}
	}

#define namecmp(a) ((!old->a && !client->a) || (old->a && client->a && (strcmp(old->a, client->a) == 0)))

	/*
	 *	Cannot insert the same client twice.
	 */
	old = rbtree_finddata(clients->trees[client->ipaddr.prefix], client);
	if (old) {
		/*
		 *	If it's a complete duplicate, then free the new
		 *	one, and return "OK".
		 */
		if ((fr_ipaddr_cmp(&old->ipaddr, &client->ipaddr) == 0) &&
		    (old->ipaddr.prefix == client->ipaddr.prefix) &&
		    namecmp(longname) && namecmp(secret) &&
		    namecmp(shortname) && namecmp(nas_type) &&
		    namecmp(login) && namecmp(password) && namecmp(server) &&
#ifdef WITH_DYNAMIC_CLIENTS
		    (old->lifetime == client->lifetime) &&
		    namecmp(client_server) &&
#endif
#ifdef WITH_COA
		    namecmp(coa_name) &&
		    (old->coa_server == client->coa_server) &&
		    (old->coa_pool == client->coa_pool) &&
#endif
		    (old->message_authenticator == client->message_authenticator)) {
			WARN("Ignoring duplicate client %s", client->longname);
			client_free(client);
			return 1;
		}

		ERROR("Failed to add duplicate client %s",
		       client->shortname);
		return 0;
	}
#undef namecmp

	/*
	 *	Other error adding client: likely is fatal.
	 */
	if (!rbtree_insert(clients->trees[client->ipaddr.prefix], client)) {
		return 0;
	}

#ifdef WITH_STATS
	if (!tree_num) {
		tree_num = rbtree_create(client_num_cmp, NULL, 0);
	}

#ifdef WITH_DYNAMIC_CLIENTS
	/*
	 *	More catching of clients added by rlm_sql.
	 *
	 *	The sql modules sets the dynamic flag BEFORE calling
	 *	us.  The client_from_request() function sets it AFTER
	 *	calling us.
	 */
	if (client->dynamic && (client->lifetime == 0)) {
		RADCLIENT *network;

		/*
		 *	If there IS an enclosing network,
		 *	inherit the lifetime from it.
		 */
		network = client_find(clients, &client->ipaddr, client->proto);
		if (network) {
			client->lifetime = network->lifetime;
		}
	}
#endif

	client->number = tree_num_max;
	tree_num_max++;
	if (tree_num) rbtree_insert(tree_num, client);
#endif

	if (client->ipaddr.prefix < clients->min_prefix) {
		clients->min_prefix = client->ipaddr.prefix;
	}

	(void) talloc_steal(clients, client); /* reparent it */

	return 1;
}
Ejemplo n.º 14
0
static void request_stats_reply(REQUEST *request)
{
	VALUE_PAIR *flag, *vp;

	/*
	 *	Statistics are available ONLY on a "status" port.
	 */
	rad_assert(request->packet->code == PW_STATUS_SERVER);
	rad_assert(request->listener->type == RAD_LISTEN_NONE);
		
	flag = pairfind(request->packet->vps, FR2ATTR(127));
	if (!flag || (flag->vp_integer == 0)) return;

	/*
	 *	Authentication.
	 */
	if (((flag->vp_integer & 0x01) != 0) &&
	    ((flag->vp_integer & 0xc0) == 0)) {
		request_stats_addvp(request, authvp, &radius_auth_stats);
	}
		
#ifdef WITH_ACCOUNTING
	/*
	 *	Accounting
	 */
	if (((flag->vp_integer & 0x02) != 0) &&
	    ((flag->vp_integer & 0xc0) == 0)) {
		request_stats_addvp(request, acctvp, &radius_acct_stats);
	}
#endif

#ifdef WITH_PROXY
	/*
	 *	Proxied authentication requests.
	 */
	if (((flag->vp_integer & 0x04) != 0) &&
	    ((flag->vp_integer & 0x20) == 0)) {
		request_stats_addvp(request, proxy_authvp, &proxy_auth_stats);
	}

#ifdef WITH_ACCOUNTING
	/*
	 *	Proxied accounting requests.
	 */
	if (((flag->vp_integer & 0x08) != 0) &&
	    ((flag->vp_integer & 0x20) == 0)) {
		request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats);
	}
#endif
#endif

	/*
	 *	Internal server statistics
	 */
	if ((flag->vp_integer & 0x10) != 0) {
		vp = radius_paircreate(request, &request->reply->vps,
				       FR2ATTR(176), PW_TYPE_DATE);
		if (vp) vp->vp_date = radius_start_time.tv_sec;
		vp = radius_paircreate(request, &request->reply->vps,
				       FR2ATTR(177), PW_TYPE_DATE);
		if (vp) vp->vp_date = radius_hup_time.tv_sec;
		
#ifdef HAVE_PTHREAD_H
		int i, array[RAD_LISTEN_MAX];

		thread_pool_queue_stats(array);

		for (i = 0; i <= RAD_LISTEN_DETAIL; i++) {
			vp = radius_paircreate(request, &request->reply->vps,
					       FR2ATTR(162 + i),
					       PW_TYPE_INTEGER);
			
			if (!vp) continue;
			vp->vp_integer = array[i];
		}
#endif
	}

	/*
	 *	For a particular client.
	 */
	if ((flag->vp_integer & 0x20) != 0) {
		fr_ipaddr_t ipaddr;
		VALUE_PAIR *server_ip, *server_port = NULL;
		RADCLIENT *client = NULL;
		RADCLIENT_LIST *cl = NULL;

		/*
		 *	See if we need to look up the client by server
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, FR2ATTR(170));
		if (server_ip) {
			server_port = pairfind(request->packet->vps,
					       FR2ATTR(171));

			if (server_port) {
				ipaddr.af = AF_INET;
				ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
				cl = listener_find_client_list(&ipaddr, server_port->vp_integer);
							       
				/*
				 *	Not found: don't do anything
				 */
				if (!cl) return;
			}
		}


		vp = pairfind(request->packet->vps, FR2ATTR(167));
		if (vp) {
			ipaddr.af = AF_INET;
			ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
			client = client_find(cl, &ipaddr);

			/*
			 *	Else look it up by number.
			 */
		} else if ((vp = pairfind(request->packet->vps,
					   FR2ATTR(168))) != NULL) {
			client = client_findbynumber(cl, vp->vp_integer);
		}

		if (client) {
			/*
			 *	If found, echo it back, along with
			 *	the requested statistics.
			 */
			pairadd(&request->reply->vps, paircopyvp(vp));

			/*
			 *	When retrieving client by number, also
			 *	echo back it's IP address.
			 */
			if ((vp->type == PW_TYPE_INTEGER) &&
			    (client->ipaddr.af == AF_INET)) {
				vp = radius_paircreate(request,
						       &request->reply->vps,
						       FR2ATTR(167),
						       PW_TYPE_IPADDR);
				if (vp) {
					vp->vp_ipaddr = client->ipaddr.ipaddr.ip4addr.s_addr;
				}

				if (client->prefix != 32) {
					vp = radius_paircreate(request,
							       &request->reply->vps,
							       FR2ATTR(169),
							       PW_TYPE_INTEGER);
					if (vp) {
						vp->vp_integer = client->prefix;
					}
				}
			}
			
			if (server_ip) {
				pairadd(&request->reply->vps,
					paircopyvp(server_ip));
				pairadd(&request->reply->vps,
					paircopyvp(server_port));
			}

			if (client->auth &&
			    ((flag->vp_integer & 0x01) != 0)) {
				request_stats_addvp(request, client_authvp,
						    client->auth);
			}
#ifdef WITH_ACCOUNTING
			if (client->acct &&
			    ((flag->vp_integer & 0x01) != 0)) {
				request_stats_addvp(request, client_acctvp,
						    client->acct);
			}
#endif
		} /* else client wasn't found, don't echo it back */
	}

	/*
	 *	For a particular "listen" socket.
	 */
	if (((flag->vp_integer & 0x40) != 0) &&
	    ((flag->vp_integer & 0x03) != 0)) {
		rad_listen_t *this;
		VALUE_PAIR *server_ip, *server_port;
		fr_ipaddr_t ipaddr;

		/*
		 *	See if we need to look up the server by socket
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, FR2ATTR(170));
		if (!server_ip) return;

		server_port = pairfind(request->packet->vps,
				       FR2ATTR(171));
		if (!server_port) return;
		
		ipaddr.af = AF_INET;
		ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
		this = listener_find_byipaddr(&ipaddr,
					      server_port->vp_integer);
		
		/*
		 *	Not found: don't do anything
		 */
		if (!this) return;
		
		pairadd(&request->reply->vps,
			paircopyvp(server_ip));
		pairadd(&request->reply->vps,
			paircopyvp(server_port));

		if (((flag->vp_integer & 0x01) != 0) &&
		    ((request->listener->type == RAD_LISTEN_AUTH) ||
		     (request->listener->type == RAD_LISTEN_NONE))) {
			request_stats_addvp(request, authvp, &this->stats);
		}
		
#ifdef WITH_ACCOUNTING
		if (((flag->vp_integer & 0x02) != 0) &&
		    ((request->listener->type == RAD_LISTEN_ACCT) ||
		     (request->listener->type == RAD_LISTEN_NONE))) {
			request_stats_addvp(request, acctvp, &this->stats);
		}
#endif
	}

	/*
	 *	Home servers.
	 */
	if (((flag->vp_integer & 0x80) != 0) &&
	    ((flag->vp_integer & 0x03) != 0)) {
		home_server *home;
		VALUE_PAIR *server_ip, *server_port;
		fr_ipaddr_t ipaddr;

		/*
		 *	See if we need to look up the server by socket
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, FR2ATTR(170));
		if (!server_ip) return;

		server_port = pairfind(request->packet->vps,
				       FR2ATTR(171));
		if (!server_port) return;
		
		ipaddr.af = AF_INET;
		ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
		home = home_server_find(&ipaddr, server_port->vp_integer);

		/*
		 *	Not found: don't do anything
		 */
		if (!home) return;
		
		pairadd(&request->reply->vps,
			paircopyvp(server_ip));
		pairadd(&request->reply->vps,
			paircopyvp(server_port));

		vp = radius_paircreate(request, &request->reply->vps,
				       FR2ATTR(172), PW_TYPE_INTEGER);
		if (vp) vp->vp_integer = home->currently_outstanding;

		vp = radius_paircreate(request, &request->reply->vps,
				       FR2ATTR(173), PW_TYPE_INTEGER);
		if (vp) vp->vp_integer = home->state;

		if ((home->state == HOME_STATE_ALIVE) &&
		    (home->revive_time.tv_sec != 0)) {
			vp = radius_paircreate(request, &request->reply->vps,
					       FR2ATTR(175), PW_TYPE_DATE);
			if (vp) vp->vp_date = home->revive_time.tv_sec;
		}

		if ((home->state == HOME_STATE_ALIVE) &&
		    (home->ema.window > 0)) {
				vp = radius_paircreate(request,
						       &request->reply->vps,
						       FR2ATTR(178),
						       PW_TYPE_INTEGER);
				if (vp) vp->vp_integer = home->ema.window;
				vp = radius_paircreate(request,
						       &request->reply->vps,
						       FR2ATTR(179),
						       PW_TYPE_INTEGER);
				if (vp) vp->vp_integer = home->ema.ema1 / EMA_SCALE;
				vp = radius_paircreate(request,
						       &request->reply->vps,
						       FR2ATTR(180),
						       PW_TYPE_INTEGER);
				if (vp) vp->vp_integer = home->ema.ema10 / EMA_SCALE;

		}

		if (home->state == HOME_STATE_IS_DEAD) {
			vp = radius_paircreate(request, &request->reply->vps,
					       FR2ATTR(174), PW_TYPE_DATE);
			if (vp) vp->vp_date = home->zombie_period_start.tv_sec + home->zombie_period;
		}

		if (((flag->vp_integer & 0x01) != 0) &&
		    (home->type == HOME_TYPE_AUTH)) {
			request_stats_addvp(request, proxy_authvp,
					    &home->stats);
		}

#ifdef WITH_ACCOUNTING
		if (((flag->vp_integer & 0x02) != 0) &&
		    (home->type == HOME_TYPE_ACCT)) {
			request_stats_addvp(request, proxy_acctvp,
					    &home->stats);
		}
#endif
	}
}
Ejemplo n.º 15
0
void request_stats_reply(REQUEST *request)
{
	VALUE_PAIR *flag, *vp;

	/*
	 *	Statistics are available ONLY on a "status" port.
	 */
	rad_assert(request->packet->code == PW_CODE_STATUS_SERVER);
	rad_assert(request->listener->type == RAD_LISTEN_NONE);

	flag = pairfind(request->packet->vps, 127, VENDORPEC_FREERADIUS, TAG_ANY);
	if (!flag || (flag->vp_integer == 0)) return;

	/*
	 *	Authentication.
	 */
	if (((flag->vp_integer & 0x01) != 0) &&
	    ((flag->vp_integer & 0xc0) == 0)) {
		request_stats_addvp(request, authvp, &radius_auth_stats);
	}

#ifdef WITH_ACCOUNTING
	/*
	 *	Accounting
	 */
	if (((flag->vp_integer & 0x02) != 0) &&
	    ((flag->vp_integer & 0xc0) == 0)) {
		request_stats_addvp(request, acctvp, &radius_acct_stats);
	}
#endif

#ifdef WITH_PROXY
	/*
	 *	Proxied authentication requests.
	 */
	if (((flag->vp_integer & 0x04) != 0) &&
	    ((flag->vp_integer & 0x20) == 0)) {
		request_stats_addvp(request, proxy_authvp, &proxy_auth_stats);
	}

#ifdef WITH_ACCOUNTING
	/*
	 *	Proxied accounting requests.
	 */
	if (((flag->vp_integer & 0x08) != 0) &&
	    ((flag->vp_integer & 0x20) == 0)) {
		request_stats_addvp(request, proxy_acctvp, &proxy_acct_stats);
	}
#endif
#endif

	/*
	 *	Internal server statistics
	 */
	if ((flag->vp_integer & 0x10) != 0) {
		vp = radius_paircreate(request->reply, &request->reply->vps,
				       176, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_date = start_time.tv_sec;
		vp = radius_paircreate(request->reply, &request->reply->vps,
				       177, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_date = hup_time.tv_sec;

#ifdef HAVE_PTHREAD_H
		int i, array[RAD_LISTEN_MAX], pps[2];

		thread_pool_queue_stats(array, pps);

		for (i = 0; i <= 4; i++) {
			vp = radius_paircreate(request->reply, &request->reply->vps,
					       162 + i, VENDORPEC_FREERADIUS);

			if (!vp) continue;
			vp->vp_integer = array[i];
		}

		for (i = 0; i < 2; i++) {
			vp = radius_paircreate(request->reply, &request->reply->vps,
					       181 + i, VENDORPEC_FREERADIUS);

			if (!vp) continue;
			vp->vp_integer = pps[i];
		}
#endif
	}

	/*
	 *	For a particular client.
	 */
	if ((flag->vp_integer & 0x20) != 0) {
		fr_ipaddr_t ipaddr;
		VALUE_PAIR *server_ip, *server_port = NULL;
		RADCLIENT *client = NULL;
		RADCLIENT_LIST *cl = NULL;

		/*
		 *	See if we need to look up the client by server
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY);
		if (server_ip) {
			server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY);

			if (server_port) {
				ipaddr.af = AF_INET;
				ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
				cl = listener_find_client_list(&ipaddr, server_port->vp_integer, IPPROTO_UDP);

				/*
				 *	Not found: don't do anything
				 */
				if (!cl) return;
			}
		}


		vp = pairfind(request->packet->vps, 167, VENDORPEC_FREERADIUS, TAG_ANY);
		if (vp) {
			memset(&ipaddr, 0, sizeof(ipaddr));
			ipaddr.af = AF_INET;
			ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
			client = client_find(cl, &ipaddr, IPPROTO_UDP);
#ifdef WITH_TCP
			if (!client) {
				client = client_find(cl, &ipaddr, IPPROTO_TCP);
			}
#endif

			/*
			 *	Else look it up by number.
			 */
		} else if ((vp = pairfind(request->packet->vps, 168, VENDORPEC_FREERADIUS, TAG_ANY)) != NULL) {
			client = client_findbynumber(cl, vp->vp_integer);
		}

		if (client) {
			/*
			 *	If found, echo it back, along with
			 *	the requested statistics.
			 */
			pairadd(&request->reply->vps, paircopyvp(request->reply, vp));

			/*
			 *	When retrieving client by number, also
			 *	echo back it's IP address.
			 */
			if ((vp->da->type == PW_TYPE_INTEGER) &&
			    (client->ipaddr.af == AF_INET)) {
				vp = radius_paircreate(request->reply,
						       &request->reply->vps,
						       167, VENDORPEC_FREERADIUS);
				if (vp) {
					vp->vp_ipaddr = client->ipaddr.ipaddr.ip4addr.s_addr;
				}

				if (client->ipaddr.prefix != 32) {
					vp = radius_paircreate(request->reply,
							       &request->reply->vps,
							       169, VENDORPEC_FREERADIUS);
					if (vp) {
						vp->vp_integer = client->ipaddr.prefix;
					}
				}
			}

			if (server_ip) {
				pairadd(&request->reply->vps,
					paircopyvp(request->reply, server_ip));
			}
			if (server_port) {
				pairadd(&request->reply->vps,
					paircopyvp(request->reply, server_port));
			}

			if ((flag->vp_integer & 0x01) != 0) {
				request_stats_addvp(request, client_authvp,
						    &client->auth);
			}
#ifdef WITH_ACCOUNTING
			if ((flag->vp_integer & 0x01) != 0) {
				request_stats_addvp(request, client_acctvp,
						    &client->acct);
			}
#endif
		} /* else client wasn't found, don't echo it back */
	}

	/*
	 *	For a particular "listen" socket.
	 */
	if (((flag->vp_integer & 0x40) != 0) &&
	    ((flag->vp_integer & 0x03) != 0)) {
		rad_listen_t *this;
		VALUE_PAIR *server_ip, *server_port;
		fr_ipaddr_t ipaddr;

		/*
		 *	See if we need to look up the server by socket
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY);
		if (!server_ip) return;

		server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY);
		if (!server_port) return;

		ipaddr.af = AF_INET;
		ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
		this = listener_find_byipaddr(&ipaddr,
					      server_port->vp_integer,
					      IPPROTO_UDP);

		/*
		 *	Not found: don't do anything
		 */
		if (!this) return;

		pairadd(&request->reply->vps,
			paircopyvp(request->reply, server_ip));
		pairadd(&request->reply->vps,
			paircopyvp(request->reply, server_port));

		if (((flag->vp_integer & 0x01) != 0) &&
		    ((request->listener->type == RAD_LISTEN_AUTH) ||
		     (request->listener->type == RAD_LISTEN_NONE))) {
			request_stats_addvp(request, authvp, &this->stats);
		}

#ifdef WITH_ACCOUNTING
		if (((flag->vp_integer & 0x02) != 0) &&
		    ((request->listener->type == RAD_LISTEN_ACCT) ||
		     (request->listener->type == RAD_LISTEN_NONE))) {
			request_stats_addvp(request, acctvp, &this->stats);
		}
#endif
	}

#ifdef WITH_PROXY
	/*
	 *	Home servers.
	 */
	if (((flag->vp_integer & 0x80) != 0) &&
	    ((flag->vp_integer & 0x03) != 0)) {
		home_server_t *home;
		VALUE_PAIR *server_ip, *server_port;
		fr_ipaddr_t ipaddr;

		/*
		 *	See if we need to look up the server by socket
		 *	socket.
		 */
		server_ip = pairfind(request->packet->vps, 170, VENDORPEC_FREERADIUS, TAG_ANY);
		if (!server_ip) return;

		server_port = pairfind(request->packet->vps, 171, VENDORPEC_FREERADIUS, TAG_ANY);
		if (!server_port) return;

#ifndef NDEBUG
		memset(&ipaddr, 0, sizeof(ipaddr));
#endif
		ipaddr.af = AF_INET;
		ipaddr.ipaddr.ip4addr.s_addr = server_ip->vp_ipaddr;
		home = home_server_find(&ipaddr, server_port->vp_integer,
					IPPROTO_UDP);

		/*
		 *	Not found: don't do anything
		 */
		if (!home) return;

		pairadd(&request->reply->vps,
			paircopyvp(request->reply, server_ip));
		pairadd(&request->reply->vps,
			paircopyvp(request->reply, server_port));

		vp = radius_paircreate(request->reply, &request->reply->vps,
				       172, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_integer = home->currently_outstanding;

		vp = radius_paircreate(request->reply, &request->reply->vps,
				       173, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_integer = home->state;

		if ((home->state == HOME_STATE_ALIVE) &&
		    (home->revive_time.tv_sec != 0)) {
			vp = radius_paircreate(request->reply, &request->reply->vps,
					       175, VENDORPEC_FREERADIUS);
			if (vp) vp->vp_date = home->revive_time.tv_sec;
		}

		if ((home->state == HOME_STATE_ALIVE) &&
		    (home->ema.window > 0)) {
				vp = radius_paircreate(request->reply,
						       &request->reply->vps,
						       178, VENDORPEC_FREERADIUS);
				if (vp) vp->vp_integer = home->ema.window;
				vp = radius_paircreate(request->reply,
						       &request->reply->vps,
						       179, VENDORPEC_FREERADIUS);
				if (vp) vp->vp_integer = home->ema.ema1 / EMA_SCALE;
				vp = radius_paircreate(request->reply,
						       &request->reply->vps,
						       180, VENDORPEC_FREERADIUS);
				if (vp) vp->vp_integer = home->ema.ema10 / EMA_SCALE;

		}

		if (home->state == HOME_STATE_IS_DEAD) {
			vp = radius_paircreate(request->reply, &request->reply->vps,
					       174, VENDORPEC_FREERADIUS);
			if (vp) vp->vp_date = home->zombie_period_start.tv_sec + home->zombie_period;
		}

		/*
		 *	Show more information...
		 *
		 *	FIXME: do this for clients, too!
		 */
		vp = radius_paircreate(request->reply, &request->reply->vps,
				       184, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_date = home->last_packet_recv;

		vp = radius_paircreate(request->reply, &request->reply->vps,
				       185, VENDORPEC_FREERADIUS);
		if (vp) vp->vp_date = home->last_packet_sent;

		if (((flag->vp_integer & 0x01) != 0) &&
		    (home->type == HOME_TYPE_AUTH)) {
			request_stats_addvp(request, proxy_authvp,
					    &home->stats);
		}

#ifdef WITH_ACCOUNTING
		if (((flag->vp_integer & 0x02) != 0) &&
		    (home->type == HOME_TYPE_ACCT)) {
			request_stats_addvp(request, proxy_acctvp,
					    &home->stats);
		}
#endif
	}
#endif	/* WITH_PROXY */
}
Ejemplo n.º 16
0
/*
 *	Find a per-socket client.
 */
RADCLIENT *client_listener_find(const rad_listen_t *listener,
				const fr_ipaddr_t *ipaddr, int src_port)
{
#ifdef WITH_DYNAMIC_CLIENTS
	int rcode;
	REQUEST *request;
	RADCLIENT *created;
#endif
	time_t now;
	RADCLIENT *client;
	RADCLIENT_LIST *clients;
	listen_socket_t *sock;

	rad_assert(listener != NULL);
	rad_assert(ipaddr != NULL);

	sock = listener->data;
	clients = sock->clients;

	/*
	 *	This HAS to have been initialized previously.
	 */
	rad_assert(clients != NULL);

	client = client_find(clients, ipaddr,sock->proto);
	if (!client) {
		char name[256], buffer[128];
					
#ifdef WITH_DYNAMIC_CLIENTS
	unknown:		/* used only for dynamic clients */
#endif

		/*
		 *	DoS attack quenching, but only in daemon mode.
		 *	If they're running in debug mode, show them
		 *	every packet.
		 */
		if (debug_flag == 0) {
			static time_t last_printed = 0;

			now = time(NULL);
			if (last_printed == now) return NULL;
			
			last_printed = now;
		}

		listener->print(listener, name, sizeof(name));

		radlog(L_ERR, "Ignoring request to %s from unknown client %s port %d"
#ifdef WITH_TCP
		       " proto %s"
#endif
		       , name, inet_ntop(ipaddr->af, &ipaddr->ipaddr,
					 buffer, sizeof(buffer)), src_port
#ifdef WITH_TCP
		       , (sock->proto == IPPROTO_UDP) ? "udp" : "tcp"
#endif
		       );
		return NULL;
	}

#ifndef WITH_DYNAMIC_CLIENTS
	return client;		/* return the found client. */
#else

	/*
	 *	No server defined, and it's not dynamic.  Return it.
	 */
	if (!client->client_server && !client->dynamic) return client;

	now = time(NULL);
	
	/*
	 *	It's a dynamically generated client, check it.
	 */
	if (client->dynamic && (src_port != 0)) {
		/*
		 *	Lives forever.  Return it.
		 */
		if (client->lifetime == 0) return client;
		
		/*
		 *	Rate-limit the deletion of known clients.
		 *	This makes them last a little longer, but
		 *	prevents the server from melting down if (say)
		 *	10k clients all expire at once.
		 */
		if (now == client->last_new_client) return client;

		/*
		 *	It's not dead yet.  Return it.
		 */
		if ((client->created + client->lifetime) > now) return client;
		
		/*
		 *	This really puts them onto a queue for later
		 *	deletion.
		 */
		client_delete(clients, client);

		/*
		 *	Go find the enclosing network again.
		 */
		client = client_find(clients, ipaddr, sock->proto);

		/*
		 *	WTF?
		 */
		if (!client) goto unknown;
		if (!client->client_server) goto unknown;

		/*
		 *	At this point, 'client' is the enclosing
		 *	network that configures where dynamic clients
		 *	can be defined.
		 */
		rad_assert(client->dynamic == 0);
	} else {
		/*
		 *	The IP is unknown, so we've found an enclosing
		 *	network.  Enable DoS protection.  We only
		 *	allow one new client per second.  Known
		 *	clients aren't subject to this restriction.
		 */
		if (now == client->last_new_client) goto unknown;
	}

	client->last_new_client = now;

	request = request_alloc();
	if (!request) goto unknown;

	request->listener = listener;
	request->client = client;
	request->packet = rad_recv(listener->fd, 0x02); /* MSG_PEEK */
	if (!request->packet) {				/* badly formed, etc */
		request_free(&request);
		goto unknown;
	}
	request->reply = rad_alloc_reply(request->packet);
	if (!request->reply) {
		request_free(&request);
		goto unknown;
	}
	request->packet->timestamp = request->timestamp;
	request->number = 0;
	request->priority = listener->type;
	request->server = client->client_server;
	request->root = &mainconfig;

	/*
	 *	Run a fake request through the given virtual server.
	 *	Look for FreeRADIUS-Client-IP-Address
	 *	         FreeRADIUS-Client-Secret
	 *		...
	 *
	 *	and create the RADCLIENT structure from that.
	 */
	DEBUG("server %s {", request->server);

	rcode = module_authorize(0, request);

	DEBUG("} # server %s", request->server);

	if (rcode != RLM_MODULE_OK) {
		request_free(&request);
		goto unknown;
	}

	/*
	 *	If the client was updated by rlm_dynamic_clients,
	 *	don't create the client from attribute-value pairs.
	 */
	if (request->client == client) {
		created = client_create(clients, request);
	} else {
		created = request->client;

		/*
		 *	This frees the client if it isn't valid.
		 */
		if (!client_validate(clients, client, created)) goto unknown;
	}
	request_free(&request);

	if (!created) goto unknown;

	return created;
#endif
}
Ejemplo n.º 17
0
/** Map multiple attributes from a client into the request
 *
 * @param[in] mod_inst		NULL.
 * @param[in] proc_inst		NULL.
 * @param[in] request		The current request.
 * @param[in] client_override	If NULL, use the current client, else use the client matching
 *				the ip given.
 * @param[in] maps		Head of the map list.
 * @return
 *	- #RLM_MODULE_NOOP no rows were returned.
 *	- #RLM_MODULE_UPDATED if one or more #VALUE_PAIR were added to the #REQUEST.
 *	- #RLM_MODULE_FAIL if an error occurred.
 */
static rlm_rcode_t map_proc_client(UNUSED void *mod_inst, UNUSED void *proc_inst, REQUEST *request,
				   fr_value_box_t **client_override, vp_map_t const *maps)
{
	rlm_rcode_t		rcode = RLM_MODULE_OK;
	vp_map_t const		*map;
	RADCLIENT		*client;
	client_get_vp_ctx_t	uctx;

	if (*client_override) {
		fr_ipaddr_t	ip;
		char const	*client_str;

		/*
		 *	Concat don't asprint, as this becomes a noop
		 *	in the vast majority of cases.
		 */
		if (fr_value_box_list_concat(request, *client_override, client_override, FR_TYPE_STRING, true) < 0) {
			REDEBUG("Failed concatenating input data");
			return RLM_MODULE_FAIL;
		}
		client_str = (*client_override)->vb_strvalue;

		if (fr_inet_pton(&ip, client_str, -1, AF_UNSPEC, false, true) < 0) {
			REDEBUG("\"%s\" is not a valid IPv4 or IPv6 address", client_str);
			rcode = RLM_MODULE_FAIL;
			goto finish;
		}

		client = client_find(NULL, &ip, IPPROTO_IP);
		if (!client) {
			RDEBUG("No client found with IP \"%s\"", client_str);
			rcode = RLM_MODULE_NOTFOUND;
			goto finish;
		}

		if (client->cs) {
			char const *filename;
			int line;

			filename = cf_filename(client->cs);
			line = cf_lineno(client->cs);

			if (filename) {
				RDEBUG2("Found client matching \"%s\".  Defined in \"%s\" line %i",
					client_str, filename, line);
			} else {
				RDEBUG2("Found client matching \"%s\"", client_str);
			}
		}
	} else {
		client = request->client;
	}
	uctx.cs = client->cs;

	RINDENT();
	for (map = maps;
	     map != NULL;
	     map = map->next) {
		char	*field = NULL;

		if (tmpl_aexpand(request, &field, request, map->rhs, NULL, NULL) < 0) {
			REDEBUG("Failed expanding RHS at %s", map->lhs->name);
			rcode = RLM_MODULE_FAIL;
			talloc_free(field);
			break;
		}

		uctx.cp = cf_pair_find(client->cs, field);
		if (!uctx.cp) {
			RDEBUG3("No matching client property \"%s\", skipping...", field);
			goto next;			/* No matching CONF_PAIR found */
		}
		uctx.field = field;

		/*
		 *	Pass the raw data to the callback, which will
		 *	create the VP and add it to the map.
		 */
		if (map_to_request(request, map, _map_proc_client_get_vp, &uctx) < 0) {
			rcode = RLM_MODULE_FAIL;
			talloc_free(field);
			break;
		}
		rcode = RLM_MODULE_UPDATED;

	next:
		talloc_free(field);
	}
	REXDENT();

finish:
	return rcode;
}
Ejemplo n.º 18
0
/*
 *	Old wrapper for client_find
 */
RADCLIENT *client_find_old(fr_ipaddr_t const *ipaddr)
{
	return client_find(root_clients, ipaddr, IPPROTO_UDP);
}