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