예제 #1
0
static int _mod_conn_free(linelog_conn_t *conn)
{
	if (shutdown(conn->sockfd, SHUT_RDWR) < 0) DEBUG3("Shutdown failed: %s", fr_syserror(errno));
	if (close(conn->sockfd) < 0) DEBUG3("Closing socket failed: %s", fr_syserror(errno));

	return 0;
}
예제 #2
0
static void *mod_conn_create(TALLOC_CTX *ctx, void *instance)
{
	int fd;
	struct sockaddr_un sa;
	rlm_smsotp_t *inst = instance;
	socklen_t socklen = sizeof(sa);
	int *fdp;

	sa.sun_family = AF_UNIX;
	strlcpy(sa.sun_path, inst->socket, sizeof(sa.sun_path));

	fd = socket(PF_UNIX, SOCK_STREAM, 0);
	if (fd < 0) {
		ERROR("Failed opening SMSOTP file %s: %s",
		       inst->socket, fr_syserror(errno));
		return NULL;
	}

	if (connect(fd, (struct sockaddr *) &sa, socklen) < -1) {
		ERROR("Failed connecting to SMSOTP file %s: %s",
		       inst->socket, fr_syserror(errno));
		return NULL;
	}

	fdp = talloc_zero(ctx, int);
	talloc_set_destructor(fdp, _mod_conn_free);
	*fdp = fd;

	return fdp;
}
예제 #3
0
static int client_socket(char const *server)
{
	int sockfd;
	uint16_t port;
	fr_ipaddr_t ipaddr;
	char *p, buffer[1024];

	strlcpy(buffer, server, sizeof(buffer));

	p = strchr(buffer, ':');
	if (!p) {
		port = PW_RADMIN_PORT;
	} else {
		port = atoi(p + 1);
		*p = '\0';
	}

	if (ip_hton(&ipaddr, AF_INET, buffer, false) < 0) {
		fprintf(stderr, "%s: Failed looking up host %s: %s\n",
			progname, buffer, fr_syserror(errno));
		exit(1);
	}

	sockfd = fr_tcp_client_socket(NULL, &ipaddr, port);
	if (sockfd < 0) {
		fprintf(stderr, "%s: Failed opening socket %s: %s\n",
			progname, server, fr_syserror(errno));
		exit(1);
	}

	return sockfd;
}
예제 #4
0
/** Open a raw socket to read/write packets from/to
 *
 * @param[out] link_layer	A sockaddr_ll struct to populate.  Must be passed to other raw
 *				functions.
 * @param[in] if_index		of the interface we're binding to.
 * @return
 *	- >= 0 a file descriptor to read/write packets on.
 *	- <0 an error ocurred.
 */
int fr_dhcpv4_raw_socket_open(struct sockaddr_ll *link_layer, int if_index)
{
	int fd;

	/*
	 * PF_PACKET - packet interface on device level.
	 * using a raw socket allows packet data to be unchanged by the device driver.
	 */
	fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
	if (fd < 0) {
		fr_strerror_printf("Cannot open socket: %s", fr_syserror(errno));
		return fd;
	}

	/* Set link layer parameters */
	memset(link_layer, 0, sizeof(struct sockaddr_ll));

	link_layer->sll_family = AF_PACKET;
	link_layer->sll_protocol = htons(ETH_P_ALL);
	link_layer->sll_ifindex = if_index;
	link_layer->sll_hatype = ARPHRD_ETHER;
	link_layer->sll_pkttype = PACKET_OTHERHOST;
	link_layer->sll_halen = 6;

	if (bind(fd, (struct sockaddr *)link_layer, sizeof(struct sockaddr_ll)) < 0) {
		close(fd);
		fr_strerror_printf("Cannot bind raw socket: %s", fr_syserror(errno));
		return -1;
	}

	return fd;
}
예제 #5
0
/*
 *	Zap all users on a NAS from the radutmp file.
 */
static rlm_rcode_t radutmp_zap(REQUEST *request, char const *filename, uint32_t nasaddr, time_t t)
{
	struct radutmp	u;
	int		fd;

	if (t == 0) time(&t);

	fd = open(filename, O_RDWR);
	if (fd < 0) {
		REDEBUG("Error accessing file %s: %s", filename, fr_syserror(errno));
		return RLM_MODULE_FAIL;
	}

	/*
	*	Lock the utmp file, prefer lockf() over flock().
	*/
	if (rad_lockfd(fd, LOCK_LEN) < 0) {
		REDEBUG("Failed to acquire lock on file %s: %s", filename, fr_syserror(errno));
		close(fd);
		return RLM_MODULE_FAIL;
	}

	/*
	*	Find the entry for this NAS / portno combination.
	*/
	while (read(fd, &u, sizeof(u)) == sizeof(u)) {
		if ((nasaddr != 0 && nasaddr != u.nas_address) || u.type != P_LOGIN) {
			continue;
		}
		/*
		 *	Match. Zap it.
		 */
		if (lseek(fd, -(off_t)sizeof(u), SEEK_CUR) < 0) {
			REDEBUG("radutmp_zap: negative lseek!");
			lseek(fd, (off_t)0, SEEK_SET);
		}
		u.type = P_IDLE;
		u.time = t;

		if (write(fd, &u, sizeof(u)) < 0) {
			REDEBUG("Failed writing: %s", fr_syserror(errno));

			close(fd);
			return RLM_MODULE_FAIL;
		}
	}
	close(fd);	/* and implicitely release the locks */

	return RLM_MODULE_OK;
}
예제 #6
0
파일: debug.c 프로젝트: janetuk/freeradius
/** Generate a talloc memory report for a context and print to stderr/stdout
 *
 * @param ctx to generate a report for, may be NULL in which case the root context is used.
 */
int fr_log_talloc_report(TALLOC_CTX *ctx)
{
#define TALLOC_REPORT_MAX_DEPTH 20

	FILE *log;
	int fd;

	fd = dup(fr_fault_log_fd);
	if (fd < 0) {
		fr_strerror_printf("Couldn't write memory report, failed to dup log fd: %s", fr_syserror(errno));
		return -1;
	}
	log = fdopen(fd, "w");
	if (!log) {
		close(fd);
		fr_strerror_printf("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno));
		return -1;
	}

	if (!ctx) {
		fprintf(log, "Current state of talloced memory:\n");
		talloc_report_full(talloc_null_ctx, log);
	} else {
		int i;

		fprintf(log, "Talloc chunk lineage:\n");
		fprintf(log, "%p (%s)", ctx, talloc_get_name(ctx));

		i = 0;
		while ((i < TALLOC_REPORT_MAX_DEPTH) && (ctx = talloc_parent(ctx))) {
			fprintf(log, " < %p (%s)", ctx, talloc_get_name(ctx));
			i++;
		}
		fprintf(log, "\n");

		i = 0;
		do {
			fprintf(log, "Talloc context level %i:\n", i++);
			talloc_report_full(ctx, log);
		} while ((ctx = talloc_parent(ctx)) &&
			 (i < TALLOC_REPORT_MAX_DEPTH) &&
			 (talloc_parent(ctx) != talloc_autofree_ctx) &&	/* Stop before we hit the autofree ctx */
			 (talloc_parent(ctx) != talloc_null_ctx));  	/* Stop before we hit NULL ctx */
	}

	fclose(log);

	return 0;
}
예제 #7
0
/*
 *	Open a socket TO the given IP and port.
 */
int fr_tcp_client_socket(fr_ipaddr_t *src_ipaddr,
			 fr_ipaddr_t *dst_ipaddr, uint16_t dst_port)
{
	int sockfd;
	struct sockaddr_storage salocal;
	socklen_t	salen;

	if (!dst_ipaddr) return -1;

	sockfd = socket(dst_ipaddr->af, SOCK_STREAM, 0);
	if (sockfd < 0) {
		return sockfd;
	}

	/*
	 *	Allow the caller to bind us to a specific source IP.
	 */
	if (src_ipaddr && (src_ipaddr->af != AF_UNSPEC)) {
		if (!fr_ipaddr2sockaddr(src_ipaddr, 0, &salocal, &salen)) {
			close(sockfd);
			return -1;
		}

		if (bind(sockfd, (struct sockaddr *) &salocal, salen) < 0) {
			fr_strerror_printf("Failure binding to IP: %s", fr_syserror(errno));
			close(sockfd);
			return -1;
		}
	}

	if (!fr_ipaddr2sockaddr(dst_ipaddr, dst_port, &salocal, &salen)) {
		close(sockfd);
		return -1;
	}

	/*
	 *	FIXME: If EINPROGRESS, then tell the caller that
	 *	somehow.  The caller can then call connect() when the
	 *	socket is ready...
	 */
	if (connect(sockfd, (struct sockaddr *) &salocal, salen) < 0) {
		fr_strerror_printf("Failed in connect(): %s", fr_syserror(errno));
		close(sockfd);
		return -1;
	}

	return sockfd;
}
/** Open a detail listener
 *
 */
static int mod_open(fr_listen_t *li)
{
	proto_detail_file_t const  *inst = talloc_get_type_abort_const(li->app_io_instance, proto_detail_file_t);
	proto_detail_file_thread_t *thread = talloc_get_type_abort(li->thread_instance, proto_detail_file_thread_t);

	if (inst->poll_interval == 0) {
		int oflag;

#ifdef O_EVTONLY
		oflag = O_EVTONLY;
#else
		oflag = O_RDONLY;
#endif
		li->fd = thread->fd = open(inst->directory, oflag);
	} else {
		li->fd = thread->fd = open("/dev/null", O_RDONLY);
	}
	if (thread->fd < 0) {
		cf_log_err(inst->cs, "Failed opening %s: %s", inst->directory, fr_syserror(errno));
		return -1;
	}

	thread->inst = inst;
	thread->name = talloc_typed_asprintf(thread, "detail polling for files matching %s", inst->filename);
	thread->vnode_fd = -1;
	pthread_mutex_init(&thread->worker_mutex, NULL);

	DEBUG("Listening on %s bound to virtual server %s",
	      thread->name, cf_section_name2(inst->parent->server_cs));

	return 0;
}
예제 #9
0
static PerlInterpreter *rlm_perl_clone(PerlInterpreter *perl, pthread_key_t *key)
{
	int ret;

	PerlInterpreter *interp;
	UV clone_flags = 0;

	PERL_SET_CONTEXT(perl);

	interp = pthread_getspecific(*key);
	if (interp) return interp;

	interp = perl_clone(perl, clone_flags);
	{
		dTHXa(interp);
	}
#  if PERL_REVISION >= 5 && PERL_VERSION <8
	call_pv("CLONE",0);
#  endif
	ptr_table_free(PL_ptr_table);
	PL_ptr_table = NULL;

	PERL_SET_CONTEXT(aTHX);
	rlm_perl_clear_handles(aTHX);

	ret = pthread_setspecific(*key, interp);
	if (ret != 0) {
		DEBUG("Failed associating interpretor with thread %s", fr_syserror(ret));

		rlm_perl_destruct(interp);
		return NULL;
	}

	return interp;
}
예제 #10
0
static void send_with_socket(RADIUS_PACKET *request)
{
	request->sockfd = sockfd;

	if (fr_dhcp_send(request) < 0) {
		fprintf(stderr, "dhcpclient: failed sending: %s\n",
			fr_syserror(errno));
		fr_exit_now(1);
	}

	if (!reply_expected) return;

	reply = fr_dhcp_recv(sockfd);
	if (!reply) {
		fprintf(stderr, "dhcpclient: Error receiving reply: %s\n", fr_strerror());
		fr_exit_now(1);
	}


	if (fr_debug_lvl) print_hex(reply);

	if (fr_dhcp_decode(reply) < 0) {
		fprintf(stderr, "dhcpclient: failed decoding\n");
		fr_exit_now(1);
	}
}
예제 #11
0
/*
 *	Full write with logging, and close on failure.
 *	Returns number of bytes written on success, errno on failure.
 */
static int otp_write(otp_fd_t *fdp, char const *buf, size_t len)
{
	size_t nleft = len;
	ssize_t nwrote;

	while (nleft) {
		nwrote = write(fdp->fd, &buf[len - nleft], nleft);
		if (nwrote == -1) {
			if (errno == EINTR) {
				continue;
			} else {
				ERROR("rlm_otp: %s: write to otpd: %s",
				       __func__, fr_syserror(errno));

				otp_putfd(fdp, 1);
				return errno;

			}
		}

		nleft -= nwrote;
	}

	return len - nleft;
}
예제 #12
0
void log_talloc_report(TALLOC_CTX *ctx)
{
	FILE *fd;
	char const *null_ctx = NULL;
	int i = 0;

	if (ctx) {
		null_ctx = talloc_get_name(NULL);
	}

	fd = fdopen(default_log.fd, "w");
	if (!fd) {
		ERROR("Couldn't write memory report, fdopen failed: %s", fr_syserror(errno));

		return;
	}

	if (!ctx) {
		talloc_report_full(NULL, fd);
	} else {
		do {
			INFO("Context level %i", i++);

			talloc_report_full(ctx, fd);
		} while ((ctx = talloc_parent(ctx)) && (talloc_get_name(ctx) != null_ctx));  /* Stop before we hit NULL ctx */
	}

	fclose(fd);
}
예제 #13
0
static int tls_socket_write(rad_listen_t *listener, REQUEST *request)
{
	uint8_t *p;
	ssize_t rcode;
	listen_socket_t *sock = listener->data;

	p = sock->ssn->dirty_out.data;

	while (p < (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used)) {
		RDEBUG3("Writing to socket %d", request->packet->sockfd);
		rcode = write(request->packet->sockfd, p,
			      (sock->ssn->dirty_out.data + sock->ssn->dirty_out.used) - p);
		if (rcode <= 0) {
			RDEBUG("Error writing to TLS socket: %s", fr_syserror(errno));

			tls_socket_close(listener);
			return 0;
		}
		p += rcode;
	}

	sock->ssn->dirty_out.used = 0;

	return 1;
}
예제 #14
0
/*
 * Full read with logging, and close on failure.
 * Returns nread on success, 0 on EOF, -1 on other failures.
 */
static int
otp_read(otp_fd_t *fdp, char *buf, size_t len)
{
	ssize_t n;
	size_t nread = 0;	/* bytes read into buf */

	while (nread < len) {
		n = read(fdp->fd, &buf[nread], len - nread);
		if (n == -1) {
			if (errno == EINTR) {
				continue;
			} else {
				ERROR("rlm_otp: %s: read from otpd: %s",
				       __func__, fr_syserror(errno));
				otp_putfd(fdp, 1);

				return -1;
			}
		}

		if (!n) {
			ERROR("rlm_otp: %s: otpd disconnect", __func__);
			otp_putfd(fdp, 1);

			return 0;
		}

		nread += n;
	} /* while (more to read) */

	return nread;
}
예제 #15
0
/*
 *	Log the query to a file.
 */
void rlm_sql_query_log(rlm_sql_t *inst, REQUEST *request,
		       sql_acct_section_t *section, char const *query)
{
	int fd;
	char const *filename = NULL;
	char *expanded = NULL;
	size_t len;
	bool failed = false;	/* Write the log message outside of the critical region */

	if (section) {
		filename = section->logfile;
	} else {
		filename = inst->config->logfile;
	}

	if (!filename) {
		return;
	}

	if (radius_axlat(&expanded, request, filename, NULL, NULL) < 0) {
		return;
	}

	fd = exfile_open(inst->ef, filename, 0640, true);
	if (fd < 0) {
		ERROR("rlm_sql (%s): Couldn't open logfile '%s': %s", inst->config->xlat_name,
		      expanded, fr_syserror(errno));

		talloc_free(expanded);
		return;
	}

	len = strlen(query);
	if ((write(fd, query, len) < 0) || (write(fd, ";\n", 2) < 0)) {
		failed = true;
	}

	if (failed) {
		ERROR("rlm_sql (%s): Failed writing to logfile '%s': %s", inst->config->xlat_name, expanded,
		      fr_syserror(errno));
	}

	talloc_free(expanded);
	exfile_close(inst->ef, fd);
}
예제 #16
0
파일: debug.c 프로젝트: janetuk/freeradius
/** Get the current maximum for core files
 *
 * Do this before anything else so as to ensure it's properly initialized.
 */
int fr_set_dumpable_init(void)
{
#ifdef HAVE_SYS_RESOURCE_H
	if (getrlimit(RLIMIT_CORE, &core_limits) < 0) {
		fr_strerror_printf("Failed to get current core limit:  %s", fr_syserror(errno));
		return -1;
	}
#endif
	return 0;
}
예제 #17
0
파일: debug.c 프로젝트: janetuk/freeradius
static int fr_set_dumpable_flag(bool dumpable)
{
	if (prctl(PR_SET_DUMPABLE, dumpable ? 1 : 0) < 0) {
		fr_strerror_printf("Cannot re-enable core dumps: prctl(PR_SET_DUMPABLE) failed: %s",
				   fr_syserror(errno));
		return -1;
	}

	return 0;
}
예제 #18
0
/** File descriptor experienced an error
 *
 * @param[in] el	fd was registered with.
 * @param[in] fd	that errored.
 * @param[in] flags	from kevent.
 * @param[in] fd_errno	from kevent.
 * @param[in] ctx	The rlm_rest_thread_t specific to this thread.
 */
static void _rest_io_service_errored(UNUSED fr_event_list_t *el, int fd, UNUSED int flags, int fd_errno, void *ctx)
{
	rlm_rest_thread_t *t;

	t = talloc_get_type_abort(ctx, rlm_rest_thread_t);

	DEBUG4("libcurl fd %i errored: %s", fd, fr_syserror(fd_errno));

	_rest_io_service(t, fd, CURL_CSELECT_ERR);
}
예제 #19
0
static ssize_t date_encode_strftime(char **out, size_t outlen, rlm_date_t const *inst,
				    REQUEST *request, time_t date)
{
	struct tm tminfo;

	if (inst->utc) {
		if (gmtime_r(&date, &tminfo) == NULL) {
			REDEBUG("Failed converting time string to gmtime: %s", fr_syserror(errno));
			return -1;
		}
	} else {
		if (localtime_r(&date, &tminfo) == NULL) {
			REDEBUG("Failed converting time string to localtime: %s", fr_syserror(errno));
			return -1;
		}
	}

	return strftime(*out, outlen, inst->fmt, &tminfo);
}
예제 #20
0
/** Connection errored
 *
 */
static void _logtee_conn_error(UNUSED fr_event_list_t *el, int sock, UNUSED int flags, int fd_errno, void *uctx)
{
	rlm_logtee_thread_t	*t = talloc_get_type_abort(uctx, rlm_logtee_thread_t);

	ERROR("Connection failed (%i): %s", sock, fr_syserror(fd_errno));

	/*
	 *	Something bad happened... Fix it...
	 */
	fr_connection_signal_reconnect(t->conn);
}
예제 #21
0
static void fr_set_dumpable(void)
{
	/*
	 *	If configured, turn core dumps off.
	 */
	if (!allow_core_dumps) {
#ifdef HAVE_SYS_RESOURCE_H
		struct rlimit no_core;


		no_core.rlim_cur = 0;
		no_core.rlim_max = 0;

		if (setrlimit(RLIMIT_CORE, &no_core) < 0) {
			ERROR("Failed disabling core dumps: %s", fr_syserror(errno));
		}
#endif
		return;
	}

	/*
	 *	Set or re-set the dumpable flag.
	 */
#ifdef HAVE_SYS_PRCTL_H
#ifdef PR_SET_DUMPABLE
	if (prctl(PR_SET_DUMPABLE, 1) < 0) {
		ERROR("Cannot re-enable core dumps: prctl(PR_SET_DUMPABLE) failed: '%s'", fr_syserror(errno));
	}
#endif
#endif

	/*
	 *	Reset the core dump limits to their original value.
	 */
#ifdef HAVE_SYS_RESOURCE_H
	if (setrlimit(RLIMIT_CORE, &core_limits) < 0) {
		ERROR("Cannot update core dump limit: %s",
		       fr_syserror(errno));
	}
#endif
}
예제 #22
0
/** Guaranteed initialization
 *
 */
void _otp_pthread_mutex_init(pthread_mutex_t *mutexp, pthread_mutexattr_t const *attr, char const *caller)
{
    int rc;

    rc = pthread_mutex_init(mutexp, attr);
    if (rc) {
        ERROR("rlm_otp: %s: pthread_mutex_init: %s",
              caller, fr_syserror(rc));

        exit(1);
    }
}
예제 #23
0
void fr_suid_down(void)
{
	if (!uid_name) return;

	if (setuid(server_uid) < 0) {
		fprintf(stderr, "%s: Failed switching to uid %s: %s\n",
			progname, uid_name, fr_syserror(errno));
		fr_exit_now(1);
	}

	fr_set_dumpable(allow_core_dumps);
}
예제 #24
0
/** Log to thread local error buffer
 *
 * @param fmt printf style format string. If NULL sets the 'new' byte to false,
 *	  effectively clearing the last message.
 */
void fr_strerror_printf(char const *fmt, ...)
{
	va_list ap;

	char *buffer;

	buffer = fr_thread_local_init(fr_strerror_buffer, _fr_logging_free);
	if (!buffer) {
		int ret;

		/*
		 *	malloc is thread safe, talloc is not
		 */
		buffer = calloc((FR_STRERROR_BUFSIZE * 2) + 1, sizeof(char));	/* One byte extra for status */
		if (!buffer) {
			fr_perror("Failed allocating memory for libradius error buffer");
			return;
		}

		ret = fr_thread_local_set(fr_strerror_buffer, buffer);
		if (ret != 0) {
			fr_perror("Failed setting up TLS for libradius error buffer: %s", fr_syserror(ret));
			free(buffer);
			return;
		}
	}

	/*
	 *	NULL has a special meaning, setting the new bit to false.
	 */
	if (!fmt) {
		buffer[FR_STRERROR_BUFSIZE * 2] &= 0x06;
		return;
	}

	va_start(ap, fmt);
	/*
	 *	Alternate where we write the message, so we can do:
	 *	fr_strerror_printf("Additional error: %s", fr_strerror());
	 */
	switch (buffer[FR_STRERROR_BUFSIZE * 2] & 0x06) {
	default:
		vsnprintf(buffer + FR_STRERROR_BUFSIZE, FR_STRERROR_BUFSIZE, fmt, ap);
		buffer[FR_STRERROR_BUFSIZE * 2] = 0x05;			/* Flip the 'new' bit to true */
		break;

	case 0x04:
		vsnprintf(buffer, FR_STRERROR_BUFSIZE, fmt, ap);
		buffer[FR_STRERROR_BUFSIZE * 2] = 0x03;			/* Flip the 'new' bit to true */
		break;
	}
	va_end(ap);
}
예제 #25
0
/** Guaranteed lock
 *
 */
void _otp_pthread_mutex_lock(pthread_mutex_t *mutexp, char const *caller)
{
    int rc;

    rc = pthread_mutex_lock(mutexp);
    if (rc) {
        ERROR("rlm_otp: %s: pthread_mutex_lock: %s",
              caller, fr_syserror(rc));

        exit(1);
    }
}
예제 #26
0
/*
 *	Log the query to a file.
 */
void rlm_sql_query_log(rlm_sql_t const *inst, REQUEST *request, sql_acct_section_t *section, char const *query)
{
	int fd;
	char const *filename = NULL;
	char *expanded = NULL;
	size_t len;
	bool failed = false;	/* Write the log message outside of the critical region */

	filename = inst->config->logfile;
	if (section && section->logfile) filename = section->logfile;

	if (!filename || !*filename) {
		return;
	}

	if (xlat_aeval(request, &expanded, request, filename, NULL, NULL) < 0) {
		return;
	}

	fd = exfile_open(inst->ef, request, filename, 0640);
	if (fd < 0) {
		ERROR("Couldn't open logfile '%s': %s", expanded, fr_syserror(errno));

		talloc_free(expanded);
		/* coverity[missing_unlock] */
		return;
	}

	len = strlen(query);
	if ((write(fd, query, len) < 0) || (write(fd, ";\n", 2) < 0)) {
		failed = true;
	}

	if (failed) ERROR("Failed writing to logfile '%s': %s", expanded, fr_syserror(errno));

	talloc_free(expanded);
	exfile_close(inst->ef, request, fd);
}
예제 #27
0
/* connect to otpd and return fd */
static int otp_connect(char const *path)
{
	int fd;
	struct sockaddr_un sa;
	size_t sp_len;		/* sun_path length (strlen) */

	/* setup for unix domain socket */
	sp_len = strlen(path);
	if (sp_len > sizeof(sa.sun_path) - 1) {
		ERROR("rlm_otp: %s: rendezvous point name too long",
		       __func__);

		return -1;
	}
	sa.sun_family = AF_UNIX;
	(void) strcpy(sa.sun_path, path);

	/* connect to otpd */
	fd = socket(PF_UNIX, SOCK_STREAM, 0);
	if (fd == -1) {
		ERROR("rlm_otp: %s: socket: %s", __func__,
		       fr_syserror(errno));

		return -1;
	}
	if (connect(fd, (struct sockaddr *) &sa,
	      sizeof(sa.sun_family) + sp_len) == -1) {

		ERROR("rlm_otp: %s: connect(%s): %s",
		       __func__, path, fr_syserror(errno));

		(void) close(fd);

		return -1;
	}

	return fd;
}
예제 #28
0
/*
 *	Log the query to a file.
 */
void rlm_sql_query_log(rlm_sql_t *inst, REQUEST *request,
		       sql_acct_section_t *section, char const *query)
{
	int fd;
	char const *filename = NULL;
	char *expanded = NULL;

	if (section) {
		filename = section->logfile;
	} else {
		filename = inst->config->logfile;
	}

	if (!filename) {
		return;
	}

	if (radius_axlat(&expanded, request, filename, NULL, NULL) < 0) {
		return;
	}

	fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0666);
	if (fd < 0) {
		ERROR("rlm_sql (%s): Couldn't open logfile '%s': %s", inst->config->xlat_name,
		       expanded, fr_syserror(errno));

		talloc_free(expanded);
		return;
	}

	if ((rad_lockfd(fd, MAX_QUERY_LEN) < 0) || (write(fd, query, strlen(query)) < 0) || (write(fd, ";\n", 2) < 0)) {
		ERROR("rlm_sql (%s): Failed writing to logfile '%s': %s", inst->config->xlat_name, expanded,
		       fr_syserror(errno));
	}

	talloc_free(expanded);
	close(fd);		/* and release the lock */
}
예제 #29
0
/** Free a control structure
 *
 *  This function really only calls the underlying "garbage collect".
 *
 * @param[in] c the control structure
 */
void fr_control_free(fr_control_t *c)
{
	struct kevent kev;

	(void) talloc_get_type_abort(c, fr_control_t);

	EV_SET(&kev, c->ident, EVFILT_USER, EV_DELETE, NOTE_FFNOP, 0, NULL);
	if (kevent(c->kq, &kev, 1, NULL, 0, NULL) < 0) {
		talloc_free(c);
		fr_strerror_printf("Failed opening KQ for control socket: %s", fr_syserror(errno));
	}

	talloc_free(c);
}
예제 #30
0
static void *mod_conn_create(TALLOC_CTX *ctx, void *instance, struct timeval const *timeout)
{
	int fd;
	rlm_smsotp_t *inst = instance;
	int *fdp;

	fd = fr_socket_client_unix(inst->socket, false);
	if (fd < 0) {
		ERROR("Failed opening SMSOTP file %s: %s", inst->socket, fr_syserror(errno));
		return NULL;
	}

	if (fr_socket_wait_for_connect(fd, timeout) < 0) {
		ERROR("Failed connecting to SMSOTP file %s: %s", inst->socket, fr_syserror(errno));
		return NULL;
	}

	fdp = talloc_zero(ctx, int);
	talloc_set_destructor(fdp, _mod_conn_free);
	*fdp = fd;

	return fdp;
}