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
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
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
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
19 * test parameters for add member to group/list
20 * imembers 0 5 pismere-team USER dtanner 1 1
21 * note: the group the group will be created if it does not exist in the AD.
23 * test parameters for remove member from group/list
24 * imembers 5 0 pismere-team USER dtanner 1 1
26 * test parameters for creating and/or populating a group/list - done
27 * list 0 7 pismere-team 1 0 1 1 1 760
29 * test parameters for deleting a group/list - done
30 * list 7 0 pismere-team 1 0 1 1 1 760
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
36 #include <mit-copyright.h>
48 #include <moira_site.h>
58 #define ECONNABORTED WSAECONNABORTED
61 #define ECONNREFUSED WSAECONNREFUSED
64 #define EHOSTUNREACH WSAEHOSTUNREACH
66 #define krb5_xfree free
70 #include <sys/utsname.h>
72 #define UCHAR unsigned char
74 #define UF_SCRIPT 0x0001
75 #define UF_ACCOUNTDISABLE 0x0002
76 #define UF_HOMEDIR_REQUIRED 0x0008
77 #define UF_LOCKOUT 0x0010
78 #define UF_PASSWD_NOTREQD 0x0020
79 #define UF_PASSWD_CANT_CHANGE 0x0040
80 #define UF_DONT_EXPIRE_PASSWD 0x10000
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
89 #define BYTE unsigned char
91 typedef unsigned int DWORD;
92 typedef unsigned long ULONG;
99 unsigned char Data4[8];
102 typedef struct _SID_IDENTIFIER_AUTHORITY {
104 } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
106 typedef struct _SID {
108 BYTE SubAuthorityCount;
109 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
110 DWORD SubAuthority[512];
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
120 #define QUERY_VERSION -1
121 #define PRIMARY_REALM "ATHENA.MIT.EDU"
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
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
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
163 #define MEMBER_REMOVE 2
164 #define MEMBER_CHANGE_NAME 3
165 #define MEMBER_ACTIVATE 4
166 #define MEMBER_DEACTIVATE 5
167 #define MEMBER_CREATE 6
169 #define GROUP_CREATE 1
170 #define GROUP_DELETE 2
171 #define GROUP_MOVE_MEMBERS 3
172 #define GROUP_UPDATE_MEMBERS 4
174 typedef struct lk_entry {
184 struct lk_entry *next;
187 #define LDAP_BERVAL struct berval
188 #define MAX_SERVER_NAMES 32
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
196 LK_ENTRY *member_base = NULL;
197 LK_ENTRY *sid_base = NULL;
198 LK_ENTRY **sid_ptr = NULL;
199 char kerberos_ou[] = "OU=kerberos, OU=moira, OU=athena";
200 char contact_ou[] = "OU=strings, OU=moira, OU=athena";
201 char user_ou[] = "OU=users, OU=moira, OU=athena";
202 char group_ou_distribution[] = "OU=distribution, OU=lists, OU=moira, OU=athena";
203 char group_ou_security[] = "OU=security, OU=lists, OU=moira, OU=athena";
204 char group_ou_neither[] = "OU=neither, OU=lists, OU=moira, OU=athena";
205 char group_ou_both[] = "OU=both, OU=lists, OU=moira, OU=athena";
206 char group_ou_root[] = "OU=lists, OU=moira, OU=athena";
208 char group_manager[64];
209 char ldap_domain[256];
215 int mr_connections = 0;
217 extern int locate_ldap_server(char *domain, char *server_name[]);
218 extern int set_password(char *user, char *domain);
220 int user_create(int ac, char **av, void *ptr);
221 int user_change_status(int ac, char **av, void *ptr);
222 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name);
223 int user_rename(int ac, char **av, void *ptr);
224 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
225 int get_group_info(int ac, char**av, void *ptr);
226 int group_create(int ac, char **av, void *ptr);
227 int group_delete(int ac, char **av, void *ptr);
228 int group_ad_delete(LDAP *ldap_handle, char *dn_path, char *group_gid);
229 int group_list_build(int ac, char **av, void *ptr);
230 int group_rename(int ac, char **av, void *ptr);
231 int member_list_build(int ac, char **av, void *ptr);
232 int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name,
233 char *group_ou, char *group_membership, char *group_gid);
234 int sid_update(LDAP *ldap_handle, char *dn_path);
235 int check_string(char *s);
236 void convert_b_to_a(char *string, UCHAR *binary, int length);
237 int mr_connect_cl(char *server, char *client, int version, int auth);
239 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
240 char **before, int beforec, char **after, int afterc);
241 void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
242 char *dn_path, char **before, int beforec, char **after,
244 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
245 char **before, int beforec, char **after, int afterc);
246 int linklist_create_entry(char *attribute, char *value,
247 LK_ENTRY **linklist_entry);
248 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
249 char **attr_array, LK_ENTRY **linklist_base,
250 int *linklist_count);
251 void linklist_free(LK_ENTRY *linklist_base);
253 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
254 char *distinguished_name, LK_ENTRY **linklist_current);
255 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
256 LK_ENTRY **linklist_base, int *linklist_count);
257 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
258 char *Attribute, char *distinguished_name,
259 LK_ENTRY **linklist_current);
261 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
262 char *oldValue, char *newValue,
263 char ***modvalues, int type);
264 void free_values(char **modvalues);
266 int convert_domain_to_dn(char *domain, char **bind_path);
267 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
268 char *distinguished_name);
269 int moira_disconnect(void);
270 int moira_connect(void);
271 void print_to_screen(const char *fmt, ...);
273 int main(int argc, char **argv)
278 int Max_wait_time = 500;
279 int Max_size_limit = LDAP_NO_LIMIT;
285 char search_exp[1024];
286 char *server_name[MAX_SERVER_NAMES];
287 ULONG version = LDAP_VERSION3;
289 LDAPMessage *ldap_entry;
292 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
296 com_err(whoami, 0, "%s", "argc < 4");
299 beforec = atoi(argv[2]);
300 afterc = atoi(argv[3]);
302 if (argc < (4 + beforec + afterc))
304 com_err(whoami, 0, "%s", "argc < (4 + breforec + afterc)");
310 after = &argv[4 + beforec];
312 memset(ldap_domain, '\0', sizeof(ldap_domain));
313 if ((fptr = fopen("winad.cfg", "r")) != NULL)
315 fread(ldap_domain, sizeof(char), sizeof(ldap_domain), fptr);
318 if (strlen(ldap_domain) == 0)
319 strcpy(ldap_domain, "win.mit.edu");
320 initialize_sms_error_table();
321 initialize_krb_error_table();
323 memset(search_exp, '\0', sizeof(search_exp));
326 convert_domain_to_dn(ldap_domain, &dn_path);
329 com_err(whoami, 0, "%s", "cannot create AD path");
332 memset(server_name, '\0', sizeof(server_name[0]) * MAX_SERVER_NAMES);
333 if (locate_ldap_server(ldap_domain, server_name) == -1)
335 com_err(whoami, 0, "%s %s", "cannot locate any server in domain ",
340 for (i = 0; i < MAX_SERVER_NAMES; i++)
342 if (server_name[i] != NULL)
344 if ((ldap_handle = ldap_open(server_name[i], LDAP_PORT)) != NULL)
350 if (i >= MAX_SERVER_NAMES)
352 com_err(whoami, 0, "%s %s", "cannot connect to any server in domain ",
356 for (i = 0; i < MAX_SERVER_NAMES; i++)
358 if (server_name[i] != NULL)
359 free(server_name[i]);
361 rc = ldap_set_option(ldap_handle, LDAP_OPT_PROTOCOL_VERSION, &version);
362 rc = ldap_set_option(ldap_handle, LDAP_OPT_TIMELIMIT,
363 (void *)&Max_wait_time);
364 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT,
365 (void *)&Max_size_limit);
366 rc = ldap_set_option(ldap_handle, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
367 rc = ldap_adgssapi_bind(ldap_handle, dn_path, GSSSASL_PRIVACY_PROTECTION);
368 if (rc != LDAP_SUCCESS)
371 for (i = 0; i < (int)strlen(table); i++)
372 table[i] = tolower(table[i]);
373 if (!strcmp(table, "users"))
374 do_user(ldap_handle, ldap_entry, ldap_domain, dn_path, before, beforec,
376 else if (!strcmp(table, "list"))
377 do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
379 else if (!strcmp(table, "imembers"))
380 do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
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);
388 rc = ldap_unbind_s(ldap_handle);
393 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
394 char **before, int beforec, char **after, int afterc)
409 if (beforec == 0 && afterc == 0)
414 apublic = bpublic = 0;
415 amaillist = bmailist = 0;
416 if (beforec > BEFORE_L_GROUP)
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]);
423 if (afterc > AFTER_L_GROUP)
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]);
431 if (rc = moira_connect())
433 critical_alert("AD incremental",
434 "Error contacting Moira server: %s",
439 if (beforec && afterc)
441 if (strcmp(after[AFTER_L_NAME], before[BEFORE_L_NAME]))
443 com_err(whoami, 0, "Changing group %s to %s",
444 before[BEFORE_L_NAME], after[AFTER_L_NAME]);
446 av[0] = after[AFTER_L_NAME];
447 call_args[0] = (char *)ldap_handle;
448 call_args[1] = dn_path;
449 call_args[2] = before[BEFORE_L_NAME];
453 if (rc = mr_query("get_list_info", 1, av, group_rename, call_args))
455 critical_alert("AD incremental", "Couldn't find group %s ",
456 after[AFTER_L_NAME]);
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]);
470 com_err(whoami, 0, "Creating group %s", after[AFTER_L_NAME]);
472 av[0] = after[AFTER_L_NAME];
473 call_args[0] = (char *)ldap_handle;
474 call_args[1] = dn_path;
475 call_args[2] = after[AFTER_L_NAME];
481 rc = mr_query("get_list_info", 1, av, group_create, call_args);
482 if ((rc) && (rc != LDAP_ALREADY_EXISTS))
484 critical_alert("AD incremental", "Couldn't create group %s",
485 after[AFTER_L_NAME]);
488 if (sid_base != NULL)
490 sid_update(ldap_handle, dn_path);
491 linklist_free(sid_base);
496 if (!(rc = mr_query("get_members_of_list", 1, av, member_list_build,
499 rc = member_list_process(ldap_handle, dn_path, after[AFTER_L_NAME],
500 call_args[3], call_args[4], call_args[5]);
504 critical_alert("AD incremental",
505 "Error contacting Moira server to resolve %s: %s",
506 after[AFTER_L_NAME], error_message(rc));
508 linklist_free(member_base);
515 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
516 char **before, int beforec, char **after, int afterc)
520 char group_name[128];
528 if (!atoi(after[AFTER_LM_EXTRA_ACTIVE]) || !atoi(after[AFTER_LM_EXTRA_GROUP]))
530 strcpy(user_name, after[AFTER_LM_MEMBER]);
531 strcpy(group_name, after[AFTER_LM_LIST]);
532 strcpy(user_type, after[AFTER_LM_TYPE]);
537 if (!atoi(before[BEFORE_LM_EXTRA_ACTIVE]) || !atoi(before[BEFORE_LM_EXTRA_GROUP]))
539 strcpy(user_name, before[BEFORE_LM_MEMBER]);
540 strcpy(group_name, before[BEFORE_LM_LIST]);
541 strcpy(user_type, before[AFTER_LM_TYPE]);
543 for (i = 0; i < (int)strlen(user_type); i++)
544 user_type[i] = tolower(user_type[i]);
545 if (strcmp(user_type, "user"))
548 if (rc = moira_connect())
550 critical_alert("AD incremental",
551 "Moira error retrieving grouplist of user %s: %s",
552 user_name, error_message(rc));
556 call_args[0] = (char *)ldap_handle;
557 call_args[1] = dn_path;
558 call_args[2] = group_name;
565 if (!(rc = mr_query("get_list_info", 1, av, group_create, call_args)))
567 if (sid_base != NULL)
569 sid_update(ldap_handle, dn_path);
570 linklist_free(sid_base);
572 if (!(rc = mr_query("get_members_of_list", 1, av, member_list_build,
575 rc = member_list_process(ldap_handle, dn_path, group_name,
576 call_args[3], call_args[4], call_args[5]);
582 critical_alert("AD incremental", "Couldn't add %s to group %s ",
583 user_name, group_name);
585 critical_alert("AD incremental", "Couldn't remove %s from group %s ",
586 user_name, group_name);
588 linklist_free(member_base);
589 if (call_args[3] != NULL)
591 if (call_args[4] != NULL)
597 void do_user(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *ldap_hostname,
598 char *dn_path, char **before, int beforec, char **after,
605 if (rc = moira_connect())
607 critical_alert("AD incremental",
608 "Error connection to Moira: %s",
613 if ((beforec != 0) && (afterc != 0))
615 if (beforec != afterc)
617 if (!strcmp(before[BEFORE_U_NAME], after[AFTER_U_NAME]))
619 com_err(whoami, 0, "Changing user %s to %s", before[BEFORE_U_NAME],
620 after[AFTER_U_NAME]);
621 av[0] = after[AFTER_U_NAME];
622 call_args[0] = (char *)ldap_handle;
623 call_args[1] = dn_path;
624 call_args[2] = (char *)MEMBER_ACTIVATE;
625 call_args[3] = before[BEFORE_U_NAME];
628 if (rc = mr_query("get_user_account_by_login", 1, av, user_rename,
631 critical_alert("AD incremental",
632 "Couldn't change user name for %s to %s",
633 before[BEFORE_U_NAME], after[AFTER_U_NAME]);
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,
648 critical_alert("AD incremental",
649 "Couldn't deactivate user %s in the AD",
650 before[BEFORE_U_NAME]);
656 com_err(whoami, 0, "%s user %s", "Creating/Reactivating",
657 after[AFTER_U_NAME]);
659 av[0] = after[AFTER_U_NAME];
660 call_args[0] = (char *)ldap_handle;
661 call_args[1] = dn_path;
662 call_args[2] = (char *)MEMBER_ACTIVATE;
666 if (rc = mr_query("get_user_account_by_login", 1, av, user_create,
669 critical_alert("AD incremental", "Couldn't activate user %s",
670 after[AFTER_U_NAME]);
673 if (sid_base != NULL)
675 sid_update(ldap_handle, dn_path);
676 linklist_free(sid_base);
683 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
684 char *oldValue, char *newValue,
685 char ***modvalues, int type)
687 LK_ENTRY *linklist_ptr;
691 if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *)))
696 for (i = 0; i < (modvalue_count + 1); i++)
697 (*modvalues)[i] = NULL;
698 if (modvalue_count != 0)
700 linklist_ptr = linklist_base;
701 for (i = 0; i < modvalue_count; i++)
703 if ((oldValue != NULL) && (newValue != NULL))
705 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
710 if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
713 memset((*modvalues)[i], '\0', strlen(newValue) + 1);
714 strcpy((*modvalues)[i], newValue);
718 if (((*modvalues)[i] = calloc(1,
719 (int)(cPtr - linklist_ptr->value) +
720 (linklist_ptr->length - strlen(oldValue)) +
721 strlen(newValue) + 1)) == NULL)
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)]);
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);
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);
749 linklist_ptr = linklist_ptr->next;
751 (*modvalues)[i] = NULL;
757 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
758 char **attr_array, LK_ENTRY **linklist_base,
762 LDAPMessage *ldap_entry;
766 (*linklist_base) = NULL;
767 (*linklist_count) = 0;
768 if ((rc = ldap_search_s(ldap_handle, dn_path, LDAP_SCOPE_SUBTREE,
769 search_exp, attr_array, 0, &ldap_entry))
772 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count);
774 ldap_msgfree(ldap_entry);
779 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
780 LK_ENTRY **linklist_base, int *linklist_count)
782 char distinguished_name[1024];
783 LK_ENTRY *linklist_ptr;
786 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
789 memset(distinguished_name, '\0', sizeof(distinguished_name));
790 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
792 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
793 linklist_base)) != 0)
796 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
798 memset(distinguished_name, '\0', sizeof(distinguished_name));
799 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
801 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
802 linklist_base)) != 0)
806 linklist_ptr = (*linklist_base);
807 (*linklist_count) = 0;
808 while (linklist_ptr != NULL)
811 linklist_ptr = linklist_ptr->next;
816 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
817 char *distinguished_name, LK_ENTRY **linklist_current)
823 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL)
825 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
827 ldap_memfree(Attribute);
828 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
831 retrieve_values(ldap_handle, ldap_entry, Attribute,
832 distinguished_name, linklist_current);
833 ldap_memfree(Attribute);
836 ldap_ber_free(ptr, 0);
840 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
841 char *Attribute, char *distinguished_name,
842 LK_ENTRY **linklist_current)
848 LK_ENTRY *linklist_previous;
849 LDAP_BERVAL **ber_value;
857 SID_IDENTIFIER_AUTHORITY *sid_auth;
858 unsigned char *subauth_count;
859 #endif /*LDAP_BEGUG*/
862 memset(temp, '\0', sizeof(temp));
863 if ((!strcmp(Attribute, "objectSid")) ||
864 (!strcmp(Attribute, "objectGUID")))
869 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
870 Ptr = (void **)ber_value;
875 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
876 Ptr = (void **)str_value;
883 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
885 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
886 linklist_previous->next = (*linklist_current);
887 (*linklist_current) = linklist_previous;
889 if (((*linklist_current)->attribute = calloc(1,
890 strlen(Attribute) + 1)) == NULL)
892 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
893 strcpy((*linklist_current)->attribute, Attribute);
896 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
897 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
899 memset((*linklist_current)->value, '\0', ber_length);
900 memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val,
902 (*linklist_current)->length = ber_length;
906 if (((*linklist_current)->value = calloc(1,
907 strlen(*Ptr) + 1)) == NULL)
909 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
910 (*linklist_current)->length = strlen(*Ptr);
911 strcpy((*linklist_current)->value, *Ptr);
913 (*linklist_current)->ber_value = use_bervalue;
914 if (((*linklist_current)->dn = calloc(1,
915 strlen(distinguished_name) + 1)) == NULL)
917 memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1);
918 strcpy((*linklist_current)->dn, distinguished_name);
921 if (!strcmp(Attribute, "objectGUID"))
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);
931 else if (!strcmp(Attribute, "objectSid"))
933 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
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");
949 print_to_screen(" UNKNOWN SID AUTHORITY\n");
950 subauth_count = GetSidSubAuthorityCount(sid);
951 print_to_screen(" SidSubAuthorityCount = %d\n",
953 print_to_screen(" SidSubAuthority:\n");
954 for (i = 0; i < *subauth_count; i++)
956 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
957 print_to_screen(" %u\n", *subauth);
961 else if ((!memcmp(Attribute, "userAccountControl",
962 strlen("userAccountControl"))) ||
963 (!memcmp(Attribute, "sAMAccountType",
964 strlen("sAmAccountType"))))
966 intValue = atoi(*Ptr);
967 print_to_screen(" %20s : %ld\n",Attribute, intValue);
968 if (!memcmp(Attribute, "userAccountControl",
969 strlen("userAccountControl")))
971 if (intValue & UF_ACCOUNTDISABLE)
972 print_to_screen(" %20s : %s\n",
973 "", "Account disabled");
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");
1008 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
1010 #endif /*LDAP_DEBUG*/
1012 if (str_value != NULL)
1013 ldap_value_free(str_value);
1014 if (ber_value != NULL)
1015 ldap_value_free_len(ber_value);
1017 (*linklist_current) = linklist_previous;
1021 int moira_connect(void)
1026 if (!mr_connections++)
1029 memset(HostName, '\0', sizeof(HostName));
1030 strcpy(HostName, "ttsp");
1031 rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
1033 rc = mr_connect(HostName);
1038 rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
1040 rc = mr_connect(uts.nodename);
1045 rc = mr_auth("winad.incr");
1052 int moira_disconnect(void)
1055 if (!--mr_connections)
1062 int convert_domain_to_dn(char *domain, char **dnp)
1069 memset(dn, 0, sizeof(dn));
1072 for (fp = domain; *fp; fp++)
1083 *dnp = (char *)strdup(dn);
1087 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1088 char *distinguished_name)
1092 CName = ldap_get_dn(ldap_handle, ldap_entry);
1095 strcpy(distinguished_name, CName);
1096 ldap_memfree(CName);
1099 int linklist_create_entry(char *attribute, char *value,
1100 LK_ENTRY **linklist_entry)
1102 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
1103 if (!(*linklist_entry))
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;
1119 void print_to_screen(const char *fmt, ...)
1123 va_start(pvar, fmt);
1124 vfprintf(stderr, fmt, pvar);
1129 int get_group_membership(char *group_membership, char *group_ou,
1130 int *security_flag, char **av)
1135 maillist_flag = atoi(av[L_MAILLIST]);
1136 group_flag = atoi(av[L_GROUP]);
1137 if (security_flag != NULL)
1138 (*security_flag) = 0;
1140 if ((maillist_flag) && (group_flag))
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);
1149 else if ((!maillist_flag) && (group_flag))
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);
1158 else if ((maillist_flag) && (!group_flag))
1160 if (group_membership != NULL)
1161 group_membership[0] = 'D';
1162 if (group_ou != NULL)
1163 strcpy(group_ou, group_ou_distribution);
1167 if (group_membership != NULL)
1168 group_membership[0] = 'N';
1169 if (group_ou != NULL)
1170 strcpy(group_ou, group_ou_neither);
1175 int get_group_info(int ac, char**av, void *ptr)
1181 if (!atoi(av[L_ACTIVE]))
1185 get_group_membership(GroupType, Group_OU, NULL, av);
1189 call_args[5] = av[L_NAME];
1190 get_group_membership(call_args[4], call_args[3], NULL, av);
1196 int group_rename(int ac, char **av, void *ptr)
1201 char group_name[256];
1204 char group_membership[2];
1205 char filter_exp[4096];
1206 char *attr_array[3];
1207 char *name_v[] = {NULL, NULL};
1212 LK_ENTRY *group_base;
1218 strcpy(group_name, av[L_NAME]);
1219 memset(group_ou, 0, sizeof(group_ou));
1220 memset(group_membership, 0, sizeof(group_membership));
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]);
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)
1233 critical_alert("AD incremental",
1234 "LDAP server unable to get group %s info: %d",
1238 if (group_count != 1)
1240 critical_alert("AD incremental",
1241 "LDAP server unable to find group %s in AD.",
1245 strcpy(old_dn, group_base->value);
1246 linklist_free(group_base);
1250 rc = ldap_rename_s((LDAP *)call_args[0], old_dn, new_dn, rel_path, TRUE, NULL, NULL);
1252 name_v[0] = group_name;
1254 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
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++)
1265 int group_create(int ac, char **av, void *ptr)
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};
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];
1287 u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
1291 char filter_exp[256];
1292 char *attr_array[3];
1297 if (!atoi(av[L_ACTIVE]))
1299 if (!check_string(av[L_NAME]))
1301 memset(group_ou, 0, sizeof(group_ou));
1302 memset(group_membership, 0, sizeof(group_membership));
1304 get_group_membership(group_membership, group_ou, &security_flag, av);
1305 call_args[3] = strdup(group_ou);
1306 call_args[4] = strdup(group_membership);
1307 call_args[5] = strdup(av[L_NAME]);
1310 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
1311 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
1312 groupTypeControl_v[0] = groupTypeControlStr;
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]);
1320 samAccountName_v[0] = sam_group_name;
1321 name_v[0] = new_group_name;
1322 cn_v[0] = new_group_name;
1324 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
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)
1333 desc_v[0] = av[L_DESC];
1334 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
1336 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
1337 if (!strcmp(av[L_ACE_TYPE], "LIST"))
1339 sprintf(info, "The Administrator of this list is the LIST: %s", av[L_ACE_NAME]);
1341 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
1345 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
1347 for (i = 0; i < n; i++)
1349 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
1351 sprintf(filter_exp, "(sAMAccountName=%s)", sam_group_name);
1352 attr_array[0] = "objectSid";
1353 attr_array[1] = NULL;
1355 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array,
1356 sid_ptr, &sid_count)) == LDAP_SUCCESS)
1360 (*sid_ptr)->member = strdup(av[L_NAME]);
1361 (*sid_ptr)->type = (char *)GROUPS;
1362 sid_ptr = &(*sid_ptr)->next;
1365 return(LDAP_SUCCESS);
1368 int group_delete(int ac, char **av, void *ptr)
1370 LK_ENTRY *group_base;
1372 char *attr_array[3];
1373 char filter_exp[1024];
1374 char group_membership[1];
1376 char sam_group_name[256];
1383 if (!check_string(av[L_NAME]))
1385 memset(group_ou, 0, sizeof(group_ou));
1386 memset(group_membership, 0, sizeof(group_membership));
1388 get_group_membership(group_membership, group_ou, &security_flag, av);
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)
1401 if (group_count == 1)
1402 rc = ldap_delete_s((LDAP *)call_args[0], group_base->value);
1403 if (rc != LDAP_SUCCESS)
1405 critical_alert("AD incremental",
1406 "Couldn't delete group %s: %s",
1407 av[L_NAME], ldap_err2string(rc));
1410 linklist_free(group_base);
1414 int group_ad_delete(LDAP *ldap_handle, char *dn_path, char *group_gid)
1416 LK_ENTRY *group_base;
1417 char *attr_array[3];
1418 char filter_exp[1024];
1419 char sam_group_name[256];
1427 attr_array[0] = "distinguishedName";
1428 attr_array[1] = NULL;
1429 strcpy(sam_group_name, group_gid);
1430 sprintf(temp, "%s,%s", group_ou_root, dn_path);
1431 sprintf(filter_exp, "(sAMAccountName=%s_zZx*)", sam_group_name);
1432 if (linklist_build(ldap_handle, temp, filter_exp, attr_array,
1433 &group_base, &group_count) != 0)
1435 if (group_count == 1)
1436 rc = ldap_delete_s(ldap_handle, group_base->value);
1438 linklist_free(group_base);
1442 int group_list_build(int ac, char **av, void *ptr)
1449 if (!atoi(av[L_ACTIVE]))
1451 if (!check_string(av[L_NAME]))
1453 linklist = calloc(1, sizeof(LK_ENTRY));
1456 critical_alert("AD incremental", "Out of memory");
1459 memset(linklist, '\0', sizeof(LK_ENTRY));
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;
1473 int member_list_build(int ac, char **av, void *ptr)
1481 strcpy(temp, av[ACE_NAME]);
1482 if (!check_string(temp))
1484 if (!strcmp(av[ACE_TYPE], "STRING"))
1486 contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou);
1488 else if (!strcmp(av[ACE_TYPE], "LIST"))
1490 strcpy(temp, av[ACE_NAME]);
1492 else if (strcmp(av[ACE_TYPE], "USER"))
1494 contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou);
1496 linklist = member_base;
1499 if (!strcasecmp(temp, linklist->member))
1501 linklist = linklist->next;
1503 linklist = calloc(1, sizeof(LK_ENTRY));
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;
1517 #define USER_COUNT 5
1519 int member_list_process(LDAP *ldap_handle, char *dn_path, char *group_name,
1520 char *group_ou, char *group_membership, char *group_gid)
1522 char distinguished_name[1024];
1524 char filter_exp[4096];
1525 char *attr_array[3];
1527 char group_member[256];
1537 LK_ENTRY *group_base;
1554 j = group_count/USER_COUNT;
1557 if (!check_string(group_name))
1559 strcpy(temp, group_name);
1560 sprintf(filter_exp, "(sAMAccountName=%s_zZx%c)", group_gid, group_membership[0]);
1561 attr_array[0] = "distinguishedName";
1562 attr_array[1] = NULL;
1563 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
1564 &group_base, &group_count)) != 0)
1566 critical_alert("AD incremental",
1567 "LDAP server unable to get group %s info: %d",
1572 if (group_count != 1)
1574 critical_alert("AD incremental",
1575 "LDAP server unable to find group %s in AD.",
1580 strcpy(distinguished_name, group_base->value);
1581 linklist_free(group_base);
1586 for (i = 0; i < j; i++)
1590 memset(filter_exp, 0, sizeof(filter_exp));
1591 strcpy(filter_exp, "(|");
1593 for (k = 0; k < USER_COUNT; k++)
1595 strcpy(group_member, pPtr->member);
1596 if (!check_string(group_member))
1603 if (!strcmp(pPtr->type, "LIST"))
1605 args[0] = pPtr->member;
1606 memset(Group_OU, 0, sizeof(Group_OU));
1607 rc = mr_query("get_list_info", 1, args, get_group_info, NULL);
1608 if (strlen(Group_OU) == 0)
1615 sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, Group_OU, dn_path);
1617 else if (!strcmp(pPtr->type, "USER"))
1619 sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, user_ou, dn_path);
1621 else if (!strcmp(pPtr->type, "STRING"))
1623 sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, contact_ou, dn_path);
1627 sprintf(temp, "(distinguishedName=cn=%s,%s,%s)", group_member, kerberos_ou, dn_path);
1629 strcat(filter_exp, temp);
1635 if (filter_count == 0)
1637 strcat(filter_exp, ")");
1638 attr_array[0] = "distinguishedName";
1639 attr_array[1] = NULL;
1642 if ((rc = linklist_build(ldap_handle, dn_path, filter_exp, attr_array,
1643 &new_list, &new_list_count)) != 0)
1645 critical_alert("AD incremental",
1646 "LDAP server unable to get group %s members from AD: %d",
1651 group_count += new_list_count;
1652 if (group_base == NULL)
1653 group_base = new_list;
1659 if (sPtr->next != NULL)
1664 sPtr->next = new_list;
1671 if (group_count != 0)
1673 if ((rc = construct_newvalues(group_base, group_count, NULL, NULL,
1674 &modvalues, REPLACE)) == 1)
1677 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
1679 if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods))
1682 mods[0]->mod_op = LDAP_MOD_REPLACE;
1683 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
1685 if (rc == LDAP_ALREADY_EXISTS)
1687 for (i = 0; i < n; i++)
1689 linklist_free(group_base);
1695 free_values(modvalues);
1696 linklist_free(group_base);
1700 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
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",
1711 char *name_v[] = {NULL, NULL};
1712 char *desc_v[] = {NULL, NULL};
1717 if (!check_string(user))
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;
1724 desc_v[0] = "Auto account created by Moira";
1726 strcpy(new_dn, cn_user_name);
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);
1735 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
1736 for (i = 0; i < n; i++)
1738 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
1740 return(LDAP_SUCCESS);
1743 int user_rename(int ac, char **av, void *ptr)
1748 char user_name[256];
1751 char *userPrincipalName_v[] = {NULL, NULL};
1752 char *altSecurityIdentities_v[] = {NULL, NULL};
1753 char *name_v[] = {NULL, NULL};
1761 if (!check_string(av[U_NAME]))
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))
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);
1773 if ((rc = ldap_rename_s((LDAP *)call_args[0], old_dn, new_dn, NULL, TRUE,
1774 NULL, NULL)) != LDAP_SUCCESS)
1776 critical_alert("AD incremental", "Couldn't rename user from %s to %s: %ld",
1777 call_args[3], user_name, rc);
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;
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);
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)
1795 critical_alert("AD incremental",
1796 "After renaming, couldn't modify user data for %s: %ld",
1800 for (i = 0; i < n; i++)
1805 int user_create(int ac, char **av, void *ptr)
1809 char user_name[256];
1811 char *cn_v[] = {NULL, NULL};
1812 char *objectClass_v[] = {"top", "person",
1813 "organizationalPerson",
1816 char *samAccountName_v[] = {NULL, NULL};
1817 char *altSecurityIdentities_v[] = {NULL, NULL};
1818 char *name_v[] = {NULL, NULL};
1819 char *desc_v[] = {NULL, NULL};
1821 char *userPrincipalName_v[] = {NULL, NULL};
1822 char *userAccountControl_v[] = {NULL, NULL};
1823 char userAccountControlStr[80];
1825 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE;
1830 char filter_exp[256];
1831 char *attr_array[3];
1836 if (!check_string(av[U_NAME]))
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))
1843 strcpy(user_name, av[U_NAME]);
1844 sprintf(upn, "%s@%s", user_name, ldap_domain);
1845 sprintf(sam_name, "%s", av[U_UID]);
1846 samAccountName_v[0] = sam_name;
1847 if (atoi(av[U_STATE]) == US_DELETED)
1848 userAccountControl |= UF_ACCOUNTDISABLE;
1849 sprintf(userAccountControlStr, "%ld", userAccountControl);
1850 userAccountControl_v[0] = userAccountControlStr;
1851 userPrincipalName_v[0] = upn;
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]);
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);
1872 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
1873 if (rc == LDAP_ALREADY_EXISTS)
1875 rc = user_change_status(ac, av, ptr);
1876 rc = LDAP_ALREADY_EXISTS;
1878 for (i = 0; i < n; i++)
1880 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
1882 if (rc == LDAP_SUCCESS)
1884 if ((rc = set_password(sam_name, ldap_domain)) != 0)
1886 if ((rc = set_password(user_name, ldap_domain)) != 0)
1888 critical_alert("AD incremental", "Couldn't set password for user %s: %ld",
1894 sprintf(filter_exp, "(sAMAccountName=%s)", av[U_UID]);
1895 attr_array[0] = "objectSid";
1896 attr_array[1] = NULL;
1898 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array,
1899 sid_ptr, &sid_count)) == LDAP_SUCCESS)
1903 (*sid_ptr)->member = strdup(av[U_NAME]);
1904 (*sid_ptr)->type = (char *)USERS;
1905 sid_ptr = &(*sid_ptr)->next;
1908 return(LDAP_SUCCESS);
1911 int user_change_status(int ac, char **av, void *ptr)
1913 char filter_exp[1024];
1914 char *attr_array[3];
1916 char distinguished_name[1024];
1917 char user_name[512];
1920 LK_ENTRY *group_base;
1931 if (!check_string(av[0]))
1933 strcpy(user_name, av[0]);
1934 operation = (int)call_args[2];
1937 sprintf(filter_exp, "(sAMAccountName=%s)", av[U_UID]);
1938 attr_array[0] = "UserAccountControl";
1939 attr_array[1] = NULL;
1940 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1], filter_exp, attr_array,
1941 &group_base, &group_count)) != 0)
1943 critical_alert("AD incremental",
1944 "LDAP server couldn't process user %s: %s",
1945 user_name, "no memory");
1949 if (group_count == 0)
1951 critical_alert("AD incremental",
1952 "LDAP server couldn't process user %s: %s",
1953 user_name, "user not found in AD");
1957 strcpy(distinguished_name, group_base->dn);
1958 ulongValue = atoi((*group_base).value);
1959 if (operation == MEMBER_DEACTIVATE)
1960 ulongValue |= UF_ACCOUNTDISABLE;
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)
1967 linklist_free(group_base);
1971 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
1973 rc = ldap_modify_s((LDAP *)call_args[0], distinguished_name, mods);
1974 for (i = 0; i < n; i++)
1976 free_values(modvalues);
1977 if (rc != LDAP_SUCCESS)
1979 critical_alert("AD incremental",
1980 "LDAP server couldn't process user %s: %d",
1984 linklist_free(group_base);
1988 int user_delete(LDAP *ldap_handle, char *dn_path, char *u_name)
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;
1998 if (!check_string(u_name))
2000 strcpy(user_name, u_name);
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)
2009 critical_alert("AD incremental",
2010 "LDAP server couldn't process user %s: %s",
2011 user_name, "no memory");
2015 if (group_count == 0)
2017 critical_alert("AD incremental",
2018 "LDAP server couldn't process user %s: %s",
2019 user_name, "user not found in AD");
2023 strcpy(distinguished_name, group_base->dn);
2024 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
2026 critical_alert("AD incremental",
2027 "LDAP server couldn't process user %s: %s",
2028 user_name, "cannot delete user from AD");
2032 linklist_free(group_base);
2036 void linklist_free(LK_ENTRY *linklist_base)
2038 LK_ENTRY *linklist_previous;
2040 while (linklist_base != NULL)
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);
2060 void free_values(char **modvalues)
2065 if (modvalues != NULL)
2067 while (modvalues[i] != NULL)
2070 modvalues[i] = NULL;
2077 int sid_update(LDAP *ldap_handle, char *dn_path)
2081 unsigned char temp[126];
2088 memset(temp, 0, sizeof(temp));
2089 convert_b_to_a(temp, ptr->value, ptr->length);
2090 av[0] = ptr->member;
2092 if (ptr->type == (char *)GROUPS)
2095 rc = mr_query("add_list_sid_by_name", 2, av, NULL, NULL);
2097 else if (ptr->type == (char *)USERS)
2100 rc = mr_query("add_user_sid_by_login", 2, av, NULL, NULL);
2107 void convert_b_to_a(char *string, UCHAR *binary, int length)
2114 for (i = 0; i < length; i++)
2121 if (string[j] > '9')
2124 string[j] = tmp & 0x0f;
2126 if (string[j] > '9')
2133 static int illegalchars[] = {
2134 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
2135 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
2136 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
2137 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
2138 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
2139 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
2140 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
2141 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
2142 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2143 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2144 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2145 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2146 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2147 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2148 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2149 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
2152 int check_string(char *s)
2158 if (illegalchars[(unsigned) *s])
2164 int mr_connect_cl(char *server, char *client, int version, int auth)
2169 status = mr_connect(server);
2172 com_err(whoami, status, "while connecting to Moira");
2176 status = mr_motd(&motd);
2180 com_err(whoami, status, "while checking server status");
2185 fprintf(stderr, "The Moira server is currently unavailable:\n%s\n",
2191 status = mr_version(version);
2194 if (status == MR_UNKNOWN_PROC)
2197 status = MR_VERSION_HIGH;
2199 status = MR_SUCCESS;
2202 if (status == MR_VERSION_HIGH)
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.");
2207 else if (status && status != MR_VERSION_LOW)
2209 com_err(whoami, status, "while setting query version number.");
2217 status = mr_auth(client);
2220 com_err(whoami, status, "while authenticating to Moira.");
2222 return MRCL_AUTH_ERROR;
2226 return MRCL_SUCCESS;