]> andersk Git - moira.git/blob - clients/passwd/chfn.c
332ada02b539c187ab2d010d5e0ac1c757a62c46
[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     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         (void) fgets(buf, sizeof(buf), stdin);
246         buf[strlen(buf) - 1] = NULL;
247         if (strlen(buf) == 0)
248             result = def_val;
249         else if (strcasecmp(buf, BLANK) == NULL)
250             result = "";
251         else 
252             result = buf;
253         
254         for (i = 0; i < strlen(buf); i++)
255         {
256             switch (buf[i])
257             {
258               case '"':
259                 printf("'\"' is not allowed.\n");
260                 ok = FALSE;
261                 break;
262               case ',':
263                 printf("',' is not allowed.\n");
264                 ok = FALSE;
265                 break;
266               case ':':
267                 printf("':' is not allowed.\n");
268                 ok = FALSE;
269                 break;
270               default:
271                 if (iscntrl(buf[i])) {
272                     printf("Control characters are not allowed.\n");
273                     ok = FALSE;
274                     break;
275                 }
276             }
277             if (!ok)
278                 break;
279         }
280         
281         if (phone_num && ok) {
282             for (i = 0; i < strlen(buf); i++) {
283                 if (!isdigit(buf[i]) && (buf[i] != '-')) {
284                     printf("Phone numbers can contain only digits.\n");
285                     ok = FALSE;
286                     break;
287                 }
288                 if (buf[i] == '-')
289                     dashes = TRUE;
290             }
291         }
292     }
293     
294     /* Remove dashes if necessary */
295     if (dashes) {
296         char *tmp1, *tmp2;
297         result = strsave(buf);
298         tmp1 = (char *)buf;
299         tmp2 = result;
300         do {
301             if (*(tmp1) != '-')
302                 *(tmp2++) = *(tmp1);
303         }
304         while (*(tmp1++));
305     }
306     
307     return(result);
308 }
309         
310 void get_new_info(old_info, new_info)
311   struct finger_info *old_info;
312   struct finger_info *new_info;
313 {
314     printf("Default values are printed inside of '[]'.\n");
315     printf("To accept the default, type <return>.\n");
316     printf("To have a blank entry, type the word '%s'.\n\n", BLANK);
317
318 #define GETINFO(m,v,n) \
319     new_info->v = strsave(ask(m, old_info->v, n))
320     
321     GETINFO("Full name", fullname, FALSE);
322     GETINFO("Nickname", nickname, FALSE);
323     GETINFO("Home address (Ex: Atkinson 304)", home_address, FALSE);
324     GETINFO("Home phone number (Ex: 3141592)", home_phone, TRUE);
325     GETINFO("Office address (Exs: E40-342 or 2-108)", 
326             office_address, FALSE);
327     GETINFO("Office phone (Ex: 3-1300)", office_phone, TRUE);
328     GETINFO("MIT department (Exs: 9, Biology, Information Services", 
329             mit_department, FALSE);
330     GETINFO("MIT year (Exs: 1989, '91, Faculty, Grad)", mit_year, FALSE);
331 }
332
333 usage()
334 {
335     fprintf(stderr, "Usage: %s [user]\n", whoami);
336     exit(1);
337 }
This page took 0.04893 seconds and 3 git commands to generate.