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