]> andersk Git - moira.git/blob - incremental/winad/winad.c
Don't use colons as a field seperator internally; it makes life hard for
[moira.git] / incremental / winad / winad.c
1 /* $Header$
2 /* test parameters for creating a user account - done 
3  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 0 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF
4  * users 10 10 a_chen 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF a_chen 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF
5  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
6  *
7  * test parameters for deactivating/deleting a user account - done
8  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF testacc 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF 
9  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF 
10  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
11  * comment: clearid is the MIT ID
12  *
13  * test parameters for reactivating a user account - done
14  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 3 950000000 STAFF testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF 
15  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
16  *
17  * test parameters for updating user account info - done
18  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc 31275 sh cmd newLastname Firstname Middlename 2 950000000 STAFF 
19  * users 10 10 6_d0006 950 sh cmd Lastname Firstname Middlename 1 900012345 STAFF 6_d0006 950 sh cmd Lastname Firstname Middlename 1 950012345 STAFF
20  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
21  *   currently, if the unix_id doesn't change, only the U_UID or U_MITID fields will be updated
22  *
23  * test parameters for changing user name - testing
24  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF testacc1 31275 sh cmd Lastname Firstname Middlename 2 950000000 STAFF
25  * users 10 10 testacc 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF testacc1 31275 sh cmd Lastname Firstname Middlename 1 950000000 STAFF
26  *   login, unix_uid, shell, winconsoleshell, last, first, middle, status, clearid, type
27  *
28  * test parameters for add member to group/list - done
29  * imembers 0 10 pismere-team USER dtanner 1 1 0 1 1 -1 1
30  * imembers 0 9 pismere-team STRING hope@ful.net 1 1 0 1 1 -1
31  *   list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid
32  *
33  * test parameters for remove member from group/list - done
34  * imembers 10 0 pismere-team USER dtanner 1 1 0 1 1 -1 1
35  * imembers 9 0 pismere-team STRING hope@ful.net 1 1 0 1 1 -1
36  *   list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid
37  *
38  * test parameters for creating and/or populating a group/list - done
39  * list 0 10 pismere-team 1 1 0 1 0 -1 USER 95260 description
40  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
41  * 
42  * test parameters for deleting a group/list - done
43  * list 10 0 pismere-team 1 1 0 1 0 -1 USER 95260 description
44  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
45  *
46  * test parameters for renaming a group/list - done
47  *  list 10 10 adtestlist 1 1 0 1 0 -1 USER 95260 description pismere-team 1 1 0 1 1 -1 USER 95260 description
48  *  list 10 10 pismere-team 1 1 0 1 1 -1 USER 95260 description adtestlist1 1 1 0 1 0 -1 USER 95260 description
49  *   name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description
50 */
51 #include <mit-copyright.h>
52 #ifdef _WIN32
53 #include <windows.h>
54 #include <stdlib.h>
55 #include <malloc.h>
56 #include <lmaccess.h>
57 #endif
58
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 (callback_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               if (callback_rc != LDAP_NO_SUCH_OBJECT)
655                 {
656                   critical_alert("AD incremental",
657                                  "Could not update user %s info : %s",
658                                  before[U_NAME], 
659                                  error_message(rc));
660                   goto cleanup;
661                 }
662             }
663         }
664       else
665         {
666           com_err(whoami, 0, "Changing user %s to %s", before[U_NAME],
667                   after[U_NAME]);
668           av[0] = after[U_NAME];
669           call_args[0] = (char *)ldap_handle;
670           call_args[1] = dn_path;
671           call_args[2] = (char *)MEMBER_ACTIVATE;
672           call_args[3] = before[U_NAME];
673           sid_base = NULL;
674           sid_ptr = &sid_base;
675           callback_rc = 0;
676           if (rc = mr_query("get_user_account_by_login", 1, av, user_rename,
677                             call_args))
678             {
679               if (callback_rc != LDAP_NO_SUCH_OBJECT)
680                 {
681                   critical_alert("AD incremental",
682                                  "Could not change user %s to %s : %s",
683                                  before[U_NAME], 
684                                  after[U_NAME], error_message(rc));
685                   goto cleanup;
686                 }
687             }
688         }
689       if (callback_rc != LDAP_NO_SUCH_OBJECT)
690         goto cleanup;
691       bstate = 0;
692     }
693   if (bstate == 1)
694     {
695       com_err(whoami, 0, "Deactivate user %s in the AD", before[U_NAME]);
696       av[0] = before[U_NAME];
697       call_args[0] = (char *)ldap_handle;
698       call_args[1] = dn_path;
699       call_args[2] = (char *)MEMBER_DEACTIVATE;
700       if (rc = mr_query("get_user_account_by_login", 1, av, user_change_status,
701                         call_args))
702         {
703           critical_alert("AD incremental",
704                          "Couldn't deactivate user %s in the AD : %s",
705                          before[U_NAME], error_message(rc));
706         }
707       goto cleanup;
708     }
709   if (astate == 1)
710     {
711       com_err(whoami, 0, "%s user %s", "Creating/Reactivating",
712               after[U_NAME]);
713
714       av[0] = after[U_NAME];
715       call_args[0] = (char *)ldap_handle;
716       call_args[1] = dn_path;
717       call_args[2] = (char *)MEMBER_ACTIVATE;
718       call_args[3] = NULL;
719       sid_base = NULL;
720       sid_ptr = &sid_base;
721       if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
722                         call_args))
723         {
724           critical_alert("AD incremental", "Couldn't create/activate user %s : %s",
725                          after[U_NAME], error_message(rc));
726           goto cleanup;
727         }
728       if (sid_base != NULL)
729         {
730           sid_update(ldap_handle, dn_path);
731           linklist_free(sid_base);
732         }
733     }
734 cleanup:
735   moira_disconnect();
736 }
737
738 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, 
739                         char *oldValue, char *newValue,
740                         char ***modvalues, int type)
741 {
742   LK_ENTRY    *linklist_ptr;
743   int         i;
744   char        *cPtr;
745
746   if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *)))
747       == NULL)
748     {
749       return(1);
750     }
751   for (i = 0; i < (modvalue_count + 1); i++)
752     (*modvalues)[i] = NULL;
753   if (modvalue_count != 0)
754     {
755       linklist_ptr = linklist_base;
756       for (i = 0; i < modvalue_count; i++)
757         {
758           if ((oldValue != NULL) && (newValue != NULL))
759             {
760               if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
761                  != (char *)NULL)
762                 {
763                   if (type == REPLACE)
764                     {
765                       if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
766                           == NULL)
767                         return(1);
768                       memset((*modvalues)[i], '\0', strlen(newValue) + 1);
769                       strcpy((*modvalues)[i], newValue);
770                     }
771                   else
772                     {
773                       if (((*modvalues)[i] = calloc(1, 
774                                         (int)(cPtr - linklist_ptr->value) + 
775                                         (linklist_ptr->length - strlen(oldValue)) + 
776                                         strlen(newValue) + 1)) == NULL)
777                         return(1);
778                       memset((*modvalues)[i], '\0', 
779                              (int)(cPtr - linklist_ptr->value) + 
780                              (linklist_ptr->length - strlen(oldValue)) + 
781                              strlen(newValue) + 1);
782                       memcpy((*modvalues)[i], linklist_ptr->value, 
783                              (int)(cPtr - linklist_ptr->value));
784                       strcat((*modvalues)[i], newValue);
785                       strcat((*modvalues)[i], 
786      &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]);
787                     }
788                 }
789               else
790                 {
791                   (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
792                   memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
793                   memcpy((*modvalues)[i], linklist_ptr->value,
794                          linklist_ptr->length);
795                 }
796             }
797         else
798             {
799               (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
800               memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
801               memcpy((*modvalues)[i], linklist_ptr->value,
802                      linklist_ptr->length);
803             }
804           linklist_ptr = linklist_ptr->next;
805         }
806       (*modvalues)[i] = NULL;
807     }
808   return(0);
809 }
810
811
812 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, 
813                    char **attr_array, LK_ENTRY **linklist_base,
814                    int *linklist_count)
815 {
816   ULONG       rc;
817   LDAPMessage *ldap_entry;
818
819   rc = 0;
820   ldap_entry = NULL;
821   (*linklist_base) = NULL;
822   (*linklist_count) = 0;
823   if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE, 
824                           search_exp, attr_array, 0, &ldap_entry))
825       != LDAP_SUCCESS)
826     return(0);
827   rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count);
828
829   ldap_msgfree(ldap_entry);
830   return(rc);
831 }
832
833
834 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
835                      LK_ENTRY **linklist_base, int *linklist_count)
836 {
837   char        distinguished_name[1024];
838   LK_ENTRY    *linklist_ptr;
839   int         rc;
840
841   if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
842     return(0);
843
844   memset(distinguished_name, '\0', sizeof(distinguished_name));
845   get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
846
847   if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
848                                 linklist_base)) != 0)
849     return(rc);
850
851   while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
852     {
853       memset(distinguished_name, '\0', sizeof(distinguished_name));
854       get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
855
856       if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
857                                     linklist_base)) != 0)
858         return(rc);
859     }
860
861   linklist_ptr = (*linklist_base);
862   (*linklist_count) = 0;
863   while (linklist_ptr != NULL)
864     {
865       ++(*linklist_count);
866       linklist_ptr = linklist_ptr->next;
867     }
868   return(0);
869 }
870
871 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
872                         char *distinguished_name, LK_ENTRY **linklist_current)
873 {
874   char        *Attribute;
875   BerElement  *ptr;
876
877   ptr = NULL;
878   if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL)
879     {
880       retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
881                       linklist_current);
882       ldap_memfree(Attribute);
883       while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry, 
884                                               ptr)) != NULL)
885         {
886           retrieve_values(ldap_handle, ldap_entry, Attribute,
887                           distinguished_name, linklist_current);
888           ldap_memfree(Attribute);
889         }
890     }
891   ldap_ber_free(ptr, 0);
892   return(0);
893 }
894
895 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
896                     char *Attribute, char *distinguished_name,
897                     LK_ENTRY **linklist_current)
898 {
899   char        **str_value;
900   char        temp[256];
901   void        **Ptr;
902   int         use_bervalue;
903   LK_ENTRY    *linklist_previous;
904   LDAP_BERVAL **ber_value;
905   DWORD       ber_length;
906 #ifdef LDAP_DEBUG
907   SID         *sid;
908   GUID        *guid;
909   int         i;
910   int         intValue;
911   DWORD       *subauth;
912   SID_IDENTIFIER_AUTHORITY    *sid_auth;
913   unsigned char   *subauth_count;
914 #endif /*LDAP_BEGUG*/
915
916   use_bervalue = 0;
917   memset(temp, '\0', sizeof(temp));
918   if ((!strcmp(Attribute, "objectSid")) ||
919       (!strcmp(Attribute, "objectGUID")))
920     use_bervalue = 1;
921
922   if (use_bervalue)
923     {
924       ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
925       Ptr = (void **)ber_value;
926       str_value = NULL;
927       }
928   else
929     {
930       str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
931       Ptr = (void **)str_value;
932       ber_value = NULL;
933     }
934   if (Ptr != NULL)
935     {
936       for (; *Ptr; Ptr++) 
937         {
938           if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
939             return(1);
940           memset(linklist_previous, '\0', sizeof(LK_ENTRY));
941           linklist_previous->next = (*linklist_current);
942           (*linklist_current) = linklist_previous;
943
944           if (((*linklist_current)->attribute = calloc(1, 
945                                                strlen(Attribute) + 1)) == NULL)
946             return(1);
947           memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
948           strcpy((*linklist_current)->attribute, Attribute);
949           if (use_bervalue)
950             {
951               ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
952               if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
953                 return(1);
954               memset((*linklist_current)->value, '\0', ber_length);
955               memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val, 
956                                                   ber_length);
957               (*linklist_current)->length = ber_length;
958             }
959           else
960             {
961               if (((*linklist_current)->value = calloc(1, 
962                                                   strlen(*Ptr) + 1)) == NULL)
963                 return(1);
964               memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
965               (*linklist_current)->length = strlen(*Ptr);
966               strcpy((*linklist_current)->value, *Ptr);
967             }
968           (*linklist_current)->ber_value = use_bervalue;
969           if (((*linklist_current)->dn = calloc(1, 
970                                       strlen(distinguished_name) + 1)) == NULL)
971             return(1);
972           memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1);
973           strcpy((*linklist_current)->dn, distinguished_name);
974
975 #ifdef LDAP_DEBUG
976           if (!strcmp(Attribute, "objectGUID"))
977             {
978               guid = (GUID *)((*linklist_current)->value);
979               sprintf(temp, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", 
980                       guid->Data1, guid->Data2, guid->Data3, 
981                       guid->Data4[0], guid->Data4[1], guid->Data4[2], 
982                       guid->Data4[3], guid->Data4[4], guid->Data4[5], 
983                       guid->Data4[6], guid->Data4[7]);
984               print_to_screen("     %20s : {%s}\n", Attribute, temp);
985             }
986           else if (!strcmp(Attribute, "objectSid"))
987             {
988               sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
989 #ifdef _WIN32
990               print_to_screen("        Revision = %d\n", sid->Revision);
991               print_to_screen("        SID Identifier Authority:\n");
992               sid_auth = &sid->IdentifierAuthority;
993               if (sid_auth->Value[0])
994                 print_to_screen("            SECURITY_NULL_SID_AUTHORITY\n");
995               else if (sid_auth->Value[1])
996                 print_to_screen("            SECURITY_WORLD_SID_AUTHORITY\n");
997               else if (sid_auth->Value[2])
998                 print_to_screen("            SECURITY_LOCAL_SID_AUTHORITY\n");
999               else if (sid_auth->Value[3])
1000                 print_to_screen("            SECURITY_CREATOR_SID_AUTHORITY\n");
1001               else if (sid_auth->Value[5])
1002                 print_to_screen("            SECURITY_NT_AUTHORITY\n");
1003               else
1004                 print_to_screen("            UNKNOWN SID AUTHORITY\n");
1005               subauth_count = GetSidSubAuthorityCount(sid);
1006               print_to_screen("        SidSubAuthorityCount = %d\n", 
1007                               *subauth_count);
1008               print_to_screen("        SidSubAuthority:\n");
1009               for (i = 0; i < *subauth_count; i++)
1010                 {
1011                   if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
1012                     print_to_screen("            %u\n", *subauth);
1013                 }
1014 #endif
1015             }
1016           else if ((!memcmp(Attribute, "userAccountControl", 
1017                             strlen("userAccountControl"))) ||
1018                    (!memcmp(Attribute, "sAMAccountType", 
1019                             strlen("sAmAccountType"))))
1020             {
1021               intValue = atoi(*Ptr);
1022               print_to_screen("     %20s : %ld\n",Attribute, intValue);
1023               if (!memcmp(Attribute, "userAccountControl", 
1024                           strlen("userAccountControl")))
1025                 {
1026                   if (intValue & UF_ACCOUNTDISABLE)
1027                     print_to_screen("     %20s :    %s\n", 
1028                                     "", "Account disabled");
1029                   else
1030                     print_to_screen("     %20s :    %s\n", 
1031                                     "", "Account active");
1032                   if (intValue & UF_HOMEDIR_REQUIRED)
1033                     print_to_screen("     %20s :    %s\n", 
1034                                     "", "Home directory required");
1035                   if (intValue & UF_LOCKOUT)
1036                     print_to_screen("     %20s :    %s\n", 
1037                                     "", "Account locked out");
1038                   if (intValue & UF_PASSWD_NOTREQD)
1039                     print_to_screen("     %20s :    %s\n", 
1040                                     "", "No password required");
1041                   if (intValue & UF_PASSWD_CANT_CHANGE)
1042                     print_to_screen("     %20s :    %s\n",
1043                                     "", "Cannot change password");
1044                   if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
1045                     print_to_screen("     %20s :    %s\n", 
1046                                     "", "Temp duplicate account");
1047                   if (intValue & UF_NORMAL_ACCOUNT)
1048                     print_to_screen("     %20s :    %s\n", 
1049                                     "", "Normal account");
1050                   if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
1051                     print_to_screen("     %20s :    %s\n", 
1052                                     "", "Interdomain trust account");
1053                   if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
1054                     print_to_screen("     %20s :    %s\n", 
1055                                     "", "Workstation trust account");
1056                   if (intValue & UF_SERVER_TRUST_ACCOUNT)
1057                     print_to_screen("     %20s :    %s\n", 
1058                                     "", "Server trust account");
1059                 }
1060             }
1061           else
1062             {
1063               print_to_screen("     %20s : %s\n",Attribute, *Ptr);
1064             }
1065 #endif /*LDAP_DEBUG*/
1066         }
1067       if (str_value != NULL)
1068         ldap_value_free(str_value);
1069       if (ber_value != NULL)
1070         ldap_value_free_len(ber_value);
1071     }
1072   (*linklist_current) = linklist_previous;
1073   return(0);
1074 }
1075
1076 int moira_connect(void)
1077 {
1078   long    rc;
1079   char    HostName[64];
1080
1081   if (!mr_connections++)
1082     {
1083 #ifdef _WIN32
1084       memset(HostName, '\0', sizeof(HostName));
1085       strcpy(HostName, "ttsp");
1086       rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
1087 /*det
1088       rc = mr_connect(HostName);
1089 */
1090 #else
1091       struct utsname uts;
1092       uname(&uts);
1093       rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
1094 /*
1095       rc = mr_connect(uts.nodename);
1096 */
1097 #endif /*WIN32*/
1098 /*det
1099       if (!rc)
1100         rc = mr_auth("winad.incr");
1101 */
1102       return rc;
1103     }
1104   return 0;
1105 }
1106
1107 int moira_disconnect(void)
1108 {
1109
1110   if (!--mr_connections)
1111     {
1112       mr_disconnect();
1113     }
1114   return 0;
1115 }
1116
1117 int convert_domain_to_dn(char *domain, char **dnp)
1118 {
1119   char    *fp;
1120   char    *dp;
1121   char    dn[1024];
1122   int     dnlen = 1;
1123     
1124   memset(dn, 0, sizeof(dn));
1125   strcpy(dn, "dc=");
1126   dp = dn+3;
1127   for (fp = domain; *fp; fp++)
1128     {
1129       if (*fp == '.') 
1130         {
1131           strcpy(dp, ",dc=");
1132           dp += 4;
1133         }
1134       else
1135         *dp++ = *fp;
1136     }
1137
1138   *dnp = (char *)strdup(dn);
1139   return 0;
1140 }
1141
1142 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, 
1143                             char *distinguished_name)
1144 {
1145   char    *CName;
1146
1147   CName = ldap_get_dn(ldap_handle, ldap_entry);
1148   if (CName == NULL)
1149     return;
1150   strcpy(distinguished_name, CName);
1151   ldap_memfree(CName);
1152 }
1153
1154 int linklist_create_entry(char *attribute, char *value, 
1155                           LK_ENTRY **linklist_entry)
1156 {
1157   (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
1158   if (!(*linklist_entry))
1159     {
1160       return(1);
1161     }
1162   memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
1163   (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
1164   memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
1165   strcpy((*linklist_entry)->attribute, attribute);
1166   (*linklist_entry)->value = calloc(1, strlen(value) + 1);
1167   memset((*linklist_entry)->value, '\0', strlen(value) + 1);
1168   strcpy((*linklist_entry)->value, value);
1169   (*linklist_entry)->length = strlen(value);
1170   (*linklist_entry)->next = NULL;
1171   return(0);
1172 }
1173
1174 void print_to_screen(const char *fmt, ...)
1175 {
1176   va_list pvar;
1177
1178   va_start(pvar, fmt);
1179   vfprintf(stderr, fmt, pvar);
1180   fflush(stderr);
1181   va_end(pvar);
1182 }
1183
1184 int get_group_membership(char *group_membership, char *group_ou, 
1185                          int *security_flag, char **av)
1186 {
1187   int  maillist_flag;
1188   int  group_flag;
1189
1190   maillist_flag = atoi(av[L_MAILLIST]);
1191   group_flag = atoi(av[L_GROUP]);
1192   if (security_flag != NULL)
1193     (*security_flag) = 0;
1194
1195   if ((maillist_flag) && (group_flag))
1196     {
1197       if (group_membership != NULL)
1198         group_membership[0] = 'B';
1199       if (security_flag != NULL)
1200         (*security_flag) = 1;
1201       if (group_ou != NULL)
1202         strcpy(group_ou, group_ou_both);
1203     }
1204   else if ((!maillist_flag) && (group_flag))
1205     {
1206       if (group_membership != NULL)
1207         group_membership[0] = 'S';
1208       if (security_flag != NULL)
1209         (*security_flag) = 1;
1210       if (group_ou != NULL)
1211         strcpy(group_ou, group_ou_security);
1212     }
1213   else if ((maillist_flag) && (!group_flag))
1214     {
1215       if (group_membership != NULL)
1216         group_membership[0] = 'D';
1217       if (group_ou != NULL)
1218         strcpy(group_ou, group_ou_distribution);
1219     }
1220   else
1221     {
1222       if (group_membership != NULL)
1223         group_membership[0] = 'N';
1224       if (group_ou != NULL)
1225         strcpy(group_ou, group_ou_neither);
1226     }
1227   return(0);
1228 }
1229
1230 int get_group_info(int ac, char**av, void *ptr)
1231 {
1232   char **call_args;
1233
1234   call_args = ptr;
1235
1236   if (!atoi(av[L_ACTIVE]))
1237     return(0);
1238   if (ptr == NULL)
1239     {
1240       get_group_membership(GroupType, NULL, NULL, av);
1241     }
1242   else
1243     {
1244     call_args[5] = av[L_NAME];
1245     get_group_membership(call_args[4], call_args[3], NULL, av);
1246     }
1247
1248   return(0);
1249 }
1250
1251 int group_rename(int ac, char **av, void *ptr)
1252 {
1253   LDAPMod   *mods[20];
1254   char      old_dn[512];
1255   char      new_dn[512];
1256   char      new_dn_path[512];
1257   char      group_ou[256];
1258   char      sam_name[256];
1259   char      group_membership[2];
1260   char      filter_exp[4096];
1261   char      *attr_array[3];
1262   char      *name_v[] = {NULL, NULL};
1263   char      *samAccountName_v[] = {NULL, NULL};
1264   int       n;
1265   int       i;
1266   int       rc;
1267   int       security_flag;
1268   LK_ENTRY  *group_base;
1269   int       group_count;
1270   char      **call_args;
1271   char      *maillist_flag = NULL;
1272   char      *group_flag = NULL;
1273
1274   call_args = ptr;
1275
1276   if (!check_string(call_args[2]))
1277     {
1278       callback_rc = LDAP_NO_SUCH_OBJECT;
1279       return(0);
1280     }
1281   if (!check_string(av[L_NAME]))
1282     {
1283       critical_alert("AD incremental - list rename",
1284                       "invalid LDAP list name %s",
1285                       av[L_NAME]);
1286       return(0);
1287     }
1288
1289   memset(group_ou, 0, sizeof(group_ou));
1290   memset(group_membership, 0, sizeof(group_membership));
1291   security_flag = 0;
1292
1293   maillist_flag = av[L_MAILLIST];
1294   group_flag = av[L_GROUP];
1295   av[L_MAILLIST] = call_args[3];
1296   av[L_GROUP] = call_args[4];
1297   get_group_membership(group_membership, NULL, NULL, av);
1298   av[L_MAILLIST] = maillist_flag;
1299   av[L_GROUP] = group_flag;
1300
1301   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", call_args[2], group_membership[0]);
1302   attr_array[0] = "distinguishedName";
1303   attr_array[1] = NULL;
1304   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
1305                            &group_base, &group_count)) != 0)
1306     {
1307       critical_alert("AD incremental - list rename",
1308                       "LDAP server unable to get list %s dn : %s",
1309                       call_args[2], ldap_err2string(rc));
1310       return(0);
1311     }
1312   if (group_count != 1)
1313     {
1314       critical_alert("AD incremental - list rename",
1315                       "LDAP server unable to find list %s in AD.",
1316                       call_args[2]);
1317       callback_rc = LDAP_NO_SUCH_OBJECT;
1318       return(0);
1319     }
1320   strcpy(old_dn, group_base->value);
1321   linklist_free(group_base);
1322   group_base = NULL;
1323   group_count = 0;
1324
1325   get_group_membership(group_membership, group_ou, &security_flag, av);
1326   sprintf(sam_name, "%s_zZx%c", av[L_NAME], group_membership[0]);
1327   sprintf(new_dn_path, "%s,%s", group_ou, call_args[1]);
1328   sprintf(new_dn, "cn=%s", av[L_NAME]);
1329   if ((rc = ldap_rename_s((LDAP *)call_args[0], old_dn, new_dn, new_dn_path,
1330                           TRUE, NULL, NULL)) != LDAP_SUCCESS)
1331     {
1332       critical_alert("AD incremental - list rename",
1333                      "Couldn't rename list from %s to %s : %s",
1334                      call_args[2], av[L_NAME], ldap_err2string(rc));
1335       return(0);
1336     }
1337
1338   name_v[0] = av[L_NAME];
1339   samAccountName_v[0] = sam_name;
1340   n = 0;
1341   ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
1342   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
1343   mods[n] = NULL;
1344   sprintf(new_dn, "cn=%s,%s,%s", av[L_NAME], group_ou, call_args[1]);
1345   if ((rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods)) != LDAP_SUCCESS)
1346     {
1347        critical_alert("AD incremental - list rename", 
1348                       "After renaming, couldn't modify list data for %s : %s",
1349                        av[L_NAME], ldap_err2string(rc));
1350     }
1351   for (i = 0; i < n; i++)
1352     free(mods[i]);
1353   return(0);
1354 }
1355
1356 int group_create(int ac, char **av, void *ptr)
1357 {
1358   LDAPMod *mods[20];
1359   char new_dn[256];
1360   char group_ou[256];
1361   char new_group_name[256];
1362   char sam_group_name[256];
1363   char cn_group_name[256];
1364   char *cn_v[] = {NULL, NULL};
1365   char *objectClass_v[] = {"top", "group", NULL};
1366   char info[256];
1367   char *samAccountName_v[] = {NULL, NULL};
1368   char *managedBy_v[] = {NULL, NULL};
1369   char *altSecurityIdentities_v[] = {NULL, NULL};
1370   char *name_v[] = {NULL, NULL};
1371   char *desc_v[] = {NULL, NULL};
1372   char *info_v[] = {NULL, NULL};
1373   char *groupTypeControl_v[] = {NULL, NULL};
1374   char groupTypeControlStr[80];
1375   char group_membership[1];
1376   int  i;
1377   int  security_flag;
1378   u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
1379   int  n;
1380   int  rc;
1381   int  sid_count;
1382   char filter_exp[256];
1383   char *attr_array[3];
1384   char **call_args;
1385
1386   call_args = ptr;
1387
1388   if (!atoi(av[L_ACTIVE]))
1389     return(0);
1390   if (!check_string(av[L_NAME]))
1391     {
1392       critical_alert("AD incremental - list create",
1393                       "invalid LDAP list name %s",
1394                       av[L_NAME]);
1395       return(0);
1396     }
1397   memset(group_ou, 0, sizeof(group_ou));
1398   memset(group_membership, 0, sizeof(group_membership));
1399   security_flag = 0;
1400   get_group_membership(group_membership, group_ou, &security_flag, av);
1401   call_args[3] = strdup(group_ou);
1402   call_args[4] = strdup(group_membership);
1403   call_args[5] = strdup(av[L_NAME]);
1404
1405   if (security_flag)
1406     groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
1407   sprintf(groupTypeControlStr, "%ld", groupTypeControl);
1408   groupTypeControl_v[0] = groupTypeControlStr;
1409
1410   strcpy(new_group_name, av[L_NAME]);
1411   strcpy(sam_group_name, av[L_NAME]);
1412   strcpy(cn_group_name, av[L_NAME]);
1413   sprintf(&sam_group_name[strlen(sam_group_name)], 
1414           "_zZx%c", group_membership[0]);
1415
1416   samAccountName_v[0] = sam_group_name;
1417   name_v[0] = new_group_name;
1418   cn_v[0] = new_group_name;
1419
1420   sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
1421   n = 0;
1422   ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
1423   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
1424   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
1425   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
1426   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
1427   if (strlen(av[L_DESC]) != 0)
1428     {
1429       desc_v[0] = av[L_DESC];
1430       ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
1431     }
1432   ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
1433   if (strlen(av[L_ACE_NAME]) != 0)
1434     {
1435       sprintf(info, "The Administrator of this list is the LIST: %s", av[L_ACE_NAME]);
1436       info_v[0] = info;
1437       ADD_ATTR("info", info_v, LDAP_MOD_ADD);
1438     }
1439   mods[n] = NULL;
1440
1441   rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
1442
1443   for (i = 0; i < n; i++)
1444     free(mods[i]);
1445   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
1446     {
1447       critical_alert("AD incremental - list rename",
1448                       "Unable to create list %s in AD : %s",
1449                       av[L_NAME], ldap_err2string(rc));
1450       return(0);
1451     }
1452   sprintf(filter_exp, "(sAMAccountName=%s)", sam_group_name);
1453   attr_array[0] = "objectSid";
1454   attr_array[1] = NULL;
1455   sid_count = 0;
1456   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
1457                                sid_ptr, &sid_count)) == LDAP_SUCCESS)
1458     {
1459       if (sid_count == 1)
1460         {
1461           (*sid_ptr)->member = strdup(av[L_NAME]);
1462           (*sid_ptr)->type = (char *)GROUPS;
1463           sid_ptr = &(*sid_ptr)->next;
1464         }
1465     }
1466   return(0);
1467 }
1468
1469 int group_delete(int ac, char **av, void *ptr)
1470 {
1471   LK_ENTRY  *group_base;
1472   char      **call_args;
1473   char      *attr_array[3];
1474   char      filter_exp[1024];
1475   char      group_membership[1];
1476   char      group_ou[256];
1477   char      sam_group_name[256];
1478   int       security_flag;
1479   int       group_count;
1480   int       rc;
1481
1482   call_args = ptr;
1483
1484   if (!check_string(av[L_NAME]))
1485     {
1486       critical_alert("AD incremental - list delete",
1487                       "invalid LDAP list name %s",
1488                       av[L_NAME]);
1489       return(0);
1490     }
1491   memset(group_ou, 0, sizeof(group_ou));
1492   memset(group_membership, 0, sizeof(group_membership));
1493   security_flag = 0;
1494   get_group_membership(group_membership, group_ou, &security_flag, av);
1495
1496   group_count = 0;
1497   group_base = NULL;
1498   attr_array[0] = "distinguishedName";
1499   attr_array[1] = NULL;
1500   strcpy(sam_group_name, av[L_NAME]);
1501   sprintf(&sam_group_name[strlen(sam_group_name)], "_zZx%c", 
1502           group_membership[0]);
1503   sprintf(filter_exp, "(sAMAccountName=%s)", sam_group_name);
1504   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, 
1505                            attr_array, &group_base, &group_count)) != 0)
1506     goto cleanup;
1507   if (group_count == 1)
1508     {
1509       if ((rc = ldap_delete_s((LDAP *)call_args[0], group_base->value)) != LDAP_SUCCESS)
1510         {
1511           critical_alert("AD incremental - list delete",
1512                          "Couldn't delete group %s : %s",
1513                          av[L_NAME], ldap_err2string(rc));
1514         }
1515     }
1516   else
1517     {
1518       critical_alert("AD incremental - list delete",
1519                       "Unable to find list %s in AD.",
1520                       av[L_NAME]);
1521     }
1522 cleanup:
1523   linklist_free(group_base);
1524   return(0);
1525 }
1526
1527 int group_ad_delete(LDAP *ldap_handle, char *dn_path, char *group_name)
1528 {
1529   LK_ENTRY  *group_base;
1530   char      *attr_array[3];
1531   char      filter_exp[1024];
1532   char      sam_group_name[256];
1533   char      temp[512];
1534   int       group_count;
1535   int       rc;
1536
1537   if (!check_string(group_name))
1538     {
1539       critical_alert("AD incremental - list AD delete",
1540                       "invalid LDAP list name %s",
1541                       group_name);
1542       return(0);
1543     }
1544   rc = 1;
1545   group_count = 0;
1546   group_base = NULL;
1547   attr_array[0] = "distinguishedName";
1548   attr_array[1] = NULL;
1549   strcpy(sam_group_name, group_name);
1550   sprintf(temp, "%s,%s", group_ou_root, dn_path);
1551   sprintf(filter_exp, "(sAMAccountName=%s_zZx*)", sam_group_name);
1552   if (linklist_build(ldap_handle, temp, filter_exp, attr_array, 
1553                            &group_base, &group_count) != 0)
1554     goto cleanup;
1555   if (group_count == 1)
1556     {
1557       if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
1558         {
1559           critical_alert("AD incremental - list AD delete",
1560                           "Unable to delete list %s from AD : %s",
1561                           group_name, ldap_err2string(rc));
1562           return(0);
1563         }
1564     }
1565   else
1566     {
1567       critical_alert("AD incremental - list AD delete",
1568                      "Unable to find list %s in AD.",
1569                       group_name);
1570     }
1571 cleanup:
1572   linklist_free(group_base);
1573   return(0);
1574 }
1575
1576 int group_list_build(int ac, char **av, void *ptr)
1577 {
1578   LK_ENTRY    *linklist;
1579   char        **call_args;
1580
1581   call_args = ptr;
1582
1583   if (!atoi(av[L_ACTIVE]))
1584     return(0);
1585   if (!check_string(av[L_NAME]))
1586     return(0);
1587   linklist = calloc(1, sizeof(LK_ENTRY));
1588   if (!linklist)
1589     {
1590       critical_alert("AD incremental", "Out of memory");
1591       exit(1);
1592     }
1593   memset(linklist, '\0', sizeof(LK_ENTRY));
1594   linklist->op = 1;
1595   linklist->dn = NULL;
1596   linklist->list = calloc(1, strlen(av[L_NAME]) + 1);
1597   strcpy(linklist->list, av[L_NAME]);
1598   linklist->type = calloc(1, strlen("USER") + 1);
1599   strcpy(linklist->type, "USER");
1600   linklist->member = calloc(1, strlen(call_args[0]) + 1);
1601   strcpy(linklist->member, call_args[0]);
1602   linklist->next = member_base;
1603   member_base = linklist;
1604   return(0);
1605 }
1606
1607 int member_list_build(int ac, char **av, void *ptr)
1608 {
1609   LK_ENTRY  *linklist;
1610   char      temp[1024];
1611   char      **call_args;
1612
1613   call_args = ptr;
1614
1615   strcpy(temp, av[ACE_NAME]);
1616   if (!check_string(temp))
1617     return(0);
1618   if (!strcmp(av[ACE_TYPE], "STRING"))
1619     {
1620     if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
1621       return(0);
1622     }
1623   else if (!strcmp(av[ACE_TYPE], "LIST"))
1624     {
1625       strcpy(temp, av[ACE_NAME]);
1626     }
1627   else if (strcmp(av[ACE_TYPE], "USER"))
1628     {
1629     if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou))
1630       return(0);
1631     }
1632   linklist = member_base;
1633   while (linklist)
1634     {
1635     if (!strcasecmp(temp, linklist->member))
1636       return(0);
1637     linklist = linklist->next;
1638     }
1639   linklist = calloc(1, sizeof(LK_ENTRY));
1640   linklist->op = 1;
1641   linklist->dn = NULL;
1642   linklist->list = calloc(1, strlen(call_args[2]) + 1);
1643   strcpy(linklist->list, call_args[2]);
1644   linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
1645   strcpy(linklist->type, av[ACE_TYPE]);
1646   linklist->member = calloc(1, strlen(temp) + 1);
1647   strcpy(linklist->member, temp);
1648   linklist->next = member_base;
1649   member_base = linklist;
1650   return(0);
1651 }
1652
1653 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, 
1654                   char *group_ou, char *group_membership, char *group_gid)
1655 {
1656   char        distinguished_name[1024];
1657   char        **modvalues;
1658   char        filter_exp[4096];
1659   char        *attr_array[3];
1660   char        temp[256];
1661   int         group_count;
1662   int         i;
1663   int         n;
1664   LDAPMod     *mods[20];
1665   LK_ENTRY    *group_base;
1666   ULONG       rc;
1667
1668   if (!check_string(group_name))
1669     return(0);
1670   strcpy(temp, group_name);
1671   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_gid, group_membership[0]);
1672   attr_array[0] = "distinguishedName";
1673   attr_array[1] = NULL;
1674   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1675                            &group_base, &group_count)) != 0)
1676     {
1677       critical_alert("AD incremental - member remove",
1678                       "LDAP server unable to get list %s info : %s",
1679                       group_name, ldap_err2string(rc));
1680       goto cleanup;
1681     }
1682   if (group_count != 1)
1683     {
1684       critical_alert("AD incremental - member remove",
1685                       "LDAP server unable to find list %s in AD.",
1686                       group_name);
1687       goto cleanup;
1688     }
1689   strcpy(distinguished_name, group_base->value);
1690   linklist_free(group_base);
1691   group_base = NULL;
1692   group_count = 0;
1693   attr_array[0] = "member";
1694   attr_array[1] = NULL;
1695   if ((rc = linklist_build(ldap_handle, distinguished_name, filter_exp, attr_array, 
1696                            &group_base, &group_count)) != 0)
1697     {
1698       critical_alert("AD incremental - member remove",
1699                       "LDAP server unable to get list %s info : %s",
1700                       group_name, ldap_err2string(rc));
1701       goto cleanup;
1702     }
1703
1704   modvalues = NULL;
1705   if (group_count != 0)
1706     {
1707       if ((rc = construct_newvalues(group_base, group_count, NULL, NULL,
1708                                     &modvalues, REPLACE)) == 1)
1709           goto cleanup;
1710       n = 0;
1711       ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
1712       mods[n] = NULL;
1713       rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1714       for (i = 0; i < n; i++)
1715         free(mods[i]);
1716       if (rc != LDAP_SUCCESS)
1717         {
1718           critical_alert("AD incremental - member remove",
1719                           "LDAP server unable to modify list %s members : %s",
1720                           group_name, ldap_err2string(rc));
1721           goto cleanup;
1722         }
1723       linklist_free(group_base);
1724       group_count = 0;
1725       group_base = NULL;
1726     }
1727
1728 cleanup:
1729   free_values(modvalues);
1730   linklist_free(group_base);
1731   return(rc);
1732 }
1733
1734 #define USER_COUNT  5
1735
1736 int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name, 
1737                         char *group_ou, char *group_membership, char *group_gid)
1738 {
1739   char        distinguished_name[1024];
1740   char        **modvalues;
1741   char        filter_exp[4096];
1742   char        *attr_array[3];
1743   char        temp[256];
1744   char        group_member[256];
1745   char        *args[2];
1746   int         group_count;
1747   int         new_list_count;
1748   int         i;
1749   int         j;
1750   int         k;
1751   int         n;
1752   int         filter_count;
1753   LDAPMod     *mods[20];
1754   LK_ENTRY    *group_base;
1755   LK_ENTRY    *new_list;
1756   LK_ENTRY    *sPtr;
1757   LK_ENTRY    *pPtr;
1758   ULONG       rc;
1759
1760   rc = 0;
1761   group_base = NULL;
1762   group_count = 0;
1763   modvalues = NULL;
1764
1765   pPtr = member_base;
1766   while (pPtr)
1767     {
1768     ++group_count;
1769     pPtr = pPtr->next;
1770     }
1771   j = group_count/USER_COUNT;
1772   ++j;
1773
1774   if (!check_string(group_name))
1775     return(0);
1776   strcpy(temp, group_name);
1777   sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_gid, group_membership[0]);
1778   attr_array[0] = "distinguishedName";
1779   attr_array[1] = NULL;
1780   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1781                            &group_base, &group_count)) != 0)
1782     {
1783       critical_alert("AD incremental - member list process",
1784                       "LDAP server unable to get list %s info : %s",
1785                       group_name, ldap_err2string(rc));
1786       goto cleanup;
1787     }
1788   if (group_count != 1)
1789     {
1790       critical_alert("AD incremental - member list process",
1791                       "LDAP server unable to find list %s in AD.",
1792                       group_name);
1793       goto cleanup;
1794     }
1795   strcpy(distinguished_name, group_base->value);
1796   linklist_free(group_base);
1797   group_base = NULL;
1798   group_count = 0;
1799
1800   pPtr = member_base;
1801   for (i = 0; i < j; i++)
1802     {
1803       if (pPtr == NULL)
1804         break;
1805       memset(filter_exp, 0, sizeof(filter_exp));
1806       strcpy(filter_exp, "(|");
1807       filter_count = 0;
1808       for (k = 0; k < USER_COUNT; k++)
1809         {
1810           strcpy(group_member, pPtr->member);
1811           if (!check_string(group_member))
1812             {
1813               pPtr = pPtr->next;
1814               if (pPtr == NULL)
1815                 break;
1816               continue;
1817             }
1818           if (!strcmp(pPtr->type, "LIST"))
1819             {
1820               args[0] = pPtr->member;
1821               rc = mr_query("get_list_info", 1, args, get_group_info, NULL);
1822               sprintf(temp, "(sAMAccountName=%s_zZx%c)", group_member, GroupType[0]);
1823             }
1824           else if (!strcmp(pPtr->type, "USER"))
1825             {
1826               sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, user_ou, dn_path);
1827             }
1828           else if (!strcmp(pPtr->type, "STRING"))
1829             {
1830               sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, contact_ou, dn_path);
1831             }
1832           else
1833             {
1834               sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, kerberos_ou, dn_path);
1835             }
1836           strcat(filter_exp, temp);
1837           ++filter_count;
1838           pPtr = pPtr->next;
1839           if (pPtr == NULL)
1840             break;
1841         }
1842       if (filter_count == 0)
1843         continue;
1844       strcat(filter_exp, ")");
1845       attr_array[0] = "distinguishedName";
1846       attr_array[1] = NULL;
1847       new_list = NULL;
1848       new_list_count = 0;
1849       if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
1850                                &new_list, &new_list_count)) != 0)
1851         {
1852           critical_alert("AD incremental - member list process",
1853                          "LDAP server unable to get list %s members from AD : %s",
1854                          group_name, ldap_err2string(rc));
1855           goto cleanup;
1856         }
1857       group_count += new_list_count;
1858       if (group_base == NULL)
1859         group_base = new_list;
1860       else
1861         {
1862           sPtr = group_base;
1863           while (sPtr)
1864             {
1865               if (sPtr->next != NULL)
1866                 {
1867                   sPtr = sPtr->next;
1868                   continue;
1869                 }
1870               sPtr->next = new_list;
1871               break;
1872             }
1873         }
1874     }
1875
1876   modvalues = NULL;
1877   if (group_count != 0)
1878     {
1879       if ((rc = construct_newvalues(group_base, group_count, NULL, NULL,
1880                                     &modvalues, REPLACE)) == 1)
1881           goto cleanup;
1882       n = 0;
1883       ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
1884       mods[n] = NULL;
1885       if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) 
1886           != LDAP_SUCCESS)
1887         {
1888           mods[0]->mod_op = LDAP_MOD_REPLACE;
1889           rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1890         }
1891       if (rc == LDAP_ALREADY_EXISTS)
1892         rc = LDAP_SUCCESS;
1893       for (i = 0; i < n; i++)
1894         free(mods[i]);
1895       linklist_free(group_base);
1896       group_count = 0;
1897       group_base = NULL;
1898       if (rc != LDAP_SUCCESS)
1899         {
1900           critical_alert("AD incremental - member list process",
1901                          "LDAP server unable to modify list %s members in AD : %s",
1902                          group_name, ldap_err2string(rc));
1903           goto cleanup;
1904         }
1905     }
1906
1907 cleanup:
1908   free_values(modvalues);
1909   linklist_free(group_base);
1910   return(0);
1911 }
1912
1913 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
1914 {
1915   LDAPMod *mods[20];
1916   char new_dn[256];
1917   char cn_user_name[256];
1918   char contact_name[256];
1919   char *cn_v[] = {NULL, NULL};
1920   char *contact_v[] = {NULL, NULL};
1921   char *objectClass_v[] = {"top", "person", 
1922                            "organizationalPerson", 
1923                            "contact", NULL};
1924   char *name_v[] = {NULL, NULL};
1925   char *desc_v[] = {NULL, NULL};
1926   int  n;
1927   int  rc;
1928   int  i;
1929
1930   if (!check_string(user))
1931     {
1932       critical_alert("AD incremental - contact create",
1933                       "invalid LDAP name %s",
1934                       user);
1935       return(1);
1936     }
1937   strcpy(contact_name, user);
1938   sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
1939   cn_v[0] = cn_user_name;
1940   contact_v[0] = contact_name;
1941   name_v[0] = user;
1942   desc_v[0] = "Auto account created by Moira";
1943
1944   strcpy(new_dn, cn_user_name);
1945   n = 0;
1946   ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
1947   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
1948   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
1949   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
1950   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
1951   mods[n] = NULL;
1952
1953   rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
1954   for (i = 0; i < n; i++)
1955     free(mods[i]);
1956   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
1957     {
1958       critical_alert("AD incremental - contact create", 
1959                      "could not create contact %s : %s",
1960                      user, ldap_err2string(rc));
1961       return(1);
1962     }
1963   return(0);
1964 }
1965
1966 int user_update(int ac, char **av, void *ptr)
1967 {
1968   LDAPMod   *mods[20];
1969   LK_ENTRY  *group_base;
1970   int  group_count;
1971   char distinguished_name[256];
1972   char user_name[256];
1973   char *uid_v[] = {NULL, NULL};
1974   char *mitid_v[] = {NULL, NULL};
1975   int  n;
1976   int  rc;
1977   int  i;
1978   char **call_args;
1979   char filter_exp[256];
1980   char *attr_array[3];
1981
1982   call_args = ptr;
1983
1984   if (!check_string(av[U_NAME]))
1985     {
1986       critical_alert("AD incremental - user update",
1987                       "invalid LDAP user name %s",
1988                       av[U_NAME]);
1989       return(0);
1990     }
1991
1992   strcpy(user_name, av[U_NAME]);
1993   group_count = 0;
1994   group_base = NULL;
1995   sprintf(filter_exp, "(sAMAccountName=%s)", av[U_NAME]);
1996   attr_array[0] = "cn";
1997   attr_array[1] = NULL;
1998   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
1999                            &group_base, &group_count)) != 0)
2000     {
2001       critical_alert("AD incremental - user update",
2002                      "LDAP server couldn't process user %s : %s",
2003                       user_name, ldap_err2string(rc));
2004       goto cleanup;
2005     }
2006
2007   if (group_count != 1)
2008     {
2009       critical_alert("AD incremental - user update",
2010                      "LDAP server unable to find user %s in AD.",
2011                       user_name);
2012       callback_rc = LDAP_NO_SUCH_OBJECT;
2013       goto cleanup;
2014     }
2015   strcpy(distinguished_name, group_base->dn);
2016
2017   n = 0;
2018   if (strlen(av[U_UID]) != 0)
2019     {
2020       uid_v[0] = av[U_UID];
2021       ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
2022       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2023     }
2024   if (strlen(av[U_MITID]) != 0)
2025     {
2026       mitid_v[0] = av[U_MITID];
2027       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2028     }
2029   mods[n] = NULL;
2030   if (n != 0)
2031     {
2032       if ((rc = ldap_modify_s((LDAP *)call_args[0], distinguished_name, mods)) != LDAP_SUCCESS)
2033         {
2034            critical_alert("AD incremental - user update", 
2035                           "Couldn't modify user data for %s : %s",
2036                            user_name, ldap_err2string(rc));
2037         }
2038       for (i = 0; i < n; i++)
2039         free(mods[i]);
2040     }
2041
2042 cleanup:
2043   linklist_free(group_base);
2044   return(0);
2045 }
2046
2047 int user_rename(int ac, char **av, void *ptr)
2048 {
2049   LDAPMod *mods[20];
2050   char new_dn[256];
2051   char old_dn[256];
2052   char user_name[256];
2053   char upn[256];
2054   char temp[128];
2055   char *userPrincipalName_v[] = {NULL, NULL};
2056   char *altSecurityIdentities_v[] = {NULL, NULL};
2057   char *name_v[] = {NULL, NULL};
2058   char *samAccountName_v[] = {NULL, NULL};
2059   char *uid_v[] = {NULL, NULL};
2060   char *mitid_v[] = {NULL, NULL};
2061   int  n;
2062   int  rc;
2063   int  i;
2064   char **call_args;
2065
2066   call_args = ptr;
2067
2068   if ((atoi(av[U_STATE]) != US_REGISTERED) && (atoi(av[U_STATE]) != US_NO_PASSWD) && 
2069       (atoi(av[U_STATE]) != US_ENROLL_NOT_ALLOWED))
2070     return(0);
2071   if (!strncmp(av[U_NAME], "#", 1))
2072     return(0);
2073   if (!check_string(call_args[3]))
2074     {
2075     callback_rc = LDAP_NO_SUCH_OBJECT;
2076     return(0);
2077     }
2078   if (!check_string(av[U_NAME]))
2079     {
2080       critical_alert("AD incremental - user rename",
2081                       "invalid LDAP user name %s",
2082                       av[U_NAME]);
2083       return(0);
2084     }
2085
2086   strcpy(user_name, av[U_NAME]);
2087   sprintf(old_dn, "cn=%s,%s,%s", call_args[3], user_ou, call_args[1]);
2088   sprintf(new_dn, "cn=%s", user_name);
2089
2090   if ((rc = ldap_rename_s((LDAP *)call_args[0], old_dn, new_dn, NULL, TRUE, 
2091                            NULL, NULL)) != LDAP_SUCCESS)
2092     {
2093       if (rc == LDAP_NO_SUCH_OBJECT)
2094         {
2095           callback_rc = LDAP_NO_SUCH_OBJECT;
2096           return(0);
2097         }
2098       critical_alert("AD incremental - user rename", 
2099                      "Couldn't rename user from %s to %s : %s",
2100                       call_args[3], user_name, ldap_err2string(rc));
2101       return(0);
2102     }
2103
2104   name_v[0] = user_name;
2105   sprintf(upn, "%s@%s", user_name, ldap_domain);
2106   userPrincipalName_v[0] = upn;
2107   sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
2108   altSecurityIdentities_v[0] = temp;
2109   samAccountName_v[0] = user_name;
2110
2111   n = 0;
2112   ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
2113   ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
2114   ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2115   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2116   if (strlen(av[U_UID]) != 0)
2117     {
2118       uid_v[0] = av[U_UID];
2119       ADD_ATTR("uid", uid_v, LDAP_MOD_REPLACE);
2120       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
2121     }
2122   if (strlen(av[U_MITID]) != 0)
2123     {
2124       mitid_v[0] = av[U_MITID];
2125       ADD_ATTR("employeeID", mitid_v, LDAP_MOD_REPLACE);
2126     }
2127   mods[n] = NULL;
2128   sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
2129   if ((rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods)) != LDAP_SUCCESS)
2130     {
2131        critical_alert("AD incremental - user rename", 
2132                       "After renaming, couldn't modify user data for %s : %s",
2133                        user_name, ldap_err2string(rc));
2134     }
2135   for (i = 0; i < n; i++)
2136     free(mods[i]);
2137   return(0);
2138 }
2139
2140 int user_create(int ac, char **av, void *ptr)
2141 {
2142   LDAPMod *mods[20];
2143   char new_dn[256];
2144   char user_name[256];
2145   char sam_name[256];
2146   char *cn_v[] = {NULL, NULL};
2147   char *objectClass_v[] = {"top", "person", 
2148                            "organizationalPerson", 
2149                            "user", NULL};
2150
2151   char *samAccountName_v[] = {NULL, NULL};
2152   char *altSecurityIdentities_v[] = {NULL, NULL};
2153   char *name_v[] = {NULL, NULL};
2154   char *desc_v[] = {NULL, NULL};
2155   char upn[256];
2156   char *userPrincipalName_v[] = {NULL, NULL};
2157   char *userAccountControl_v[] = {NULL, NULL};
2158   char *uid_v[] = {NULL, NULL};
2159   char *mitid_v[] = {NULL, NULL};
2160   char userAccountControlStr[80];
2161   char temp[128];
2162   u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE;
2163   int  n;
2164   int  rc;
2165   int  i;
2166   int  sid_count;
2167   char filter_exp[256];
2168   char *attr_array[3];
2169   char **call_args;
2170
2171   call_args = ptr;
2172
2173   if ((atoi(av[U_STATE]) != US_REGISTERED) && (atoi(av[U_STATE]) != US_NO_PASSWD) && 
2174       (atoi(av[U_STATE]) != US_ENROLL_NOT_ALLOWED))
2175     return(0);
2176   if (!strncmp(av[U_NAME], "#", 1))
2177     return(0);
2178   if (!check_string(av[U_NAME]))
2179     {
2180       critical_alert("AD incremental - user create",
2181                       "invalid LDAP user name %s",
2182                       av[U_NAME]);
2183       return(0);
2184     }
2185
2186   strcpy(user_name, av[U_NAME]);
2187   sprintf(upn, "%s@%s", user_name, ldap_domain);
2188   sprintf(sam_name, "%s", av[U_NAME]);
2189   samAccountName_v[0] = sam_name;
2190   if (atoi(av[U_STATE]) == US_DELETED)
2191     userAccountControl |= UF_ACCOUNTDISABLE;
2192   sprintf(userAccountControlStr, "%ld", userAccountControl);
2193   userAccountControl_v[0] = userAccountControlStr;
2194   userPrincipalName_v[0] = upn;
2195
2196   cn_v[0] = user_name;
2197   name_v[0] = user_name;
2198   desc_v[0] = "Auto account created by Moira";
2199   sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
2200   altSecurityIdentities_v[0] = temp;    
2201   sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
2202
2203   n = 0;
2204   ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2205   ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2206   ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2207   ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
2208   ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
2209   ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2210   ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2211   ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2212   ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
2213   if (strlen(av[U_UID]) != 0)
2214     {
2215       uid_v[0] = av[U_UID];
2216       ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
2217       ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
2218     }
2219   if (strlen(av[U_MITID]) != 0)
2220       mitid_v[0] = av[U_MITID];
2221   else
2222       mitid_v[0] = "none";
2223   ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
2224   mods[n] = NULL;
2225
2226   rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2227   for (i = 0; i < n; i++)
2228     free(mods[i]);
2229   if (rc == LDAP_ALREADY_EXISTS)
2230     {
2231       rc = user_change_status(ac, av, ptr);
2232       return(0);
2233     }
2234   if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2235     {
2236        critical_alert("AD incremental - user create", 
2237                       "could not create user %s : %s",
2238                        user_name, ldap_err2string(rc));
2239        return(0);
2240     }
2241   if (rc == LDAP_SUCCESS)
2242     {
2243       if ((rc = set_password(sam_name, ldap_domain)) != 0)
2244         {
2245           if ((rc = set_password(user_name, ldap_domain)) != 0)
2246             {
2247               critical_alert("AD incremental - user create", 
2248                              "Couldn't set password for user %s : %ld",
2249                              user_name, rc);
2250             }
2251         }
2252     }
2253   sprintf(filter_exp, "(sAMAccountName=%s)", av[U_NAME]);
2254   attr_array[0] = "objectSid";
2255   attr_array[1] = NULL;
2256   sid_count = 0;
2257   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
2258                            sid_ptr, &sid_count)) == LDAP_SUCCESS)
2259     {
2260       if (sid_count == 1)
2261         {
2262           (*sid_ptr)->member = strdup(av[U_NAME]);
2263           (*sid_ptr)->type = (char *)USERS;
2264           sid_ptr = &(*sid_ptr)->next;
2265         }
2266     }
2267   return(0);
2268 }
2269
2270 int user_change_status(int ac, char **av, void *ptr)
2271 {
2272   char      filter_exp[1024];
2273   char      *attr_array[3];
2274   char      temp[256];
2275   char      distinguished_name[1024];
2276   char      user_name[512];
2277   char      **modvalues;
2278   LDAPMod   *mods[20];
2279   LK_ENTRY  *group_base;
2280   int       group_count;
2281   int       rc;
2282   int       i;
2283   int       n;
2284   int       operation;
2285   ULONG     ulongValue;
2286   char **call_args;
2287
2288   call_args = ptr;
2289
2290   if (!check_string(av[U_NAME]))
2291     {
2292       critical_alert("AD incremental - user change status",
2293                       "invalid LDAP user name %s",
2294                       av[U_NAME]);
2295       return(0);
2296     }
2297   strcpy(user_name, av[U_NAME]);
2298   operation = (int)call_args[2];
2299   group_count = 0;
2300   group_base = NULL;
2301   sprintf(filter_exp, "(sAMAccountName=%s)", av[U_NAME]);
2302   attr_array[0] = "UserAccountControl";
2303   attr_array[1] = NULL;
2304   if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array, 
2305                            &group_base, &group_count)) != 0)
2306     {
2307       critical_alert("AD incremental - user change status",
2308                      "LDAP server couldn't process user %s : %s",
2309                       user_name, ldap_err2string(rc));
2310       goto cleanup;
2311     }
2312
2313   if (group_count != 1)
2314     {
2315       critical_alert("AD incremental - user change status",
2316                      "LDAP server unable to find user %s in AD.",
2317                       user_name);
2318       goto cleanup;
2319     }
2320
2321   strcpy(distinguished_name, group_base->dn);
2322   ulongValue = atoi((*group_base).value);
2323   if (operation == MEMBER_DEACTIVATE)
2324     ulongValue |= UF_ACCOUNTDISABLE;
2325   else    
2326     ulongValue &= ~UF_ACCOUNTDISABLE;
2327   sprintf(temp, "%ld", ulongValue);
2328   if ((rc = construct_newvalues(group_base, group_count, (*group_base).value, 
2329                                 temp, &modvalues, REPLACE)) == 1)
2330       goto cleanup;
2331   linklist_free(group_base);
2332   group_base = NULL;
2333   group_count = 0;
2334   n = 0;
2335   ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
2336   mods[n] = NULL;
2337   rc = ldap_modify_s((LDAP *)call_args[0], distinguished_name, mods);
2338   for (i = 0; i < n; i++)
2339     free(mods[i]);
2340   free_values(modvalues);
2341   if (rc != LDAP_SUCCESS)
2342     {
2343       critical_alert("AD incremental - user change status",
2344                      "LDAP server could not change status of user %s : %s",
2345                      user_name, ldap_err2string(rc));
2346     }
2347 cleanup:
2348   linklist_free(group_base);
2349   return(0);
2350 }
2351
2352 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name)
2353 {
2354   char      filter_exp[1024];
2355   char      *attr_array[3];
2356   char      distinguished_name[1024];
2357   char      user_name[512];
2358   LK_ENTRY  *group_base;
2359   int       group_count;
2360   int       rc;
2361
2362   if (!check_string(u_name))
2363     return(0);
2364   strcpy(user_name, u_name);
2365   group_count = 0;
2366   group_base = NULL;
2367   sprintf(filter_exp, "(sAMAccountName=%s)", user_name);
2368   attr_array[0] = "name";
2369   attr_array[1] = NULL;
2370   if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array, 
2371                            &group_base, &group_count)) != 0)
2372     {
2373       critical_alert("AD incremental",
2374                      "LDAP server couldn't process user %s : %s",
2375                       user_name, ldap_err2string(rc));
2376       goto cleanup;
2377     }
2378
2379   if (group_count != 1)
2380     {
2381       critical_alert("AD incremental - user change status",
2382                      "LDAP server unable to find user %s in AD.",
2383                       user_name);
2384       goto cleanup;
2385     }
2386
2387   strcpy(distinguished_name, group_base->dn);
2388   if (rc = ldap_delete_s(ldap_handle, distinguished_name))
2389     {
2390       critical_alert("AD incremental",
2391                      "LDAP server couldn't process user %s : %s",
2392                       user_name, ldap_err2string(rc));
2393     }
2394
2395 cleanup:
2396   linklist_free(group_base);
2397   return(0);
2398 }
2399
2400 void linklist_free(LK_ENTRY *linklist_base)
2401 {
2402   LK_ENTRY *linklist_previous;
2403
2404   while (linklist_base != NULL)
2405     {
2406       if (linklist_base->dn != NULL)
2407         free(linklist_base->dn);
2408       if (linklist_base->attribute != NULL)
2409         free(linklist_base->attribute);
2410       if (linklist_base->value != NULL)
2411         free(linklist_base->value);
2412       if (linklist_base->member != NULL)
2413         free(linklist_base->member);
2414       if (linklist_base->type != NULL)
2415         free(linklist_base->type);
2416       if (linklist_base->list != NULL)
2417         free(linklist_base->list);
2418       linklist_previous = linklist_base;
2419       linklist_base = linklist_previous->next;
2420       free(linklist_previous);
2421     }
2422 }
2423
2424 void free_values(char **modvalues)
2425 {
2426   int i;
2427
2428   i = 0;
2429   if (modvalues != NULL)
2430     {
2431     while (modvalues[i] != NULL)
2432       {
2433         free(modvalues[i]);
2434         modvalues[i] = NULL;
2435         ++i;
2436       }
2437     free(modvalues);
2438   }
2439 }
2440
2441 int sid_update(LDAP *ldap_handle, char *dn_path)
2442 {
2443   LK_ENTRY      *ptr;
2444   int           rc;
2445   unsigned char temp[126];
2446   char          *av[3];
2447
2448   ptr = sid_base;
2449
2450   while (ptr != NULL)
2451     {
2452       memset(temp, 0, sizeof(temp));
2453       convert_b_to_a(temp, ptr->value, ptr->length);
2454       av[0] = ptr->member;
2455       av[1] = temp;
2456       if (ptr->type == (char *)GROUPS)
2457         {
2458           ptr->type = NULL;
2459           rc = mr_query("add_list_sid_by_name", 2, av, NULL, NULL);
2460         }
2461       else if (ptr->type == (char *)USERS)
2462         {
2463           ptr->type = NULL;
2464           rc = mr_query("add_user_sid_by_login", 2, av, NULL, NULL);
2465         }
2466       ptr = ptr->next;
2467     }
2468   return(0);
2469 }
2470
2471 void convert_b_to_a(char *string, UCHAR *binary, int length)
2472 {
2473   int   i;
2474   int   j;
2475   UCHAR tmp;
2476
2477   j = 0;
2478   for (i = 0; i < length; i++)
2479     {
2480       tmp = binary[i];
2481       string[j] = tmp;
2482       string[j] >>= 4;
2483       string[j] &= 0x0f;
2484       string[j] += 0x30;
2485       if (string[j] > '9')
2486         string[j] += 0x27;
2487       ++j;
2488       string[j] = tmp & 0x0f;
2489       string[j] += 0x30;
2490       if (string[j] > '9')
2491         string[j] += 0x27;
2492       j++;
2493     }
2494   string[j] = 0;
2495 }
2496
2497 static int illegalchars[] = {
2498   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2499   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2500   1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
2501   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
2502   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
2503   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
2504   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2505   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
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   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2509   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2510   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2511   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2512   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2513   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2514 };
2515
2516 int check_string(char *s)
2517 {
2518   char  character;
2519
2520   for (; *s; s++)
2521     {
2522       character = *s;
2523       if (isupper(character))
2524         character = tolower(character);
2525       if (illegalchars[(unsigned) character])
2526         return 0;
2527     }
2528   return 1;
2529 }
2530
2531 int mr_connect_cl(char *server, char *client, int version, int auth)
2532 {
2533   int   status;
2534   char  *motd;
2535   char  temp[128];
2536
2537   status = mr_connect(server);
2538   if (status)
2539     {
2540       com_err(whoami, status, "while connecting to Moira");
2541       return MRCL_FAIL;
2542     }
2543
2544   status = mr_motd(&motd);
2545   if (status)
2546     {
2547       mr_disconnect();
2548       com_err(whoami, status, "while checking server status");
2549       return MRCL_FAIL;
2550     }
2551   if (motd)
2552     {
2553       sprintf(temp, "The Moira server is currently unavailable: %s", motd);
2554       com_err(whoami, status, temp);
2555       mr_disconnect();
2556       return MRCL_FAIL;
2557     }
2558
2559   status = mr_version(version);
2560   if (status)
2561     {
2562       if (status == MR_UNKNOWN_PROC)
2563               {
2564                 if (version > 2)
2565                   status = MR_VERSION_HIGH;
2566                 else
2567                   status = MR_SUCCESS;
2568               }
2569
2570       if (status == MR_VERSION_HIGH)
2571               {
2572                 com_err(whoami, 0, "Warning: This client is running newer code than the server.");
2573                 com_err(whoami, 0, "Some operations may not work.");
2574               }
2575       else if (status && status != MR_VERSION_LOW)
2576               {
2577                 com_err(whoami, status, "while setting query version number.");
2578                 mr_disconnect();
2579                 return MRCL_FAIL;
2580               }
2581     }
2582
2583   if (auth)
2584     {
2585       status = mr_auth(client);
2586       if (status)
2587               {
2588                 com_err(whoami, status, "while authenticating to Moira.");
2589                 mr_disconnect();
2590                 return MRCL_AUTH_ERROR;
2591               }
2592     }
2593
2594   return MRCL_SUCCESS;
2595 }
2596
This page took 0.251161 seconds and 5 git commands to generate.