📄 pam_radius.c
字号:
return PAM_SUCCESS;}static voidadd_stat_pairs(grad_avp_t *plist){ /* FIXME: noop */}static int_radius_acct(pam_handle_t *pamh, struct radutmp *ut){ grad_server_queue_t *queue; int retval; grad_avp_t *pairs, *add_pair = NULL; grad_request_t *req; grad_dict_value_t *dv; int type; grad_locus_t loc = { __FILE__, __LINE__ }; /* FIXME */ retval = pam_get_data(pamh, "radius_server_queue", (const void **)&queue); if (retval != PAM_SUCCESS) { _pam_log(LOG_CRIT, "can't get [radius_server_queue]: %s", pam_strerror(pamh, retval)); return PAM_NO_MODULE_DATA; } retval = pam_get_data(pamh, "radius_pairlist", (const void **)&add_pair); if (retval != PAM_SUCCESS && retval != PAM_NO_MODULE_DATA) { _pam_log(LOG_CRIT, "can't get [radius_attrlist]: %s", pam_strerror(pamh, retval)); return PAM_SESSION_ERR; } ut->nas_address = ntohl(queue->source_ip); /* * Create accounting request */ pairs = NULL; grad_avl_add_pair(&pairs, grad_avp_create_string(DA_USER_NAME, ut->login)); grad_avl_add_pair(&pairs, grad_avp_create_integer(DA_NAS_IP_ADDRESS, queue->source_ip)); grad_avl_add_pair(&pairs, grad_avp_create_integer(DA_NAS_PORT_ID, ut->nas_port)); grad_avl_add_pair(&pairs, grad_avp_create_string(DA_ACCT_SESSION_ID, ut->session_id)); /* Add any additional attributes */ for (; add_pair; add_pair = add_pair->next) { grad_avp_t *p = grad_create_pair(&loc, add_pair->name, grad_operator_equal, add_pair->avp_strvalue); switch (p->attribute) { case DA_LOGIN_IP_HOST: case DA_FRAMED_IP_ADDRESS: ut->framed_address = htonl(p->avp_lvalue); break; case DA_FRAMED_PROTOCOL: ut->proto = p->avp_lvalue; break; case DA_ACCT_DELAY_TIME: ut->delay = p->avp_lvalue; break; case DA_NAS_PORT_TYPE: ut->porttype = p->avp_lvalue; break; } grad_avl_add_pair(&pairs, p); } switch (ut->type) { case P_LOGIN: type = DV_ACCT_STATUS_TYPE_START; radutmp_putent(radutmp_path, ut, type); break; case P_IDLE: type = DV_ACCT_STATUS_TYPE_STOP; radutmp_putent(radutmp_path, ut, type); grad_avl_add_pair(&pairs, grad_avp_create_integer(DA_ACCT_SESSION_TIME, ut->duration)); add_stat_pairs(pairs); } grad_avl_add_pair(&pairs, grad_avp_create_integer(DA_ACCT_STATUS_TYPE, type)); req = grad_client_send(queue, GRAD_PORT_ACCT, RT_ACCOUNTING_REQUEST, pairs); if (req == NULL) { _pam_log(LOG_ERR, "no response from radius server"); grad_avl_free(pairs); return PAM_SESSION_ERR; } if (req->code == RT_ACCOUNTING_RESPONSE) retval = PAM_SUCCESS; else { _pam_log(LOG_CRIT, "received unexpected response: %d", req->code); retval = PAM_SESSION_ERR; } grad_request_free(req); return retval;}static intconverse(pam_handle_t *pamh, int nargs, struct pam_message **message, struct pam_response **response){ int retval; struct pam_conv *conv; DEBUG(100,("enter converse")); retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv); DEBUG(10,("pam_get_item(PAM_CONV): %d", retval)); if (retval == PAM_SUCCESS) { retval = conv->conv(nargs, (const struct pam_message **) message, response, conv->appdata_ptr); DEBUG(10, ("app conversation returned %d", retval)); if (retval != PAM_SUCCESS) { AUDIT(("conversation failure [%s]", pam_strerror(pamh, retval))); } } else if (retval != PAM_CONV_AGAIN) { _pam_log(LOG_ERR, "couldn't obtain coversation function: %s", pam_strerror(pamh, retval)); } DEBUG(100,("exit converse: %d", retval)); return retval; /* propagate error status */}static int_pam_get_password(pam_handle_t *pamh, char **password, const char *prompt){ char *item, *token; int retval; struct pam_message msg[3], *pmsg[3]; struct pam_response *resp; int i, replies; DEBUG(100,("enter _pam_get_password")); if (cntl_flags&CNTL_AUTHTOK) { /* * get the password from the PAM item */ retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &item); if (retval != PAM_SUCCESS) { /* very strange. */ _pam_log(LOG_ALERT, "can't retrieve password item: %s", pam_strerror(pamh, retval)); return retval; } else if (item != NULL) { *password = item; item = NULL; return PAM_SUCCESS; } else return PAM_AUTHTOK_RECOVER_ERR; } /* * ask user for the password */ /* prepare to converse */ i = 0; pmsg[i] = &msg[i]; msg[i].msg_style = PAM_PROMPT_ECHO_OFF; msg[i++].msg = (const void*)prompt; replies = 1; /* run conversation */ resp = NULL; token = NULL; retval = converse(pamh, i, pmsg, &resp); if (resp != NULL) { if (retval == PAM_SUCCESS) { /* a good conversation */ token = XSTRDUP(resp[i - replies].resp); DEBUG(10,("app returned [%s]", token)); PAM_DROP_REPLY(resp, 1); } else { AUDIT(("conversation error: %s", pam_strerror(pamh, retval))); } } else { retval = (retval == PAM_SUCCESS) ? PAM_AUTHTOK_RECOVER_ERR : retval; } if (retval == PAM_SUCCESS) { /* * keep password as data specific to this module. pam_end() * will arrange to clean it up. */ retval = pam_set_data(pamh, "password", (void *)token, _cleanup_string); if (retval != PAM_SUCCESS) { _pam_log(LOG_CRIT, "can't keep password: %s", pam_strerror(pamh, retval)); _pam_delete(token); } else { *password = token; token = NULL; /* break link to password */ } } else { AUDIT(("unable to obtain a password: %s", pam_strerror(pamh, retval))); } DEBUG(100,("exit _pam_get_password: %d", retval)); return retval;}static voiddebug_hook(int mode, const char *file, int line){#ifdef MAINTAINER_MODE if (CNTL_HANG() & mode) { int status; _pam_log(LOG_CRIT, "WAITING FOR DEBUG AT %s:%d", file, line); status = 0; while (!status) status = status; }#endif }/* * PAM framework looks for these entry-points to pass control to the * authentication module. *//* Fun starts here :) * pam_sm_authenticate() performs RADIUS authentication * */PAM_EXTERN intpam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv){ int retval; char *name; char *password; _pam_parse(pamh, argc, argv); debug_hook(HANG_START, __FILE__, __LINE__); DEBUG(100,("enter pam_sm_authenticate")); for (;;) { /* * initialize client side */ if (_pam_init_radius_client(pamh)) { _pam_log(LOG_ERR, "can't initialize client side"); retval = PAM_AUTHINFO_UNAVAIL; break; } /* * get username */ retval = pam_get_user(pamh, (const char**)&name, "login: "); if (retval == PAM_SUCCESS) { DEBUG(10, ("username [%s] obtained", name)); } else { _pam_log(LOG_NOTICE, "can't get username"); break; } /* * get password */ retval = _pam_get_password(pamh, &password, "password: "); if (retval == PAM_SUCCESS) { retval = _radius_auth(pamh, name, password); if (retval != PAM_SUCCESS) pam_set_item(pamh, PAM_AUTHTOK, password); } break; } name = password = NULL; DEBUG(100,("exit pam_sm_authenticate: %d", retval)); return retval;}PAM_EXTERN intpam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv){ return PAM_SUCCESS;}static intdecode_port(const char *tty, int *port){ /* FIXME */ return PAM_SUCCESS;}static intpam_session_common(pam_handle_t *pamh, struct radutmp *ut){ int retval; char *user_name; char *tty = NULL; memset(ut, 0, sizeof(*ut)); time(&ut->time); /* initialize client side */ if (_pam_init_radius_client(pamh)) { _pam_log(LOG_ERR, "can't initialize client side"); return PAM_AUTHINFO_UNAVAIL; } retval = pam_get_item(pamh, PAM_USER, (void *) &user_name); if (retval == PAM_SUCCESS) { if (!user_name) { _pam_log(LOG_NOTICE, "got null username"); return PAM_SESSION_ERR; } DEBUG(10, ("username [%s] obtained", user_name)); } else { _pam_log(LOG_NOTICE, "can't get username"); return retval; } retval = pam_get_item(pamh, PAM_TTY, (const void **)&tty); if (retval == PAM_SUCCESS) { if (!tty) { _pam_log(LOG_NOTICE, "got null tty"); return PAM_SESSION_ERR; } DEBUG(10, ("tty [%s] obtained", *tty)); } else { _pam_log(LOG_NOTICE, "can't get tty"); } strncpy(ut->login, user_name, sizeof(ut->login)); ut->login[sizeof(ut->login)-1] = 0; strncpy(ut->orig_login, user_name, sizeof(ut->orig_login)); ut->orig_login[sizeof(ut->orig_login)-1] = 0; if (memcmp(tty, "/dev/", 5) == 0) tty += 5; retval = decode_port(tty, &ut->nas_port); /* Create a session id. Only one tty can hold a session */ snprintf(ut->session_id, sizeof(ut->session_id), "%s", tty); return retval;}PAM_EXTERN intpam_sm_open_session(pam_handle_t *pamh, int flags, int argc, const char **argv){ int retval; char *user_name; char *tty = NULL; struct radutmp ut; _pam_parse(pamh, argc, argv); DEBUG(100,("enter pam_sm_open_session")); debug_hook(HANG_START, __FILE__, __LINE__); retval = pam_session_common(pamh, &ut); if (retval != PAM_SUCCESS) return retval; ut.type = P_LOGIN; retval = _radius_acct(pamh, &ut); DEBUG(100,("exit pam_sm_open_session: %d", retval)); return retval;}PAM_EXTERN intpam_sm_close_session(pam_handle_t *pamh, int flags, int argc, const char **argv){ int retval; char *user_name; char *tty = NULL; struct radutmp ut; _pam_parse(pamh, argc, argv); DEBUG(100,("enter pam_sm_close_session")); debug_hook(HANG_STOP, __FILE__, __LINE__); retval = pam_session_common(pamh, &ut); if (retval != PAM_SUCCESS) return retval; ut.type = P_IDLE; retval = _radius_acct(pamh, &ut); DEBUG(100,("exit pam_sm_close_session: %d", retval)); return retval;}#ifdef PAM_STATICstruct pam_module _pam_radius_modstruct = { "pam_radius", /* name of the module */ pam_sm_authenticate, pam_sm_setcred, NULL, pam_sm_open_session, pam_sm_close_session, NULL};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -