1: /*
2: * thttpdpasswd.c: simple program for manipulating password file for NCSA httpd
3: *
4: * Rob McCool
5: */
6:
7: /* Modified 29aug97 by Jef Poskanzer to accept new password on stdin,
8: ** if stdin is a pipe or file. This is necessary for use from CGI.
9: */
10:
11: #include <sys/types.h>
12: #include <stdio.h>
13: #include <string.h>
14: #include <signal.h>
15: #include <stdlib.h>
16: #include <time.h>
17: #include <unistd.h>
18:
19: extern char *crypt(const char *key, const char *setting);
20:
21: #define LF 10
22: #define CR 13
23:
24: #define MAX_STRING_LEN 256
25:
26: int tfd;
27: char temp_template[] = "/tmp/htp.XXXXXX";
28:
29: void interrupted(int);
30:
31: static char * strd(char *s) {
32: char *d;
33:
34: d=(char *)malloc(strlen(s) + 1);
35: strcpy(d,s);
36: return(d);
37: }
38:
39: static void getword(char *word, char *line, char stop) {
40: int x = 0,y;
41:
42: for(x=0;((line[x]) && (line[x] != stop));x++)
43: word[x] = line[x];
44:
45: word[x] = '\0';
46: if(line[x]) ++x;
47: y=0;
48:
49: while((line[y++] = line[x++]));
50: }
51:
52: static int getline(char *s, int n, FILE *f) {
53: register int i=0;
54:
55: while(1) {
56: s[i] = (char)fgetc(f);
57:
58: if(s[i] == CR)
59: s[i] = fgetc(f);
60:
61: if((s[i] == 0x4) || (s[i] == LF) || (i == (n-1))) {
62: s[i] = '\0';
63: return (feof(f) ? 1 : 0);
64: }
65: ++i;
66: }
67: }
68:
69: static void putline(FILE *f,char *l) {
70: int x;
71:
72: for(x=0;l[x];x++) fputc(l[x],f);
73: fputc('\n',f);
74: }
75:
76:
77: /* From local_passwd.c (C) Regents of Univ. of California blah blah */
78: static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
79: "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
80:
81: static void to64(register char *s, register long v, register int n) {
82: while (--n >= 0) {
83: *s++ = itoa64[v&0x3f];
84: v >>= 6;
85: }
86: }
87:
88: #ifdef MPE
89: /* MPE lacks getpass() and a way to suppress stdin echo. So for now, just
90: issue the prompt and read the results with echo. (Ugh). */
91:
92: char *getpass(const char *prompt) {
93:
94: static char password[81];
95:
96: fputs(prompt,stderr);
97: gets((char *)&password);
98:
99: if (strlen((char *)&password) > 8) {
100: password[8]='\0';
101: }
102:
103: return (char *)&password;
104: }
105: #endif
106:
107: static void
108: add_password( char* user, FILE* f )
109: {
110: char pass[100];
111: char* pw;
112: char* cpw;
113: char salt[3];
114:
115: if ( ! isatty( fileno( stdin ) ) )
116: {
117: (void) fgets( pass, sizeof(pass), stdin );
118: if ( pass[strlen(pass) - 1] == '\n' )
119: pass[strlen(pass) - 1] = '\0';
120: pw = pass;
121: }
122: else
123: {
124: pw = strd( (char*) getpass( "New password:" ) );
125: if ( strcmp( pw, (char*) getpass( "Re-type new password:" ) ) != 0 )
126: {
127: (void) fprintf( stderr, "They don't match, sorry.\n" );
128: if ( tfd != -1 )
129: unlink( temp_template );
130: exit( 1 );
131: }
132: }
133: (void) srandom( (int) time( (time_t*) 0 ) );
134: to64( &salt[0], random(), 2 );
135: cpw = crypt( pw, salt );
136: (void) fprintf( f, "%s:%s\n", user, cpw );
137: }
138:
139: static void usage(void) {
140: fprintf(stderr,"Usage: thttpdpasswd [-c] passwordfile username\n");
141: fprintf(stderr,"The -c flag creates a new file.\n");
142: exit(1);
143: }
144:
145: void interrupted(int signo) {
146: fprintf(stderr,"Interrupted.\n");
147: if(tfd != -1) unlink(temp_template);
148: exit(1);
149: }
150:
151: int main(int argc, char *argv[]) {
152: FILE *tfp,*f;
153: char user[MAX_STRING_LEN];
154: char line[MAX_STRING_LEN];
155: char l[MAX_STRING_LEN];
156: char w[MAX_STRING_LEN];
157: char command[MAX_STRING_LEN];
158: int found;
159:
160: tfd = -1;
161: signal(SIGINT,(void (*)(int))interrupted);
162: if(argc == 4) {
163: if(strcmp(argv[1],"-c"))
164: usage();
165: if(!(tfp = fopen(argv[2],"w"))) {
166: fprintf(stderr,"Could not open passwd file %s for writing.\n",
167: argv[2]);
168: perror("fopen");
169: exit(1);
170: }
171: printf("Adding password for %s.\n",argv[3]);
172: add_password(argv[3],tfp);
173: fclose(tfp);
174: exit(0);
175: } else if(argc != 3) usage();
176:
177: tfd = mkstemp(temp_template);
178: if(!(tfp = fdopen(tfd,"w"))) {
179: fprintf(stderr,"Could not open temp file.\n");
180: exit(1);
181: }
182:
183: if(!(f = fopen(argv[1],"r"))) {
184: fprintf(stderr,
185: "Could not open passwd file %s for reading.\n",argv[1]);
186: fprintf(stderr,"Use -c option to create new one.\n");
187: exit(1);
188: }
189: strcpy(user,argv[2]);
190:
191: found = 0;
192: while(!(getline(line,MAX_STRING_LEN,f))) {
193: if(found || (line[0] == '#') || (!line[0])) {
194: putline(tfp,line);
195: continue;
196: }
197: strcpy(l,line);
198: getword(w,l,':');
199: if(strcmp(user,w)) {
200: putline(tfp,line);
201: continue;
202: }
203: else {
204: printf("Changing password for user %s\n",user);
205: add_password(user,tfp);
206: found = 1;
207: }
208: }
209: if(!found) {
210: printf("Adding user %s\n",user);
211: add_password(user,tfp);
212: }
213: fclose(f);
214: fclose(tfp);
215: sprintf(command,"cp %s %s",temp_template,argv[1]);
216: system(command);
217: unlink(temp_template);
218: exit(0);
219: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>