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