1 /*
2  * AUTHOR: Pedro Lineu Orso
3  *                                                            1998, 2009
4  * CHPASSWD - Apache, Squid change passwd          http://sarg-squid.org
5  *
6  * CHPASSWD donations:
7  *      please look at http://sarg.sourceforge.net/donations.php
8  * ---------------------------------------------------------------------
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
23  *
24  */
25 
26 #include "conf.h"
27 
28 #define MAXLEN 1024
29 #define hhex(x) (((x) >= '0' && (x) <= '9') || ((x) >= 'a' && (x) <= 'f') || \
30                   ((x) >= 'A' && (x) <= 'F'))
31 char           *tn;
32 char template[255]="/var/tmp/chpasswd.XXXXXX";
33 int  fd;
34 FILE           *fpw,
35                *tmp;
36 
37 void
getword(char * word,char * line,char stop)38 getword(char *word, char *line, char stop)
39 {
40     int             x = 0,
41                     y;
42 
43     for (x = 0; ((line[x]) && (line[x] != stop)); x++)
44 	word[x] = line[x];
45 
46     word[x] = '\0';
47     if (line[x])
48 	++x;
49     y = 0;
50 
51     while ((line[y++] = line[x++]));
52 }
53 
54 
55 void
Hmsg(char * msg)56 Hmsg(char *msg)
57 {
58     printf("Content-type: text/html\n");
59     puts("\n");
60     printf("<html>\n");
61     printf("<head>\n");
62     printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
63     printf("</head>\n");
64     printf("<font color=red size=+2>%s\n", msg);
65     printf("</html>\n");
66     return;
67 }
68 
69 
strip_latin(char * line)70 static void strip_latin(char *line)
71 {
72    char buf[255];
73    char warea[255];
74 
75    while(strstr(line,"&") != 0){
76       getword(warea,line,'&');
77       strncat(warea,line,1);
78       getword(buf,line,';');
79       strcat(warea,line);
80       strcpy(line,warea);
81    }
82 
83    return;
84 
85 }
86 
87 
sendmail(char * user,char * subj,char * msg)88 void sendmail(char *user, char *subj, char *msg)
89 {
90 
91    FILE *mail;
92    char cmd[MAXLEN];
93 
94    sprintf(cmd,"mailx -s '%s' %s",subj,user);
95 
96    if (access("/bin/mailx", R_OK) == 0)
97       sprintf(cmd,"/bin/mailx -s '%s' %s",subj,user);
98    if (access("/usr/bin/mailx", R_OK) == 0)
99       sprintf(cmd,"/bin/mailx -s '%s' %s",subj,user);
100 
101    if((mail =popen(cmd, "w")) != NULL ) {
102       fputs(msg,mail);
103       pclose(mail);
104    }
105 
106    return;
107 }
108 
109 
log(pwdlogfile,user,newpwd,showpwd,msg,pwdfile,smtpuser,smtpsubject)110 void log(pwdlogfile, user, newpwd, showpwd, msg, pwdfile, smtpuser, smtpsubject)
111 	unsigned char *pwdlogfile;
112 	unsigned char *user;
113 	unsigned char *newpwd;
114 	unsigned char *showpwd;
115 	unsigned char *msg;
116 	unsigned char *pwdfile;
117 	unsigned char *smtpuser;
118 	unsigned char *smtpsubject;
119 {
120 	FILE *fp_ou;
121 	char Msg[MAXLEN];
122 	time_t tm;
123 	struct tm *t;
124 	char time_string[128];
125 	char pwd[MAXLEN];
126 
127 	tm = time(NULL);
128 	t = localtime(&tm);
129 	strftime(time_string, 127, "%Y/%m/%d %H:%M:%S", t);
130 
131 	if ((fp_ou = fopen(pwdlogfile, "a")) == NULL) {
132             sprintf(Msg, "%s %s",msg16, pwdlogfile);
133 	    Hmsg(Msg);
134 	    exit(1);
135         }
136 
137         Msg[0]='\0';
138         strcpy(pwd,"-");
139 
140         if(strcmp(showpwd,"yes") == 0){
141            if(strlen(newpwd) > 0)
142 	      strcpy(pwd,newpwd);
143 	}
144 
145         if(strlen(user) == 0)
146            strcpy(user,"-");
147 
148         sprintf(Msg, "%s %s %s %s %s pwdfile=%s\n",getenv("REMOTE_ADDR"),time_string,user,pwd,msg,pwdfile);
149         Msg[strlen(Msg)-1]='\n';
150 	strip_latin(Msg);
151 	fputs(Msg,fp_ou);
152 	fclose(fp_ou);
153 
154         if(strlen(smtpuser) > 0)
155            sendmail(smtpuser,smtpsubject,Msg);
156 
157 	return;
158 
159 }
160 
161 
162 void
Herror(char * msg)163 Herror(char *msg)
164 {
165     printf("Content-type: text/html\n");
166     puts("\n");
167     printf("<html>\n");
168     printf("<head>\n");
169     printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
170     printf("</head>\n");
171     printf("<font color=red size=+2>%s\n", msg);
172     printf("</html>\n");
173 
174     if (fpw)
175 	fclose(fpw);
176     if (tmp) {
177 	fclose(tmp);
178 	unlink(template);
179     }
180     return;
181 }
182 
183 
184 void
putline(FILE * f,char * l)185 putline(FILE * f, char *l)
186 {
187     int             x;
188 
189     for (x = 0; l[x]; x++)
190 	fputc(l[x], f);
191 // fputc('\n',f);
192 }
193 
194 
195 static unsigned char itoa64[] =	/*
196 				 * 0 ... 63 => ascii - 64
197 				 */
198 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
199 
to64(s,v,n)200 to64(s, v, n)
201     register char  *s;
202     register long   v;
203     register int    n;
204 {
205     while (--n >= 0) {
206 	*s++ = itoa64[v & 0x3f];
207 	v >>= 6;
208     }
209 }
210 
211 
212 void
Changed(char * user,char * PwdLogFile,char * newpwd,char * showpwd,char * PwdFile,char * SmtpUser,char * SmtpSubject)213 Changed(char *user, char *PwdLogFile, char *newpwd, char *showpwd, char *PwdFile, char *SmtpUser, char *SmtpSubject)
214 {
215     char Msg[MAXLEN];
216 
217     printf("Content-type: text/html\n");
218     puts("\n");
219     printf("<html>\n");
220     printf("<head>\n");
221     printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
222     printf("</head>\n");
223     printf("<font color=blue size=+2>\n");
224     sprintf(Msg, "%s %s %s",msg11, user, msg12);
225     printf(Msg);
226     printf("</font>\n");
227     printf("</html>\n");
228 
229     if(strlen(PwdLogFile) > 0)
230        log(PwdLogFile,user,newpwd,showpwd,Msg,PwdFile,SmtpUser,SmtpSubject);
231     return;
232 }
233 
234 
235 void
NotFound(char * user,char * PwdLogFile,char * newpwd,char * showpwd,char * PwdFile,char * SmtpUser,char * SmtpSubject)236 NotFound(char *user, char *PwdLogFile, char *newpwd, char *showpwd, char *PwdFile, char *SmtpUser, char *SmtpSubject)
237 {
238     char Msg[MAXLEN];
239 
240     printf("Content-type: text/html\n");
241     puts("\n");
242     printf("<html>\n");
243     printf("<head>\n");
244     printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
245     printf("</head>\n");
246     printf("<font color=red size=+2>\n");
247     sprintf(Msg, "%s %s %s",msg13, user, msg14);
248     printf(Msg);
249     printf("</font>\n");
250     printf("</html>\n");
251 
252     if(strlen(PwdLogFile) > 0)
253        log(PwdLogFile,user,newpwd,showpwd,Msg,PwdFile,SmtpUser,SmtpSubject);
254     return;
255 }
256 
257 
258 static void
fixpwd(str)259 fixpwd(str)
260         unsigned char   *str;
261 {
262         unsigned char   *dest = str;
263 
264         while (str[0])
265         {
266                 if (str[0] == '+')
267                         dest[0] = ' ';
268                 else if (str[0] == '%' && hhex(str[1]) && hhex(str[2]))
269                 {
270                         dest[0] = (unsigned char) htoi(str + 1);
271                         str += 2;
272                 }
273                 else
274                         dest[0] = str[0];
275 
276                 str++;
277                 dest++;
278         }
279 
280         dest[0] = '\0';
281 	return;
282 
283 }
284 
285 
286 //static int
htoi(s)287 htoi(s)
288         unsigned char   *s; {
289         int     value;
290         char    c;
291 
292         c = s[0];
293         if (isupper(c))
294                 c = tolower(c);
295         value = (c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10) * 16;
296 
297         c = s[1];
298         if (isupper(c))
299                 c = tolower(c);
300         value += c >= '0' && c <= '9' ? c - '0' : c - 'a' + 10;
301 
302         return (value);
303 }
304 
305 
306 void
rulefail(char * minchar,char * minnum,char * minspec)307 rulefail(char *minchar, char *minnum, char *minspec)
308 {
309     char Msg[MAXLEN];
310 
311     printf("Content-type: text/html\n");
312     puts("\n");
313     printf("<html>\n");
314     printf("<head>\n");
315     printf("  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-2\">\n");
316     printf("</head>\n");
317     printf("<font color=red size=+2>");
318     sprintf(Msg,"%s</font><br><br>",msg17);
319     printf(Msg);
320     sprintf(Msg,"%s<br><br>\n",msg18);
321     printf(Msg);
322 
323     if(strcmp(minchar,"0") != 0)
324        printf("<table><tr><td align=right>%s</td><td align=left><b>%s</b></td></tr>\n",msg19,minchar);
325       else
326        printf("<table><tr><td align=right>%s</td><td align=left><b></b></td></tr>\n",msg19);
327 
328     if(strcmp(minnum,"0") != 0)
329        printf("<tr><td align=right>%s</td><td align=left><b>%s</b></td></tr>\n",msg20,minnum);
330      else
331        printf("<tr><td align=right>%s</td><td align=left><b></b></td></tr>\n",msg20);
332 
333     if(strcmp(minspec,"0") != 0)
334        printf("<tr><td align=right>%s</td><td align=left><b>%s</b></td></tr>\n",msg21,minspec);
335      else
336        printf("<tr><td align=right>%s</td><td align=left><b></b></td></tr>\n",msg21);
337 
338     printf("</table>\n");
339 
340     exit(1);
341 }
342 
343 
getconf(ConfigFile,IpAuth,PwdFile,PwdMinLen,PwdMaxLen,PwdMinChar,PwdMinNum,PwdMinSpec,PwdLogFile,ShowPwd,BgColor,TxColor,TiColor,RuColor,Logo,Width,Height,Header,BgImage,SmtpUser,SmtpSubject,ShowInfo,DenyFile)344 void getconf(ConfigFile, IpAuth, PwdFile, PwdMinLen, PwdMaxLen, PwdMinChar, PwdMinNum, PwdMinSpec, PwdLogFile, ShowPwd, BgColor, TxColor, TiColor, RuColor, Logo, Width, Height, Header, BgImage, SmtpUser, SmtpSubject, ShowInfo, DenyFile)
345 	unsigned char *ConfigFile;
346 	unsigned char *PwdFile;
347 	unsigned char *IpAuth;
348 	unsigned char *PwdLogFile;
349         unsigned char *ShowPwd;
350 	unsigned char *PwdMinLen;
351 	unsigned char *PwdMaxLen;
352 	unsigned char *PwdMinChar;
353 	unsigned char *PwdMinNum;
354 	unsigned char *PwdMinSpec;
355 	unsigned char *BgColor;
356 	unsigned char *TxColor;
357 	unsigned char *TiColor;
358 	unsigned char *RuColor;
359 	unsigned char *Logo;
360 	unsigned char *Width;
361 	unsigned char *Height;
362 	unsigned char *Header;
363 	unsigned char *BgImage;
364 	unsigned char *SmtpUser;
365 	unsigned char *SmtpSubject;
366 	unsigned char *ShowInfo;
367         unsigned char *DenyFile;
368 {
369 
370         FILE *fp_in;
371         char buf[255];
372         char wbuf[255];
373 	char Msg[255];
374 	char *str;
375 
376 //        bzero(NcsaPlus,5);
377 //        bzero(ShowInfo,5);
378 
379         if ((fp_in = fopen(ConfigFile, "r")) == NULL) {
380             sprintf(Msg, "%s %s", msg15, ConfigFile);
381 	    Hmsg(Msg);
382 	    exit(1);
383 	}
384 
385 	while (fgets(buf, MAXLEN, fp_in) != NULL) {
386 	   if((str=(char *) strstr(buf,"#")) != (char *) NULL)
387 	      continue;
388 
389  	   if(strstr(buf,"password_file") != 0) {
390 	      getword(wbuf,buf,' ');
391 	      getword(PwdFile,buf,' ');
392 	      PwdFile[strlen(PwdFile)-1]='\0';
393 	   }
394 
395 
396 
397  	   if(strstr(buf,"ip_auth") != 0) {
398 	      getword(wbuf,buf,' ');
399 	      getword(IpAuth,buf,' ');
400 	      IpAuth[strlen(IpAuth)-1]='\0';
401 	   }
402 
403  	   if(strstr(buf,"minimum_length") != 0) {
404 	      getword(wbuf,buf,' ');
405 	      getword(PwdMinLen,buf,' ');
406 	      PwdMinLen[strlen(PwdMinLen)-1]='\0';
407 	   }
408 
409  	   if(strstr(buf,"maximum_length") != 0) {
410 	      getword(wbuf,buf,' ');
411 	      getword(PwdMaxLen,buf,' ');
412 	      PwdMaxLen[strlen(PwdMaxLen)-1]='\0';
413 	   }
414 
415  	   if(strstr(buf,"minimum_char") != 0) {
416 	      getword(wbuf,buf,' ');
417 	      getword(PwdMinChar,buf,' ');
418 	      PwdMinChar[strlen(PwdMinChar)-1]='\0';
419 	   }
420 
421  	   if(strstr(buf,"minimum_num") != 0) {
422 	      getword(wbuf,buf,' ');
423 	      getword(PwdMinNum,buf,' ');
424 	      PwdMinNum[strlen(PwdMinNum)-1]='\0';
425 	   }
426 
427  	   if(strstr(buf,"minimum_spec") != 0) {
428 	      getword(wbuf,buf,' ');
429 	      getword(PwdMinSpec,buf,' ');
430 	      PwdMinSpec[strlen(PwdMinSpec)-1]='\0';
431 	   }
432 
433  	   if(strstr(buf,"enable_log") != 0) {
434 	      getword(wbuf,buf,' ');
435 	      getword(PwdLogFile,buf,'\0');
436 	      PwdLogFile[strlen(PwdLogFile)-1]='\0';
437 	   }
438 
439  	   if(strstr(buf,"show_pwd") != 0) {
440 	      getword(wbuf,buf,' ');
441 	      getword(ShowPwd,buf,'\0');
442 	      ShowPwd[strlen(ShowPwd)-1]='\0';
443 	   }
444 
445  	   if(strstr(buf,"background_color") != 0) {
446 	      getword(wbuf,buf,' ');
447               getword(BgColor,buf,'\0');
448 	      BgColor[strlen(BgColor)-1]='\0';
449 	   }
450 
451  	   if(strstr(buf,"text_color") != 0) {
452 	      getword(wbuf,buf,' ');
453 	      getword(TxColor,buf,'\0');
454 	      TxColor[strlen(TxColor)-1]='\0';
455 	   }
456 
457  	   if(strstr(buf,"title_color") != 0) {
458 	      getword(wbuf,buf,' ');
459 	      getword(TiColor,buf,'\0');
460 	      TiColor[strlen(TiColor)-1]='\0';
461 	   }
462 
463  	   if(strstr(buf,"rules_color") != 0) {
464 	      getword(wbuf,buf,' ');
465 	      getword(RuColor,buf,'\0');
466 	      RuColor[strlen(RuColor)-1]='\0';
467 	   }
468 
469  	   if(strstr(buf,"logo_image") != 0) {
470 	      getword(wbuf,buf,' ');
471 	      getword(Logo,buf,'\0');
472 	      Logo[strlen(Logo)-1]='\0';
473 	   }
474 
475  	   if(strstr(buf,"background_image") != 0) {
476 	      getword(wbuf,buf,' ');
477 	      getword(BgImage,buf,'\0');
478 	      BgImage[strlen(BgImage)-1]='\0';
479 	   }
480 
481  	   if(strstr(buf,"alert_mail_user") != 0) {
482 	      getword(wbuf,buf,' ');
483 	      getword(SmtpUser,buf,'\0');
484 	      SmtpUser[strlen(SmtpUser)-1]='\0';
485 	   }
486 
487  	   if(strstr(buf,"ncsa_plus") != 0) {
488 	      getword(wbuf,buf,' ');
489 	      getword(NcsaPlus,buf,'\0');
490 	      NcsaPlus[strlen(NcsaPlus)-1]='\0';
491 	   }
492 
493  	   if(strstr(buf,"show_info") != 0) {
494 	      getword(wbuf,buf,' ');
495 	      getword(ShowInfo,buf,'\0');
496 	      ShowInfo[strlen(ShowInfo)-1]='\0';
497 	   }
498 
499  	   if(strstr(buf,"alert_mail_subject") != 0) {
500 	      getword(wbuf,buf,'"');
501 	      getword(SmtpSubject,buf,'"');
502 	   }
503 
504  	   if(strstr(buf,"image_size") != 0) {
505 	      getword(wbuf,buf,' ');
506 	      getword(Width,buf,' ');
507 	      getword(Height,buf,'\0');
508 	      Height[strlen(Height)-1]='\0';
509 	   }
510 
511  	   if(strstr(buf,"header") != 0) {
512 	      getword(wbuf,buf,'"');
513 	      getword(Header,buf,'"');
514 	   }
515 
516 	   if(strstr(buf,"denyfile") != 0) {
517 	      getword(wbuf,buf,' ');
518 	      getword(DenyFile,buf,' ');
519 	      DenyFile[strlen(DenyFile)-1]='\0';
520 	   }
521 
522 	}
523 
524         fclose(fp_in);
525 
526 	return;
527 }
528 
529 
vrfyrule(unsigned char * str,unsigned char * minchar,unsigned char * minnum,unsigned char * minspec)530 static void vrfyrule(unsigned char *str, unsigned char *minchar, unsigned char *minnum, unsigned char *minspec)
531 {
532     int tnum=0, talfa=0, tspec=0;
533     char *ostr = str;
534 
535     while(str[0]) {
536        if (str[0] == '%' && hhex(str[1]) && hhex(str[2])) {
537           tspec++;
538 	  str=str+3;
539 	  continue;
540        }
541        if (str[0] == '.') {
542           tspec++;
543 	  str++;
544 	  continue;
545        }
546        if ((str[0] >= 'a' && str[0] <= 'z') || (str[0] >='A' && str[0] <= 'Z'))
547           talfa++;
548        if (str[0] >= '0' && str[0] <= '9')
549           tnum++;
550 
551        str++;
552     }
553 
554     if(talfa < atoi(minchar))
555        rulefail(minchar,minnum,minspec);
556 
557     if(tnum < atoi(minnum))
558        rulefail(minchar,minnum,minspec);
559 
560     if(tspec < atoi(minspec))
561        rulefail(minchar,minnum,minspec);
562 
563     return;
564 }
565 
566 
vrfyauth(char * authfile,char * PwdLogFile,char * PwdFile,char * SmtpUser,char * SmtpSubject)567 static void vrfyauth(char *authfile, char *PwdLogFile, char *PwdFile, char *SmtpUser, char *SmtpSubject)
568 {
569 
570    FILE *auth;
571    char IP[30];
572    char buf[MAXLEN];
573    int  authbit=0;
574    struct stat statb;
575 
576    if(stat(authfile,&statb)) eperror(authfile);
577    if(statb.st_uid != 0) {
578       Hmsg(msg23);
579       if(strlen(PwdLogFile) > 0)
580          log(PwdLogFile,"-","","no",msg23,PwdFile,SmtpUser,SmtpSubject);
581       exit(1);
582    }
583    if(statb.st_mode & 022) {
584       Hmsg(msg24);
585       if(strlen(PwdLogFile) > 0)
586          log(PwdLogFile,"-","","no",msg24,PwdFile,SmtpUser,SmtpSubject);
587       exit(1);
588    }
589 
590    if((auth=fopen(authfile,"r"))==NULL) {
591       Hmsg(msg25);
592       if(strlen(PwdLogFile) > 0)
593          log(PwdLogFile,"-","","no",msg25,PwdFile,SmtpUser,SmtpSubject);
594       exit(1);
595    }
596 
597    if(getenv("HTTP_X_FORWARDED_FOR"))
598       sprintf(IP,"%s",getenv("HTTP_X_FORWARDED_FOR"));
599     else sprintf(IP,"%s",getenv("REMOTE_ADDR"));
600 
601    while(fgets(buf,MAXLEN,auth)!=NULL) {
602       if(!authbit) {
603          if(strstr(buf,"#") != 0)
604             continue;
605           else  authbit=vauth(buf,IP);
606       }
607    }
608 
609    if(!authbit) {
610       Hmsg(msg26);
611       if(strlen(PwdLogFile) > 0)
612          log(PwdLogFile,"-","","no",msg26,PwdFile,SmtpUser,SmtpSubject);
613       exit(1);
614    }
615 
616    return;
617 
618 }
619 
620 
rtrim(char * stri)621 char *rtrim (char * stri){
622    char *strt;
623    for (strt=stri;*strt==' ';strt++);
624    if (strt!=stri){
625       memmove (stri, strt, strlen(stri)-(strt-stri));
626       stri[strlen(stri)-(strt-stri)]='\0';
627    }
628    return stri;
629 }
630 
ltrim(char * stri)631 char *ltrim (char *stri){
632    int last = strlen (stri);
633    while ( last && (stri[last-1]==' '))
634       stri[last-1]=stri[last--];
635    return stri;
636 }
637 
638 
vrfyuser(char * DenyFile,char * User,char * PwdLogFile,char * SmtpUser,char * SmtpSubject)639 int vrfyuser ( char *DenyFile, char *User, char *PwdLogFile, char *SmtpUser, char *SmtpSubject){
640    FILE *fdn;
641    int  goon;
642    char DUser[255];
643    char buf[MAXLEN];
644    char Msg [MAXLEN];
645 
646    fdn=NULL;
647 
648    if (strlen(DenyFile)==0)
649       return 1;
650 
651    if ((fdn=fopen(DenyFile,"r"))==NULL){
652       sprintf(Msg,"%s %s", msg28,DenyFile);
653       Herror (Msg);
654       exit (1);
655    }
656    goon=1;
657    while ((fgets(buf, MAXLEN, fdn)!=NULL) && (goon)) {
658       if (buf[strlen(buf)-1]=='\n')
659          buf[strlen(buf)-1] = '\0';
660       ltrim(rtrim(buf));
661       if (strcmp(buf,User)==0)
662          goon=0;
663    }
664    fclose(fdn);
665    return (goon);
666 }
667 
vauth(char * buf,char * ip)668 int vauth(char *buf, char *ip) {
669    char a1[4],a2[4],a3[4],a4[4];
670    char o1[4],o2[4],o3[4],o4[4];
671    char ip2[255];
672    int ok=1;
673 
674    strcpy(ip2,ip);
675 
676    buf[strlen(buf)-1]='\0';
677 
678    if(strcmp(buf,"0.0.0.0") == 0)
679       return(1);
680    if(strcmp(buf,ip2) == 0)
681       return(1);
682 
683    getword(a1,buf,'.');
684    getword(a2,buf,'.');
685    getword(a3,buf,'.');
686    getword(a4,buf,' ');
687 
688    getword(o1,ip2,'.');
689    getword(o2,ip2,'.');
690    getword(o3,ip2,'.');
691    getword(o4,ip2,' ');
692 
693    if(strcmp(a1,"0") != 0){
694       if(strcmp(a1,o1) != 0)
695          ok=0;
696    }
697    if(strcmp(a2,"0") != 0){
698       if(strcmp(a2,o2) != 0)
699          ok=0;
700    }
701    if(strcmp(a3,"0") != 0){
702       if(strcmp(a3,o3) != 0)
703          ok=0;
704    }
705    if(strcmp(a4,"0") != 0){
706       if(strcmp(a4,o4) != 0)
707          ok=0;
708    }
709 
710    return(ok);
711 }
712 
713 
eperror(s)714 eperror(s)
715 register char *s; {
716    perror("chpasswd.cgi");
717    exit(1);
718 
719 }
720 
721 
main(argc,argv)722 main(argc, argv)
723     int             argc;
724     char           *argv[];
725 {
726 
727     char            buf[MAXLEN];
728     char            User[255];
729     char            PUser[255];
730     char            WUser[255];
731     char            Old_pw[255];
732     char            WOld_pw[255];
733     char            New_pw1[255];
734     char            New_pw2[255];
735     char            Action[255];
736     char            Msg[MAXLEN];
737     char            command[255];
738     char	    PwdFile[MAXLEN]="/usr/local/squid/etc/passwd";
739     char	    IpAuth[MAXLEN]="";
740     char	    PwdMinLen[255]="4";
741     char	    PwdMaxLen[255]="10";
742     char	    ShowPwd[255]="no";
743     char	    PwdMinChar[255]="0";
744     char	    PwdMinNum[255]="0";
745     char	    PwdMinSpec[255]="0";
746     char	    BgColor[255]="white";
747     char	    TiColor[255]="green";
748     char	    TxColor[255]="blue";
749     char	    RuColor[255]="red";
750     char	    Logo[MAXLEN]="";
751     char	    Width[MAXLEN]="80";
752     char	    Height[MAXLEN]="80";
753     char	    Header[MAXLEN];
754     char	    BgImage[MAXLEN]="";
755     char	    SmtpUser[MAXLEN]="";
756     char	    SmtpSubject[MAXLEN]="CHPASSWD EVENT";
757     char            InputBuffer[1024];
758     char	    ConfigFile[255];
759     char	    PwdLogFile[255];
760     char            ShowInfo[5]="on";
761     char            authorized_ip[20];
762     char           *pContentLength;
763     char           *str;
764     char           *cpw,
765                     salt[3];
766     int             ContentLength;
767     int             i;
768     int             x,
769                     ok = 0;
770     char            DenyFile[MAXLEN]="";
771 
772     tn = NULL;
773     fpw = NULL;
774     tmp = NULL;
775 
776     buf[0]='\0';
777     User[0]='\0';
778     PUser[0]='\0';
779     WUser[0]='\0';
780     Old_pw[0]='\0';
781     WOld_pw[0]='\0';
782     New_pw1[0]='\0';
783     New_pw2[0]='\0';
784     Action[0]='\0';
785     Msg[0]='\0';
786     command[0]='\0';
787     PwdLogFile[0]='\0';
788     strcpy(Header,msg22);
789 
790     sprintf(ConfigFile,"%s/chpasswd.conf",PREFIX);
791     if (access(ConfigFile, R_OK) == 0) {
792        getconf(ConfigFile,IpAuth,PwdFile,PwdMinLen,PwdMaxLen,PwdMinChar,PwdMinNum,PwdMinSpec,PwdLogFile,ShowPwd,BgColor,TxColor,TiColor,RuColor,Logo,Width,Height,Header,BgImage,SmtpUser,SmtpSubject,ShowInfo,DenyFile);
793     }
794 
795     if (strlen(IpAuth) > 0 ) {
796        if (access(IpAuth, R_OK) != 0) {
797           Hmsg(msg27);
798           if(strlen(PwdLogFile) > 0)
799              log(PwdLogFile,"-","","no",msg27,PwdFile,SmtpUser,SmtpSubject);
800           exit(1);
801        }
802        vrfyauth(IpAuth,PwdLogFile,PwdFile,SmtpUser,SmtpSubject);
803     }
804 
805     if (strcmp(getenv("REQUEST_METHOD"), "GET") == 0) {
806 	UserForm(PwdMinLen,PwdMaxLen,PwdMinChar,PwdMinNum,PwdMinSpec,BgColor,TxColor,TiColor,RuColor,Logo,Width,Height,Header,BgImage,ShowInfo);
807 	return 0;
808     }
809 
810     pContentLength = getenv("CONTENT_LENGTH");
811 
812     if (pContentLength != NULL)
813 	ContentLength = atoi(pContentLength);
814     else
815 	ContentLength = 0;
816 
817 
818     if (ContentLength > sizeof(InputBuffer) - 1) {
819 	ContentLength = sizeof(InputBuffer) - 1;
820     }
821     i = 0;
822 
823     while (i < ContentLength) {
824 	x = fgetc(stdin);
825 	if (x == EOF)
826 	    break;
827 	InputBuffer[i++] = x;
828     }
829 
830     InputBuffer[i] = '\0';
831     ContentLength = i;
832     getword(User, InputBuffer, '=');
833     getword(User, InputBuffer, '&');
834     getword(Old_pw, InputBuffer, '=');
835     getword(Old_pw, InputBuffer, '&');
836     getword(New_pw1, InputBuffer, '=');
837     getword(New_pw1, InputBuffer, '&');
838     getword(New_pw2, InputBuffer, '=');
839     getword(New_pw2, InputBuffer, '&');
840     getword(Action, InputBuffer, '=');
841 
842     if(atoi(PwdMinChar) || atoi(PwdMinNum) || atoi(PwdMinSpec))
843        vrfyrule(New_pw1,PwdMinChar,PwdMinNum,PwdMinSpec);
844 
845     fixpwd(Old_pw);
846     fixpwd(New_pw1);
847     fixpwd(New_pw2);
848 
849     if (strcmp(Action, "change") == 0) {
850     	if (vrfyuser(DenyFile, User, PwdLogFile,SmtpUser,SmtpSubject)==0){
851          sprintf(Msg," %s %s",msg29, User);
852             if(strlen(PwdLogFile) > 0)
853                log(PwdLogFile,User,New_pw1,ShowPwd,Msg,PwdFile,SmtpUser,SmtpSubject);
854 	    Herror(Msg);
855 	    return 0;
856     	}
857 
858         if (strlen(New_pw1) < atoi(PwdMinLen)) {
859             sprintf(Msg, "%s %s %s",msg02, PwdMinLen, msg03);
860  	    if(strlen(PwdLogFile) > 0)
861   	       log(PwdLogFile,User,New_pw1,ShowPwd,Msg,PwdFile,SmtpUser,SmtpSubject);
862 	    Herror(Msg);
863 	    return 0;
864         }
865 
866 	if (strlen(New_pw1) > atoi(PwdMaxLen)) {
867 	    sprintf(Msg, "%s %s %s",msg04, PwdMaxLen, msg03);
868             if(strlen(PwdLogFile) > 0)
869                log(PwdLogFile,User,New_pw1,ShowPwd,Msg,PwdFile,SmtpUser,SmtpSubject);
870 	    Herror(Msg);
871 	    return 0;
872 	}
873 
874 	if (strcmp(Old_pw, New_pw1) == 0) {
875 	    sprintf(Msg, "%s",msg05);
876             if(strlen(PwdLogFile) > 0)
877                log(PwdLogFile,User,New_pw1,ShowPwd,Msg,PwdFile,SmtpUser,SmtpSubject);
878 	    Herror(Msg);
879 	    return 0;
880 	}
881 
882 	if (strcmp(New_pw1, New_pw2) != 0) {
883 	    sprintf(Msg, "%s",msg06);
884             if(strlen(PwdLogFile) > 0)
885                log(PwdLogFile,User,New_pw1,ShowPwd,Msg,PwdFile,SmtpUser,SmtpSubject);
886 	    Herror(Msg);
887 	    return 0;
888 	}
889 
890 	if ((fpw = fopen(PwdFile, "r")) == NULL) {
891 	    sprintf(Msg, "%s %s",msg07, PwdFile);
892 	    Herror(Msg);
893 	    return 0;
894 	}
895 
896         fd = mkstemp(template);
897         if((fd == -1 ) ||
898             ((tmp = fdopen (fd, "w+" )) == NULL)  ) {    /* failure, bail out */
899 	       sprintf(Msg, "%s",msg08);
900        	       Herror(Msg);
901                return 0;
902         }
903 	while (fgets(buf, MAXLEN, fpw) != NULL) {
904 	    if (!ok) {
905                 strcpy(PUser,User);
906                 strcat(PUser,":");
907 
908                 if ((str = (char *) strstr(buf, PUser)) != (char *) NULL ) {
909 		    getword(WUser, buf, ':');
910                     if(strncmp(NcsaPlus,"on",2) == 0) {
911 		       getword(WOld_pw, buf, ':');
912 		       getword(authorized_ip, buf, ':');
913 		       strcpy(authorized_ip,buf);
914                     } else getword(WOld_pw, buf, '\n');
915 
916 		    if (strcmp(WOld_pw, crypt(Old_pw, WOld_pw)) != 0) {
917 			sprintf(Msg, "%s %s",msg09, User);
918             		if(strlen(PwdLogFile) > 0)
919                		   log(PwdLogFile,User,New_pw1,ShowPwd,Msg,PwdFile,SmtpUser,SmtpSubject);
920 			Herror(Msg);
921 			return 0;
922 		    }
923 
924 		    (void) srand((int) time((time_t *) NULL));
925 		    to64(&salt[0], rand(), 2);
926 		    cpw = crypt(New_pw1, salt);
927 
928                     if(strncmp(NcsaPlus,"on",2) == 0) {
929                        tm = time(NULL);
930                        t = localtime(&tm);
931                        strftime(ttime, 127, "%d/%m/%Y-%H%M", t);
932 		       sprintf(buf, "%s:%s:%s:%s\n", User, cpw, ttime, authorized_ip);
933                     } else sprintf(buf, "%s:%s\n", User, cpw);
934 		    ok++;
935 		}
936 	    }
937 	    putline(tmp, buf);
938 	}
939 
940 	fclose(fpw);
941 	fclose(tmp);
942 
943         if ((tmp = fopen(template, "r")) == NULL) {
944             sprintf(Msg, "%s",msg08);
945             Herror(Msg);
946             return 0;
947         }
948 
949         if ((fpw = fopen(PwdFile, "w")) == NULL) {
950             sprintf(Msg, "%s",msg07);
951             Herror(Msg);
952             return 0;
953         }
954 
955 	while (fgets(buf, MAXLEN, tmp) != NULL)
956            fputs(buf,fpw);
957 
958 	fclose(fpw);
959 	fclose(tmp);
960 
961 	unlink(template);
962 
963 	if (ok)
964 	    Changed(User, PwdLogFile, New_pw1, ShowPwd, PwdFile, SmtpUser, SmtpSubject);
965 	else
966 	    NotFound(User, PwdLogFile, New_pw1, ShowPwd, PwdFile, SmtpUser, SmtpSubject);
967     } else {
968         if (strcmp(Action, "cancel") == 0) {
969    	   sprintf(Msg, "%s",msg10);
970            if(strlen(PwdLogFile) > 0)
971               log(PwdLogFile,User,New_pw1,ShowPwd,Msg,PwdFile,SmtpUser,SmtpSubject);
972 	   Herror(Msg);
973 	   return 0;
974 	}
975     }
976     return 0;
977 }
978