-/* $Header$
+/* $Id$
*
- * Program to add users en batch to the moira database
+ * Program to add users en masse to the moira database
*
* by Mark Rosenstein, July 1992.
*
- * Copyright 1992 by the Massachusetts Institute of Technology.
- *
- * (c) Copyright 1992 by the Massachusetts Institute of Technology.
+ * Copyright (C) 1992-1998 by the Massachusetts Institute of Technology.
* For copying and distribution information, please see the file
* <mit-copyright.h>.
*/
#include <mit-copyright.h>
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <des.h>
-#include <krb.h>
#include <moira.h>
#include <moira_site.h>
+#include <mrclient.h>
-#ifndef LINT
-static char adduser_rcsid[] = "$Header$";
-#endif
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+RCSID("$Header$");
+
+struct owner_type {
+ int type;
+ char *name;
+};
+
+#define M_ANY 0
+#define M_USER 1
+#define M_LIST 2
+#define M_KERBEROS 3
+#define M_NONE 4
#ifdef ATHENA
-#define DEFAULT_SHELL "/bin/athena/tcsh"
+#define DEFAULT_SHELL "/bin/athena/bash"
#else
-#define DEFAULT_SHELL "/bin/csh"
+#define DEFAULT_SHELL "/bin/bash"
#endif
+#define DEFAULT_WINCONSOLESHELL "cmd"
+#define DEFAULT_WINHOMEDIR "[DFS]"
+#define DEFAULT_WINPROFILEDIR "[DFS]"
+
/* flags from command line */
-char *class, *comment, *status_str, *shell, *filename;
-int reg_only, reg, verbose, nodupcheck;
+char *class, *comment, *status_str, *shell, *winconsoleshell, *filename;
+char *expiration;
+int reg_only, reg, verbose, nodupcheck, securereg, nocaps;
+struct owner_type *sponsor;
/* argument parsing macro */
-#define argis(a,b) ((strcmp(*arg+1, a) == 0) || (strcmp(*arg+1, b) == 0))
+#define argis(a, b) (!strcmp(*arg + 1, a) || !strcmp(*arg + 1, b))
char *whoami;
int duplicate, errors;
-extern char *FixCase(), *RemoveHyphens(), *strtrim();
-extern int errno;
-int usercheck(), scream();
+void usage(char **argv);
+int usercheck(int argc, char **argv, void *qargv);
+int get_uid(int argc, char **argv, void *qargv);
+struct owner_type *parse_member(char *s);
-
-main(argc, argv)
-int argc;
-char **argv;
+int main(int argc, char **argv)
{
- int status, lineno;
- char **arg = argv, *qargv[U_END];
- char *motd, *p, *first, *middle, *last, *id, *login, *passwd, *server;
- char buf[BUFSIZ], idbuf[32];
- FILE *input;
-
- /* clear all flags & lists */
- reg_only = reg = verbose = lineno = nodupcheck = errors = 0;
- server = NULL;
- filename = "-";
- shell = DEFAULT_SHELL;
- class = "TEMP";
- comment = "";
- status_str = "0";
-
- whoami = argv[0];
-
- /* parse args */
- while (++arg - argv < argc) {
- if (**arg == '-')
+ int status, lineno;
+ char **arg = argv, *qargv[U_END];
+ char *p, *first, *middle, *last, *id, *login, *server;
+ char buf[BUFSIZ];
+ FILE *input;
+
+ /* clear all flags & lists */
+ reg_only = reg = verbose = lineno = nodupcheck = errors = securereg = nocaps = 0;
+ sponsor = NULL;
+ server = NULL;
+ filename = "-";
+ shell = DEFAULT_SHELL;
+ winconsoleshell = DEFAULT_WINCONSOLESHELL;
+ class = "TEMP";
+ comment = "";
+ expiration = "";
+ status_str = "0";
+
+ whoami = argv[0];
+
+ /* parse args */
+ while (++arg - argv < argc)
+ {
+ if (**arg == '-')
{
- if (argis("c", "class"))
- if (arg - argv < argc - 1) {
- ++arg;
- class = *arg;
- } else
- usage(argv);
- else if (argis("C", "comment"))
- if (arg - argv < argc - 1) {
- ++arg;
- comment = *arg;
- } else
- usage(argv);
- else if (argis("s", "status"))
- if (arg - argv < argc - 1) {
- ++arg;
- status_str = *arg;
- } else
- usage(argv);
- else if (argis("h", "shell"))
- if (arg - argv < argc - 1) {
- ++arg;
- shell = *arg;
- } else
- usage(argv);
- else if (argis("r", "reg_only"))
- reg_only++;
- else if (argis("R", "register"))
- reg++;
- else if (argis("f", "file"))
- if (arg - argv < argc - 1) {
- ++arg;
- filename = *arg;
- } else
- usage(argv);
- else if (argis("v","verbose"))
- verbose++;
- else if (argis("d","nodupcheck"))
- nodupcheck++;
- else if (argis("S","server") || argis("db","database"))
- if (arg - argv < argc - 1) {
- ++arg;
- server = *arg;
- } else
- usage(argv);
- else
+ if (argis("c", "class"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ class = *arg;
+ }
+ else
usage(argv);
- } else
- usage(argv);
- }
-
- if (!strcmp(filename, "-"))
- input = stdin;
- else {
- input = fopen(filename, "r");
- if (input == NULL) {
- com_err(whoami, errno, "opening input file %s", filename);
- exit(2);
+ }
+ else if (argis("C", "comment"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ comment = *arg;
+ }
+ else
+ usage(argv);
+ }
+ else if (argis("s", "status"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ status_str = *arg;
+ }
+ else
+ usage(argv);
+ }
+ else if (argis("h", "shell"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ shell = *arg;
+ }
+ else
+ usage(argv);
+ }
+ else if (argis("w", "winshell"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ winconsoleshell = *arg;
+ }
+ else
+ usage(argv);
+ }
+ else if (argis("sp", "sponsor"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ sponsor = parse_member(*arg);
+ }
+ else
+ usage(argv);
+ }
+ else if (argis("e", "expiration"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ expiration = *arg;
+ }
+ else
+ usage(argv);
+ }
+ else if (argis("6", "secure"))
+ securereg++;
+ else if (argis("r", "reg_only"))
+ reg_only++;
+ else if (argis("R", "register"))
+ reg++;
+ else if (argis("f", "file"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ filename = *arg;
+ }
+ else
+ usage(argv);
+ }
+ else if (argis("v", "verbose"))
+ verbose++;
+ else if (argis("d", "nodupcheck"))
+ nodupcheck++;
+ else if (argis("n", "nocaps"))
+ nocaps++;
+ else if (argis("S", "server") || argis("db", "database"))
+ {
+ if (arg - argv < argc - 1)
+ {
+ ++arg;
+ server = *arg;
+ }
+ else
+ usage(argv);
+ }
+ else
+ usage(argv);
}
+ else
+ usage(argv);
}
- if (!reg_only) {
- /* fire up Moira */
- if (status = mr_connect(server)) {
- com_err(whoami, status, "unable to connect to the Moira server");
- exit(2);
- }
- if ( status = mr_motd(&motd) ) {
- com_err(whoami, status, "unable to check server status");
- exit(2);
- }
- if (motd) {
- fprintf(stderr, "The Moira server is currently unavailable:\n%s\n", motd);
- mr_disconnect();
- exit(2);
- }
-
- if (status = mr_auth("addusr")) {
- if (status == MR_USER_AUTH)
- com_err(whoami, status, "");
- else {
- com_err(whoami, status, "unable to authenticate to Moira");
- exit(2);
- }
+ if (!strcmp(filename, "-"))
+ input = stdin;
+ else
+ {
+ input = fopen(filename, "r");
+ if (!input)
+ {
+ com_err(whoami, errno, "opening input file %s", filename);
+ exit(2);
}
}
- if (reg || reg_only)
- ureg_init();
-
- qargv[U_NAME] = UNIQUE_LOGIN;
- qargv[U_UID] = UNIQUE_UID;
- qargv[U_SHELL] = shell;
- qargv[U_STATE] = status_str;
- qargv[U_CLASS] = class;
- qargv[U_COMMENT] = comment;
- qargv[U_SIGNATURE] = "";
- qargv[U_SECURE] = "0";
- while (fgets(buf, BUFSIZ, input)) {
- /* throw away terminating newline */
- p = &buf[strlen(buf) - 1];
- if (*p == '\n')
- *p = 0;
- lineno++;
- if (strlen(buf) == 0)
+ /* fire up Moira */
+ if (mrcl_connect(server, "addusr", 12, 1) != MRCL_SUCCESS)
+ exit(2);
+
+ qargv[U_NAME] = UNIQUE_LOGIN;
+ qargv[U_UID] = UNIQUE_UID;
+ qargv[U_SHELL] = shell;
+ qargv[U_WINCONSOLESHELL] = winconsoleshell;
+ qargv[U_WINHOMEDIR] = DEFAULT_WINHOMEDIR;
+ qargv[U_WINPROFILEDIR] = DEFAULT_WINPROFILEDIR;
+ qargv[U_EXPIRATION] = expiration;
+ qargv[U_STATE] = status_str;
+ qargv[U_CLASS] = class;
+ qargv[U_COMMENT] = comment;
+ qargv[U_SIGNATURE] = "";
+ qargv[U_SECURE] = securereg ? "1" : "0";
+
+ while (fgets(buf, BUFSIZ, input))
+ {
+ /* throw away terminating newline */
+ p = &buf[strlen(buf) - 1];
+ if (*p == '\n')
+ *p = '\0';
+ lineno++;
+ if (strlen(buf) == 0)
+ continue;
+ /* Last name is first thing on line */
+ last = buf;
+ /* First name follows a comma */
+ p = strchr(last, ',');
+ if (!p)
+ {
+ com_err(whoami, MR_BAD_CHAR, "Missing comma on line %d", lineno);
+ errors++;
continue;
- /* Last name is first thing on line */
- last = buf;
- /* First name follows a comma */
- p = strchr(last, ',');
- if (!p) {
- com_err(whoami, MR_BAD_CHAR, "Missing comma on line %d", lineno);
- errors++;
- continue;
}
- *p++ = 0;
- first = p;
- while (*p) p++; /* find end-of-line */
- if (reg_only || reg) {
- while (!isspace(*p)) p--;
- if (p <= first) {
- com_err(whoami, 0, "Missing password on line %d", lineno);
- errors++;
- continue;
- }
- passwd = strtrim(&p[1]);
- *p-- = 0;
- /* previous field is login name */
- while (isspace(*p)) p--;
- while (!isspace(*p)) p--;
- if (p <= first) {
- com_err(whoami, 0, "Missing login on line %d", lineno);
- errors++;
- continue;
- }
- login = strtrim(&p[1]);
- *p-- = 0;
- } else {
- /* ID is last thing on line */
+ *p++ = '\0';
+ first = strtrim(p);
+ while (*p) /* find end-of-line */
+ p++;
+ if (reg_only || reg)
+ {
+ while (!isspace(*p))
p--;
+ if (p <= first)
+ {
+ com_err(whoami, 0, "Missing login on line %d", lineno);
+ errors++;
+ continue;
+ }
+ login = strtrim(&p[1]);
+ *p-- = '\0';
+ }
+ else
+ {
+ /* ID is last thing on line */
+ p--;
+ }
+ while (isspace(*p))
+ p--;
+ while (!isspace(*p))
+ p--;
+ if (p <= first)
+ {
+ com_err(whoami, 0, "Missing ID on line %d", lineno);
+ errors++;
+ continue;
}
- while (isspace(*p)) p--;
- while (!isspace(*p)) p--;
- if (p <= first) {
- com_err(whoami, 0, "Missing ID on line %d", lineno);
- errors++;
- continue;
+ id = &p[1];
+ *p-- = '\0';
+ /* If something between first name & ID, it's middle name */
+ while (isspace(*p))
+ p--;
+ while (!isspace(*p))
+ p--;
+ if (p <= first)
+ middle = "";
+ else
+ {
+ middle = &p[1];
+ *p = '\0';
}
- id = &p[1];
- *p-- = 0;
- /* If something between first name & ID, it's middle name */
- while (isspace(*p)) p--;
- while (!isspace(*p)) p--;
- if (p <= first)
- middle = "";
- else {
- middle = &p[1];
- *p = 0;
+ qargv[U_FIRST] = strtrim(first);
+ qargv[U_MIDDLE] = strtrim(middle);
+ qargv[U_LAST] = strtrim(last);
+ qargv[U_MITID] = strtrim(id);
+ if (!nocaps)
+ {
+ FixCase(qargv[U_FIRST]);
+ FixCase(qargv[U_MIDDLE]);
+ FixCase(qargv[U_LAST]);
}
- qargv[U_FIRST] = strtrim(first);
- qargv[U_MIDDLE] = strtrim(middle);
- qargv[U_LAST] = strtrim(last);
- qargv[U_MITID] = strtrim(id);
- FixCase(qargv[U_FIRST]);
- FixCase(qargv[U_MIDDLE]);
- FixCase(qargv[U_LAST]);
- RemoveHyphens(qargv[U_MITID]);
- if (!reg_only) {
- if (!nodupcheck) {
- char *dargv[2];
-
- dargv[0] = qargv[U_FIRST];
- dargv[1] = qargv[U_LAST];
- duplicate = 0;
- status = mr_query("get_user_account_by_name", 2, dargv,
- usercheck, (char *) qargv);
- if (status && status != MR_NO_MATCH) {
- com_err(whoami, status,
- "checking to see if user %s %s already exists",
- qargv[0], qargv[1]);
- com_err(whoami, 0, "NOT ADDING USER");
- errors++;
- continue;
+ RemoveHyphens(qargv[U_MITID]);
+ if (!reg_only)
+ {
+ if (!nodupcheck)
+ {
+ char *dargv[2];
+
+ dargv[0] = qargv[U_FIRST];
+ dargv[1] = qargv[U_LAST];
+ duplicate = 0;
+ status = mr_query("get_user_account_by_name", 2, dargv,
+ usercheck, qargv);
+ if (status && status != MR_NO_MATCH)
+ {
+ com_err(whoami, status,
+ "checking to see if user %s %s already exists",
+ qargv[U_FIRST], qargv[U_LAST]);
+ com_err(whoami, 0, "NOT ADDING USER");
+ errors++;
+ continue;
+ }
+ if (duplicate > 0)
+ {
+ com_err(whoami, MR_EXISTS, "user %s %s already exists",
+ qargv[U_FIRST], qargv[U_LAST]);
+ com_err(whoami, 0, "NOT ADDING USER");
+ errors++;
+ continue;
}
- if (duplicate > 0) {
- com_err(whoami, MR_EXISTS, "user %s %s already exists",
- qargv[0], qargv[1]);
- com_err(whoami, 0, "NOT ADDING USER");
- errors++;
- continue;
- } else if (duplicate < 0) {
- com_err(whoami, MR_EXISTS,
- "user %s %s already exists with different ID number",
- qargv[U_FIRST], qargv[U_LAST]);
- com_err(whoami, 0, "ADDING user anyway");
+ else if (duplicate < 0)
+ {
+ com_err(whoami, MR_EXISTS,
+ "user %s %s already exists with different ID number",
+ qargv[U_FIRST], qargv[U_LAST]);
+ com_err(whoami, 0, "ADDING user anyway");
}
}
- status = mr_query("add_user_account", U_SECURE + 1, qargv,
- scream, NULL);
- if (status) {
- com_err(whoami, status, "adding user %s %s", first, last);
- errors++;
- } else if (verbose)
+
+ if (sponsor)
+ {
+ qargv[U_SPONSOR_NAME] = sponsor->name;
+ switch (sponsor->type)
+ {
+ case M_ANY:
+ case M_USER:
+ qargv[U_SPONSOR_TYPE] = "USER";
+ status = mr_query("add_user_account", 18, qargv, NULL, NULL);
+ if (sponsor->type != M_ANY || status != MR_USER)
+ break;
+
+ case M_LIST:
+ qargv[U_SPONSOR_TYPE] = "LIST";
+ status = mr_query("add_user_account", 18, qargv, NULL, NULL);
+ break;
+
+ case M_KERBEROS:
+ qargv[U_SPONSOR_TYPE] = "KERBEROS";
+ status = mrcl_validate_kerberos_member(qargv[U_SPONSOR_NAME],
+ &qargv[U_SPONSOR_NAME]);
+ if (mrcl_get_message())
+ mrcl_com_err(whoami);
+ if (status == MRCL_REJECT)
+ exit(1);
+ status = mr_query("add_user_account", 18, qargv, NULL, NULL);
+ break;
+
+ case M_NONE:
+ qargv[U_SPONSOR_TYPE] = "NONE";
+ status = mr_query("add_user_account", 18, qargv, NULL, NULL);
+ break;
+ }
+ }
+ else
+ {
+ qargv[U_SPONSOR_TYPE] = "NONE";
+ qargv[U_SPONSOR_NAME] = "NONE";
+
+ status = mr_query("add_user_account", 18, qargv, NULL, NULL);
+ }
+
+ if (status)
+ {
+ com_err(whoami, status, "adding user %s %s", first, last);
+ errors++;
+ }
+ else if (verbose)
+ {
printf("Added user %s %s %s (%s)\n", qargv[U_FIRST],
qargv[U_MIDDLE], qargv[U_LAST], qargv[U_MITID]);
+ }
}
- if (reg || reg_only) {
- EncryptID(idbuf, qargv[U_MITID], qargv[U_FIRST], qargv[U_LAST]);
- status = grab_login(qargv[U_FIRST], qargv[U_LAST],
- qargv[U_MITID], idbuf, login);
- if (status) {
- com_err(whoami, status, "while registering (login) %s %s",
- qargv[U_FIRST], qargv[U_LAST]);
- errors++;
- continue;
- } else if (verbose)
+ if (reg || reg_only)
+ {
+ char *gargv[2], *rargv[3], uid[10];
+
+ uid[0] = '\0';
+ gargv[0] = qargv[U_FIRST];
+ gargv[1] = qargv[U_LAST];
+ status = mr_query("get_user_account_by_name", 2, gargv,
+ get_uid, &uid);
+ if (status)
+ {
+ com_err(whoami, status, "while looking up uid for %s %s",
+ qargv[U_FIRST], qargv[U_LAST]);
+ errors++;
+ continue;
+ }
+
+ rargv[0] = uid;
+ rargv[1] = login;
+ rargv[2] = "IMAP";
+
+ status = mr_query("register_user", 3, rargv, NULL, NULL);
+ if (status)
+ {
+ com_err(whoami, status, "while registering (login) %s %s",
+ qargv[U_FIRST], qargv[U_LAST]);
+ errors++;
+ continue;
+ }
+ else if (verbose)
+ {
printf("Registered user %s %s as %s\n", qargv[U_FIRST],
qargv[U_LAST], login);
- status = set_password(qargv[U_FIRST], qargv[U_LAST],
- qargv[U_MITID], idbuf, passwd);
- if (status) {
- com_err(whoami, status, "While registering (passwd) %s %s",
- qargv[U_FIRST], qargv[U_LAST]);
- errors++;
- continue;
- } else if (verbose)
- printf("Set password for user %s\n", login);
+ }
}
}
- exit(errors);
+ exit(errors);
}
-usage(argv)
-char **argv;
+void usage(char **argv)
{
- fprintf(stderr, "Usage: %s [options]\n",argv[0]);
- fprintf(stderr, "Options are\n");
- fprintf(stderr, " -f | -file filename (default STDIN)\n");
- fprintf(stderr, " -c | -class class (default TEMP)\n");
- fprintf(stderr, " -C | -comment \"comment\" (default \"\")\n");
- fprintf(stderr, " -s | -status status (default 0)\n");
- fprintf(stderr, " -h | -shell shell (default %s)\n", DEFAULT_SHELL);
- fprintf(stderr, " -r | -reg_only\n");
- fprintf(stderr, " -R | -register (and add to database)\n");
- fprintf(stderr, " -v | -verbose\n");
- fprintf(stderr, " -d | -nodupcheck (don't check for duplicates)\n");
- fprintf(stderr, " -db | -database host:port\n");
- exit(1);
+ fprintf(stderr, "Usage: %s [options]\n", argv[0]);
+ fprintf(stderr, "Options are\n");
+ fprintf(stderr, " -f | -file filename (default STDIN)\n");
+ fprintf(stderr, " -c | -class class (default TEMP)\n");
+ fprintf(stderr, " -C | -comment \"comment\" (default \"\")\n");
+ fprintf(stderr, " -s | -status status (default 0)\n");
+ fprintf(stderr, " -h | -shell shell (default %s)\n", DEFAULT_SHELL);
+ fprintf(stderr, " -w | -winshell windows console shell (default %s)\n",
+ DEFAULT_WINCONSOLESHELL);
+ fprintf(stderr, " -sp | -sponsor sponsor (default NONE)\n");
+ fprintf(stderr, " -e | -expiration \"expiration date\" (default \"\")\n");
+ fprintf(stderr, " -r | -reg_only\n");
+ fprintf(stderr, " -R | -register (and add to database)\n");
+ fprintf(stderr, " -v | -verbose\n");
+ fprintf(stderr, " -d | -nodupcheck (don't check for duplicates)\n");
+ fprintf(stderr, " -n | -nocaps (don't fix capitalization of names)\n");
+ fprintf(stderr, " -db | -database host:port\n");
+ exit(1);
}
-/* Called only if a query returns a value that we weren't expecting */
+/* query callback routine to check for duplicate users */
-scream()
+int usercheck(int argc, char **argv, void *qargv)
{
- fprintf(stderr, "Programmer botch\n");
- exit(3);
+ if (!strcmp(argv[U_MITID], ((char **)qargv)[U_MITID]))
+ duplicate++;
+ else
+ duplicate--;
+
+ return MR_CONT;
}
+/* query callback to get uid of a just-added account */
+int get_uid(int argc, char **argv, void *uidv)
+{
+ char *uid = uidv;
-/* query callback routine to check for duplicate users */
+ if (uid[0] == '\0')
+ strcpy(uid, argv[U_UID]);
+ else
+ {
+ if (!strcmp(argv[U_MODWITH], "addusr"))
+ strcpy(uid, argv[U_UID]);
+ }
-usercheck(argc, argv, qargv)
-int argc;
-char **argv;
-char **qargv;
+ return MR_CONT;
+}
+
+/* Parse a line of input, fetching a member. NULL is returned if a member
+ * is not found. ';' is a comment character.
+ */
+struct owner_type *parse_member(char *s)
{
- if (!strcmp(argv[U_MITID], qargv[U_MITID]))
- duplicate++;
- else
- duplicate--;
+ struct owner_type *m;
+ char *p, *lastchar;
+
+ while (*s && isspace(*s))
+ s++;
+ lastchar = p = s;
+ while (*p && *p != '\n' && *p != ';')
+ {
+ if (isprint(*p) && !isspace(*p))
+ lastchar = p++;
+ else
+ p++;
+ }
+ lastchar++;
+ *lastchar = '\0';
+ if (p == s || strlen(s) == 0)
+ return NULL;
+
+ if (!(m = malloc(sizeof(struct owner_type))))
+ return NULL;
+
+ if ((p = strchr(s, ':')))
+ {
+ *p = '\0';
+ m->name = ++p;
+ if (!strcasecmp("user", s))
+ m->type = M_USER;
+ else if (!strcasecmp("list", s))
+ m->type = M_LIST;
+ else if (!strcasecmp("kerberos", s))
+ m->type = M_KERBEROS;
+ else if (!strcasecmp("none", s))
+ m->type = M_NONE;
+ else
+ {
+ m->type = M_ANY;
+ *(--p) = ':';
+ m->name = s;
+ }
+ m->name = strdup(m->name);
+ }
+ else
+ {
+ m->name = strdup(s);
+ m->type = strcasecmp(s, "none") ? M_ANY : M_NONE;
+ }
+ return m;
}