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