#include #include #include #include #include "userconf.h" #include "userconf.m" #include #include #include #include "internal.h" #include #include static const char *tbargs[]={"domain",NULL}; static MESSAGE_DEF editupass ("editupass",tbargs); void upass_setintro (M_DIALOG &dia, const char *server) { /* #Specification: html password dialog / introduction The admin may supply a file /etc/passwd.htmlintro. This file must contain html and will be inserted in the html dialog letting a user change his password. */ /* Added by jmdault@netrevolution.com on 02/13/2000: For virtual pop servers, you can supply a file /etc/vmail/htmlintro.DOMAIN. When a virtual pop user wants to change his password, he will get the html from the domain file. */ char htmlpath[PATH_MAX]; sprintf(htmlpath,"%s/htmlintro.%s",ETC_VMAIL,server); CONFIG_FILE f_intro (htmlpath,help_nil,CONFIGF_OPTIONAL); static CONFIG_FILE default_intro (ETC_PASSWD_HTMLINTRO, help_nil,CONFIGF_OPTIONAL); FILE_CFG *fin = f_intro.fopen ("r"); if (fin != NULL){ char buf[500]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ dia.html_top ("%s",buf); } fclose (fin); } else { FILE_CFG *default_fin = default_intro.fopen ("r"); if (default_fin != NULL){ char buf[500]; while (fgets(buf,sizeof(buf)-1,default_fin)!=NULL){ dia.html_top ("%s",buf); } fclose (default_fin); }else{ dia.html_intro (MSG_U(I_SERVER ,"

Server %s

\n
\n") ,server); } } } void upass_setintro (DIALOG &dia, const char *server) { M_DIALOG mdia (&dia); upass_setintro (mdia,server); } void upass_setend (M_DIALOG &dia, const char *server) { /* #Specification: html password dialog / end of page The admin may supply a file /etc/passwd.htmlend. This file must contain html and will be inserted in the html dialog letting a user change his password. */ /* Added by jmdault@netrevolution.com on 02/13/2000: For virtual pop servers, you can supply a file /etc/vmail/htmlend.DOMAIN. When a virtual pop user wants to change his password, he will get the html from the domain file. */ char htmlpath[PATH_MAX]; sprintf(htmlpath,"%s/htmlend.%s",ETC_VMAIL,server); CONFIG_FILE f_end (htmlpath,help_nil,CONFIGF_OPTIONAL); static CONFIG_FILE default_end (ETC_PASSWD_HTMLEND,help_nil,CONFIGF_OPTIONAL); FILE_CFG *fin = f_end.fopen ("r"); if (fin != NULL){ char buf[500]; while (fgets(buf,sizeof(buf)-1,fin)!=NULL){ dia.html_end ("%s",buf); } fclose (fin); } else { FILE_CFG *default_fin = default_end.fopen ("r"); if (default_fin != NULL){ char buf[500]; while (fgets(buf,sizeof(buf)-1,default_fin)!=NULL){ dia.html_end ("%s",buf); } fclose (default_fin); } else { dia.html_end ("%s", "

\n" "\n" "\n" "\n" "\n" "\n" "\n"); } } } void upass_setend (DIALOG &dia, const char *server) { M_DIALOG mdia (&dia); upass_setend (mdia,server); } /* Let a user change its own password This will generally be used by PPP or POP users who can't do it otherwise. This is only usable with the html mode. */ void userconf_editupass( USERS &users, const char *server) { int nof=0; while (1){ DIALOG dia; upass_setintro(dia,server); dia.html_intro (MSG_U(I_IDENTIFY ,"Enter your account id and your current password\n" "followed by the new password you want. You must\n" "enter it twice to make sure you have it right")); SSTRING account; dia.newf_str (MSG_U(F_ACCOUNT,"Account"),account); SSTRING pass; dia.newf_pass (MSG_U(F_CURPASSWORD,"Current password"),pass); SSTRING npass1; SSTRING npass2; dia.newf_pass (MSG_U(F_NEWPASSWORD,"New password"),npass1); dia.newf_pass (MSG_U(F_PASSCONFIRM,"New password again"),npass2); upass_setend (dia,server); if (dia.edit_form (MSG_U(T_IDENTIFY,"Change your password") ,"" ,help_nil ,nof)==MENU_ACCEPT){ USER *u = users.getitem(account.get()); if (u == NULL){ xconf_error (MSG_U(E_IVLDUPASS ,"Invalid user or password\n" "Try again!")); nof = 1; }else if (account.cmp("root")==0){ xconf_error (MSG_U(E_UPASSROOT ,"Can't change the password\n" "of the superuser this way. Sorry!")); }else{ SHADOW *shadow = users.getshadow(u); if (u->pass_maychange(shadow)){ if (!perm_validpass (users,account.get(),pass.get())){ xconf_error (MSG_R(E_IVLDUPASS)); nof = 1; }else if (npass1.cmp(npass2)!=0){ xconf_error (MSG_R(E_MISMATCH)); nof = 2; }else if (npass1.cmp(pass)==0){ xconf_error (MSG_U(E_PICKNEW ,"Pick a different new password please")); nof = 2; }else if (!pass_isweak (npass1.get())){ u->update_passwd(npass1.get(),shadow,false,users.getdomain()); perm_setbypass(true); users.write(NULL); perm_setbypass(false); xconf_notice (MSG_U(N_NEWPASSOK ,"Your new password has been accepted!")); } } } }else{ break; } } } static void upass_assist (M_DIALOG &dia, bool intro) { THISHOST th; char hostname[PATH_MAX]; if (html_getourname(hostname)==-1){ strcpy_cut (hostname,th.getname1(),sizeof(hostname)-1); } if (intro){ upass_setintro (dia,hostname); }else{ upass_setend (dia,hostname); } } /* Change the password of a user of the main domain */ static void upass_changemain (const char *hostname) { if (perm_fct_change != NULL){ while (1){ DIALOG dia; upass_setintro(dia,hostname); SSTRING account; dia.newf_str (MSG_R(F_ACCOUNT),account); upass_setend (dia,hostname); int nof = 0; if (dia.edit_form (MSG_U(T_YOURNAME,"Your account ID") ,MSG_U(I_YOURNAME,"Please enter your account name") ,help_nil ,nof)==MENU_ACCEPT){ if (account.cmp("root")!=0){ int ret = (*perm_fct_change)(account.get(),false,"",upass_assist); if (ret == -1){ xconf_error (MSG_R(E_PASSCHG)); }else{ xconf_notice (MSG_R(N_NEWPASSOK)); } }else{ xconf_error (MSG_R(E_PASSCHG)); } }else{ break; } } }else{ USERS users; userconf_editupass (users,hostname); } } /* Let a user change its own password This will generally be used by PPP or POP users who can't do it otherwise. This is only usable with the html mode. */ void userconf_editupass() { THISHOST th; char hostname[PATH_MAX]; if (html_getourname(hostname)==-1){ upass_changemain(th.getname1()); }else{ const char *argv[2]; argv[0] = hostname; argv[1] = NULL; // Let the mailconf module handle virtual email domains if (module_sendmessage(editupass,1,argv)==LNCF_NOT_APPLICABLE){ upass_changemain(th.getname1()); } } }