Research V7 development
[unix-history] / usr / src / cmd / passwd.c
CommitLineData
b4e2e355
KT
1/*
2 * enter a password in the password file
3 * this program should be suid with owner
4 * with an owner with write permission on /etc/passwd
5 */
6#include <stdio.h>
7#include <signal.h>
8#include <pwd.h>
9
10char passwd[] = "/etc/passwd";
11char temp[] = "/etc/ptmp";
12struct passwd *pwd;
13struct passwd *getpwent();
14int endpwent();
15char *strcpy();
16char *crypt();
17char *getpass();
18char *getlogin();
19char *pw;
20char pwbuf[10];
21char buf[512];
22
23main(argc, argv)
24char *argv[];
25{
26 char *p;
27 int i;
28 char saltc[2];
29 long salt;
30 int u,fi,fo;
31 int insist;
32 int ok, flags;
33 int c;
34 int pwlen;
35 FILE *tf;
36 char *uname;
37
38 insist = 0;
39 if(argc < 2) {
40 if ((uname = getlogin()) == NULL) {
41 printf ("Usage: passwd user\n");
42 goto bex;
43 } else {
44 printf("Changing password for %s\n", uname);
45 }
46 } else {
47 uname = argv[1];
48 }
49 while(((pwd=getpwent()) != NULL)&&(strcmp(pwd->pw_name,uname)!=0));
50 u = getuid();
51 if((pwd==NULL) || (u!=0 && u != pwd->pw_uid))
52 {
53 printf("Permission denied.\n");
54 goto bex;
55 }
56 endpwent();
57 if (pwd->pw_passwd[0] && u != 0) {
58 strcpy(pwbuf, getpass("Old password:"));
59 pw = crypt(pwbuf, pwd->pw_passwd);
60 if(strcmp(pw, pwd->pw_passwd) != 0) {
61 printf("Sorry.\n");
62 goto bex;
63 }
64 }
65tryagn:
66 strcpy(pwbuf, getpass("New password:"));
67 pwlen = strlen(pwbuf);
68 if (pwlen == 0) {
69 printf("Password unchanged.\n");
70 goto bex;
71 }
72 ok = 0;
73 flags = 0;
74 p = pwbuf;
75 while(c = *p++){
76 if(c>='a' && c<='z') flags |= 2;
77 else if(c>='A' && c<='Z') flags |= 4;
78 else if(c>='0' && c<='9') flags |= 1;
79 else flags |= 8;
80 }
81 if(flags >=7 && pwlen>= 4) ok = 1;
82 if(((flags==2)||(flags==4)) && pwlen>=6) ok = 1;
83 if(((flags==3)||(flags==5)||(flags==6))&&pwlen>=5) ok = 1;
84
85 if((ok==0) && (insist<2)){
86 if(flags==1)
87 printf("Please use at least one non-numeric character.\n");
88 else
89 printf("Please use a longer password.\n");
90 insist++;
91 goto tryagn;
92 }
93
94 if (strcmp(pwbuf,getpass("Retype new password:")) != 0) {
95 printf ("Mismatch - password unchanged.\n");
96 goto bex;
97 }
98
99 time(&salt);
100 salt += getpid();
101
102 saltc[0] = salt & 077;
103 saltc[1] = (salt>>6) & 077;
104 for(i=0;i<2;i++){
105 c = saltc[i] + '.';
106 if(c>'9') c += 7;
107 if(c>'Z') c += 6;
108 saltc[i] = c;
109 }
110 pw = crypt(pwbuf, saltc);
111 signal(SIGHUP, SIG_IGN);
112 signal(SIGINT, SIG_IGN);
113 signal(SIGQUIT, SIG_IGN);
114
115 if(access(temp, 0) >= 0) {
116 printf("Temporary file busy -- try again\n");
117 goto bex;
118 }
119 close(creat(temp,0600));
120 if((tf=fopen(temp,"w")) == NULL) {
121 printf("Cannot create temporary file\n");
122 goto bex;
123 }
124
125/*
126 * copy passwd to temp, replacing matching lines
127 * with new password.
128 */
129
130 while((pwd=getpwent()) != NULL) {
131 if(strcmp(pwd->pw_name,uname) == 0) {
132 u = getuid();
133 if(u != 0 && u != pwd->pw_uid) {
134 printf("Permission denied.\n");
135 goto out;
136 }
137 pwd->pw_passwd = pw;
138 }
139 fprintf(tf,"%s:%s:%d:%d:%s:%s:%s\n",
140 pwd->pw_name,
141 pwd->pw_passwd,
142 pwd->pw_uid,
143 pwd->pw_gid,
144 pwd->pw_gecos,
145 pwd->pw_dir,
146 pwd->pw_shell);
147 }
148 endpwent();
149 fclose(tf);
150
151/*
152 * copy temp back to passwd file
153 */
154
155 if((fi=open(temp,0)) < 0) {
156 printf("Temp file disappeared!\n");
157 goto out;
158 }
159 if((fo=creat(passwd, 0644)) < 0) {
160 printf("Cannot recreat passwd file.\n");
161 goto out;
162 }
163 while((u=read(fi,buf,sizeof(buf))) > 0) write(fo,buf,u);
164
165out:
166 unlink(temp);
167
168bex:
169 exit(1);
170}