]> andersk Git - moira.git/blame - incremental/winad/winad.c
Fix usage message.
[moira.git] / incremental / winad / winad.c
CommitLineData
5d0a7127 1/* $Header$
2 *
3 * Do incremental updates of a Windows Active Directory
4 *
5 * test parameters for reactivating a user account
6 * users 9 9 testaccount 1 sh account test A 3 2 3 testaccount 1 csh new login b 1 2 3
7 */
8
9#include <mit-copyright.h>
10#ifdef _WIN32
11#include <windows.h>
12#include <stdlib.h>
13#include <malloc.h>
14#include <lmaccess.h>
15#endif
16#include <ldap.h>
17#include <stdio.h>
18#include <moira.h>
19#include <moira_site.h>
20#include <krb5.h>
21#include <krb.h>
22#include <gsssasl.h>
23#include <gssldap.h>
24
25#ifndef _WIN32
26#include <sys/utsname.h>
27
28#define UF_SCRIPT 0x0001
29#define UF_ACCOUNTDISABLE 0x0002
30#define UF_HOMEDIR_REQUIRED 0x0008
31#define UF_LOCKOUT 0x0010
32#define UF_PASSWD_NOTREQD 0x0020
33#define UF_PASSWD_CANT_CHANGE 0x0040
34
35#define UF_TEMP_DUPLICATE_ACCOUNT 0x0100
36#define UF_NORMAL_ACCOUNT 0x0200
37#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800
38#define UF_WORKSTATION_TRUST_ACCOUNT 0x1000
39#define UF_SERVER_TRUST_ACCOUNT 0x2000
40
41#ifndef BYTE
42#define BYTE unsigned char
43#endif
44typedef unsigned int DWORD;
45typedef unsigned long ULONG;
46
47typedef struct _GUID
48{
49 unsigned long Data1;
50 unsigned short Data2;
51 unsigned short Data3;
52 unsigned char Data4[8];
53} GUID;
54
55typedef struct _SID_IDENTIFIER_AUTHORITY {
56 BYTE Value[6];
57} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
58
59typedef struct _SID {
60 BYTE Revision;
61 BYTE SubAuthorityCount;
62 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
63 DWORD SubAuthority[512];
64} SID;
65#endif/*!WIN32*/
66
67#define SUBSTITUTE 1
68#define REPLACE 2
69
70#define MEMBER_ADD 1
71#define MEMBER_REMOVE 2
72#define MEMBER_CHANGE_NAME 3
73#define MEMBER_ACTIVATE 4
74#define MEMBER_DEACTIVATE 5
75
76#define GROUP_CREATE 1
77#define GROUP_DELETE 2
78#define GROUP_MOVE_MEMBERS 3
79#define GROUP_UPDATE_MEMBERS 4
80
81typedef struct lk_entry {
82 int op;
83 int length;
84 int ber_value;
85 char *dn;
86 char *attribute;
87 char *value;
88 char *member;
89 char *type;
90 char *list;
91 struct lk_entry *next;
92} LK_ENTRY;
93
94#define LDAP_BERVAL struct berval
95
96LK_ENTRY *member_base = NULL;
97char group_ou[] = "OU=groups,OU=athena";
98char *whoami;
99static int mr_connections = 0;
100
101int add_list_members(int ac, char **av, void *group);
102int add_user_lists(int ac, char **av, void *user);
103int member_update(LDAP *ldap_handle, char *dn_path, LDAPMessage *ldap_entry,
104 char *login_name, char *new_login_name, char *ldap_hostname,
105 int operation, LK_ENTRY *group_base);
106int group_update(LDAP *ldap_handle, char *ldap_hostname,
107 char *before_group_name, char *after_group_name,
108 int operation, LK_ENTRY *user_list);
109int check_user(int ac, char **av, void *ustate);
110int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
111 int newValue_count, char *oldValue, char *newValue,
112 LDAPMod ***newValueArray, char ****modvalues,
113 int type);
114int convert_domain_to_dn(char *domain, char **bind_path);
115void delete_user(LDAP *ldap_handle, LDAPMessage *ldap_entry);
116void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
117 char **before, int beforec, char **after, int afterc);
118void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
119 char *dn_path, char **before, int beforec, char **after,
120 int afterc);
121void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
122 char **before, int beforec, char **after, int afterc);
123void edit_group(int op, char *group, char *type, char *member,
124 LDAP *ldap_handle, char *dn_path, char *ldap_hostname);
125int linklist_create_entry(char *attribute, char *value,
126 LK_ENTRY **linklist_entry);
127int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
128 char **attr_array, LK_ENTRY **linklist_base,
129 int *linklist_count);
130void linklist_free(LK_ENTRY *linklist_base);
131void free_values(int newvalue_count, LDAPMod **newvalue_array,
132 char ***modvalues);
133void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
134 char *distinguished_name);
135int moira_disconnect(void);
136int moira_connect(void);
137void print_to_screen(const char *fmt, ...);
138int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
139 char *distinguished_name, LK_ENTRY **linklist_current);
140int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
141 LK_ENTRY **linklist_base, int *linklist_count);
142int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
143 char *Attribute, char *distinguished_name,
144 LK_ENTRY **linklist_current);
145
146int main(int argc, char **argv)
147{
148 unsigned long rc;
149 int beforec, afterc, Max_wait_time = 500, Max_size_limit = LDAP_NO_LIMIT;
150 char ldap_hostname[256], search_exp[1024];
151 char *dn_path, *table, **before, **after;
152 ULONG version = LDAP_VERSION3;
153 LDAP *ldap_handle;
154 LDAPMessage *ldap_entry;
155 FILE *fptr;
156
157 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
158 /*
159 * if (argc < 4)
160 * exit(1);
161 *
162 * beforec = atoi(argv[2]);
163 * afterc = atoi(argv[3]);
164 *
165 * if (argc < (4 + beforec + afterc))
166 * exit(1);
167 *
168 * table = argv[1];
169 * before = &argv[4];
170 * after = &argv[4 + beforec];
171 */
172 memset(ldap_hostname, '\0', sizeof(ldap_hostname));
173 if ((fptr = fopen("winad.cfg", "r")) != NULL)
174 {
175 fread(ldap_hostname, sizeof(char), sizeof(ldap_hostname), fptr);
176 fclose(fptr);
177 }
178 if (strlen(ldap_hostname) == 0)
179 strcpy(ldap_hostname, "windows.mit.edu");
180
181 initialize_sms_error_table();
182 initialize_krb_error_table();
183
184 memset(search_exp, '\0', sizeof(search_exp));
185 ldap_entry = NULL;
186 dn_path = NULL;
187 convert_domain_to_dn(ldap_hostname, &dn_path);
188 if (dn_path == NULL)
189 exit(1);
190
191 ldap_handle = ldap_open(ldap_hostname, LDAP_PORT);
192 if (ldap_handle == NULL)
193 exit(1);
194 rc = ldap_set_option(ldap_handle, LDAP_OPT_PROTOCOL_VERSION, &version);
195 rc = ldap_set_option(ldap_handle, LDAP_OPT_TIMELIMIT,
196 (void *)&Max_wait_time);
197 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT,
198 (void *)&Max_size_limit);
199 rc = ldap_set_option(ldap_handle, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
200 rc = ldap_adgssapi_bind(ldap_handle, dn_path, GSSSASL_NO_SECURITY_LAYER);
201 if (rc != LDAP_SUCCESS)
202 exit(1);
203
204 /* used for testing
205 * do_list(ldap_handle, dn_path, ldap_hostname, before, beforec, after,
206 * afterc);
207 */
208
209 rc = group_update(ldap_handle, ldap_hostname, "testaccountF", NULL,
210 GROUP_CREATE, NULL);
211 printf("first rc = %d\n", rc);
212 if (rc != 0)
213 exit(1);
214 rc = group_update(ldap_handle, ldap_hostname, "pismere-team",
215 "testaccountF", GROUP_MOVE_MEMBERS, NULL);
216 printf("second rc = %d\n", rc);
217 if (rc != 0)
218 exit(1);
219 rc = group_update(ldap_handle, ldap_hostname, "testaccountF", NULL,
220 GROUP_DELETE, NULL);
221 printf("third rc = %d\n", rc);
222 exit(1);
223
224 if (!strcmp(table, "users"))
225 {
226 sprintf(search_exp, "(sAMAccountName=%s)", before[U_NAME]);
227 if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE,
228 search_exp, NULL, 0, &ldap_entry))
229 == LDAP_SUCCESS)
230 do_user(ldap_handle, ldap_entry, ldap_hostname, dn_path, before,
231 beforec, after, afterc);
232 rc = ldap_msgfree(ldap_entry);
233 }
234 else if (!strcmp(table, "list"))
235 do_list(ldap_handle, dn_path, ldap_hostname, before, beforec, after,
236 afterc);
237 else if (!strcmp(table, "imembers"))
238 do_member(ldap_handle, dn_path, ldap_hostname, before, beforec, after,
239 afterc);
240 /*
241 * else if (!strcmp(table, "filesys"))
242 * do_filesys(before, beforec, after, afterc);
243 * else if (!strcmp(table, "quota"))
244 * do_quota(before, beforec, after, afterc);
245 */
246 rc = ldap_unbind_s(ldap_handle);
247 free(dn_path);
248
249 exit(0);
250}
251
252void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
253 char **before, int beforec, char **after, int afterc)
254{
255 int agid = 0, bgid = 0, ahide, bhide;
256 long rc, id;
257 char *av[2];
258
259 if (beforec > L_GID && atoi(before[L_ACTIVE]) && atoi(before[L_GROUP]))
260 {
261 bgid = atoi(before[L_GID]);
262 bhide = atoi(before[L_HIDDEN]);
263 }
264 if (afterc > L_GID && atoi(after[L_ACTIVE]) && atoi(after[L_GROUP]))
265 {
266 agid = atoi(after[L_GID]);
267 ahide = atoi(after[L_HIDDEN]);
268 }
269
270 if (agid == 0 && bgid == 0)
271 return;
272
273 if (agid && bgid)
274 {
275 if (strcmp(after[L_NAME], before[L_NAME]))
276 {
277 com_err(whoami, 0, "Changing group %s to %s",
278 before[L_NAME], after[L_NAME]);
279
280 if (!(rc = group_update(ldap_handle, ldap_hostname,
281 after[L_NAME], NULL, GROUP_CREATE, NULL)))
282 {
283 if (!(rc = group_update(ldap_handle, ldap_hostname,
284 before[L_NAME], after[L_NAME],
285 GROUP_MOVE_MEMBERS, NULL)))
286 {
287 rc = group_update(ldap_handle, ldap_hostname,
288 before[L_NAME], NULL, GROUP_DELETE,
289 NULL);
290 }
291 }
292 if (rc)
293 {
294 critical_alert("incremental", "Couldn't change group %s "
295 "to %s", before[L_NAME], after[L_NAME]);
296 }
297 }
298 return;
299 }
300 if (bgid)
301 {
302 com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
303 rc = group_update(ldap_handle, ldap_hostname, before[L_NAME], NULL,
304 GROUP_DELETE, NULL);
305 if (rc)
306 {
307 critical_alert("incremental",
308 "Couldn't delete group %s (id %d)",
309 before[L_NAME], -bgid);
310 }
311 return;
312 }
313 if (agid)
314 {
315 id = -agid;
316 com_err(whoami, 0, "Creating group %s", after[L_NAME]);
317 rc = group_update(ldap_handle, ldap_hostname, after[L_NAME], NULL,
318 GROUP_CREATE, NULL);
319 if (rc)
320 {
321 critical_alert("incremental", "Couldn't create group %s (id %d)",
322 after[L_NAME], id);
323 return;
324 }
325
326 if (beforec < L_ACTIVE)
327 return;
328
329 rc = moira_connect();
330 if (rc)
331 {
332 critical_alert("incremental",
333 "Error contacting Moira server to resolve %s: %s",
334 after[L_NAME], error_message(rc));
335 return;
336 }
337 av[0] = after[L_NAME];
338 rc = mr_query("get_end_members_of_list", 1, av,
339 add_list_members, after[L_NAME]);
340 if (rc)
341 {
342 critical_alert("incremental",
343 "Couldn't retrieve full membership of list %s: %s",
344 after[L_NAME], error_message(rc));
345 }
346 rc = group_update(ldap_handle, ldap_hostname, after[L_NAME], NULL,
347 GROUP_UPDATE_MEMBERS, member_base);
348 linklist_free(member_base);
349 moira_disconnect();
350 return;
351 }
352}
353
354#define LM_EXTRA_ACTIVE (LM_END)
355#define LM_EXTRA_PUBLIC (LM_END+1)
356#define LM_EXTRA_HIDDEN (LM_END+2)
357#define LM_EXTRA_MAILLIST (LM_END+3)
358#define LM_EXTRA_GROUP (LM_END+4)
359#define LM_EXTRA_GID (LM_END+5)
360#define LM_EXTRA_END (LM_END+6)
361
362void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
363 char **before, int beforec, char **after, int afterc)
364{
365 if (afterc)
366 {
367 if (afterc < LM_EXTRA_END)
368 return;
369 else
370 {
371 if (!atoi(after[LM_EXTRA_ACTIVE]) || !atoi(after[LM_EXTRA_GROUP]))
372 return;
373 }
374 edit_group(1, after[LM_LIST], after[LM_TYPE], after[LM_MEMBER],
375 ldap_handle, dn_path, ldap_hostname);
376 }
377 else if (beforec)
378 {
379 if (beforec < LM_EXTRA_END)
380 return;
381 else
382 {
383 if (!atoi(before[LM_EXTRA_ACTIVE]) || !atoi(before[LM_EXTRA_GROUP]))
384 return;
385 }
386 edit_group(0, before[LM_LIST], before[LM_TYPE], before[LM_MEMBER],
387 ldap_handle, dn_path, ldap_hostname);
388 }
389}
390
391void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
392 char *dn_path, char **before, int beforec, char **after,
393 int afterc)
394{
395 int astate = 0, bstate = 0, auid = 0, buid = 0, rc;
396 char *av[2];
397
398 if (afterc > U_STATE)
399 astate = atoi(after[U_STATE]);
400 if (beforec > U_STATE)
401 bstate = atoi(before[U_STATE]);
402 if (afterc > U_UID)
403 auid = atoi(after[U_UID]);
404 if (beforec > U_UID)
405 buid = atoi(before[U_UID]);
406
407 if (astate == 2)
408 astate = 1;
409 if (bstate == 2)
410 bstate = 1;
411
412 if (astate != 1 && bstate != 1) /* inactive user */
413 return;
414
415 if ((astate == bstate) && (auid == buid) &&
416 !strcmp(before[U_NAME], after[U_NAME]))
417 return;
418
419 if (astate == bstate)
420 {
421 com_err(whoami, 0, "Changing user %s to %s", before[U_NAME],
422 after[U_NAME]);
423 rc = member_update(ldap_handle, dn_path, ldap_entry, before[U_NAME],
424 after[U_NAME], ldap_hostname, MEMBER_CHANGE_NAME,
425 NULL);
426 if (rc)
427 {
428 critical_alert("incremental",
429 "Couldn't change user %s (id %d) to %s (id %d)",
430 before[U_NAME], buid, after[U_NAME], auid);
431 }
432 return;
433 }
434 if (bstate == 1)
435 {
436 com_err(whoami, 0, "Deleting user %s", before[U_NAME]);
437 rc = member_update(ldap_handle, dn_path, ldap_entry, before[U_NAME],
438 NULL, ldap_hostname, MEMBER_DEACTIVATE, NULL);
439 if (rc)
440 {
441 critical_alert("incremental", "Couldn't deactivate user %s (id %d)",
442 before[U_NAME], buid);
443 }
444 return;
445 }
446 if (astate == 1)
447 {
448 com_err(whoami, 0, "%s user %s",
449 ((bstate != 0) ? "Reactivating" : "Creating"),
450 after[U_NAME]);
451
452 rc = member_update(ldap_handle, dn_path, ldap_entry, after[U_NAME],
453 NULL, ldap_hostname, MEMBER_ACTIVATE, NULL);
454 if (rc)
455 {
456 critical_alert("incremental", "Couldn't activate user %s (id %d)",
457 after[U_NAME], auid);
458 return;
459 }
460 if (bstate != 0)
461 {
462 /* Reactivating a user; get his group list */
463 rc = moira_connect();
464 if (rc)
465 {
466 critical_alert("incremental", "Error contacting Moira server "
467 "to retrieve grouplist of user %s: %s",
468 after[U_NAME], error_message(rc));
469 return;
470 }
471 av[0] = "ruser";
472 av[1] = after[U_NAME];
473 member_base = NULL;
474 rc = mr_query("get_lists_of_member", 2, av, add_user_lists,
475 after[U_NAME]);
476 if (rc && rc != MR_NO_MATCH)
477 {
478 critical_alert("incremental",
479 "Couldn't retrieve membership of user %s: %s",
480 after[U_NAME], error_message(rc));
481 }
482 else
483 {
484 rc = member_update(ldap_handle, dn_path, ldap_entry,
485 after[U_NAME], NULL, ldap_hostname,
486 MEMBER_ADD, member_base);
487 linklist_free(member_base);
488 }
489 moira_disconnect();
490 }
491 return;
492 }
493}
494
495int group_update(LDAP *ldap_handle, char *ldap_hostname, char *group_name,
496 char *after_group_name, int operation, LK_ENTRY *user_list)
497{
498 char distinguished_name[1024], filter_exp[1024], temp[256];
499 char ***modvalues, *attr_array[3], *dn_path = NULL;
500 int newvalue_count, group_count, sPtr_count;
501 LDAPMod **newvalue_array;
502 LK_ENTRY *group_base;
503 LK_ENTRY **sPtr;
504 LK_ENTRY *pPtr;
505 ULONG rc = 0;
506
507 convert_domain_to_dn(ldap_hostname, &dn_path);
508
509 newvalue_array = NULL;
510 newvalue_count = 0;
511 modvalues = NULL;
512 group_base = NULL;
513 group_count = 0;
514 newvalue_count = 0;
515 newvalue_array = NULL;
516 modvalues = NULL;
517 if ((newvalue_array = calloc(1, (5+1) * sizeof(LDAPMod *))) == NULL)
518 {
519 rc = 1;
520 goto cleanup;
521 }
522 newvalue_array[0] = NULL;
523 newvalue_array[1] = NULL;
524 newvalue_array[2] = NULL;
525 newvalue_array[3] = NULL;
526 newvalue_array[4] = NULL;
527 if ((modvalues = calloc(1, (5+1) * sizeof(char **))) == NULL)
528 {
529 rc = 1;
530 goto cleanup;
531 }
532 modvalues[0] = NULL;
533 modvalues[1] = NULL;
534 modvalues[2] = NULL;
535 modvalues[3] = NULL;
536 modvalues[4] = NULL;
537
538 if (operation == GROUP_DELETE)
539 {
540 sprintf(filter_exp, "(sAMAccountName=%s)", group_name);
541 attr_array[0] = "distinguishedName";
542 attr_array[1] = NULL;
543 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
544 &group_base, &group_count)) != 0)
545 goto cleanup;
546 if (group_count == 1)
547 rc = ldap_delete_s(ldap_handle, group_base->value);
548 if (rc != LDAP_SUCCESS)
549 {
550 critical_alert("incremental",
551 "Couldn't delete group %s: %s",
552 group_name, ldap_err2string(rc));
553 goto cleanup;
554 }
555 }
556 else if (operation == GROUP_CREATE)
557 {
558 linklist_create_entry("cn", group_name, &group_base);
559 group_count = 1;
560 if ((rc = construct_newvalues(group_base, group_count, newvalue_count,
561 NULL, NULL, &newvalue_array, &modvalues,
562 REPLACE)) == 1)
563 goto cleanup;
564 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
565 newvalue_array[newvalue_count]->mod_type = "cn";
566 newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
567 linklist_free(group_base);
568 group_base = NULL;
569
570 ++newvalue_count;
571 linklist_create_entry("name", group_name, &group_base);
572 group_count = 1;
573 if ((rc = construct_newvalues(group_base, group_count, newvalue_count,
574 NULL, NULL, &newvalue_array, &modvalues,
575 REPLACE)) == 1)
576 goto cleanup;
577 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
578 newvalue_array[newvalue_count]->mod_type = "name";
579 newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
580 linklist_free(group_base);
581 group_base = NULL;
582
583 ++newvalue_count;
584 linklist_create_entry("objectClass","top", &group_base);
585 linklist_create_entry("objectClass", "group", &group_base->next);
586 group_count = 2;
587 if ((rc = construct_newvalues(group_base, group_count, newvalue_count,
588 NULL, NULL, &newvalue_array, &modvalues,
589 REPLACE)) == 1)
590 goto cleanup;
591 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
592 newvalue_array[newvalue_count]->mod_type = "objectClass";
593 newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
594 linklist_free(group_base);
595 group_base = NULL;
596
597 ++newvalue_count;
598 linklist_create_entry("sAMAccountName", group_name, &group_base);
599 group_count = 1;
600 if ((rc = construct_newvalues(group_base, group_count, newvalue_count,
601 NULL, NULL, &newvalue_array, &modvalues,
602 REPLACE)) == 1)
603 goto cleanup;
604 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
605 newvalue_array[newvalue_count]->mod_type = "sAMAccountName";
606 newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
607 linklist_free(group_base);
608 group_base = NULL;
609
610 sprintf(temp,"CN=%s,%s,%s", group_name, group_ou, dn_path);
611 rc = ldap_add_s(ldap_handle, temp, newvalue_array);
612 if (rc != LDAP_SUCCESS)
613 {
614 critical_alert("incremental",
615 "Couldn't create group %s: %s",
616 group_name, ldap_err2string(rc));
617 goto cleanup;
618 }
619 }
620 else if (operation == GROUP_UPDATE_MEMBERS)
621 {
622 sprintf(filter_exp, "(sAMAccountName=%s)", group_name);
623 attr_array[0] = "distinguishedName";
624 attr_array[1] = NULL;
625 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
626 &group_base, &group_count)) != 0)
627 goto cleanup;
628 if (group_count != 1)
629 {
630 rc = 1;
631 goto cleanup;
632 }
633 strcpy(distinguished_name, group_base->value);
634 linklist_free(group_base);
635
636 pPtr = member_base;
637 group_base = NULL;
638 group_count = 0;
639 sPtr = &group_base;
640 while (pPtr)
641 {
642 sprintf(filter_exp, "(sAMAccountName=%s)", pPtr->member);
643 attr_array[0] = "distinguishedName";
644 attr_array[1] = NULL;
645 if ((*sPtr) != NULL)
646 sPtr = &((*sPtr)->next);
647 sPtr_count = 0;
648 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp,
649 attr_array, sPtr, &sPtr_count)) != 0)
650 goto cleanup;
651 if (sPtr_count != 0)
652 group_count += sPtr_count;
653 pPtr = pPtr->next;
654 }
655 if (group_count != 0)
656 {
657 if ((rc = construct_newvalues(group_base, group_count,
658 newvalue_count, NULL, NULL,
659 &newvalue_array, &modvalues,
660 REPLACE)) == 1)
661 goto cleanup;
662 linklist_free(group_base);
663 newvalue_array[newvalue_count]->mod_type = "member";
664 newvalue_array[newvalue_count]->mod_values =
665 modvalues[newvalue_count];
666 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
667 rc = ldap_modify_s(ldap_handle, distinguished_name, newvalue_array);
668 group_count = 0;
669 group_base = NULL;
670 if (rc != LDAP_SUCCESS)
671 {
672 critical_alert("incremental",
673 "Couldn't add users to group %s: %s",
674 group_name, ldap_err2string(rc));
675 goto cleanup;
676 }
677 }
678 }
679 else if (operation == GROUP_MOVE_MEMBERS)
680 {
681 sprintf(filter_exp, "(sAMAccountName=%s)", after_group_name);
682 attr_array[0] = "distinguishedName";
683 attr_array[1] = NULL;
684 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
685 &group_base, &group_count)) != 0)
686 goto cleanup;
687 if (group_count != 1)
688 {
689 rc = 1;
690 goto cleanup;
691 }
692 strcpy(distinguished_name, group_base->value);
693 linklist_free(group_base);
694
695 group_base = NULL;
696 group_count = 0;
697 sprintf(filter_exp, "(sAMAccountName=%s)", group_name);
698 attr_array[0] = "member";
699 attr_array[1] = NULL;
700 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
701 &group_base, &group_count)) != 0)
702 goto cleanup;
703
704 if (group_count != 0)
705 {
706 if ((rc = construct_newvalues(group_base, group_count,
707 newvalue_count, NULL, NULL,
708 &newvalue_array, &modvalues,
709 REPLACE)) == 1)
710 goto cleanup;
711 linklist_free(group_base);
712 newvalue_array[newvalue_count]->mod_type = "member";
713 newvalue_array[newvalue_count]->mod_values =
714 modvalues[newvalue_count];
715 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
716 rc = ldap_modify_s(ldap_handle, distinguished_name, newvalue_array);
717 group_count = 0;
718 group_base = NULL;
719 if (rc != LDAP_SUCCESS)
720 {
721 critical_alert("incremental",
722 "Couldn't add users to group %s: %s",
723 group_name, ldap_err2string(rc));
724 goto cleanup;
725 }
726 }
727 }
728
729 cleanup:
730 free_values(newvalue_count, newvalue_array, modvalues);
731 linklist_free(group_base);
732 if (dn_path != NULL)
733 free(dn_path);
734 if (rc == 1)
735 critical_alert("incremental",
736 "Couldn't process group %s: %s",
737 group_name, "Cannot calloc - out of memory");
738 return(rc);
739}
740
741int member_update(LDAP *ldap_handle, char *cn_path, LDAPMessage *ldap_entry,
742 char *login_name, char *new_login_name, char *ldap_hostname,
743 int operation, LK_ENTRY *group_list)
744{
745 char distinguished_name[1024], filter_exp[1024], temp[64];
746 char ***modvalues; /* each *mod has a char **modvalue */
747 char *attr_array[3], *dn_path = NULL;
748 int newvalue_count, memberOf_count, group_count, processGroup_count;
749 LDAPMod **newvalue_array;
750 LK_ENTRY *processGroup;
751 LK_ENTRY *processGroup_base;
752 LK_ENTRY *memberOf_base;
753 LK_ENTRY *group_base;
754 LK_ENTRY *gPtr;
755 LK_ENTRY *sPtr;
756 LK_ENTRY *pPtr;
757 ULONG rc;
758 ULONG ulongValue;
759
760 memset(distinguished_name, '\0', sizeof(distinguished_name));
761 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
762 if (strlen(distinguished_name) == 0)
763 return(1);
764
765 convert_domain_to_dn(ldap_hostname, &dn_path);
766
767 memberOf_base = NULL;
768 processGroup_base = NULL;
769 processGroup = NULL;
770 newvalue_array = NULL;
771 newvalue_count = 0;
772 modvalues = NULL;
773 group_count = 0;
774 group_base = NULL;
775
776 if ((newvalue_array = calloc(1, (3+1) * sizeof(LDAPMod *))) == NULL)
777 {
778 rc = 1;
779 goto cleanup;
780 }
781 newvalue_array[0] = NULL;
782 newvalue_array[1] = NULL;
783 newvalue_array[2] = NULL;
784 newvalue_array[3] = NULL;
785 if ((modvalues = calloc(1, (3+1) * sizeof(char **))) == NULL)
786 {
787 rc = 1;
788 goto cleanup;
789 }
790 modvalues[0] = NULL;
791 modvalues[1] = NULL;
792 modvalues[2] = NULL;
793 modvalues[3] = NULL;
794
795 if (operation == MEMBER_CHANGE_NAME)
796 {
797 sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
798 attr_array[0] = "sAMAccountName";
799 attr_array[1] = NULL;
800 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
801 &group_base, &group_count)) != 0)
802 goto cleanup;
803
804 if (group_count != 0)
805 {
806 if ((rc = construct_newvalues(group_base, group_count,
807 newvalue_count, login_name,
808 new_login_name, &newvalue_array,
809 &modvalues, REPLACE)) == 1)
810 goto cleanup;
811 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
812 newvalue_array[newvalue_count]->mod_type = "sAMAccountName";
813 newvalue_array[newvalue_count]->mod_values =
814 modvalues[newvalue_count];
815 linklist_free(group_base);
816 group_count = 0;
817 group_base = NULL;
818 ++newvalue_count;
819 }
820
821 sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
822 attr_array[0] = "UserPrincipalName";
823 attr_array[1] = NULL;
824 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
825 &group_base, &group_count)) != 0)
826 goto cleanup;
827 if (group_count != 0)
828 {
829 if ((rc = construct_newvalues(group_base, group_count,
830 newvalue_count, login_name,
831 new_login_name, &newvalue_array,
832 &modvalues, SUBSTITUTE)) == 1)
833 goto cleanup;
834 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
835 newvalue_array[newvalue_count]->mod_type = "UserPrincipalName";
836 newvalue_array[newvalue_count]->mod_values =
837 modvalues[newvalue_count];
838 linklist_free(group_base);
839 group_count = 0;
840 group_base = NULL;
841 ++newvalue_count;
842 }
843
844 sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
845 attr_array[0] = "AltSecurityIdentities";
846 attr_array[1] = NULL;
847 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
848 &group_base, &group_count)) != 0)
849 goto cleanup;
850 if (group_count != 0)
851 {
852 if ((rc = construct_newvalues(group_base, group_count,
853 newvalue_count, login_name,
854 new_login_name, &newvalue_array,
855 &modvalues, SUBSTITUTE)) == 1)
856 goto cleanup;
857 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
858 newvalue_array[newvalue_count]->mod_type = "AltSecurityIdentities";
859 newvalue_array[newvalue_count]->mod_values =
860 modvalues[newvalue_count];
861 linklist_free(group_base);
862 group_count = 0;
863 group_base = NULL;
864 ++newvalue_count;
865 }
866
867 if (newvalue_count != 0)
868 rc = ldap_modify_s(ldap_handle, distinguished_name, newvalue_array);
869 if (rc != LDAP_SUCCESS)
870 {
871 critical_alert("incremental",
872 "Couldn't process user %s: %s",
873 login_name, ldap_err2string(rc));
874 }
875 goto cleanup;
876 }
877 if ((operation == MEMBER_ACTIVATE) ||
878 (operation == MEMBER_DEACTIVATE))
879 {
880 sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
881 attr_array[0] = "UserAccountControl";
882 attr_array[1] = NULL;
883 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
884 &group_base, &group_count)) != 0)
885 goto cleanup;
886
887 if (group_count != 0)
888 {
889 ulongValue = atoi((*group_base).value);
890 if (operation == MEMBER_DEACTIVATE)
891 ulongValue |= UF_ACCOUNTDISABLE;
892 else
893 ulongValue &= ~UF_ACCOUNTDISABLE;
894 sprintf(temp, "%ld", ulongValue);
895 if ((rc = construct_newvalues(group_base, group_count,
896 newvalue_count, (*group_base).value,
897 temp, &newvalue_array, &modvalues,
898 REPLACE)) == 1)
899 goto cleanup;
900 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
901 newvalue_array[newvalue_count]->mod_type = "UserAccountControl";
902 newvalue_array[newvalue_count]->mod_values =
903 modvalues[newvalue_count];
904 ++newvalue_count;
905 rc = ldap_modify_s(ldap_handle, distinguished_name, newvalue_array);
906 if (rc != LDAP_SUCCESS)
907 {
908 critical_alert("incremental",
909 "Couldn't process user %s: %s",
910 login_name, ldap_err2string(rc));
911 }
912 }
913 goto cleanup;
914 }
915
916 sprintf(filter_exp, "(objectClass=group)");
917 attr_array[0] = "cn";
918 attr_array[1] = NULL;
919 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
920 &group_base, &group_count)) != 0)
921 goto cleanup;
922
923 sPtr = group_list;
924 while (sPtr != NULL)
925 {
926 gPtr = group_base;
927 while (gPtr != NULL)
928 {
929 if (!strcmp(sPtr->list, gPtr->value))
930 {
931 if (sPtr->dn != NULL)
932 free(sPtr->dn);
933 sPtr->dn = calloc(1, strlen(gPtr->dn) + 1);
934 memset(sPtr->dn, '\0', strlen(gPtr->dn) + 1);
935 strcpy(sPtr->dn, gPtr->dn);
936 if (sPtr->attribute != NULL)
937 free(sPtr->attribute);
938 sPtr->attribute = calloc(1, strlen(gPtr->attribute) + 1);
939 memset(sPtr->attribute, '\0', strlen(gPtr->attribute) + 1);
940 strcpy(sPtr->attribute, gPtr->attribute);
941 if (sPtr->value != NULL)
942 free(sPtr->value);
943 sPtr->value = calloc(1, strlen(gPtr->value) + 1);
944 memset(sPtr->value, '\0', strlen(gPtr->value) + 1);
945 strcpy(sPtr->value, gPtr->value);
946 break;
947 }
948 gPtr = gPtr->next;
949 }
950 sPtr = sPtr->next;
951 }
952
953 memberOf_count = 0;
954 memberOf_base = NULL;
955 sprintf(filter_exp, "(sAMAccountName=%s)", login_name);
956 attr_array[0] = "memberOf";
957 attr_array[1] = NULL;
958 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
959 &memberOf_base, &memberOf_count)) != 0)
960 goto cleanup;
961
962 processGroup_count = 0;
963 processGroup_base = NULL;
964 sPtr = group_list;
965 while (sPtr)
966 {
967 if (sPtr->dn == NULL)
968 {
969 sPtr = sPtr->next;
970 continue;
971 }
972 gPtr = memberOf_base;
973 while (gPtr)
974 {
975 if (!strcmp(gPtr->value, sPtr->dn))
976 break;
977 gPtr = gPtr->next;
978 }
979 if (sPtr->dn != NULL)
980 {
981 if (((gPtr == NULL) && (operation == MEMBER_ADD)) ||
982 ((gPtr != NULL) && (operation == MEMBER_REMOVE)))
983 {
984 gPtr = calloc(1, sizeof(LK_ENTRY));
985 memset(gPtr, '\0', sizeof(LK_ENTRY));
986 gPtr->attribute = calloc(1, strlen("member") + 1);
987 memset(gPtr->attribute, '\0', strlen("member") + 1);
988 strcpy(gPtr->attribute, "member");
989 gPtr->dn = calloc(1, strlen(sPtr->dn) + 1);
990 memset(gPtr->dn, '\0', strlen(sPtr->dn) + 1);
991 strcpy(gPtr->dn, sPtr->dn);
992 gPtr->value = calloc(1, strlen(distinguished_name) + 1);
993 memset(gPtr->value, '\0', strlen(distinguished_name) + 1);
994 strcpy(gPtr->value, distinguished_name);
995 if (processGroup_base != NULL)
996 gPtr->next = processGroup_base;
997 processGroup_base = gPtr;
998 gPtr = NULL;
999 ++processGroup_count;
1000 }
1001 }
1002 sPtr = sPtr->next;
1003 }
1004
1005 linklist_free(group_base);
1006 linklist_free(processGroup);
1007 group_base = NULL;
1008 processGroup = NULL;
1009 sPtr = processGroup_base;
1010 while (sPtr)
1011 {
1012 newvalue_count = 0;
1013 newvalue_array = NULL;
1014 modvalues = NULL;
1015 processGroup = NULL;
1016 if ((newvalue_array = calloc(1, (1+1) * sizeof(LDAPMod *))) == NULL)
1017 {
1018 rc = 1;
1019 goto cleanup;
1020 }
1021 newvalue_array[0] = NULL;
1022 newvalue_array[1] = NULL;
1023 if ((modvalues = calloc(1, (1+1) * sizeof(char **))) == NULL)
1024 {
1025 rc = 1;
1026 goto cleanup;
1027 }
1028 modvalues[0] = NULL;
1029 modvalues[1] = NULL;
1030
1031 if (operation == MEMBER_REMOVE)
1032 {
1033 processGroup_count = 0;
1034 processGroup = NULL;
1035 sprintf(filter_exp, "(distinguishedName=%s)", sPtr->dn);
1036 attr_array[0] = "member";
1037 attr_array[1] = NULL;
1038 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp,
1039 attr_array, &processGroup,
1040 &processGroup_count)) != 0)
1041 goto cleanup;
1042 gPtr = processGroup;
1043 pPtr = NULL;
1044 while (gPtr)
1045 {
1046 if (!strcmp(gPtr->value, sPtr->value))
1047 {
1048 if (pPtr != NULL)
1049 pPtr->next = gPtr->next;
1050 else
1051 processGroup = gPtr->next;
1052 gPtr->next = NULL;
1053 linklist_free(gPtr);
1054 --processGroup_count;
1055 break;
1056 }
1057 pPtr = gPtr;
1058 gPtr = gPtr->next;
1059 }
1060 if ((rc = construct_newvalues(processGroup, processGroup_count,
1061 newvalue_count, NULL, NULL,
1062 &newvalue_array, &modvalues,
1063 REPLACE)) == 1)
1064 goto cleanup;
1065 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_REPLACE ;
1066 pPtr = processGroup;
1067 }
1068 else
1069 {
1070 processGroup = calloc(1, sizeof(LK_ENTRY));
1071 memset(processGroup, '\0', sizeof(LK_ENTRY));
1072 memcpy(processGroup, sPtr, sizeof(LK_ENTRY));
1073 processGroup->next = NULL;
1074 processGroup_count = 1;
1075 if ((rc = construct_newvalues(processGroup, processGroup_count,
1076 newvalue_count, NULL, NULL,
1077 &newvalue_array, &modvalues,
1078 REPLACE)) == 1)
1079 goto cleanup;
1080 newvalue_array[newvalue_count]->mod_op = LDAP_MOD_ADD;
1081 pPtr = sPtr;
1082 }
1083 newvalue_array[newvalue_count]->mod_type = "member";
1084 newvalue_array[newvalue_count]->mod_values = modvalues[newvalue_count];
1085 rc = ldap_modify_s(ldap_handle, sPtr->dn, newvalue_array);
1086 if (operation == MEMBER_REMOVE)
1087 linklist_free(processGroup);
1088 else
1089 free(processGroup);
1090 processGroup = NULL;
1091 newvalue_count = 1;
1092 free_values(newvalue_count, newvalue_array, modvalues);
1093 newvalue_array = NULL;
1094 modvalues = NULL;
1095 if (rc != LDAP_SUCCESS)
1096 {
1097 critical_alert("incremental",
1098 "Couldn't process user %s: %s",
1099 login_name, ldap_err2string(rc));
1100 goto cleanup;
1101 }
1102 sPtr = sPtr->next;
1103 }
1104
1105 cleanup:
1106 free_values(newvalue_count, newvalue_array, modvalues);
1107 linklist_free(memberOf_base);
1108 linklist_free(group_base);
1109 linklist_free(processGroup_base);
1110 free(dn_path);
1111 if (rc == 1)
1112 critical_alert("incremental",
1113 "Couldn't process user %s: %s",
1114 login_name, "Cannot calloc - out of memory");
1115 return(rc);
1116}
1117
1118int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
1119 int newvalue_count, char *oldValue, char *newValue,
1120 LDAPMod ***newValueArray, char ****modvalues,
1121 int type)
1122{
1123 LK_ENTRY *linklist_ptr;
1124 int i;
1125 char *cPtr;
1126
1127 if (((*newValueArray)[newvalue_count] =
1128 calloc(1, sizeof(LDAPMod))) == NULL)
1129 return(1);
1130
1131 if (((*modvalues)[newvalue_count] =
1132 calloc(1, (modvalue_count + 1) * sizeof(char *))) == NULL)
1133 return(1);
1134
1135 for (i = 0; i < (modvalue_count + 1); i++)
1136 (*modvalues)[newvalue_count][i] = NULL;
1137 if (modvalue_count != 0)
1138 {
1139 linklist_ptr = linklist_base;
1140 for (i = 0; i < modvalue_count; i++)
1141 {
1142 if ((oldValue != NULL) && (newValue != NULL))
1143 {
1144 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1145 != (char *)NULL)
1146 {
1147 if (type == REPLACE)
1148 {
1149 if (((*modvalues)[newvalue_count][i] =
1150 calloc(1, strlen(newValue) + 1)) == NULL)
1151 return(1);
1152 memset((*modvalues)[newvalue_count][i], '\0',
1153 strlen(newValue) + 1);
1154 strcpy((*modvalues)[newvalue_count][i], newValue);
1155 }
1156 else
1157 {
1158 if (((*modvalues)[newvalue_count][i] =
1159 calloc(1, (int)(cPtr - linklist_ptr->value) +
1160 (linklist_ptr->length - strlen(oldValue)) +
1161 strlen(newValue) + 1)) == NULL)
1162 return(1);
1163 memset((*modvalues)[newvalue_count][i], '\0',
1164 (int)(cPtr - linklist_ptr->value) +
1165 (linklist_ptr->length - strlen(oldValue)) +
1166 strlen(newValue) + 1);
1167 memcpy((*modvalues)[newvalue_count][i],
1168 linklist_ptr->value,
1169 (int)(cPtr - linklist_ptr->value));
1170 strcat((*modvalues)[newvalue_count][i], newValue);
1171 strcat((*modvalues)[newvalue_count][i],
1172 &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]);
1173 }
1174 }
1175 else
1176 {
1177 (*modvalues)[newvalue_count][i] =
1178 calloc(1, linklist_ptr->length + 1);
1179 memset((*modvalues)[newvalue_count][i],
1180 '\0', linklist_ptr->length + 1);
1181 memcpy((*modvalues)[newvalue_count][i],
1182 linklist_ptr->value, linklist_ptr->length);
1183 }
1184 }
1185 else
1186 {
1187 (*modvalues)[newvalue_count][i] =
1188 calloc(1, linklist_ptr->length + 1);
1189 memset((*modvalues)[newvalue_count][i], '\0',
1190 linklist_ptr->length + 1);
1191 memcpy((*modvalues)[newvalue_count][i], linklist_ptr->value,
1192 linklist_ptr->length);
1193 }
1194 linklist_ptr = linklist_ptr->next;
1195 }
1196 (*modvalues)[newvalue_count][i] = NULL;
1197 }
1198 return(0);
1199}
1200
1201int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
1202 char **attr_array, LK_ENTRY **linklist_base,
1203 int *linklist_count)
1204{
1205 ULONG rc = 0;
1206 LDAPMessage *ldap_entry;
1207
1208 ldap_entry = NULL;
1209 (*linklist_base) = NULL;
1210 (*linklist_count) = 0;
1211 if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE,
1212 search_exp, attr_array, 0, &ldap_entry))
1213 != LDAP_SUCCESS)
1214 return(0);
1215 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base,
1216 linklist_count);
1217
1218 ldap_msgfree(ldap_entry);
1219 return(rc);
1220}
1221
1222int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1223 LK_ENTRY **linklist_base, int *linklist_count)
1224{
1225 char distinguished_name[1024];
1226 LK_ENTRY *linklist_ptr;
1227 int rc;
1228
1229 memset(distinguished_name, '\0', sizeof(distinguished_name));
1230 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1231
1232 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1233 return(0);
1234
1235 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1236 linklist_base)) != 0)
1237 return(rc);
1238
1239 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1240 {
1241 if ((rc = retrieve_attributes(ldap_handle, ldap_entry,
1242 distinguished_name, linklist_base)) != 0)
1243 return(rc);
1244 }
1245
1246 linklist_ptr = (*linklist_base);
1247 (*linklist_count) = 0;
1248 while (linklist_ptr != NULL)
1249 {
1250 ++(*linklist_count);
1251 linklist_ptr = linklist_ptr->next;
1252 }
1253 return(0);
1254}
1255
1256int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1257 char *distinguished_name, LK_ENTRY **linklist_current)
1258{
1259 char *Attribute;
1260 BerElement *ptr;
1261
1262 ptr = NULL;
1263 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr))
1264 != NULL)
1265 {
1266 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1267 linklist_current);
1268 ldap_memfree(Attribute);
1269 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry, ptr))
1270 != NULL)
1271 {
1272 retrieve_values(ldap_handle, ldap_entry, Attribute,
1273 distinguished_name, linklist_current);
1274 ldap_memfree(Attribute);
1275 }
1276 }
1277 return(0);
1278}
1279
1280int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1281 char *Attribute, char *distinguished_name,
1282 LK_ENTRY **linklist_current)
1283{
1284 char **str_value;
1285 char temp[256];
1286 void **Ptr;
1287 int use_bervalue;
1288 LK_ENTRY *linklist_previous;
1289 LDAP_BERVAL **ber_value;
1290 DWORD ber_length;
1291#ifdef LDAP_DEBUG
1292 SID *sid;
1293 GUID *guid;
1294 int i;
1295 int intValue;
1296 DWORD *subauth;
1297 SID_IDENTIFIER_AUTHORITY *sid_auth;
1298 unsigned char *subauth_count;
1299#endif /*LDAP_DEBUG*/
1300
1301 use_bervalue = 0;
1302 memset(temp, '\0', sizeof(temp));
1303 if ((!strcmp(Attribute, "objectSid")) ||
1304 (!strcmp(Attribute, "objectGUID")))
1305 use_bervalue = 1;
1306
1307 if (use_bervalue)
1308 {
1309 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1310 Ptr = (void **)ber_value;
1311 str_value = NULL;
1312 }
1313 else
1314 {
1315 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1316 Ptr = (void **)str_value;
1317 ber_value = NULL;
1318 }
1319 if (Ptr != NULL)
1320 {
1321 for (; *Ptr; Ptr++)
1322 {
1323 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
1324 return(1);
1325 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
1326 linklist_previous->next = (*linklist_current);
1327 (*linklist_current) = linklist_previous;
1328
1329 if (((*linklist_current)->attribute =
1330 calloc(1, strlen(Attribute) + 1)) == NULL)
1331 return(1);
1332 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
1333 strcpy((*linklist_current)->attribute, Attribute);
1334 if (use_bervalue)
1335 {
1336 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
1337 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
1338 return(1);
1339 memset((*linklist_current)->value, '\0', ber_length);
1340 memcpy((*linklist_current)->value,
1341 (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length);
1342 (*linklist_current)->length = ber_length;
1343 }
1344 else
1345 {
1346 if (((*linklist_current)->value = calloc(1, strlen(*Ptr) + 1))
1347 == NULL)
1348 return(1);
1349 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
1350 (*linklist_current)->length = strlen(*Ptr);
1351 strcpy((*linklist_current)->value, *Ptr);
1352 }
1353 (*linklist_current)->ber_value = use_bervalue;
1354 if (((*linklist_current)->dn =
1355 calloc(1, strlen(distinguished_name) + 1)) == NULL)
1356 return(1);
1357 memset((*linklist_current)->dn, '\0',
1358 strlen(distinguished_name) + 1);
1359 strcpy((*linklist_current)->dn, distinguished_name);
1360
1361#ifdef LDAP_DEBUG
1362 if (!strcmp(Attribute, "objectGUID"))
1363 {
1364 guid = (GUID *)((*linklist_current)->value);
1365 sprintf(temp,
1366 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1367 guid->Data1, guid->Data2, guid->Data3,
1368 guid->Data4[0], guid->Data4[1], guid->Data4[2],
1369 guid->Data4[3], guid->Data4[4], guid->Data4[5],
1370 guid->Data4[6], guid->Data4[7]);
1371 print_to_screen(" %20s : {%s}\n", Attribute, temp);
1372 }
1373 else if (!strcmp(Attribute, "objectSid"))
1374 {
1375 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
1376#ifdef _WIN32
1377 print_to_screen(" Revision = %d\n", sid->Revision);
1378 print_to_screen(" SID Identifier Authority:\n");
1379 sid_auth = &sid->IdentifierAuthority;
1380 if (sid_auth->Value[0])
1381 print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
1382 else if (sid_auth->Value[1])
1383 print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
1384 else if (sid_auth->Value[2])
1385 print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
1386 else if (sid_auth->Value[3])
1387 print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
1388 else if (sid_auth->Value[5])
1389 print_to_screen(" SECURITY_NT_AUTHORITY\n");
1390 else
1391 print_to_screen(" UNKNOWN SID AUTHORITY\n");
1392 subauth_count = GetSidSubAuthorityCount(sid);
1393 print_to_screen(" SidSubAuthorityCount = %d\n",
1394 *subauth_count);
1395 print_to_screen(" SidSubAuthority:\n");
1396 for (i = 0; i < *subauth_count; i++)
1397 {
1398 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
1399 print_to_screen(" %u\n", *subauth);
1400 }
1401#endif
1402 }
1403 else if ((!memcmp(Attribute, "userAccountControl",
1404 strlen("userAccountControl"))) ||
1405 (!memcmp(Attribute, "sAMAccountType",
1406 strlen("sAmAccountType"))))
1407 {
1408 intValue = atoi(*Ptr);
1409 print_to_screen(" %20s : %ld\n",Attribute, intValue);
1410 if (!memcmp(Attribute, "userAccountControl",
1411 strlen("userAccountControl")))
1412 {
1413 if (intValue & UF_ACCOUNTDISABLE)
1414 print_to_screen(" %20s : %s\n", "",
1415 "Account disabled");
1416 else
1417 print_to_screen(" %20s : %s\n", "",
1418 "Account active");
1419 if (intValue & UF_HOMEDIR_REQUIRED)
1420 print_to_screen(" %20s : %s\n", "",
1421 "Home directory required");
1422 if (intValue & UF_LOCKOUT)
1423 print_to_screen(" %20s : %s\n", "",
1424 "Account locked out");
1425 if (intValue & UF_PASSWD_NOTREQD)
1426 print_to_screen(" %20s : %s\n", "",
1427 "No password required");
1428 if (intValue & UF_PASSWD_CANT_CHANGE)
1429 print_to_screen(" %20s : %s\n", "",
1430 "Cannot change password");
1431 if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
1432 print_to_screen(" %20s : %s\n", "",
1433 "Temp duplicate account");
1434 if (intValue & UF_NORMAL_ACCOUNT)
1435 print_to_screen(" %20s : %s\n", "",
1436 "Normal account");
1437 if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
1438 print_to_screen(" %20s : %s\n", "",
1439 "Interdomain trust account");
1440 if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
1441 print_to_screen(" %20s : %s\n", "",
1442 "Workstation trust account");
1443 if (intValue & UF_SERVER_TRUST_ACCOUNT)
1444 print_to_screen(" %20s : %s\n", "",
1445 "Server trust account");
1446 }
1447 }
1448 else
1449 {
1450 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
1451 }
1452#endif /*LDAP_DEBUG*/
1453 }
1454 if (str_value != NULL)
1455 ldap_value_free(str_value);
1456 if (ber_value != NULL)
1457 ldap_value_free_len(ber_value);
1458 }
1459 (*linklist_current) = linklist_previous;
1460 return(0);
1461}
1462
1463int add_user_lists(int ac, char **av, void *user)
1464{
1465 if (atoi(av[L_ACTIVE]) && atoi(av[L_GROUP])) /* active group ? */
1466 edit_group(1, av[L_NAME], "USER", user, NULL, NULL, NULL);
1467 return 0;
1468}
1469
1470void edit_group(int op, char *group, char *type, char *member,
1471 LDAP *ldap_handle, char *dn_path, char *ldap_hostname)
1472{
1473 ULONG rc;
1474 char *p = 0;
1475 char search_exp[128];
1476 static char local_realm[REALM_SZ+1] = "";
1477 LK_ENTRY *linklist;
1478 LDAPMessage *ldap_entry;
1479
1480 /* The following KERBEROS rc allows for the use of entities
1481 * user@foreign_cell.
1482 */
1483 if (!local_realm[0])
1484 krb_get_lrealm(local_realm, 1);
1485 if (!strcmp(type, "KERBEROS"))
1486 {
1487 p = (char *)strchr(member, '@');
1488 if (p && !strcasecmp(p+1, local_realm))
1489 *p = 0;
1490 }
1491 else if (strcmp(type, "USER"))
1492 return; /* invalid type */
1493
1494 /* Cannot risk doing another query during a callback */
1495 /* We could do this simply for type USER, but eventually this may also
1496 * dynamically add KERBEROS types to the prdb, and we will need to do
1497 * a query to look up the uid of the null-instance user
1498 */
1499 if (mr_connections)
1500 {
1501 linklist = calloc(1, sizeof(LK_ENTRY));
1502 if (!linklist)
1503 {
1504 critical_alert("incremental", "Out of memory");
1505 exit(1);
1506 }
1507 memset(linklist, '\0', sizeof(LK_ENTRY));
1508 linklist->op = op;
1509 linklist->dn = NULL;
1510 linklist->list = calloc(1, strlen(group) + 1);
1511 memset(linklist->list, '\0', strlen(group) + 1);
1512 strcpy(linklist->list, group);
1513 linklist->type = calloc(1, strlen(type) + 1);
1514 memset(linklist->type, '\0', strlen(type) + 1);
1515 strcpy(linklist->type, type);
1516 linklist->member = calloc(1, strlen(member) + 1);
1517 memset(linklist->member, '\0', strlen(member) + 1);
1518 strcpy(linklist->member, member);
1519 linklist->next = member_base;
1520 member_base = linklist;
1521 return;
1522 }
1523
1524 com_err(whoami, 0, "%s %s %s group %s", (op ? "Adding" : "Removing"),
1525 member, (op ? "to" : "from"), group);
1526 sprintf(search_exp, "(sAMAccountName=%s)", member);
1527 if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE,
1528 search_exp, NULL, 0, &ldap_entry)) != LDAP_SUCCESS)
1529 {
1530 critical_alert("incremental", "Couldn't %s %s %s %s",
1531 op ? "add" : "remove", member,
1532 op ? "to" : "from", group);
1533 rc = ldap_msgfree(ldap_entry);
1534 return;
1535 }
1536 linklist = calloc(1, sizeof(LK_ENTRY));
1537 if (!linklist)
1538 {
1539 critical_alert("incremental", "Out of memory");
1540 exit(1);
1541 }
1542 memset(linklist, '\0', sizeof(LK_ENTRY));
1543 linklist->op = op;
1544 linklist->dn = NULL;
1545 linklist->list = calloc(1, strlen(group) + 1);
1546 memset(linklist->list, '\0', strlen(group) + 1);
1547 strcpy(linklist->list, group);
1548 linklist->type = calloc(1, strlen(type) + 1);
1549 memset(linklist->type, '\0', strlen(type) + 1);
1550 strcpy(linklist->type, type);
1551 linklist->member = calloc(1, strlen(member) + 1);
1552 memset(linklist->member, '\0', strlen(member) + 1);
1553 strcpy(linklist->member, member);
1554 linklist->next = NULL;
1555
1556 rc = member_update(ldap_handle, dn_path, ldap_entry, member, NULL,
1557 ldap_hostname, op ? MEMBER_ADD : MEMBER_REMOVE, linklist);
1558 if (rc)
1559 {
1560 critical_alert("incremental", "Couldn't %s %s %s %s: %s",
1561 op ? "add" : "remove", member,
1562 op ? "to" : "from", group);
1563 }
1564
1565 linklist_free(linklist);
1566 rc = ldap_msgfree(ldap_entry);
1567 /*
1568 * rc = pr_try(op ? pr_AddToGroup : pr_RemoveUserFromGroup, member, buf);
1569 * if (rc)
1570 * {
1571 * if (op==1 && rc == PRIDEXIST)
1572 * return;
1573 * if (rc == PRNOENT)
1574 * {
1575 * if (op == 0)
1576 * return;
1577 * if (!strcmp(type, "KERBEROS"))
1578 * return;
1579 * rc = moira_connect();
1580 * if (!rc)
1581 * {
1582 * rc = mr_query("get_user_by_login", 1, &member,
1583 * (void *)check_user, (char *) &ustate);
1584 * }
1585 * if (rc)
1586 * {
1587 * critical_alert("incremental", "Error contacting Moira server "
1588 * "to lookup user %s: %s", member,
1589 * error_message(rc));
1590 * }
1591 * mr_disconnect();
1592 * mr_connections--;
1593 * if (!rc && ustate!=1 && ustate!=2)
1594 * return;
1595 * rc = PRNOENT;
1596 * }
1597 * critical_alert("incremental", "Couldn't %s %s %s %s: %s",
1598 * op ? "add" : "remove", member,
1599 * op ? "to" : "from", buf,
1600 * error_message(rc));
1601 * }
1602 */
1603}
1604
1605int moira_connect(void)
1606{
1607 long rc;
1608 char HostName[64];
1609
1610 if (!mr_connections++)
1611 {
1612#ifdef _WIN32
1613 memset(HostName, '\0', sizeof(HostName));
1614 strcpy(HostName, "ttsp");
1615 rc = mr_connect(HostName);
1616#else
1617 struct utsname uts;
1618 uname(&uts);
1619 rc = mr_connect(uts.nodename);
1620#endif /*WIN32*/
1621 if (!rc)
1622 rc = mr_auth("afs.incr");
1623 return rc;
1624 }
1625 return 0;
1626}
1627
1628int moira_disconnect(void)
1629{
1630 if (!--mr_connections)
1631 mr_disconnect();
1632 return 0;
1633}
1634
1635int add_list_members(int ac, char **av, void *group)
1636{
1637 edit_group(1, group, av[0], av[1], NULL, NULL, NULL);
1638 return 0;
1639}
1640
1641int check_user(int ac, char **av, void *ustate)
1642{
1643 *(int *)ustate = atoi(av[U_STATE]);
1644 return 0;
1645}
1646
1647void free_values(int newvalue_count, LDAPMod **newvalue_array,
1648 char ***modvalues)
1649{
1650 int i, j;
1651
1652 if (newvalue_array != NULL)
1653 {
1654 i = 0;
1655 while (newvalue_array[i] != NULL)
1656 {
1657 free(newvalue_array[i]);
1658 newvalue_array[i]= NULL;
1659 ++i;
1660 }
1661 free(newvalue_array);
1662 newvalue_array = NULL;
1663 }
1664 if (modvalues != NULL)
1665 {
1666 i = 0;
1667 while (modvalues[i] != NULL)
1668 {
1669 j = 0;
1670 while (modvalues[i][j] != NULL)
1671 {
1672 free(modvalues[i][j]);
1673 modvalues[i][j] = NULL;
1674 ++j;
1675 }
1676 free(modvalues[i]);
1677 modvalues[i] = NULL;
1678 ++i;
1679 }
1680 free(modvalues);
1681 modvalues = NULL;
1682 }
1683}
1684
1685void linklist_free(LK_ENTRY *linklist_base)
1686{
1687 LK_ENTRY *linklist_previous;
1688
1689 while (linklist_base != NULL)
1690 {
1691 if (linklist_base->dn != NULL)
1692 free(linklist_base->dn);
1693 if (linklist_base->attribute != NULL)
1694 free(linklist_base->attribute);
1695 if (linklist_base->value != NULL)
1696 free(linklist_base->value);
1697 if (linklist_base->member != NULL)
1698 free(linklist_base->member);
1699 if (linklist_base->type != NULL)
1700 free(linklist_base->type);
1701 if (linklist_base->list != NULL)
1702 free(linklist_base->list);
1703 linklist_previous = linklist_base;
1704 linklist_base = linklist_previous->next;
1705 free(linklist_previous);
1706 }
1707}
1708
1709int convert_domain_to_dn(char *domain, char **dnp)
1710{
1711 char *fp, *dp;
1712 char dn[1024];
1713 int dnlen = 1;
1714
1715 memset(dn, 0, sizeof(dn));
1716 strcpy(dn, "dc=");
1717 dp = dn+3;
1718 for (fp = domain; *fp; fp++)
1719 {
1720 if (*fp == '.')
1721 {
1722 strcpy(dp, ",dc=");
1723 dp += 4;
1724 }
1725 else
1726 *dp++ = *fp;
1727 }
1728
1729 *dnp = (char *)strdup(dn);
1730 return 0;
1731}
1732
1733void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1734 char *distinguished_name)
1735{
1736 char *CName;
1737
1738 CName = ldap_get_dn(ldap_handle, ldap_entry);
1739 if (CName == NULL)
1740 return;
1741 strcpy(distinguished_name, CName);
1742 ldap_memfree(CName);
1743}
1744
1745int linklist_create_entry(char *attribute, char *value,
1746 LK_ENTRY **linklist_entry)
1747{
1748 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
1749 if (!(*linklist_entry))
1750 {
1751 return(1);
1752 }
1753 memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
1754 (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
1755 memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
1756 strcpy((*linklist_entry)->attribute, attribute);
1757 (*linklist_entry)->value = calloc(1, strlen(value) + 1);
1758 memset((*linklist_entry)->value, '\0', strlen(value) + 1);
1759 strcpy((*linklist_entry)->value, value);
1760 (*linklist_entry)->length = strlen(value);
1761 (*linklist_entry)->next = NULL;
1762 return(0);
1763}
1764
1765void print_to_screen(const char *fmt, ...)
1766{
1767 va_list pvar;
1768
1769 va_start(pvar, fmt);
1770 vfprintf(stderr, fmt, pvar);
1771 fflush(stderr);
1772 va_end(pvar);
1773}
This page took 0.287161 seconds and 5 git commands to generate.