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