📄 rlm_sqlippool.c
字号:
(strlen(data->alive_update) == 0)) { radlog(L_ERR, "rlm_sqlippool: the 'alive-update' statement must be set."); sqlippool_detach(data); return -1; } if ((data->stop_clear == NULL) || (strlen(data->stop_clear) == 0)) { radlog(L_ERR, "rlm_sqlippool: the 'stop-clear' statement must be set."); sqlippool_detach(data); return -1; } if ((data->on_clear == NULL) || (strlen(data->on_clear) == 0)) { radlog(L_ERR, "rlm_sqlippool: the 'on-clear' statement must be set."); sqlippool_detach(data); return -1; } if ((data->off_clear == NULL) || (strlen(data->off_clear) == 0)) { radlog(L_ERR, "rlm_sqlippool: the 'off-clear' statement must be set."); sqlippool_detach(data); return -1; } pool_name = cf_section_name2(conf); if (pool_name != NULL) data->pool_name = strdup(pool_name); else data->pool_name = strdup("ippool"); modinst = find_module_instance(cf_section_find("modules"), data->sql_instance_name); if (!modinst) { radlog(L_ERR, "sqlippool_instantiate: failed to find sql instance named %s", data->sql_instance_name); sqlippool_detach(data); return -1; } if (strcmp(modinst->entry->name, "rlm_sql") != 0) { radlog(L_ERR, "sqlippool_instantiate: Module \"%s\"" " is not an instance of the rlm_sql module", data->sql_instance_name); sqlippool_detach(data); return -1; } data->sql_inst = (SQL_INST *) modinst->insthandle; sqlippool_initialize_sql(data); *instance = data; return 0;}/* * if we have something to log, then we log it * otherwise we return the retcode as soon as possible */static int do_logging(char *str, int retcode){ if (strlen(str)) radlog(L_INFO,"%s", str); return retcode;}/* * 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]; /* * If there is a Framed-IP-Address attribute in the reply do nothing */ if (pairfind(request->reply->vps, PW_FRAMED_IP_ADDRESS) != NULL) { /* We already have a Framed-IP-Address */ radius_xlat(logstr, sizeof(logstr), data->log_exists, request, NULL); DEBUG("rlm_sqlippool: Framed-IP-Address already exists"); return do_logging(logstr, RLM_MODULE_NOOP); } if (pairfind(request->config_items, PW_POOL_NAME) == NULL) { DEBUG("rlm_sqlippool: No Pool-Name defined."); radius_xlat(logstr, sizeof(logstr), data->log_nopool, request, NULL); return do_logging(logstr, RLM_MODULE_NOOP); } if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_sqlippool: No NAS-IP-Address in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_FAIL; } /* * BEGIN */ sqlippool_command(data->allocate_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->allocate_clear, sqlsocket, instance, request, (char *) NULL, 0); /* * FIND */ allocation_len = sqlippool_query1(allocation, sizeof(allocation), data->allocate_find, sqlsocket, instance, 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, instance, request, (char *) NULL, 0); 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 */ DEBUG("rlm_sqlippool: pool appears to be full"); radius_xlat(logstr, sizeof(logstr), data->log_failed, request, 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 */ DEBUG("rlm_sqlippool: IP address could not be allocated as no pool exists with that name."); return RLM_MODULE_NOOP; } sql_release_socket(data->sql_inst, sqlsocket); DEBUG("rlm_sqlippool: IP address could not be allocated."); radius_xlat(logstr, sizeof(logstr), data->log_failed, request, 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); DEBUG("rlm_sqlippool: Invalid IP number [%s] returned from database query.", allocation); sql_release_socket(data->sql_inst, sqlsocket); radius_xlat(logstr, sizeof(logstr), data->log_failed, request, NULL); return do_logging(logstr, RLM_MODULE_NOOP); } /* * UPDATE */ sqlippool_command(data->allocate_update, sqlsocket, instance, request, allocation, allocation_len); DEBUG("rlm_sqlippool: Allocated IP %s [%08x]", allocation, ip_allocation); vp = radius_paircreate(request, &request->reply->vps, PW_FRAMED_IP_ADDRESS, PW_TYPE_IPADDR); vp->vp_ipaddr = ip_allocation; /* * COMMIT */ sqlippool_command(data->allocate_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); radius_xlat(logstr, sizeof(logstr), data->log_success, request, NULL); return do_logging(logstr, RLM_MODULE_OK);}static int sqlippool_accounting_start(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->start_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * UPDATE */ sqlippool_command(data->start_update, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->start_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}static int sqlippool_accounting_alive(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->alive_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * UPDATE */ sqlippool_command(data->alive_update, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->alive_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}static int sqlippool_accounting_stop(void * instance, REQUEST * request){ char logstr[MAX_STRING_LEN]; rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->stop_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->stop_clear, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->stop_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); radius_xlat(logstr, sizeof(logstr), data->log_clear, request, NULL); return do_logging(logstr, RLM_MODULE_OK);}static int sqlippool_accounting_on(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->on_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->on_clear, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->on_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}static int sqlippool_accounting_off(void * instance, REQUEST * request){ rlm_sqlippool_t * data = (rlm_sqlippool_t *) instance; SQLSOCK * sqlsocket; if (pairfind(request->packet->vps, PW_NAS_IP_ADDRESS) == NULL) { DEBUG("rlm_ippool: Could not find nas information in packet."); return RLM_MODULE_NOOP; } sqlsocket = sql_get_socket(data->sql_inst); if (sqlsocket == NULL) { DEBUG("rlm_sqlippool: cannot allocate sql connection"); return RLM_MODULE_NOOP; } /* * BEGIN */ sqlippool_command(data->off_begin, sqlsocket, instance, request, (char *) NULL, 0); /* * CLEAR */ sqlippool_command(data->off_clear, sqlsocket, instance, request, (char *) NULL, 0); /* * COMMIT */ sqlippool_command(data->off_commit, sqlsocket, instance, request, (char *) NULL, 0); sql_release_socket(data->sql_inst, sqlsocket); return RLM_MODULE_OK;}/* * Check for an Accounting-Stop * If we find one and we have allocated an IP to this nas/port * combination, then deallocate it. */static int sqlippool_accounting(void * instance, REQUEST * request){ VALUE_PAIR * vp; int acct_status_type; vp = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE); if (!vp) { DEBUG("rlm_sqlippool: Could not find account status type in packet."); return RLM_MODULE_NOOP; } acct_status_type = vp->vp_integer; switch (acct_status_type) { case PW_STATUS_START: return sqlippool_accounting_start(instance, request); case PW_STATUS_ALIVE: return sqlippool_accounting_alive(instance, request); case PW_STATUS_STOP: return sqlippool_accounting_stop(instance, request); case PW_STATUS_ACCOUNTING_ON: return sqlippool_accounting_on(instance, request); case PW_STATUS_ACCOUNTING_OFF: return sqlippool_accounting_off(instance, request); default: /* We don't care about any other accounting packet */ return RLM_MODULE_NOOP; }}/* * The module name should be the only globally exported symbol. * That is, everything else should be 'static'. * * If the module needs to temporarily modify it's instantiation * data, the type should be changed to RLM_TYPE_THREAD_UNSAFE. * The server will then take care of ensuring that the module * is single-threaded. */module_t rlm_sqlippool = { RLM_MODULE_INIT, "SQL IP Pool", RLM_TYPE_THREAD_SAFE, /* type */ sqlippool_instantiate, /* instantiation */ sqlippool_detach, /* detach */ { NULL, /* authentication */ NULL, /* authorization */ NULL, /* preaccounting */ sqlippool_accounting, /* accounting */ NULL, /* checksimul */ NULL, /* pre-proxy */ NULL, /* post-proxy */ sqlippool_postauth /* post-auth */ },};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -