]> andersk Git - moira.git/blob - clients/addusr/addusr.c
a0a946bbe28c781891ced9a9a11344804f9df239
[moira.git] / clients / addusr / addusr.c
1 /* $Id$
2  *
3  * Program to add users en masse to the moira database
4  *
5  * by Mark Rosenstein, July 1992.
6  *
7  * Copyright (C) 1992-1998 by the Massachusetts Institute of Technology.
8  * For copying and distribution information, please see the file
9  * <mit-copyright.h>.
10  */
11
12 #include <mit-copyright.h>
13 #include <moira.h>
14 #include <moira_site.h>
15 #include <mrclient.h>
16
17 #include <ctype.h>
18 #include <errno.h>
19 #include <stdio.h>
20 #include <string.h>
21
22 RCSID("$Header$");
23
24 struct owner_type {
25   int type;
26   char *name;
27 };
28
29 #define M_ANY           0
30 #define M_USER          1
31 #define M_LIST          2
32 #define M_KERBEROS      3
33 #define M_NONE          4
34
35 #ifdef ATHENA
36 #define DEFAULT_SHELL "/bin/athena/tcsh"
37 #else
38 #define DEFAULT_SHELL "/bin/csh"
39 #endif
40
41 #define DEFAULT_WINCONSOLESHELL "cmd"
42 #define DEFAULT_WINHOMEDIR "[DFS]"
43 #define DEFAULT_WINPROFILEDIR "[DFS]"
44
45 /* flags from command line */
46 char *class, *comment, *status_str, *shell, *winconsoleshell, *filename;
47 int reg_only, reg, verbose, nodupcheck, securereg, nocaps;
48 struct owner_type *sponsor;
49
50 /* argument parsing macro */
51 #define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
52
53 char *whoami;
54 int duplicate, errors;
55
56 void usage(char **argv);
57 int usercheck(int argc, char **argv, void *qargv);
58 int get_uid(int argc, char **argv, void *qargv);
59 struct owner_type *parse_member(char *s);
60
61 int main(int argc, char **argv)
62 {
63   int status, lineno;
64   char **arg = argv, *qargv[U_END];
65   char *p, *first, *middle, *last, *id, *login, *server;
66   char buf[BUFSIZ];
67   FILE *input;
68
69   /* clear all flags & lists */
70   reg_only = reg = verbose = lineno = nodupcheck = errors = securereg = nocaps = 0;
71   sponsor = NULL;
72   server = NULL;
73   filename = "-";
74   shell = DEFAULT_SHELL;
75   winconsoleshell = DEFAULT_WINCONSOLESHELL;
76   class = "TEMP";
77   comment = "";
78   status_str = "0";
79
80   whoami = argv[0];
81
82   /* parse args */
83   while (++arg - argv < argc)
84     {
85       if  (**arg == '-')
86         {
87           if (argis("c", "class"))
88             {
89               if (arg - argv < argc - 1)
90                 {
91                   ++arg;
92                   class = *arg;
93                 }
94               else
95                 usage(argv);
96             }
97           else if (argis("C", "comment"))
98             {
99               if (arg - argv < argc - 1)
100                 {
101                   ++arg;
102                   comment = *arg;
103                 }
104               else
105                 usage(argv);
106             }
107           else if (argis("s", "status"))
108             {
109               if (arg - argv < argc - 1)
110                 {
111                   ++arg;
112                   status_str = *arg;
113                 }
114               else
115                 usage(argv);
116             }
117           else if (argis("h", "shell"))
118             {
119               if (arg - argv < argc - 1)
120                 {
121                   ++arg;
122                   shell = *arg;
123                 }
124               else
125                 usage(argv);
126             }
127           else if (argis("w", "winshell"))
128             {
129               if (arg - argv < argc - 1)
130                 {
131                   ++arg;
132                   winconsoleshell = *arg;
133                 }
134               else 
135                 usage(argv);
136             }
137           else if (argis("sp", "sponsor"))
138             {
139               if (arg - argv < argc - 1)
140                 {
141                   ++arg;
142                   sponsor = parse_member(*arg);
143                 }
144               else
145                 usage(argv);
146             }
147           else if (argis("6", "secure"))
148             securereg++;
149           else if (argis("r", "reg_only"))
150             reg_only++;
151           else if (argis("R", "register"))
152             reg++;
153           else if (argis("f", "file"))
154             {
155               if (arg - argv < argc - 1)
156                 {
157                   ++arg;
158                   filename = *arg;
159                 }
160               else
161                 usage(argv);
162             }
163           else if (argis("v", "verbose"))
164             verbose++;
165           else if (argis("d", "nodupcheck"))
166             nodupcheck++;
167           else if (argis("n", "nocaps"))
168             nocaps++;
169           else if (argis("S", "server") || argis("db", "database"))
170             {
171               if (arg - argv < argc - 1)
172                 {
173                   ++arg;
174                   server = *arg;
175                 }
176               else
177                 usage(argv);
178             }
179           else
180             usage(argv);
181         }
182       else
183         usage(argv);
184     }
185
186   if (!strcmp(filename, "-"))
187     input = stdin;
188   else
189     {
190       input = fopen(filename, "r");
191       if (!input)
192         {
193           com_err(whoami, errno, "opening input file %s", filename);
194           exit(2);
195         }
196     }
197
198   /* fire up Moira */
199   if (mrcl_connect(server, "addusr", 12, 1) != MRCL_SUCCESS)
200     exit(2);
201
202   qargv[U_NAME] = UNIQUE_LOGIN;
203   qargv[U_UID] = UNIQUE_UID;
204   qargv[U_SHELL] = shell;
205   qargv[U_WINCONSOLESHELL] = winconsoleshell;
206   qargv[U_WINHOMEDIR] = DEFAULT_WINHOMEDIR;
207   qargv[U_WINPROFILEDIR] = DEFAULT_WINPROFILEDIR;
208   qargv[U_STATE] = status_str;
209   qargv[U_CLASS] = class;
210   qargv[U_COMMENT] = comment;
211   qargv[U_SIGNATURE] = "";
212   qargv[U_SECURE] = securereg ? "1" : "0";
213   
214   while (fgets(buf, BUFSIZ, input))
215     {
216       /* throw away terminating newline */
217       p = &buf[strlen(buf) - 1];
218       if (*p == '\n')
219         *p = '\0';
220       lineno++;
221       if (strlen(buf) == 0)
222         continue;
223       /* Last name is first thing on line */
224       last = buf;
225       /* First name follows a comma */
226       p = strchr(last, ',');
227       if (!p)
228         {
229           com_err(whoami, MR_BAD_CHAR, "Missing comma on line %d", lineno);
230           errors++;
231           continue;
232         }
233       *p++ = '\0';
234       first = strtrim(p);
235       while (*p)                /* find end-of-line */
236         p++;
237       if (reg_only || reg)
238         {
239           while (!isspace(*p))
240             p--;
241           if (p <= first)
242             {
243               com_err(whoami, 0, "Missing login on line %d", lineno);
244               errors++;
245               continue;
246             }
247           login = strtrim(&p[1]);
248           *p-- = '\0';
249         }
250       else
251         {
252           /* ID is last thing on line */
253           p--;
254         }
255       while (isspace(*p))
256         p--;
257       while (!isspace(*p))
258         p--;
259       if (p <= first)
260         {
261           com_err(whoami, 0, "Missing ID on line %d", lineno);
262           errors++;
263           continue;
264         }
265       id = &p[1];
266       *p-- = '\0';
267       /* If something between first name & ID, it's middle name */
268       while (isspace(*p))
269         p--;
270       while (!isspace(*p))
271         p--;
272       if (p <= first)
273         middle = "";
274       else
275         {
276           middle = &p[1];
277           *p = '\0';
278         }
279       qargv[U_FIRST] = strtrim(first);
280       qargv[U_MIDDLE] = strtrim(middle);
281       qargv[U_LAST] = strtrim(last);
282       qargv[U_MITID] = strtrim(id);
283       if (!nocaps)
284         {
285           FixCase(qargv[U_FIRST]);
286           FixCase(qargv[U_MIDDLE]);
287           FixCase(qargv[U_LAST]);
288         }
289       RemoveHyphens(qargv[U_MITID]);
290       if (!reg_only)
291         {
292           if (!nodupcheck)
293             {
294               char *dargv[2];
295
296               dargv[0] = qargv[U_FIRST];
297               dargv[1] = qargv[U_LAST];
298               duplicate = 0;
299               status = mr_query("get_user_account_by_name", 2, dargv,
300                                 usercheck, qargv);
301               if (status && status != MR_NO_MATCH)
302                 {
303                   com_err(whoami, status,
304                           "checking to see if user %s %s already exists",
305                           qargv[U_FIRST], qargv[U_LAST]);
306                   com_err(whoami, 0, "NOT ADDING USER");
307                   errors++;
308                   continue;
309                 }
310               if (duplicate > 0)
311                 {
312                   com_err(whoami, MR_EXISTS, "user %s %s already exists",
313                           qargv[U_FIRST], qargv[U_LAST]);
314                   com_err(whoami, 0, "NOT ADDING USER");
315                   errors++;
316                   continue;
317                 }
318               else if (duplicate < 0)
319                 {
320                   com_err(whoami, MR_EXISTS,
321                           "user %s %s already exists with different ID number",
322                           qargv[U_FIRST], qargv[U_LAST]);
323                   com_err(whoami, 0, "ADDING user anyway");
324                 }
325             }
326
327           if (sponsor)
328             {
329               qargv[U_SPONSOR_NAME] = sponsor->name;
330               switch (sponsor->type)
331                 {
332                 case M_ANY:
333                 case M_USER:
334                   qargv[U_SPONSOR_TYPE] = "USER";
335                   status = mr_query("add_user_account", 17, qargv, NULL, NULL);
336                   if (sponsor->type != M_ANY || status != MR_USER)
337                     break;
338                   
339                 case M_LIST:
340                   qargv[U_SPONSOR_TYPE] = "LIST";
341                   status = mr_query("add_user_account", 17, qargv, NULL, NULL);
342                   break;
343                   
344                 case M_KERBEROS:
345                   qargv[U_SPONSOR_TYPE] = "KERBEROS";
346                   status = mrcl_validate_kerberos_member(qargv[U_SPONSOR_NAME],
347                                                          &qargv[U_SPONSOR_NAME]);
348                   if (mrcl_get_message())
349                     mrcl_com_err(whoami);
350                   if (status == MRCL_REJECT)
351                 exit(1);
352                   status = mr_query("add_user_account", 17, qargv, NULL, NULL);
353                   break;
354                   
355                 case M_NONE:
356                   qargv[U_SPONSOR_TYPE] = "NONE";
357                   status = mr_query("add_user_account", 17, qargv, NULL, NULL);
358                   break;
359                 }
360             }
361           else
362             {
363               qargv[U_SPONSOR_TYPE] = "NONE";
364               qargv[U_SPONSOR_NAME] = "NONE";
365           
366               status = mr_query("add_user_account", 17, qargv, NULL, NULL);
367             }
368           
369           if (status)
370             {
371               com_err(whoami, status, "adding user %s %s", first, last);
372               errors++;
373             }
374           else if (verbose)
375             {
376               printf("Added user %s %s %s (%s)\n", qargv[U_FIRST],
377                      qargv[U_MIDDLE], qargv[U_LAST], qargv[U_MITID]);
378             }
379         }
380       if (reg || reg_only)
381         {
382           char *gargv[2], *rargv[3], uid[10];
383
384           uid[0] = '\0';
385           gargv[0] = qargv[U_FIRST];
386           gargv[1] = qargv[U_LAST];
387           status = mr_query("get_user_account_by_name", 2, gargv,
388                             get_uid, &uid);
389           if (status)
390             {
391               com_err(whoami, status, "while looking up uid for %s %s",
392                       qargv[U_FIRST], qargv[U_LAST]);
393               errors++;
394               continue;
395             }
396
397           rargv[0] = uid;
398           rargv[1] = login;
399           rargv[2] = "IMAP";
400
401           status = mr_query("register_user", 3, rargv, NULL, NULL);
402           if (status)
403             {
404               com_err(whoami, status, "while registering (login) %s %s",
405                       qargv[U_FIRST], qargv[U_LAST]);
406               errors++;
407               continue;
408             }
409           else if (verbose)
410             {
411               printf("Registered user %s %s as %s\n", qargv[U_FIRST],
412                      qargv[U_LAST], login);
413             }
414         }
415     }
416
417   exit(errors);
418 }
419
420
421 void usage(char **argv)
422 {
423   fprintf(stderr, "Usage: %s [options]\n", argv[0]);
424   fprintf(stderr, "Options are\n");
425   fprintf(stderr, "   -f | -file filename (default STDIN)\n");
426   fprintf(stderr, "   -c | -class class (default TEMP)\n");
427   fprintf(stderr, "   -C | -comment \"comment\" (default \"\")\n");
428   fprintf(stderr, "   -s | -status status (default 0)\n");
429   fprintf(stderr, "   -h | -shell shell (default %s)\n", DEFAULT_SHELL);
430   fprintf(stderr, "   -w | -winshell windows console shell (default %s)\n",
431           DEFAULT_WINCONSOLESHELL);
432   fprintf(stderr, "   -sp | -sponsor sponsor (default NONE)\n");
433   fprintf(stderr, "   -r | -reg_only\n");
434   fprintf(stderr, "   -R | -register (and add to database)\n");
435   fprintf(stderr, "   -v | -verbose\n");
436   fprintf(stderr, "   -d | -nodupcheck (don't check for duplicates)\n");
437   fprintf(stderr, "   -n | -nocaps (don't fix capitalization of names)\n");
438   fprintf(stderr, "   -db | -database host:port\n");
439   exit(1);
440 }
441
442
443 /* query callback routine to check for duplicate users */
444
445 int usercheck(int argc, char **argv, void *qargv)
446 {
447   if (!strcmp(argv[U_MITID], ((char **)qargv)[U_MITID]))
448     duplicate++;
449   else
450     duplicate--;
451
452   return MR_CONT;
453 }
454
455 /* query callback to get uid of a just-added account */
456 int get_uid(int argc, char **argv, void *uidv)
457 {
458   char *uid = uidv;
459
460   if (uid[0] == '\0')
461     strcpy(uid, argv[U_UID]);
462   else
463     {
464       if (!strcmp(argv[U_MODWITH], "addusr"))
465         strcpy(uid, argv[U_UID]);
466     }
467
468   return MR_CONT;
469 }
470
471 /* Parse a line of input, fetching a member.  NULL is returned if a member
472  * is not found.  ';' is a comment character.
473  */
474 struct owner_type *parse_member(char *s)
475 {
476   struct owner_type *m;
477   char *p, *lastchar;
478
479   while (*s && isspace(*s))
480     s++;
481   lastchar = p = s;
482   while (*p && *p != '\n' && *p != ';')
483     {
484       if (isprint(*p) && !isspace(*p))
485         lastchar = p++;
486       else
487         p++;
488     }
489   lastchar++;
490   *lastchar = '\0';
491   if (p == s || strlen(s) == 0)
492     return NULL;
493
494   if (!(m = malloc(sizeof(struct owner_type))))
495     return NULL;
496
497   if ((p = strchr(s, ':')))
498     {
499       *p = '\0';
500       m->name = ++p;
501       if (!strcasecmp("user", s))
502         m->type = M_USER;
503       else if (!strcasecmp("list", s))
504         m->type = M_LIST;
505       else if (!strcasecmp("kerberos", s))
506         m->type = M_KERBEROS;
507       else if (!strcasecmp("none", s))
508         m->type = M_NONE;
509       else
510         {
511           m->type = M_ANY;
512           *(--p) = ':';
513           m->name = s;
514         }
515       m->name = strdup(m->name);
516     }
517   else
518     {
519       m->name = strdup(s);
520       m->type = strcasecmp(s, "none") ? M_ANY : M_NONE;
521     }
522   return m;
523 }
This page took 0.067545 seconds and 3 git commands to generate.