static int sqlippool_accounting_stop(SQLSOCK * sqlsocket, rlm_sqlippool_t *data, REQUEST *request) { char logstr[MAX_STRING_LEN]; /* * BEGIN */ sqlippool_command(data->stop_begin, sqlsocket, data, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->stop_clear, sqlsocket, data, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->stop_commit, sqlsocket, data, request, (char *) NULL, 0); radius_xlat(logstr, sizeof(logstr), data->log_clear, request, NULL, NULL); return do_logging(logstr, RLM_MODULE_OK); }
static int sqlippool_accounting_off(SQLSOCK * sqlsocket, rlm_sqlippool_t *data, REQUEST *request) { /* * BEGIN */ sqlippool_command(data->off_begin, sqlsocket, data, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->off_clear, sqlsocket, data, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->off_commit, sqlsocket, data, request, (char *) NULL, 0); return RLM_MODULE_OK; }
static int sqlippool_accounting_alive(SQLSOCK * sqlsocket, rlm_sqlippool_t *data, REQUEST *request) { /* * BEGIN */ sqlippool_command(data->alive_begin, sqlsocket, data, request, (char *) NULL, 0); /* * UPDATE */ sqlippool_command(data->alive_update, sqlsocket, data, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->alive_commit, sqlsocket, data, request, (char *) NULL, 0); return RLM_MODULE_OK; }
static int sqlippool_accounting_start(SQLSOCK * sqlsocket, rlm_sqlippool_t *inst, REQUEST *request) { /* * BEGIN */ sqlippool_command(inst->start_begin, sqlsocket, inst, request, (char *) NULL, 0); /* * UPDATE */ sqlippool_command(inst->start_update, sqlsocket, inst, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(inst->start_commit, sqlsocket, inst, request, (char *) NULL, 0); return RLM_MODULE_OK; }
/* * Allocate an IP number from the pool. */ static int sqlippool_postauth(void *instance, REQUEST * request) { rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; char allocation[MAX_STRING_LEN]; int allocation_len; uint32_t ip_allocation; VALUE_PAIR * vp; SQLSOCK * sqlsocket; fr_ipaddr_t ipaddr; char logstr[MAX_STRING_LEN]; char sqlusername[MAX_STRING_LEN]; /* * If there is a Framed-IP-Address attribute in the reply do nothing */ if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS, 0) != NULL) { /* We already have a Framed-IP-Address */ radius_xlat(logstr, sizeof(logstr), data->log_exists, request, NULL, NULL); RDEBUG("Framed-IP-Address already exists"); return do_logging(logstr, RLM_MODULE_NOOP); } if (pairfind(request->config_items, PW_POOL_NAME, 0) == NULL) { RDEBUG("No Pool-Name defined."); radius_xlat(logstr, sizeof(logstr), data->log_nopool, request, NULL, NULL); return do_logging(logstr, RLM_MODULE_NOOP); } sqlsocket = data->sql_inst->sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { RDEBUG("cannot allocate sql connection"); return RLM_MODULE_FAIL; } if (data->sql_inst->sql_set_user(data->sql_inst, request, sqlusername, NULL) < 0) { return RLM_MODULE_FAIL; } /* * BEGIN */ sqlippool_command(data->allocate_begin, sqlsocket, data, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->allocate_clear, sqlsocket, data, request, (char *) NULL, 0); /* * FIND */ allocation_len = sqlippool_query1(allocation, sizeof(allocation), data->allocate_find, sqlsocket, data, request, (char *) NULL, 0); /* * Nothing found... */ if (allocation_len == 0) { /* * COMMIT */ sqlippool_command(data->allocate_commit, sqlsocket, instance, request, (char *) NULL, 0); /* * Should we perform pool-check ? */ if (data->pool_check && *data->pool_check) { /* * Ok, so the allocate-find query found nothing ... * Let's check if the pool exists at all */ allocation_len = sqlippool_query1(allocation, sizeof(allocation), data->pool_check, sqlsocket, data, request, (char *) NULL, 0); data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket); if (allocation_len) { /* * Pool exists after all... So, * the failure to allocate the IP * address was most likely due to * the depletion of the pool. In * that case, we should return * NOTFOUND */ RDEBUG("pool appears to be full"); radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL, NULL); return do_logging(logstr, RLM_MODULE_NOTFOUND); } /* * Pool doesn't exist in the table. It * may be handled by some other instance of * sqlippool, so we should just ignore this * allocation failure and return NOOP */ RDEBUG("IP address could not be allocated as no pool exists with that name."); return RLM_MODULE_NOOP; } data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket); RDEBUG("IP address could not be allocated."); radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL, NULL); return do_logging(logstr, RLM_MODULE_NOOP); } /* * FIXME: Make it work with the ipv6 addresses */ if ((ip_hton(allocation, AF_INET, &ipaddr) < 0) || ((ip_allocation = ipaddr.ipaddr.ip4addr.s_addr) == INADDR_NONE)) { /* * COMMIT */ sqlippool_command(data->allocate_commit, sqlsocket, instance, request, (char *) NULL, 0); RDEBUG("Invalid IP number [%s] returned from database query.", allocation); data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket); radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL, NULL); return do_logging(logstr, RLM_MODULE_NOOP); } /* * UPDATE */ sqlippool_command(data->allocate_update, sqlsocket, data, request, allocation, allocation_len); RDEBUG("Allocated IP %s [%08x]", allocation, ip_allocation); vp = radius_paircreate(request, &request->reply->vps, PW_FRAMED_IP_ADDRESS, 0, PW_TYPE_IPADDR); vp->vp_ipaddr = ip_allocation; /* * COMMIT */ sqlippool_command(data->allocate_commit, sqlsocket, data, request, (char *) NULL, 0); data->sql_inst->sql_release_socket(data->sql_inst, sqlsocket); radius_xlat(logstr, sizeof(logstr), data->log_success, request, NULL, NULL); return do_logging(logstr, RLM_MODULE_OK); }
/* * Allocate an IP number from the pool. */ static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST *request) { rlm_sqlippool_t *inst = (rlm_sqlippool_t *) instance; char allocation[MAX_STRING_LEN]; int allocation_len; VALUE_PAIR *vp; rlm_sql_handle_t *handle; time_t now; /* * If there is a Framed-IP-Address attribute in the reply do nothing */ if (fr_pair_find_by_num(request->reply->vps, inst->framed_ip_address, 0, TAG_ANY) != NULL) { RDEBUG("Framed-IP-Address already exists"); return do_logging(request, inst->log_exists, RLM_MODULE_NOOP); } if (fr_pair_find_by_num(request->config, PW_POOL_NAME, 0, TAG_ANY) == NULL) { RDEBUG("No Pool-Name defined"); return do_logging(request, inst->log_nopool, RLM_MODULE_NOOP); } handle = fr_connection_get(inst->sql_inst->pool); if (!handle) { REDEBUG("Failed reserving SQL connection"); return RLM_MODULE_FAIL; } if (inst->sql_inst->sql_set_user(inst->sql_inst, request, NULL) < 0) { return RLM_MODULE_FAIL; } /* * Limit the number of clears we do. There are minor * race conditions for the check, but so what. The * actual work is protected by a transaction. The idea * here is that if we're allocating 100 IPs a second, * we're only do 1 CLEAR per second. */ now = time(NULL); if (inst->last_clear < now) { inst->last_clear = now; DO_PART(allocate_begin); DO_PART(allocate_clear); DO_PART(allocate_commit); } DO_PART(allocate_begin); allocation_len = sqlippool_query1(allocation, sizeof(allocation), inst->allocate_find, handle, inst, request, (char *) NULL, 0); /* * Nothing found... */ if (allocation_len == 0) { DO_PART(allocate_commit); /* *Should we perform pool-check ? */ if (inst->pool_check && *inst->pool_check) { /* *Ok, so the allocate-find query found nothing ... *Let's check if the pool exists at all */ allocation_len = sqlippool_query1(allocation, sizeof(allocation), inst->pool_check, handle, inst, request, (char *) NULL, 0); fr_connection_release(inst->sql_inst->pool, handle); if (allocation_len) { /* * Pool exists after all... So, * the failure to allocate the IP * address was most likely due to * the depletion of the pool. In * that case, we should return * NOTFOUND */ RDEBUG("pool appears to be full"); return do_logging(request, inst->log_failed, RLM_MODULE_NOTFOUND); } /* * Pool doesn't exist in the table. It * may be handled by some other instance of * sqlippool, so we should just ignore this * allocation failure and return NOOP */ RDEBUG("IP address could not be allocated as no pool exists with that name"); return RLM_MODULE_NOOP; } fr_connection_release(inst->sql_inst->pool, handle); RDEBUG("IP address could not be allocated"); return do_logging(request, inst->log_failed, RLM_MODULE_NOOP); } /* * See if we can create the VP from the returned data. If not, * error out. If so, add it to the list. */ vp = fr_pair_afrom_num(request->reply, inst->framed_ip_address, 0); if (fr_pair_value_from_str(vp, allocation, allocation_len) < 0) { DO_PART(allocate_commit); RDEBUG("Invalid IP number [%s] returned from instbase query.", allocation); fr_connection_release(inst->sql_inst->pool, handle); return do_logging(request, inst->log_failed, RLM_MODULE_NOOP); } RDEBUG("Allocated IP %s", allocation); fr_pair_add(&request->reply->vps, vp); /* * UPDATE */ sqlippool_command(inst->allocate_update, &handle, inst, request, allocation, allocation_len); DO_PART(allocate_commit); fr_connection_release(inst->sql_inst->pool, handle); return do_logging(request, inst->log_success, RLM_MODULE_OK); }
/* * Allocate an IP number from the pool. */ static rlm_rcode_t CC_HINT(nonnull) mod_post_auth(void *instance, REQUEST *request) { rlm_sqlippool_t *inst = (rlm_sqlippool_t *) instance; char allocation[MAX_STRING_LEN]; int allocation_len; uint32_t ip_allocation; VALUE_PAIR *vp; rlm_sql_handle_t *handle; fr_ipaddr_t ipaddr; time_t now; /* * If there is a Framed-IP-Address attribute in the reply do nothing */ if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS, 0, TAG_ANY) != NULL) { RDEBUG("Framed-IP-Address already exists"); return do_logging(request, inst->log_exists, RLM_MODULE_NOOP); } if (pairfind(request->config_items, PW_POOL_NAME, 0, TAG_ANY) == NULL) { RDEBUG("No Pool-Name defined"); return do_logging(request, inst->log_nopool, RLM_MODULE_NOOP); } handle = inst->sql_inst->sql_get_socket(inst->sql_inst); if (!handle) { REDEBUG("cannot get sql connection"); return RLM_MODULE_FAIL; } if (inst->sql_inst->sql_set_user(inst->sql_inst, request, NULL) < 0) { return RLM_MODULE_FAIL; } /* * Limit the number of clears we do. There are minor * race conditions for the check, but so what. The * actual work is protected by a transaction. The idea * here is that if we're allocating 100 IPs a second, * we're only do 1 CLEAR per second. */ now = time(NULL); if (inst->last_clear < now) { inst->last_clear = now; DO(allocate_begin); DO(allocate_clear); DO(allocate_commit); } DO(allocate_begin); allocation_len = sqlippool_query1(allocation, sizeof(allocation), inst->allocate_find, handle, inst, request, (char *) NULL, 0); /* * Nothing found... */ if (allocation_len == 0) { DO(allocate_commit); /* *Should we perform pool-check ? */ if (inst->pool_check && *inst->pool_check) { /* *Ok, so the allocate-find query found nothing ... *Let's check if the pool exists at all */ allocation_len = sqlippool_query1(allocation, sizeof(allocation), inst->pool_check, handle, inst, request, (char *) NULL, 0); inst->sql_inst->sql_release_socket(inst->sql_inst, handle); if (allocation_len) { /* * Pool exists after all... So, * the failure to allocate the IP * address was most likely due to * the depletion of the pool. In * that case, we should return * NOTFOUND */ RDEBUG("pool appears to be full"); return do_logging(request, inst->log_failed, RLM_MODULE_NOTFOUND); } /* * Pool doesn't exist in the table. It * may be handled by some other instance of * sqlippool, so we should just ignore this * allocation failure and return NOOP */ RDEBUG("IP address could not be allocated as no pool exists with that name"); return RLM_MODULE_NOOP; } inst->sql_inst->sql_release_socket(inst->sql_inst, handle); RDEBUG("IP address could not be allocated"); return do_logging(request, inst->log_failed, RLM_MODULE_NOOP); } /* * FIXME: Make it work with the ipv6 addresses */ if ((ip_hton(&ipaddr, AF_INET, allocation, false) < 0) || ((ip_allocation = ipaddr.ipaddr.ip4addr.s_addr) == INADDR_NONE)) { DO(allocate_commit); RDEBUG("Invalid IP number [%s] returned from instbase query.", allocation); inst->sql_inst->sql_release_socket(inst->sql_inst, handle); return do_logging(request, inst->log_failed, RLM_MODULE_NOOP); } /* * UPDATE */ sqlippool_command(inst->allocate_update, handle, inst, request, allocation, allocation_len); RDEBUG("Allocated IP %s [%08x]", allocation, ip_allocation); vp = radius_paircreate(request->reply, &request->reply->vps, PW_FRAMED_IP_ADDRESS, 0); vp->vp_ipaddr = ip_allocation; vp->length = 4; DO(allocate_commit); inst->sql_inst->sql_release_socket(inst->sql_inst, handle); return do_logging(request, inst->log_success, RLM_MODULE_OK); }