24 RCSID(
"$Id: 727587dc4ad1b7d5750e8c5d2ebacf1e8fdbce16 $")
26 #define LOG_PREFIX "passwd"
28 #include <freeradius-devel/server/base.h>
29 #include <freeradius-devel/server/module_rlm.h>
30 #include <freeradius-devel/util/debug.h>
61 void printpw(
struct mypasswd *pw,
int num_fields){
64 for( i = 0; i < num_fields; i++ ) printf(
"%s:", pw->
field[i]);
67 else printf (
"Not found\n");
79 *len =
sizeof(
struct mypasswd) + num_fields *
sizeof (
char*) + num_fields *
sizeof (
char ) + strlen(
buffer) + 1;
86 struct mypasswd *passwd,
size_t bufferlen)
96 if (
string[len-1] ==
'\n') len--;
98 if (
string[len-1] ==
'\r') len--;
101 bufferlen < (len + num_fields *
sizeof (
char*) + num_fields *
sizeof (
char) +
sizeof (
struct mypasswd) + 1) )
return 0;
103 data_beg=(
char *)passwd +
sizeof(
struct mypasswd);
104 str = data_beg + num_fields *
sizeof (char) + num_fields *
sizeof (
char*);
105 memcpy (str,
string, len);
107 passwd->
field[fn++] = str;
108 passwd->
listflag = data_beg + num_fields *
sizeof (
char *);
109 for(i=0; i < len; i++){
110 if (str[i] == delimiter) {
112 passwd->
field[fn++] = str + i + 1;
113 if (fn == num_fields)
break;
116 for (; fn < num_fields; fn++) passwd->
field[fn] = NULL;
117 return len + num_fields * sizeof (
char) + num_fields *
sizeof (
char*) +
sizeof (
struct mypasswd) + 1;
125 while ((p = pass) != NULL) {
132 static unsigned int hash(
char const *
username,
unsigned int tablesize)
136 return h % tablesize;
165 struct mypasswd *hashentry, *hashentry1;
180 if (delimiter) ht->
delimiter = delimiter;
182 if(!tablesize)
return ht;
183 if(!(ht->
fp = fopen(
file,
"r"))) {
193 memset(ht->
buffer, 0, 1024);
195 while (fgets(
buffer, 1024, ht->
fp)) {
204 if (!hashentry->
field[key_field] || *hashentry->
field[key_field] ==
'\0') {
210 list = hashentry->
field[key_field];
211 for (nextlist = list; *nextlist && *nextlist!=
','; nextlist++);
212 if (*nextlist) *nextlist++ = 0;
215 h =
hash(hashentry->
field[key_field], tablesize);
217 ht->
table[h] = hashentry;
219 for (list=nextlist; nextlist; list = nextlist){
220 for (nextlist = list; *nextlist && *nextlist!=
','; nextlist++);
221 if (*nextlist) *nextlist++ = 0;
227 for (i=0; i<num_fields; i++) hashentry1->
field[i] = hashentry->
field[i];
228 hashentry1->
field[key_field] = list;
229 h =
hash(list, tablesize);
231 ht->
table[h] = hashentry1;
248 char *list, *nextlist;
252 hashentry = *last_found;
253 for (; hashentry; hashentry = hashentry->
next) {
256 *last_found = hashentry->
next;
263 if (!ht->
fp)
return NULL;
275 for (list = passwd->
field[ht->
key_field], nextlist = list; nextlist; list = nextlist) {
276 for(nextlist = list; *nextlist && *nextlist!=
','; nextlist++);
282 if (!strcmp(list,
name)) {
301 if (!ht || !
name || (*
name ==
'\0'))
return NULL;
305 for (hashentry = ht->
table[h]; hashentry; hashentry = hashentry->
next) {
308 *last_found=hashentry->
next;
319 if (!(ht->
fp=fopen(ht->
filename,
"r")))
return NULL;
325 #define MALLOC_CHECK_ 1
335 printf(
"Hash table not built\n");
341 for (pw = ht->
table[i]; pw; pw = pw->
next) {
347 while(fgets(
buffer, 1024, stdin)){
390 int num_fields = 0, key_field = -1, listable = 0;
402 if (
inst->hash_size == 0) {
409 ERROR(
"Memory allocation failed for lf");
412 memset(lf, 0, strlen(
inst->format));
414 s =
inst->format - 1;
416 if(s ==
inst->format - 1 || *s ==
':'){
418 key_field = num_fields;
445 inst->hash_size,
inst->ignore_nislike, *
inst->delimiter);
447 ERROR(
"Can't build hashtable from passwd file");
453 ERROR(
"Memory allocation failed");
459 ERROR(
"Unable to convert format entry");
465 memcpy(
inst->pwd_fmt->listflag, lf, num_fields);
468 for (i=0; i<num_fields; i++) {
469 if (*
inst->pwd_fmt->field[i] ==
'*')
inst->pwd_fmt->field[i]++;
470 if (*
inst->pwd_fmt->field[i] ==
',')
inst->pwd_fmt->field[i]++;
471 if (*
inst->pwd_fmt->field[i] ==
'=')
inst->pwd_fmt->field[i]++;
472 if (*
inst->pwd_fmt->field[i] ==
'~')
inst->pwd_fmt->field[i]++;
474 if (!*
inst->pwd_fmt->field[key_field]) {
482 inst->pwd_fmt->field[key_field],
true,
true);
484 PERROR(
"Unable to resolve attribute");
491 inst->num_fields = num_fields;
492 inst->key_field = key_field;
493 inst->listable = listable;
495 DEBUG3(
"num_fields: %d key_field %d(%s) listable: %s", num_fields, key_field,
496 inst->pwd_fmt->field[key_field], listable ?
"yes" :
"no");
520 for (i = 0; i <
inst->num_fields; i++) {
521 if (
inst->pwd_fmt->field[i] && *
inst->pwd_fmt->field[i] && pw->
field[i] &&
522 (i !=
inst->key_field) &&
inst->pwd_fmt->listflag[i] == when) {
523 if (!
inst->ignore_empty || pw->
field[i][0] != 0 ) {
528 REDEBUG(
"Ignoring unknown attribute '%s'",
inst->pwd_fmt->field[i]);
534 len = strlen(pw->
field[i]);
536 switch (
vp->vp_type) {
556 RDEBUG2(
"Added %s.%s: = %s ", listname,
inst->pwd_fmt->field[i], pw->
field[i]);
558 RDEBUG2(
"NOOP %s.%s = %s ", listname,
inst->pwd_fmt->field[i], pw->
field[i]);
582 #ifdef STATIC_ANALYZER
594 result_add(request->control_ctx,
inst, request, &request->control_pairs, pw, 0,
"config");
595 result_add(request->reply_ctx,
inst, request, &request->reply_pairs, pw, 1,
"reply_items");
596 result_add(request->request_ctx,
inst, request, &request->request_pairs, pw, 2,
"request_items");
601 if (!
inst->allow_multiple)
break;
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
static int const char char buffer[256]
#define CONF_PARSER_TERMINATOR
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
#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_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
@ CONF_FLAG_FILE_INPUT
File matching value must exist, and must be readable.
Defines a CONF_PAIR to C data type mapping.
A section grouping multiple CONF_PAIR.
#define cf_log_err(_cf, _fmt,...)
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
int main(int argc, char **argv)
fr_dict_attr_t const * fr_dict_attr_search_by_qualified_oid(fr_dict_attr_err_t *err, fr_dict_t const *dict_def, char const *attr, bool internal, bool foreign))
Locate a qualified fr_dict_attr_t by its name and a dictionary qualifier.
fr_dict_attr_t const * fr_dict_attr_by_name(fr_dict_attr_err_t *err, fr_dict_attr_t const *parent, char const *attr))
Locate a fr_dict_attr_t by its name.
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Specifies a dictionary which must be loaded/loadable for the module to function.
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
uint32_t fr_hash_string(char const *p)
#define RPEDEBUG(fmt,...)
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_OCTETS
Raw octets.
module_instance_t const * mi
Instance of the module being instantiated.
module_instance_t * mi
Module instance to detach.
module_instance_t * mi
Instance of the module being instantiated.
Temporary structure to hold arguments for module calls.
Temporary structure to hold arguments for detach calls.
Temporary structure to hold arguments for instantiation calls.
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.
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, bool tainted)
Convert string value to native attribute value.
static const conf_parser_t config[]
rlm_rcode_t
Return codes indicating the result of the module call.
#define RETURN_MODULE_NOTFOUND
static int mod_detach(module_detach_ctx_t const *mctx)
fr_dict_attr_t const * keyattr
static fr_dict_t const * dict_freeradius
static struct mypasswd * get_pw_nam(char *name, struct hashtable *ht, struct mypasswd **last_found)
static struct mypasswd * mypasswd_alloc(char const *buffer, int num_fields, size_t *len)
static unlang_action_t mod_passwd_map(rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
struct mypasswd * pwd_fmt
static struct hashtable * build_hash_table(char const *file, int num_fields, int key_field, int islist, int tablesize, int ignorenis, char delimiter)
static int string_to_entry(char const *string, int num_fields, char delimiter, struct mypasswd *passwd, size_t bufferlen)
static unsigned int hash(char const *username, unsigned int tablesize)
static void destroy_password(struct mypasswd *pass)
static struct mypasswd * get_next(char *name, struct hashtable *ht, struct mypasswd **last_found)
static void release_ht(struct hashtable *ht)
static const conf_parser_t module_config[]
static void result_add(TALLOC_CTX *ctx, rlm_passwd_t const *inst, request_t *request, fr_pair_list_t *vps, struct mypasswd *pw, char when, char const *listname)
static void release_hash_table(struct hashtable *ht)
static int mod_instantiate(module_inst_ctx_t const *mctx)
fr_dict_autoload_t rlm_passwd_dict[]
static int instantiate(module_inst_ctx_t const *mctx)
#define FR_SBUFF_OUT(_start, _len_or_end)
#define SECTION_NAME(_name1, _name2)
Define a section name consisting of a verb and a noun.
CONF_SECTION * conf
Module's instance configuration.
void * data
Module's instance data.
#define MODULE_BINDING_TERMINATOR
Terminate a module binding list.
Named methods exported by a module.
MEM(pair_append_request(&vp, attr_eap_aka_sim_identity) >=0)
eap_aka_sim_process_conf_t * inst
Stores an attribute, a value and various bits of other data.
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
#define talloc_get_type_abort_const
#define fr_pair_dcursor_by_da_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes matching the specified fr_dict_attr_t.
ssize_t fr_pair_print_value_quoted(fr_sbuff_t *out, fr_pair_t const *vp, fr_token_t quote)
Print the value of an attribute to a string.
int format(printf, 5, 0))