26 RCSID(
"$Id: e2f6bf5d579f3bd8ca3b159a8910864c56a9ac86 $")
29 #define LOG_PREFIX mctx->inst->name
31 #include <freeradius-devel/radius/radius.h>
32 #include <freeradius-devel/server/base.h>
33 #include <freeradius-devel/server/module_rlm.h>
34 #include <freeradius-devel/server/sysutmp.h>
35 #include <freeradius-devel/util/perm.h>
36 #include <freeradius-devel/unlang/xlat_func.h>
48 static char trans[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
49 #define ENC(c) trans[c]
115 RPEDEBUG(
"Failed resolving user name");
120 RPEDEBUG(
"Failed resolving group name");
131 if (pwd->pw_gid == grp->gr_gid) {
137 for (member = grp->gr_mem; *member; member++) {
138 if (strcmp(*member, pwd->pw_name) == 0) {
167 char const *p = arg->vb_strvalue;
196 PERROR(
"Failed registering group expansion");
207 xlat_arg[0].
concat =
true;
208 xlat_arg[0].
func = NULL;
209 xlat_arg[0].
uctx = NULL;
225 char const *encrypted_pass;
227 struct spwd *spwd = NULL;
230 #ifdef HAVE_GETUSERSHELL
244 encrypted_pass = NULL;
246 if ((pwd = getpwnam(
name)) == NULL) {
249 encrypted_pass = pwd->pw_passwd;
261 if ((!encrypted_pass) || (strlen(encrypted_pass) < 10)) {
262 if ((spwd = getspnam(
name)) == NULL) {
265 encrypted_pass = spwd->sp_pwdp;
273 if (strcmp(pwd->pw_shell, DENY_SHELL) == 0) {
279 #ifdef HAVE_GETUSERSHELL
284 while ((shell = getusershell()) != NULL) {
285 if (strcmp(shell, pwd->pw_shell) == 0 ||
286 strcmp(shell,
"/RADIUSD/ANY/SHELL") == 0) {
292 REDEBUG(
"[%s]: invalid shell [%s]",
name, pwd->pw_shell);
297 #if defined(HAVE_GETSPNAM) && !defined(M_UNIX)
301 if (spwd && spwd->sp_lstchg > 0 && spwd->sp_max >= 0 &&
302 (
fr_time_to_sec(request->packet->timestamp) / 86400) > (spwd->sp_lstchg + spwd->sp_max)) {
309 if (spwd && spwd->sp_expire > 0 &&
310 (
fr_time_to_sec(request->packet->timestamp) / 86400) > spwd->sp_expire) {
316 #if defined(__FreeBSD__) || defined(bsdi) || defined(_PWF_EXPIRE)
320 if ((pwd->pw_expire > 0) &&
332 if (encrypted_pass[0] == 0)
350 static unsigned char res[7];
351 unsigned char *
data = (
unsigned char *)
in;
354 res[1] =
ENC( ((
data[0] << 4) & 060) + ((
data[1] >> 4) & 017) );
355 res[2] =
ENC( ((
data[1] << 2) & 074) + ((
data[2] >> 6) & 03) );
359 res[5] =
ENC( (
data[3] << 4) & 060 );
362 for(i = 0; i < 6; i++) {
363 if (res[i] ==
' ') res[i] =
'`';
364 if (res[i] < 32 || res[i] > 127)
365 printf(
"uue: protocol error ?!\n");
382 char const *s = NULL;
385 int framed_address = 0;
390 bool port_seen =
true;
396 if (!
inst->radwtmp) {
397 RDEBUG2(
"No radwtmp file configured. Ignoring accounting request");
401 if (request->packet->socket.inet.src_ipaddr.af != AF_INET) {
402 RDEBUG2(
"IPv6 is not supported!");
410 RDEBUG2(
"no Accounting-Status-Type attribute in request");
413 status =
vp->vp_uint32;
430 memset(&ut, 0,
sizeof(ut));
439 if (
vp->vp_length >=
sizeof(ut.ut_name)) {
440 memcpy(ut.ut_name,
vp->vp_strvalue,
sizeof(ut.ut_name));
442 strlcpy(ut.ut_name,
vp->vp_strvalue,
sizeof(ut.ut_name));
447 framed_address =
vp->vp_ipv4addr;
451 protocol =
vp->vp_uint32;
454 nas_address =
vp->vp_ipv4addr;
457 nas_port =
vp->vp_uint32;
463 delay =
vp->vp_uint32;
476 if (strncmp(ut.ut_name,
"!root",
sizeof(ut.ut_name)) == 0 || !port_seen)
483 if (nas_address == 0) {
484 nas_address = request->packet->socket.inet.src_ipaddr.addr.v4.s_addr;
489 if (!s || s[0] == 0) s =
uue(&(nas_address));
501 snprintf(buf,
sizeof(buf),
"%03u:%s", nas_port, s);
508 if (framed_address) {
509 inet_ntop(AF_INET, &framed_address, buf,
sizeof(buf));
541 if ((fp = fopen(
inst->radwtmp,
"a")) != NULL) {
542 if ((fwrite(&ut,
sizeof(ut), 1, fp)) != 1) {
565 { .name1 =
"recv", .name2 =
"access-request", .method =
mod_authorize },
566 { .name1 =
"send", .name2 =
"accounting-response", .method =
mod_accounting },
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
strcpy(log_entry->msg, buffer)
#define USES_APPLE_DEPRECATED_API
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET_FLAGS(_name, _flags, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Defines a CONF_PAIR to C data type mapping.
static int fr_dcursor_append(fr_dcursor_t *cursor, void *v)
Insert a single item at the end of the list.
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Specifies an attribute which must be present for the module to function.
Specifies a dictionary which must be loaded/loadable for the module to function.
void *_CONST data
Module instance's parsed configuration.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
static xlat_action_t unix_group_xlat(TALLOC_CTX *ctx, fr_dcursor_t *out, xlat_ctx_t const *xctx, request_t *request, fr_value_box_list_t *in)
Check if the user is a member of a particular unix group.
char const * shortname
Client nickname.
Describes a host allowed to send packets to the server.
#define RPEDEBUG(fmt,...)
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_BOOL
A truth value.
#define fr_skip_whitespace(_p)
Skip whitespace ('\t', '\n', '\v', '\f', '\r', ' ')
char const * inet_ntop(int af, void const *src, char *dst, size_t cnt)
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
dl_module_inst_t const * inst
Dynamic loader API handle for the module.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for instantiation calls.
Specifies a module method identifier.
module_t common
Common fields presented by all modules.
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
int fr_perm_getgrnam(TALLOC_CTX *ctx, struct group **out, char const *name)
Resolve a group name to a group database entry.
int fr_perm_getpwnam(TALLOC_CTX *ctx, struct passwd **out, char const *name)
Resolve a username to a passwd entry.
static const conf_parser_t config[]
#define RETURN_MODULE_REJECT
#define RETURN_MODULE_NOOP
#define RETURN_MODULE_UPDATED
rlm_rcode_t
Return codes indicating the result of the module call.
#define RETURN_MODULE_NOTFOUND
static fr_dict_attr_t const * attr_login_ip_host
static fr_dict_attr_t const * attr_crypt_password
static fr_dict_t const * dict_freeradius
static char * uue(void *in)
static fr_dict_attr_t const * attr_expr_bool_enum
static fr_dict_t const * dict_radius
static int mod_bootstrap(module_inst_ctx_t const *mctx)
static fr_dict_attr_t const * attr_auth_type
static fr_dict_attr_t const * attr_nas_ip_address
static bool unix_check_group(UNUSED rlm_unix_t const *inst, request_t *request, char const *name)
Check if the user is in the given group.
static fr_dict_attr_t const * attr_framed_ip_address
static unlang_action_t mod_accounting(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
static fr_dict_attr_t const * attr_framed_protocol
static fr_dict_attr_t const * attr_nas_port
static fr_dict_attr_t const * attr_acct_status_type
static fr_dict_attr_t const * attr_user_name
static fr_dict_attr_t const * attr_acct_delay_time
static const conf_parser_t module_config[]
fr_dict_autoload_t rlm_unix_dict[]
static unlang_action_t mod_authorize(rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
fr_dict_attr_autoload_t rlm_unix_dict_attr[]
@ MODULE_TYPE_THREAD_UNSAFE
Module is not threadsafe.
#define MODULE_NAME_TERMINATOR
#define pair_update_control(_attr, _da)
Return or allocate a fr_pair_t in the control list.
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
fr_client_t * client_from_request(request_t *request)
Search up a list of requests trying to locate one which has a client.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
size_t strlcpy(char *dst, char const *src, size_t siz)
Stores an attribute, a value and various bits of other data.
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
char ut_line[UT_LINESIZE]
char ut_host[UT_HOSTSIZE]
#define talloc_get_type_abort_const
static int64_t fr_time_to_sec(fr_time_t when)
Convert an fr_time_t (internal time) to number of sec since the unix epoch (wallclock time)
fr_type_t type
Type to cast argument to.
void * uctx
Argument to pass to escape callback.
bool required
Argument must be present, and non-empty.
xlat_escape_func_t func
Function to handle tainted values.
bool concat
Concat boxes together.
#define XLAT_ARG_PARSER_TERMINATOR
@ XLAT_ACTION_DONE
We're done evaluating this level of nesting.
Definition for a single argument consumend by an xlat function.
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
static size_t char ** out
module_ctx_t const * mctx
Synthesised module calling ctx.
int xlat_func_mono_set(xlat_t *x, xlat_arg_parser_t const args[])
Register the argument of an xlat.
xlat_t * xlat_func_register_module(TALLOC_CTX *ctx, module_inst_ctx_t const *mctx, char const *name, xlat_func_t func, fr_type_t return_type)
Register an xlat function for a module.