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