Exemplo n.º 1
0
static void check_pair(REQUEST *request, VALUE_PAIR *check_item, VALUE_PAIR *reply_item, int *pass, int *fail)
{
	int compare;

	if (check_item->op == T_OP_SET) return;

	compare = paircmp(check_item, reply_item);
	if (compare < 0) {
		REDEBUG("Comparison failed: %s", fr_strerror());
	}

	if (compare == 1) {
		++*(pass);
	} else {
		++*(fail);
	}

	if (RDEBUG_ENABLED3) {
		char rule[1024], pair[1024];

		vp_prints(rule, sizeof(rule), check_item);
		vp_prints(pair, sizeof(pair), reply_item);
		RDEBUG3("%s %s %s", pair, compare == 1 ? "allowed by" : "disallowed by", rule);
	}

	return;
}
Exemplo n.º 2
0
static int  addlinetocontent(VALUE_PAIR *vp) {

	int outlen = sizeof(content) - concntr - 1;
	int lendiv;

	if ( outlen < 4 ) return -1;
	if ( vp == NULL ) { /* add empty line */
		content[concntr++] = '\n';
		content[concntr] = '\0';
	} else {
		while ( vp != NULL ){
			lendiv = vp_prints(&content[concntr],outlen,vp);
			if ( lendiv > 0 ) {
				outlen -= lendiv;

				if (outlen > 3)  {
					strcat(content,", ");
					concntr += lendiv + 2;
					outlen -= 2;
				} else {
					concntr = 0;
					return -1;
				}
			}
			vp = vp -> next;
		}

		if ( concntr > 2 ) {  /* remove trailing ',' */
			content[--concntr] = '\0';
			content[concntr - 1] = '\n';
		}
	}

	return 0;
}
Exemplo n.º 3
0
/** Print one attribute and value to FP
 *
 * Complete string with '\\t' and '\\n' is written to buffer before printing to
 * avoid issues when running with multiple threads.
 *
 * @param fp to output to.
 * @param vp to print.
 */
void vp_print(FILE *fp, VALUE_PAIR const *vp)
{
	char	buf[1024];
	char	*p = buf;
	size_t	len;

	VERIFY_VP(vp);

	*p++ = '\t';
	len = vp_prints(p, sizeof(buf) - 1, vp);
	if (!len) {
		return;
	}
	p += len;

	/*
	 *	Deal with truncation gracefully
	 */
	if (((size_t) (p - buf)) >= (sizeof(buf) - 2)) {
		p = buf + (sizeof(buf) - 2);
	}

	*p++ = '\n';
	*p = '\0';

	fputs(buf, fp);
}
Exemplo n.º 4
0
/*
 *	Print one attribute and value.
 */
void vp_print(FILE *fp, VALUE_PAIR *vp)
{
	char	buf[1024];

	vp_prints(buf, sizeof(buf), vp);
	fputs(buf, fp);
}
Exemplo n.º 5
0
/** Print a list of valuepairs to the request list.
 *
 * @param[in] level Debug level (1-4).
 * @param[in] request to read logging params from.
 * @param[in] vp to print.
 */
void rdebug_pair_list(int level, REQUEST *request, VALUE_PAIR *vp)
{
	vp_cursor_t cursor;
	char buffer[256];
	if (!vp || !request || !request->log.func) return;

	if (!radlog_debug_enabled(L_DBG, level, request)) return;

	for (vp = fr_cursor_init(&cursor, &vp);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		/*
		 *	Take this opportunity to verify all the VALUE_PAIRs are still valid.
		 */
		if (!talloc_get_type(vp, VALUE_PAIR)) {
			REDEBUG("Expected VALUE_PAIR pointer got \"%s\"", talloc_get_name(vp));

			fr_log_talloc_report(vp);
			rad_assert(0);
		}

		vp_prints(buffer, sizeof(buffer), vp);
		RDEBUGX(level, "\t%s", buffer);
	}
}
Exemplo n.º 6
0
/*
 *      Dump a whole list of attributes to DEBUG2
 */
void vp_listdebug(VALUE_PAIR *vp)
{
    char tmpPair[70];
    for (; vp; vp = vp->next) {
        vp_prints(tmpPair, sizeof(tmpPair), vp);
        DEBUG2("     %s", tmpPair);
    }
}
Exemplo n.º 7
0
/*
 *      Dump a whole list of attributes to DEBUG2
 */
void vp_listdebug(VALUE_PAIR *vp)
{
	vp_cursor_t cursor;
	char tmpPair[70];
	for (vp = fr_cursor_init(&cursor, &vp);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		vp_prints(tmpPair, sizeof(tmpPair), vp);
		DEBUG2("     %s", tmpPair);
	}
}
Exemplo n.º 8
0
/** Print a list of valuepairs to the request list.
 * 
 * @param[in] level Debug level (1-4).
 * @param[in] request to read logging params from.
 * @param[in] vp to print.
 */
void rdebug_pair_list(int level, REQUEST *request, VALUE_PAIR *vp)
{
	char buffer[256];
	if (!vp || !request || !request->radlog) return;
	
	while (vp) {
		vp_prints(buffer, sizeof(buffer), vp);
		
		request->radlog(L_DBG, level, request, "\t%s", buffer);
		vp = vp->next;
	}	
}
Exemplo n.º 9
0
static void 
debug_packet(RADIUS_PACKET *packet, int direction)
{
	VALUE_PAIR *vp;
	char buffer[1024];
	const char *received, *from;
	const fr_ipaddr_t *ip;
	int port;

	if (!packet) return;

	if (direction == 0) {
		received = "Received";
		from = "from";	/* what else? */
		ip = &packet->src_ipaddr;
		port = packet->src_port;

	} else {
		received = "Sending";
		from = "to";	/* hah! */
		ip = &packet->dst_ipaddr;
		port = packet->dst_port;
	}
	
	/*
	 *	Client-specific debugging re-prints the input
	 *	packet into the client log.
	 *
	 *	This really belongs in a utility library
	 */
	if ((packet->code > 0) && (packet->code < FR_MAX_PACKET_CODE)) {
		printf("%s %s packet %s host %s port %d, id=%d, length=%d\n",
		       received, fr_packet_codes[packet->code], from,
		       inet_ntop(ip->af, &ip->ipaddr, buffer, sizeof(buffer)),
		       port, packet->id, packet->data_len);
	} else {
		printf("%s packet %s host %s port %d code=%d, id=%d, length=%d\n",
		       received, from,
		       inet_ntop(ip->af, &ip->ipaddr, buffer, sizeof(buffer)),
		       port,
		       packet->code, packet->id, packet->data_len);
	}

	for (vp = packet->vps; vp != NULL; vp = vp->next) {
		vp_prints(buffer, sizeof(buffer), vp);
		printf("\t%s\n", buffer);
	}
	fflush(stdout);
}
Exemplo n.º 10
0
/**
 * @brief Replace %whatever in a string.
 *
 *	See 'doc/variables.txt' for more information.
 *
 * @param out output buffer
 * @param outlen size of output buffer
 * @param fmt string to expand
 * @param request current request
 * @param func function to escape final value e.g. SQL quoting
 * @return length of string written @bug should really have -1 for failure
 */
int radius_xlat(char *out, int outlen, const char *fmt,
		REQUEST *request,
		RADIUS_ESCAPE_STRING func, void *funcarg)
{
	int c, len, freespace;
	const char *p;
	char *q;
	char *nl;
	VALUE_PAIR *tmp;
	struct tm *TM, s_TM;
	char tmpdt[40]; /* For temporary storing of dates */

	/*
	 *	Catch bad modules.
	 */
	if (!fmt || !out || !request) return 0;

       	q = out;
	p = fmt;
	while (*p) {
		/* Calculate freespace in output */
		freespace = outlen - (q - out);
		if (freespace <= 1)
			break;
		c = *p;

		if ((c != '%') && (c != '$') && (c != '\\')) {
			/*
			 * We check if we're inside an open brace.  If we are
			 * then we assume this brace is NOT literal, but is
			 * a closing brace and apply it
			 */
			*q++ = *p++;
			continue;
		}

		/*
		 *	There's nothing after this character, copy
		 *	the last '%' or "$' or '\\' over to the output
		 *	buffer, and exit.
		 */
		if (*++p == '\0') {
			*q++ = c;
			break;
		}

		if (c == '\\') {
			switch(*p) {
			case '\\':
				*q++ = *p;
				break;
			case 't':
				*q++ = '\t';
				break;
			case 'n':
				*q++ = '\n';
				break;
			default:
				*q++ = c;
				*q++ = *p;
				break;
			}
			p++;

		} else if (c == '%') switch(*p) {
			case '{':
				p--;
				if (decode_attribute(&p, &q, freespace, request, func, funcarg) < 0) return 0;
				break;

			case '%':
				*q++ = *p++;
				break;
			case 'd': /* request day */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%d", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'l': /* request timestamp */
				snprintf(tmpdt, sizeof(tmpdt), "%lu",
					 (unsigned long) request->timestamp);
				strlcpy(q,tmpdt,freespace);
				q += strlen(q);
				p++;
				break;
			case 'm': /* request month */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%m", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 't': /* request timestamp */
				CTIME_R(&request->timestamp, tmpdt, sizeof(tmpdt));
				nl = strchr(tmpdt, '\n');
				if (nl) *nl = '\0';
				strlcpy(q, tmpdt, freespace);
				q += strlen(q);
				p++;
				break;
			case 'C': /* ClientName */
				strlcpy(q,request->client->shortname,freespace);
				q += strlen(q);
				p++;
				break;
			case 'D': /* request date */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%Y%m%d", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'G': /* request minute */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%M", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'H': /* request hour */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%H", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'I': /* Request ID */
				snprintf(tmpdt, sizeof(tmpdt), "%i", request->packet->id);
				strlcpy(q, tmpdt, freespace);
				q += strlen(q);
				p++;
				break;
			case 'S': /* request timestamp in SQL format*/
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d %H:%M:%S", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'T': /* request timestamp */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d-%H.%M.%S.000000", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'V': /* Request-Authenticator */
				strlcpy(q,"Verified",freespace);
				q += strlen(q);
				p++;
				break;
			case 'Y': /* request year */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%Y", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'Z': /* Full request pairs except password */
				tmp = request->packet->vps;
				while (tmp && (freespace > 3)) {
					if (tmp->attribute != PW_USER_PASSWORD) {
						*q++ = '\t';
						len = vp_prints(q, freespace - 2, tmp);
						q += len;
						freespace -= (len + 2);
						*q++ = '\n';
					}
					tmp = tmp->next;
				}
				p++;
				break;
			default:
				RDEBUG2("WARNING: Unknown variable '%%%c': See 'doc/variables.txt'", *p);
				if (freespace > 2) {
					*q++ = '%';
					*q++ = *p++;
				}
				break;
		}
	}
	*q = '\0';

	RDEBUG2("\texpand: %s -> %s", fmt, out);

	return strlen(out);
}
Exemplo n.º 11
0
/**
 * @brief Replace %whatever in a string.
 *
 *	See 'doc/variables.txt' for more information.
 *
 * @param out output buffer
 * @param outlen size of output buffer
 * @param fmt string to expand
 * @param request current request
 * @param func function to escape final value e.g. SQL quoting
 * @return length of string written @bug should really have -1 for failure
 */
int radius_xlat(char *out, int outlen, const char *fmt,
		REQUEST *request, RADIUS_ESCAPE_STRING func)
{
	int c, len, freespace;
	const char *p;
	char *q;
	char *nl;
	VALUE_PAIR *tmp;
	struct tm *TM, s_TM;
	char tmpdt[40]; /* For temporary storing of dates */
	int openbraces=0;

	/*
	 *	Catch bad modules.
	 */
	if (!fmt || !out || !request) return 0;

	/*
	 *  Ensure that we always have an escaping function.
	 */
	if (func == NULL) {
		func = xlat_copy;
	}

       	q = out;
	p = fmt;
	while (*p) {
		/* Calculate freespace in output */
		freespace = outlen - (q - out);
		if (freespace <= 1)
			break;
		c = *p;

		if ((c != '%') && (c != '$') && (c != '\\')) {
			/*
			 * We check if we're inside an open brace.  If we are
			 * then we assume this brace is NOT literal, but is
			 * a closing brace and apply it
			 */
			if ((c == '}') && openbraces) {
				openbraces--;
				p++; /* skip it */
				continue;
			}
			*q++ = *p++;
			continue;
		}

		/*
		 *	There's nothing after this character, copy
		 *	the last '%' or "$' or '\\' over to the output
		 *	buffer, and exit.
		 */
		if (*++p == '\0') {
			*q++ = c;
			break;
		}

		if (c == '\\') {
			switch(*p) {
			case '\\':
				*q++ = *p;
				break;
			case 't':
				*q++ = '\t';
				break;
			case 'n':
				*q++ = '\n';
				break;
			default:
				*q++ = c;
				*q++ = *p;
				break;
			}
			p++;

		} else if (c == '%') switch(*p) {
			case '{':
				p--;
				if (decode_attribute(&p, &q, freespace, request, func) < 0) return 0;
				break;

			case '%':
				*q++ = *p++;
				break;
			case 'a': /* Protocol: */
				q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_PROTOCOL, 0),PW_TYPE_INTEGER, func);
				p++;
				break;
			case 'c': /* Callback-Number */
				q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_CALLBACK_NUMBER, 0),PW_TYPE_STRING, func);
				p++;
				break;
			case 'd': /* request day */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%d", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'f': /* Framed IP address */
				q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_IP_ADDRESS, 0),PW_TYPE_IPADDR, func);
				p++;
				break;
			case 'i': /* Calling station ID */
				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CALLING_STATION_ID, 0),PW_TYPE_STRING, func);
				p++;
				break;
			case 'l': /* request timestamp */
				snprintf(tmpdt, sizeof(tmpdt), "%lu",
					 (unsigned long) request->timestamp);
				strlcpy(q,tmpdt,freespace);
				q += strlen(q);
				p++;
				break;
			case 'm': /* request month */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%m", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'n': /* NAS IP address */
				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_IP_ADDRESS, 0),PW_TYPE_IPADDR, func);
				p++;
				break;
			case 'p': /* Port number */
				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_NAS_PORT, 0),PW_TYPE_INTEGER, func);
				p++;
				break;
			case 's': /* Speed */
				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_CONNECT_INFO, 0),PW_TYPE_STRING, func);
				p++;
				break;
			case 't': /* request timestamp */
				CTIME_R(&request->timestamp, tmpdt, sizeof(tmpdt));
				nl = strchr(tmpdt, '\n');
				if (nl) *nl = '\0';
				strlcpy(q, tmpdt, freespace);
				q += strlen(q);
				p++;
				break;
			case 'u': /* User name */
				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_USER_NAME, 0),PW_TYPE_STRING, func);
				p++;
				break;
			case 'A': /* radacct_dir */
				strlcpy(q,radacct_dir,freespace);
				q += strlen(q);
				p++;
				break;
			case 'C': /* ClientName */
				strlcpy(q,request->client->shortname,freespace);
				q += strlen(q);
				p++;
				break;
			case 'D': /* request date */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%Y%m%d", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'H': /* request hour */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%H", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'L': /* radlog_dir */
				strlcpy(q,radlog_dir,freespace);
				q += strlen(q);
				p++;
				break;
			case 'M': /* MTU */
				q += valuepair2str(q,freespace,pairfind(request->reply->vps,PW_FRAMED_MTU, 0),PW_TYPE_INTEGER, func);
				p++;
				break;
			case 'R': /* radius_dir */
				strlcpy(q,radius_dir,freespace);
				q += strlen(q);
				p++;
				break;
			case 'S': /* request timestamp in SQL format*/
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d %H:%M:%S", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'T': /* request timestamp */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%Y-%m-%d-%H.%M.%S.000000", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'U': /* Stripped User name */
				q += valuepair2str(q,freespace,pairfind(request->packet->vps,PW_STRIPPED_USER_NAME, 0),PW_TYPE_STRING, func);
				p++;
				break;
			case 'V': /* Request-Authenticator */
				strlcpy(q,"Verified",freespace);
				q += strlen(q);
				p++;
				break;
			case 'Y': /* request year */
				TM = localtime_r(&request->timestamp, &s_TM);
				len = strftime(tmpdt, sizeof(tmpdt), "%Y", TM);
				if (len > 0) {
					strlcpy(q, tmpdt, freespace);
					q += strlen(q);
				}
				p++;
				break;
			case 'Z': /* Full request pairs except password */
				tmp = request->packet->vps;
				while (tmp && (freespace > 3)) {
					if (tmp->attribute != PW_USER_PASSWORD) {
						*q++ = '\t';
						len = vp_prints(q, freespace - 2, tmp);
						q += len;
						freespace -= (len + 2);
						*q++ = '\n';
					}
					tmp = tmp->next;
				}
				p++;
				break;
			default:
				RDEBUG2("WARNING: Unknown variable '%%%c': See 'doc/variables.txt'", *p);
				if (freespace > 2) {
					*q++ = '%';
					*q++ = *p++;
				}
				break;
		}
	}
	*q = '\0';

	RDEBUG2("\texpand: %s -> %s", fmt, out);

	return strlen(out);
}
Exemplo n.º 12
0
/*
 *	Cache the reply items and the Auth-Type
 */
static int caching_postauth(void *instance, REQUEST *request)
{
	rlm_caching_t *data = (rlm_caching_t *)instance;
	char key[MAX_STRING_LEN];
	datum key_datum;
	datum data_datum;
	VALUE_PAIR *reply_vp;
	VALUE_PAIR *auth_type;
	rlm_caching_data cache_data;
	int count = 0;
	int ret = 0;
	int size = 0;
	int rcode = 0;

	if (pairfind(request->packet->vps, PW_CACHE_NO_CACHING, 0) != NULL){
		DEBUG("rlm_caching: Cache-No-Caching is set. Returning NOOP");
		return RLM_MODULE_NOOP;
	}
	if ((auth_type = pairfind(request->config_items, PW_AUTH_TYPE, 0)) != NULL){
		DEBUG("rlm_caching: Found Auth-Type, value: '%s'",auth_type->vp_strvalue);
		if (strcmp(auth_type->vp_strvalue,"Reject") == 0 && data->cache_rejects == 0){
			DEBUG("rlm_caching: No caching of Rejects. Returning NOOP");
			return RLM_MODULE_NOOP;
		}
		if (strlen(auth_type->vp_strvalue) > MAX_AUTH_TYPE - 1){
			DEBUG("rlm_caching: Auth-Type value too large");
			return RLM_MODULE_NOOP;
		}
	}
	else{
		DEBUG("rlm_caching: No Auth-Type found. Returning NOOP");
		return RLM_MODULE_NOOP;
	}

	reply_vp = request->reply->vps;

	if (reply_vp == NULL) {
		DEBUG("rlm_caching: The Request does not contain any reply attributes");
		return RLM_MODULE_NOOP;
	}
	if (!radius_xlat(key,sizeof(key), data->key, request, NULL)){
		radlog(L_ERR, "rlm_caching: xlat on key '%s' failed.",data->key);
		return RLM_MODULE_FAIL;
	}

	memset(&cache_data,0,sizeof(rlm_caching_data));

	cache_data.creation = time(NULL);
	strcpy(cache_data.auth_type,auth_type->vp_strvalue);

	size = MAX_RECORD_LEN;

	while(reply_vp) {
		if (size <= 1){
			DEBUG("rlm_caching: Not enough space.");
			return RLM_MODULE_NOOP;
		}
		ret = vp_prints(cache_data.data + count,size,reply_vp);
		if (ret == 0) {
			DEBUG("rlm_caching: Record is too large, will not store it.");
			return RLM_MODULE_NOOP;
		}
		count += (ret + 1);
		size -= (ret + 1);
		DEBUG("rlm_caching: VP=%s,VALUE=%s,length=%d,cache record length=%d, space left=%d",
			reply_vp->name,reply_vp->vp_strvalue,ret,count,size);
		reply_vp = reply_vp->next;
	}
	cache_data.len = count;

	DEBUG("rlm_caching: Storing cache for Key='%s'",key);
	data_datum.dptr = (rlm_caching_data *) &cache_data;
	data_datum.dsize = sizeof(rlm_caching_data);

	key_datum.dptr = (char *) key;
	key_datum.dsize = strlen(key);

	pthread_mutex_lock(&data->mutex);
	rcode = gdbm_store(data->gdbm, key_datum, data_datum, GDBM_REPLACE);
	pthread_mutex_unlock(&data->mutex);
	if (rcode < 0) {
		radlog(L_ERR, "rlm_caching: Failed storing data to %s: %s",
				data->filename, gdbm_strerror(gdbm_errno));
		return RLM_MODULE_FAIL;
	}
	DEBUG("rlm_caching: New value stored successfully.");

	return RLM_MODULE_OK;
}
Exemplo n.º 13
0
/*
 *	Write accounting information to this modules database.
 */
static int xmlrpc_accounting(void *instance, REQUEST * request)
{
	rlm_xmlrpc_t *inst = instance;
	rlm_xmlrpc_client_t *client;
	VALUE_PAIR *vps = request->packet->vps;

	xmlrpc_value *array_param;
	xmlrpc_value *array_string;
	xmlrpc_value *resultP;

	char *const methodName = inst->method;
	int error;

	VALUE_PAIR *status_type_pair;
	if ((status_type_pair = pairfind(request->packet->vps, PW_ACCT_STATUS_TYPE)) == NULL) {
		radlog(L_ERR, "rlm_xmlrpc: No Accounting-Status-Type record.");
		return RLM_MODULE_NOOP;
	}

	client = get_client(instance);

	/*
	 * Xmlrpc wants method params in an array, so we build an array
	 * with a pointer in index 0. This pointer contains a sub array
	 * filled whith strings each one for packet attributes.
	 */
	array_param = xmlrpc_array_new(&client->env);
	error = check_error(&client->env);
	if (error != RLM_MODULE_OK)
		return error;

	array_string = xmlrpc_array_new(&client->env);
	error = check_error(&client->env);
	if (error != RLM_MODULE_OK)
		return error;

	/*
	 * The array of strings is built whit vp_prints
	 */
	VALUE_PAIR *vp = vps;
	for (; vp; vp = vp->next) {
		char buf[1024];
		vp_prints(buf, sizeof(buf), vp);
		xmlrpc_array_append_item(&client->env, array_string,
					 xmlrpc_string_new(&client->env, buf));
		int error = check_error(&client->env);
		if (error != RLM_MODULE_OK)
			return error;
	}

	xmlrpc_array_append_item(&client->env, array_param, array_string);
	error = check_error(&client->env);
	if (error != RLM_MODULE_OK)
		return error;

	xmlrpc_client_call2(&client->env, client->clientP, client->serverInfoP,
			    methodName, array_param, &resultP);
	error = check_error(&client->env);
	if (error != RLM_MODULE_OK)
		return error;

	/*
	 * We don't check for method return value. If an accounting packet is
	 * dispatched without errors, it should be processed by server 
	 * without any further notification.
	 */

	xmlrpc_DECREF(resultP);
	xmlrpc_DECREF(array_param);
	xmlrpc_DECREF(array_string);

	return RLM_MODULE_OK;
}