]> andersk Git - moira.git/blob - clients/passwd/chfn.c
004e714f96290f1af272fc6b238c24a04cfe5851
[moira.git] / clients / passwd / chfn.c
1 /*
2  * Copyright 1988 by the Massachusetts Institute of Technology. For copying
3  * and distribution information, see the file "mit-copyright.h". 
4  *
5  * $Source$
6  * $Header$
7  * $Author$
8  *
9  */
10
11 #ifndef lint
12 static char *rcsid_chfn_c = "$Header$";
13 #endif not lint
14
15 /*
16  * Talk to the SMS database to change a person's GECOS information.
17  * 
18  * chfn with no modifiers changes the information of the user who is 
19  * running the program.
20  * 
21  * If a commandline argument is given, it is taken to be the username
22  * of the user whose information is to be changed.
23  *
24  */
25
26 #define FALSE 0
27 #define TRUE 1
28
29 #include <sys/types.h>
30 #include <stdio.h>
31 #include <strings.h>
32 #include <ctype.h>
33 #include <sys/file.h>
34 #include <krb.h>
35 #include <ctype.h>
36 #include <errno.h>
37
38 /* SMS includes */
39 #include <sms.h>
40 #include <sms_app.h>
41 #include "mit-copyright.h"
42
43 char *whoami;
44
45 extern char *krb_err_txt[];
46
47 struct finger_info {
48     char *fullname;
49     char *nickname;
50     char *home_address;
51     char *home_phone;
52     char *office_address;
53     char *office_phone;
54     char *mit_department;
55     char *mit_year;
56 };
57
58 main(argc, argv)
59     int argc;
60     char *argv[];
61 {
62     char pname[ANAME_SZ];
63     char *uname = pname;
64     int k_errno;
65     char *whoami;
66
67     if ((whoami = rindex(argv[0], '/')) == NULL)
68         whoami = argv[0];
69     else
70         whoami++;
71
72     if (argc > 2) {
73         usage();
74     }
75     
76     if (argc == 2)
77         uname = argv[1];
78     else
79     {
80         /* Do it right; get name from kerberos ticket file rather than 
81            from passord file. */
82         
83         if (k_errno = tf_init(TKT_FILE, R_TKT_FIL)) {
84             fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
85             exit(1);
86         }
87         
88         if (k_errno = tf_get_pname(pname)) {
89             fprintf(stderr, "%s: %s\n", whoami, krb_err_txt[k_errno]);
90             exit(1);
91         }
92
93         tf_close();
94     }
95     
96     exit(chfn(uname));
97 }
98
99 leave(status)
100   int status;
101   /* This should be called rather than exit once connection to sms server
102      has been established. */
103 {
104     sms_disconnect();
105     exit(status);
106 }
107
108 scream()
109 {
110     com_err(whoami, 0, "Unexpected return value from SMS -- programmer botch");
111     leave(1);
112 }
113
114 chfn(uname)
115   char *uname;
116 {
117     int status;                 /* general purpose exit status */
118     int q_argc;                 /* argc for sms_query */
119     char *q_argv[F_END];        /* argv for sms_query */
120     int i;
121
122     int get_user_info();
123     void get_new_info();
124
125     struct finger_info old_info;
126     struct finger_info new_info;
127
128     /* Try each query.  If we ever fail, print error message and exit. */
129
130     status = sms_connect(SMS_SERVER);
131     if (status) {
132         com_err(whoami, status, " while connecting to SMS");
133         exit(1);
134     }
135
136     status = sms_auth("chfn");  /* Don't use argv[0] - too easy to fake */
137     if (status) {
138         com_err(whoami, status, 
139                 " while authenticating -- run \"kinit\" and try again.");
140         leave(1);
141     }
142
143     /* First, do an access check. */
144
145     q_argv[F_NAME] = uname;
146     for (i = F_NAME + 1; i < F_MODTIME; i++)
147         q_argv[i] = "junk";
148     q_argc = F_MODTIME;         /* one more than the last updatable field */
149     
150     if (status = sms_access("update_finger_by_login", q_argc, q_argv)) {
151         com_err(whoami, status, "; finger\ninformation not changed.");
152         leave(2);
153     }
154
155     printf("Changing finger information for %s.\n", uname);
156
157     /* Get information */
158
159     q_argv[NAME] = uname;
160     q_argc = NAME + 1;
161     if (status = sms_query("get_finger_by_login", q_argc, q_argv, 
162                        get_user_info, (char *) &old_info))
163     {
164         com_err(whoami, status, " while getting user information.");
165         leave(2);
166     }
167
168     /* Get the new information from the user */
169
170     get_new_info(&old_info, &new_info);
171
172     /* Do the update */
173
174     printf("Changing finger information...\n");
175
176     q_argv[F_NAME] = uname;
177     q_argv[F_FULLNAME] = new_info.fullname;
178     q_argv[F_NICKNAME] = new_info.nickname;
179     q_argv[F_HOME_ADDR] = new_info.home_address;
180     q_argv[F_HOME_PHONE] = new_info.home_phone;
181     q_argv[F_OFFICE_ADDR] = new_info.office_address;
182     q_argv[F_OFFICE_PHONE] = new_info.office_phone;
183     q_argv[F_MIT_DEPT] = new_info.mit_department;
184     q_argv[F_MIT_AFFIL] = new_info.mit_year;
185     q_argc = F_MODTIME;         /* First non-update query argument */
186
187     if (status = sms_query("update_finger_by_login", q_argc, q_argv,
188                            scream, (char *)NULL))
189     {
190         com_err(whoami, status, " while updating finger information.");
191         leave(1);
192     }
193
194     printf("Finger information updated succesfully.\n");
195
196     return(0);
197 }
198
199 get_user_info(argc, argv, message)
200   int argc;
201   char *argv[];
202   char *message;
203 {
204     struct finger_info *old_info = (struct finger_info *) message;
205     
206     if (argc != F_END) {
207         fprintf(stderr, "Some internal error occurred; try again.\n");
208         leave(3);
209     }
210     
211     printf("Info last changed on %s by user %s with %s.\n",
212            argv[F_MODTIME], argv[F_MODBY], argv[F_MODWITH]);
213     
214     old_info->fullname = strsave(argv[F_FULLNAME]);
215     old_info->nickname = strsave(argv[F_NICKNAME]);
216     old_info->home_address = strsave(argv[F_HOME_ADDR]);
217     old_info->home_phone = strsave(argv[F_HOME_PHONE]);
218     old_info->office_address = strsave(argv[F_OFFICE_ADDR]);
219     old_info->office_phone = strsave(argv[F_OFFICE_PHONE]);
220     old_info->mit_department = strsave(argv[F_MIT_DEPT]);
221     old_info->mit_year = strsave(argv[F_MIT_AFFIL]);
222     
223     /* Only pay attention to the first match since login names are
224        unique in the database. */
225     return(SMS_ABORT);
226 }
227
228 char *ask(question, def_val, phone_num)
229   char *question;
230   char *def_val;
231   int phone_num;                /* True if this must contain only digits */
232 {
233     static char buf[BUFSIZ];
234     int ok = FALSE;
235     char *result;
236     int i;
237     int dashes = FALSE;
238     
239 #define BLANK "none"
240     
241     while (!ok)
242     {
243         ok = TRUE;
244         printf("%s [%s]: ", question, def_val);
245         if (fgets(buf, sizeof(buf), stdin) == NULL)
246           leave(0);
247         buf[strlen(buf) - 1] = NULL;
248         if (strlen(buf) == 0)
249             result = def_val;
250         else if (strcasecmp(buf, BLANK) == NULL)
251             result = "";
252         else 
253             result = buf;
254         
255         for (i = 0; i < strlen(buf); i++)
256         {
257             switch (buf[i])
258             {
259               case '"':
260                 printf("'\"' is not allowed.\n");
261                 ok = FALSE;
262                 break;
263               case ',':
264                 printf("',' is not allowed.\n");
265                 ok = FALSE;
266                 break;
267               case ':':
268                 printf("':' is not allowed.\n");
269                 ok = FALSE;
270                 break;
271               default:
272                 if (iscntrl(buf[i])) {
273                     printf("Control characters are not allowed.\n");
274                     ok = FALSE;
275                     break;
276                 }
277             }
278             if (!ok)
279                 break;
280         }
281         
282         if (phone_num && ok) {
283             for (i = 0; i < strlen(buf); i++) {
284                 if (!isdigit(buf[i]) && (buf[i] != '-')) {
285                     printf("Phone numbers can contain only digits.\n");
286                     ok = FALSE;
287                     break;
288                 }
289                 if (buf[i] == '-')
290                     dashes = TRUE;
291             }
292         }
293     }
294     
295     /* Remove dashes if necessary */
296     if (dashes && result == buf) {
297         char *tmp1, *tmp2;
298         tmp1 = tmp2 = (char *)buf;
299         do {
300             if (*(tmp1) != '-')
301                 *(tmp2++) = *(tmp1);
302         }
303         while (*(tmp1++));
304     }
305     
306     return(result);
307 }
308         
309 void get_new_info(old_info, new_info)
310   struct finger_info *old_info;
311   struct finger_info *new_info;
312 {
313     printf("Default values are printed inside of '[]'.\n");
314     printf("To accept the default, type <return>.\n");
315     printf("To have a blank entry, type the word '%s'.\n\n", BLANK);
316
317 #define GETINFO(m,v,n) \
318     new_info->v = strsave(ask(m, old_info->v, n))
319     
320     GETINFO("Full name", fullname, FALSE);
321     GETINFO("Nickname", nickname, FALSE);
322     GETINFO("Home address (Ex: Atkinson 304)", home_address, FALSE);
323     GETINFO("Home phone number (Ex: 3141592)", home_phone, TRUE);
324     GETINFO("Office address (Exs: E40-342 or 2-108)", 
325             office_address, FALSE);
326     GETINFO("Office phone (Ex: 3-1300)", office_phone, TRUE);
327     GETINFO("MIT department (Exs: 9, Biology, Information Services", 
328             mit_department, FALSE);
329     GETINFO("MIT year (Exs: 1989, '91, Faculty, Grad)", mit_year, FALSE);
330 }
331
332 usage()
333 {
334     fprintf(stderr, "Usage: %s [user]\n", whoami);
335     exit(1);
336 }
This page took 0.0551 seconds and 3 git commands to generate.