[1832] in Moira Commits

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

/svn/moira r3979 - in trunk/moira: clients/addusr clients/moira clients/stanley db include server

daemon@ATHENA.MIT.EDU (Garry Zacheiss)
Tue Feb 16 15:27:04 2010

Date: Tue, 16 Feb 2010 15:26:57 -0500
From: Garry Zacheiss <zacheiss@MIT.EDU>
Message-Id: <201002162026.o1GKQvKr003707@drugstore.mit.edu>
To: moira-commits@mit.edu
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Author: zacheiss
Date: 2010-02-16 15:26:57 -0500 (Tue, 16 Feb 2010)
New Revision: 3979

Modified:
   trunk/moira/clients/addusr/addusr.c
   trunk/moira/clients/moira/defs.h
   trunk/moira/clients/moira/user.c
   trunk/moira/clients/stanley/stanley.c
   trunk/moira/db/schema.sql
   trunk/moira/include/moira_site.h
   trunk/moira/server/qaccess.pc
   trunk/moira/server/queries2.c
Log:
Add alternate_email, alternate_phone columns to users table for guest accounts, and associated query support.

Modified: trunk/moira/clients/addusr/addusr.c
===================================================================
--- trunk/moira/clients/addusr/addusr.c	2010-02-14 16:49:49 UTC (rev 3978)
+++ trunk/moira/clients/addusr/addusr.c	2010-02-16 20:26:57 UTC (rev 3979)
@@ -208,7 +208,7 @@
     }
 
   /* fire up Moira */
-  if (mrcl_connect(server, "addusr", 12, 1) != MRCL_SUCCESS)
+  if (mrcl_connect(server, "addusr", 14, 1) != MRCL_SUCCESS)
     exit(2);
 
   qargv[U_NAME] = UNIQUE_LOGIN;
@@ -218,6 +218,8 @@
   qargv[U_WINHOMEDIR] = DEFAULT_WINHOMEDIR;
   qargv[U_WINPROFILEDIR] = DEFAULT_WINPROFILEDIR;
   qargv[U_EXPIRATION] = expiration;
+  qargv[U_ALT_EMAIL] = "";
+  qargv[U_ALT_PHONE] = "";
   qargv[U_STATE] = status_str;
   qargv[U_CLASS] = class;
   qargv[U_COMMENT] = comment;
@@ -409,7 +411,7 @@
 
 	  rargv[0] = uid;
 	  rargv[1] = login;
-	  rargv[2] = "IMAP";
+	  rargv[2] = "EXCHANGE";
 
 	  status = mr_query("register_user", 3, rargv, NULL, NULL);
 	  if (status)

Modified: trunk/moira/clients/moira/defs.h
===================================================================
--- trunk/moira/clients/moira/defs.h	2010-02-14 16:49:49 UTC (rev 3978)
+++ trunk/moira/clients/moira/defs.h	2010-02-16 20:26:57 UTC (rev 3979)
@@ -50,7 +50,7 @@
 
 /* What version of the queries are we asking for? */
 
-#define QUERY_VERSION 13
+#define QUERY_VERSION 14
 
 /* This is unimplemented in the menu stuff, but would be nice. */
 

Modified: trunk/moira/clients/moira/user.c
===================================================================
--- trunk/moira/clients/moira/user.c	2010-02-14 16:49:49 UTC (rev 3978)
+++ trunk/moira/clients/moira/user.c	2010-02-16 20:26:57 UTC (rev 3979)
@@ -120,6 +120,10 @@
   sprintf(sponsor, "%s %s", info[U_SPONSOR_TYPE], info[U_SPONSOR_NAME]);
   sprintf(buf, "Sponsor: %-23s Expiration date: %s", sponsor,  info[U_EXPIRATION]);
   Put_message(buf);
+  sprintf(buf, "Alternate Email: %s", info[U_ALT_EMAIL]);
+  Put_message(buf);
+  sprintf(buf, "Alternate Phone: %s", info[U_ALT_PHONE]);
+  Put_message(buf);
   sprintf(buf, "Account is: %-20s MIT ID number: %s",
 	  UserState(atoi(info[U_STATE])), info[U_MITID]);
   Put_message(buf);
@@ -168,6 +172,8 @@
   info[U_SPONSOR_TYPE] = strdup("NONE");
   info[U_SPONSOR_NAME] = strdup("NONE");
   info[U_EXPIRATION] = strdup("");
+  info[U_ALT_EMAIL] = strdup("");
+  info[U_ALT_PHONE] = strdup("");
   info[U_MODTIME] = info[U_MODBY] = info[U_MODWITH] = info[U_END] = NULL;
   info[U_CREATED] = info[U_CREATOR] = NULL;
   return info;
@@ -332,6 +338,12 @@
   if (GetValueFromUser("Expiration date", &info[U_EXPIRATION]) == SUB_ERROR)
     return NULL;
 
+  if (GetValueFromUser("Alternate Email", &info[U_ALT_EMAIL]) == SUB_ERROR)
+    return NULL;
+
+  if (GetValueFromUser("Alternate Phone", &info[U_ALT_PHONE]) == SUB_ERROR)
+    return NULL;
+
   state = atoi(info[U_STATE]);
   if (!name || state == 0 || state == 2)
     {
@@ -633,7 +645,7 @@
   Put_message("KERBEROS code not added, did not reserve name with kerberos.");
   args[1] = login;
   
-  sprintf(temp_buf, "IMAP");
+  sprintf(temp_buf, "EXCHANGE");
   potype = strdup(temp_buf);
   if (GetValueFromUser("P.O. Box Type for this user? ", &potype) == SUB_ERROR)
     {

Modified: trunk/moira/clients/stanley/stanley.c
===================================================================
--- trunk/moira/clients/stanley/stanley.c	2010-02-14 16:49:49 UTC (rev 3978)
+++ trunk/moira/clients/stanley/stanley.c	2010-02-16 20:26:57 UTC (rev 3979)
@@ -54,6 +54,7 @@
 
 char *newlogin, *uid, *shell, *winshell, *last, *first, *middle, *u_status;
 char *clearid, *class, *comment, *secure, *winhomedir, *winprofiledir, *expiration;
+char *alternate_email, *alternate_phone;
 
 struct owner_type *parse_member(char *s);
 
@@ -103,7 +104,7 @@
   list_res_flag = update_res_flag = unformatted_flag = verbose = noauth = 0;
   newlogin = uid = shell = winshell = last = first = middle = NULL;
   u_status = clearid = class = comment = secure = NULL;
-  winhomedir = winprofiledir = expiration = NULL;
+  winhomedir = winprofiledir = expiration = alternate_email = alternate_phone = NULL;
   reservation_add_queue = reservation_remove_queue = NULL;
   sponsor = NULL;
   whoami = argv[0];
@@ -259,6 +260,22 @@
 	    } else
 	      usage(argv);
 	  }
+	  else if (argis("ae", "alternateemail")) {
+	    if (arg - argv < argc - 1) {
+	      arg++;
+	      update_flag++;
+	      alternate_email = *arg;
+	    } else
+	      usage(argv);
+	  }
+	  else if (argis("ap", "alternatephone")) {
+	    if (arg - argv < argc - 1) {
+	      arg++;
+	      update_flag++;
+	      alternate_phone = *arg;
+	    } else
+	      usage(argv);
+	  }
 	  else if (argis("ar", "addreservation")) {
 	    if (arg - argv < argc - 1) {
 	      arg++;
@@ -313,7 +330,7 @@
   }
 
   /* fire up Moira */
-  status = mrcl_connect(server, "stanley", 12, !noauth);
+  status = mrcl_connect(server, "stanley", 14, !noauth);
   if (status == MRCL_AUTH_ERROR)
     {
       com_err(whoami, 0, "Try the -noauth flag if you don't "
@@ -325,10 +342,10 @@
   /* create if needed */
   if (create_flag)
     {
-      char *argv[20];
+      char *argv[25];
       int cnt;
 
-      for (cnt = 0; cnt < 20; cnt++) {
+      for (cnt = 0; cnt < 25; cnt++) {
 	argv[cnt] = "";
       }
 
@@ -380,6 +397,10 @@
 	argv[U_WINPROFILEDIR] = "[DFS]";
       if (expiration)
 	argv[U_EXPIRATION] = expiration;
+      if (alternate_email)
+        argv[U_ALT_EMAIL] = alternate_email;
+      if (alternate_phone)
+        argv[U_ALT_PHONE] = alternate_phone;
       if (sponsor)
 	{
 	  argv[U_SPONSOR_NAME] = sponsor->name;
@@ -388,13 +409,13 @@
 	    case M_ANY:
 	    case M_USER:
 	      argv[U_SPONSOR_TYPE] = "USER";
-	      status = wrap_mr_query("add_user_account", 18, argv, NULL, NULL);
+	      status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
 	      if (sponsor->type != M_ANY || status != MR_USER)
 		break;
 
 	    case M_LIST:
 	      argv[U_SPONSOR_TYPE] = "LIST";
-	      status = wrap_mr_query("add_user_account", 18, argv, NULL, NULL);
+	      status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
 	      break;
 
 	    case M_KERBEROS:
@@ -405,12 +426,12 @@
 		mrcl_com_err(whoami);
 	      if (status == MRCL_REJECT)
 		exit(1);
-	      status = wrap_mr_query("add_user_account", 18, argv, NULL, NULL);
+	      status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
 	      break;
 
 	    case M_NONE:
 	      argv[U_SPONSOR_TYPE] = "NONE";
-	      status = wrap_mr_query("add_user_account", 18, argv, NULL, NULL);
+	      status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
 	      break;
 	    }
 	}
@@ -419,9 +440,9 @@
 	  argv[U_SPONSOR_TYPE] = "NONE";
 	  argv[U_SPONSOR_NAME] = "NONE";
 	  
-	  status = wrap_mr_query("add_user_account", 18, argv, NULL, NULL);
+	  status = wrap_mr_query("add_user_account", 20, argv, NULL, NULL);
 	}
-	      
+
       if (status)
 	{
 	  com_err(whoami, status, "while adding user account.");
@@ -430,8 +451,8 @@
     }
   else if (update_flag)
     {
-      char *old_argv[20];
-      char *argv[20];
+      char *old_argv[25];
+      char *argv[25];
       char *args[5];
 
       args[0] = username;
@@ -462,7 +483,9 @@
       argv[16] = old_argv[15];
       argv[17] = old_argv[16];
       argv[18] = old_argv[17];
-      
+      argv[19] = old_argv[18];
+      argv[20] = old_argv[19];
+
       argv[0] = username;
       if (newlogin)
 	argv[1] = newlogin;
@@ -494,6 +517,10 @@
 	argv[15] = winprofiledir;
       if (expiration)
 	argv[18] = expiration;
+      if (alternate_email)
+	argv[19] = alternate_email;
+      if (alternate_phone)
+	argv[20] = alternate_phone;
       if (sponsor)
 	{
 	  argv[17] = sponsor->name;
@@ -502,14 +529,14 @@
 	    case M_ANY:
 	    case M_USER:
 	      argv[16] = "USER";
-	      status = wrap_mr_query("update_user_account", 19, argv, NULL, 
+	      status = wrap_mr_query("update_user_account", 21, argv, NULL, 
 				     NULL);
 	      if (sponsor->type != M_ANY || status != MR_USER)
 		break;
 
 	    case M_LIST:
 	      argv[16] = "LIST";
-	      status = wrap_mr_query("update_user_account", 19, argv, NULL,
+	      status = wrap_mr_query("update_user_account", 21, argv, NULL,
 				     NULL);
 	      break;
 
@@ -520,19 +547,19 @@
 		mrcl_com_err(whoami);
 	      if (status == MRCL_REJECT)
 		exit(1);
-	      status = wrap_mr_query("update_user_account", 19, argv, NULL,
+	      status = wrap_mr_query("update_user_account", 21, argv, NULL,
 				     NULL);
 	      break;
 
 	    case M_NONE:
 	      argv[16] = "NONE";
-	      status = wrap_mr_query("update_user_account", 19, argv, NULL,
+	      status = wrap_mr_query("update_user_account", 21, argv, NULL,
 				     NULL);
 	      break;
 	    }
 	}
       else
-	status = wrap_mr_query("update_user_account", 19, argv, NULL, NULL);
+	status = wrap_mr_query("update_user_account", 21, argv, NULL, NULL);
 
       if (status)
 	com_err(whoami, status, "while updating user.");
@@ -608,7 +635,7 @@
   if (info_flag)
     {
       char *args[2];
-      char *argv[20];
+      char *argv[25];
 
       args[0] = username;
       status = wrap_mr_query("get_user_account_by_login", 1, args,
@@ -628,7 +655,7 @@
   if (reg_flag)
     {
       char *args[3];
-      char *argv[20];
+      char *argv[25];
 
       args[0] = username;
       status = wrap_mr_query("get_user_account_by_login", 1, args,
@@ -641,7 +668,7 @@
 
       args[0] = argv[U_UID];
       args[1] = username;
-      args[2] = "IMAP";
+      args[2] = "EXCHANGE";
 
       status = wrap_mr_query("register_user", 3, args, NULL, NULL);
       if (status)
@@ -772,11 +799,13 @@
   printf("User id: %-23s Login shell: %-10s\n", argv[U_UID], argv[U_SHELL]);
   printf("Class: %-25s Windows Console Shell: %-10s\n", argv[U_CLASS],
 	 argv[U_WINCONSOLESHELL]);
+  printf("Account is: %-20s MIT ID number: %s\n",
+         UserState(atoi(argv[U_STATE])), argv[U_MITID]);
   sprintf(tbuf, "%s %s", argv[U_SPONSOR_TYPE],
 	  strcmp(argv[U_SPONSOR_TYPE], "NONE") ? argv[U_SPONSOR_NAME] : "");
   printf("Sponsor: %-23s Expiration date: %s\n", tbuf, argv[U_EXPIRATION]);
-  printf("Account is: %-20s MIT ID number: %s\n",
-	 UserState(atoi(argv[U_STATE])), argv[U_MITID]);
+  printf("Alternate Email: %s\n", argv[U_ALT_EMAIL]);
+  printf("Alternate Phone: %s\n", argv[U_ALT_PHONE]);
   printf("Windows Home Directory: %s\n", argv[U_WINHOMEDIR]);
   printf("Windows Profile Directory: %s\n", argv[U_WINPROFILEDIR]);
   status = atoi(argv[U_STATE]);
@@ -805,6 +834,8 @@
 	  strcmp(argv[U_SPONSOR_TYPE], "NONE") ? argv[U_SPONSOR_NAME] : "");
   printf("Sponsor:                   %s\n", tbuf);
   printf("Expiration date:           %s\n", argv[U_EXPIRATION]);
+  printf("Alternate Email:           %s\n", argv[U_ALT_EMAIL]);
+  printf("Alternate Phone:           %s\n", argv[U_ALT_PHONE]);
   printf("Login shell:               %s\n", argv[U_SHELL]);
   printf("Windows Console Shell:     %s\n", argv[U_WINCONSOLESHELL]);
   printf("Account is:                %s\n", UserState(atoi(argv[U_STATE])));
@@ -851,6 +882,8 @@
 	  "-wp  | -winprofiledir winprofiledir");
   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, "-u   | -unformatted",
           "-n   | -noauth");
   fprintf(stderr, USAGE_OPTIONS_FORMAT, "-v   | -verbose",

Modified: trunk/moira/db/schema.sql
===================================================================
--- trunk/moira/db/schema.sql	2010-02-14 16:49:49 UTC (rev 3978)
+++ trunk/moira/db/schema.sql	2010-02-16 20:26:57 UTC (rev 3979)
@@ -54,7 +54,9 @@
 	winprofiledir	VARCHAR(260)	DEFAULT '[DFS]' NOT NULL,
 	sponsor_type	VARCHAR(8) 	DEFAULT 'NONE'	NOT NULL,
 	sponsor_id	INTEGER		DEFAULT 0	NOT NULL,
-	expiration	VARCHAR(24)	DEFAULT CHR(0)	NOT NULL
+	expiration	VARCHAR(24)	DEFAULT CHR(0)	NOT NULL,
+	alternate_email	VARCHAR(255)	DEFAULT CHR(0)	NOT NULL,
+	alternate_phone	VARCHAR(24)	DEFAULT CHR(0)	NOT NULL
 );
 
 create table krbmap

Modified: trunk/moira/include/moira_site.h
===================================================================
--- trunk/moira/include/moira_site.h	2010-02-14 16:49:49 UTC (rev 3978)
+++ trunk/moira/include/moira_site.h	2010-02-16 20:26:57 UTC (rev 3979)
@@ -381,12 +381,14 @@
 #define U_SPONSOR_TYPE 15
 #define U_SPONSOR_NAME 16
 #define U_EXPIRATION 17
-#define U_MODTIME 18
-#define U_MODBY   19
-#define U_MODWITH 20
-#define U_CREATED 21
-#define U_CREATOR 22
-#define U_END     23
+#define U_ALT_EMAIL 18
+#define U_ALT_PHONE 19
+#define U_MODTIME 20
+#define U_MODBY   21
+#define U_MODWITH 22
+#define U_CREATED 23
+#define U_CREATOR 24
+#define U_END     25
 
 /* User states (the value of argv[U_STATE] from a user query) */
 

Modified: trunk/moira/server/qaccess.pc
===================================================================
--- trunk/moira/server/qaccess.pc	2010-02-14 16:49:49 UTC (rev 3978)
+++ trunk/moira/server/qaccess.pc	2010-02-16 20:26:57 UTC (rev 3979)
@@ -52,12 +52,14 @@
 int access_update_user(struct query *q, char *argv[], client *cl)
 {
   EXEC SQL BEGIN DECLARE SECTION;
-  int users_id, unix_uid, status, comments, secure;
+  int users_id, unix_uid, status, comments, secure, sponsor_id;
   char login[USERS_LOGIN_SIZE], shell[USERS_SHELL_SIZE];
   char winconsoleshell[USERS_WINCONSOLESHELL_SIZE], last[USERS_LAST_SIZE];
   char first[USERS_FIRST_SIZE], middle[USERS_MIDDLE_SIZE];
   char clearid[USERS_CLEARID_SIZE], type[USERS_TYPE_SIZE];
-  char signature[USERS_SIGNATURE_SIZE];
+  char signature[USERS_SIGNATURE_SIZE], sponsor_type[USERS_SPONSOR_TYPE_SIZE];
+  char expiration[USERS_EXPIRATION_SIZE], alternate_email[USERS_ALTERNATE_EMAIL_SIZE];
+  char alternate_phone[USERS_ALTERNATE_PHONE_SIZE];
   EXEC SQL END DECLARE SECTION;
 
   /* The two fields we let users update themselves didn't appear until
@@ -73,8 +75,10 @@
 
   EXEC SQL SELECT u.login, u.unix_uid, u.shell, u.winconsoleshell, u.last,
     u.first, u.middle, u.status, u.clearid, u.type, u.comments, u.signature,
-    u.secure INTO :login, :unix_uid, :shell, :winconsoleshell, :last, :first,
-    :middle, :status, :clearid, :type, :comments, :signature, :secure
+    u.secure, u.sponsor_type, u.sponsor_id, u.expiration, u.alternate_email,
+    u.alternate_phone INTO :login, :unix_uid, :shell, :winconsoleshell, :last, :first,
+    :middle, :status, :clearid, :type, :comments, :signature, :secure, :sponsor_type,
+    :sponsor_id, :expiration, :alternate_email, :alternate_phone
     FROM USERS u WHERE u.users_id = :users_id;
 
   /* None of these things can have changed. */
@@ -93,6 +97,23 @@
       (secure != atoi(argv[13])))
     return MR_PERM;
 
+  /* These fields added in version 12 of the query. */
+  if (q->version >= 12)
+    {
+      if (strcmp(argv[16], strtrim(sponsor_type)) ||
+	  (sponsor_id != atoi(argv[17])) ||
+	  strcmp(argv[18], strtrim(expiration)))
+	return MR_PERM;
+    }
+
+  /* These fields added in version 14 of the query. */
+  if (q->version >= 14)
+    {
+      if (strcmp(argv[19], strtrim(alternate_email)) ||
+	  strcmp(argv[20], strtrim(alternate_phone)))
+	return MR_PERM;
+    }
+
   return MR_SUCCESS;
 }
 

Modified: trunk/moira/server/queries2.c
===================================================================
--- trunk/moira/server/queries2.c	2010-02-14 16:49:49 UTC (rev 3978)
+++ trunk/moira/server/queries2.c	2010-02-16 20:26:57 UTC (rev 3979)
@@ -103,7 +103,7 @@
   "creator",
 };
 
-static char *gual_fields[] = {
+static char *gual12_fields[] = {
   "login",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -111,6 +111,14 @@
   "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", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static char *gubl2_fields[] = {
   "login",
   "login", "unix_uid", "shell", "last", "first", "middle", "status",
@@ -172,7 +180,7 @@
   "creator",
 };
 
-static char *guau_fields[] = {
+static char *guau12_fields[] = {
   "unix_uid",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure", 
@@ -180,6 +188,14 @@
   "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", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static char *guan2_fields[] = {
   "first", "last",
   "login", "unix_uid", "shell", "last", "first", "middle", "status",
@@ -202,7 +218,7 @@
   "creator",
 };
 
-static char *guan_fields[] = {
+static char *guan12_fields[] = {
   "first", "last",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -210,6 +226,14 @@
   "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", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static struct validate guan2_validate =
 {
   0,
@@ -258,7 +282,7 @@
   "creator",
 };
 
-static char *guac_fields[] = {
+static char *guac12_fields[] = {
   "class",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -266,6 +290,14 @@
   "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", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static char *guam2_fields[] = {
   "clearid",
   "login", "unix_uid", "shell", "last", "first", "middle", "status",
@@ -288,7 +320,7 @@
   "creator", 
 };
 
-static char *guam_fields[] = {
+static char *guam12_fields[] = {
   "clearid",
   "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
   "status", "clearid", "class", "comments", "signature", "secure",
@@ -296,6 +328,14 @@
   "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", "modtime", "modby", "modwith", "created", "creator",
+};
+
 static char *guas_fields[] = {
   "sponsor_type", "sponsor_name",
   "login",
@@ -438,10 +478,17 @@
   "winhomedir", "winprofiledir",
 };
 
+static char *auac12_fields[] = {
+  "login", "unix_uid", "shell", "winconsoleshell", "last", "first", "middle",
+  "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+};
+
 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",
 };
 
 static struct valobj auac2_valobj[] = {
@@ -490,6 +537,26 @@
   {V_LEN, 14, USERS_TABLE, "winprofiledir"},
 };
 
+static struct valobj auac12_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"},
+};
+
 static struct valobj auac_valobj[] = {
   {V_CHAR, 0, USERS_TABLE, "login"},
   {V_NUM, 1},
@@ -508,6 +575,8 @@
   {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 validate auac2_validate = {
@@ -546,9 +615,21 @@
   followup_ausr,
 };
 
+static struct validate auac12_validate = {
+  auac12_valobj,
+  17,
+  "login",
+  "login = '%s'",
+  1,
+  "users_id",
+  0,
+  setup_ausr,
+  followup_ausr,
+};
+
 static struct validate auac_validate = {
   auac_valobj,
-  17,
+  19,
   "login",
   "login = '%s'",
   1,
@@ -594,9 +675,21 @@
   followup_ausr,
 };
 
+static struct validate ausr12_validate = {
+  auac12_valobj,
+  15,
+  "login",
+  "login = '%s'",
+  1,
+  "users_id",
+  0,
+  setup_ausr,
+  followup_ausr,
+};
+
 static struct validate ausr_validate = {
   auac_valobj,
-  15,
+  17,
   "login",
   "login = '%s'",
   1,
@@ -646,11 +739,19 @@
   "winhomedir", "winprofiledir",
 };
 
+static char *uuac12_fields[] = {
+  "login",
+  "newlogin", "unix_uid", "shell", "winconsoleshell", "last", "first",
+  "middle", "status", "clearid", "class", "comments", "signature", "secure",
+  "winhomedir", "winprofiledir", "sponsor_type", "sponsor_name", "expiration",
+};
+
 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",
 };
 
 static struct valobj uuac2_valobj[] = {
@@ -702,6 +803,27 @@
   {V_LEN, 15, USERS_TABLE, "winprofiledir"},
 };
 
+static struct valobj uuac12_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"},
+};
+
 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},
@@ -721,6 +843,8 @@
   {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 validate uuac2_validate = {
@@ -759,9 +883,21 @@
   set_modtime_by_id,
 };
 
+static struct validate uuac12_validate = {
+  uuac12_valobj,
+  18,
+  0,
+  0,
+  0,
+  "users_id",
+  access_update_user,
+  setup_ausr,
+  set_modtime_by_id,
+};
+
 static struct validate uuac_validate = {
   uuac_valobj,
-  18,
+  20,
   0,
   0,
   0,
@@ -807,9 +943,21 @@
   set_modtime_by_id,
 };
 
+static struct validate uusr12_validate = {
+  uuac12_valobj,
+  16,
+  0,
+  0,
+  0,
+  "users_id",
+  0,
+  setup_ausr,
+  set_modtime_by_id,
+};
+
 static struct validate uusr_validate = {
   uuac_valobj,
-  16,
+  18,
   0,
   0,
   0,
@@ -4226,7 +4374,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, 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,
+    gual12_fields,
     23,
     "u.login LIKE '%s' AND u.users_id != 0 AND u.comments = str.string_id",
     1,
@@ -4235,6 +4383,23 @@
   },
 
   {
+    /* Q_GUAL - GET_USER_ACCOUNT_BY_LOGIN, v14 */
+    "get_user_account_by_login",
+    "gual",
+    14,
+    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, 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,
+    25,
+    "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",
@@ -4277,7 +4442,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, 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",
-    guau3_fields,
+    guau11_fields,
     20,
     "u.unix_uid = %s AND u.users_id != 0 AND u.comments = str.string_id",
     1,
@@ -4294,7 +4459,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, 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,
+    guau12_fields,
     23,
     "u.unix_uid = %s AND u.users_id != 0 AND u.comments = str.string_id",
     1,
@@ -4303,6 +4468,23 @@
   }, 
 
   {
+    /* Q_GUAU - GET_USER_ACCOUNT_BY_UID, v14 */
+    "get_user_account_by_uid",
+    "guau",
+    14,
+    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, 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,
+    25,
+    "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",
@@ -4362,7 +4544,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, 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,
+    guan12_fields,
     23,
     "u.first LIKE '%s' AND u.last LIKE '%s' AND u.users_id != 0 and u.comments = str.string_id",
     2,
@@ -4371,6 +4553,23 @@
   },
 
   {
+    /* Q_GUAN - GET_USER_ACCOUNT_BY_NAME, v14 */
+    "get_user_account_by_name",
+    "guan",
+    14,
+    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, 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,
+    25,
+    "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",
@@ -4430,7 +4629,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, 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,
+    guac12_fields,
     23,
     "u.type = UPPER('%s') AND u.users_id != 0 AND u.comments = str.string_id",
     1,
@@ -4438,6 +4637,23 @@
     &guan_validate,
   },
 
+  { 
+    /* Q_GUAC - GET_USER_ACCOUNT_BY_CLASS, v14 */
+    "get_user_account_by_class",
+    "guac",
+    14,
+    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, 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,
+    25,
+    "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",
@@ -4498,7 +4714,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, 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,
+    guam12_fields,
     23,
     "u.clearid LIKE '%s' AND u.users_id != 0 AND u.comments = str.string_id",
     1,
@@ -4507,6 +4723,23 @@
   },
 
   {
+    /* Q_GUAM - GET_USER_ACCOUNT_BY_MITID, v14 */
+    "get_user_account_by_id",
+    "guai",
+    14,
+    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, 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,
+    25,
+    "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",
@@ -4765,11 +4998,31 @@
      * 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, 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)), %s, SYSDATE, %s)",
-    auac_fields,
+    auac12_fields,
     18,
     NULL,
     0,
     NULL,
+    &auac12_validate,
+  },
+
+  {
+    /* Q_AUAC - ADD_USER_ACCOUNT, v14 */  /* uses prefetch_value() for users_id */
+    "add_user_account",
+    "auac",
+    14,
+    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, 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,
+    20,
+    NULL,
+    0,
+    NULL,
     &auac_validate,
   },
 
@@ -4833,11 +5086,28 @@
     "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, 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)), %s, SYSDATE, %s)",
-    auac_fields,
+    auac12_fields,
     15,
     0,
     0,
     NULL,
+    &ausr12_validate,
+  },
+
+  {
+    /* Q_AUSR - ADD_USER, v14 */  /* uses prefetch_value() for users_id */
+    "add_user",
+    "ausr",
+    14,
+    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, 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,
+    17,
+    0,
+    0,
+    NULL,
     &ausr_validate,
   },
 
@@ -4922,11 +5192,29 @@
     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))",
-    uuac_fields,
+    uuac12_fields,
     18,
     "users_id = %d",
     1,
     NULL,
+    &uuac12_validate,
+  },
+
+  {
+    /* Q_UUAC - UPDATE_USER_ACCOUNT, v14 */
+    "update_user_account",
+    "uuac",
+    14,
+    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))",
+    uuac_fields,
+    20,
+    "users_id = %d",
+    1,
+    NULL,
     &uuac_validate,
   },
 
@@ -4990,11 +5278,28 @@
     "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)) ",
-    uuac_fields,
+    uuac12_fields,
     15,
     "users_id = %d",
     1,
     NULL,
+    &uusr12_validate,
+  },
+
+  {
+    /* Q_UUSR - UPDATE_USER, v14 */
+    "update_user",
+    "uusr",
+    14,
+    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)) ",
+    uuac_fields,
+    17,
+    "users_id = %d",
+    1,
+    NULL,
     &uusr_validate,
   },
 


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