]> andersk Git - moira.git/blame - clients/addusr/addusr.c
tcsh is dead. Long live bash.
[moira.git] / clients / addusr / addusr.c
CommitLineData
c441a31a 1/* $Id$
93d0b3bf 2 *
7ac48069 3 * Program to add users en masse to the moira database
93d0b3bf 4 *
5 * by Mark Rosenstein, July 1992.
6 *
7ac48069 7 * Copyright (C) 1992-1998 by the Massachusetts Institute of Technology.
93d0b3bf 8 * For copying and distribution information, please see the file
9 * <mit-copyright.h>.
10 */
11
12#include <mit-copyright.h>
93d0b3bf 13#include <moira.h>
14#include <moira_site.h>
2a12a5ec 15#include <mrclient.h>
93d0b3bf 16
7ac48069 17#include <ctype.h>
18#include <errno.h>
19#include <stdio.h>
20#include <string.h>
21
22RCSID("$Header$");
93d0b3bf 23
7902e669 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
17490e42 35#ifdef ATHENA
78364700 36#define DEFAULT_SHELL "/bin/athena/bash"
17490e42 37#else
78364700 38#define DEFAULT_SHELL "/bin/bash"
17490e42 39#endif
40
0978529a 41#define DEFAULT_WINCONSOLESHELL "cmd"
7902e669 42#define DEFAULT_WINHOMEDIR "[DFS]"
43#define DEFAULT_WINPROFILEDIR "[DFS]"
0978529a 44
93d0b3bf 45/* flags from command line */
0978529a 46char *class, *comment, *status_str, *shell, *winconsoleshell, *filename;
00fef14d 47char *expiration;
c41ec264 48int reg_only, reg, verbose, nodupcheck, securereg, nocaps;
7902e669 49struct owner_type *sponsor;
93d0b3bf 50
51/* argument parsing macro */
5eaef520 52#define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
93d0b3bf 53
54char *whoami;
55int duplicate, errors;
56
7ac48069 57void usage(char **argv);
58int usercheck(int argc, char **argv, void *qargv);
aa7d79ff 59int get_uid(int argc, char **argv, void *qargv);
7902e669 60struct owner_type *parse_member(char *s);
93d0b3bf 61
5eaef520 62int main(int argc, char **argv)
93d0b3bf 63{
5eaef520 64 int status, lineno;
65 char **arg = argv, *qargv[U_END];
2a12a5ec 66 char *p, *first, *middle, *last, *id, *login, *server;
533bacb3 67 char buf[BUFSIZ];
5eaef520 68 FILE *input;
93d0b3bf 69
5eaef520 70 /* clear all flags & lists */
c41ec264 71 reg_only = reg = verbose = lineno = nodupcheck = errors = securereg = nocaps = 0;
7902e669 72 sponsor = NULL;
5eaef520 73 server = NULL;
74 filename = "-";
75 shell = DEFAULT_SHELL;
0978529a 76 winconsoleshell = DEFAULT_WINCONSOLESHELL;
5eaef520 77 class = "TEMP";
78 comment = "";
00fef14d 79 expiration = "";
5eaef520 80 status_str = "0";
93d0b3bf 81
5eaef520 82 whoami = argv[0];
93d0b3bf 83
5eaef520 84 /* parse args */
85 while (++arg - argv < argc)
86 {
87 if (**arg == '-')
93d0b3bf 88 {
5eaef520 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 }
0978529a 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 }
7902e669 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 }
00fef14d 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 }
c0c29294 159 else if (argis("6", "secure"))
160 securereg++;
5eaef520 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++;
c41ec264 179 else if (argis("n", "nocaps"))
180 nocaps++;
5eaef520 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
93d0b3bf 189 usage(argv);
5eaef520 190 }
191 else
192 usage(argv);
193 }
194 else
195 usage(argv);
93d0b3bf 196 }
197
5eaef520 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);
93d0b3bf 207 }
208 }
209
aa7d79ff 210 /* fire up Moira */
7902e669 211 if (mrcl_connect(server, "addusr", 12, 1) != MRCL_SUCCESS)
2a12a5ec 212 exit(2);
93d0b3bf 213
5eaef520 214 qargv[U_NAME] = UNIQUE_LOGIN;
215 qargv[U_UID] = UNIQUE_UID;
216 qargv[U_SHELL] = shell;
0978529a 217 qargv[U_WINCONSOLESHELL] = winconsoleshell;
7902e669 218 qargv[U_WINHOMEDIR] = DEFAULT_WINHOMEDIR;
219 qargv[U_WINPROFILEDIR] = DEFAULT_WINPROFILEDIR;
00fef14d 220 qargv[U_EXPIRATION] = expiration;
5eaef520 221 qargv[U_STATE] = status_str;
222 qargv[U_CLASS] = class;
223 qargv[U_COMMENT] = comment;
224 qargv[U_SIGNATURE] = "";
c0c29294 225 qargv[U_SECURE] = securereg ? "1" : "0";
7902e669 226
5eaef520 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++;
93d0b3bf 244 continue;
93d0b3bf 245 }
5eaef520 246 *p++ = '\0';
2afc856a 247 first = strtrim(p);
5eaef520 248 while (*p) /* find end-of-line */
249 p++;
250 if (reg_only || reg)
251 {
5eaef520 252 while (!isspace(*p))
93d0b3bf 253 p--;
5eaef520 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';
93d0b3bf 262 }
5eaef520 263 else
264 {
265 /* ID is last thing on line */
266 p--;
93d0b3bf 267 }
5eaef520 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;
93d0b3bf 277 }
5eaef520 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);
c41ec264 296 if (!nocaps)
297 {
298 FixCase(qargv[U_FIRST]);
299 FixCase(qargv[U_MIDDLE]);
300 FixCase(qargv[U_LAST]);
301 }
5eaef520 302 RemoveHyphens(qargv[U_MITID]);
303 if (!reg_only)
304 {
305 if (!nodupcheck)
306 {
307 char *dargv[2];
93d0b3bf 308
5eaef520 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,
7ac48069 313 usercheck, qargv);
5eaef520 314 if (status && status != MR_NO_MATCH)
315 {
316 com_err(whoami, status,
317 "checking to see if user %s %s already exists",
9e1ff037 318 qargv[U_FIRST], qargv[U_LAST]);
5eaef520 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",
9e1ff037 326 qargv[U_FIRST], qargv[U_LAST]);
5eaef520 327 com_err(whoami, 0, "NOT ADDING USER");
328 errors++;
329 continue;
93d0b3bf 330 }
5eaef520 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");
93d0b3bf 337 }
338 }
7902e669 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";
00fef14d 348 status = mr_query("add_user_account", 18, qargv, NULL, NULL);
7902e669 349 if (sponsor->type != M_ANY || status != MR_USER)
350 break;
351
352 case M_LIST:
353 qargv[U_SPONSOR_TYPE] = "LIST";
00fef14d 354 status = mr_query("add_user_account", 18, qargv, NULL, NULL);
7902e669 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);
00fef14d 365 status = mr_query("add_user_account", 18, qargv, NULL, NULL);
7902e669 366 break;
367
368 case M_NONE:
369 qargv[U_SPONSOR_TYPE] = "NONE";
00fef14d 370 status = mr_query("add_user_account", 18, qargv, NULL, NULL);
7902e669 371 break;
372 }
373 }
374 else
375 {
376 qargv[U_SPONSOR_TYPE] = "NONE";
377 qargv[U_SPONSOR_NAME] = "NONE";
378
00fef14d 379 status = mr_query("add_user_account", 18, qargv, NULL, NULL);
7902e669 380 }
381
5eaef520 382 if (status)
383 {
384 com_err(whoami, status, "adding user %s %s", first, last);
385 errors++;
386 }
387 else if (verbose)
388 {
93d0b3bf 389 printf("Added user %s %s %s (%s)\n", qargv[U_FIRST],
390 qargv[U_MIDDLE], qargv[U_LAST], qargv[U_MITID]);
5eaef520 391 }
93d0b3bf 392 }
5eaef520 393 if (reg || reg_only)
394 {
aa7d79ff 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 }
8c0ce358 409
aa7d79ff 410 rargv[0] = uid;
8c0ce358 411 rargv[1] = login;
17540151 412 rargv[2] = "IMAP";
8c0ce358 413
aa7d79ff 414 status = mr_query("register_user", 3, rargv, NULL, NULL);
5eaef520 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 {
93d0b3bf 424 printf("Registered user %s %s as %s\n", qargv[U_FIRST],
425 qargv[U_LAST], login);
5eaef520 426 }
93d0b3bf 427 }
428 }
429
5eaef520 430 exit(errors);
93d0b3bf 431}
432
433
7ac48069 434void usage(char **argv)
93d0b3bf 435{
5eaef520 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);
0978529a 443 fprintf(stderr, " -w | -winshell windows console shell (default %s)\n",
444 DEFAULT_WINCONSOLESHELL);
7902e669 445 fprintf(stderr, " -sp | -sponsor sponsor (default NONE)\n");
00fef14d 446 fprintf(stderr, " -e | -expiration \"expiration date\" (default \"\")\n");
5eaef520 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");
c41ec264 451 fprintf(stderr, " -n | -nocaps (don't fix capitalization of names)\n");
5eaef520 452 fprintf(stderr, " -db | -database host:port\n");
453 exit(1);
93d0b3bf 454}
455
456
93d0b3bf 457/* query callback routine to check for duplicate users */
458
7ac48069 459int usercheck(int argc, char **argv, void *qargv)
93d0b3bf 460{
7ac48069 461 if (!strcmp(argv[U_MITID], ((char **)qargv)[U_MITID]))
5eaef520 462 duplicate++;
463 else
464 duplicate--;
7ac48069 465
466 return MR_CONT;
93d0b3bf 467}
aa7d79ff 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}
7902e669 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.25639 seconds and 5 git commands to generate.