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