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