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