예제 #1
0
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);
}
예제 #2
0
static int mod_accounting_stop(rlm_sql_handle_t **handle,
			       rlm_sqlippool_t *inst, REQUEST *request)
{
	DO(stop_begin);
	DO(stop_clear);
	DO(stop_commit);

	return do_logging(request, inst->log_clear, RLM_MODULE_OK);
}
예제 #3
0
/**
 * The main update method of the controller, called from
 * main.cpp. This sends all the current variables to the GUI, so that
 * they can be updated on the screen if necessary.
 */
void Controller::update() {
  check_warning_level();
  m_keytrigger=false;


  // only do_logging if we are enable
if( m_log_interval_seconds > 0)
    do_logging();

  check_sleep_switch();

  if(m_sleeping) return;

  do_dimming();

  send_cpm_values();
  send_graph_data();
  send_total_timer();
  send_svrem();
  send_becq();
  send_logstatus();
}
예제 #4
0
/*
 *	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);
}
예제 #5
0
/*
 *	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);
}
예제 #6
0
/*
 *	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);
}
예제 #7
0
static int logg_internal(const enum loglevel level,
                         const char *file,
                         const char *func,
                         const unsigned int line,
                         int log_errno,
                         const char *fmt,
                         va_list args
                        )
{
	struct big_buff *logg_buff;
	int ret_val, old_errno, retry_cnt;

	old_errno  = errno;

	/* get our tls-print buf */
	if(!(logg_buff = logg_get_buf()))
	{
		/*
		 * hmmm, something went wrong, lets see, if we can get the message to
		 * the user by other means
		 */
		return do_vlogging(level, fmt, args);
	}

	/* add time, if wanted, to buffer */
	if(server.settings.logging.add_date_time)
		logg_buff->pos += add_time_to_buffer(buffer_start(*logg_buff), buffer_remaining(*logg_buff));

	/* put out the "extra" stuff, if there */
	if(file)
	{
		retry_cnt = 0;
		prefetch(strlpcpy);
		prefetch(file);
		prefetch(func);
		/*
		 * calling snprintf for 2 * strcpy + an itoa is "nice"
		 * but goes round the full stdio bloat:
		 * snprintf->vsnprintf->vfprintf-> myriads of funcs to print
		 */
		do
		{
			char *sptr, *stmp, *rstart;
			size_t remaining;

			stmp = sptr = buffer_start(*logg_buff);
			remaining = buffer_remaining(*logg_buff);
			rstart = strlpcpy(sptr, file, remaining);
			remaining -= rstart - sptr;
			if(unlikely(remaining < 7))
				goto realloc;
			sptr = rstart;

			*sptr++ = ':';
			remaining--;
			rstart = strlpcpy(sptr, func, remaining);
			remaining -= rstart - sptr;
			if(unlikely(remaining < 18)) /* make sure we have enough space */
				goto realloc;
			sptr = rstart;

			*sptr++ = '(';
			*sptr++ = ')';
			*sptr++ = '@';
			remaining -= 3;
			rstart = put_dec_trunc(sptr, line); /* 99,999 lines should be... */
			strreverse(sptr, rstart - 1);
			remaining -= rstart - sptr;
			if(unlikely(remaining < 2))
				goto realloc;
			sptr = rstart;
			*sptr++ = ':';
			*sptr++ = ' ';
			logg_buff->pos += sptr - stmp;
			break;
realloc:
			/* now we are in a slow path, no need to hurry */
			{
				struct big_buff *tmp_buff;
				size_t len = strlen(file) + strlen(func) + 6 + 30 + strlen(fmt) * 3;
				len = ROUND_ALIGN(len * 2, 2048) + logg_buff->capacity;
				tmp_buff = realloc(logg_buff, sizeof(*logg_buff) + len);
				if(tmp_buff) {
					logg_buff = tmp_buff;
					logg_buff->limit = logg_buff->capacity = len;
				} else
					break;
				retry_cnt++;
			}
		} while(retry_cnt < 4);
	}

	ret_val = 0; retry_cnt = 0;
	/* format the message in tls */
	do
	{
		size_t len = logg_buff->capacity;
		va_list tmp_valist;
		if(ret_val < 0)
		{
			len *= 2;
			if(++retry_cnt > 4) {
				ret_val = 0;
				break;
			}
		}
		else if((size_t)ret_val > buffer_remaining(*logg_buff))
			len = ROUND_ALIGN((size_t)ret_val * 2, 1024); /* align to a k */
		if(unlikely(len != logg_buff->capacity))
		{
			struct big_buff *tmp_buf = realloc(logg_buff, sizeof(*logg_buff) + len);
			if(tmp_buf) {
				logg_buff = tmp_buf;
				logg_buff->limit = logg_buff->capacity = len;
			} else {
				ret_val = buffer_remaining(*logg_buff);
				break;
			}
		}
		/* put msg printed out in buffer */
		va_copy(tmp_valist, args);
		ret_val = my_vsnprintf(buffer_start(*logg_buff), buffer_remaining(*logg_buff), fmt, tmp_valist);
		va_end(tmp_valist);
		/* error? repeat */
	} while(unlikely(ret_val < 0 || (size_t)ret_val > buffer_remaining(*logg_buff)));
	logg_buff->pos += (size_t)ret_val;

	/* add errno string if wanted */
	if(log_errno)
	{
		if(buffer_remaining(*logg_buff) < STRERROR_R_SIZE + 4)
		{
			size_t len = logg_buff->capacity * 2;
			struct big_buff *tmp_buff = realloc(logg_buff, sizeof(*logg_buff) + len);
			if(!tmp_buff)
				goto no_errno;
			logg_buff = tmp_buff;
			logg_buff->limit = logg_buff->capacity += len;
		}
		*buffer_start(*logg_buff) = ':'; logg_buff->pos++;
		*buffer_start(*logg_buff) = ' '; logg_buff->pos++;
		{
#if defined STRERROR_R_CHAR_P || defined HAVE_MTSAFE_STRERROR || WIN32 || !(defined HAVE_STRERROR_R || HAVE_DECL_STRERROR_R-0 > 0)
			size_t err_str_len;
# ifdef WIN32
			const char *s = buffer_start(*logg_buff);
			if(!(err_str_len = FormatMessage(
				FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, /* flags */
				0, /* pointer to other source */
				old_errno, /* msg id */
				MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* language */
				buffer_start(*logg_buff), /* buffer */
				buffer_remaining(*logg_buff)-1, /* size */
				0 /* va_args */
			))) {
				s = "Unknown system error";
				err_str_len = strlen(s) < buffer_remaining(*logg_buff)-2 ?
				              strlen(s) : buffer_remaining(*logg_buff)-2;
			}
# else
#  ifdef STRERROR_R_CHAR_P
			/*
			 * the f***ing GNU-Version of strerror_r wich returns
			 * a char * to the buffer....
			 * This sucks especially in conjunction with strnlen,
			 * wich needs a #define __GNU_SOURCE, but conflicts
			 * with this...
			 */
			const char *s = strerror_r(old_errno, buffer_start(*logg_buff), buffer_remaining(*logg_buff)-2);
#  else
			/*
			 * Ol Solaris seems to have a static msgtable, so
			 * strerror is threadsafe and we don't have a
			 * _r version
			 */
			/*
			 * we also simply fall into here if strerror is not thread
			 * safe, but we have nothing else.
			 * Since what should we do in this case... _sys_errlist
			 * is a bsd extentions.
			 */
			const char *s = strerror(old_errno);
#  endif
			if(s)
				err_str_len = strnlen(s, buffer_remaining(*logg_buff)-2);
			else {
				s = "Unknown system error";
				err_str_len = strlen(s) < (buffer_remaining(*logg_buff)-2) ?
				              strlen(s) : buffer_remaining(*logg_buff)-2;
			}
# endif

			if(s != buffer_start(*logg_buff))
				my_memcpy(buffer_start(*logg_buff), s, err_str_len);
			logg_buff->pos += err_str_len;
#else
			if(!strerror_r(old_errno, buffer_start(*logg_buff), buffer_remaining(*logg_buff)))
//			if(!strerror_s(buffer_start(*logg_buff), buffer_remaining(*logg_buff), old_errno))
				logg_buff->pos += strnlen(buffer_start(*logg_buff), buffer_remaining(*logg_buff));
			else
			{
				size_t err_l;
				const char *bs;
				if(EINVAL == errno) {
					err_l = str_size("Unknown errno value!");
					bs = "Unknown errno value!";
				} else if(ERANGE == errno) {
					err_l = str_size("errno msg to long for buffer!");
					bs = "errno msg to long for buffer!";
				} else {
					err_l = str_size("failure while retrieving errno msg!");
					bs = "failure while retrieving errno msg!";
				}
				err_l = (buffer_remaining(*logg_buff)-2) >= err_l ? err_l : (buffer_remaining(*logg_buff)-2);
				my_memcpy(buffer_start(*logg_buff), bs, err_l);
				logg_buff->pos += err_l;
			}
#endif
		}
		*buffer_start(*logg_buff) = '\n'; logg_buff->pos++;
		*buffer_start(*logg_buff) = '\0';
	}
no_errno:

	/* output that stuff */
	buffer_flip(*logg_buff);
	ret_val = do_logging(level, buffer_start(*logg_buff), buffer_remaining(*logg_buff));
	logg_ret_buf(logg_buff);
	return ret_val;
}