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