📄 rlm_passwd.c
字号:
ht->last_found = NULL; if (ht->tablesize > 0) { h = hash (name, ht->tablesize); for (hashentry = ht->table[h]; hashentry; hashentry = hashentry->next) if (!strcmp(hashentry->field[ht->keyfield], name)){ /* save address of next item to check into buffer */ ht->last_found=hashentry->next; return hashentry; } return NULL; } if (ht->fp) fclose(ht->fp); if (!(ht->fp=fopen(ht->filename, "r"))) return NULL; return get_next(name, ht);}#ifdef TEST#define MALLOC_CHECK_ 1int main(void){ struct hashtable *ht; char *buffer; struct mypasswd* pw; int i; ht = build_hash_table("/etc/group", 4, 3, 1, 100, 0, ":"); if(!ht) { printf("Hash table not built\n"); return -1; } for (i=0; i<ht->tablesize; i++) if (ht->table[i]) { printf("%d:\n", i); for(pw=ht->table[i]; pw; pw=pw->next) printpw(pw, 4); } while(fgets(buffer, 1024, stdin)){ buffer[strlen(buffer)-1] = 0; pw = get_pw_nam(buffer, ht); printpw(pw,4); while (pw = get_next(buffer, ht)) printpw(pw,4); } release_ht(ht);}#else /* TEST */struct passwd_instance { struct hashtable *ht; struct mypasswd *pwdfmt; char *filename; char *format; char *authtype; char * delimiter; int allowmultiple; int ignorenislike; int hashsize; int nfields; int keyfield; int listable; int keyattr; int keyattrtype; int ignoreempty;};static CONF_PARSER module_config[] = { { "filename", PW_TYPE_STRING_PTR, offsetof(struct passwd_instance, filename), NULL, NULL }, { "format", PW_TYPE_STRING_PTR, offsetof(struct passwd_instance, format), NULL, NULL }, { "authtype", PW_TYPE_STRING_PTR, offsetof(struct passwd_instance, authtype), NULL, NULL }, { "delimiter", PW_TYPE_STRING_PTR, offsetof(struct passwd_instance, delimiter), NULL, ":" }, { "ignorenislike", PW_TYPE_BOOLEAN, offsetof(struct passwd_instance, ignorenislike), NULL, "yes" }, { "ignoreempty", PW_TYPE_BOOLEAN, offsetof(struct passwd_instance, ignoreempty), NULL, "yes" }, { "allowmultiplekeys", PW_TYPE_BOOLEAN, offsetof(struct passwd_instance, allowmultiple), NULL, "no" }, { "hashsize", PW_TYPE_INTEGER, offsetof(struct passwd_instance, hashsize), NULL, "100" }, { NULL, -1, 0, NULL, NULL }};static int passwd_instantiate(CONF_SECTION *conf, void **instance){#define inst ((struct passwd_instance *)*instance) int nfields=0, keyfield=-1, listable=0; char *s; char *lf=NULL; /* destination list flags temporary */ int len; int i; DICT_ATTR * da; *instance = rad_malloc(sizeof(struct passwd_instance)); if ( !*instance) { radlog(L_ERR, "rlm_passwd: cann't alloc instance"); return -1; } memset(*instance, 0, sizeof(struct passwd_instance)); if (cf_section_parse(conf, inst, module_config) < 0) { free(inst); radlog(L_ERR, "rlm_passwd: cann't parse configuration"); return -1; } if(!inst->filename || *inst->filename == '\0' || !inst->format || *inst->format == '\0') { radlog(L_ERR, "rlm_passwd: cann't find passwd file and/or format in configuration"); return -1; } lf=strdup(inst->format); if ( lf == NULL) { radlog(L_ERR, "rlm_passwd: memory allocation failed for lf"); return -1; } memset(lf, 0, strlen(inst->format)); s = inst->format - 1; do { if(s == inst->format - 1 || *s == ':'){ if(*(s+1) == '*'){ keyfield = nfields; s++; } if(*(s+1) == ','){ listable = 1; s++; } if(*(s+1) == '='){ lf[nfields]=1; s++; } if(*(s+1) == '~'){ lf[nfields]=2; s++; } nfields++; } s++; }while(*s); if(keyfield < 0) { radlog(L_ERR, "rlm_passwd: no field market as key in format: %s", inst->format); return -1; } if (! (inst->ht = build_hash_table (inst->filename, nfields, keyfield, listable, inst->hashsize, inst->ignorenislike, inst->delimiter)) ){ radlog(L_ERR, "rlm_passwd: can't build hashtable from passwd file"); return -1; } if (! (inst->pwdfmt = mypasswd_malloc(inst->format, nfields, &len)) ){ radlog(L_ERR, "rlm_passwd: memory allocation failed"); release_ht(inst->ht); return -1; } if (!string_to_entry(inst->format, nfields, ':', inst->pwdfmt , len)) { radlog(L_ERR, "rlm_passwd: unable to convert format entry"); release_ht(inst->ht); return -1; } memcpy(inst->pwdfmt->listflag, lf, nfields); free(lf); for (i=0; i<nfields; i++) { if (*inst->pwdfmt->field[i] == '*') inst->pwdfmt->field[i]++; if (*inst->pwdfmt->field[i] == ',') inst->pwdfmt->field[i]++; if (*inst->pwdfmt->field[i] == '=') inst->pwdfmt->field[i]++; if (*inst->pwdfmt->field[i] == '~') inst->pwdfmt->field[i]++; } if (!*inst->pwdfmt->field[keyfield]) { radlog(L_ERR, "rlm_passwd: key field is empty"); release_ht(inst->ht); return -1; } if (! (da = dict_attrbyname (inst->pwdfmt->field[keyfield])) ) { radlog(L_ERR, "rlm_passwd: unable to resolve attribute: %s", inst->pwdfmt->field[keyfield]); release_ht(inst->ht); return -1; } inst->keyattr = da->attr; inst->keyattrtype = da->type; inst->nfields = nfields; inst->keyfield = keyfield; inst->listable = listable; radlog(L_INFO, "rlm_passwd: nfields: %d keyfield %d(%s) listable: %s", nfields, keyfield, inst->pwdfmt->field[keyfield], listable?"yes":"no"); return 0;#undef inst}static int passwd_detach (void *instance) {#define inst ((struct passwd_instance *)instance) if(inst->ht) release_ht(inst->ht); if (inst->filename != NULL) free(inst->filename); if (inst->format != NULL) free(inst->format); if (inst->authtype != NULL ) free(inst->authtype); if (inst->delimiter != NULL) free(inst->delimiter); free(instance); return 0;#undef inst}static void addresult (struct passwd_instance * inst, VALUE_PAIR ** vp, struct mypasswd * pw, char when, const char *listname){ int i; VALUE_PAIR *newpair; for (i=0; i<inst->nfields; i++) { if (inst->pwdfmt->field[i] && *inst->pwdfmt->field[i] && pw->field[i] && i != inst->keyfield && inst->pwdfmt->listflag[i] == when) { if ( !inst->ignoreempty || pw->field[i][0] != 0 ) { /* if value in key/value pair is not empty */ if (! (newpair = pairmake (inst->pwdfmt->field[i], pw->field[i], T_OP_EQ))) { radlog(L_AUTH, "rlm_passwd: Unable to create %s: %s", inst->pwdfmt->field[i], pw->field[i]); return; } radlog(L_DBG, "rlm_passwd: Added %s: '%s' to %s ", inst->pwdfmt->field[i], pw->field[i], listname); pairadd (vp, newpair); } else radlog(L_DBG, "rlm_passwd: NOOP %s: '%s' to %s ", inst->pwdfmt->field[i], pw->field[i], listname); } }}static int passwd_authorize(void *instance, REQUEST *request){#define inst ((struct passwd_instance *)instance) char * name; char buffer[1024]; VALUE_PAIR * key; struct mypasswd * pw; int found = 0; if(!request || !request->packet ||!request->packet->vps) return RLM_MODULE_INVALID; for (key = request->packet->vps; key && (key = pairfind (key, inst->keyattr)); key = key->next ){ switch (inst->keyattrtype) { case PW_TYPE_INTEGER: snprintf(buffer, 1024, "%u", key->lvalue); name = buffer; break; default: name = key->strvalue; } if (! (pw = get_pw_nam(name, inst->ht)) ) { continue; } do { addresult(inst, &request->config_items, pw, 0, "config_items"); addresult(inst, &request->reply->vps, pw, 1, "reply_items"); addresult(inst, &request->packet->vps, pw, 2, "request_items"); } while ( (pw = get_next(name, inst->ht)) ); found++; if (!inst->allowmultiple) break; } if(!found) { return RLM_MODULE_NOTFOUND; } if (inst->authtype && (key = pairmake ("Auth-Type", inst->authtype, T_OP_EQ))) { radlog(L_INFO, "rlm_passwd: Adding \"Auth-Type = %s\"", inst->authtype); /* * Don't call pairadd. pairmove doesn't * over-write existing attributes. */ pairmove(&request->config_items, &key); pairfree(&key); /* pairmove may have NOT moved it */ } return RLM_MODULE_OK;#undef inst}module_t rlm_passwd = { "passwd", RLM_TYPE_THREAD_SAFE, /* type */ NULL, /* initialize */ passwd_instantiate, /* instantiation */ { NULL, /* authentication */ passwd_authorize, /* authorization */ NULL, /* pre-accounting */ NULL, /* accounting */ NULL, /* checksimul */ NULL, /* pre-proxy */ NULL, /* post-proxy */ NULL /* post-auth */ }, passwd_detach, /* detach */ NULL /* destroy */};#endif /* TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -