#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; } } 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 *parse_mount_src(char *srv) { int rv; regex_t exp; rv=regcomp(&exp,"//[^ \t\r\n\v\f]+/",REG_EXTENDED); //rv=regcomp(&exp,"server-cless",REG_EXTENDED); regmatch_t matches[1]; rv=regexec(&exp,srv,1,matches,0); if(rv==0) { //printf("%d\n",rv); //printf("\"%s\" matches characters %d - %d\n", srv, matches[0].rm_so, matches[0].rm_eo); int len=matches[0].rm_eo-matches[0].rm_so; //printf("%d\n",len-3); char *buff=(char*)malloc(sizeof(char)*(len-2)); char *orig_buff[256]; memcpy(buff,&srv[matches[0].rm_so+2],len-3); buff[len-3]='\0'; //printf("%s))))))\n",buff); strcpy(orig_buff,buff); //printf("%s((((((\n",orig_buff); buff=get_ip(buff); //printf("lo que me queda es %s\n",buff); return str_replace(srv,orig_buff,buff); } return srv; } static void _mkdir(const char *dir,char* user) { char tmp[256]; char *p = NULL; size_t len; int ret; //char buff[256]; snprintf(tmp, sizeof(tmp),"%s",dir); len = strlen(tmp); if(tmp[len - 1] == '/') tmp[len - 1] = 0; for(p = tmp + 1; *p; p++) if(*p == '/') { *p = 0; //printf("%s\n",tmp); ret=mkdir(tmp,S_IRWXU); if(ret!=-1) { struct passwd *pwd; pwd=getpwnam(user); //sprintf(buff,"echo uid %i gid %i\n >> /tmp/log",pwd->pw_uid,pwd->pw_gid); //system(buff); chown(tmp,pwd->pw_uid,pwd->pw_gid); } *p = '/'; } //printf("%s\n",tmp); ret=mkdir(tmp,S_IRWXU); if(ret!=-1) { struct passwd *pwd; pwd=getpwnam(user); chown(tmp,pwd->pw_uid,pwd->pw_gid); } } bool is_dir_mounted(char* dir) { struct mntent *mnt_info; FILE *mnt_file; mnt_file = setmntent("/proc/mounts", "r"); if (mnt_file == NULL) return false; while (NULL != (mnt_info = getmntent(mnt_file))) { if(strcmp(mnt_info->mnt_dir,dir)==0) return true; } return false; } bool is_source_mounted(char* src) { struct mntent *mnt_info; FILE *mnt_file; mnt_file = setmntent("/proc/mounts", "r"); if (mnt_file == NULL) { //perror("setmntent"); return false; } while (NULL != (mnt_info = getmntent(mnt_file))) { if(strcmp(mnt_info->mnt_fsname,src)==0) return true; } return false; } int cmount(char* src, char *dir, char *type, char *opts,char *owner) { //printf("antes %s\n",src); char *parsed_src; char new_opts[256]; int rv; regex_t exp; rv=regcomp(&exp,"//[^ \t\r\n\v\f]+/",REG_EXTENDED); //rv=regcomp(&exp,"server-cless",REG_EXTENDED); regmatch_t matches[1]; rv=regexec(&exp,src,1,matches,0); if(rv==0) { int len=matches[0].rm_eo-matches[0].rm_so; char *buff=(char*)malloc(sizeof(char)*(len-2)); char *orig_buff[256]; memcpy(buff,&src[matches[0].rm_so+2],len-3); buff[len-3]='\0'; strcpy(orig_buff,buff); buff=get_ip(buff); if (strcmp(src,buff)!=0) sprintf(new_opts,"%s,addr=%s",opts,buff); else { src=parse_mount_src(src); sprintf(new_opts,"%s",opts); } } else { src=parse_mount_src(src); sprintf(new_opts,"%s",opts); } int ret=mount(src,dir,type,MS_SILENT,new_opts); if(ret==0) { FILE *fd; struct mntent ent; int res; fd=setmntent("/etc/mtab","a"); if(fd!=NULL) { ent.mnt_type=type; ent.mnt_dir=dir; ent.mnt_fsname=src; ent.mnt_opts=owner; ent.mnt_freq=0; ent.mnt_passno=0; addmntent(fd,&ent); endmntent(fd); } } return ret; } int manual_mount_sources(const char* user, const char* password) { FILE *fp; long f_size; char *buffer; char msource_path[256]; enum json_tokener_error jerr; struct passwd *t_pwd; t_pwd=getpwnam(user); //printf("%s\n",t_pwd->pw_dir); sprintf(msource_path,"%s/.MOUNT_SOURCES",t_pwd->pw_dir); //printf("%s\n",msource_path); fp=fopen(msource_path,"rb"); if( !fp ) return -1; fseek( fp , SEEK_SET , SEEK_END); f_size = ftell( fp ); rewind( fp ); buffer = calloc( 1, f_size+1 ); if( !buffer ) return -1; /* copy the file into the buffer */ if( 1!=fread( buffer , f_size, 1 , fp) ) { fclose(fp); free(buffer); return -1; } fclose(fp); json_object *jobj=json_tokener_parse_verbose(buffer,&jerr); if(jerr!=json_tokener_success || jobj==NULL) { free(buffer); return -1; } if (json_object_is_type(jobj, json_type_object)!=1) { free(buffer); return -1; } json_object *tmp=json_object_object_get(jobj,"MOUNT_SOURCES"); if(tmp==NULL) { free(buffer); return -1; } json_object *tmp2; tmp2=json_object_object_get(tmp,"value"); if(tmp2==NULL) { free(buffer); return -1; } if (json_object_is_type(tmp2, json_type_object)!=1) { free(buffer); return -1; } json_object_object_foreach(tmp2, key, val) { const char *mount_src=key; json_object *tmp3=json_object_object_get(tmp2,mount_src); if(json_object_is_type(tmp3, json_type_object)!=1 || tmp3==NULL) continue; const char *mount_dst=json_object_get_string(json_object_object_get(val,"dst")); const char *mount_fstype=json_object_get_string(json_object_object_get(val,"fstype")); bool force_perm=json_object_get_boolean(json_object_object_get(val,"force_perms")); if(mount_dst==NULL || mount_fstype==NULL) continue; if(force_perm==NULL) force_perm=false; // printf("[ %s ] = dst: %s , fstype: %s\n",mount_src,mount_dst,mount_fstype); char buff[256]; char buff2[256]; if(!force_perm) { //printf("not forcing\n"); sprintf(buff,"username=%s,password=%s,noperm,_netdev",(char*)user,password); sprintf(buff2,"username=%s",(char*)user); } else { //printf("forcing\n"); struct passwd *pwd; pwd=getpwnam(user); sprintf(buff,"username=%s,password=%s,uid=%i,gid=%i,_netdev",(char*)user,password,pwd->pw_uid,pwd->pw_gid); sprintf(buff2,"username=%s,uid=%i,gid=%i",(char*)user,pwd->pw_uid,pwd->pw_gid); } //sprintf(buff2,"username=%s",(char*)user); char *dst=str_replace(mount_dst,"$USER",user); _mkdir(dst,user); if(!is_dir_mounted(dst)) cmount((char*)mount_src,dst,(char*)mount_fstype,buff,buff2); } free(buffer); free(tmp); return 0; } 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; const char *ip; 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) { //char *display; //display=getenv("DISPLAY"); //if(display!=NULL) manual_mount_sources((const char*)user,password); /* // DISABLED FOR NOW ip=get_ip(); if(ip!=NULL) { //printf("register_credentials: %d\n",register_credentials(ip,user,password)); register_credentials(ip,user,password); //system("echo 4 >> /tmp/log_"); } */ } 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) { /* manual_mount_sources((const char*)user,password); char cmd[256]; sprintf(cmd,"su -c '/etc/lightdm/home-linker %s' -s /bin/sh root",user); printf(cmd); system(cmd); */ 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); }