]> andersk Git - moira.git/blobdiff - incremental/winad/winad.c
Deal better with null pointers. Corrects a seg fault we're seeing
[moira.git] / incremental / winad / winad.c
index e30ae958dc46c350bace0bdcbacdaf946aef012f..6fc9437d21517c56800614e8a97072f0acbba6dc 100755 (executable)
@@ -1,44 +1,52 @@
 /* $Header$
-/ *test parameters for creating a user account - done
- * users 0 3 6_d0006 950 2
- * users 0 3 6_d0006 950 1
+/* test parameters for creating a user account - done 
+ * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 0 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF
+ * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF
+ *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
  *
  * test parameters for deactivating/deleting a user account - done
- * users 3 0 6_d0006 950 3
- * users 3 0 6_d0006 950 3
+ * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF testacc 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF 
+ * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF 
+ *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
+ * comment: clearid is the MIT ID
  *
- *test parameters for reactivating a user account - done
- * users 0 3 6_d0006 950 2
- * users 0 3 6_d0006 950 1
+ * test parameters for reactivating a user account - done
+ * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF 
+ *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
  *
- *test parameters for updating user account info - done
- * users 1 0 6_d0006
- * currently, this only occurs when the U_UID or U_MITID changes
+ * test parameters for updating user account info - done
+ * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc 31275 sh cmd newLastname Firstname Middlename 2 950000000 STAFF 
+ * users 10 10 6_d0006 950 sh cmd Lastname Firstname Middlename 1 900012345 STAFF 6_d0006 950 sh cmd Lastname Firstname Middlename 1 950012345 STAFF
+ *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
+ *   currently, if the unix_id doesn't change, only the U_UID or U_MITID fields will be updated
  *
- * test parameters for changing account name - done
- * users 3 3 6_d0006 950 1 alexp 950 1
- * users 3 3 6_d0006 950 2 alexp 950 2
- * users 3 3 6_d0006 950 2 a_chen 950 2
+ * test parameters for changing user name - testing
+ * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc1 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF
+ * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF testacc1 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF
+ *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
  *
- * test parameters for add member to group/list 
- * imembers 0 5 pismere-team USER dtanner 1 1
- * note: the group the group will be created if it does not exist in the AD.
+ * test parameters for add member to group/list - done
+ * imembers 0 10 pismere-team USER dtanner 1 1 0 1 1 -1 1
+ * imembers 0 9 pismere-team STRING hope@ful.net 1 1 0 1 1 -1
+ *   list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid
  *
- * test parameters for remove member from group/list
- * imembers 5 0 pismere-team USER dtanner 1 1
+ * test parameters for remove member from group/list - done
+ * imembers 10 0 pismere-team USER dtanner 1 1 0 1 1 -1 1
+ * imembers 9 0 pismere-team STRING hope@ful.net 1 1 0 1 1 -1
+ *   list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid
  *
  * test parameters for creating and/or populating a group/list - done
- * list 0 7 pismere-team 1 0 1 1 1 760
+ * list 0 10 pismere-team 1 1 0 1 0 -1 USER 95260 description
+ *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
  * 
  * test parameters for deleting a group/list - done
- * list 7 0 pismere-team 1 0 1 1 1 760
- * L_NAME L_ACTIVE L_PUBLIC L_HIDDEN L_MAILLIST L_GROUP L_GID
- * used when ever L_ACTIVE changes
+ * list 10 0 pismere-team 1 1 0 1 0 -1 USER 95260 description
+ *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
  *
- * test parameters for renaming a group/list
- * list 7 7 6_d0006-acl 1 0 1 0 0 760 1.00students 1 0 1 1 1 760
- * L_NAME L_ACTIVE L_PUBLIC L_HIDDEN L_MAILLIST L_GROUP L_GID
- * used whenever L_NAME, L_MAILLIST or L_GROUP changes
+ * test parameters for renaming a group/list - done
+ *  list 10 10 adtestlist 1 1 0 1 0 -1 USER 95260 description pismere-team 1 1 0 1 1 -1 USER 95260 description
+ *  list 10 10 pismere-team 1 1 0 1 1 -1 USER 95260 description adtestlist1 1 1 0 1 0 -1 USER 95260 description
+ *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
 */
 #include <mit-copyright.h>
 #ifdef _WIN32
@@ -47,7 +55,7 @@
 #include <malloc.h>
 #include <lmaccess.h>
 #endif
-
+#include <hesiod.h>
 #include <string.h>
 #include <ldap.h>
 #include <stdio.h>
 #define EHOSTUNREACH WSAEHOSTUNREACH
 #endif
 #define krb5_xfree free
+#define F_OK 0
+#define sleep(A) Sleep(A * 1000);
 #endif /* _WIN32 */
 
 #ifndef _WIN32
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
 #include <sys/utsname.h>
+#include <unistd.h>
 
+#define strnicmp(A,B,C) strncasecmp(A,B,C)
 #define UCHAR unsigned char
 
 #define UF_SCRIPT               0x0001
@@ -118,48 +134,18 @@ typedef struct _SID {
 } SID;
 #endif/*!WIN32*/
 
+#define AFS "/afs/"
+#define WINAFS "\\\\afs\\all\\"
+
 #define ADS_GROUP_TYPE_GLOBAL_GROUP         0x00000002
-#define        ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP   0x00000004
-#define        ADS_GROUP_TYPE_LOCAL_GROUP          0x00000004
-#define        ADS_GROUP_TYPE_UNIVERSAL_GROUP      0x00000008
-#define        ADS_GROUP_TYPE_SECURITY_ENABLED     0x80000000
+#define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP   0x00000004
+#define ADS_GROUP_TYPE_LOCAL_GROUP          0x00000004
+#define ADS_GROUP_TYPE_UNIVERSAL_GROUP      0x00000008
+#define ADS_GROUP_TYPE_SECURITY_ENABLED     0x80000000
 
 #define QUERY_VERSION -1
 #define PRIMARY_REALM "ATHENA.MIT.EDU"
 
-#define BEFORE_U_NAME   0
-#define BEFORE_U_UID    1
-#define BEFORE_U_STATE  2
-#define AFTER_U_NAME    0
-#define AFTER_U_UID     1
-#define AFTER_U_STATE   2
-
-#define BEFORE_LM_LIST          0
-#define BEFORE_LM_TYPE          1
-#define BEFORE_LM_MEMBER        2
-#define BEFORE_LM_EXTRA_ACTIVE  3
-#define BEFORE_LM_EXTRA_GROUP   4
-#define AFTER_LM_LIST           0
-#define AFTER_LM_TYPE           1
-#define AFTER_LM_MEMBER         2
-#define AFTER_LM_EXTRA_ACTIVE   3
-#define AFTER_LM_EXTRA_GROUP    4
-
-#define BEFORE_L_NAME     0
-#define BEFORE_L_ACTIVE   1
-#define BEFORE_L_PUBLIC   2
-#define BEFORE_L_HIDDEN   3
-#define BEFORE_L_MAILLIST 4
-#define BEFORE_L_GROUP    5
-#define BEFORE_L_GID      6
-#define AFTER_L_NAME      0
-#define AFTER_L_ACTIVE    1
-#define AFTER_L_PUBLIC    2
-#define AFTER_L_HIDDEN    3
-#define AFTER_L_MAILLIST  4
-#define AFTER_L_GROUP     5
-#define AFTER_L_GID       6
-
 #define SUBSTITUTE  1
 #define REPLACE     2
 
@@ -173,10 +159,14 @@ typedef struct _SID {
 #define MEMBER_DEACTIVATE   5
 #define MEMBER_CREATE       6
 
-#define GROUP_CREATE            1
-#define GROUP_DELETE            2
-#define GROUP_MOVE_MEMBERS      3
-#define GROUP_UPDATE_MEMBERS    4
+#define MOIRA_ALL       0x0
+#define MOIRA_USERS     0x1
+#define MOIRA_KERBEROS  0x2
+#define MOIRA_STRINGS   0x4
+#define MOIRA_LISTS     0x8
+
+#define ADFS_ADD    1
+#define ADFS_DELETE 2
 
 typedef struct lk_entry {
   int     op;
@@ -191,6 +181,9 @@ typedef struct lk_entry {
   struct  lk_entry *next;
 } LK_ENTRY;
 
+#define STOP_FILE "/moira/winad/nowinad"
+#define file_exists(file) (access((file), F_OK) == 0)
+
 #define LDAP_BERVAL struct berval
 #define MAX_SERVER_NAMES 32
 
@@ -203,14 +196,15 @@ typedef struct lk_entry {
 LK_ENTRY *member_base = NULL;
 LK_ENTRY *sid_base = NULL;
 LK_ENTRY **sid_ptr = NULL;
-char kerberos_ou[] = "OU=kerberos, OU=moira, OU=athena";
-char contact_ou[] = "OU=strings, OU=moira, OU=athena";
-char user_ou[] = "OU=users, OU=moira, OU=athena";
-char group_ou_distribution[] = "OU=distribution, OU=lists, OU=moira, OU=athena";
-char group_ou_security[] = "OU=security, OU=lists, OU=moira, OU=athena";
-char group_ou_neither[] = "OU=neither, OU=lists, OU=moira, OU=athena";
-char group_ou_both[] = "OU=both, OU=lists, OU=moira, OU=athena";
-char group_ou_root[] = "OU=lists, OU=moira, OU=athena";
+static char tbl_buf[1024];
+char  kerberos_ou[] = "OU=kerberos, OU=moira";
+char  contact_ou[] = "OU=strings, OU=moira";
+char  user_ou[] = "OU=users, OU=moira";
+char  group_ou_distribution[] = "OU=mail, OU=lists, OU=moira";
+char  group_ou_root[] = "OU=lists, OU=moira";
+char  group_ou_security[] = "OU=group, OU=lists, OU=moira";
+char  group_ou_neither[] = "OU=special, OU=lists, OU=moira";
+char  group_ou_both[] = "OU=mail, OU=group, OU=lists, OU=moira";
 char *whoami;
 char group_manager[64];
 char ldap_domain[256];
@@ -220,10 +214,19 @@ int  maillist_flag;
 int  group_flag;
 int  mr_connections = 0;
 int  callback_rc;
-
-extern int locate_ldap_server(char *domain, char *server_name[]);
-extern int set_password(char *user, char *domain);
-
+char default_server[256];
+static char tbl_buf[1024];
+
+extern int set_password(char *user, char *password, char *domain);
+
+void AfsToWinAfs(char* path, char* winPath);
+int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, 
+               char *Win2kPassword, char *Win2kUser, char *default_server,
+               int connect_to_kdc);
+void ad_kdc_disconnect();
+void check_winad(void);
+void expand_groups(LDAP *ldap_handle, char *dn_path, char *group_name);
+int filesys_process(int ac, char **av, void *ptr);
 int user_create(int ac, char **av, void *ptr);
 int user_change_status(int ac, char **av, void *ptr);
 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name);
@@ -236,9 +239,11 @@ int group_delete(int ac, char **av, void *ptr);
 int group_ad_delete(LDAP *ldap_handle, char *dn_path, char *group_name);
 int group_list_build(int ac, char **av, void *ptr);
 int group_rename(int ac, char **av, void *ptr);
+int list_list_build(int ac, char **av, void *ptr);
 int member_list_build(int ac, char **av, void *ptr);
 int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name, 
-                        char *group_ou, char *group_membership, char *group_gid);
+                        char *group_ou, char *group_membership, char *group_gid,
+                        int operation);
 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, 
                   char *group_ou, char *group_membership, char *group_gid);
 int sid_update(LDAP *ldap_handle, char *dn_path);
@@ -246,11 +251,12 @@ int check_string(char *s);
 void convert_b_to_a(char *string, UCHAR *binary, int length);
 int mr_connect_cl(char *server, char *client, int version, int auth);
 
-void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 
+void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
+             char **before, int beforec, char **after, int afterc);
+void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
+             char **before, int beforec, char **after, int afterc);
+void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 
              char **before, int beforec, char **after, int afterc);
-void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname, 
-             char *dn_path, char **before, int beforec, char **after, 
-             int afterc);
 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
                char **before, int beforec, char **after, int afterc);
 int linklist_create_entry(char *attribute, char *value,
@@ -285,19 +291,13 @@ int main(int argc, char **argv)
   unsigned long   rc;
   int             beforec;
   int             afterc;
-  int             Max_wait_time = 500;
-  int             Max_size_limit = LDAP_NO_LIMIT;
   int             i;
-  char            *dn_path;
   char            *table;
   char            **before;
   char            **after;
-  char            search_exp[1024];
-  char            *server_name[MAX_SERVER_NAMES];
-  ULONG           version = LDAP_VERSION3;
   LDAP            *ldap_handle;
-  LDAPMessage     *ldap_entry;
   FILE            *fptr;
+  char            dn_path[256];
 
   whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
 
@@ -319,8 +319,17 @@ int main(int argc, char **argv)
   before = &argv[4];
   after = &argv[4 + beforec];
 
+  for (i = 1; i < argc; i++)
+    {
+      strcat(tbl_buf, argv[i]);
+      strcat(tbl_buf, " ");
+    }
+  com_err(whoami, 0, "%s", tbl_buf);
+
+  check_winad();
+  
   memset(ldap_domain, '\0', sizeof(ldap_domain));
-  if ((fptr = fopen("winad.cfg", "r")) != NULL)
+  if ((fptr = fopen("/moira/winad/winad.cfg", "r")) != NULL)
     {
       fread(ldap_domain, sizeof(char), sizeof(ldap_domain), fptr);
       fclose(fptr);
@@ -330,81 +339,137 @@ int main(int argc, char **argv)
   initialize_sms_error_table();
   initialize_krb_error_table();
 
-  memset(search_exp, '\0', sizeof(search_exp));
-  ldap_entry = NULL;
-  dn_path = NULL;
-  convert_domain_to_dn(ldap_domain, &dn_path);
-  if (dn_path == NULL)
-    {
-      com_err(whoami, 0, "%s", "cannot create AD path");
-      exit(1);
-    }
-  memset(server_name, '\0', sizeof(server_name[0]) * MAX_SERVER_NAMES);
-  if (locate_ldap_server(ldap_domain, server_name) == -1)
-    {
-      com_err(whoami, 0, "%s %s", "cannot locate any server in domain ",
-              ldap_domain);
-      exit(1);
-    }
-
-  for (i = 0; i < MAX_SERVER_NAMES; i++)
-    {
-      if (server_name[i] != NULL)
-        {
-          if ((ldap_handle = ldap_open(server_name[i], LDAP_PORT)) != NULL)
-            {
-              break;
-            }
-        }
-    }
-  if (i >= MAX_SERVER_NAMES)
+  memset(default_server, '\0', sizeof(default_server));
+  memset(dn_path, '\0', sizeof(dn_path));
+  if (ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", default_server, 1))
     {
       com_err(whoami, 0, "%s %s", "cannot connect to any server in domain ",
               ldap_domain);
       exit(1);
     }
-  for (i = 0; i < MAX_SERVER_NAMES; i++)
-    {
-      if (server_name[i] != NULL)
-        free(server_name[i]);
-    }
-  rc = ldap_set_option(ldap_handle, LDAP_OPT_PROTOCOL_VERSION, &version);
-  rc = ldap_set_option(ldap_handle, LDAP_OPT_TIMELIMIT, 
-                      (void *)&Max_wait_time);
-  rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, 
-                      (void *)&Max_size_limit);
-  rc = ldap_set_option(ldap_handle, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
-  rc = ldap_adgssapi_bind(ldap_handle, dn_path, GSSSASL_PRIVACY_PROTECTION);
-  if (rc != LDAP_SUCCESS) 
-        exit(1);
 
   for (i = 0; i < (int)strlen(table); i++)
     table[i] = tolower(table[i]);
   if (!strcmp(table, "users"))
-    do_user(ldap_handle, ldap_entry, ldap_domain, dn_path, before, beforec,
-            after, afterc);
+    do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
+            afterc);
   else if (!strcmp(table, "list"))
     do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
             afterc);
   else if (!strcmp(table, "imembers"))
     do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
               afterc);
-/*
   else if (!strcmp(table, "filesys"))
-    do_filesys(before, beforec, after, afterc);
+    do_filesys(ldap_handle, dn_path, ldap_domain, before, beforec, after,
+               afterc);
+/*
   else if (!strcmp(table, "quota"))
     do_quota(before, beforec, after, afterc);
 */
+
+  ad_kdc_disconnect();
   rc = ldap_unbind_s(ldap_handle);
-  free(dn_path);
   exit(0);
 }
 
+void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
+             char **before, int beforec, char **after, int afterc)
+{
+  long  rc;
+  char  *av[3];
+  char  *call_args[7];
+  int   acreate;
+  int   atype;
+  int   bcreate;
+  int   btype;
+
+  if (rc = moira_connect())
+    {
+      critical_alert("AD incremental",
+                     "Error contacting Moira server : %s",
+                     error_message(rc));
+      return;
+    }
+
+  if (afterc < FS_CREATE)
+    atype = acreate = 0;
+  else
+    {
+      atype = !strcmp(after[FS_TYPE], "AFS");
+      acreate = atoi(after[FS_CREATE]);
+    }
+
+  if (beforec < FS_CREATE)
+    {
+      if (acreate == 0 || atype == 0)
+        goto cleanup;
+      com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
+      av[0] = after[FS_NAME];
+      call_args[0] = (char *)ldap_handle;
+      call_args[1] = dn_path;
+      call_args[2] = after[FS_NAME];
+      call_args[3] = (char *)ADFS_ADD;
+      if (rc = mr_query("get_filesys_by_label", 1, av, filesys_process, call_args))
+        {
+          critical_alert("AD incremental", "Couldn't process filesys %s : %s",
+                          after[FS_NAME], error_message(rc));
+          goto cleanup;
+        }
+      goto cleanup;
+    }
+
+  btype = !strcmp(before[FS_TYPE], "AFS");
+  bcreate = atoi(before[FS_CREATE]);
+  if (afterc < FS_CREATE)
+    {
+      if (btype && bcreate)
+        {
+          av[0] = before[FS_NAME];
+          av[1] = before[FS_TYPE];
+          call_args[0] = (char *)ldap_handle;
+          call_args[1] = dn_path;
+          call_args[2] = before[FS_NAME];
+          call_args[3] = (char *)ADFS_DELETE;
+          if (filesys_process(beforec, before, (void *)call_args))
+            {
+              critical_alert("AD incremental", "Couldn't delete filesys %s : %s",
+                             before[FS_NAME], error_message(rc));
+            }
+        }
+      goto cleanup;
+    }
+
+  if (!acreate)
+    goto cleanup;
+
+  if (!atype && !btype)
+    {
+      if (strcmp(before[FS_TYPE], "ERR") || strcmp(after[FS_TYPE], "ERR"))
+        {
+          critical_alert("incremental", "Filesystem %s or %s is not AFS: "
+                         "Operation not supported", before[FS_NAME], after[FS_NAME]);
+          goto cleanup;
+        }
+    }
+  com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
+  av[0] = after[FS_NAME];
+  call_args[0] = (char *)ldap_handle;
+  call_args[1] = dn_path;
+  call_args[2] = after[FS_NAME];
+  call_args[3] = (char *)ADFS_ADD;
+  if (rc = mr_query("get_filesys_by_label", 1, av, filesys_process, call_args))
+    {
+      critical_alert("AD incremental", "Couldn't process filesys %s : %s",
+                     after[FS_NAME], error_message(rc));
+      goto cleanup;
+    }
+cleanup:
+  moira_disconnect();
+  return;
+}
 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
              char **before, int beforec, char **after, int afterc)
 {
-  int     agid;
-  int     bgid;
   int     ahide;
   int     bhide;
   int     apublic;
@@ -412,34 +477,41 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
   int     bgroup;
   int     agroup;
   int     amaillist;
-  int     bmailist;
+  int     bmaillist;
+  int     bstatus;
+  int     astatus;
   long    rc;
   char    *av[3];
-  char    *call_args[6];
-
+  char    *call_args[7];
 
   if (beforec == 0 && afterc == 0)
     return;
 
-  agid = bgid = 0;
+  astatus = bstatus = 0;
   ahide = bhide = 0;
   apublic = bpublic = 0;
-  amaillist = bmailist = 0;
-  if (beforec > BEFORE_L_GROUP)
+  amaillist = bmaillist = 0;
+  if (beforec != 0)
     {
-      bgid = atoi(before[BEFORE_L_GID]);
-      bhide = atoi(before[BEFORE_L_HIDDEN]);
-      bpublic = atoi(before[BEFORE_L_PUBLIC]);
-      bmailist = atoi(before[BEFORE_L_MAILLIST]);
-      bgroup = atoi(before[BEFORE_L_GROUP]);
-    }
-  if (afterc > AFTER_L_GROUP)
+      if (atoi(before[L_ACTIVE]))
+        {
+          bstatus = atoi(before[L_ACTIVE]);
+          bhide = atoi(before[L_HIDDEN]);
+          bpublic = atoi(before[L_PUBLIC]);
+          bmaillist = atoi(before[L_MAILLIST]);
+          bgroup = atoi(before[L_GROUP]);
+        }
+     }
+  if (afterc != 0)
     {
-      agid = atoi(after[AFTER_L_GID]);
-      ahide = atoi(after[AFTER_L_HIDDEN]);
-      apublic = atoi(after[AFTER_L_PUBLIC]);
-      amaillist = atoi(after[AFTER_L_MAILLIST]);
-      agroup = atoi(after[AFTER_L_GROUP]);
+      if (atoi(after[L_ACTIVE]))
+        {
+          astatus = atoi(after[L_ACTIVE]);
+          ahide = atoi(after[L_HIDDEN]);
+          apublic = atoi(after[L_PUBLIC]);
+          amaillist = atoi(after[L_MAILLIST]);
+          agroup = atoi(after[L_GROUP]);
+        }
     }
 
   if (rc = moira_connect())
@@ -450,121 +522,139 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
       return;
     }
 
-  if (beforec && afterc)
-    {
-       com_err(whoami, 0, "Changing group %s to %s",
-                before[BEFORE_L_NAME], after[AFTER_L_NAME]);
-
-       av[0] = after[AFTER_L_NAME];
-       call_args[0] = (char *)ldap_handle;
-       call_args[1] = dn_path;
-       call_args[2] = before[BEFORE_L_NAME];
-       call_args[3] = before[BEFORE_L_MAILLIST];
-       call_args[4] = before[BEFORE_L_GROUP];
-       call_args[5] = NULL;
-       callback_rc = 0;
-       if (rc = mr_query("get_list_info", 1, av, group_rename, call_args))
-         {
-            if (rc != LDAP_NO_SUCH_OBJECT)
-              {
-                critical_alert("AD incremental",
-                               "Could not change list %s to %s : %s",
-                               before[BEFORE_L_NAME], 
-                               after[AFTER_L_NAME], error_message(rc));
-                goto cleanup;
-              }
-            callback_rc = LDAP_NO_SUCH_OBJECT;
-          }
-       if (callback_rc != LDAP_NO_SUCH_OBJECT)
-         goto cleanup;
-       beforec = 0;
-    }
-  if (beforec)
-    {
-      com_err(whoami, 0, "Deleting group %s", before[BEFORE_L_NAME]);
-      rc = group_ad_delete(ldap_handle, dn_path, before[BEFORE_L_NAME]);
+  if (astatus && bstatus)
+    {
+      if ((bmaillist == amaillist) && (bgroup == agroup) &&
+          (!strcmp(before[L_NAME], after[L_NAME])))
+        return;
+      com_err(whoami, 0, "Changing group %s to %s",
+              before[L_NAME], after[L_NAME]);
+
+      av[0] = after[L_NAME];
+      call_args[0] = (char *)ldap_handle;
+      call_args[1] = dn_path;
+      call_args[2] = before[L_NAME];
+      call_args[3] = before[L_MAILLIST];
+      call_args[4] = before[L_GROUP];
+      call_args[5] = NULL;
+      callback_rc = 0;
+      if (rc = mr_query("get_list_info", 1, av, group_rename, call_args))
+        {
+           if (callback_rc != LDAP_NO_SUCH_OBJECT)
+             {
+               critical_alert("AD incremental",
+                              "Could not change list %s to %s : %s",
+                              before[L_NAME], 
+                              after[L_NAME], error_message(rc));
+               goto cleanup;
+             }
+           callback_rc = LDAP_NO_SUCH_OBJECT;
+         }
+      if (callback_rc != LDAP_NO_SUCH_OBJECT)
+        goto cleanup;
+      bstatus = 0;
+    }
+  if (bstatus)
+    {
+      com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
+      rc = group_ad_delete(ldap_handle, dn_path, before[L_NAME]);
       goto cleanup;
     }
-  if (afterc)
+  if (astatus)
     {
-      com_err(whoami, 0, "Creating group %s", after[AFTER_L_NAME]);
+      com_err(whoami, 0, "Creating group %s", after[L_NAME]);
 
-      av[0] = after[AFTER_L_NAME];
+      sleep(1);
+      av[0] = after[L_NAME];
       call_args[0] = (char *)ldap_handle;
       call_args[1] = dn_path;
-      call_args[2] = after[AFTER_L_NAME];
+      call_args[2] = after[L_NAME];
       call_args[3] = NULL;
       call_args[4] = NULL;
       call_args[5] = NULL;
+      call_args[6] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
       sid_base = NULL;
       sid_ptr = &sid_base;
       if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
         {
           critical_alert("AD incremental", "Couldn't create list %s : %s",
-                         after[AFTER_L_NAME], error_message(rc));
+                         after[L_NAME], error_message(rc));
             goto cleanup;
         }
+      if ((call_args[3] == NULL) || (call_args[4] == NULL) || (call_args[5] == NULL))
+        {
+          linklist_free(member_base);
+          linklist_free(sid_base);
+          sid_base = NULL;
+          member_base = NULL;
+          goto cleanup;
+        }
       if (sid_base != NULL)
         {
           sid_update(ldap_handle, dn_path);
           linklist_free(sid_base);
+          sid_base = NULL;
         }
 
       if (afterc == 0)
         goto cleanup;
+      sleep(1);
+
       member_base = NULL;
-      if (!(rc = mr_query("get_members_of_list", 1, av, member_list_build,
+      if (!(rc = mr_query("get_end_members_of_list", 1, av, member_list_build,
                           call_args)))
         {
           if (member_base != NULL)
-            rc = member_list_process(ldap_handle, dn_path, after[AFTER_L_NAME],
-                                     call_args[3], call_args[4], call_args[5]);
+            {
+              rc = member_list_process(ldap_handle, dn_path, after[L_NAME],
+                                       call_args[3], call_args[4], call_args[5],
+                                       MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+              expand_groups(ldap_handle, dn_path, after[L_NAME]);
+            }
         }
       else
         {
           critical_alert("AD incremental",
                          "Error contacting Moira server to resolve %s : %s",
-                         after[AFTER_L_NAME], error_message(rc));
+                         after[L_NAME], error_message(rc));
         }
       linklist_free(member_base);
+      member_base = NULL;
       goto cleanup;
     }
 cleanup:
   moira_disconnect();
 }
 
+#define LM_EXTRA_ACTIVE  (LM_END)
+
 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
                char **before, int beforec, char **after, int afterc)
 {
-  char  *call_args[6];
+  char  *call_args[7];
   char  *av[2];
   char  group_name[128];
   char  user_name[128];
   char  user_type[128];
   int   rc;
-  int   i;
 
   if (afterc)
     {
-      if (!atoi(after[AFTER_LM_EXTRA_ACTIVE]) || !atoi(after[AFTER_LM_EXTRA_GROUP]))
+      if (!atoi(after[LM_EXTRA_ACTIVE]))
         return;
-      strcpy(user_name, after[AFTER_LM_MEMBER]);
-      strcpy(group_name, after[AFTER_LM_LIST]);
-      strcpy(user_type, after[AFTER_LM_TYPE]);
+      strcpy(user_name, after[LM_MEMBER]);
+      strcpy(group_name, after[LM_LIST]);
+      strcpy(user_type, after[LM_TYPE]);
 
     }
   else if (beforec)
     {
-      if (!atoi(before[BEFORE_LM_EXTRA_ACTIVE]) || !atoi(before[BEFORE_LM_EXTRA_GROUP]))
+      if (!atoi(before[LM_EXTRA_ACTIVE]))
           return;
-      strcpy(user_name, before[BEFORE_LM_MEMBER]);
-      strcpy(group_name, before[BEFORE_LM_LIST]);
-      strcpy(user_type, before[AFTER_LM_TYPE]);
+      strcpy(user_name, before[LM_MEMBER]);
+      strcpy(group_name, before[LM_LIST]);
+      strcpy(user_type, before[LM_TYPE]);
     }
-  for (i = 0; i < (int)strlen(user_type); i++)
-    user_type[i] = tolower(user_type[i]);
-  if (strcmp(user_type, "user"))
-    return;
 
   if (rc = moira_connect())
     {
@@ -573,6 +663,8 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
                      user_name, error_message(rc));
       return;
     }
+  com_err(whoami, 0, "Updating list %s membership for user %s.", group_name,
+          user_name);
   av[0] = group_name;
   call_args[0] = (char *)ldap_handle;
   call_args[1] = dn_path;
@@ -580,29 +672,41 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
   call_args[3] = NULL;
   call_args[4] = NULL;
   call_args[5] = NULL;
+  call_args[6] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
   member_base = NULL;
   sid_base = NULL;
   sid_ptr = &sid_base;
   if (!(rc = mr_query("get_list_info", 1, av, group_create, call_args)))
     {
-      if (sid_base != NULL)
-        {
-          sid_update(ldap_handle, dn_path);
-          linklist_free(sid_base);
-        }
-      member_base = NULL;
-      if (!(rc = mr_query("get_members_of_list", 1, av, member_list_build,
-                          call_args)))
+      rc = 1;
+      if ((call_args[3] != NULL) && (call_args[4] != NULL) && (call_args[5]
+= NULL))
         {
-          if (member_base == NULL)
+          rc = 0;
+          if (sid_base != NULL)
             {
-              member_remove(ldap_handle, dn_path, group_name,
-                            call_args[3], call_args[4], call_args[5]);
+              sid_update(ldap_handle, dn_path);
+              linklist_free(sid_base);
+              sid_base = NULL;
             }
-          else
+          member_base = NULL;
+          sleep(1);
+
+          if (!(rc = mr_query("get_end_members_of_list", 1, av, member_list_build,
+                              call_args)))
             {
-              rc = member_list_process(ldap_handle, dn_path, group_name,
-                                       call_args[3], call_args[4], call_args[5]);
+              if (member_base == NULL)
+                {
+                  member_remove(ldap_handle, dn_path, group_name,
+                                call_args[3], call_args[4], call_args[5]);
+                }
+              else
+                {
+                  rc = member_list_process(ldap_handle, dn_path, group_name,
+                                           call_args[3], call_args[4], call_args[5],
+                                           MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+                  expand_groups(ldap_handle, dn_path, group_name);
+                }
             }
         }
     }
@@ -616,6 +720,8 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
                        user_name, group_name);
     }
   linklist_free(member_base);
+  linklist_free(sid_base);
+  member_base = NULL;
   if (call_args[3] != NULL)
     free(call_args[3]);
   if (call_args[4] != NULL)
@@ -624,13 +730,33 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
 }
 
 
-void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname, 
-             char *dn_path, char **before, int beforec, char **after, 
+void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 
+             char **before, int beforec, char **after, 
              int afterc)
 {
-  int       rc;
-  char      *av[2];
-  char      *call_args[6];
+  int   rc;
+  char  *av[2];
+  char  *call_args[6];
+  int   astate;
+  int   bstate;
+
+  if ((beforec == 0) || (afterc == 0))
+    return;
+
+  astate = 0;
+  bstate = 0;
+  if (afterc > U_STATE)
+    astate = atoi(after[U_STATE]);
+  if (beforec > U_STATE)
+    bstate = atoi(before[U_STATE]);
+
+  if (astate == 2)
+    astate = 1;
+  if (bstate == 2)
+    bstate = 1;
+
+  if ((bstate == 0) && (astate == 0))
+    return;
 
   if (rc = moira_connect())
     {
@@ -640,62 +766,63 @@ void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
       return;
     }
 
-  if ((beforec == 1) && (afterc == 0))
+  if (astate == bstate)
     {
-      com_err(whoami, 0, "Updating user %s info", before[BEFORE_U_NAME]);
-      av[0] = before[BEFORE_U_NAME];
-      call_args[0] = (char *)ldap_handle;
-      call_args[1] = dn_path;
-      sid_base = NULL;
-      sid_ptr = &sid_base;
-      callback_rc = 0;
-      if (rc = mr_query("get_user_account_by_login", 1, av, user_update,
-                        call_args))
+      if (!strcmp(before[U_NAME], after[U_NAME]))
         {
-          critical_alert("AD incremental",
-                         "Could not update user %s info : %s",
-                         before[BEFORE_U_NAME], 
-                         error_message(rc));
+          com_err(whoami, 0, "Updating user %s info", before[U_NAME]);
+          av[0] = before[U_NAME];
+          call_args[0] = (char *)ldap_handle;
+          call_args[1] = dn_path;
+          sid_base = NULL;
+          sid_ptr = &sid_base;
+          callback_rc = 0;
+          if (rc = mr_query("get_user_account_by_login", 1, av, user_update,
+                            call_args))
+            {
+              if (callback_rc != LDAP_NO_SUCH_OBJECT)
+                {
+                  critical_alert("AD incremental",
+                                 "Could not update user %s info : %s",
+                                 before[U_NAME], 
+                                 error_message(rc));
+                  goto cleanup;
+                }
+            }
         }
-      goto cleanup;
-    }
-  if ((beforec != 0) && (afterc != 0))
-    {
-      if (beforec != afterc)
-        return;
-      if (!strcmp(before[BEFORE_U_NAME], after[AFTER_U_NAME]))
-        return;
-      com_err(whoami, 0, "Changing user %s to %s", before[BEFORE_U_NAME],
-              after[AFTER_U_NAME]);
-      av[0] = after[AFTER_U_NAME];
-      call_args[0] = (char *)ldap_handle;
-      call_args[1] = dn_path;
-      call_args[2] = (char *)MEMBER_ACTIVATE;
-      call_args[3] = before[BEFORE_U_NAME];
-      sid_base = NULL;
-      sid_ptr = &sid_base;
-      callback_rc = 0;
-      if (rc = mr_query("get_user_account_by_login", 1, av, user_rename,
-                        call_args))
+      else
         {
-          if (rc != LDAP_NO_SUCH_OBJECT)
+          com_err(whoami, 0, "Changing user %s to %s", before[U_NAME],
+                  after[U_NAME]);
+          av[0] = after[U_NAME];
+          call_args[0] = (char *)ldap_handle;
+          call_args[1] = dn_path;
+          call_args[2] = (char *)MEMBER_ACTIVATE;
+          call_args[3] = before[U_NAME];
+          sid_base = NULL;
+          sid_ptr = &sid_base;
+          callback_rc = 0;
+          if (rc = mr_query("get_user_account_by_login", 1, av, user_rename,
+                            call_args))
             {
-              critical_alert("AD incremental",
-                             "Could not change user %s to %s : %s",
-                             before[BEFORE_U_NAME], 
-                             after[AFTER_U_NAME], error_message(rc));
-              goto cleanup;
+              if (callback_rc != LDAP_NO_SUCH_OBJECT)
+                {
+                  critical_alert("AD incremental",
+                                 "Could not change user %s to %s : %s",
+                                 before[U_NAME], 
+                                 after[U_NAME], error_message(rc));
+                  goto cleanup;
+                }
             }
-          callback_rc = LDAP_NO_SUCH_OBJECT;
         }
       if (callback_rc != LDAP_NO_SUCH_OBJECT)
         goto cleanup;
-      beforec = 0;
+      bstate = 0;
     }
-  if (beforec != 0)
+  if (bstate == 1)
     {
-      com_err(whoami, 0, "Deactivate user %s in the AD", before[BEFORE_U_NAME]);
-      av[0] = before[BEFORE_U_NAME];
+      com_err(whoami, 0, "Deactivate user %s in the AD", before[U_NAME]);
+      av[0] = before[U_NAME];
       call_args[0] = (char *)ldap_handle;
       call_args[1] = dn_path;
       call_args[2] = (char *)MEMBER_DEACTIVATE;
@@ -704,16 +831,16 @@ void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
         {
           critical_alert("AD incremental",
                          "Couldn't deactivate user %s in the AD : %s",
-                         before[BEFORE_U_NAME], error_message(rc));
+                         before[U_NAME], error_message(rc));
         }
       goto cleanup;
     }
-  if (afterc != 0)
+  if (astate == 1)
     {
       com_err(whoami, 0, "%s user %s", "Creating/Reactivating",
-              after[AFTER_U_NAME]);
+              after[U_NAME]);
 
-      av[0] = after[AFTER_U_NAME];
+      av[0] = after[U_NAME];
       call_args[0] = (char *)ldap_handle;
       call_args[1] = dn_path;
       call_args[2] = (char *)MEMBER_ACTIVATE;
@@ -724,7 +851,7 @@ void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
                         call_args))
         {
           critical_alert("AD incremental", "Couldn't create/activate user %s : %s",
-                         after[AFTER_U_NAME], error_message(rc));
+                         after[U_NAME], error_message(rc));
           goto cleanup;
         }
       if (sid_base != NULL)
@@ -1106,38 +1233,30 @@ int moira_connect(void)
   return 0;
 }
 
-int moira_disconnect(void)
+void check_winad(void)
 {
-
-  if (!--mr_connections)
+  int i;
+  
+  for (i = 0; file_exists(STOP_FILE); i++)
     {
-      mr_disconnect();
+      if (i > 30)
+        {
+          critical_alert("incremental",
+                         "WINAD incremental failed (%s exists): %s",
+                         STOP_FILE, tbl_buf);
+          exit(1);
+        }
+      sleep(60);
     }
-  return 0;
 }
 
-int convert_domain_to_dn(char *domain, char **dnp)
+int moira_disconnect(void)
 {
-  char    *fp;
-  char    *dp;
-  char    dn[1024];
-  int     dnlen = 1;
-    
-  memset(dn, 0, sizeof(dn));
-  strcpy(dn, "dc=");
-  dp = dn+3;
-  for (fp = domain; *fp; fp++)
-    {
-      if (*fp == '.') 
-        {
-          strcpy(dp, ",dc=");
-          dp += 4;
-        }
-      else
-        *dp++ = *fp;
-    }
 
-  *dnp = (char *)strdup(dn);
+  if (!--mr_connections)
+    {
+      mr_disconnect();
+    }
   return 0;
 }
 
@@ -1456,7 +1575,7 @@ int group_create(int ac, char **av, void *ptr)
   attr_array[1] = NULL;
   sid_count = 0;
   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
-                               sid_ptr, &sid_count)) == LDAP_SUCCESS)
+                           sid_ptr, &sid_count)) == LDAP_SUCCESS)
     {
       if (sid_count == 1)
         {
@@ -1617,20 +1736,33 @@ int member_list_build(int ac, char **av, void *ptr)
   strcpy(temp, av[ACE_NAME]);
   if (!check_string(temp))
     return(0);
-  if (!strcmp(av[ACE_TYPE], "STRING"))
+  if (!strcmp(av[ACE_TYPE], "USER"))
     {
-    if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
-      return(0);
+      if (!((int)call_args[6] & MOIRA_USERS))
+        return(0);
+    }
+  else if (!strcmp(av[ACE_TYPE], "STRING"))
+    {
+      if (!((int)call_args[6] & MOIRA_STRINGS))
+        return(0);
+      if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
+        return(0);
     }
   else if (!strcmp(av[ACE_TYPE], "LIST"))
     {
-      strcpy(temp, av[ACE_NAME]);
+      if (!((int)call_args[6] & MOIRA_LISTS))
+        return(0);
     }
-  else if (strcmp(av[ACE_TYPE], "USER"))
+  else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
     {
-    if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
-      return(0);
+      if (!((int)call_args[6] & MOIRA_KERBEROS))
+        return(0);
+      if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
+        return(0);
     }
+  else
+    return(0);
+
   linklist = member_base;
   while (linklist)
     {
@@ -1652,6 +1784,39 @@ int member_list_build(int ac, char **av, void *ptr)
   return(0);
 }
 
+int list_list_build(int ac, char **av, void *ptr)
+{
+  LK_ENTRY  *linklist;
+  char      temp[1024];
+  char      **call_args;
+
+  call_args = ptr;
+
+  strcpy(temp, av[L_NAME]);
+  if (!check_string(temp))
+    return(0);
+
+  linklist = member_base;
+  while (linklist)
+    {
+    if (!strcasecmp(temp, linklist->member))
+      return(0);
+    linklist = linklist->next;
+    }
+  linklist = calloc(1, sizeof(LK_ENTRY));
+  linklist->op = 1;
+  linklist->dn = NULL;
+  linklist->list = calloc(1, strlen(call_args[2]) + 1);
+  strcpy(linklist->list, call_args[2]);
+  linklist->type = calloc(1, strlen("LIST") + 1);
+  strcpy(linklist->type, "LIST");
+  linklist->member = calloc(1, strlen(temp) + 1);
+  strcpy(linklist->member, temp);
+  linklist->next = member_base;
+  member_base = linklist;
+  return(0);
+}
+
 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, 
                   char *group_ou, char *group_membership, char *group_gid)
 {
@@ -1736,7 +1901,8 @@ cleanup:
 #define USER_COUNT  5
 
 int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name, 
-                        char *group_ou, char *group_membership, char *group_gid)
+                        char *group_ou, char *group_membership, char *group_gid,
+                        int operation)
 {
   char        distinguished_name[1024];
   char        **modvalues;
@@ -1819,20 +1985,30 @@ int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name,
             }
           if (!strcmp(pPtr->type, "LIST"))
             {
+              if (!(operation & MOIRA_LISTS))
+                continue;
               args[0] = pPtr->member;
               rc = mr_query("get_list_info", 1, args, get_group_info, NULL);
               sprintf(temp, "(sAMAccountName=%s_zZx%c)", group_member, GroupType[0]);
             }
           else if (!strcmp(pPtr->type, "USER"))
             {
+              if (!(operation & MOIRA_USERS))
+                continue;
               sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, user_ou, dn_path);
             }
           else if (!strcmp(pPtr->type, "STRING"))
             {
+              if (!(operation & MOIRA_STRINGS))
+                continue;
+              if ((group_membership[0] != 'B') && (group_membership[0] != 'D'))
+                continue;
               sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, contact_ou, dn_path);
             }
           else
             {
+              if (!(operation & MOIRA_KERBEROS))
+                continue;
               sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, kerberos_ou, dn_path);
             }
           strcat(filter_exp, temp);
@@ -1918,6 +2094,7 @@ int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
   char new_dn[256];
   char cn_user_name[256];
   char contact_name[256];
+  char *email_v[] = {NULL, NULL};
   char *cn_v[] = {NULL, NULL};
   char *contact_v[] = {NULL, NULL};
   char *objectClass_v[] = {"top", "person", 
@@ -1942,6 +2119,7 @@ int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
   contact_v[0] = contact_name;
   name_v[0] = user;
   desc_v[0] = "Auto account created by Moira";
+  email_v[0] = user;
 
   strcpy(new_dn, cn_user_name);
   n = 0;
@@ -1950,11 +2128,28 @@ int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
+  if (!strcmp(group_ou, contact_ou))
+    {
+      ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
+    }
   mods[n] = NULL;
 
   rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
   for (i = 0; i < n; i++)
     free(mods[i]);
+  if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
+    {
+      n = 0;
+      ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
+      ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
+      ADD_ATTR("name", name_v, LDAP_MOD_ADD);
+      ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
+      ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
+      mods[n] = NULL;
+      rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
+      for (i = 0; i < n; i++)
+        free(mods[i]);
+    }
   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
     {
       critical_alert("AD incremental - contact create", 
@@ -1974,12 +2169,19 @@ int user_update(int ac, char **av, void *ptr)
   char user_name[256];
   char *uid_v[] = {NULL, NULL};
   char *mitid_v[] = {NULL, NULL};
+  char *homedir_v[] = {NULL, NULL};
+  char *winProfile_v[] = {NULL, NULL};
+  char *drives_v[] = {NULL, NULL};
   int  n;
   int  rc;
   int  i;
   char **call_args;
   char filter_exp[256];
   char *attr_array[3];
+  char **hp;
+  char path[256];
+  char winPath[256];
+  char winProfile[256];
 
   call_args = ptr;
 
@@ -2011,6 +2213,7 @@ int user_update(int ac, char **av, void *ptr)
       critical_alert("AD incremental - user update",
                      "LDAP server unable to find user %s in AD.",
                       user_name);
+      callback_rc = LDAP_NO_SUCH_OBJECT;
       goto cleanup;
     }
   strcpy(distinguished_name, group_base->dn);
@@ -2027,6 +2230,24 @@ int user_update(int ac, char **av, void *ptr)
       mitid_v[0] = av[U_MITID];
       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
     }
+  if ((hp = hes_resolve(user_name, "filsys")) != NULL)
+    {
+      memset(path, 0, sizeof(path));
+      memset(winPath, 0, sizeof(winPath));
+      sscanf(hp[0], "%*s %s", path);
+      if (strlen(path) && strnicmp(path, AFS, strlen(AFS)) == 0)
+        {
+          AfsToWinAfs(path, winPath);
+          homedir_v[0] = winPath;
+          ADD_ATTR("homeDirectory", homedir_v, LDAP_MOD_REPLACE);
+          strcpy(winProfile, winPath);
+          strcat(winProfile, "\\.winprofile");
+          winProfile_v[0] = winProfile;
+          ADD_ATTR("profilePath", winProfile_v, LDAP_MOD_REPLACE);
+          drives_v[0] = "H:";
+          ADD_ATTR("homeDrive", drives_v, LDAP_MOD_REPLACE);
+        }
+    }
   mods[n] = NULL;
   if (n != 0)
     {
@@ -2039,6 +2260,15 @@ int user_update(int ac, char **av, void *ptr)
       for (i = 0; i < n; i++)
         free(mods[i]);
     }
+  if (hp != NULL)
+    {
+      i = 0;
+      while (hp[i])
+        {
+          free(hp[i]);
+          i++;
+        }
+    }
 
 cleanup:
   linklist_free(group_base);
@@ -2138,6 +2368,117 @@ int user_rename(int ac, char **av, void *ptr)
   return(0);
 }
 
+int filesys_process(int ac, char **av, void *ptr)
+{
+  char  distinguished_name[256];
+  char  winPath[256];
+  char  winProfile[256];
+  char  fs_name[128];
+  char  filter_exp[256];
+  char  *attr_array[3];
+  char  *homedir_v[] = {NULL, NULL};
+  char  *winProfile_v[] = {NULL, NULL};
+  char  *drives_v[] = {NULL, NULL};
+  char  **call_args;
+  int   group_count;
+  int   n;
+  int   rc;
+  int   i;
+  int   operation;
+  LDAPMod   *mods[20];
+  LK_ENTRY  *group_base;
+
+  call_args = ptr;
+
+  if (!check_string(av[FS_NAME]))
+    {
+      critical_alert("AD incremental - user filesys",
+                      "invalid filesys name %s",
+                      av[FS_NAME]);
+      return(0);
+    }
+
+
+  if (strcmp(av[FS_TYPE], "AFS"))
+    {
+      critical_alert("AD incremental - user filesys",
+                      "invalid filesys type %s",
+                      av[FS_TYPE]);
+      return(0);
+    }
+
+  sleep(10);
+  strcpy(fs_name, av[FS_NAME]);
+  group_count = 0;
+  group_base = NULL;
+  sprintf(filter_exp, "(sAMAccountName=%s)", av[FS_NAME]);
+  attr_array[0] = "cn";
+  attr_array[1] = NULL;
+  if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
+                           &group_base, &group_count)) != 0)
+    {
+      critical_alert("AD incremental - user update",
+                     "LDAP server couldn't process filesys %s : %s",
+                      fs_name, ldap_err2string(rc));
+      goto cleanup;
+    }
+
+  if (group_count != 1)
+    {
+      critical_alert("AD incremental - user update",
+                     "LDAP server unable to find user %s in AD.",
+                      fs_name);
+      callback_rc = LDAP_NO_SUCH_OBJECT;
+      goto cleanup;
+    }
+  strcpy(distinguished_name, group_base->dn);
+
+  operation = LDAP_MOD_ADD;
+  if ((int)call_args[3] == ADFS_DELETE)
+    operation = LDAP_MOD_DELETE;
+
+  n = 0;
+  if (operation == LDAP_MOD_ADD)
+    {
+      memset(winPath, 0, sizeof(winPath));
+      AfsToWinAfs(av[FS_PACK], winPath);
+      homedir_v[0] = winPath;
+      drives_v[0] = "H:";
+      memset(winProfile, 0, sizeof(winProfile));
+      strcpy(winProfile, winPath);
+      strcat(winProfile, "\\.winprofile");
+      winProfile_v[0] = winProfile;
+    }
+  else
+    {
+      homedir_v[0] = NULL;
+      drives_v[0] = NULL;
+      winProfile_v[0] = NULL;
+    }
+  ADD_ATTR("profilePath", winProfile_v, operation);
+  ADD_ATTR("homeDrive", drives_v, operation);
+  ADD_ATTR("homeDirectory", homedir_v, operation);
+  mods[n] = NULL;
+
+  for (i = 1; i < 6; i++)
+    {
+      if ((rc = ldap_modify_s((LDAP *)call_args[0], distinguished_name, mods)) == LDAP_SUCCESS)
+        break;
+      sleep(10);
+    }
+  if (rc != LDAP_SUCCESS)
+    {
+      critical_alert("AD incremental - filesys update", 
+                     "Couldn't modify user data for filesys %s : %s",
+                     fs_name, ldap_err2string(rc));
+    }
+  for (i = 0; i < n; i++)
+    free(mods[i]);
+
+cleanup:
+  return(0);
+}
+
 int user_create(int ac, char **av, void *ptr)
 {
   LDAPMod *mods[20];
@@ -2241,14 +2582,11 @@ int user_create(int ac, char **av, void *ptr)
     }
   if (rc == LDAP_SUCCESS)
     {
-      if ((rc = set_password(sam_name, ldap_domain)) != 0)
+      if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
         {
-          if ((rc = set_password(user_name, ldap_domain)) != 0)
-            {
-              critical_alert("AD incremental - user create", 
-                             "Couldn't set password for user %s : %ld",
-                             user_name, rc);
-            }
+          critical_alert("AD incremental - user create", 
+                         "Couldn't set password for user %s : %ld",
+                         user_name, rc);
         }
     }
   sprintf(filter_exp, "(sAMAccountName=%s)", av[U_NAME]);
@@ -2531,14 +2869,15 @@ int check_string(char *s)
 
 int mr_connect_cl(char *server, char *client, int version, int auth)
 {
-  int status;
-  char *motd;
+  int   status;
+  char  *motd;
+  char  temp[128];
 
   status = mr_connect(server);
   if (status)
     {
       com_err(whoami, status, "while connecting to Moira");
-      return MRCL_FAIL;
+      return status;
     }
 
   status = mr_motd(&motd);
@@ -2546,51 +2885,204 @@ int mr_connect_cl(char *server, char *client, int version, int auth)
     {
       mr_disconnect();
       com_err(whoami, status, "while checking server status");
-      return MRCL_FAIL;
+      return status;
     }
   if (motd)
     {
-      fprintf(stderr, "The Moira server is currently unavailable:\n%s\n",
-                   motd);
+      sprintf(temp, "The Moira server is currently unavailable: %s", motd);
+      com_err(whoami, status, temp);
       mr_disconnect();
-      return MRCL_FAIL;
+      return status;
     }
 
   status = mr_version(version);
   if (status)
     {
       if (status == MR_UNKNOWN_PROC)
-             {
-               if (version > 2)
-                 status = MR_VERSION_HIGH;
-               else
-                 status = MR_SUCCESS;
-             }
+        {
+          if (version > 2)
+            status = MR_VERSION_HIGH;
+          else
+            status = MR_SUCCESS;
+        }
 
       if (status == MR_VERSION_HIGH)
-             {
-               com_err(whoami, 0, "Warning: This client is running newer code than the server.");
-               com_err(whoami, 0, "Some operations may not work.");
-             }
+        {
+          com_err(whoami, 0, "Warning: This client is running newer code than the server.");
+                  com_err(whoami, 0, "Some operations may not work.");
+        }
       else if (status && status != MR_VERSION_LOW)
-             {
-               com_err(whoami, status, "while setting query version number.");
-               mr_disconnect();
-               return MRCL_FAIL;
-             }
+        {
+          com_err(whoami, status, "while setting query version number.");
+          mr_disconnect();
+          return status;
+        }
     }
 
   if (auth)
     {
       status = mr_auth(client);
       if (status)
-             {
-               com_err(whoami, status, "while authenticating to Moira.");
-               mr_disconnect();
-               return MRCL_AUTH_ERROR;
-             }
+        {
+          com_err(whoami, status, "while authenticating to Moira.");
+          mr_disconnect();
+          return status;
+        }
     }
 
-  return MRCL_SUCCESS;
+  return MR_SUCCESS;
+}
+
+void expand_groups(LDAP *ldap_handle, char *dn_path, char *group_name)
+{
+  LK_ENTRY  *group_base = NULL;
+  LK_ENTRY  *ptr = NULL;
+  char      *call_args[7];
+  char      *av[2];
+  int       rc;
+  int       before_count;
+  int       after_count;
+
+  av[0] = "RLIST";
+  av[1] = group_name;
+  call_args[0] = (char *)ldap_handle;
+  call_args[1] = dn_path;
+  call_args[2] = group_name;
+  call_args[3] = NULL;
+
+  linklist_free(member_base);
+  member_base = NULL;
+  linklist_free(sid_base);
+  sid_base = NULL;
+  if (mr_query("get_lists_of_member", 2, av, list_list_build, call_args) == MR_NO_MATCH)
+    return;
+  if (member_base == NULL)
+    return;
+  while (1)
+    {
+      group_base = member_base;
+      ptr = group_base;
+      before_count = 0;
+      while(ptr != NULL)
+        {
+          ++before_count;
+          ptr = ptr->next;
+        }
+      ptr = group_base;
+      while (ptr != NULL)
+        {
+          sleep(1);
+          av[0] = "RLIST";
+          av[1] = ptr->member;
+          call_args[0] = (char *)ldap_handle;
+          call_args[1] = dn_path;
+          call_args[2] = ptr->member;
+          call_args[3] = NULL;
+          mr_query("get_lists_of_member", 2, av, list_list_build, call_args);
+          ptr = ptr->next;
+        }
+      after_count = 0;
+      ptr = group_base;
+      while(ptr != NULL)
+        {
+          ++after_count;
+          ptr = ptr->next;
+        }
+      if (before_count == after_count)
+        break;
+    }
+
+  group_base = member_base;
+  ptr = group_base;
+  while (ptr != NULL)
+    {
+      sleep(1);
+      member_base = NULL;
+      sid_base = NULL;
+      sid_ptr = &sid_base;
+      av[0] = ptr->member;
+      av[1] = NULL;
+      call_args[0] = (char *)ldap_handle;
+      call_args[1] = dn_path;
+      call_args[2] = ptr->member;
+      call_args[3] = NULL;
+      call_args[4] = NULL;
+      call_args[5] = NULL;
+      call_args[6] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+      if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
+        {
+          linklist_free(member_base);
+          linklist_free(sid_base);
+          sid_base = NULL;
+          member_base = NULL;
+          ptr = ptr->next;
+          continue;
+        }
+      if ((call_args[3] == NULL) || (call_args[4] == NULL) || (call_args[5] == NULL))
+        {
+          linklist_free(member_base);
+          linklist_free(sid_base);
+          sid_base = NULL;
+          member_base = NULL;
+          ptr = ptr->next;
+          continue;
+        }
+      if (sid_base != NULL)
+        {
+          sid_update(ldap_handle, dn_path);
+          linklist_free(sid_base);
+          sid_base = NULL;
+        }
+      sleep(1);
+      member_base = NULL;
+      if (!(rc = mr_query("get_end_members_of_list", 1, av, member_list_build,
+                          call_args)))
+        {
+          if (member_base == NULL)
+            {
+              member_remove(ldap_handle, dn_path, ptr->member,
+                            call_args[3], call_args[4], call_args[5]);
+            }
+          else
+            {
+              rc = member_list_process(ldap_handle, dn_path, ptr->member,
+                                       call_args[3], call_args[4], call_args[5],
+                                       MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+            }
+        }
+      linklist_free(member_base);
+      member_base = NULL;
+      if (call_args[3] != NULL)
+        free(call_args[3]);
+      if (call_args[4] != NULL)
+        free(call_args[4]);
+      call_args[3] = NULL;
+      call_args[4] = NULL;
+      call_args[5] = NULL;
+      call_args[6] = NULL;
+      ptr = ptr->next;
+    }
+  linklist_free(group_base);
+  group_base = NULL;
+  return;
 }
 
+void AfsToWinAfs(char* path, char* winPath)
+{
+    char* pathPtr;
+    char* winPathPtr;
+    strcpy(winPath, WINAFS);
+    pathPtr = path + strlen(AFS);
+    winPathPtr = winPath + strlen(WINAFS);
+
+    while (*pathPtr)
+    {
+        if (*pathPtr == '/')
+          *winPathPtr = '\\';
+        else
+          *winPathPtr = *pathPtr;
+
+        pathPtr++;
+        winPathPtr++;
+    }
+}
This page took 0.107736 seconds and 4 git commands to generate.