]> andersk Git - moira.git/commitdiff
Work in a mult-server Win2k domain.
authorzacheiss <zacheiss>
Mon, 23 Apr 2001 02:11:22 +0000 (02:11 +0000)
committerzacheiss <zacheiss>
Mon, 23 Apr 2001 02:11:22 +0000 (02:11 +0000)
Implement filesys incremental processing.

incremental/winad/kpasswd.h
incremental/winad/krb5_utils.c
incremental/winad/setpw.c
incremental/winad/winad.c

index cfd51088a0bf16741900e3b6bd91afa1cd599954..37f19d72437bc09e11359b8d60815debf6d0d763 100644 (file)
@@ -1,52 +1,49 @@
 /*--
-
-THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
-ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
-PARTICULAR PURPOSE.
-
-Copyright (C) 1999  Microsoft Corporation.  All rights reserved.
-
 Module Name:
 
     kpasswd.h
 
-Abstract:
-
-    Definitions for the Kerberos change password functions
-
 --*/
 
-/* changepw.h */
-krb5_error_code krb5_set_password
-       KRB5_PROTOTYPE((krb5_context, krb5_ccache, char *, char *, char *, int *));
-
-/*krb5_error_code 
-(krb5_context, const krb5_data *, struct sockaddr **, int *);
-*/
 
-/* password change constants */
+krb5_error_code krb5_set_password
+  KRB5_PROTOTYPE((krb5_context, krb5_ccache, char *, char *, char *, int *));
 
 typedef struct _krb5_setpw {
-       krb5_magic      magic;
-       krb5_data       newpasswd;
-       krb5_principal  targprinc;
+  krb5_magic      magic;
+  krb5_data       newpasswd;
+  krb5_principal  targprinc;
 } krb5_setpw;
 
+
+#define MAX_SERVER_NAMES 32
+#ifndef T_SRV
+#define T_SRV 33
+#endif
+#define LDAP_SERVICE  "_ldap"
+#define TCP_PROTOCOL  "_tcp"
+
+#define KDC_RECEIVE_TIMEOUT       10
+#define KDC_RECEIVE_ERROR         11
+#define KDC_SEND_ERROR            12
+#define KDC_GETSOCKNAME_ERROR     13
+#define KDC_GETPEERNAME_ERROR     14
+
 #ifndef KRB5_KPASSWD_SUCCESS
-#define KRB5_KPASSWD_SUCCESS           0
-#define KRB5_KPASSWD_MALFORMED         1
-#define KRB5_KPASSWD_HARDERROR         2
-#define KRB5_KPASSWD_AUTHERROR         3
-#define KRB5_KPASSWD_SOFTERROR         4
+#define KRB5_KPASSWD_SUCCESS              0
+#define KRB5_KPASSWD_MALFORMED            1
+#define KRB5_KPASSWD_HARDERROR            2
+#define KRB5_KPASSWD_AUTHERROR            3
+#define KRB5_KPASSWD_SOFTERROR            4
 #endif
-#define KRB5_KPASSWD_ACCESSDENIED      5
-#define KRB5_KPASSWD_BAD_VERSION       6
-#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED 7
+#define KRB5_KPASSWD_ACCESSDENIED         5
+#define KRB5_KPASSWD_BAD_VERSION          6
+#define KRB5_KPASSWD_INITIAL_FLAG_NEEDED  7
 
-#define KRB5_KPASSWD_VERS_CHANGEPW     1
-#define KRB5_KPASSWD_VERS_SETPW                0xff80
+#define KRB5_KPASSWD_VERS_CHANGEPW        1
+#define KRB5_KPASSWD_VERS_SETPW           0xff80
 
 #ifndef DEFAULT_KPASSWD_PORT
-#define DEFAULT_KPASSWD_PORT   464
+#define DEFAULT_KPASSWD_PORT 464
 #endif
+
index 68a1571dce34f11cd954dd9808a02273aa658629..4e8a7aa3299744ae94fb70ffc96065971a15a6a1 100644 (file)
@@ -9,6 +9,7 @@ Abstract:
 --*/
 
 #include <krb5.h>
+#include <ldap.h>
 #ifdef _WIN32
 #include "asn1_make.h"
 #endif
@@ -31,10 +32,6 @@ Abstract:
 #endif
 #endif
 
-#ifndef T_SRV
-#define T_SRV 33
-#endif
-
 #ifndef _WIN32
 typedef krb5_octet asn1_octet;
 typedef krb5_error_code asn1_error_code;
@@ -42,7 +39,7 @@ typedef struct code_buffer_rep {
   char *base, *bound, *next;
 } asn1buf;
 typedef enum { UNIVERSAL = 0x00, APPLICATION = 0x40,
-                CONTEXT_SPECIFIC = 0x80, PRIVATE = 0xC0 } asn1_class;
+               CONTEXT_SPECIFIC = 0x80, PRIVATE = 0xC0 } asn1_class;
 #endif
 
 static const char rcsid[] = "$Id$";
@@ -135,131 +132,3 @@ krb5_error_code encode_krb5_setpw(const krb5_setpw *rep,
   krb5_cleanup();
 }
 
-krb5_error_code
-krb5_locate_dns_srv(krb5_context context, const krb5_data *realm,
-                    const char *service, const char *protocol,
-                    struct sockaddr **addr_pp, int *naddrs)
-{
-  int             len;
-  int             out;
-  int             j;
-  int             count;
-  unsigned char   reply[1024];
-  struct hostent  *hp;
-  unsigned char   *p;
-  char            host[128];
-  int             status;
-  int             priority;
-  int             weight;
-  u_short         port;
-  struct sockaddr *addr_p = NULL;
-  struct sockaddr_in *sin_p;
-    
-  out = 0;
-  addr_p = (struct sockaddr *)malloc (sizeof (struct sockaddr));
-  if (addr_p == NULL)
-         return(ENOMEM);
-  count = 1;
-
-#ifdef HAVE_SNPRINTF
-  snprintf(host, sizeof(host), "%s.%s.%*s.",
-                service, protocol, realm->length, realm->data);
-#else
-  sprintf(host, "%s.%s.%*s.",
-               service, protocol, realm->length, realm->data);
-#endif
-  len = res_search(host, C_IN, T_SRV, reply, sizeof(reply));
-  if (len >=0)
-    {
-         p = reply;
-           p += sizeof(HEADER);
-           status = dn_expand(reply, reply + len, p, host, sizeof(host));
-         if (status < 0)
-             goto out;
-           p += status;
-         p += 4;
-         while (p < reply + len)
-        {
-               int type, class, ttl, size;
-               status = dn_expand(reply, reply + len, p, host, sizeof(host));
-               if (status < 0)
-                       goto out;
-             p += status;
-               type = (p[0] << 8) | p[1];
-               p += 2;
-               class = (p[0] << 8) | p[1];
-               p += 2;
-             ttl = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3];
-               p += 4;
-               size = (p[0] << 8) | p[1];
-               p += 2;
-               if (type == T_SRV)
-            {
-                         status = dn_expand(reply, reply + len, p + 6, host, sizeof(host));
-                       if (status < 0)
-                         goto out;
-                         priority = (p[0] << 8) | p[1];
-                         weight = (p[2] << 8) | p[3];
-                         port = (p[4] << 8) | p[5];
-                       hp = (struct hostent *)gethostbyname(host);
-                       if (hp != 0)
-                {
-                             switch (hp->h_addrtype)
-                    {
-#ifdef KRB5_USE_INET
-                                 case AF_INET:
-                                         for (j=0; hp->h_addr_list[j]; j++)
-                          {
-                                             sin_p = (struct sockaddr_in *) &addr_p[out++];
-                                             memset ((char *)sin_p, 0, sizeof(struct sockaddr));
-                                             sin_p->sin_family = hp->h_addrtype;
-                                             sin_p->sin_port = htons(port);
-                                             memcpy((char *)&sin_p->sin_addr,
-                                                   (char *)hp->h_addr_list[j],
-                                                 sizeof(struct in_addr));
-                                           if (out+1 >= count)
-                              {
-                                                     count += 5;
-                                                       addr_p = (struct sockaddr *)
-                                                       realloc ((char *)addr_p,
-                                                             sizeof(struct sockaddr) * count);
-                                                       if (!addr_p)
-                                                         goto out;
-                                               }
-                                           }
-                                         break;
-#endif
-                               default:
-                                       break;
-                               }
-                           }
-                         p += size;
-                 }
-             }
-    }
-    
-out:
-  if (out == 0)
-    {
-     free(addr_p);
-     return(KRB5_REALM_CANT_RESOLVE);
-    }
-
-  *addr_pp = addr_p;
-  *naddrs = out;
-  return(0);
-}
-
-krb5_error_code 
-krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
-                    struct sockaddr **addr_pp, int *naddrs)
-{
-  krb5_error_code code;
-       code = krb5_locate_dns_srv(context, realm, "_kpasswd", "_tcp",
-                                  addr_pp, naddrs);
-  if (code)
-    code = krb5_locate_dns_srv(context, realm, "_kpasswd", "_udp",
-                               addr_pp, naddrs);
-
-  return(code);
-}
index 85c42867f7ae0064e51132560c5e63da0a411d5c..ed6af233540de1510257ee6abb0c54b338924bdb 100644 (file)
@@ -9,7 +9,7 @@ Copyright (C) 1999  Microsoft Corporation.  All rights reserved.
 
 Module Name:
 
-    ksetpw.c
+    setpw.c
 
 Abstract:
 
@@ -41,35 +41,44 @@ Abstract:
  * 
  */
 
+
 #define NEED_SOCKETS
 #include <krb5.h>
 #include <krb.h>
+#include <ldap.h>
 #ifdef _WIN32
+#include <wshelper.h>
 #include "k5-int.h"
 #include "adm_err.h"
 #include "krb5_err.h"
-#endif
-#include <auth_con.h>
-#include "kpasswd.h"
-
-#ifndef _WIN32
+#else
 #include <sys/socket.h>
 #include <netdb.h>
 #include <sys/select.h>
 #endif
-
+#include <auth_con.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
 #include <sys/timeb.h>
 #include <errno.h>
+#include "kpasswd.h"
+#include "gsssasl.h"
+#include "gssldap.h"
 
 #define PW_LENGTH 25
+#define KDC_PORT  464
+#define ULONG     unsigned long
 
 #ifndef krb5_is_krb_error
 #define krb5_is_krb_error(dat)\
-        ((dat) && (dat)->length && ((dat)->data[0] == 0x7e ||\
-        (dat)->data[0] == 0x5e))
+            ((dat) && (dat)->length && ((dat)->data[0] == 0x7e ||\
+            (dat)->data[0] == 0x5e))
+#endif
+
+#ifdef _WIN32
+#define sleep(Seconds) Sleep(Seconds * 1000)
+#define gethostbyname(Server) rgethostbyname(Server)
 #endif
 
 /* Win32 defines. */
@@ -162,18 +171,38 @@ static int start_freq [26] =
 /*
  * This MUST be equal to the sum of all elements in the above array.
  */
+
+struct sockaddr_in  kdc_server;
+SOCKET              kdc_socket;
+krb5_context        context;
+krb5_ccache         ccache;
+krb5_auth_context   auth_context = NULL;
+krb5_data           ap_req;
+krb5_creds          *credsp = NULL;
+krb5_creds          creds;
+char                connected_server[128];
+
 static int total_sum = 11646;
 
+int get_krb5_error(krb5_error_code rc, char *in, char *out);
+int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, 
+               char *Win2kPassword, char *Win2kUser, char *default_server, 
+               int connect_to_kdc);
+int ad_kdc_connect(char *connectedServer);
+int ad_server_connect(char *connectedServer, char *domain);
+void ad_kdc_disconnect();
+int compare_elements(const void *arg1, const void *arg2);
+int convert_domain_to_dn(char *domain, char *dnp);
+int set_password(char *user, char *password, char *domain);
+
+int locate_ldap_server(char *domain, char **server_name);
+
 long myrandom();
 void generate_password(char *password);
-int set_password(char *user, char *domain);
 krb5_error_code encode_krb5_setpw
-  PROTOTYPE((const krb5_setpw *rep, krb5_data ** code));
-krb5_error_code 
-krb5_locate_kpasswd(krb5_context context, const krb5_data *realm,
-                    struct sockaddr **addr_pp, int *naddrs);
+        PROTOTYPE((const krb5_setpw *rep, krb5_data ** code));
 
-krb5_error_code krb5_mk_setpw_req(krb5_context context,  krb5_auth_context auth_context,
+krb5_error_code make_setpw_req(krb5_context context,  krb5_auth_context auth_context,
                                   krb5_data *ap_req, krb5_principal targprinc,
                                   char *passwd, krb5_data *packet)
 {
@@ -185,7 +214,7 @@ krb5_error_code krb5_mk_setpw_req(krb5_context context,  krb5_auth_context auth_
   char             *ptr;
   register int     count = 2;
 
-  memset (&setpw, 0, sizeof(krb5_setpw));
+  memset(&setpw, 0, sizeof(krb5_setpw));
   if (ret = krb5_auth_con_setflags(context, auth_context,
                                    KRB5_AUTH_CONTEXT_DO_SEQUENCE))
     return(ret);
@@ -214,12 +243,15 @@ krb5_error_code krb5_mk_setpw_req(krb5_context context,  krb5_auth_context auth_
   ptr += ap_req->length;
   /* krb-priv of password */
   memcpy(ptr, cipherpw.data, cipherpw.length);
+  free(cipherpw.data);
+/*  krb5_free_data_contents(context, &cipherpw);*/
+  krb5_free_data(context, encoded_setpw);
   return(0);
 }
 
-krb5_error_code krb5_rd_setpw_rep(krb5_context context, krb5_auth_context auth_context,
-                                  krb5_data *packet, int *result_code,
-                                  krb5_data *result_data)
+krb5_error_code get_setpw_rep(krb5_context context, krb5_auth_context auth_context,
+                              krb5_data *packet, int *result_code,
+                              krb5_data *result_data)
 {
   char             *ptr;
   int              plen;
@@ -285,8 +317,10 @@ krb5_error_code krb5_rd_setpw_rep(krb5_context context, krb5_auth_context auth_c
     {
       cipherresult.data = ptr;
       cipherresult.length = (packet->data + packet->length) - ptr;
+
       if (ret = krb5_rd_error(context, &cipherresult, &krberror))
         return(ret);
+
       clearresult = krberror->e_data;
     }
   if (clearresult.length < 2)
@@ -307,7 +341,7 @@ krb5_error_code krb5_rd_setpw_rep(krb5_context context, krb5_auth_context auth_c
   if ((ap_rep.length == 0) && (*result_code == KRB5_KPASSWD_SUCCESS))
     {
       ret = KRB5KRB_AP_ERR_MODIFIED;
-      goto cleanup;
+        goto cleanup;
     }
   result_data->length = (clearresult.data + clearresult.length) - ptr;
   if (result_data->length)
@@ -316,184 +350,155 @@ krb5_error_code krb5_rd_setpw_rep(krb5_context context, krb5_auth_context auth_c
       memcpy(result_data->data, ptr, result_data->length);
     }
   else
-    result_data->data = NULL;
+      result_data->data = NULL;
   ret = 0;
 cleanup:
   if (ap_rep.length)
     free(clearresult.data);
   else
-    krb5_free_error(context, krberror);
+      krb5_free_error(context, krberror);
   return(ret);
 }
 
-krb5_error_code krb5_set_password(krb5_context context, krb5_ccache ccache,
+krb5_error_code kdc_set_password(krb5_context context, krb5_ccache ccache,
                                   char *newpw, char *user, char *domain,
                                   int *result_code)
 {
-  krb5_auth_context auth_context;
-  krb5_data         ap_req;
-  krb5_data         chpw_req;
-  krb5_data         chpw_rep;
+  krb5_data         chpw_snd;
+  krb5_data         chpw_rcv;
   krb5_data         result_string;
   krb5_address      local_kaddr;
   krb5_address      remote_kaddr;
   char              userrealm[256];
   char              temp[256];
   krb5_error_code   code;
-  krb5_creds        creds;
-  krb5_creds        *credsp;
-  struct sockaddr   *addr_p;
   struct sockaddr   local_addr;
   struct sockaddr   remote_addr;
-  struct sockaddr   tmp_addr;
-  SOCKET            s1;
-  SOCKET            s2;
   int               i;
-  int               out;
   int               addrlen;
   int               cc;
   int               local_result_code;
-  int               tmp_len;
-  int               error_count;
+  int               nfds;
   krb5_principal    targprinc;
-  int               count;
-  int               last_count;
+  struct timeval    TimeVal;
+  fd_set            readfds;
 
-  auth_context = NULL;
-  addr_p = NULL;
-  credsp = NULL;
   memset(&local_addr, 0, sizeof(local_addr));
   memset(&local_kaddr, 0, sizeof(local_kaddr));
   memset(&result_string, 0, sizeof(result_string));
   memset(&remote_kaddr, 0, sizeof(remote_kaddr));
-  memset(&chpw_req, 0, sizeof(krb5_data));
-  memset(&chpw_rep, 0, sizeof(krb5_data));
-  memset(&ap_req, 0, sizeof(krb5_data));
-  auth_context = NULL;
-  memset(&creds, 0, sizeof(creds));
+  memset(&chpw_snd, 0, sizeof(krb5_data));
+  memset(&chpw_rcv, 0, sizeof(krb5_data));
   memset(userrealm, '\0', sizeof(userrealm));
   targprinc = NULL;
+
+  chpw_rcv.length = 1500;
+  chpw_rcv.data = (char *) calloc(1, chpw_rcv.length);
+
   for (i = 0; i < (int)strlen(domain); i++)
     userrealm[i] = toupper(domain[i]);
 
   sprintf(temp, "%s@%s", user, userrealm);
   krb5_parse_name(context, temp, &targprinc);
 
-  sprintf(temp, "%s@%s", "kadmin/changepw", userrealm);
-  if (code = krb5_parse_name(context, temp, &creds.server))
-    goto cleanup;
-
-  if (code = krb5_cc_get_principal(context, ccache, &creds.client))
-    goto cleanup;
-  if (code = krb5_get_credentials(context, 0, ccache, &creds, &credsp))
-    goto cleanup;
-  if (code = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY,
-                                  NULL, credsp, &ap_req))
-    goto cleanup;
-  if (code = krb5_locate_kpasswd(context, &targprinc->realm, &addr_p, &out))
-    goto cleanup;
-  if (out == 0)
-    {     /* Couldn't resolve any KPASSWD names */
-      code = 1;
-      goto cleanup;
+  if (credsp == NULL)
+    {
+      memset(&creds, 0, sizeof(creds));
+      memset(&ap_req, 0, sizeof(krb5_data));
+      sprintf(temp, "%s@%s", "kadmin/changepw", userrealm);
+      if (code = krb5_parse_name(context, temp, &creds.server))
+        goto cleanup;
+      if (code = krb5_cc_get_principal(context, ccache, &creds.client))
+        goto cleanup;
+      if (code = krb5_get_credentials(context, 0, ccache, &creds, &credsp))
+        goto cleanup;
+      if (code = krb5_mk_req_extended(context, &auth_context, AP_OPTS_USE_SUBKEY,
+                                      NULL, credsp, &ap_req))
+        goto cleanup;
     }
 
-  if ((s1 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+  addrlen = sizeof(local_addr);
+  if (getsockname(kdc_socket, &local_addr, &addrlen) < 0)
     {
-      free(addr_p);
-      return(errno);
+      code = KDC_GETSOCKNAME_ERROR;
+      goto cleanup;
     }
-  if ((s2 = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+  if (((struct sockaddr_in *)&local_addr)->sin_addr.s_addr != 0)
     {
-      closesocket(s1);
-      free(addr_p);
-      return(errno);
+      local_kaddr.addrtype = ADDRTYPE_INET;
+      local_kaddr.length =
+        sizeof(((struct sockaddr_in *) &local_addr)->sin_addr);
+      local_kaddr.contents = 
+        (char *) &(((struct sockaddr_in *) &local_addr)->sin_addr);
     }
-  error_count = 0;
-  for (i=0; i<out; i++)
+  else
     {
-      if (connect(s2, &addr_p[i], sizeof(addr_p[i])) == SOCKET_ERROR)
-        continue;
-      addrlen = sizeof(local_addr);
-      if (getsockname(s2, &local_addr, &addrlen) < 0)
-        continue;
-      if (((struct sockaddr_in *)&local_addr)->sin_addr.s_addr != 0)
-        {
-printf("1\n");
-          local_kaddr.addrtype = ADDRTYPE_INET;
-          local_kaddr.length =
-            sizeof(((struct sockaddr_in *) &local_addr)->sin_addr);
-          local_kaddr.contents = 
-            (char *) &(((struct sockaddr_in *) &local_addr)->sin_addr);
-        }
-      else
-        {
-          krb5_address **addrs;
-          krb5_os_localaddr(context, &addrs);
-          local_kaddr.magic = addrs[0]->magic;
-          local_kaddr.addrtype = addrs[0]->addrtype;
-          local_kaddr.length = addrs[0]->length;
-          local_kaddr.contents = calloc(1, addrs[0]->length);
-          memcpy(local_kaddr.contents, addrs[0]->contents, addrs[0]->length);
-          krb5_free_addresses(context, addrs);
-        }
-
-      addrlen = sizeof(remote_addr);
-      if (getpeername(s2, &remote_addr, &addrlen) < 0)
-         continue;
-      remote_kaddr.addrtype = ADDRTYPE_INET;
-      remote_kaddr.length =
-        sizeof(((struct sockaddr_in *) &remote_addr)->sin_addr);
-      remote_kaddr.contents = 
-        (char *) &(((struct sockaddr_in *) &remote_addr)->sin_addr);
+      krb5_address **addrs;
+      krb5_os_localaddr(context, &addrs);
+      local_kaddr.magic = addrs[0]->magic;
+      local_kaddr.addrtype = addrs[0]->addrtype;
+      local_kaddr.length = addrs[0]->length;
+      local_kaddr.contents = calloc(1, addrs[0]->length);
+      memcpy(local_kaddr.contents, addrs[0]->contents, addrs[0]->length);
+      krb5_free_addresses(context, addrs);
+    }
 
-      if (code = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL))
-        goto cleanup;
-      if (code = krb5_mk_setpw_req(context, auth_context, &ap_req,
-                                   targprinc, newpw, &chpw_req))
-        goto cleanup;
+  addrlen = sizeof(remote_addr);
+  if (getpeername(kdc_socket, &remote_addr, &addrlen) < 0)
+    {
+      code = KDC_GETPEERNAME_ERROR;
+      goto cleanup;
+    }
+  remote_kaddr.addrtype = ADDRTYPE_INET;
+  remote_kaddr.length = sizeof(((struct sockaddr_in *) &remote_addr)->sin_addr);
+  remote_kaddr.contents = (char *) &(((struct sockaddr_in *) &remote_addr)->sin_addr);
 
-      if ((cc = sendto(s1, chpw_req.data, chpw_req.length, 0,
-                       (struct sockaddr *) &addr_p[i],
-                       sizeof(addr_p[i]))) != chpw_req.length)
-        continue;
+  if (code = krb5_auth_con_setaddrs(context, auth_context, &local_kaddr, NULL))
+    goto cleanup;
+  if (code = make_setpw_req(context, auth_context, &ap_req,
+                               targprinc, newpw, &chpw_snd))
+    goto cleanup;
 
-      if (chpw_req.data != NULL)
-        free(chpw_req.data);
-      chpw_rep.length = 1500;
-      chpw_rep.data = (char *) calloc(1, chpw_rep.length);
+  for (i = 0; i < 3; i++)
+    {
+      if ((cc = sendto(kdc_socket, chpw_snd.data, chpw_snd.length, 0,
+                       NULL,
+                       0)) != chpw_snd.length)
+        {
+          code = KDC_SEND_ERROR;
+          sleep(1);
+          continue;
+        }
 
-      tmp_len = sizeof(tmp_addr);
-      last_count = 0;
-      while (1)
+      TimeVal.tv_sec = 3;
+      TimeVal.tv_usec = 0;
+      FD_ZERO(&readfds);
+      FD_SET(kdc_socket, &readfds);
+      nfds = kdc_socket + 1;
+      code = select(nfds, &readfds, NULL, NULL, &TimeVal);
+      if ((code == 0) || (code == SOCKET_ERROR))
         {
-          cc = recvfrom(s1, chpw_rep.data, chpw_rep.length, MSG_PEEK, 
-                        &tmp_addr, &tmp_len);
-          if ((last_count == cc) && (cc != 0))
-            break;
-          last_count = cc;
-          if (cc == 0)
-            {
-              if (last_count == -1)
-                break;
-              last_count = -1;
-            }
+          code = KDC_RECEIVE_TIMEOUT;
           sleep(1);
+          continue;
         }
-      if ((cc = recvfrom(s1, chpw_rep.data, chpw_rep.length, 0, &tmp_addr, &tmp_len)) < 0)
+
+      if ((cc = recvfrom(kdc_socket, chpw_rcv.data, chpw_rcv.length, 0, 
+                         NULL, NULL)) < 0)
         {
-          code = errno;
-          goto cleanup;
+          code = KDC_RECEIVE_TIMEOUT;
+          sleep(1);
+          continue;
         }
-      chpw_rep.length = cc;
-      if (code = krb5_auth_con_setaddrs(context, auth_context, NULL,
-                                            &remote_kaddr))
+      chpw_rcv.length = cc;
+      if (code = krb5_auth_con_setaddrs(context, auth_context, NULL, &remote_kaddr))
         {
-          goto cleanup;
+          sleep(1);
+          continue;
         }
       local_result_code = 0;
-      code = krb5_rd_setpw_rep(context, auth_context, &chpw_rep,
-                               &local_result_code, &result_string);
+      code = get_setpw_rep(context, auth_context, &chpw_rcv,
+                           &local_result_code, &result_string);
 
       if (local_result_code)
         {
@@ -501,51 +506,38 @@ printf("1\n");
             local_result_code = KRB5_KPASSWD_SUCCESS;
           *result_code = local_result_code;
         }
-      if (chpw_rep.data != NULL)
-        free(chpw_rep.data);
-      break;
-
+      if ((code == 0) && (local_result_code == 0))
+        break;
+      sleep(1);
     }
+
 cleanup:
-  closesocket(s1);
-  closesocket(s2);
-  if (addr_p != NULL)
-    free(addr_p);
-  if (auth_context != NULL)
-    krb5_auth_con_free(context, auth_context);
-  if (ap_req.data != NULL)
-    free(ap_req.data);
-  krb5_free_cred_contents(context, &creds);
-  if (credsp != NULL)
-    krb5_free_creds(context, credsp);
+  if (chpw_snd.data != NULL)
+    free(chpw_snd.data);
+  if (chpw_rcv.data != NULL)
+    free(chpw_rcv.data);
   if (targprinc != NULL)
     krb5_free_principal(context, targprinc);
   return(code);
 }
 
-int set_password(char *user, char *domain)
+int set_password(char *user, char *password, char *domain)
 {
-  krb5_context    context;
-  krb5_ccache     ccache;
   int             res_code;
   krb5_error_code retval;
   char            pw[PW_LENGTH+1];
 
-  if (retval = krb5_init_context(&context))
-    return retval;
-  if (retval = krb5_cc_default(context, &ccache))
-    return(retval);
-
   memset(pw, '\0', sizeof(pw));
-  generate_password(pw);
+  if (strlen(password) != 0)
+    strcpy(pw, password);
+  else
+    generate_password(pw);
   res_code = 0;
-  retval = krb5_set_password(context, ccache, pw, user, domain, &res_code);
+  retval = kdc_set_password(context, ccache, pw, user, domain, &res_code);
 
-  krb5_cc_close(context, ccache);
-  krb5_free_context(context);
-  if (retval)
-    return(retval);
-  return(res_code);
+  if (res_code)
+    return(res_code);
+  return(retval);
 }
 
 void generate_password(char *password)
@@ -607,3 +599,299 @@ long myrandom()
     }
   return (rand());
 }
+
+int get_krb5_error(krb5_error_code rc, char *in, char *out)
+{
+  int krb5Error;
+  int retval;
+
+  retval = 1;
+
+  if (rc < 0)
+    {
+      krb5Error = ((int)(rc & 255));
+      sprintf(out, "%s: %s(%ld)", in, error_message(rc), krb5Error);
+    }
+  else
+    {
+      switch (rc)
+        {
+          case KDC_RECEIVE_TIMEOUT:
+            {
+              retval = 0;
+              sprintf(out, "%s: %s(%d)", in, "Receive timeout", rc);
+              break;
+            }
+          case KDC_RECEIVE_ERROR:
+            {
+              retval = 0;
+              sprintf(out, "%s: %s(%d)", in, "Receive error", rc);
+              break;
+            }
+          case KRB5_KPASSWD_MALFORMED:
+            {
+              sprintf(out, "%s: %s(%d)", in, "malformed password", rc);
+              break;
+            }
+          case KRB5_KPASSWD_HARDERROR:
+            {
+              sprintf(out, "%s: %s(%d)", in, "hard error", rc);
+              break;
+            }
+          case KRB5_KPASSWD_AUTHERROR:
+            {
+              retval = 0;
+              sprintf(out, "%s: %s(%d)", in, "authentication error", rc);
+              break;
+            }
+          case KRB5_KPASSWD_SOFTERROR:
+            {
+              retval = 0;
+              sprintf(out, "%s: %s(%d)", in, "soft error", rc);
+              break;
+            }
+          case KRB5_KPASSWD_ACCESSDENIED:
+            {
+              sprintf(out, "%s: %s(%d)", in, "Access denied", rc);
+              break;
+            }
+          case KDC_SEND_ERROR:
+            {
+              retval = 0;
+              sprintf(out, "%s: %s(%d)", in, "Send error", rc);
+              break;
+            }
+          case KDC_GETSOCKNAME_ERROR:
+            {
+              retval = 0;
+              sprintf(out, "%s: %s(%d)", in, "Socket error - getsockname", rc);
+              break;
+            }
+          case KDC_GETPEERNAME_ERROR:
+            {
+              retval = 0;
+              sprintf(out, "%s: %s(%d)", in, "Socket error - getpeername", rc);
+              break;
+            }
+          default:
+            {
+              sprintf(out, "%s: %s(%d)", in, "unknown error", rc);
+              break;
+            }
+        }
+    }
+  return(retval);
+}
+
+int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, 
+               char *Win2kPassword, char *Win2kUser, char *default_server,
+               int connect_to_kdc)
+{
+  int         i;
+  int         j;
+  char        *server_name[MAX_SERVER_NAMES];
+  char        server_array[MAX_SERVER_NAMES][256];
+  static char temp[128];
+  ULONG       version = LDAP_VERSION3;
+  ULONG       rc;
+  int         Max_wait_time = 500;
+  int         Max_size_limit = LDAP_NO_LIMIT;
+
+  if (ldap_domain == NULL)
+    ldap_domain = "win.mit.edu";
+  convert_domain_to_dn(ldap_domain, dn_path);
+  if (strlen(dn_path) == 0)
+    return(1);
+
+  memset(server_name, 0, sizeof(server_name[0]) * MAX_SERVER_NAMES);
+  memset(server_array, 0, sizeof(server_array[0]) * MAX_SERVER_NAMES);
+  if (strlen(default_server) == 0)
+    {
+      if (locate_ldap_server(ldap_domain, server_name) == -1)
+        return(2);
+      j = 0;
+      for (i = 0; i < MAX_SERVER_NAMES; i++)
+        {
+          if (server_name[i] != NULL)
+            {
+              strcpy(server_array[i], server_name[i]);
+              free(server_name[i]);
+              j++;
+            }
+        }
+      if (j == 0)
+        return(2);
+#ifdef _WIN32
+      qsort((void *)server_array, (size_t)j, sizeof(server_array[0]), compare_elements);
+#endif
+    }
+  else
+    strcpy(server_array[0], default_server);
+
+  for (i = 0; i < MAX_SERVER_NAMES; i++)
+    {
+      if (strlen(server_array[i]) != 0)
+        {
+          if (((*ldap_handle) = ldap_open(server_array[i], LDAP_PORT)) != NULL)
+            {
+              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)
+                {
+                  if (connect_to_kdc)
+                    {
+                      if (!ad_server_connect(server_array[i], ldap_domain))
+                        {
+                          ldap_unbind_s((*ldap_handle));
+                          continue;
+                        }
+                    }
+                  if (strlen(default_server) == 0)
+                    strcpy(default_server, server_array[i]);
+                  strcpy(connected_server, server_array[i]);
+                  break;
+                }
+            }
+        }
+    }
+  if (i >= MAX_SERVER_NAMES)
+    return(3);
+  return(0);
+}
+
+int ad_server_connect(char *connectedServer, char *domain)
+{
+  krb5_error_code   rc;
+  krb5_creds        creds;
+  krb5_creds        *credsp;
+  char              temp[256];
+  char              userrealm[256];
+  int               i;
+  unsigned short    port = KDC_PORT;
+
+  context = NULL;
+  credsp = NULL;
+  memset(&ccache, 0, sizeof(ccache));
+  memset(&creds, 0, sizeof(creds));
+  memset(userrealm, '\0', sizeof(userrealm));
+
+  rc = 0;
+  if (krb5_init_context(&context))
+    goto cleanup;
+  if (krb5_cc_default(context, &ccache))
+    goto cleanup;
+
+  for (i = 0; i < (int)strlen(domain); i++)
+    userrealm[i] = toupper(domain[i]);
+  sprintf(temp, "%s@%s", "kadmin/changepw", userrealm);
+  if (krb5_parse_name(context, temp, &creds.server))
+    goto cleanup;
+  if (krb5_cc_get_principal(context, ccache, &creds.client))
+    goto cleanup;
+  if (krb5_get_credentials(context, 0, ccache, &creds, &credsp))
+    goto cleanup;
+
+  rc = ad_kdc_connect(connectedServer);
+
+
+cleanup:
+  if (!rc)
+    {
+      krb5_cc_close(context, ccache);
+      krb5_free_context(context);
+    }
+  krb5_free_cred_contents(context, &creds);
+  if (credsp != NULL)
+    krb5_free_creds(context, credsp);
+  return(rc);
+}
+
+
+int ad_kdc_connect(char *connectedServer)
+{
+  struct hostent  *hp;
+  int             rc;
+
+  rc = 0;
+  hp = gethostbyname(connectedServer);
+  if (hp == NULL)
+    goto cleanup;
+  memset(&kdc_server, 0, sizeof(kdc_server));
+  memcpy(&(kdc_server.sin_addr),hp->h_addr_list[0],hp->h_length);
+  kdc_server.sin_family = hp->h_addrtype;
+  kdc_server.sin_port = htons(KDC_PORT);
+
+  if ((kdc_socket = socket(AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
+    goto cleanup;
+  if (connect(kdc_socket, (struct sockaddr*)&kdc_server, sizeof(kdc_server)) == SOCKET_ERROR)
+    goto cleanup;
+  rc = 1;
+
+cleanup:
+  return(rc);
+}
+
+void ad_kdc_disconnect()
+{
+
+  if (auth_context != NULL)
+    {
+      krb5_auth_con_free(context, auth_context);
+      if (ap_req.data != NULL)
+        free(ap_req.data);
+      krb5_free_cred_contents(context, &creds);
+      if (credsp != NULL)
+        krb5_free_creds(context, credsp);
+    }
+  credsp = NULL;
+  auth_context = NULL;
+  if (context != NULL)
+    {
+      krb5_cc_close(context, ccache);
+      krb5_free_context(context);
+    }
+  closesocket(kdc_socket);
+
+}
+
+int convert_domain_to_dn(char *domain, char *dnp)
+{
+  char    *fp;
+  char    *dp;
+  char    dn[512];
+
+  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;
+    }
+
+  strcpy(dnp, dn);
+  return 0;
+}
+
+int compare_elements(const void *arg1, const void *arg2)
+{
+  int rc;
+
+  rc = strcmp((char*)arg1, (char*)arg2);
+  if (rc < 0)
+    return(1);
+  if (rc > 0)
+    return(-1);
+  return(rc);
+}
+
index 76e58097f6ab78e564f1dd676d6b24c266ff93db..000e1cdbf1ad3e784c8ac59375593dcdc8981d28 100755 (executable)
@@ -55,7 +55,7 @@
 #include <malloc.h>
 #include <lmaccess.h>
 #endif
-
+#include <hesiod.h>
 #include <string.h>
 #include <ldap.h>
 #include <stdio.h>
 #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
@@ -129,11 +134,14 @@ 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"
@@ -151,6 +159,15 @@ typedef struct _SID {
 #define MEMBER_DEACTIVATE   5
 #define MEMBER_CREATE       6
 
+#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;
   int     length;
@@ -180,14 +197,14 @@ LK_ENTRY *member_base = NULL;
 LK_ENTRY *sid_base = NULL;
 LK_ENTRY **sid_ptr = NULL;
 static char tbl_buf[1024];
-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";
+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];
@@ -197,11 +214,18 @@ int  maillist_flag;
 int  group_flag;
 int  mr_connections = 0;
 int  callback_rc;
+char default_server[256];
 
-extern int locate_ldap_server(char *domain, char *server_name[]);
-extern int set_password(char *user, char *domain);
+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);
@@ -214,9 +238,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);
@@ -224,11 +250,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,
@@ -263,19 +290,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]);
 
@@ -302,14 +323,14 @@ int main(int argc, char **argv)
   for (i = 0; i < beforec; i++)
     {
       if (i > 0)
-       strcat(tbl_buf, ",");
+        strcat(tbl_buf, ",");
       strcat(tbl_buf, before[i]);
     }
   strcat(tbl_buf, ")->(");
   for (i = 0; i < afterc; i++)
     {
       if (i > 0)
-       strcat(tbl_buf, ",");
+        strcat(tbl_buf, ",");
       strcat(tbl_buf, after[i]);
     }
   strcat(tbl_buf, ")");
@@ -326,76 +347,134 @@ 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)
 {
@@ -411,8 +490,7 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
   int     astatus;
   long    rc;
   char    *av[3];
-  char    *call_args[6];
-
+  char    *call_args[7];
 
   if (beforec == 0 && afterc == 0)
     return;
@@ -501,6 +579,7 @@ void do_list(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);
       sid_base = NULL;
       sid_ptr = &sid_base;
       if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
@@ -513,17 +592,22 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
         {
           sid_update(ldap_handle, dn_path);
           linklist_free(sid_base);
+          sid_base = NULL;
         }
 
       if (afterc == 0)
         goto cleanup;
       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[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
         {
@@ -532,18 +616,19 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
                          after[L_NAME], error_message(rc));
         }
       linklist_free(member_base);
+      member_base = NULL;
       goto cleanup;
     }
 cleanup:
   moira_disconnect();
 }
 
-#define LM_EXTRA_ACTIVE          (LM_END)
+#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];
@@ -575,6 +660,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;
@@ -582,6 +669,7 @@ 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;
@@ -591,9 +679,10 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
         {
           sid_update(ldap_handle, dn_path);
           linklist_free(sid_base);
+          sid_base = NULL;
         }
       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)
@@ -604,7 +693,9 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
           else
             {
               rc = member_list_process(ldap_handle, dn_path, group_name,
-                                       call_args[3], call_args[4], call_args[5]);
+                                       call_args[3], call_args[4], call_args[5],
+                                       MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
+              expand_groups(ldap_handle, dn_path, group_name);
             }
         }
     }
@@ -618,6 +709,7 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
                        user_name, group_name);
     }
   linklist_free(member_base);
+  member_base = NULL;
   if (call_args[3] != NULL)
     free(call_args[3]);
   if (call_args[4] != NULL)
@@ -626,8 +718,8 @@ 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;
@@ -636,7 +728,6 @@ void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
   int   astate;
   int   bstate;
 
-
   if ((beforec == 0) || (afterc == 0))
     return;
 
@@ -1138,11 +1229,11 @@ void check_winad(void)
     {
       if (i > 30)
         {
-         critical_alert("incremental",
-                        "WINAD incremental failed (%s exists): %s",
-                        STOP_FILE, tbl_buf);
-         exit(1);
-       }
+          critical_alert("incremental",
+                         "WINAD incremental failed (%s exists): %s",
+                         STOP_FILE, tbl_buf);
+          exit(1);
+        }
       sleep(60);
     }
 }
@@ -1157,31 +1248,6 @@ int moira_disconnect(void)
   return 0;
 }
 
-int convert_domain_to_dn(char *domain, char **dnp)
-{
-  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);
-  return 0;
-}
-
 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
                             char *distinguished_name)
 {
@@ -1497,7 +1563,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)
         {
@@ -1658,20 +1724,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)
     {
@@ -1693,6 +1772,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)
 {
@@ -1777,7 +1889,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;
@@ -1860,20 +1973,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);
@@ -1959,6 +2082,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", 
@@ -1983,6 +2107,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;
@@ -1991,11 +2116,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", 
@@ -2015,12 +2157,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;
 
@@ -2069,6 +2218,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)
     {
@@ -2081,6 +2248,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);
@@ -2180,6 +2356,116 @@ 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);
+    }
+
+  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(20);
+    }
+  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];
@@ -2283,14 +2569,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]);
@@ -2603,37 +2886,176 @@ int mr_connect_cl(char *server, char *client, int version, int auth)
   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 MRCL_FAIL;
+        }
     }
 
   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 MRCL_AUTH_ERROR;
+        }
     }
 
   return MRCL_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)
+        {
+          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)
+    {
+      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);
+          member_base = NULL;
+          ptr = ptr->next;
+          continue;
+        }
+      if (sid_base != NULL)
+        {
+          sid_update(ldap_handle, dn_path);
+          linklist_free(sid_base);
+          sid_base = NULL;
+        }
+      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 1.154497 seconds and 5 git commands to generate.