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