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