[2032] in Moira Commits

home help back first fref pref prev next nref lref last post

/svn/moira r4174 - in trunk/moira: clients/moira clients/stanley db include man server

daemon@ATHENA.MIT.EDU (Garry Zacheiss)
Mon Jul 21 18:13:21 2014

Date: Mon, 21 Jul 2014 18:13:13 -0400
From: Garry Zacheiss <zacheiss@MIT.EDU>
Message-Id: <201407212213.s6LMDD7c027221@drugstore.mit.edu>
To: moira-commits@MIT.EDU
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: zacheiss
Date: 2014-07-21 18:13:13 -0400 (Mon, 21 Jul 2014)
New Revision: 4174

Modified:
   trunk/moira/clients/moira/defs.h
   trunk/moira/clients/moira/f_defs.h
   trunk/moira/clients/moira/menus.c
   trunk/moira/clients/moira/user.c
   trunk/moira/clients/stanley/stanley.c
   trunk/moira/db/dbopt.sql
   trunk/moira/db/schema.sql
   trunk/moira/include/moira_site.h
   trunk/moira/man/stanley.1
   trunk/moira/server/increment.pc
   trunk/moira/server/queries2.c
Log:
Implement default VPN group queries and client support, plus boolean flag for requiring 2FA for Touchstone.

Modified: trunk/moira/clients/moira/defs.h
===================================================================
--- trunk/moira/clients/moira/defs.h	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/clients/moira/defs.h	2014-07-21 22:13:13 UTC (rev 4174)
@@ -52,7 +52,7 @@
 
 /* What version of the queries are we asking for? */
 
-#define QUERY_VERSION 15
+#define QUERY_VERSION 16
 
 /* This is unimplemented in the menu stuff, but would be nice. */
 

Modified: trunk/moira/clients/moira/f_defs.h
===================================================================
--- trunk/moira/clients/moira/f_defs.h	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/clients/moira/f_defs.h	2014-07-21 22:13:13 UTC (rev 4174)
@@ -174,6 +174,8 @@
 int GetUserByReservation(int argc, char **argv);
 void PrintReservationTypes(void);
 int UserBySponsor(int argc, char **argv);
+int GetVPNGroup(int argc, char **argv);
+int SetVPNGroup(int argc, char **argv);
 
 /* printer.c */
 int GetPrn(int argc, char **argv);

Modified: trunk/moira/clients/moira/menus.c
===================================================================
--- trunk/moira/clients/moira/menus.c	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/clients/moira/menus.c	2014-07-21 22:13:13 UTC (rev 4174)
@@ -674,6 +674,24 @@
   }
 };
 
+Menu vpn_menu = {
+  NULLFUNC,
+  NULLFUNC,
+  "User VPN Group Menu",
+  2,
+  {
+    { GetVPNGroup, NULLMENU, 2, {
+	{ "get", "Get User Default VPN Group" },
+	{ "user", "User login name: " },
+    } },
+    { SetVPNGroup, NULLMENU, 3, {
+	{ "set", "Set User Default VPN Group" },
+	{ "user", "User login name: " },
+	{ "list", "List name: " },
+    } },
+  }
+};
+
 /*
  * User Menu
  */
@@ -682,7 +700,7 @@
   NULLFUNC,
   NULLFUNC,
   "User Menu",
-  12,
+  14,
   {
     {ShowUserByLogin, NULLMENU, 2, {
        {"login", "Show user information by login name"},
@@ -720,6 +738,7 @@
     SUBMENU("pobox", "Post Office Box Menu", &pobox_menu),
     SUBMENU("krbmap", "User Kerberos Mappings", &krbmap_menu),
     SUBMENU("reservations", "User Reservations Menu", &reservations_menu),
+    SUBMENU("vpn", "VPN Group Menu", &vpn_menu),
   }
 };
 

Modified: trunk/moira/clients/moira/user.c
===================================================================
--- trunk/moira/clients/moira/user.c	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/clients/moira/user.c	2014-07-21 22:13:13 UTC (rev 4174)
@@ -142,6 +142,9 @@
 	      atoi(info[U_SECURE]) ? "needs" : "does not need");
       Put_message(buf);
     }
+  sprintf(buf, "User %s two-factor authentication for Touchstone services.",
+	  atoi(info[U_TWOFACTOR]) ? "requires" : "does not require");
+  Put_message(buf);
   sprintf(buf, "Comments: %s", info[U_COMMENT]);
   Put_message(buf);
   sprintf(buf, "Created  by %s on %s.", info[U_CREATOR], info[U_CREATED]);
@@ -181,6 +184,7 @@
   info[U_MODTIME] = info[U_MODBY] = info[U_MODWITH] = info[U_END] = NULL;
   info[U_CREATED] = info[U_CREATOR] = NULL;
   info[U_AFF_BASIC] = info[U_AFF_DETAILED] = NULL;
+  info[U_TWOFACTOR] = strdup("0");
   return info;
 }
 
@@ -365,6 +369,18 @@
 	}
     }
 
+  if (YesNoQuestion("User requires two-factor authentication for Touchstone",
+		    atoi(info[U_TWOFACTOR]) ? TRUE : FALSE) == FALSE)
+    {
+      free(info[U_TWOFACTOR]);
+      info[U_TWOFACTOR] = strdup("0");
+    }
+  else
+    {
+      free(info[U_TWOFACTOR]);
+      info[U_TWOFACTOR] = strdup("1");
+    }
+
   info[U_SIGNATURE] = strdup("");
 
   FreeAndClear(&info[U_MODTIME], TRUE);
@@ -1054,6 +1070,44 @@
   return DM_NORMAL;
 }
 
+int GetVPNGroup(int argc, char **argv)
+{
+  int stat;
+  struct mqelem *elem = NULL, *top;
+  char buf[BUFSIZ];
+
+  if ((stat = do_mr_query("get_user_vpn_group", 1, &argv[1],
+                          StoreInfo, &elem)))
+    {
+      com_err(program_name, stat, " in GetVPNGroup.");
+      return DM_NORMAL;
+    }
+
+  top = elem = QueueTop(elem);
+  Put_message("");
+  while (elem)
+    {
+      char **info = elem->q_data;
+      sprintf(buf, "User: %-9s Default VPN Group: %s",
+              info[KMAP_USER], info[KMAP_PRINCIPAL]);
+      Put_message(buf);
+      elem = elem->q_forw;
+    }
+
+  FreeQueue(QueueTop(top));
+  return DM_NORMAL;
+}
+
+int SetVPNGroup(int argc, char **argv)
+{
+  int stat;
+
+  if ((stat = do_mr_query("set_user_vpn_group", 2, &argv[1],
+                          NULL, NULL)))
+    com_err(program_name, stat, " in SetVPNGroup.");
+  return DM_NORMAL;
+}
+
 int GetUserReservations(int argc, char **argv)
 {
   int stat;

Modified: trunk/moira/clients/stanley/stanley.c
===================================================================
--- trunk/moira/clients/stanley/stanley.c	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/clients/stanley/stanley.c	2014-07-21 22:13:13 UTC (rev 4174)
@@ -35,6 +35,7 @@
 /* flags from command line */
 int info_flag, update_flag, create_flag, deact_flag, reg_flag;
 int list_res_flag, update_res_flag, unformatted_flag, verbose, noauth;
+int list_vpn_group_flag, set_vpn_group_flag;
 
 int count;
 
@@ -45,7 +46,7 @@
 
 char *newlogin, *uid, *shell, *winshell, *last, *first, *middle, *u_status;
 char *clearid, *class, *comment, *secure, *winhomedir, *winprofiledir, *expiration;
-char *alternate_email, *alternate_phone;
+char *alternate_email, *alternate_phone, *twofactor_enabled, *vpn_group;
 
 static char *states[] = {
   "Registerable (0)",
@@ -77,6 +78,7 @@
 
 void usage(char **argv);
 int save_query_info(int argc, char **argv, void *hint);
+int show_vpn_group(int argc, char **argv, void *hint);
 int show_reservations(int argc, char **argv, void *hint);
 int show_user_info(int argc, char **argv, void *hint);
 int show_user_info_unformatted(int argc, char **argv, void *hint);
@@ -94,9 +96,11 @@
   /* clear all flags & lists */
   info_flag = update_flag = create_flag = deact_flag = reg_flag = 0;
   list_res_flag = update_res_flag = unformatted_flag = verbose = noauth = 0;
+  list_vpn_group_flag = set_vpn_group_flag = 0;
   newlogin = uid = shell = winshell = last = first = middle = NULL;
   u_status = clearid = class = comment = secure = NULL;
   winhomedir = winprofiledir = expiration = alternate_email = alternate_phone = NULL;
+  twofactor_enabled = vpn_group = NULL;
   reservation_add_queue = reservation_remove_queue = NULL;
   sponsor = NULL;
   whoami = argv[0];
@@ -273,6 +277,25 @@
 	    } else
 	      usage(argv);
 	  }
+	  else if (argis("2fa", "twofactor")) {
+	    if (arg - argv < argc - 1) {
+	      arg++;
+	      update_flag++;
+	      twofactor_enabled = *arg;
+	    } else 
+	      usage(argv);
+	  }
+	  else if (argis("lv", "listvpn")) {
+	    list_vpn_group_flag++;
+	  }
+	  else if (argis("sv", "setvpn")) {
+	    if (arg - argv < argc - 1) {
+	      arg++;
+	      vpn_group = *arg;
+	    } else
+	      usage(argv);
+	    set_vpn_group_flag++;
+	  }
 	  else if (argis("ar", "addreservation")) {
 	    if (arg - argv < argc - 1) {
 	      arg++;
@@ -322,12 +345,12 @@
   /* default to info_flag if nothing else was specified */
   if(!(info_flag       || update_flag || create_flag   || \
        deact_flag      || reg_flag    || list_res_flag || \
-       update_res_flag)) {
+       update_res_flag || list_vpn_group_flag || set_vpn_group_flag)) {
     info_flag++;
   }
 
   /* fire up Moira */
-  status = mrcl_connect(server, "stanley", 15, !noauth);
+  status = mrcl_connect(server, "stanley", 16, !noauth);
   if (status == MRCL_AUTH_ERROR)
     {
       com_err(whoami, 0, "Try the -noauth flag if you don't "
@@ -426,6 +449,10 @@
         argv[U_ALT_EMAIL] = alternate_email;
       if (alternate_phone)
         argv[U_ALT_PHONE] = alternate_phone;
+      if (twofactor_enabled)
+	argv[U_TWOFACTOR] = twofactor_enabled;
+      else
+	argv[U_TWOFACTOR] = "0";
       if (sponsor)
 	{
 	  argv[U_SPONSOR_NAME] = sponsor->name;
@@ -434,13 +461,13 @@
 	    case MRCL_M_ANY:
 	    case MRCL_M_USER:
 	      argv[U_SPONSOR_TYPE] = "USER";
-	      status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
+	      status = wrap_mr_query("add_user_account", 21, argv, NULL, NULL);
 	      if (sponsor->type != MRCL_M_ANY || status != MR_USER)
 		break;
 
 	    case MRCL_M_LIST:
 	      argv[U_SPONSOR_TYPE] = "LIST";
-	      status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
+	      status = wrap_mr_query("add_user_account", 21, argv, NULL, NULL);
 	      break;
 
 	    case MRCL_M_KERBEROS:
@@ -451,12 +478,12 @@
 		mrcl_com_err(whoami);
 	      if (status == MRCL_REJECT)
 		exit(1);
-	      status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
+	      status = wrap_mr_query("add_user_account", 21, argv, NULL, NULL);
 	      break;
 
 	    case MRCL_M_NONE:
 	      argv[U_SPONSOR_TYPE] = "NONE";
-	      status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
+	      status = wrap_mr_query("add_user_account", 21, argv, NULL, NULL);
 	      break;
 	    }
 	}
@@ -465,7 +492,7 @@
 	  argv[U_SPONSOR_TYPE] = "NONE";
 	  argv[U_SPONSOR_NAME] = "NONE";
 	  
-	  status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
+	  status = wrap_mr_query("add_user_account", 21, argv, NULL, NULL);
 	}
 
       if (status)
@@ -510,6 +537,7 @@
       argv[18] = old_argv[17];
       argv[19] = old_argv[18];
       argv[20] = old_argv[19];
+      argv[21] = old_argv[20];
 
       argv[0] = username;
       if (newlogin)
@@ -546,6 +574,8 @@
 	argv[19] = alternate_email;
       if (alternate_phone)
 	argv[20] = alternate_phone;
+      if (twofactor_enabled)
+	argv[21] = twofactor_enabled;
       if (sponsor)
 	{
 	  argv[17] = sponsor->name;
@@ -554,14 +584,14 @@
 	    case MRCL_M_ANY:
 	    case MRCL_M_USER:
 	      argv[16] = "USER";
-	      status = wrap_mr_query("update_user_account", 21, argv, NULL, 
+	      status = wrap_mr_query("update_user_account", 22, argv, NULL, 
 				     NULL);
 	      if (sponsor->type != MRCL_M_ANY || status != MR_USER)
 		break;
 
 	    case MRCL_M_LIST:
 	      argv[16] = "LIST";
-	      status = wrap_mr_query("update_user_account", 21, argv, NULL,
+	      status = wrap_mr_query("update_user_account", 22, argv, NULL,
 				     NULL);
 	      break;
 
@@ -572,19 +602,19 @@
 		mrcl_com_err(whoami);
 	      if (status == MRCL_REJECT)
 		exit(1);
-	      status = wrap_mr_query("update_user_account", 21, argv, NULL,
+	      status = wrap_mr_query("update_user_account", 22, argv, NULL,
 				     NULL);
 	      break;
 
 	    case MRCL_M_NONE:
 	      argv[16] = "NONE";
-	      status = wrap_mr_query("update_user_account", 21, argv, NULL,
+	      status = wrap_mr_query("update_user_account", 22, argv, NULL,
 				     NULL);
 	      break;
 	    }
 	}
       else
-	status = wrap_mr_query("update_user_account", 21, argv, NULL, NULL);
+	status = wrap_mr_query("update_user_account", 22, argv, NULL, NULL);
 
       if (status)
 	com_err(whoami, status, "while updating user.");
@@ -767,6 +797,39 @@
 	  q = q->next;
 	}
     }
+
+
+  /* list user default vpn group */
+  if (list_vpn_group_flag)
+    {
+      char *args[1];
+
+      args[0] = username;
+      status = wrap_mr_query("get_user_vpn_group", 1, args,
+			     show_vpn_group, NULL);
+      if (status)
+	{
+	  com_err(whoami, status, "while getting user vpn group.");
+	  exit(1);
+	}
+    }
+
+  if (set_vpn_group_flag)
+    {
+      char *args[2];
+
+      args[0] = username;
+      args[1] = vpn_group;
+
+      status = wrap_mr_query("set_user_vpn_group", 2, args,
+			     NULL, NULL);
+      if (status)
+	{
+	  com_err(whoami, status, "while setting user vpn group.");
+	  exit(1);
+	}
+    }
+
   /* We're done! */
   mr_disconnect();
   exit(0);
@@ -791,6 +854,13 @@
   return MR_CONT;
 }
 
+int show_vpn_group(int argc, char **argv, void *hint)
+{
+  printf("Login: %s, Default VPN group: %s\n", argv[0], argv[1]);
+
+  return MR_CONT;
+}
+
 struct string_list *add_to_string_list(struct string_list *old_list, char *s) {
   struct string_list *new_list;
 
@@ -845,6 +915,8 @@
       printf("User %s secure Account Coupon to register\n",
 	      atoi(argv[U_SECURE]) ? "needs" : "does not need");
     }
+  printf("User %s two-factor authentication for Touchstone services.\n",
+	 atoi(argv[U_TWOFACTOR]) ? "requires" : "does not require");
   printf("Comments: %s\n", argv[U_COMMENT]);
   printf("Created  by %s on %s.\n", argv[U_CREATOR], argv[U_CREATED]);
   printf("Last mod by %s at %s with %s.\n", argv[U_MODBY], argv[U_MODTIME],
@@ -881,6 +953,8 @@
   if (status == 0 || status == 2)
     printf("Secure:                  %s secure Account Coupon to register\n",
 	   atoi(argv[U_SECURE]) ? "Needs" : "Does not need");
+  printf("Two-factor:                %s two-factor authentication for Touchstone services\n",
+	 atoi(argv[U_TWOFACTOR]) ? "requires" : "does not require");
   printf("Comments:                  %s\n", argv[U_COMMENT]);
   printf("Created by:                %s\n", argv[U_CREATOR]);
   printf("Created on:                %s\n", argv[U_CREATED]);
@@ -896,35 +970,37 @@
 #define USAGE_OPTIONS_FORMAT "  %-39s%s\n"
   fprintf(stderr, "Usage: %s username [options]\n", argv[0]);
   fprintf(stderr, "Options are\n");
-  fprintf(stderr, "  %-39s\n", "-i   | -info");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-C   | -create",
-          "-D   | -deact");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-r   | -register",
-	  "-R   | -rename newname");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-U   | -uid uid",
-	  "-s   | -shell shell");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-S   | -status status",
-	  "-w   | -winshell winshell");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-F   | -first firstname",
-	  "-L   | -last lastname");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-M   | -middle middlename",
-	  "-I   | -mitid mitid");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-cl  | -class class",
-	  "-c   | -comment comment");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-6   | -secure 0|1",
-	  "-lr  | -listreservation");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-ar  | -addreservation reservation",
-	  "-dr  | -deletereservation reservation");
-  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-wh  | -winhomedir winhomedir",
-	  "-wp  | -winprofiledir winprofiledir");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-i   | -info",
+	  "-C   | -create");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-D   | -deact",
+	  "-r   | -register");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-R   | -rename newname",
+	  "-U   | -uid uid");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-s   | -shell shell",
+	  "-S   | -status status");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-w   | -winshell winshell",
+	  "-F   | -first firstname");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-L   | -last lastname",
+	  "-M   | -middle middlename");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-I   | -mitid mitid",
+	  "-cl  | -class class");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-c   | -comment comment",
+	  "-6   | -secure 0|1");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-lr  | -listreservation",
+	  "-ar  | -addreservation reservation");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-dr  | -deletereservation reservation",
+	  "-wh  | -winhomedir winhomedir");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-wp  | -winprofiledir winprofiledir",
+	  "-2fa | -twofactor 0|1");
   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-sp  | -sponsor sponsor",
 	  "-e   | -expiration expiration date");
   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-ae  | -alternateemail address",
 	  "-ap  | -alternatephone phone number");
+  fprintf(stderr, USAGE_OPTIONS_FORMAT, "-lv  | -listvpn",
+          "-sv  | -setvpn listname");
   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-u   | -unformatted",
           "-n   | -noauth");
   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-v   | -verbose",
 	  "-db  | -database host[:port]");
-
   exit(1);
 }

Modified: trunk/moira/db/dbopt.sql
===================================================================
--- trunk/moira/db/dbopt.sql	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/db/dbopt.sql	2014-07-21 22:13:13 UTC (rev 4174)
@@ -9,6 +9,8 @@
 create index i_usr_clearid on users (clearid);
 create index i_usr_resv on users (reservations);
 create index i_usr_sponsor on users (sponsor_id);
+create index i_usr_vpn_group on users (default_vpn_group);
+create index i_usr_twofactor on users (twofactor_enabled);
 
 create unique index i_krb_usid on krbmap  (users_id);
 create index i_krb_str on  krbmap (string_id);

Modified: trunk/moira/db/schema.sql
===================================================================
--- trunk/moira/db/schema.sql	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/db/schema.sql	2014-07-21 22:13:13 UTC (rev 4174)
@@ -59,7 +59,9 @@
 	alternate_phone	VARCHAR(24)	DEFAULT CHR(0)	NOT NULL,
 	affiliation_basic	VARCHAR(10)	DEFAULT 'affiliate'	NOT NULL,
 	affiliation_detailed	VARCHAR(40)	DEFAULT 'MIT Affiliate'	NOT NULL,
-	last_krb_pwd_change	DATE		DEFAULT SYSDATE		NOT NULL
+	last_krb_pwd_change	DATE		DEFAULT SYSDATE		NOT NULL,
+	default_vpn_group	INTEGER		DEFAULT 0		NOT NULL,
+	twofactor_enabled	INTEGER		DEFAULT 0		NOT NULL
 );
 
 create table krbmap

Modified: trunk/moira/include/moira_site.h
===================================================================
--- trunk/moira/include/moira_site.h	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/include/moira_site.h	2014-07-21 22:13:13 UTC (rev 4174)
@@ -383,14 +383,15 @@
 #define U_EXPIRATION 17
 #define U_ALT_EMAIL 18
 #define U_ALT_PHONE 19
-#define U_AFF_BASIC 20
-#define U_AFF_DETAILED 21
-#define U_MODTIME 22
-#define U_MODBY   23
-#define U_MODWITH 24
-#define U_CREATED 25
-#define U_CREATOR 26
-#define U_END     27
+#define U_TWOFACTOR 20
+#define U_AFF_BASIC 21
+#define U_AFF_DETAILED 22
+#define U_MODTIME 23
+#define U_MODBY   24
+#define U_MODWITH 25
+#define U_CREATED 26
+#define U_CREATOR 27
+#define U_END     28
 
 /* User states (the value of argv[U_STATE] from a user query) */
 

Modified: trunk/moira/man/stanley.1
===================================================================
--- trunk/moira/man/stanley.1	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/man/stanley.1	2014-07-21 22:13:13 UTC (rev 4174)
@@ -57,6 +57,9 @@
 .IP \fB-secure\ \fI0|1\ \fRor\ \fB-6\ \fI0|1\fR
 Change whether a user requires a secure Account Coupon to register for
 an account.
+.IP \fB-twofactor\ \fI0|1\ \fRor\ \fB-2fa\ \fI0|1\fR
+Change whether a user requires two-factor authentication when
+authenticating to a Touchstone service.
 
 .IP \fB-sponsor\ \fIsponsor\ \fRor\ \fB-sp\ \fIsponsor\fR
 Set the sponsor of the specified user to \fIsponsor\fR.  This field is
@@ -66,6 +69,11 @@
 field is intended to be used for accounts in the GUEST and VOUCH
 classes.
 
+.IP \fB-listvpn\ \fRor\ \fB-lv\fR
+Display the default VPN group for the specified user.
+.IP \fB-setvpn\ \fIlistname\ \fRor\ \fB-sv\ \fIlistname\fR
+Set the default VPN group for the user to the specified list.
+
 .IP \fB-unformatted\ \fRor\ \fB-u\fR
 Display user information with each field on a seperate line, in the 
 form "fieldname: value".
@@ -101,7 +109,7 @@
 accounts after being registered.
 
 .SH AUTHORS
-Garry Zacheiss, MIT Information Systems.
+Garry Zacheiss, MIT Information Systems & Technology.
 .SH SEE ALSO
 moira(1)
 

Modified: trunk/moira/server/increment.pc
===================================================================
--- trunk/moira/server/increment.pc	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/server/increment.pc	2014-07-21 22:13:13 UTC (rev 4174)
@@ -91,9 +91,9 @@
       sprintf(stmt_buf, "SELECT u.login, u.unix_uid, u.shell, "
 	      "u.winconsoleshell, u.last, u.first, u.middle, u.status, "
 	      "u.clearid, u.type, u.users_id, u.winhomedir, u.winprofiledir, "
-	      "u.potype FROM users u WHERE %s", qual);
+	      "u.potype, u.twofactor_enabled FROM users u WHERE %s", qual);
       dosql(before);
-      beforec = 14;
+      beforec = 15;
       break;
     case MACHINE_TABLE:
       sprintf(stmt_buf, "SELECT m.name, m.mach_id, m.vendor, m.model, m.os, m.location, "
@@ -322,9 +322,9 @@
       sprintf(stmt_buf, "SELECT u.login, u.unix_uid, u.shell, "
 	      "u.winconsoleshell, u.last, u.first, u.middle, u.status, "
 	      "u.clearid, u.type, u.users_id, u.winhomedir, u.winprofiledir, "
-	      "u.potype FROM users u WHERE %s", qual);
+	      "u.potype, u.twofactor_enabled FROM users u WHERE %s", qual);
       dosql(after);
-      afterc = 14;
+      afterc = 15;
       break;
     case MACHINE_TABLE:
       sprintf(stmt_buf, "SELECT m.name, m.mach_id, m.vendor, m.model, m.os, m.location, "

Modified: trunk/moira/server/queries2.c
===================================================================
--- trunk/moira/server/queries2.c	2014-07-21 17:55:18 UTC (rev 4173)
+++ trunk/moira/server/queries2.c	2014-07-21 22:13:13 UTC (rev 4174)
@@ -119,7 +119,7 @@
   "alternate_email", "alternate_phone", "modtime", "modby", "modwith", "created", "creator",
 };
 
-static char *gual_fields[] = {
+static char *gual15_fields[] = {
   "login",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -128,6 +128,15 @@
   "modtime", "modby", "modwith", "created", "creator",
 };
 
+static char *gual_fields[] = {
+  "login",
+  "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
+  "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+  "alternate_email", "alternate_phone", "twofactor_enabled",
+  "affiliation_basic", "affiliation_detailed", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static char *gubl2_fields[] = {
   "login",
   "login", "unix_uid", "shell", "last", "first", "middle", "status",
@@ -223,7 +232,7 @@
   "alternate_email", "alternate_phone", "modtime", "modby", "modwith", "created", "creator",
 };
 
-static char *guau_fields[] = {
+static char *guau15_fields[] = {
   "unix_uid",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -232,6 +241,15 @@
   "modtime", "modby", "modwith", "created", "creator",
 };
 
+static char *guau_fields[] = {
+  "unix_uid",
+  "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
+  "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+  "alternate_email", "alternate_phone", "twofactor_enabled",
+  "affiliation_basic", "affiliation_detailed", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static char *guan2_fields[] = {
   "first", "last",
   "login", "unix_uid", "shell", "last", "first", "middle", "status",
@@ -270,7 +288,7 @@
   "alternate_email", "alternate_phone", "modtime", "modby", "modwith", "created", "creator",
 };
 
-static char *guan_fields[] = {
+static char *guan15_fields[] = {
   "first", "last",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -279,6 +297,15 @@
   "modtime", "modby", "modwith", "created", "creator",
 };
 
+static char *guan_fields[] = {
+  "first", "last",
+  "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
+  "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+  "alternate_email", "alternate_phone", "twofactor_enabled", 
+  "affiliation_basic", "affiliation_detailed", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static struct validate guan2_validate =
 {
   0,
@@ -343,7 +370,7 @@
   "alternate_email", "alternate_phone", "modtime", "modby", "modwith", "created", "creator",
 };
 
-static char *guac_fields[] = {
+static char *guac15_fields[] = {
   "class",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -352,6 +379,15 @@
   "modtime", "modby", "modwith", "created", "creator",
 };
 
+static char *guac_fields[] = {
+  "class",
+  "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
+  "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+  "alternate_email", "alternate_phone", "twofactor_enabled", 
+  "affiliation_basic", "affiliation_detailed", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static char *guam2_fields[] = {
   "clearid",
   "login", "unix_uid", "shell", "last", "first", "middle", "status",
@@ -390,7 +426,7 @@
   "alternate_email", "alternate_phone", "modtime", "modby", "modwith", "created", "creator",
 };
 
-static char *guam_fields[] = {
+static char *guam15_fields[] = {
   "clearid",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -399,6 +435,15 @@
   "modtime", "modby", "modwith", "created", "creator",
 };
 
+static char *guam_fields[] = {
+  "clearid",
+  "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
+  "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+  "alternate_email", "alternate_phone", "twofactor_enabled",
+  "affiliation_basic", "affiliation_detailed", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static char *guas_fields[] = {
   "sponsor_type", "sponsor_name",
   "login",
@@ -547,13 +592,20 @@
   "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
 };
 
-static char *auac_fields[] = {
+static char *auac14_fields[] = {
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
   "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
   "alternate_email", "alternate_phone",
 };
 
+static char *auac_fields[] = {
+  "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
+  "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+  "alternate_email", "alternate_phone", "twofactor_enabled",
+};
+
 static struct valobj auac2_valobj[] = {
   {V_CHAR, 0, USERS_TABLE, "login"},
   {V_NUM, 1},
@@ -620,6 +672,28 @@
   {V_CHAR, 17, USERS_TABLE, "expiration"},
 };
 
+static struct valobj auac14_valobj[] = {
+  {V_CHAR, 0, USERS_TABLE, "login"},
+  {V_NUM, 1},
+  {V_CHAR, 2, USERS_TABLE, "shell"},
+  {V_CHAR, 3, USERS_TABLE, "winconsoleshell"},
+  {V_CHAR, 4, USERS_TABLE, "last"},
+  {V_CHAR, 5, USERS_TABLE, "first"},
+  {V_CHAR, 6, USERS_TABLE, "middle"},
+  {V_NUM, 7},
+  {V_CHAR, 8, USERS_TABLE, "clearid"},
+  {V_TYPE, 9, 0, "class", 0, MR_BAD_CLASS},
+  {V_ID, 10, STRINGS_TABLE, "string", "string_id", MR_NO_MATCH},
+  {V_NUM, 12},
+  {V_LEN, 13, USERS_TABLE, "winhomedir"},
+  {V_LEN, 14, USERS_TABLE, "winprofiledir"},
+  {V_TYPE, 15, 0, "ace_type", 0, MR_ACE},
+  {V_TYPEDATA, 16, 0, 0, "list_id", MR_ACE},
+  {V_CHAR, 17, USERS_TABLE, "expiration"},
+  {V_CHAR, 18, USERS_TABLE, "alternate_email"},
+  {V_CHAR, 19, USERS_TABLE, "alternate_phone"},
+};
+
 static struct valobj auac_valobj[] = {
   {V_CHAR, 0, USERS_TABLE, "login"},
   {V_NUM, 1},
@@ -640,6 +714,7 @@
   {V_CHAR, 17, USERS_TABLE, "expiration"},
   {V_CHAR, 18, USERS_TABLE, "alternate_email"},
   {V_CHAR, 19, USERS_TABLE, "alternate_phone"},
+  {V_NUM, 20},
 };
 
 static struct validate auac2_validate = {
@@ -690,9 +765,21 @@
   followup_ausr,
 };
 
+static struct validate auac14_validate = {
+  auac14_valobj,
+  19,
+  "login",
+  "login = '%s'",
+  1,
+  "users_id",
+  0,
+  setup_ausr,
+  followup_ausr,
+};
+
 static struct validate auac_validate = {
   auac_valobj,
-  19,
+  20,
   "login",
   "login = '%s'",
   1,
@@ -750,9 +837,21 @@
   followup_ausr,
 };
 
+static struct validate ausr14_validate = {
+  auac14_valobj,
+  17,
+  "login",
+  "login = '%s'",
+  1,
+  "users_id",
+  0,
+  setup_ausr,
+  followup_ausr,
+};
+
 static struct validate ausr_validate = {
   auac_valobj,
-  17,
+  18,
   "login",
   "login = '%s'",
   1,
@@ -809,7 +908,7 @@
   "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
 };
 
-static char *uuac_fields[] = {
+static char *uuac14_fields[] = {
   "login",
   "newlogin", "unix_uid", "shell", "winconsoleshell", "last", "first",
   "middle", "status", "clearid", "class", "comments", "signature", "secure",
@@ -817,6 +916,14 @@
   "alternate_email", "alternate_phone",
 };
 
+static char *uuac_fields[] = {
+  "login",
+  "newlogin", "unix_uid", "shell", "winconsoleshell", "last", "first",
+  "middle", "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+  "alternate_email", "alternate_phone", "twofactor_enabled",
+};
+
 static struct valobj uuac2_valobj[] = {
   {V_ID, 0, USERS_TABLE, "login", "users_id", MR_USER},
   {V_RENAME, 1, USERS_TABLE, "login", "users_id", MR_NOT_UNIQUE},
@@ -887,6 +994,29 @@
   {V_CHAR, 18, USERS_TABLE, "expiration"},
 };
 
+static struct valobj uuac14_valobj[] = {
+  {V_ID, 0, USERS_TABLE, "login", "users_id", MR_USER},
+  {V_RENAME, 1, USERS_TABLE, "login", "users_id", MR_NOT_UNIQUE},
+  {V_NUM, 2},
+  {V_CHAR, 3, USERS_TABLE, "shell"},
+  {V_CHAR, 4, USERS_TABLE, "winconsoleshell"},
+  {V_CHAR, 5, USERS_TABLE, "first"},
+  {V_CHAR, 6, USERS_TABLE, "last"},
+  {V_CHAR, 7, USERS_TABLE, "middle"},
+  {V_NUM, 8},
+  {V_CHAR, 9, USERS_TABLE, "clearid"},
+  {V_TYPE, 10, 0, "class", 0, MR_BAD_CLASS},
+  {V_ID, 11, STRINGS_TABLE, "string", "string_id", MR_NO_MATCH},
+  {V_NUM, 13},
+  {V_LEN, 14, USERS_TABLE, "winhomedir"},
+  {V_LEN, 15, USERS_TABLE, "winprofiledir"},
+  {V_TYPE, 16, 0, "ace_type", 0, MR_ACE},
+  {V_TYPEDATA, 17, 0, 0, "list_id", MR_ACE},
+  {V_CHAR, 18, USERS_TABLE, "expiration"},
+  {V_CHAR, 19, USERS_TABLE, "alternate_email"},
+  {V_CHAR, 20, USERS_TABLE, "alternate_phone"},
+};
+
 static struct valobj uuac_valobj[] = {
   {V_ID, 0, USERS_TABLE, "login", "users_id", MR_USER},
   {V_RENAME, 1, USERS_TABLE, "login", "users_id", MR_NOT_UNIQUE},
@@ -908,6 +1038,7 @@
   {V_CHAR, 18, USERS_TABLE, "expiration"},
   {V_CHAR, 19, USERS_TABLE, "alternate_email"},
   {V_CHAR, 20, USERS_TABLE, "alternate_phone"},
+  {V_NUM, 21},
 };
 
 static struct validate uuac2_validate = {
@@ -958,6 +1089,18 @@
   set_modtime_by_id,
 };
 
+static struct validate uuac14_validate = {
+  uuac14_valobj,
+  20,
+  0,
+  0,
+  0,
+  "users_id",
+  access_update_user,
+  setup_ausr,
+  set_modtime_by_id,
+};
+
 static struct validate uuac_validate = {
   uuac_valobj,
   20,
@@ -1018,9 +1161,21 @@
   set_modtime_by_id,
 };
 
+static struct validate uusr14_validate = {
+  uuac14_valobj,
+  18,
+  0,
+  0,
+  0,
+  "users_id",
+  0,
+  setup_ausr,
+  set_modtime_by_id,
+};
+
 static struct validate uusr_validate = {
   uuac_valobj,
-  18,
+  19,
   0,
   0,
   0,
@@ -1129,6 +1284,33 @@
   "pin",
 };
 
+static char *suvg_fields[] = {
+  "login",
+  "listname",
+};
+
+static struct valobj suvg_valobj[] = {
+  {V_ID, 0, USERS_TABLE, "login", "users_id", MR_USER},
+  {V_ID, 1, LIST_TABLE, "name", "list_id", MR_LIST},
+};
+
+static struct validate suvg_validate = {
+  suvg_valobj,
+  2,
+  0,
+  0,
+  0,
+  "users_id",
+  0,
+  0,
+  set_modtime_by_id,
+};
+
+static char *guvg_fields[] = {
+  "login",
+  "login", "listname",
+};
+
 static char *dusr_fields[] = {
   "login",
 };
@@ -4693,7 +4875,7 @@
     "u",
     USERS_TABLE,
     "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
-    gual_fields,
+    gual15_fields,
     28,
     27,
     "u.login LIKE '%s' AND u.users_id != 0 AND u.comments = str.string_id",
@@ -4703,6 +4885,24 @@
   },
 
   {
+    /* Q_GUAL - GET_USER_ACCOUNT_BY_LOGIN, v16 */
+    "get_user_account_by_login",
+    "gual",
+    16,
+    MR_Q_RETRIEVE,
+    "u",
+    USERS_TABLE,
+    "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.twofactor_enabled, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
+    gual_fields,
+    29,
+    28,
+    "u.login LIKE '%s' AND u.users_id != 0 AND u.comments = str.string_id",
+    1,
+    "u.login",
+    &gubl_validate,
+  },
+
+  {
     /* Q_GUAU - GET_USER_ACCOUNT_BY_UID, v2 */
     "get_user_account_by_uid",
     "guau",
@@ -4801,7 +5001,7 @@
     "u",
     USERS_TABLE,
     "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
-    guau_fields,
+    guau15_fields,
     28,
     27,
     "u.unix_uid = %s AND u.users_id != 0 AND u.comments = str.string_id",
@@ -4811,6 +5011,24 @@
   },
 
   {
+    /* Q_GUAU - GET_USER_ACCOUNT_BY_UID, v16 */
+    "get_user_account_by_uid",
+    "guau",
+    16,
+    MR_Q_RETRIEVE,
+    "u",
+    USERS_TABLE,
+    "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.twofactor_enabled, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
+    guau_fields,
+    29,
+    28,
+    "u.unix_uid = %s AND u.users_id != 0 AND u.comments = str.string_id",
+    1,
+    "u.login",
+    &gubu_validate,
+  },
+
+  {
     /* Q_GUAN - GET_USER_ACCOUNT_BY_NAME, v2 */
     "get_user_account_by_name",
     "guan",
@@ -4909,7 +5127,7 @@
     "u",
     USERS_TABLE,
     "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
-    guan_fields,
+    guan15_fields,
     29,
     27,
     "u.first LIKE '%s' AND u.last LIKE '%s' AND u.users_id != 0 and u.comments = str.string_id",
@@ -4919,6 +5137,24 @@
   },
 
   {
+    /* Q_GUAN - GET_USER_ACCOUNT_BY_NAME, v16 */
+    "get_user_account_by_name",
+    "guan",
+    16,
+    MR_Q_RETRIEVE,
+    "u",
+    USERS_TABLE,
+    "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.twofactor_enabled, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
+    guan_fields,
+    30,
+    28,
+    "u.first LIKE '%s' AND u.last LIKE '%s' AND u.users_id != 0 and u.comments = str.string_id",
+    2,
+    "u.login",
+    &guan_validate,
+  },
+
+  {
     /* Q_GUAC - GET_USER_ACCOUNT_BY_CLASS, v2 */
     "get_user_account_by_class",
     "guac",
@@ -5017,7 +5253,7 @@
     "u",
     USERS_TABLE,
     "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
-    guac_fields,
+    guac15_fields,
     28,
     27,
     "u.type = UPPER('%s') AND u.users_id != 0 AND u.comments = str.string_id",
@@ -5027,6 +5263,24 @@
   },
 
   {
+    /* Q_GUAC - GET_USER_ACCOUNT_BY_CLASS, v16 */
+    "get_user_account_by_class",
+    "guac",
+    16,
+    MR_Q_RETRIEVE,
+    "u",
+    USERS_TABLE,
+    "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.twofactor_enabled, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
+    guac_fields,
+    29,
+    28,
+    "u.type = UPPER('%s') AND u.users_id != 0 AND u.comments = str.string_id",
+    1,
+    "u.login",
+    &guan_validate,
+  },
+
+  {
     /* Q_GUAM - GET_USER_ACCOUNT_BY_MITID, v2 */
     "get_user_account_by_id",
     "guai",
@@ -5125,7 +5379,7 @@
     "u",
     USERS_TABLE,
     "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
-    guam_fields,
+    guam15_fields,
     28,
     27,
     "u.clearid LIKE '%s' AND u.users_id != 0 AND u.comments = str.string_id",
@@ -5135,6 +5389,24 @@
   },
 
   {
+    /* Q_GUAM - GET_USER_ACCOUNT_BY_MITID, v16 */
+    "get_user_account_by_id",
+    "guai",
+    16,
+    MR_Q_RETRIEVE,
+    "u",
+    USERS_TABLE,
+    "u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last, u.first, u.middle, u.status, u.clearid, u.type, str.string, CHR(0), u.secure, u.winhomedir, u.winprofiledir, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email, u.alternate_phone, u.twofactor_enabled, u.affiliation_basic, u.affiliation_detailed, TO_CHAR(u.modtime, 'DD-mon-YYYY HH24:MI:SS'), u.modby, u.modwith, TO_CHAR(u.created, 'DD-mon-YYYY HH24:MI:SS'), u.creator FROM users u, strings str",
+    guam_fields,
+    29,
+    28,
+    "u.clearid LIKE '%s' AND u.users_id != 0 AND u.comments = str.string_id",
+    1,
+    "u.login",
+    &guan_validate,
+  },
+
+  {
     /* Q_GUAS - GET_USER_ACCOUNT_BY_SPONSOR, v12 */
     "get_user_account_by_sponsor",
     "guas",
@@ -5428,12 +5700,33 @@
      * but using up one argv element.
      */
     "INTO users (login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type, comments, signature, secure, winhomedir, winprofiledir, sponsor_type, sponsor_id, expiration, alternate_email, alternate_phone, users_id, created, creator) VALUES ('%s', %s, '%s', NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, NVL('%s', CHR(0)), '%s', %d, NVL(CHR(0), '%s'), %s, NVL('%s', CHR(0)), NVL('%s', CHR(0)), '%s', %d, NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, SYSDATE, %s)",
-    auac_fields,
+    auac14_fields,
     20,
     20,
     NULL,
     0,
     NULL,
+    &auac14_validate,
+  },
+
+  {
+    /* Q_AUAC - ADD_USER_ACCOUNT, v16 */  /* uses prefetch_value() for users_id */
+    "add_user_account",
+    "auac",
+    16,
+    MR_Q_APPEND,
+    "u",
+    USERS_TABLE,
+    /* We set signature to "NVL(CHR(0), '%s')", which is to say, "CHR(0)",
+     * but using up one argv element.
+     */
+    "INTO users (login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type, comments, signature, secure, winhomedir, winprofiledir, sponsor_type, sponsor_id, expiration, alternate_email, alternate_phone, twofactor_enabled, users_id, created, creator) VALUES ('%s', %s, '%s', NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, NVL('%s', CHR(0)), '%s', %d, NVL(CHR(0), '%s'), %s, NVL('%s', CHR(0)), NVL('%s', CHR(0)), '%s', %d, NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, %s, SYSDATE, %s)",
+    auac_fields,
+    21,
+    21,
+    NULL,
+    0,
+    NULL,
     &auac_validate,
   },
 
@@ -5518,12 +5811,30 @@
     "u",
     USERS_TABLE,
     "INTO users (login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type, comments, signature, secure, winhomedir, winprofiledir, sponsor_type, sponsor_id, expiration, alternate_email, alternate_phone, users_id, created, creator) VALUES ('%s', %s, '%s', NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, NVL('%s', CHR(0)), '%s', 0, CHR(0), 0, NVL('%s', CHR(0)), NVL('%s', CHR(0)), '%s', %d, NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, SYSDATE, %s)",
-    auac_fields,
+    auac14_fields,
     17,
     17,
     0,
     0,
     NULL,
+    &ausr14_validate,
+  },
+
+  {
+    /* Q_AUSR - ADD_USER, v16 */  /* uses prefetch_value() for users_id */
+    "add_user",
+    "ausr",
+    16,
+    MR_Q_APPEND,
+    "u",
+    USERS_TABLE,
+    "INTO users (login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type, comments, signature, secure, winhomedir, winprofiledir, sponsor_type, sponsor_id, expiration, alternate_email, alternate_phone, twofactor_enabled, users_id, created, creator) VALUES ('%s', %s, '%s', NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, NVL('%s', CHR(0)), '%s', 0, CHR(0), 0, NVL('%s', CHR(0)), NVL('%s', CHR(0)), '%s', %d, NVL('%s', CHR(0)), NVL('%s', CHR(0)), NVL('%s', CHR(0)), %s, %s, SYSDATE, %s)",
+    auac_fields,
+    18,
+    18,
+    0,
+    0,
+    NULL,
     &ausr_validate,
   },
 
@@ -5631,12 +5942,31 @@
     USERS_TABLE,
     /* See comment in auac about signature. */
     "users SET login = '%s', unix_uid = %s, shell = '%s', winconsoleshell = '%s', last = NVL('%s', CHR(0)), first = NVL('%s', CHR(0)), middle = NVL('%s', CHR(0)), status = %s, clearid = NVL('%s', CHR(0)), type = '%s', comments = %d, signature = NVL(CHR(0), '%s'), secure = %s, winhomedir = NVL('%s', CHR(0)), winprofiledir = NVL('%s', CHR(0)), sponsor_type = '%s', sponsor_id = %d, expiration = NVL('%s', CHR(0)), alternate_email = NVL('%s', CHR(0)), alternate_phone = NVL('%s', CHR(0))",
-    uuac_fields,
+    uuac14_fields,
     21,
     20,
     "users_id = %d",
     1,
     NULL,
+    &uuac14_validate,
+  },
+
+  {
+    /* Q_UUAC - UPDATE_USER_ACCOUNT, v16 */
+    "update_user_account",
+    "uuac",
+    16,
+    MR_Q_UPDATE,
+    "u",
+    USERS_TABLE,
+    /* See comment in auac about signature. */
+    "users SET login = '%s', unix_uid = %s, shell = '%s', winconsoleshell = '%s', last = NVL('%s', CHR(0)), first = NVL('%s', CHR(0)), middle = NVL('%s', CHR(0)), status = %s, clearid = NVL('%s', CHR(0)), type = '%s', comments = %d, signature = NVL(CHR(0), '%s'), secure = %s, winhomedir = NVL('%s', CHR(0)), winprofiledir = NVL('%s', CHR(0)), sponsor_type = '%s', sponsor_id = %d, expiration = NVL('%s', CHR(0)), alternate_email = NVL('%s', CHR(0)), alternate_phone = NVL('%s', CHR(0)), twofactor_enabled = %s",
+    uuac_fields,
+    22,
+    21,   
+    "users_id = %d",
+    1,
+    NULL,
     &uuac_validate,
   },
 
@@ -5721,12 +6051,30 @@
     "u",
     USERS_TABLE,
     "users SET login = '%s', unix_uid = %s, shell = '%s', winconsoleshell = '%s', last = NVL('%s', CHR(0)), first = NVL('%s', CHR(0)), middle = NVL('%s', CHR(0)), status = %s, clearid = NVL('%s', CHR(0)),  type = '%s', winhomedir = NVL('%s', CHR(0)), winprofiledir = NVL('%s', CHR(0)), sponsor_type = '%s', sponsor_id = %d, expiration = NVL('%s', CHR(0)), alternate_email = NVL('%s', CHR(0)), alternate_phone = NVL('%s', CHR(0)) ",
-    uuac_fields,
+    uuac14_fields,
     18,
     17,
     "users_id = %d",
     1,
     NULL,
+    &uusr14_validate,
+  },
+
+  {
+    /* Q_UUSR - UPDATE_USER, v16 */
+    "update_user",
+    "uusr",
+    16,
+    MR_Q_UPDATE,
+    "u",
+    USERS_TABLE,
+    "users SET login = '%s', unix_uid = %s, shell = '%s', winconsoleshell = '%s', last = NVL('%s', CHR(0)), first = NVL('%s', CHR(0)), middle = NVL('%s', CHR(0)), status = %s, clearid = NVL('%s', CHR(0)),  type = '%s', winhomedir = NVL('%s', CHR(0)), winprofiledir = NVL('%s', CHR(0)), sponsor_type = '%s', sponsor_id = %d, expiration = NVL('%s', CHR(0)), alternate_email = NVL('%s', CHR(0)), alternate_phone = NVL('%s', CHR(0)), twofactor_enabled = %s ",
+    uuac_fields,
+    19,
+    18,
+    "users_id = %d",
+    1,
+    NULL,
     &uusr_validate,
   },
 
@@ -5839,6 +6187,42 @@
   },
 
   {
+    /* Q_SUVG - SET_USER_VPN_GROUP */
+    "set_user_vpn_group",
+    "suvg",
+    2,
+    MR_Q_UPDATE,
+    "u",
+    USERS_TABLE,
+    "users SET default_vpn_group = %d",
+    suvg_fields,
+    2,
+    1,
+    "users_id = %d",
+    1,
+    NULL,
+    &suvg_validate,
+  },
+  
+  {
+    /* Q_GUVG - GET_USER_VPN_GROUP */
+    "get_user_vpn_group",
+    "guvg",
+    2,
+    MR_Q_RETRIEVE,
+    "u",
+    USERS_TABLE,
+    "u.login, l.name FROM users u, list l",
+    guvg_fields,
+    3,
+    2,
+    "u.login = '%s' AND u.default_vpn_group = l.list_id",
+    1,
+    NULL,
+    NULL,
+  },
+
+  {
     /* Q_DUSR - DELETE_USER */
     "delete_user",
     "dusr",


home help back first fref pref prev next nref lref last post