]> andersk Git - moira.git/blob - incremental/winad/winad.c
Change group security when renaming groups.
[moira.git] / incremental / winad / winad.c
1 /* $Header$
2 /* test parameters for creating a user account - done 
3  * 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
4  * 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
5  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
6  *
7  * test parameters for deactivating/deleting a user account - done
8  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF 
9  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF 
10  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
11  * comment: clearid is the MIT ID
12  *
13  * test parameters for reactivating a user account - done
14  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF 
15  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
16  *
17  * test parameters for updating user account info - done
18  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc 31275 sh cmd newLastname Firstname Middlename 2 950000000 STAFF 
19  * 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
20  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
21  *   currently, if the unix_id doesn't change, only the U_UID or U_MITID fields will be updated
22  *
23  * test parameters for changing user name - testing
24  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc1 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF
25  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF testacc1 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF
26  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
27  *
28  * test parameters for add member to group/list - done
29  * imembers 0 10 pismere-team USER dtanner 1 1 0 1 1 -1 1
30  *   list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid
31  *
32  * test parameters for remove member from group/list - done
33  * imembers 10 0 pismere-team USER dtanner 1 1 0 1 1 -1 1
34  *   list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid
35  *
36  * test parameters for creating and/or populating a group/list - done
37  * list 0 10 pismere-team 1 1 0 1 0 -1 USER 95260 description
38  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
39  * 
40  * test parameters for deleting a group/list - done
41  * list 10 0 pismere-team 1 1 0 1 0 -1 USER 95260 description
42  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
43  *
44  * test parameters for renaming a group/list - done
45  *  list 10 10 adtestlist 1 1 0 1 0 -1 USER 95260 description pismere-team 1 1 0 1 1 -1 USER 95260 description
46  *  list 10 10 pismere-team 1 1 0 1 1 -1 USER 95260 description adtestlist1 1 1 0 1 0 -1 USER 95260 description
47  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
48  *
49  * test parameters for adding a file system - done
50  *   filesys 0 11 addusr5 AFS ATHENA.MIT.EDU /afs/athena.mit.edu/user/a/d/addusr5 /mit/addusr5 w UserLocker addusr5 wheel 1 HOMEDIR
51  *
52  * test parameters for deleting a file system - done
53  *   filesys 11 0 addusr8 AFS ATHENA.MIT.EDU /afs/athena.mit.edu/user/a/d/addusr8 /mit/addusr8 w none dtanner wheel 1 HOMEDIR
54 */
55 #include <mit-copyright.h>
56 #ifdef _WIN32
57 #include <windows.h>
58 #include <stdlib.h>
59 #include <malloc.h>
60 #include <lmaccess.h>
61 #endif
62 #include <hesiod.h>
63 #include <string.h>
64 #include <ldap.h>
65 #include <stdio.h>
66 #include <moira.h>
67 #include <moira_site.h>
68 #include <mrclient.h>
69 #include <krb5.h>
70 #include <krb.h>
71 #include <gsssasl.h>
72 #include <gssldap.h>
73 #include "kpasswd.h"
74
75 #ifdef _WIN32
76 #ifndef ECONNABORTED
77 #define ECONNABORTED WSAECONNABORTED
78 #endif
79 #ifndef ECONNREFUSED
80 #define ECONNREFUSED WSAECONNREFUSED
81 #endif
82 #ifndef EHOSTUNREACH
83 #define EHOSTUNREACH WSAEHOSTUNREACH
84 #endif
85 #define krb5_xfree free
86 #define F_OK 0
87 #define sleep(A) Sleep(A * 1000);
88 #endif /* _WIN32 */
89
90 #ifndef _WIN32
91 #include <sys/types.h>
92 #include <netinet/in.h>
93 #include <arpa/nameser.h>
94 #include <resolv.h>
95 #include <sys/utsname.h>
96 #include <unistd.h>
97
98 #define WINADCFG "/moira/winad/winad.cfg"
99 #define strnicmp(A,B,C) strncasecmp(A,B,C)
100 #define UCHAR unsigned char
101
102 #define UF_SCRIPT               0x0001
103 #define UF_ACCOUNTDISABLE       0x0002
104 #define UF_HOMEDIR_REQUIRED     0x0008
105 #define UF_LOCKOUT              0x0010
106 #define UF_PASSWD_NOTREQD       0x0020
107 #define UF_PASSWD_CANT_CHANGE   0x0040
108 #define UF_DONT_EXPIRE_PASSWD   0x10000
109
110 #define UF_TEMP_DUPLICATE_ACCOUNT       0x0100
111 #define UF_NORMAL_ACCOUNT               0x0200
112 #define UF_INTERDOMAIN_TRUST_ACCOUNT    0x0800
113 #define UF_WORKSTATION_TRUST_ACCOUNT    0x1000
114 #define UF_SERVER_TRUST_ACCOUNT         0x2000
115
116 #ifndef BYTE
117 #define BYTE unsigned char
118 #endif
119 typedef unsigned int DWORD;
120 typedef unsigned long ULONG;
121
122 typedef struct _GUID
123 {
124   unsigned long Data1;
125   unsigned short Data2;
126   unsigned short Data3;
127   unsigned char Data4[8];
128 } GUID;
129
130 typedef struct _SID_IDENTIFIER_AUTHORITY { 
131   BYTE Value[6]; 
132 } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY; 
133
134 typedef struct _SID {
135   BYTE  Revision;
136   BYTE  SubAuthorityCount;
137   SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
138   DWORD SubAuthority[512];
139 } SID;
140 #endif/*!WIN32*/
141
142 #ifndef WINADCFG
143 #define WINADCFG "winad.cfg"
144 #endif
145
146 #define AFS "/afs/"
147 #define WINAFS "\\\\afs\\all\\"
148
149 #define ADS_GROUP_TYPE_GLOBAL_GROUP         0x00000002
150 #define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP   0x00000004
151 #define ADS_GROUP_TYPE_LOCAL_GROUP          0x00000004
152 #define ADS_GROUP_TYPE_UNIVERSAL_GROUP      0x00000008
153 #define ADS_GROUP_TYPE_SECURITY_ENABLED     0x80000000
154
155 #define QUERY_VERSION -1
156 #define PRIMARY_REALM "ATHENA.MIT.EDU"
157
158 #define SUBSTITUTE  1
159 #define REPLACE     2
160
161 #define USERS         0
162 #define GROUPS        1
163
164 #define MEMBER_ADD          1
165 #define MEMBER_REMOVE       2
166 #define MEMBER_CHANGE_NAME  3
167 #define MEMBER_ACTIVATE     4
168 #define MEMBER_DEACTIVATE   5
169 #define MEMBER_CREATE       6
170
171 #define MOIRA_ALL       0x0
172 #define MOIRA_USERS     0x1
173 #define MOIRA_KERBEROS  0x2
174 #define MOIRA_STRINGS   0x4
175 #define MOIRA_LISTS     0x8
176
177 typedef struct lk_entry {
178   int     op;
179   int     length;
180   int     ber_value;
181   char    *dn;
182   char    *attribute;
183   char    *value;
184   char    *member;
185   char    *type;
186   char    *list;
187   struct  lk_entry *next;
188 } LK_ENTRY;
189
190 #define STOP_FILE "/moira/winad/nowinad"
191 #define file_exists(file) (access((file), F_OK) == 0)
192
193 #define LDAP_BERVAL struct berval
194 #define MAX_SERVER_NAMES 32
195
196 #define ADD_ATTR(t, v, o)               \
197   mods[n] = malloc(sizeof(LDAPMod));    \
198   mods[n]->mod_op = o;  \
199   mods[n]->mod_type = t;                \
200   mods[n++]->mod_values = v
201
202 LK_ENTRY *member_base = NULL;
203 LK_ENTRY *sid_base = NULL;
204 LK_ENTRY **sid_ptr = NULL;
205 static char tbl_buf[1024];
206 char  kerberos_ou[] = "OU=kerberos, OU=moira";
207 char  contact_ou[] = "OU=strings, OU=moira";
208 char  user_ou[] = "OU=users, OU=moira";
209 char  group_ou_distribution[] = "OU=mail, OU=lists, OU=moira";
210 char  group_ou_root[] = "OU=lists, OU=moira";
211 char  group_ou_security[] = "OU=group, OU=lists, OU=moira";
212 char  group_ou_neither[] = "OU=special, OU=lists, OU=moira";
213 char  group_ou_both[] = "OU=mail, OU=group, OU=lists, OU=moira";
214 char *whoami;
215 char ldap_domain[256];
216 int  mr_connections = 0;
217 int  callback_rc;
218 int  UserReactivate = 0;
219 char default_server[256];
220 static char tbl_buf[1024];
221
222 extern int set_password(char *user, char *password, char *domain);
223
224 void AfsToWinAfs(char* path, char* winPath);
225 int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, 
226                char *Win2kPassword, char *Win2kUser, char *default_server,
227                int connect_to_kdc);
228 void ad_kdc_disconnect();
229 void check_winad(void);
230 int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name, 
231                     char *fs_type, char *fs_pack, int operation);
232 int get_group_membership(char *group_membership, char *group_ou, 
233                          int *security_flag, char **av);
234 int process_lists(int ac, char **av, void *ptr);
235 int user_create(int ac, char **av, void *ptr);
236 int user_change_status(LDAP *ldap_handle, char *dn_path, char *user_name, int operation);
237 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name);
238 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, 
239                 char *user_name, char *Uid, char *MitId, int State);
240 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
241                 char *uid, char *MitId);
242 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
243 int group_create(int ac, char **av, void *ptr);
244 int group_delete(LDAP *ldap_handle, char *dn_path, 
245                  char *group_name, char *group_membership);
246 int group_rename(LDAP *ldap_handle, char *dn_path, 
247                  char *before_group_name, char *before_group_membership, 
248                  char *before_group_ou, int before_security_flag, char *before_desc,
249                  char *after_group_name, char *after_group_membership, 
250                  char *after_group_ou, int after_security_flag, char *after_desc);
251 int member_list_build(int ac, char **av, void *ptr);
252 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, 
253                         char *group_ou, char *group_membership, 
254                         char *user_name, char *pUserOu);
255 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, 
256                   char *group_ou, char *group_membership, char *user_name,
257                   char *pUserOu);
258 int sid_update(LDAP *ldap_handle, char *dn_path);
259 int check_string(char *s);
260 void convert_b_to_a(char *string, UCHAR *binary, int length);
261 int mr_connect_cl(char *server, char *client, int version, int auth);
262
263 void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
264              char **before, int beforec, char **after, int afterc);
265 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
266              char **before, int beforec, char **after, int afterc);
267 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 
268              char **before, int beforec, char **after, int afterc);
269 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
270                char **before, int beforec, char **after, int afterc);
271 int linklist_create_entry(char *attribute, char *value,
272                           LK_ENTRY **linklist_entry);
273 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, 
274                    char **attr_array, LK_ENTRY **linklist_base, 
275                    int *linklist_count);
276 void linklist_free(LK_ENTRY *linklist_base);
277
278 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
279                         char *distinguished_name, LK_ENTRY **linklist_current);
280 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
281                      LK_ENTRY **linklist_base, int *linklist_count);
282 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
283                     char *Attribute, char *distinguished_name, 
284                     LK_ENTRY **linklist_current);
285
286 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, 
287                         char *oldValue, char *newValue,
288                         char ***modvalues, int type);
289 void free_values(char **modvalues);
290
291 int convert_domain_to_dn(char *domain, char **bind_path);
292 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
293                             char *distinguished_name);
294 int moira_disconnect(void);
295 int moira_connect(void);
296 void print_to_screen(const char *fmt, ...);
297
298 int main(int argc, char **argv)
299 {
300   unsigned long   rc;
301   int             beforec;
302   int             afterc;
303   int             i;
304   char            *table;
305   char            **before;
306   char            **after;
307   LDAP            *ldap_handle;
308   FILE            *fptr;
309   char            dn_path[256];
310
311   whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
312
313   if (argc < 4)
314     {
315       com_err(whoami, 0, "%s", "argc < 4");
316       exit(1);
317     }
318   beforec = atoi(argv[2]);
319   afterc = atoi(argv[3]);
320
321   if (argc < (4 + beforec + afterc))
322     {
323       com_err(whoami, 0, "%s", "argc < (4 + breforec + afterc)");
324       exit(1);
325     }
326
327   table = argv[1];
328   before = &argv[4];
329   after = &argv[4 + beforec];
330
331   for (i = 1; i < argc; i++)
332     {
333       strcat(tbl_buf, argv[i]);
334       strcat(tbl_buf, " ");
335     }
336   com_err(whoami, 0, "%s", tbl_buf);
337
338   check_winad();
339
340   memset(ldap_domain, '\0', sizeof(ldap_domain));
341   if ((fptr = fopen(WINADCFG, "r")) != NULL)
342     {
343       fread(ldap_domain, sizeof(char), sizeof(ldap_domain), fptr);
344       fclose(fptr);
345     }
346   if (strlen(ldap_domain) == 0)
347     strcpy(ldap_domain, "win.mit.edu");
348   initialize_sms_error_table();
349   initialize_krb_error_table();
350
351   memset(default_server, '\0', sizeof(default_server));
352   memset(dn_path, '\0', sizeof(dn_path));
353   if (ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", default_server, 1))
354     {
355       com_err(whoami, 0, "cannot connect to any server in domain %s", ldap_domain);
356       exit(1);
357     }
358
359   for (i = 0; i < (int)strlen(table); i++)
360     table[i] = tolower(table[i]);
361   if (!strcmp(table, "users"))
362     do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
363             afterc);
364   else if (!strcmp(table, "list"))
365     do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
366             afterc);
367   else if (!strcmp(table, "imembers"))
368     do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
369               afterc);
370   else if (!strcmp(table, "filesys"))
371     do_filesys(ldap_handle, dn_path, ldap_domain, before, beforec, after,
372                afterc);
373 /*
374   else if (!strcmp(table, "quota"))
375     do_quota(before, beforec, after, afterc);
376 */
377
378   ad_kdc_disconnect();
379   rc = ldap_unbind_s(ldap_handle);
380   exit(0);
381 }
382
383 void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
384              char **before, int beforec, char **after, int afterc)
385 {
386   long  rc;
387   char  *av[3];
388   char  *call_args[7];
389   int   acreate;
390   int   atype;
391   int   bcreate;
392   int   btype;
393   int   abort_flag;
394
395   abort_flag = 0;
396
397   if (afterc < FS_CREATE)
398     atype = acreate = 0;
399   else
400     {
401       atype = !strcmp(after[FS_TYPE], "AFS");
402       acreate = atoi(after[FS_CREATE]);
403     }
404
405   if (beforec < FS_CREATE)
406     {
407       if (acreate == 0 || atype == 0)
408         goto cleanup;
409       com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
410       abort_flag = 0;
411       while (1)
412       {
413         if ((rc = filesys_process(ldap_handle, dn_path, after[FS_NAME], 
414                     after[FS_TYPE], after[FS_PACK], LDAP_MOD_ADD)) != LDAP_NO_SUCH_OBJECT)
415           {
416             if (rc != LDAP_SUCCESS)
417               com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
418             break;
419           }
420         if (abort_flag == 1)
421           break;
422         sleep(1);
423         abort_flag = 1;
424         if (rc = moira_connect())
425           {
426             critical_alert("AD incremental",
427                            "Error contacting Moira server : %s",
428                            error_message(rc));
429             return;
430           }
431         av[0] = after[FS_NAME];
432         call_args[0] = (char *)ldap_handle;
433         call_args[1] = dn_path;
434         call_args[2] = (char *)MEMBER_ACTIVATE;
435         call_args[3] = NULL;
436         sid_base = NULL;
437         sid_ptr = &sid_base;
438         callback_rc = 0;
439         if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
440                           call_args))
441           {
442             moira_disconnect();
443             com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
444             break;
445           }
446         if (callback_rc)
447           {
448             moira_disconnect();
449             com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
450             break;
451           }
452         if (sid_base != NULL)
453           {
454             sid_update(ldap_handle, dn_path);
455             linklist_free(sid_base);
456             sid_base = NULL;
457           }
458         moira_disconnect();
459       }
460       goto cleanup;
461     }
462
463   btype = !strcmp(before[FS_TYPE], "AFS");
464   bcreate = atoi(before[FS_CREATE]);
465   if (afterc < FS_CREATE)
466     {
467       if (btype && bcreate)
468         {
469           if (rc = filesys_process(ldap_handle, dn_path, before[FS_NAME], 
470                       before[FS_TYPE], before[FS_PACK], LDAP_MOD_DELETE))
471             {
472               com_err(whoami, 0, "Couldn't delete filesys %s", before[FS_NAME]);
473             }
474         }
475       return;
476     }
477
478   if (!acreate)
479     return;
480
481   if (!atype && !btype)
482     {
483       if (strcmp(before[FS_TYPE], "ERR") || strcmp(after[FS_TYPE], "ERR"))
484         {
485           com_err(whoami, 0, "Filesystem %s or %s is not AFS",
486                   before[FS_NAME], after[FS_NAME]);
487           return;
488         }
489     }
490   com_err(whoami, 0, "Processing filesys %s", after[FS_NAME]);
491   abort_flag = 0;
492   while (1)
493   {
494     if ((rc = filesys_process(ldap_handle, dn_path, after[FS_NAME], 
495                     after[FS_TYPE], after[FS_PACK], LDAP_MOD_ADD)) != LDAP_NO_SUCH_OBJECT)
496       {
497         if (rc != LDAP_SUCCESS)
498           com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
499         break;
500       }
501     if (abort_flag == 1)
502       break;
503     sleep(1);
504     abort_flag = 1;
505     if (rc = moira_connect())
506       {
507         critical_alert("AD incremental",
508                        "Error contacting Moira server : %s",
509                        error_message(rc));
510         return;
511       }
512     av[0] = after[FS_NAME];
513     call_args[0] = (char *)ldap_handle;
514     call_args[1] = dn_path;
515     call_args[2] = (char *)MEMBER_ACTIVATE;
516     call_args[3] = NULL;
517     sid_base = NULL;
518     sid_ptr = &sid_base;
519     callback_rc = 0;
520     if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
521                       call_args))
522       {
523         moira_disconnect();
524         com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
525         break;
526       }
527     if (callback_rc)
528       {
529         moira_disconnect();
530         com_err(whoami, 0, "Couldn't process filesys %s", after[FS_NAME]);
531         break;
532       }
533     if (sid_base != NULL)
534       {
535         sid_update(ldap_handle, dn_path);
536         linklist_free(sid_base);
537         sid_base = NULL;
538       }
539     moira_disconnect();
540   }
541
542 cleanup:
543   return;
544 }
545 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
546              char **before, int beforec, char **after, int afterc)
547 {
548   int   agid;
549   int   bgid;
550   int   ahide;
551   int   bhide;
552   int   apublic;
553   int   bpublic;
554   int   bgroup;
555   int   agroup;
556   int   amaillist;
557   int   bmaillist;
558   int   bstatus;
559   int   astatus;
560   long  rc;
561   char  *av[3];
562   char  *call_args[7];
563   char  group_membership[1];
564   int   security_flag;
565   char  group_ou[256];
566   char  before_group_membership[1];
567   int   before_security_flag;
568   char  before_group_ou[256];
569   char  *pUserOu;
570   LK_ENTRY *ptr = NULL;
571
572   if (beforec == 0 && afterc == 0)
573     return;
574
575   astatus = bstatus = 0;
576   ahide = bhide = 0;
577   apublic = bpublic = 0;
578   amaillist = bmaillist = 0;
579   agid = 0;
580   bgid = 0;
581
582   if (beforec > L_GID && atoi(before[L_ACTIVE]))
583     {
584       bgid = atoi(before[L_GID]);
585       bstatus = atoi(before[L_ACTIVE]);
586       bhide = atoi(before[L_HIDDEN]);
587       bpublic = atoi(before[L_PUBLIC]);
588       bmaillist = atoi(before[L_MAILLIST]);
589       bgroup = atoi(before[L_GROUP]);
590       before_security_flag = 0;
591       memset(before_group_ou, '\0', sizeof(before_group_ou));
592       memset(before_group_membership, '\0', sizeof(before_group_membership));
593       get_group_membership(before_group_membership, before_group_ou, &before_security_flag, before);
594     }
595   if (afterc > L_GID && atoi(after[L_ACTIVE]))
596     {
597       agid = atoi(after[L_GID]);
598       astatus = atoi(after[L_ACTIVE]);
599       ahide = atoi(after[L_HIDDEN]);
600       apublic = atoi(after[L_PUBLIC]);
601       amaillist = atoi(after[L_MAILLIST]);
602       agroup = atoi(after[L_GROUP]);
603       security_flag = 0;
604       memset(group_ou, '\0', sizeof(group_ou));
605       memset(group_membership, '\0', sizeof(group_membership));
606       get_group_membership(group_membership, group_ou, &security_flag, after);
607     }
608   if (agid == 0 && bgid == 0)
609     return;
610
611   if (agid && bgid)
612     {
613       if ((strcmp(after[L_NAME], before[L_NAME])) || 
614           ((!strcmp(after[L_NAME], before[L_NAME])) && 
615            (strcmp(before_group_ou, group_ou))))
616         {
617           if (astatus && bstatus)
618             {
619               com_err(whoami, 0, "Changing list name from %s to %s",
620                       before[L_NAME], after[L_NAME]);
621               if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0) ||
622                   (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
623                 {
624                   com_err(whoami, 0, "%s", "couldn't find the group OU's");
625                   return;
626                 }
627               if ((rc = group_rename(ldap_handle, dn_path, 
628                                      before[L_NAME], before_group_membership, 
629                                      before_group_ou, before_security_flag, before[9],
630                                      after[L_NAME], group_membership, 
631                                      group_ou, security_flag, after[9])) != LDAP_NO_SUCH_OBJECT)
632                 {
633                   if (rc != LDAP_SUCCESS)
634                     com_err(whoami, 0, "Could not change list name from %s to %s",
635                                     before[L_NAME], 
636                                     after[L_NAME]);
637                   return;
638                 }
639               bgid = 0;
640             }
641           if (!agid)
642             return;
643         }
644       else
645         bgid = 0;
646     }
647
648   if (bgid)
649     {
650       if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0))
651         {
652           com_err(whoami, 0, "couldn't find the group OU for group %s", before[L_NAME]);
653           return;
654         }
655       com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
656       rc = group_delete(ldap_handle, dn_path, before[L_NAME], before_group_membership);
657       return;
658     }
659   if (agid)
660     {
661       com_err(whoami, 0, "Creating group %s", after[L_NAME]);
662
663       if (rc = moira_connect())
664         {
665           critical_alert("AD incremental",
666                          "Error contacting Moira server : %s",
667                          error_message(rc));
668           return;
669         }
670
671       av[0] = after[L_NAME];
672       call_args[0] = (char *)ldap_handle;
673       call_args[1] = dn_path;
674       call_args[2] = after[L_NAME];
675       call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
676       call_args[4] = NULL;
677       sid_base = NULL;
678       sid_ptr = &sid_base;
679       callback_rc = 0;
680       if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
681         {
682           moira_disconnect();
683           com_err(whoami, 0, "Couldn't create list %s : %s", after[L_NAME], error_message(rc));
684           return;
685         }
686       if (callback_rc)
687         {
688           moira_disconnect();
689           com_err(whoami, 0, "Couldn't create list %s", after[L_NAME]);
690           return;
691         }
692
693       if (sid_base != NULL)
694         {
695           sid_update(ldap_handle, dn_path);
696           linklist_free(sid_base);
697           sid_base = NULL;
698         }
699
700       sleep(1);
701       com_err(whoami, 0, "Populating group %s", after[L_NAME]);
702       av[0] = after[L_NAME];
703       call_args[0] = (char *)ldap_handle;
704       call_args[1] = dn_path;
705       call_args[2] = after[L_NAME];
706       call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
707       call_args[4] = NULL;
708       member_base = NULL;
709       if (rc = mr_query("get_end_members_of_list", 1, av,
710                         member_list_build, call_args))
711         {
712           moira_disconnect();
713           com_err(whoami, 0, "Couldn't populate list %s : %s", 
714                   after[L_NAME], error_message(rc));
715           return;
716         }
717       if (member_base != NULL)
718         {
719           ptr = member_base;
720           while (ptr != NULL)
721             {
722               if (!strcasecmp(ptr->type, "LIST"))
723                 {
724                   ptr = ptr->next;
725                   continue;
726                 }
727               pUserOu = user_ou;
728               if (!strcasecmp(ptr->type, "STRING"))
729                 {
730                   if (contact_create(ldap_handle, dn_path, ptr->member, contact_ou))
731                     return;
732                   pUserOu = contact_ou;
733                 }
734               else if (!strcasecmp(ptr->type, "KERBEROS"))
735                 {
736                   if (contact_create(ldap_handle, dn_path, ptr->member, kerberos_ou))
737                     return;
738                   pUserOu = kerberos_ou;
739                 }
740               rc = member_add(ldap_handle, dn_path, after[L_NAME],
741                               group_ou, group_membership, ptr->member, pUserOu);
742               ptr = ptr->next;
743             }
744           linklist_free(member_base);
745           member_base = NULL;
746         }
747       moira_disconnect();
748     }
749
750   return;
751 }
752
753 #define LM_EXTRA_ACTIVE   (LM_END)
754 #define LM_EXTRA_PUBLIC   (LM_END+1)
755 #define LM_EXTRA_HIDDEN   (LM_END+2)
756 #define LM_EXTRA_MAILLIST (LM_END+3)
757 #define LM_EXTRA_GROUP    (LM_END+4)
758 #define LM_EXTRA_GID      (LM_END+5)
759 #define LM_EXTRA_END      (LM_END+6)
760
761 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
762                char **before, int beforec, char **after, int afterc)
763 {
764   char  group_name[128];
765   char  user_name[128];
766   char  user_type[128];
767   int   rc;
768   char  group_membership[1];
769   int   security_flag;
770   char  group_ou[256];
771   char  *args[16];
772   char  **ptr;
773   char  *pUserOu;
774
775   pUserOu = NULL;
776   ptr = NULL;
777   if (afterc)
778     {
779       if (afterc < LM_EXTRA_END)
780         return;
781       if (!atoi(after[LM_EXTRA_ACTIVE]))
782         return;
783       ptr = after;
784       strcpy(user_name, after[LM_MEMBER]);
785       strcpy(group_name, after[LM_LIST]);
786       strcpy(user_type, after[LM_TYPE]);
787
788     }
789   else if (beforec)
790     {
791       if (beforec < LM_EXTRA_END)
792         return;
793       if (!atoi(before[LM_EXTRA_ACTIVE]))
794           return;
795       ptr = before;
796       strcpy(user_name, before[LM_MEMBER]);
797       strcpy(group_name, before[LM_LIST]);
798       strcpy(user_type, before[LM_TYPE]);
799     }
800
801   if (ptr == NULL)
802     return;
803
804   args[L_NAME] = ptr[LM_LIST];
805   args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
806   args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
807   args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
808   args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
809   args[L_GROUP] = ptr[LM_EXTRA_GROUP];
810   args[L_GID] = ptr[LM_EXTRA_GID];
811
812   security_flag = 0;
813   memset(group_ou, '\0', sizeof(group_ou));
814   get_group_membership(group_membership, group_ou, &security_flag, args);
815   if (strlen(group_ou) == 0)
816     {
817       com_err(whoami, 0, "couldn't find the group OU for group %s", group_name);
818       return;
819     }
820
821   rc = 0;
822   if (beforec)
823     {
824       if (!strcasecmp(ptr[LM_TYPE], "LIST"))
825         return;
826
827       com_err(whoami, 0, "Removing user %s from list %s", user_name, group_name);
828       pUserOu = user_ou;
829       if (!strcasecmp(ptr[LM_TYPE], "STRING"))
830         {
831           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
832             return;
833           pUserOu = contact_ou;
834         }
835       else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
836         {
837           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
838             return;
839           pUserOu = kerberos_ou;
840         }
841       rc = member_remove(ldap_handle, dn_path, group_name,
842                        group_ou, group_membership, ptr[LM_MEMBER], pUserOu);
843     }
844   else
845     {
846       if (!strcasecmp(ptr[LM_TYPE], "LIST"))
847         return;
848
849       com_err(whoami, 0, "Adding user %s to list %s", user_name, group_name);
850       pUserOu = user_ou;
851       if (!strcasecmp(ptr[LM_TYPE], "STRING"))
852         {
853           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
854             return;
855           pUserOu = contact_ou;
856         }
857       else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
858         {
859           if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
860             return;
861           pUserOu = kerberos_ou;
862         }
863       rc = member_add(ldap_handle, dn_path, group_name,
864                       group_ou, group_membership, ptr[LM_MEMBER], pUserOu);
865     }
866   if (rc)
867     {
868       if (afterc)
869         com_err(whoami, 0, "Couldn't add %s to group %s", user_name, group_name);
870       else
871         com_err(whoami, 0, "Couldn't remove %s to group %s", user_name, group_name);
872     }
873   return;
874 }
875
876
877 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, 
878              char **before, int beforec, char **after, 
879              int afterc)
880 {
881   int   rc;
882   char  *av[2];
883   char  *call_args[6];
884   int   astate;
885   int   bstate;
886
887   if ((beforec == 0) && (afterc == 0))
888     return;
889
890   astate = 0;
891   bstate = 0;
892   if (afterc > U_STATE)
893     astate = atoi(after[U_STATE]);
894   if (beforec > U_STATE)
895     bstate = atoi(before[U_STATE]);
896
897   if (astate == 2)
898     astate = 1;
899   if (bstate == 2)
900     bstate = 1;
901
902   if ((bstate == 0) && (astate == 0))
903     return;
904
905   if (astate == bstate)
906     {
907       if (!strcmp(before[U_NAME], after[U_NAME]))
908         {
909           com_err(whoami, 0, "Updating user %s info", before[U_NAME]);
910           rc = user_update(ldap_handle, dn_path, before[U_NAME],
911                            before[U_UID], before[U_MITID]);
912           return;
913         }
914       else
915         {
916           com_err(whoami, 0, "Changing user %s to %s", before[U_NAME],
917                   after[U_NAME]);
918           if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME], 
919                 after[U_NAME], after[U_UID], after[U_MITID], 
920                 atoi(after[U_STATE]))) != LDAP_NO_SUCH_OBJECT)
921             {
922               if (rc != LDAP_SUCCESS)
923                 {
924                   com_err(whoami, 0, "Could not change user %s to %s : %s",
925                           before[U_NAME], 
926                           after[U_NAME], error_message(rc));
927                 }
928               return;
929             }
930         }
931       bstate = 0;
932     }
933
934   if (bstate == 1)
935     {
936       com_err(whoami, 0, "Deactivate user %s in the AD", before[U_NAME]);
937
938       if ((rc = user_change_status(ldap_handle, dn_path, before[U_NAME], 
939                                    MEMBER_DEACTIVATE)) != LDAP_SUCCESS)
940         {
941           com_err(whoami, 0, "Couldn't deactivate user %s in the AD", before[U_NAME]);
942         }
943       return;
944     }
945
946   if (astate == 1)
947     {
948       if (rc = moira_connect())
949         {
950           critical_alert("AD incremental", 
951                          "Error connection to Moira : %s",
952                          error_message(rc));
953           return;
954         }
955       com_err(whoami, 0, "Creating/Reactivating user %s", after[U_NAME]);
956
957       av[0] = after[U_NAME];
958       call_args[0] = (char *)ldap_handle;
959       call_args[1] = dn_path;
960       call_args[2] = (char *)MEMBER_ACTIVATE;
961       call_args[3] = NULL;
962       sid_base = NULL;
963       sid_ptr = &sid_base;
964       UserReactivate = 0;
965       callback_rc = 0;
966       if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
967                         call_args))
968         {
969           moira_disconnect();
970           com_err(whoami, 0, "Couldn't create/activate user %s : %s",
971                   after[U_NAME], error_message(rc));
972           return;
973         }
974       if (callback_rc)
975         {
976           moira_disconnect();
977           com_err(whoami, 0, "Couldn't create/activate user %s", after[U_NAME]);
978           return;
979         }
980       sleep(1);
981       if (sid_base != NULL)
982         {
983           sid_update(ldap_handle, dn_path);
984           linklist_free(sid_base);
985         }
986       if (UserReactivate)
987         {
988           av[0] = "ruser";
989           av[1] = after[U_NAME];
990           call_args[0] = (char *)ldap_handle;
991           call_args[1] = dn_path;
992           call_args[2] = after[U_NAME];
993           call_args[3] = user_ou;
994           rc = mr_query("get_lists_of_member", 2, av, process_lists,
995                           call_args);
996           if (rc && rc != MR_NO_MATCH)
997             {
998               com_err(whoami, 0, "Couldn't retrieve membership of user %s: %s",
999                       after[U_NAME], error_message(rc));
1000             }
1001         }
1002       moira_disconnect();
1003     }
1004
1005   return;
1006 }
1007
1008 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, 
1009                         char *oldValue, char *newValue,
1010                         char ***modvalues, int type)
1011 {
1012   LK_ENTRY    *linklist_ptr;
1013   int         i;
1014   char        *cPtr;
1015
1016   if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *)))
1017       == NULL)
1018     {
1019       return(1);
1020     }
1021   for (i = 0; i < (modvalue_count + 1); i++)
1022     (*modvalues)[i] = NULL;
1023   if (modvalue_count != 0)
1024     {
1025       linklist_ptr = linklist_base;
1026       for (i = 0; i < modvalue_count; i++)
1027         {
1028           if ((oldValue != NULL) && (newValue != NULL))
1029             {
1030               if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1031                  != (char *)NULL)
1032                 {
1033                   if (type == REPLACE)
1034                     {
1035                       if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1036                           == NULL)
1037                         return(1);
1038                       memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1039                       strcpy((*modvalues)[i], newValue);
1040                     }
1041                   else
1042                     {
1043                       if (((*modvalues)[i] = calloc(1, 
1044                                         (int)(cPtr - linklist_ptr->value) + 
1045                                         (linklist_ptr->length - strlen(oldValue)) + 
1046                                         strlen(newValue) + 1)) == NULL)
1047                         return(1);
1048                       memset((*modvalues)[i], '\0', 
1049                              (int)(cPtr - linklist_ptr->value) + 
1050                              (linklist_ptr->length - strlen(oldValue)) + 
1051                              strlen(newValue) + 1);
1052                       memcpy((*modvalues)[i], linklist_ptr->value, 
1053                              (int)(cPtr - linklist_ptr->value));
1054                       strcat((*modvalues)[i], newValue);
1055                       strcat((*modvalues)[i], 
1056      &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]);
1057                     }
1058                 }
1059               else
1060                 {
1061                   (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1062                   memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1063                   memcpy((*modvalues)[i], linklist_ptr->value,
1064                          linklist_ptr->length);
1065                 }
1066             }
1067         else
1068             {
1069               (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1070               memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1071               memcpy((*modvalues)[i], linklist_ptr->value,
1072                      linklist_ptr->length);
1073             }
1074           linklist_ptr = linklist_ptr->next;
1075         }
1076       (*modvalues)[i] = NULL;
1077     }
1078   return(0);
1079 }
1080
1081
1082 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, 
1083                    char **attr_array, LK_ENTRY **linklist_base,
1084                    int *linklist_count)
1085 {
1086   ULONG       rc;
1087   LDAPMessage *ldap_entry;
1088
1089   rc = 0;
1090   ldap_entry = NULL;
1091   (*linklist_base) = NULL;
1092   (*linklist_count) = 0;
1093   if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE, 
1094                           search_exp, attr_array, 0, &ldap_entry))
1095       != LDAP_SUCCESS)
1096     return(0);
1097   rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count);
1098
1099   ldap_msgfree(ldap_entry);
1100   return(rc);
1101 }
1102
1103
1104 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1105                      LK_ENTRY **linklist_base, int *linklist_count)
1106 {
1107   char        distinguished_name[1024];
1108   LK_ENTRY    *linklist_ptr;
1109   int         rc;
1110
1111   if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1112     return(0);
1113
1114   memset(distinguished_name, '\0', sizeof(distinguished_name));
1115   get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1116
1117   if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1118                                 linklist_base)) != 0)
1119     return(rc);
1120
1121   while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1122     {
1123       memset(distinguished_name, '\0', sizeof(distinguished_name));
1124       get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1125
1126       if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1127                                     linklist_base)) != 0)
1128         return(rc);
1129     }
1130
1131   linklist_ptr = (*linklist_base);
1132   (*linklist_count) = 0;
1133   while (linklist_ptr != NULL)
1134     {
1135       ++(*linklist_count);
1136       linklist_ptr = linklist_ptr->next;
1137     }
1138   return(0);
1139 }
1140
1141 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1142                         char *distinguished_name, LK_ENTRY **linklist_current)
1143 {
1144   char        *Attribute;
1145   BerElement  *ptr;
1146
1147   ptr = NULL;
1148   if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL)
1149     {
1150       retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1151                       linklist_current);
1152       ldap_memfree(Attribute);
1153       while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry, 
1154                                               ptr)) != NULL)
1155         {
1156           retrieve_values(ldap_handle, ldap_entry, Attribute,
1157                           distinguished_name, linklist_current);
1158           ldap_memfree(Attribute);
1159         }
1160     }
1161   ldap_ber_free(ptr, 0);
1162   return(0);
1163 }
1164
1165 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1166                     char *Attribute, char *distinguished_name,
1167                     LK_ENTRY **linklist_current)
1168 {
1169   char        **str_value;
1170   char        temp[256];
1171   void        **Ptr;
1172   int         use_bervalue;
1173   LK_ENTRY    *linklist_previous;
1174   LDAP_BERVAL **ber_value;
1175   DWORD       ber_length;
1176 #ifdef LDAP_DEBUG
1177   SID         *sid;
1178   GUID        *guid;
1179   int         i;
1180   int         intValue;
1181   DWORD       *subauth;
1182   SID_IDENTIFIER_AUTHORITY    *sid_auth;
1183   unsigned char   *subauth_count;
1184 #endif /*LDAP_BEGUG*/
1185
1186   use_bervalue = 0;
1187   memset(temp, '\0', sizeof(temp));
1188   if ((!strcmp(Attribute, "objectSid")) ||
1189       (!strcmp(Attribute, "objectGUID")))
1190     use_bervalue = 1;
1191
1192   if (use_bervalue)
1193     {
1194       ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1195       Ptr = (void **)ber_value;
1196       str_value = NULL;
1197       }
1198   else
1199     {
1200       str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1201       Ptr = (void **)str_value;
1202       ber_value = NULL;
1203     }
1204   if (Ptr != NULL)
1205     {
1206       for (; *Ptr; Ptr++) 
1207         {
1208           if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
1209             return(1);
1210           memset(linklist_previous, '\0', sizeof(LK_ENTRY));
1211           linklist_previous->next = (*linklist_current);
1212           (*linklist_current) = linklist_previous;
1213
1214           if (((*linklist_current)->attribute = calloc(1, 
1215                                                strlen(Attribute) + 1)) == NULL)
1216             return(1);
1217           memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
1218           strcpy((*linklist_current)->attribute, Attribute);
1219           if (use_bervalue)
1220             {
1221               ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
1222               if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
1223                 return(1);
1224               memset((*linklist_current)->value, '\0', ber_length);
1225               memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val, 
1226                                                   ber_length);
1227               (*linklist_current)->length = ber_length;
1228             }
1229           else
1230             {
1231               if (((*linklist_current)->value = calloc(1, 
1232                                                   strlen(*Ptr) + 1)) == NULL)
1233                 return(1);
1234               memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
1235               (*linklist_current)->length = strlen(*Ptr);
1236               strcpy((*linklist_current)->value, *Ptr);
1237             }
1238           (*linklist_current)->ber_value = use_bervalue;
1239           if (((*linklist_current)->dn = calloc(1, 
1240                                       strlen(distinguished_name) + 1)) == NULL)
1241             return(1);
1242           memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1);
1243           strcpy((*linklist_current)->dn, distinguished_name);
1244
1245 #ifdef LDAP_DEBUG
1246           if (!strcmp(Attribute, "objectGUID"))
1247             {
1248               guid = (GUID *)((*linklist_current)->value);
1249               sprintf(temp, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 
1250                       guid->Data1, guid->Data2, guid->Data3, 
1251                       guid->Data4[0], guid->Data4[1], guid->Data4[2], 
1252                       guid->Data4[3], guid->Data4[4], guid->Data4[5], 
1253                       guid->Data4[6], guid->Data4[7]);
1254               print_to_screen("     %20s : {%s}\n", Attribute, temp);
1255             }
1256           else if (!strcmp(Attribute, "objectSid"))
1257             {
1258               sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
1259 #ifdef _WIN32
1260               print_to_screen("        Revision = %d\n", sid->Revision);
1261               print_to_screen("        SID Identifier Authority:\n");
1262               sid_auth = &sid->IdentifierAuthority;
1263               if (sid_auth->Value[0])
1264                 print_to_screen("            SECURITY_NULL_SID_AUTHORITY\n");
1265               else if (sid_auth->Value[1])
1266                 print_to_screen("            SECURITY_WORLD_SID_AUTHORITY\n");
1267               else if (sid_auth->Value[2])
1268                 print_to_screen("            SECURITY_LOCAL_SID_AUTHORITY\n");
1269               else if (sid_auth->Value[3])
1270                 print_to_screen("            SECURITY_CREATOR_SID_AUTHORITY\n");
1271               else if (sid_auth->Value[5])
1272                 print_to_screen("            SECURITY_NT_AUTHORITY\n");
1273               else
1274                 print_to_screen("            UNKNOWN SID AUTHORITY\n");
1275               subauth_count = GetSidSubAuthorityCount(sid);
1276               print_to_screen("        SidSubAuthorityCount = %d\n", 
1277                               *subauth_count);
1278               print_to_screen("        SidSubAuthority:\n");
1279               for (i = 0; i < *subauth_count; i++)
1280                 {
1281                   if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
1282                     print_to_screen("            %u\n", *subauth);
1283                 }
1284 #endif
1285             }
1286           else if ((!memcmp(Attribute, "userAccountControl", 
1287                             strlen("userAccountControl"))) ||
1288                    (!memcmp(Attribute, "sAMAccountType", 
1289                             strlen("sAmAccountType"))))
1290             {
1291               intValue = atoi(*Ptr);
1292               print_to_screen("     %20s : %ld\n",Attribute, intValue);
1293               if (!memcmp(Attribute, "userAccountControl", 
1294                           strlen("userAccountControl")))
1295                 {
1296                   if (intValue & UF_ACCOUNTDISABLE)
1297                     print_to_screen("     %20s :    %s\n", 
1298                                     "", "Account disabled");
1299                   else
1300                     print_to_screen("     %20s :    %s\n", 
1301                                     "", "Account active");
1302                   if (intValue & UF_HOMEDIR_REQUIRED)
1303                     print_to_screen("     %20s :    %s\n", 
1304                                     "", "Home directory required");
1305                   if (intValue & UF_LOCKOUT)
1306                     print_to_screen("     %20s :    %s\n", 
1307                                     "", "Account locked out");
1308                   if (intValue & UF_PASSWD_NOTREQD)
1309                     print_to_screen("     %20s :    %s\n", 
1310                                     "", "No password required");
1311                   if (intValue & UF_PASSWD_CANT_CHANGE)
1312                     print_to_screen("     %20s :    %s\n",
1313                                     "", "Cannot change password");
1314                   if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
1315                     print_to_screen("     %20s :    %s\n", 
1316                                     "", "Temp duplicate account");
1317                   if (intValue & UF_NORMAL_ACCOUNT)
1318                     print_to_screen("     %20s :    %s\n", 
1319                                     "", "Normal account");
1320                   if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
1321                     print_to_screen("     %20s :    %s\n", 
1322                                     "", "Interdomain trust account");
1323                   if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
1324                     print_to_screen("     %20s :    %s\n", 
1325                                     "", "Workstation trust account");
1326                   if (intValue & UF_SERVER_TRUST_ACCOUNT)
1327                     print_to_screen("     %20s :    %s\n", 
1328                                     "", "Server trust account");
1329                 }
1330             }
1331           else
1332             {
1333               print_to_screen("     %20s : %s\n",Attribute, *Ptr);
1334             }
1335 #endif /*LDAP_DEBUG*/
1336         }
1337       if (str_value != NULL)
1338         ldap_value_free(str_value);
1339       if (ber_value != NULL)
1340         ldap_value_free_len(ber_value);
1341     }
1342   (*linklist_current) = linklist_previous;
1343   return(0);
1344 }
1345
1346 int moira_connect(void)
1347 {
1348   long    rc;
1349   char    HostName[64];
1350
1351   if (!mr_connections++)
1352     {
1353 #ifdef _WIN32
1354       memset(HostName, '\0', sizeof(HostName));
1355       strcpy(HostName, "ttsp");
1356       rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
1357 /*det
1358       rc = mr_connect(HostName);
1359 */
1360 #else
1361       struct utsname uts;
1362       uname(&uts);
1363       rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
1364 /*
1365       rc = mr_connect(uts.nodename);
1366 */
1367 #endif /*WIN32*/
1368 /*det
1369       if (!rc)
1370         rc = mr_auth("winad.incr");
1371 */
1372       return rc;
1373     }
1374   return 0;
1375 }
1376
1377 void check_winad(void)
1378 {
1379   int i;
1380   
1381   for (i = 0; file_exists(STOP_FILE); i++)
1382     {
1383       if (i > 30)
1384         {
1385           critical_alert("AD incremental",
1386                          "WINAD incremental failed (%s exists): %s",
1387                          STOP_FILE, tbl_buf);
1388           exit(1);
1389         }
1390       sleep(60);
1391     }
1392 }
1393
1394 int moira_disconnect(void)
1395 {
1396
1397   if (!--mr_connections)
1398     {
1399       mr_disconnect();
1400     }
1401   return 0;
1402 }
1403
1404 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1405                             char *distinguished_name)
1406 {
1407   char    *CName;
1408
1409   CName = ldap_get_dn(ldap_handle, ldap_entry);
1410   if (CName == NULL)
1411     return;
1412   strcpy(distinguished_name, CName);
1413   ldap_memfree(CName);
1414 }
1415
1416 int linklist_create_entry(char *attribute, char *value, 
1417                           LK_ENTRY **linklist_entry)
1418 {
1419   (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
1420   if (!(*linklist_entry))
1421     {
1422       return(1);
1423     }
1424   memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
1425   (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
1426   memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
1427   strcpy((*linklist_entry)->attribute, attribute);
1428   (*linklist_entry)->value = calloc(1, strlen(value) + 1);
1429   memset((*linklist_entry)->value, '\0', strlen(value) + 1);
1430   strcpy((*linklist_entry)->value, value);
1431   (*linklist_entry)->length = strlen(value);
1432   (*linklist_entry)->next = NULL;
1433   return(0);
1434 }
1435
1436 void print_to_screen(const char *fmt, ...)
1437 {
1438   va_list pvar;
1439
1440   va_start(pvar, fmt);
1441   vfprintf(stderr, fmt, pvar);
1442   fflush(stderr);
1443   va_end(pvar);
1444 }
1445
1446 int get_group_membership(char *group_membership, char *group_ou, 
1447                          int *security_flag, char **av)
1448 {
1449   int  maillist_flag;
1450   int  group_flag;
1451
1452   maillist_flag = atoi(av[L_MAILLIST]);
1453   group_flag = atoi(av[L_GROUP]);
1454   if (security_flag != NULL)
1455     (*security_flag) = 0;
1456
1457   if ((maillist_flag) && (group_flag))
1458     {
1459       if (group_membership != NULL)
1460         group_membership[0] = 'B';
1461       if (security_flag != NULL)
1462         (*security_flag) = 1;
1463       if (group_ou != NULL)
1464         strcpy(group_ou, group_ou_both);
1465     }
1466   else if ((!maillist_flag) && (group_flag))
1467     {
1468       if (group_membership != NULL)
1469         group_membership[0] = 'S';
1470       if (security_flag != NULL)
1471         (*security_flag) = 1;
1472       if (group_ou != NULL)
1473         strcpy(group_ou, group_ou_security);
1474     }
1475   else if ((maillist_flag) && (!group_flag))
1476     {
1477       if (group_membership != NULL)
1478         group_membership[0] = 'D';
1479       if (group_ou != NULL)
1480         strcpy(group_ou, group_ou_distribution);
1481     }
1482   else
1483     {
1484       if (group_membership != NULL)
1485         group_membership[0] = 'N';
1486       if (group_ou != NULL)
1487         strcpy(group_ou, group_ou_neither);
1488     }
1489   return(0);
1490 }
1491
1492 int group_rename(LDAP *ldap_handle, char *dn_path, 
1493                  char *before_group_name, char *before_group_membership, 
1494                  char *before_group_ou, int before_security_flag, char *before_desc,
1495                  char *after_group_name, char *after_group_membership, 
1496                  char *after_group_ou, int after_security_flag, char *after_desc)
1497 {
1498   LDAPMod   *mods[20];
1499   char      old_dn[512];
1500   char      new_dn[512];
1501   char      new_dn_path[512];
1502   char      sam_name[256];
1503   char      filter_exp[4096];
1504   char      *attr_array[3];
1505   char      *name_v[] = {NULL, NULL};
1506   char      *desc_v[] = {NULL, NULL};
1507   char      *samAccountName_v[] = {NULL, NULL};
1508   char      *groupTypeControl_v[] = {NULL, NULL};
1509   u_int     groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
1510   char      groupTypeControlStr[80];
1511   int       n;
1512   int       i;
1513   int       rc;
1514   LK_ENTRY  *group_base;
1515   int       group_count;
1516
1517   if (!check_string(before_group_name))
1518     {
1519       com_err(whoami, 0, "invalid LDAP list name %s", before_group_name);
1520       return(-1);
1521     }
1522   if (!check_string(after_group_name))
1523     {
1524       com_err(whoami, 0, "invalid LDAP list name %s", after_group_name);
1525       return(-1);
1526     }
1527
1528   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", before_group_name, before_group_membership[0]);
1529   attr_array[0] = "distinguishedName";
1530   attr_array[1] = NULL;
1531   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1532                            &group_base, &group_count)) != 0)
1533     {
1534       com_err(whoami, 0, "LDAP server unable to get list %s dn : %s",
1535               after_group_name, ldap_err2string(rc));
1536       return(rc);
1537     }
1538   if (group_count != 1)
1539     {
1540       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1541               after_group_name);
1542       callback_rc = LDAP_NO_SUCH_OBJECT;
1543       return(-1);
1544     }
1545   strcpy(old_dn, group_base->value);
1546   linklist_free(group_base);
1547   group_base = NULL;
1548   group_count = 0;
1549
1550   sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
1551   sprintf(new_dn, "cn=%s", after_group_name);
1552   if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
1553                           TRUE, NULL, NULL)) != LDAP_SUCCESS)
1554     {
1555       com_err(whoami, 0, "Couldn't rename list from %s to %s : %s",
1556               after_group_name, after_group_name, ldap_err2string(rc));
1557       return(rc);
1558     }
1559
1560   sprintf(sam_name, "%s_zZx%c", after_group_name, after_group_membership[0]);
1561   name_v[0] = after_group_name;
1562   samAccountName_v[0] = sam_name;
1563   desc_v[0] = after_desc;
1564   if (after_security_flag)
1565     groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
1566   sprintf(groupTypeControlStr, "%ld", groupTypeControl);
1567   groupTypeControl_v[0] = groupTypeControlStr;
1568   n = 0;
1569   ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
1570   ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
1571   if (strlen(after_desc) == 0)
1572     desc_v[0] = NULL;
1573   ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE);
1574   ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
1575   mods[n] = NULL;
1576   sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
1577   if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
1578     {
1579       com_err(whoami, 0, "After renaming, couldn't modify list data for %s : %s",
1580               after_group_name, ldap_err2string(rc));
1581     }
1582   for (i = 0; i < n; i++)
1583     free(mods[i]);
1584   return(rc);
1585 }
1586
1587 int group_create(int ac, char **av, void *ptr)
1588 {
1589   LDAPMod *mods[20];
1590   LK_ENTRY  *group_base;
1591   char new_dn[256];
1592   char group_ou[256];
1593   char new_group_name[256];
1594   char sam_group_name[256];
1595   char cn_group_name[256];
1596   char *cn_v[] = {NULL, NULL};
1597   char *objectClass_v[] = {"top", "group", NULL};
1598   char info[256];
1599   char *samAccountName_v[] = {NULL, NULL};
1600   char *managedBy_v[] = {NULL, NULL};
1601   char *altSecurityIdentities_v[] = {NULL, NULL};
1602   char *name_v[] = {NULL, NULL};
1603   char *desc_v[] = {NULL, NULL};
1604   char *info_v[] = {NULL, NULL};
1605   char *groupTypeControl_v[] = {NULL, NULL};
1606   char groupTypeControlStr[80];
1607   char group_membership[1];
1608   int  i;
1609   int  security_flag;
1610   u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
1611   int  n;
1612   int  rc;
1613   int  group_count;
1614   char filter_exp[256];
1615   char *attr_array[3];
1616   char **call_args;
1617
1618   call_args = ptr;
1619
1620   if (!atoi(av[L_ACTIVE]))
1621     return(1);
1622   if (!check_string(av[L_NAME]))
1623     {
1624       com_err(whoami, 0, "invalid LDAP list name %s", av[L_NAME]);
1625       return(1);
1626     }
1627
1628   memset(group_ou, 0, sizeof(group_ou));
1629   memset(group_membership, 0, sizeof(group_membership));
1630   security_flag = 0;
1631   get_group_membership(group_membership, group_ou, &security_flag, av);
1632
1633   if (security_flag)
1634     groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
1635   sprintf(groupTypeControlStr, "%ld", groupTypeControl);
1636   groupTypeControl_v[0] = groupTypeControlStr;
1637
1638   strcpy(new_group_name, av[L_NAME]);
1639   strcpy(cn_group_name, av[L_NAME]);
1640   sprintf(sam_group_name, "%s_zZx%c", av[L_NAME], group_membership[0]);
1641
1642   samAccountName_v[0] = sam_group_name;
1643   name_v[0] = new_group_name;
1644   cn_v[0] = new_group_name;
1645
1646   sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
1647   n = 0;
1648   ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
1649   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
1650   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
1651   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
1652   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
1653   if (strlen(av[L_DESC]) != 0)
1654     {
1655       desc_v[0] = av[L_DESC];
1656       ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
1657     }
1658   ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
1659   if (strlen(av[L_ACE_NAME]) != 0)
1660     {
1661       sprintf(info, "The Administrator of this list is the LIST: %s", av[L_ACE_NAME]);
1662       info_v[0] = info;
1663       ADD_ATTR("info", info_v, LDAP_MOD_ADD);
1664     }
1665   mods[n] = NULL;
1666
1667   rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
1668
1669   for (i = 0; i < n; i++)
1670     free(mods[i]);
1671   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
1672     {
1673       com_err(whoami, 0, "Unable to create list %s in AD : %s",
1674               av[L_NAME], ldap_err2string(rc));
1675       callback_rc = rc;
1676       return(rc);
1677     }
1678   if (rc == LDAP_ALREADY_EXISTS)
1679     {
1680       n = 0;
1681       desc_v[0] = av[L_DESC];
1682       if (strlen(av[L_DESC]) == 0)
1683         desc_v[0] = NULL;
1684       ADD_ATTR("description", desc_v, LDAP_MOD_REPLACE);
1685       mods[n] = NULL;
1686       rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
1687       for (i = 0; i < n; i++)
1688         free(mods[i]);
1689     }
1690   sprintf(filter_exp, "(sAMAccountName=%s)", sam_group_name);
1691   attr_array[0] = "objectSid";
1692   attr_array[1] = NULL;
1693   group_count = 0;
1694   group_base = NULL;
1695   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
1696                            &group_base, &group_count)) == LDAP_SUCCESS)
1697     {
1698       if (group_count == 1)
1699         {
1700           (*sid_ptr) = group_base;
1701           (*sid_ptr)->member = strdup(av[L_NAME]);
1702           (*sid_ptr)->type = (char *)GROUPS;
1703           sid_ptr = &(*sid_ptr)->next;
1704         }
1705       else
1706         {
1707           if (group_base != NULL)
1708             linklist_free(group_base);
1709         }
1710     }
1711   else
1712     {
1713       if (group_base != NULL)
1714         linklist_free(group_base);
1715     }
1716   return(LDAP_SUCCESS);
1717 }
1718
1719 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name, char *group_membership)
1720 {
1721   LK_ENTRY  *group_base;
1722   char      *attr_array[3];
1723   char      filter_exp[1024];
1724   char      sam_group_name[256];
1725   char      temp[512];
1726   int       group_count;
1727   int       rc;
1728
1729   if (!check_string(group_name))
1730     {
1731       com_err(whoami, 0, "invalid LDAP list name %s", group_name);
1732       return(-1);
1733     }
1734   rc = 1;
1735   group_count = 0;
1736   group_base = NULL;
1737   attr_array[0] = "distinguishedName";
1738   attr_array[1] = NULL;
1739   strcpy(sam_group_name, group_name);
1740   sprintf(temp, "%s,%s", group_ou_root, dn_path);
1741   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1742   if (linklist_build(ldap_handle, temp, filter_exp, attr_array, 
1743                            &group_base, &group_count) != 0)
1744     return(-1);
1745   if (group_count == 1)
1746     {
1747       if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
1748         {
1749           linklist_free(group_base);
1750           com_err(whoami, 0, "Unable to delete list %s from AD : %s",
1751                   group_name, ldap_err2string(rc));
1752           return(-1);
1753         }
1754       linklist_free(group_base);
1755     }
1756   else
1757     {
1758       linklist_free(group_base);
1759       com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
1760       return(-1);
1761     }
1762
1763   return(0);
1764 }
1765
1766 int process_lists(int ac, char **av, void *ptr)
1767 {
1768   int   rc;
1769   int   security_flag;
1770   char  group_ou[256];
1771   char  group_membership[2];
1772   char  **call_args;
1773
1774   call_args = ptr;
1775
1776   security_flag = 0;
1777   memset(group_ou, '\0', sizeof(group_ou));
1778   memset(group_membership, '\0', sizeof(group_membership));
1779   get_group_membership(group_membership, group_ou, &security_flag, av);
1780   rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
1781                   group_ou, group_membership, call_args[2],  (char *)call_args[3]);
1782   if (rc)
1783     {
1784       com_err(whoami, 0, "Couldn't add %s to group %s", call_args[2], av[L_NAME]);
1785     }
1786   return(0);
1787 }
1788
1789 int member_list_build(int ac, char **av, void *ptr)
1790 {
1791   LK_ENTRY  *linklist;
1792   char      temp[1024];
1793   char      **call_args;
1794
1795   call_args = ptr;
1796
1797   strcpy(temp, av[ACE_NAME]);
1798   if (!check_string(temp))
1799     return(0);
1800   if (!strcmp(av[ACE_TYPE], "USER"))
1801     {
1802       if (!((int)call_args[3] & MOIRA_USERS))
1803         return(0);
1804     }
1805   else if (!strcmp(av[ACE_TYPE], "STRING"))
1806     {
1807       if (!((int)call_args[3] & MOIRA_STRINGS))
1808         return(0);
1809       if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
1810         return(0);
1811     }
1812   else if (!strcmp(av[ACE_TYPE], "LIST"))
1813     {
1814       if (!((int)call_args[3] & MOIRA_LISTS))
1815         return(0);
1816     }
1817   else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
1818     {
1819       if (!((int)call_args[3] & MOIRA_KERBEROS))
1820         return(0);
1821       if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
1822         return(0);
1823     }
1824   else
1825     return(0);
1826
1827   linklist = member_base;
1828   while (linklist)
1829     {
1830     if (!strcasecmp(temp, linklist->member))
1831       return(0);
1832     linklist = linklist->next;
1833     }
1834   linklist = calloc(1, sizeof(LK_ENTRY));
1835   linklist->op = 1;
1836   linklist->dn = NULL;
1837   linklist->list = calloc(1, strlen(call_args[2]) + 1);
1838   strcpy(linklist->list, call_args[2]);
1839   linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
1840   strcpy(linklist->type, av[ACE_TYPE]);
1841   linklist->member = calloc(1, strlen(temp) + 1);
1842   strcpy(linklist->member, temp);
1843   linklist->next = member_base;
1844   member_base = linklist;
1845   return(0);
1846 }
1847
1848 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, 
1849                   char *group_ou, char *group_membership, char *user_name,
1850                   char *UserOu)
1851 {
1852   char        distinguished_name[1024];
1853   char        *modvalues[2];
1854   char        filter_exp[4096];
1855   char        *attr_array[3];
1856   char        temp[256];
1857   int         group_count;
1858   int         i;
1859   int         n;
1860   LDAPMod     *mods[20];
1861   LK_ENTRY    *group_base;
1862   ULONG       rc;
1863
1864   if (!check_string(group_name))
1865     return(1);
1866   strcpy(temp, group_name);
1867   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1868   attr_array[0] = "distinguishedName";
1869   attr_array[1] = NULL;
1870   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1871                            &group_base, &group_count)) != 0)
1872     {
1873       com_err(whoami, 0, "LDAP server unable to get list %s info : %s",
1874               group_name, ldap_err2string(rc));
1875       goto cleanup;
1876     }
1877   if (group_count != 1)
1878     {
1879       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1880               group_name);
1881       linklist_free(group_base);
1882       group_base = NULL;
1883       group_count = 0;
1884       goto cleanup;
1885     }
1886   strcpy(distinguished_name, group_base->value);
1887   linklist_free(group_base);
1888   group_base = NULL;
1889   group_count = 0;
1890
1891   sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
1892   modvalues[0] = temp;
1893   modvalues[1] = NULL;
1894
1895   n = 0;
1896   ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
1897   mods[n] = NULL;
1898   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1899   for (i = 0; i < n; i++)
1900     free(mods[i]);
1901   if (rc != LDAP_SUCCESS)
1902     {
1903       com_err(whoami, 0, "LDAP server unable to modify list %s members : %s",
1904               group_name, ldap_err2string(rc));
1905       goto cleanup;
1906     }
1907
1908 cleanup:
1909   return(rc);
1910 }
1911
1912 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, 
1913                char *group_ou, char *group_membership, char *user_name, char *UserOu)
1914 {
1915   char        distinguished_name[1024];
1916   char        *modvalues[2];
1917   char        filter_exp[4096];
1918   char        *attr_array[3];
1919   char        temp[256];
1920   int         group_count;
1921   int         n;
1922   int         i;
1923   LDAPMod     *mods[20];
1924   LK_ENTRY    *group_base;
1925   ULONG       rc;
1926
1927   rc = 0;
1928   group_base = NULL;
1929   group_count = 0;
1930
1931   if (!check_string(group_name))
1932     return(-1);
1933
1934   strcpy(temp, group_name);
1935   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_name, group_membership[0]);
1936   attr_array[0] = "distinguishedName";
1937   attr_array[1] = NULL;
1938   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1939                            &group_base, &group_count)) != 0)
1940     {
1941       com_err(whoami, 0, "LDAP server unable to get list %s info : %s",
1942               group_name, ldap_err2string(rc));
1943       return(-1);
1944     }
1945   if (group_count != 1)
1946     {
1947       linklist_free(group_base);
1948       group_base = NULL;
1949       group_count = 0;
1950       com_err(whoami, 0, "LDAP server unable to find list %s in AD",
1951               group_name);
1952       return(-1);
1953     }
1954
1955   strcpy(distinguished_name, group_base->value);
1956   linklist_free(group_base);
1957   group_base = NULL;
1958   group_count = 0;
1959
1960   sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
1961   modvalues[0] = temp;
1962   modvalues[1] = NULL;
1963
1964   n = 0;
1965   ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
1966   mods[n] = NULL;
1967   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1968   if (rc == LDAP_ALREADY_EXISTS)
1969     rc = LDAP_SUCCESS;
1970   for (i = 0; i < n; i++)
1971     free(mods[i]);
1972   if (rc != LDAP_SUCCESS)
1973     {
1974       com_err(whoami, 0, "LDAP server unable to modify list %s members in AD : %s",
1975               group_name, ldap_err2string(rc));
1976     }
1977
1978   return(rc);
1979 }
1980
1981 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
1982 {
1983   LDAPMod *mods[20];
1984   char new_dn[256];
1985   char cn_user_name[256];
1986   char contact_name[256];
1987   char *email_v[] = {NULL, NULL};
1988   char *cn_v[] = {NULL, NULL};
1989   char *contact_v[] = {NULL, NULL};
1990   char *objectClass_v[] = {"top", "person", 
1991                            "organizationalPerson", 
1992                            "contact", NULL};
1993   char *name_v[] = {NULL, NULL};
1994   char *desc_v[] = {NULL, NULL};
1995   int  n;
1996   int  rc;
1997   int  i;
1998
1999   if (!check_string(user))
2000     {
2001       com_err(whoami, 0, "invalid LDAP name %s", user);
2002       return(-1);
2003     }
2004   strcpy(contact_name, user);
2005   sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
2006   cn_v[0] = cn_user_name;
2007   contact_v[0] = contact_name;
2008   name_v[0] = user;
2009   desc_v[0] = "Auto account created by Moira";
2010   email_v[0] = user;
2011
2012   strcpy(new_dn, cn_user_name);
2013   n = 0;
2014   ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
2015   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2016   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2017   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2018   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2019   if (!strcmp(group_ou, contact_ou))
2020     {
2021       ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
2022     }
2023   mods[n] = NULL;
2024
2025   rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
2026   for (i = 0; i < n; i++)
2027     free(mods[i]);
2028   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2029     {
2030       n = 0;
2031       ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
2032       ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2033       ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2034       ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2035       ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2036       mods[n] = NULL;
2037       rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
2038       for (i = 0; i < n; i++)
2039         free(mods[i]);
2040     }
2041   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2042     {
2043       com_err(whoami, 0, "could not create contact %s : %s",
2044               user, ldap_err2string(rc));
2045       return(-1);
2046     }
2047   return(0);
2048 }
2049
2050 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
2051                 char *Uid, char *MitId)
2052 {
2053   LDAPMod   *mods[20];
2054   LK_ENTRY  *group_base;
2055   int  group_count;
2056   char distinguished_name[256];
2057   char *uid_v[] = {NULL, NULL};
2058   char *mitid_v[] = {NULL, NULL};
2059   char *homedir_v[] = {NULL, NULL};
2060   char *winProfile_v[] = {NULL, NULL};
2061   char *drives_v[] = {NULL, NULL};
2062   int  n;
2063   int  rc;
2064   int  i;
2065   char filter_exp[256];
2066   char *attr_array[3];
2067   char **hp;
2068   char path[256];
2069   char winPath[256];
2070   char winProfile[256];
2071
2072   if (!check_string(user_name))
2073     {
2074       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2075       return(-1);
2076     }
2077
2078   group_count = 0;
2079   group_base = NULL;
2080   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2081   attr_array[0] = "cn";
2082   attr_array[1] = NULL;
2083   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2084                            &group_base, &group_count)) != 0)
2085     {
2086       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2087               user_name, ldap_err2string(rc));
2088       return(rc);
2089     }
2090
2091   if (group_count != 1)
2092     {
2093       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2094               user_name);
2095       linklist_free(group_base);
2096       return(LDAP_NO_SUCH_OBJECT);
2097     }
2098   strcpy(distinguished_name, group_base->dn);
2099
2100   linklist_free(group_base);
2101   group_count = 0;
2102   n = 0;
2103   if (strlen(Uid) != 0)
2104     {
2105       uid_v[0] = Uid;
2106       ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
2107       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2108     }
2109   if (strlen(MitId) != 0)
2110     {
2111       mitid_v[0] = MitId;
2112       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2113     }
2114   if ((hp = hes_resolve(user_name, "filsys")) != NULL)
2115     {
2116       memset(path, 0, sizeof(path));
2117       memset(winPath, 0, sizeof(winPath));
2118       sscanf(hp[0], "%*s %s", path);
2119       if (strlen(path) && strnicmp(path, AFS, strlen(AFS)) == 0)
2120         {
2121           AfsToWinAfs(path, winPath);
2122           homedir_v[0] = winPath;
2123           ADD_ATTR("homeDirectory", homedir_v, LDAP_MOD_REPLACE);
2124           strcpy(winProfile, winPath);
2125           strcat(winProfile, "\\.winprofile");
2126           winProfile_v[0] = winProfile;
2127           ADD_ATTR("profilePath", winProfile_v, LDAP_MOD_REPLACE);
2128           drives_v[0] = "H:";
2129           ADD_ATTR("homeDrive", drives_v, LDAP_MOD_REPLACE);
2130         }
2131     }
2132   mods[n] = NULL;
2133   if (n != 0)
2134     {
2135       if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) != LDAP_SUCCESS)
2136         {
2137           com_err(whoami, 0, "Couldn't modify user data for %s : %s",
2138                   user_name, ldap_err2string(rc));
2139         }
2140       for (i = 0; i < n; i++)
2141         free(mods[i]);
2142     }
2143   if (hp != NULL)
2144     {
2145       i = 0;
2146       while (hp[i])
2147         {
2148           free(hp[i]);
2149           i++;
2150         }
2151     }
2152
2153   return(rc);
2154 }
2155
2156 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, 
2157                 char *user_name, char *Uid, char *MitId, int State)
2158 {
2159   LDAPMod *mods[20];
2160   char new_dn[256];
2161   char old_dn[256];
2162   char upn[256];
2163   char temp[128];
2164   char *userPrincipalName_v[] = {NULL, NULL};
2165   char *altSecurityIdentities_v[] = {NULL, NULL};
2166   char *name_v[] = {NULL, NULL};
2167   char *samAccountName_v[] = {NULL, NULL};
2168   char *uid_v[] = {NULL, NULL};
2169   char *mitid_v[] = {NULL, NULL};
2170   int  n;
2171   int  rc;
2172   int  i;
2173
2174   if ((State != US_REGISTERED) && (State != US_NO_PASSWD) && (State != US_ENROLL_NOT_ALLOWED))
2175     return(-1);
2176
2177   if (!check_string(before_user_name))
2178     {
2179       com_err(whoami, 0, "invalid LDAP user name %s", before_user_name);
2180       return(-1);
2181     }
2182   if (!check_string(user_name))
2183     {
2184       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2185       return(-1);
2186     }
2187
2188   strcpy(user_name, user_name);
2189   sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
2190   sprintf(new_dn, "cn=%s", user_name);
2191   if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE, 
2192                            NULL, NULL)) != LDAP_SUCCESS)
2193     {
2194       if (rc != LDAP_NO_SUCH_OBJECT)
2195         com_err(whoami, 0, "Couldn't rename user from %s to %s : %s",
2196                 before_user_name, user_name, ldap_err2string(rc));
2197       return(rc);
2198     }
2199
2200   name_v[0] = user_name;
2201   sprintf(upn, "%s@%s", user_name, ldap_domain);
2202   userPrincipalName_v[0] = upn;
2203   sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
2204   altSecurityIdentities_v[0] = temp;
2205   samAccountName_v[0] = user_name;
2206
2207   n = 0;
2208   ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
2209   ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
2210   ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2211   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2212   if (strlen(Uid) != 0)
2213     {
2214       uid_v[0] = Uid;
2215       ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
2216       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2217     }
2218   if (strlen(MitId) != 0)
2219     {
2220       mitid_v[0] = MitId;
2221       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2222     }
2223   mods[n] = NULL;
2224   sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
2225   if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2226     {
2227       com_err(whoami, 0, "After renaming, couldn't modify user data for %s : %s",
2228               user_name, ldap_err2string(rc));
2229     }
2230   for (i = 0; i < n; i++)
2231     free(mods[i]);
2232   return(rc);
2233 }
2234
2235 int filesys_process(LDAP *ldap_handle, char *dn_path, char *fs_name, 
2236                     char *fs_type, char *fs_pack, int operation)
2237 {
2238   char  distinguished_name[256];
2239   char  winPath[256];
2240   char  winProfile[256];
2241   char  filter_exp[256];
2242   char  *attr_array[3];
2243   char  *homedir_v[] = {NULL, NULL};
2244   char  *winProfile_v[] = {NULL, NULL};
2245   char  *drives_v[] = {NULL, NULL};
2246   int   group_count;
2247   int   n;
2248   int   rc;
2249   int   i;
2250   LDAPMod   *mods[20];
2251   LK_ENTRY  *group_base;
2252
2253   if (!check_string(fs_name))
2254     {
2255       com_err(whoami, 0, "invalid filesys name %s", fs_name);
2256       return(-1);
2257     }
2258
2259   if (strcmp(fs_type, "AFS"))
2260     {
2261       com_err(whoami, 0, "invalid filesys type %s", fs_type);
2262       return(-1);
2263     }
2264
2265   group_count = 0;
2266   group_base = NULL;
2267   sprintf(filter_exp, "(sAMAccountName=%s)", fs_name);
2268   attr_array[0] = "cn";
2269   attr_array[1] = NULL;
2270   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2271                            &group_base, &group_count)) != 0)
2272     {
2273       com_err(whoami, 0, "LDAP server couldn't process filesys %s : %s",
2274               fs_name, ldap_err2string(rc));
2275       return(rc);
2276     }
2277
2278   if (group_count != 1)
2279     {
2280       linklist_free(group_base);
2281       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2282               fs_name);
2283       return(LDAP_NO_SUCH_OBJECT);
2284     }
2285   strcpy(distinguished_name, group_base->dn);
2286   linklist_free(group_base);
2287   group_count = 0;
2288
2289   n = 0;
2290   if (operation == LDAP_MOD_ADD)
2291     {
2292       memset(winPath, 0, sizeof(winPath));
2293       AfsToWinAfs(fs_pack, winPath);
2294       homedir_v[0] = winPath;
2295       drives_v[0] = "H:";
2296       memset(winProfile, 0, sizeof(winProfile));
2297       strcpy(winProfile, winPath);
2298       strcat(winProfile, "\\.winprofile");
2299       winProfile_v[0] = winProfile;
2300     }
2301   else
2302     {
2303       homedir_v[0] = NULL;
2304       drives_v[0] = NULL;
2305       winProfile_v[0] = NULL;
2306     }
2307   ADD_ATTR("profilePath", winProfile_v, operation);
2308   ADD_ATTR("homeDrive", drives_v, operation);
2309   ADD_ATTR("homeDirectory", homedir_v, operation);
2310   mods[n] = NULL;
2311
2312   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2313   if (rc != LDAP_SUCCESS)
2314     {
2315       com_err(whoami, 0, "Couldn't modify user data for filesys %s : %s",
2316               fs_name, ldap_err2string(rc));
2317     }
2318   for (i = 0; i < n; i++)
2319     free(mods[i]);
2320
2321   return(rc);
2322 }
2323
2324 int user_create(int ac, char **av, void *ptr)
2325 {
2326   LK_ENTRY  *group_base;
2327   LDAPMod *mods[20];
2328   char new_dn[256];
2329   char user_name[256];
2330   char sam_name[256];
2331   char upn[256];
2332   char *cn_v[] = {NULL, NULL};
2333   char *objectClass_v[] = {"top", "person", 
2334                            "organizationalPerson", 
2335                            "user", NULL};
2336
2337   char *samAccountName_v[] = {NULL, NULL};
2338   char *altSecurityIdentities_v[] = {NULL, NULL};
2339   char *name_v[] = {NULL, NULL};
2340   char *desc_v[] = {NULL, NULL};
2341   char *userPrincipalName_v[] = {NULL, NULL};
2342   char *userAccountControl_v[] = {NULL, NULL};
2343   char *uid_v[] = {NULL, NULL};
2344   char *mitid_v[] = {NULL, NULL};
2345   char userAccountControlStr[80];
2346   char temp[128];
2347   u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE;
2348   int  n;
2349   int  rc;
2350   int  i;
2351   int  group_count;
2352   char filter_exp[256];
2353   char *attr_array[3];
2354   char **call_args;
2355
2356   call_args = ptr;
2357
2358   if ((atoi(av[U_STATE]) != US_REGISTERED) && (atoi(av[U_STATE]) != US_NO_PASSWD) && 
2359       (atoi(av[U_STATE]) != US_ENROLL_NOT_ALLOWED))
2360     {
2361       callback_rc = -1;
2362       return(-1);
2363     }
2364   if (!strncmp(av[U_NAME], "#", 1))
2365     {
2366       callback_rc = -1;
2367       return(-1);
2368     }
2369   if (!check_string(av[U_NAME]))
2370     {
2371       callback_rc = -1;
2372       com_err(whoami, 0, "invalid LDAP user name %s", av[U_NAME]);
2373       return(-1);
2374     }
2375
2376   strcpy(user_name, av[U_NAME]);
2377   sprintf(upn, "%s@%s", user_name, ldap_domain);
2378   sprintf(sam_name, "%s", av[U_NAME]);
2379   samAccountName_v[0] = sam_name;
2380   if (atoi(av[U_STATE]) == US_DELETED)
2381     userAccountControl |= UF_ACCOUNTDISABLE;
2382   sprintf(userAccountControlStr, "%ld", userAccountControl);
2383   userAccountControl_v[0] = userAccountControlStr;
2384   userPrincipalName_v[0] = upn;
2385
2386   cn_v[0] = user_name;
2387   name_v[0] = user_name;
2388   desc_v[0] = "Auto account created by Moira";
2389   sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
2390   altSecurityIdentities_v[0] = temp;    
2391   sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
2392
2393   n = 0;
2394   ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2395   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2396   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2397   ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
2398   ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
2399   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2400   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2401   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2402   ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
2403   if (strlen(av[U_UID]) != 0)
2404     {
2405       uid_v[0] = av[U_UID];
2406       ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
2407       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
2408     }
2409   if (strlen(av[U_MITID]) != 0)
2410       mitid_v[0] = av[U_MITID];
2411   else
2412       mitid_v[0] = "none";
2413   ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
2414   mods[n] = NULL;
2415
2416   rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2417   for (i = 0; i < n; i++)
2418     free(mods[i]);
2419   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2420     {
2421       com_err(whoami, 0, "could not create user %s : %s",
2422               user_name, ldap_err2string(rc));
2423       callback_rc = rc;
2424       return(rc);
2425     }
2426   if (rc == LDAP_ALREADY_EXISTS)
2427     {
2428       UserReactivate = 1;
2429       rc = user_change_status((LDAP *)call_args[0], call_args[1], av[U_NAME], MEMBER_ACTIVATE);
2430       return(0);
2431     }
2432   if (rc == LDAP_SUCCESS)
2433     {
2434       if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
2435         {
2436           com_err(whoami, 0, "Couldn't set password for user %s : %ld",
2437                   user_name, rc);
2438         }
2439     }
2440   sprintf(filter_exp, "(sAMAccountName=%s)", av[U_NAME]);
2441   attr_array[0] = "objectSid";
2442   attr_array[1] = NULL;
2443   group_count = 0;
2444   group_base = NULL;
2445   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
2446                            &group_base, &group_count)) == LDAP_SUCCESS)
2447     {
2448       if (group_count == 1)
2449         {
2450           (*sid_ptr) = group_base;
2451           (*sid_ptr)->member = strdup(av[L_NAME]);
2452           (*sid_ptr)->type = (char *)GROUPS;
2453           sid_ptr = &(*sid_ptr)->next;
2454         }
2455       else
2456         {
2457           if (group_base != NULL)
2458             linklist_free(group_base);
2459         }
2460     }
2461   else
2462     {
2463       if (group_base != NULL)
2464         linklist_free(group_base);
2465     }
2466   return(0);
2467 }
2468
2469 int user_change_status(LDAP *ldap_handle, char *dn_path, char *user_name, int operation)
2470 {
2471   char      filter_exp[1024];
2472   char      *attr_array[3];
2473   char      temp[256];
2474   char      distinguished_name[1024];
2475   char      **modvalues;
2476   LDAPMod   *mods[20];
2477   LK_ENTRY  *group_base;
2478   int       group_count;
2479   int       rc;
2480   int       i;
2481   int       n;
2482   ULONG     ulongValue;
2483
2484   if (!check_string(user_name))
2485     {
2486       com_err(whoami, 0, "invalid LDAP user name %s", user_name);
2487       return(-1);
2488     }
2489
2490   group_count = 0;
2491   group_base = NULL;
2492   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2493   attr_array[0] = "UserAccountControl";
2494   attr_array[1] = NULL;
2495   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2496                            &group_base, &group_count)) != 0)
2497     {
2498       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2499               user_name, ldap_err2string(rc));
2500       return(rc);
2501     }
2502
2503   if (group_count != 1)
2504     {
2505       linklist_free(group_base);
2506       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2507               user_name);
2508       return(LDAP_NO_SUCH_OBJECT);
2509     }
2510
2511   strcpy(distinguished_name, group_base->dn);
2512   ulongValue = atoi((*group_base).value);
2513   if (operation == MEMBER_DEACTIVATE)
2514     ulongValue |= UF_ACCOUNTDISABLE;
2515   else    
2516     ulongValue &= ~UF_ACCOUNTDISABLE;
2517   sprintf(temp, "%ld", ulongValue);
2518   if ((rc = construct_newvalues(group_base, group_count, (*group_base).value, 
2519                                 temp, &modvalues, REPLACE)) == 1)
2520     goto cleanup;
2521   linklist_free(group_base);
2522   group_base = NULL;
2523   group_count = 0;
2524   n = 0;
2525   ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
2526   mods[n] = NULL;
2527   rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
2528   for (i = 0; i < n; i++)
2529     free(mods[i]);
2530   free_values(modvalues);
2531   if (rc != LDAP_SUCCESS)
2532     {
2533       com_err(whoami, 0, "LDAP server could not change status of user %s : %s",
2534               user_name, ldap_err2string(rc));
2535     }
2536 cleanup:
2537   return(rc);
2538 }
2539
2540 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name)
2541 {
2542   char      filter_exp[1024];
2543   char      *attr_array[3];
2544   char      distinguished_name[1024];
2545   char      user_name[512];
2546   LK_ENTRY  *group_base;
2547   int       group_count;
2548   int       rc;
2549
2550   if (!check_string(u_name))
2551     return(0);
2552   strcpy(user_name, u_name);
2553   group_count = 0;
2554   group_base = NULL;
2555   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2556   attr_array[0] = "name";
2557   attr_array[1] = NULL;
2558   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2559                            &group_base, &group_count)) != 0)
2560     {
2561       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2562               user_name, ldap_err2string(rc));
2563       goto cleanup;
2564     }
2565
2566   if (group_count != 1)
2567     {
2568       com_err(whoami, 0, "LDAP server unable to find user %s in AD",
2569               user_name);
2570       goto cleanup;
2571     }
2572
2573   strcpy(distinguished_name, group_base->dn);
2574   if (rc = ldap_delete_s(ldap_handle, distinguished_name))
2575     {
2576       com_err(whoami, 0, "LDAP server couldn't process user %s : %s",
2577               user_name, ldap_err2string(rc));
2578     }
2579
2580 cleanup:
2581   linklist_free(group_base);
2582   return(0);
2583 }
2584
2585 void linklist_free(LK_ENTRY *linklist_base)
2586 {
2587   LK_ENTRY *linklist_previous;
2588
2589   while (linklist_base != NULL)
2590     {
2591       if (linklist_base->dn != NULL)
2592         free(linklist_base->dn);
2593       if (linklist_base->attribute != NULL)
2594         free(linklist_base->attribute);
2595       if (linklist_base->value != NULL)
2596         free(linklist_base->value);
2597       if (linklist_base->member != NULL)
2598         free(linklist_base->member);
2599       if (linklist_base->type != NULL)
2600         free(linklist_base->type);
2601       if (linklist_base->list != NULL)
2602         free(linklist_base->list);
2603       linklist_previous = linklist_base;
2604       linklist_base = linklist_previous->next;
2605       free(linklist_previous);
2606     }
2607 }
2608
2609 void free_values(char **modvalues)
2610 {
2611   int i;
2612
2613   i = 0;
2614   if (modvalues != NULL)
2615     {
2616     while (modvalues[i] != NULL)
2617       {
2618         free(modvalues[i]);
2619         modvalues[i] = NULL;
2620         ++i;
2621       }
2622     free(modvalues);
2623   }
2624 }
2625
2626 int sid_update(LDAP *ldap_handle, char *dn_path)
2627 {
2628   LK_ENTRY      *ptr;
2629   int           rc;
2630   unsigned char temp[126];
2631   char          *av[3];
2632
2633   ptr = sid_base;
2634
2635   while (ptr != NULL)
2636     {
2637       memset(temp, 0, sizeof(temp));
2638       convert_b_to_a(temp, ptr->value, ptr->length);
2639       if (!ptr->member)
2640         continue;
2641       av[0] = ptr->member;
2642       av[1] = temp;
2643       if (ptr->type == (char *)GROUPS)
2644         {
2645           ptr->type = NULL;
2646           rc = mr_query("add_list_sid_by_name", 2, av, NULL, NULL);
2647         }
2648       else if (ptr->type == (char *)USERS)
2649         {
2650           ptr->type = NULL;
2651           rc = mr_query("add_user_sid_by_login", 2, av, NULL, NULL);
2652         }
2653       ptr = ptr->next;
2654     }
2655   return(0);
2656 }
2657
2658 void convert_b_to_a(char *string, UCHAR *binary, int length)
2659 {
2660   int   i;
2661   int   j;
2662   UCHAR tmp;
2663
2664   j = 0;
2665   for (i = 0; i < length; i++)
2666     {
2667       tmp = binary[i];
2668       string[j] = tmp;
2669       string[j] >>= 4;
2670       string[j] &= 0x0f;
2671       string[j] += 0x30;
2672       if (string[j] > '9')
2673         string[j] += 0x27;
2674       ++j;
2675       string[j] = tmp & 0x0f;
2676       string[j] += 0x30;
2677       if (string[j] > '9')
2678         string[j] += 0x27;
2679       j++;
2680     }
2681   string[j] = 0;
2682 }
2683
2684 static int illegalchars[] = {
2685   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2686   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2687   1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
2688   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
2689   0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
2690   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
2691   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2692   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
2693   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2694   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2695   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2696   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2697   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2698   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2699   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2700   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2701 };
2702
2703 int check_string(char *s)
2704 {
2705   char  character;
2706
2707   for (; *s; s++)
2708     {
2709       character = *s;
2710       if (isupper(character))
2711         character = tolower(character);
2712       if (illegalchars[(unsigned) character])
2713         return 0;
2714     }
2715   return 1;
2716 }
2717
2718 int mr_connect_cl(char *server, char *client, int version, int auth)
2719 {
2720   int   status;
2721   char  *motd;
2722   char  temp[128];
2723
2724   status = mr_connect(server);
2725   if (status)
2726     {
2727       com_err(whoami, status, "while connecting to Moira");
2728       return status;
2729     }
2730
2731   status = mr_motd(&motd);
2732   if (status)
2733     {
2734       mr_disconnect();
2735       com_err(whoami, status, "while checking server status");
2736       return status;
2737     }
2738   if (motd)
2739     {
2740       sprintf(temp, "The Moira server is currently unavailable: %s", motd);
2741       com_err(whoami, status, temp);
2742       mr_disconnect();
2743       return status;
2744     }
2745
2746   status = mr_version(version);
2747   if (status)
2748     {
2749       if (status == MR_UNKNOWN_PROC)
2750         {
2751           if (version > 2)
2752             status = MR_VERSION_HIGH;
2753           else
2754             status = MR_SUCCESS;
2755         }
2756
2757       if (status == MR_VERSION_HIGH)
2758         {
2759           com_err(whoami, 0, "Warning: This client is running newer code than the server.");
2760                   com_err(whoami, 0, "Some operations may not work.");
2761         }
2762       else if (status && status != MR_VERSION_LOW)
2763         {
2764           com_err(whoami, status, "while setting query version number.");
2765           mr_disconnect();
2766           return status;
2767         }
2768     }
2769
2770   if (auth)
2771     {
2772       status = mr_auth(client);
2773       if (status)
2774         {
2775           com_err(whoami, status, "while authenticating to Moira.");
2776           mr_disconnect();
2777           return status;
2778         }
2779     }
2780
2781   return MR_SUCCESS;
2782 }
2783
2784 void AfsToWinAfs(char* path, char* winPath)
2785 {
2786     char* pathPtr;
2787     char* winPathPtr;
2788     strcpy(winPath, WINAFS);
2789     pathPtr = path + strlen(AFS);
2790     winPathPtr = winPath + strlen(WINAFS);
2791
2792     while (*pathPtr)
2793     {
2794         if (*pathPtr == '/')
2795           *winPathPtr = '\\';
2796         else
2797           *winPathPtr = *pathPtr;
2798
2799         pathPtr++;
2800         winPathPtr++;
2801     }
2802 }
This page took 0.314 seconds and 5 git commands to generate.