#define PAM_SM_ACCOUNT 1 #define PAM_SM_AUTH 1 #define PAM_SM_SESSION 1 #define PAM_SM_PASSWORD 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifndef PAM_EXTERN # define PAM_EXTERN #endif #include #include #include #include #include #include #include char global_buff[256]; struct pam_args { bool get_pw_from_pam, get_pw_interactive, propagate_pw; }; struct pam_args Args; char * str_replace( char const * const original, char const * const pattern, char const * const replacement ) { size_t const replen = strlen(replacement); size_t const patlen = strlen(pattern); size_t const orilen = strlen(original); size_t patcnt = 0; const char * oriptr; const char * patloc; // find how many times the pattern occurs in the original string for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen) { patcnt++; } { // allocate memory for the new string size_t const retlen = orilen + patcnt * (replen - patlen); char * const returned = (char *) malloc( sizeof(char) * (retlen + 1) ); if (returned != NULL) { // copy the original string, // replacing all the instances of the pattern char * retptr = returned; for (oriptr = original; patloc = strstr(oriptr, pattern); oriptr = patloc + patlen) { size_t const skplen = patloc - oriptr; // copy the section until the occurence of the pattern strncpy(retptr, oriptr, skplen); retptr += skplen; // copy the replacement strncpy(retptr, replacement, replen); retptr += replen; } // copy the rest of the string. strcpy(retptr, oriptr); } return returned; } } int captureError(xmlrpc_env * const envP) { if(envP->fault_occurred) { //printf("%s\n",envP->fault_string); return -1; } } char *get_ip(char *srv) { struct hostent *lh=gethostbyname(srv); char answer[INET_ADDRSTRLEN]; if(lh!=NULL) { //printf("gethost not null\n"); inet_ntop(AF_INET,lh->h_addr_list[0],answer,INET_ADDRSTRLEN); char *ret=(char*)malloc(sizeof(char)*20); strcpy(ret,answer); return ret; } else { //printf("gethostbyname failed\n"); return srv; } } char *get_variable(char *variable) { xmlrpc_env env; xmlrpc_server_info *server; xmlrpc_value *resultP; struct xmlrpc_clientparms client_params; struct xmlrpc_curl_xportparms curl_params; xmlrpc_client *client; xmlrpc_value *params; xmlrpc_value *result; int result_size; char url[234]="https://"; const char *str_value; int error=0; curl_params.network_interface="localhost"; curl_params.no_ssl_verifypeer=1; curl_params.no_ssl_verifyhost=1; curl_params.user_agent="pam_lliurex"; client_params.transport="curl"; client_params.transportparmsP=&curl_params; client_params.transportparm_size=XMLRPC_CXPSIZE(user_agent); xmlrpc_env_init(&env); error=captureError(&env); if(error==-1) return NULL; xmlrpc_client_setup_global_const(&env); error=captureError(&env); if(error==-1) return NULL; xmlrpc_client_create(&env,0,"pam_lliurex","1",&client_params,XMLRPC_CPSIZE(transportparm_size),&client); error=captureError(&env); if(error==-1) return NULL; server=xmlrpc_server_info_new(&env,"https://localhost:9779"); error=captureError(&env); if(error==-1) return NULL; params=xmlrpc_array_new(&env); error=captureError(&env); if(error==-1) return NULL; xmlrpc_array_append_item(&env,params,xmlrpc_string_new(&env,"")); error=captureError(&env); if(error==-1) return NULL; xmlrpc_array_append_item(&env,params,xmlrpc_string_new(&env,"VariablesManager")); error=captureError(&env); if(error==-1) return NULL; xmlrpc_array_append_item(&env,params,xmlrpc_string_new(&env,variable)); error=captureError(&env); if(error==-1) return NULL; xmlrpc_client_call2(&env,client,server,"get_variable",params,&result); error=captureError(&env); if(error==-1) return NULL; if(!env.fault_occurred) { xmlrpc_read_string(&env,result,&str_value); error=captureError(&env); if(error==-1) return NULL; else return (char*)str_value; } else return NULL; } char *register_ticket(const char *server_url, const char *user, const char *password) { xmlrpc_env env; xmlrpc_server_info *server; xmlrpc_value *resultP; xmlrpc_value *user_info; xmlrpc_value *user_info2; struct xmlrpc_clientparms client_params; struct xmlrpc_curl_xportparms curl_params; xmlrpc_client *client; xmlrpc_value *params; xmlrpc_value *result; int result_size; char url[234]="https://"; const char *str_value; int error=0; char *n4d_key; curl_params.network_interface=0; curl_params.no_ssl_verifypeer=1; curl_params.no_ssl_verifyhost=1; curl_params.user_agent="pam_lliurex"; client_params.transport="curl"; client_params.transportparmsP=&curl_params; client_params.transportparm_size=XMLRPC_CXPSIZE(user_agent); xmlrpc_env_init(&env); error=captureError(&env); if(error==-1) return NULL; xmlrpc_client_setup_global_const(&env); error=captureError(&env); if(error==-1) return NULL; xmlrpc_client_create(&env,0,"pam_lliurex","1",&client_params,XMLRPC_CPSIZE(transportparm_size),&client); error=captureError(&env); if(error==-1) return NULL; server_url=get_ip(server_url); //printf("%s\n",server_url); strcat(url,server_url); strcat(url,":9779"); server=xmlrpc_server_info_new(&env,url); error=captureError(&env); if(error==-1) return NULL; params=xmlrpc_array_new(&env); error=captureError(&env); if(error==-1) return NULL; xmlrpc_array_append_item(&env,params,xmlrpc_string_new(&env,user)); error=captureError(&env); if(error==-1) return NULL; xmlrpc_array_append_item(&env,params,xmlrpc_string_new(&env,password)); error=captureError(&env); if(error==-1) return NULL; xmlrpc_client_call2(&env,client,server,"register_n4d_ticket",params,&result); error=captureError(&env); if(error==-1) return NULL; //printf("register_credentials 5\n"); //printf("RESULT SIZE: %i\n",result_size); if(!env.fault_occurred) { xmlrpc_read_string(&env,result,&str_value); error=captureError(&env); if(error==-1) return NULL; else return (char*)str_value; } else return NULL; } int *set_ticket(const char *user, const char *ticket) { FILE *file; char buff[256]; sprintf(buff,"/run/n4d/tickets/%s",user); file = fopen(buff,"w"); if(file!=NULL) { fprintf(file,"%s", ticket); fclose(file); struct passwd *pwd; pwd=getpwnam(user); chown(buff,pwd->pw_uid,0); chmod(buff,0460); return 0; } return -1; } static void clean_system_authtok(pam_handle_t *pamh, void *data, int errcode) { //w4rn("clean system authtok=%p (%d)\n", data, errcode); /* if (data != NULL) { unsigned int len = strlen(data) + 1; memset(data, 0, len); munlock(data, len); free(data); } */ } char *grab_password(pam_handle_t *pamh) { char *authtok = NULL; char *user=NULL; int ret; Args.get_pw_from_pam = true; Args.get_pw_interactive = true; Args.propagate_pw = true; if (Args.get_pw_from_pam) { ret = pam_get_item(pamh, PAM_AUTHTOK, static_cast(const void **,static_cast(void *, &authtok))); if (ret == PAM_SUCCESS && authtok != NULL) { //strcpy(global_buff,authtok); //ret = pam_set_data(pamh, "pam_n4d_system_authtok", global_buff, clean_system_authtok); //char buff[256]; //sprintf(buff,"echo %s >> /tmp/log",authtok); //system(buff); return authtok; } } return NULL; } static char *grab_authtok(pam_handle_t *pamh) { char *authtok = NULL; int ret; ret = pam_get_data(pamh, "pam_n4d_system_authtok",static_cast(const void **, static_cast(void *, &authtok))); if (ret == PAM_SUCCESS) { return authtok; } return NULL; } PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { const char *user = NULL; char *password=NULL; char *ip; char *ticket; int retval; retval = pam_get_item(pamh, PAM_USER, &user); password=grab_password(pamh); if(retval==PAM_SUCCESS) { pam_modutil_getpwnam (pamh, user); if(password!=NULL && user!=NULL) { ip=get_variable("SRV_IP"); if(ip!=NULL) { //printf("%s\n",ip); ticket=register_ticket(ip,user,password); if(ticket!=NULL) { //printf("%s\n",ticket); retval=set_ticket(user,ticket); //printf("%i\n",retval); } } } else { // DO NOTHING } } return PAM_SUCCESS; } PAM_EXTERN int pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) { const void *user = NULL; int retval; const char *password=NULL; password=grab_authtok(pamh); retval = pam_get_item(pamh, PAM_USER, &user); if(retval==PAM_SUCCESS) { if (pam_modutil_getpwnam (pamh, (const char*)user)!=NULL) { return PAM_SUCCESS; } } return PAM_SUCCESS; } PAM_EXTERN int pam_sm_close_session (pam_handle_t *pamh, int flags, int argc, const char **argv) { return PAM_SUCCESS; } PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { return (PAM_SUCCESS); } PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { return (PAM_SUCCESS); } PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char *argv[]) { return (PAM_SERVICE_ERR); }