]> andersk Git - moira.git/blob - clients/passwd/chfn.c
4cf62ab54d9bd654db08ae23ec8f5f2316fc0f6c
[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     char *motd;                 /* for SMS server status */
121     int i;
122
123     int get_user_info();
124     void get_new_info();
125
126     struct finger_info old_info;
127     struct finger_info new_info;
128
129     /* Try each query.  If we ever fail, print error message and exit. */
130
131     status = sms_connect(SMS_SERVER);
132     if (status) {
133         com_err(whoami, status, " while connecting to SMS");
134         exit(1);
135     }
136
137     status = sms_motd(&motd);
138     if (status) {
139         com_err(whoami, status, " unable to check server status");
140         leave(1);
141     }
142     if (motd) {
143         fprintf(stderr, "The SMS server is currently unavailable:\n%s\n", motd);
144         leave(1);
145     }
146
147     status = sms_auth("chfn");  /* Don't use argv[0] - too easy to fake */
148     if (status) {
149         com_err(whoami, status, 
150                 " while authenticating -- run \"kinit\" and try again.");
151         leave(1);
152     }
153
154     /* First, do an access check. */
155
156     q_argv[F_NAME] = uname;
157     for (i = F_NAME + 1; i < F_MODTIME; i++)
158         q_argv[i] = "junk";
159     q_argc = F_MODTIME;         /* one more than the last updatable field */
160     
161     if (status = sms_access("update_finger_by_login", q_argc, q_argv)) {
162         com_err(whoami, status, "; finger\ninformation not changed.");
163         leave(2);
164     }
165
166     printf("Changing finger information for %s.\n", uname);
167
168     /* Get information */
169
170     q_argv[NAME] = uname;
171     q_argc = NAME + 1;
172     if (status = sms_query("get_finger_by_login", q_argc, q_argv, 
173                        get_user_info, (char *) &old_info))
174     {
175         com_err(whoami, status, " while getting user information.");
176         leave(2);
177     }
178
179     /* Get the new information from the user */
180
181     get_new_info(&old_info, &new_info);
182
183     /* Do the update */
184
185     printf("Changing finger information...\n");
186
187     q_argv[F_NAME] = uname;
188     q_argv[F_FULLNAME] = new_info.fullname;
189     q_argv[F_NICKNAME] = new_info.nickname;
190     q_argv[F_HOME_ADDR] = new_info.home_address;
191     q_argv[F_HOME_PHONE] = new_info.home_phone;
192     q_argv[F_OFFICE_ADDR] = new_info.office_address;
193     q_argv[F_OFFICE_PHONE] = new_info.office_phone;
194     q_argv[F_MIT_DEPT] = new_info.mit_department;
195     q_argv[F_MIT_AFFIL] = new_info.mit_year;
196     q_argc = F_MODTIME;         /* First non-update query argument */
197
198     if (status = sms_query("update_finger_by_login", q_argc, q_argv,
199                            scream, (char *)NULL))
200     {
201         com_err(whoami, status, " while updating finger information.");
202         leave(1);
203     }
204
205     printf("Finger information updated succesfully.\n");
206
207     return(0);
208 }
209
210 get_user_info(argc, argv, message)
211   int argc;
212   char *argv[];
213   char *message;
214 {
215     struct finger_info *old_info = (struct finger_info *) message;
216     
217     if (argc != F_END) {
218         fprintf(stderr, "Some internal error occurred; try again.\n");
219         leave(3);
220     }
221     
222     printf("Info last changed on %s by user %s with %s.\n",
223            argv[F_MODTIME], argv[F_MODBY], argv[F_MODWITH]);
224     
225     old_info->fullname = strsave(argv[F_FULLNAME]);
226     old_info->nickname = strsave(argv[F_NICKNAME]);
227     old_info->home_address = strsave(argv[F_HOME_ADDR]);
228     old_info->home_phone = strsave(argv[F_HOME_PHONE]);
229     old_info->office_address = strsave(argv[F_OFFICE_ADDR]);
230     old_info->office_phone = strsave(argv[F_OFFICE_PHONE]);
231     old_info->mit_department = strsave(argv[F_MIT_DEPT]);
232     old_info->mit_year = strsave(argv[F_MIT_AFFIL]);
233     
234     /* Only pay attention to the first match since login names are
235        unique in the database. */
236     return(SMS_ABORT);
237 }
238
239 char *ask(question, def_val, phone_num)
240   char *question;
241   char *def_val;
242   int phone_num;                /* True if this must contain only digits */
243 {
244     static char buf[BUFSIZ];
245     int ok = FALSE;
246     char *result;
247     int i;
248     int dashes = FALSE;
249     
250 #define BLANK "none"
251     
252     while (!ok)
253     {
254         ok = TRUE;
255         printf("%s [%s]: ", question, def_val);
256         if (fgets(buf, sizeof(buf), stdin) == NULL)
257           leave(0);
258         buf[strlen(buf) - 1] = NULL;
259         if (strlen(buf) == 0)
260             result = def_val;
261         else if (strcasecmp(buf, BLANK) == NULL)
262             result = "";
263         else 
264             result = buf;
265         
266         for (i = 0; i < strlen(buf); i++)
267         {
268             switch (buf[i])
269             {
270               case '"':
271                 printf("'\"' is not allowed.\n");
272                 ok = FALSE;
273                 break;
274               case ',':
275                 printf("',' is not allowed.\n");
276                 ok = FALSE;
277                 break;
278               case ':':
279                 printf("':' is not allowed.\n");
280                 ok = FALSE;
281                 break;
282               default:
283                 if (iscntrl(buf[i])) {
284                     printf("Control characters are not allowed.\n");
285                     ok = FALSE;
286                     break;
287                 }
288             }
289             if (!ok)
290                 break;
291         }
292         
293         if (phone_num && ok) {
294             for (i = 0; i < strlen(buf); i++) {
295                 if (!isdigit(buf[i]) && (buf[i] != '-')) {
296                     printf("Phone numbers can contain only digits.\n");
297                     ok = FALSE;
298                     break;
299                 }
300                 if (buf[i] == '-')
301                     dashes = TRUE;
302             }
303         }
304     }
305     
306     /* Remove dashes if necessary */
307     if (dashes && result == buf) {
308         char *tmp1, *tmp2;
309         tmp1 = tmp2 = (char *)buf;
310         do {
311             if (*(tmp1) != '-')
312                 *(tmp2++) = *(tmp1);
313         }
314         while (*(tmp1++));
315     }
316     
317     return(result);
318 }
319         
320 void get_new_info(old_info, new_info)
321   struct finger_info *old_info;
322   struct finger_info *new_info;
323 {
324     printf("Default values are printed inside of '[]'.\n");
325     printf("To accept the default, type <return>.\n");
326     printf("To have a blank entry, type the word '%s'.\n\n", BLANK);
327
328 #define GETINFO(m,v,n) \
329     new_info->v = strsave(ask(m, old_info->v, n))
330     
331     GETINFO("Full name", fullname, FALSE);
332     GETINFO("Nickname", nickname, FALSE);
333     GETINFO("Home address (Ex: Atkinson 304)", home_address, FALSE);
334     GETINFO("Home phone number (Ex: 3141592)", home_phone, TRUE);
335     GETINFO("Office address (Exs: E40-342 or 2-108)", 
336             office_address, FALSE);
337     GETINFO("Office phone (Ex: 3-1300)", office_phone, TRUE);
338     GETINFO("MIT department (Exs: 9, Biology, Information Services", 
339             mit_department, FALSE);
340     GETINFO("MIT year (Exs: 1989, '91, Faculty, Grad)", mit_year, FALSE);
341 }
342
343 usage()
344 {
345     fprintf(stderr, "Usage: %s [user]\n", whoami);
346     exit(1);
347 }
This page took 0.051191 seconds and 3 git commands to generate.