2 /* ldap.incr arguments example
4 * arguments when moira creates the account - ignored by ldap.incr since the
5 * account is unusable. users 0 11 #45198 45198 /bin/cmd cmd Last First Middle
6 * 0 950000001 2000 121049
8 * login, unix_uid, shell, winconsoleshell, last,
9 * first, middle, status, mitid, type, moiraid
11 * arguments for creating or updating a user account
12 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
13 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
14 * First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
15 * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF
16 * 121058 PathToHomeDir PathToProfileDir newuser 45206 /bin/cmd cmd Last
17 * First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
19 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
20 * mitid, type, moiraid
22 * arguments for deactivating/deleting a user account
23 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
24 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
25 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
26 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
27 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
28 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
30 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
31 * mitid, type, moiraid
33 * arguments for reactivating a user account
34 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
35 * 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
37 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
38 * 121058 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 12105
40 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
41 * mitid, type, moiraid
43 * arguments for changing user name
44 * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001
45 * STAFF 121058 PathToHomeDir PathToProfileDir newusername 45206 /bin/cmd cmd
46 * Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
48 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
49 * mitid, type, moiraid
51 * arguments for expunging a user
52 * users 11 0 username 45198 /bin/cmd cmd Last First Middle 0 950000001 2000
55 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
56 * mitid, type, moiraid
58 * arguments for creating a "special" group/list
59 * list 0 11 listname 1 1 0 0 0 -1 NONE 0 description 92616
61 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
62 * acl_id, description, moiraid
64 * arguments for creating a "mail" group/list
65 * list 0 11 listname 1 1 0 1 0 -1 NONE 0 description 92616
67 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
68 * acl_id, description, moiraid
70 * arguments for creating a "group" group/list
71 * list 0 11 listname 1 1 0 0 1 -1 NONE 0 description 92616
73 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
74 * acl_id, description, moiraid
76 * arguments for creating a "group/mail" group/list
77 * list 0 11 listname 1 1 0 1 1 -1 NONE 0 description 92616
79 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
80 * acl_id, description, moiraid
82 * arguments to add a USER member to group/list
83 * imembers 0 12 listname USER userName 1 1 0 0 0 -1 1 92616 121047
85 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
86 * gid, userStatus, moiraListId, moiraUserId
88 * arguments to add a STRING or KERBEROS member to group/list
89 * imembers 0 10 listname STRING stringName 1 1 0 0 0 -1 92616
90 * imembers 0 10 listlistnameName KERBEROS kerberosName 1 1 0 0 0 -1 92616
92 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
95 * NOTE: group members of type LIST are ignored.
97 * arguments to remove a USER member to group/list
98 * imembers 12 0 listname USER userName 1 1 0 0 0 -1 1 92616 121047
100 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
101 * gid, userStatus, moiraListId, moiraUserId
103 * arguments to remove a STRING or KERBEROS member to group/list
104 * imembers 10 0 listname STRING stringName 1 1 0 0 0 -1 92616
105 * imembers 10 0 listname KERBEROS kerberosName 1 1 0 0 0 -1 92616
107 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
110 * NOTE: group members of type LIST are ignored.
112 * arguments for renaming a group/list
113 * list 11 11 oldlistname 1 1 0 0 0 -1 NONE 0 description 92616 newlistname 1
114 * 1 0 0 0 -1 description 0 92616
116 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
117 * acl_id, description, moiraListId
119 * arguments for deleting a group/list
120 * list 11 0 listname 1 1 0 0 0 -1 NONE 0 description 92616
122 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
123 * acl_id, description, moiraListId
125 * arguments for adding a file system
126 * filesys 0 12 username AFS ATHENA.MIT.EDU
127 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
128 * wheel 1 HOMEDIR 101727
130 * arguments for deleting a file system
131 * filesys 12 0 username AFS ATHENA.MIT.EDU
132 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
133 * wheel 1 HOMEDIR 101727
135 * arguments when moira creates a container (OU).
136 * containers 0 8 machines/test/bottom description location contact USER
139 * arguments when moira deletes a container (OU).
140 * containers 8 0 machines/test/bottom description location contact USER
141 * 105316 2222 groupname
143 * arguments when moira modifies a container information (OU).
144 * containers 8 8 machines/test/bottom description location contact USER
145 * 105316 2222 groupname machines/test/bottom description1 location contact
146 * USER 105316 2222 groupname
148 * arguments when moira adds a machine from an OU
149 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
150 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
152 * arguments when moira removes a machine from an OU
153 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
154 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
158 #include <mit-copyright.h>
161 #include <winsock2.h>
165 #include <lmaccess.h>
173 #include <moira_site.h>
174 #include <mrclient.h>
182 #define ECONNABORTED WSAECONNABORTED
185 #define ECONNREFUSED WSAECONNREFUSED
188 #define EHOSTUNREACH WSAEHOSTUNREACH
190 #define krb5_xfree free
192 #define sleep(A) Sleep(A * 1000);
196 #include <sys/types.h>
197 #include <netinet/in.h>
198 #include <arpa/nameser.h>
200 #include <sys/utsname.h>
203 #define CFG_PATH "/moira/ldap/"
204 #define WINADCFG "ldap.cfg"
205 #define strnicmp(A,B,C) strncasecmp(A,B,C)
206 #define UCHAR unsigned char
208 #define UF_SCRIPT 0x0001
209 #define UF_ACCOUNTDISABLE 0x0002
210 #define UF_HOMEDIR_REQUIRED 0x0008
211 #define UF_LOCKOUT 0x0010
212 #define UF_PASSWD_NOTREQD 0x0020
213 #define UF_PASSWD_CANT_CHANGE 0x0040
214 #define UF_DONT_EXPIRE_PASSWD 0x10000
216 #define UF_TEMP_DUPLICATE_ACCOUNT 0x0100
217 #define UF_NORMAL_ACCOUNT 0x0200
218 #define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800
219 #define UF_WORKSTATION_TRUST_ACCOUNT 0x1000
220 #define UF_SERVER_TRUST_ACCOUNT 0x2000
222 #define OWNER_SECURITY_INFORMATION (0x00000001L)
223 #define GROUP_SECURITY_INFORMATION (0x00000002L)
224 #define DACL_SECURITY_INFORMATION (0x00000004L)
225 #define SACL_SECURITY_INFORMATION (0x00000008L)
228 #define BYTE unsigned char
230 typedef unsigned int DWORD;
231 typedef unsigned long ULONG;
236 unsigned short Data2;
237 unsigned short Data3;
238 unsigned char Data4[8];
241 typedef struct _SID_IDENTIFIER_AUTHORITY {
243 } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
245 typedef struct _SID {
247 BYTE SubAuthorityCount;
248 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
249 DWORD SubAuthority[512];
254 #define WINADCFG "ldap.cfg"
262 #define WINAFS "\\\\afs\\all\\"
264 #define ADS_GROUP_TYPE_GLOBAL_GROUP 0x00000002
265 #define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP 0x00000004
266 #define ADS_GROUP_TYPE_LOCAL_GROUP 0x00000004
267 #define ADS_GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
268 #define ADS_GROUP_TYPE_SECURITY_ENABLED 0x80000000
270 #define QUERY_VERSION -1
271 #define PRIMARY_REALM "ATHENA.MIT.EDU"
272 #define PRIMARY_DOMAIN "win.mit.edu"
273 #define PRODUCTION_PRINCIPAL "sms"
274 #define TEST_PRINCIPAL "smstest"
283 #define MEMBER_REMOVE 2
284 #define MEMBER_CHANGE_NAME 3
285 #define MEMBER_ACTIVATE 4
286 #define MEMBER_DEACTIVATE 5
287 #define MEMBER_CREATE 6
289 #define MOIRA_ALL 0x0
290 #define MOIRA_USERS 0x1
291 #define MOIRA_KERBEROS 0x2
292 #define MOIRA_STRINGS 0x4
293 #define MOIRA_LISTS 0x8
294 #define MOIRA_MACHINE 0x16
296 #define CHECK_GROUPS 1
297 #define CLEANUP_GROUPS 2
299 #define AD_NO_GROUPS_FOUND -1
300 #define AD_WRONG_GROUP_DN_FOUND -2
301 #define AD_MULTIPLE_GROUPS_FOUND -3
302 #define AD_INVALID_NAME -4
303 #define AD_LDAP_FAILURE -5
304 #define AD_INVALID_FILESYS -6
305 #define AD_NO_ATTRIBUTE_FOUND -7
306 #define AD_NO_OU_FOUND -8
307 #define AD_NO_USER_FOUND -9
309 /* container arguments */
310 #define CONTAINER_NAME 0
311 #define CONTAINER_DESC 1
312 #define CONTAINER_LOCATION 2
313 #define CONTAINER_CONTACT 3
314 #define CONTAINER_TYPE 4
315 #define CONTAINER_ID 5
316 #define CONTAINER_ROWID 6
317 #define CONTAINER_GROUP_NAME 7
319 /*mcntmap arguments*/
320 #define OU_MACHINE_NAME 0
321 #define OU_CONTAINER_NAME 1
322 #define OU_MACHINE_ID 2
323 #define OU_CONTAINER_ID 3
324 #define OU_CONTAINER_GROUP 4
326 typedef struct lk_entry {
336 struct lk_entry *next;
339 #define STOP_FILE "/moira/ldap/noldap"
340 #define file_exists(file) (access((file), F_OK) == 0)
342 #define N_SD_BER_BYTES 5
343 #define LDAP_BERVAL struct berval
344 #define MAX_SERVER_NAMES 32
346 #define HIDDEN_GROUP "HiddenGroup.g"
347 #define HIDDEN_GROUP_WITH_ADMIN "HiddenGroupWithAdmin.g"
348 #define NOT_HIDDEN_GROUP "NotHiddenGroup.g"
349 #define NOT_HIDDEN_GROUP_WITH_ADMIN "NotHiddenGroupWithAdmin.g"
351 #define ADDRESS_LIST_PREFIX "CN=MIT Directory,CN=All Address Lists,\
352 CN=Address Lists Container,CN=Massachusetts Institute of Technology,\
353 CN=Microsoft Exchange,CN=Services,CN=Configuration,"
355 #define ADD_ATTR(t, v, o) \
356 mods[n] = malloc(sizeof(LDAPMod)); \
357 mods[n]->mod_op = o; \
358 mods[n]->mod_type = t; \
359 mods[n++]->mod_values = v
361 #define DEL_ATTR(t, o) \
362 DelMods[i] = malloc(sizeof(LDAPMod)); \
363 DelMods[i]->mod_op = o; \
364 DelMods[i]->mod_type = t; \
365 DelMods[i++]->mod_values = NULL
367 #define DOMAIN_SUFFIX "MIT.EDU"
368 #define DOMAIN "DOMAIN:"
369 #define PRINCIPALNAME "PRINCIPAL:"
370 #define SERVER "SERVER:"
373 #define GROUP_SUFFIX "GROUP_SUFFIX:"
374 #define GROUP_TYPE "GROUP_TYPE:"
375 #define SET_GROUP_ACE "SET_GROUP_ACE:"
376 #define SET_PASSWORD "SET_PASSWORD:"
377 #define EXCHANGE "EXCHANGE:"
378 #define REALM "REALM:"
379 #define ACTIVE_DIRECTORY "ACTIVE_DIRECTORY:"
381 #define PROCESS_MACHINE_CONTAINER "PROCESS_MACHINE_CONTAINER:"
382 #define GROUP_POPULATE_MEMBERS "GROUP_POPULATE_MEMBERS:"
383 #define MAX_DOMAINS 10
384 char DomainNames[MAX_DOMAINS][128];
386 LK_ENTRY *member_base = NULL;
388 char PrincipalName[128];
389 static char tbl_buf[1024];
390 char kerberos_ou[] = "OU=kerberos,OU=moira";
391 char contact_ou[] = "OU=strings,OU=moira";
392 char user_ou[] = "OU=users,OU=moira";
393 char group_ou_distribution[1024];
394 char group_ou_root[1024];
395 char group_ou_security[1024];
396 char group_ou_neither[1024];
397 char group_ou_both[1024];
398 char orphans_machines_ou[] = "OU=Machines,OU=Orphans";
399 char orphans_other_ou[] = "OU=Other,OU=Orphans";
400 char security_template_ou[] = "OU=security_templates";
402 char ldap_domain[256];
403 char ldap_realm[256];
405 char *ServerList[MAX_SERVER_NAMES];
406 char default_server[256];
407 static char tbl_buf[1024];
408 char group_suffix[256];
409 char exchange_acl[256];
410 int mr_connections = 0;
413 int UseGroupSuffix = 1;
414 int UseGroupUniversal = 0;
418 int ProcessMachineContainer = 1;
419 int ActiveDirectory = 1;
420 int UpdateDomainList;
422 int GroupPopulateDelete = 0;
424 extern int set_password(char *user, char *password, char *domain);
426 int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name,
427 char *group_membership, char *MoiraId, char *attribute,
428 LK_ENTRY **linklist_base, int *linklist_count,
430 void AfsToWinAfs(char* path, char* winPath);
431 int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
432 char *Win2kPassword, char *Win2kUser, char *default_server,
433 int connect_to_kdc, char **ServerList, char *ldap_realm,
435 void ad_kdc_disconnect();
436 int ad_server_connect(char *connectedServer, char *domain);
437 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
438 char *attribute_value, char *attribute, char *user_name);
439 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer);
440 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name);
441 int check_winad(void);
442 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName,
445 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
446 char *distinguishedName, int count, char **av);
447 void container_check(LDAP *ldap_handle, char *dn_path, char *name);
448 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av);
449 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av);
450 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
451 char *distinguishedName, int count,
453 void container_get_dn(char *src, char *dest);
454 void container_get_name(char *src, char *dest);
455 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName);
456 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
457 char **before, int afterc, char **after);
458 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
459 char **before, int afterc, char **after);
461 int GetAceInfo(int ac, char **av, void *ptr);
462 int get_group_membership(char *group_membership, char *group_ou,
463 int *security_flag, char **av);
464 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
465 char *machine_ou, char *pPtr);
466 int Moira_container_group_create(char **after);
467 int Moira_container_group_delete(char **before);
468 int Moira_groupname_create(char *GroupName, char *ContainerName,
469 char *ContainerRowID);
470 int Moira_container_group_update(char **before, char **after);
471 int Moira_process_machine_container_group(char *MachineName, char* groupName,
473 int Moira_addGroupToParent(char *origContainerName, char *GroupName);
474 int Moira_getContainerGroup(int ac, char **av, void *ptr);
475 int Moira_getGroupName(char *origContainerName, char *GroupName,
477 int Moira_setContainerGroup(char *ContainerName, char *GroupName);
478 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *group_name, char *Type,
479 int UpdateGroup, int *ProcessGroup, char *maillist);
480 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
481 char *group_name, char *group_ou, char *group_membership,
482 int group_security_flag, int type, char *maillist);
483 int process_lists(int ac, char **av, void *ptr);
484 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
485 char *TargetGroupName, int HiddenGroup,
486 char *AceType, char *AceName);
487 int ProcessMachineName(int ac, char **av, void *ptr);
488 int ReadConfigFile(char *DomainName);
489 int ReadDomainList();
490 void StringTrim(char *StringToTrim);
491 char *escape_string(char *s);
492 int save_query_info(int argc, char **argv, void *hint);
493 int save_fsgroup_info(int argc, char **argv, void *hint);
494 int user_create(int ac, char **av, void *ptr);
495 int user_change_status(LDAP *ldap_handle, char *dn_path,
496 char *user_name, char *MoiraId, int operation);
497 int user_delete(LDAP *ldap_handle, char *dn_path,
498 char *u_name, char *MoiraId);
499 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
501 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
502 char *uid, char *MitId, char *MoiraId, int State,
503 char *WinHomeDir, char *WinProfileDir, char *first,
504 char *middle, char *last, char *shell, char *class);
505 void change_to_lower_case(char *ptr);
506 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
507 int contact_remove_email(LDAP *ld, char *bind_path,
508 LK_ENTRY **linklist_entry, int linklist_current);
509 int group_create(int ac, char **av, void *ptr);
510 int group_delete(LDAP *ldap_handle, char *dn_path,
511 char *group_name, char *group_membership, char *MoiraId);
512 int group_rename(LDAP *ldap_handle, char *dn_path,
513 char *before_group_name, char *before_group_membership,
514 char *before_group_ou, int before_security_flag,
515 char *before_desc, char *after_group_name,
516 char *after_group_membership, char *after_group_ou,
517 int after_security_flag, char *after_desc,
518 char *MoiraId, char *filter, char *maillist);
519 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name);
520 int machine_GetMoiraContainer(int ac, char **av, void *ptr);
521 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
522 char *machine_name, char *container_name);
523 int machine_move_to_ou(LDAP *ldap_handle, char *dn_path,
524 char *MoiraMachineName, char *DestinationOu);
525 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
526 char *group_name, char *group_ou, char *group_membership,
527 int group_security_flag, int updateGroup, char *maillist);
528 int member_list_build(int ac, char **av, void *ptr);
529 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
530 char *group_ou, char *group_membership,
531 char *user_name, char *pUserOu, char *MoiraId);
532 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
533 char *group_ou, char *group_membership, char *user_name,
534 char *pUserOu, char *MoiraId);
535 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
536 char *group_ou, char *group_membership,
537 int group_security_flag, char *MoiraId);
538 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
539 char *DistinguishedName,
540 char *WinHomeDir, char *WinProfileDir,
541 char **homedir_v, char **winProfile_v,
542 char **drives_v, LDAPMod **mods,
544 int sid_update(LDAP *ldap_handle, char *dn_path);
545 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n);
546 int check_string(char *s);
547 int check_container_name(char* s);
549 int mr_connect_cl(char *server, char *client, int version, int auth);
550 void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
551 char **before, int beforec, char **after, int afterc);
552 void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
553 char **before, int beforec, char **after, int afterc);
554 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
555 char **before, int beforec, char **after, int afterc);
556 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
557 char **before, int beforec, char **after, int afterc);
558 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
559 char **before, int beforec, char **after, int afterc);
560 void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
561 char **before, int beforec, char **after, int afterc);
562 int linklist_create_entry(char *attribute, char *value,
563 LK_ENTRY **linklist_entry);
564 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
565 char **attr_array, LK_ENTRY **linklist_base,
566 int *linklist_count, unsigned long ScopeType);
567 void linklist_free(LK_ENTRY *linklist_base);
569 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
570 char *distinguished_name, LK_ENTRY **linklist_current);
571 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
572 LK_ENTRY **linklist_base, int *linklist_count);
573 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
574 char *Attribute, char *distinguished_name,
575 LK_ENTRY **linklist_current);
577 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
578 char *oldValue, char *newValue,
579 char ***modvalues, int type);
580 void free_values(char **modvalues);
582 int convert_domain_to_dn(char *domain, char **bind_path);
583 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
584 char *distinguished_name);
585 int moira_disconnect(void);
586 int moira_connect(void);
587 void print_to_screen(const char *fmt, ...);
588 int GetMachineName(char *MachineName);
589 int tickets_get_k5();
590 int destroy_cache(void);
593 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
594 char **homeServerName);
596 int main(int argc, char **argv)
612 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
616 com_err(whoami, 0, "Unable to process %s", "argc < 4");
620 if (argc < (4 + atoi(argv[2]) + atoi(argv[3])))
622 com_err(whoami, 0, "Unable to process %s",
623 "argc < (4 + beforec + afterc)");
627 if (!strcmp(argv[1], "filesys"))
630 for (i = 1; i < argc; i++)
632 strcat(tbl_buf, argv[i]);
633 strcat(tbl_buf, " ");
636 com_err(whoami, 0, "%s", tbl_buf);
640 com_err(whoami, 0, "%s failed", "check_winad()");
644 initialize_sms_error_table();
645 initialize_krb_error_table();
647 UpdateDomainList = 0;
648 memset(DomainNames, '\0', sizeof(DomainNames[0]) * MAX_DOMAINS);
650 if (ReadDomainList())
652 com_err(whoami, 0, "%s failed", "ReadDomainList()");
656 for (i = 0; i < argc; i++)
659 for (k = 0; k < MAX_DOMAINS; k++)
661 if (strlen(DomainNames[k]) == 0)
663 for (i = 0; i < argc; i++)
665 if (orig_argv[i] != NULL)
667 orig_argv[i] = strdup(argv[i]);
670 memset(PrincipalName, '\0', sizeof(PrincipalName));
671 memset(ldap_domain, '\0', sizeof(ldap_domain));
672 memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES);
673 memset(default_server, '\0', sizeof(default_server));
674 memset(dn_path, '\0', sizeof(dn_path));
675 memset(group_suffix, '\0', sizeof(group_suffix));
676 memset(exchange_acl, '\0', sizeof(exchange_acl));
680 UseGroupUniversal = 0;
684 ProcessMachineContainer = 1;
687 sprintf(group_suffix, "%s", "_group");
688 sprintf(exchange_acl, "%s", "exchange-acl");
690 beforec = atoi(orig_argv[2]);
691 afterc = atoi(orig_argv[3]);
692 table = orig_argv[1];
693 before = &orig_argv[4];
694 after = &orig_argv[4 + beforec];
702 if (ReadConfigFile(DomainNames[k]))
707 sprintf(group_ou_distribution, "OU=mail,OU=lists,OU=moira");
708 sprintf(group_ou_root, "OU=lists,OU=moira");
709 sprintf(group_ou_security, "OU=group,OU=lists,OU=moira");
710 sprintf(group_ou_neither, "OU=special,OU=lists,OU=moira");
711 sprintf(group_ou_both, "OU=mail,OU=group,OU=lists,OU=moira");
715 sprintf(group_ou_distribution, "OU=lists,OU=moira");
716 sprintf(group_ou_root, "OU=lists,OU=moira");
717 sprintf(group_ou_security, "OU=lists,OU=moira");
718 sprintf(group_ou_neither, "OU=lists,OU=moira");
719 sprintf(group_ou_both, "OU=lists,OU=moira");
722 OldUseSFU30 = UseSFU30;
724 for (i = 0; i < 5; i++)
726 ldap_handle = (LDAP *)NULL;
727 if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "",
728 default_server, SetPassword, ServerList,
729 ldap_realm, ldap_port)))
731 com_err(whoami, 0, "connected to domain %s", DomainNames[k]);
736 if ((rc) || (ldap_handle == NULL))
738 critical_alert("incremental",
739 "ldap.incr cannot connect to any server in "
740 "domain %s", DomainNames[k]);
744 for (i = 0; i < (int)strlen(table); i++)
745 table[i] = tolower(table[i]);
747 if (!strcmp(table, "users"))
748 do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
750 else if (!strcmp(table, "list"))
751 do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
753 else if (!strcmp(table, "imembers"))
754 do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
756 else if (!strcmp(table, "containers"))
757 do_container(ldap_handle, dn_path, ldap_domain, before, beforec, after,
759 else if (!strcmp(table, "mcntmap"))
760 do_mcntmap(ldap_handle, dn_path, ldap_domain, before, beforec, after,
766 for (i = 0; i < MAX_SERVER_NAMES; i++)
768 if (ServerList[i] != NULL)
771 ServerList[i] = NULL;
775 rc = ldap_unbind_s(ldap_handle);
781 void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
782 char **before, int beforec, char **after, int afterc)
784 char MoiraContainerName[128];
785 char ADContainerName[128];
786 char MachineName[1024];
787 char OriginalMachineName[1024];
790 char MoiraContainerGroup[64];
792 if (!ProcessMachineContainer)
794 com_err(whoami, 0, "Process machines and containers disabled, skipping");
799 memset(ADContainerName, '\0', sizeof(ADContainerName));
800 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
802 if ((beforec == 0) && (afterc == 0))
805 if (rc = moira_connect())
807 critical_alert("AD incremental",
808 "Error contacting Moira server : %s",
813 if ((beforec != 0) && (afterc == 0)) /*remove a machine*/
815 strcpy(OriginalMachineName, before[OU_MACHINE_NAME]);
816 strcpy(MachineName, before[OU_MACHINE_NAME]);
817 strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]);
819 com_err(whoami, 0, "removing machine %s from %s",
820 OriginalMachineName, before[OU_CONTAINER_NAME]);
822 else if ((beforec == 0) && (afterc != 0)) /*add a machine*/
824 strcpy(OriginalMachineName, after[OU_MACHINE_NAME]);
825 strcpy(MachineName, after[OU_MACHINE_NAME]);
826 strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]);
827 com_err(whoami, 0, "adding machine %s to container %s",
828 OriginalMachineName, after[OU_CONTAINER_NAME]);
836 rc = GetMachineName(MachineName);
838 if (strlen(MachineName) == 0)
841 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
842 OriginalMachineName);
846 Moira_process_machine_container_group(MachineName, MoiraContainerGroup,
849 if (machine_check(ldap_handle, dn_path, MachineName))
851 com_err(whoami, 0, "Unable to find machine %s (alias %s) in AD.",
852 OriginalMachineName, MachineName);
857 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
858 machine_get_moira_container(ldap_handle, dn_path, MachineName,
861 if (strlen(MoiraContainerName) == 0)
863 com_err(whoami, 0, "Unable to fine machine %s (alias %s) container "
864 "in Moira - moving to orphans OU.",
865 OriginalMachineName, MachineName);
866 machine_move_to_ou(ldap_handle, dn_path, MachineName,
867 orphans_machines_ou);
872 container_get_dn(MoiraContainerName, ADContainerName);
874 if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/')
875 strcat(MoiraContainerName, "/");
877 container_check(ldap_handle, dn_path, MoiraContainerName);
878 machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName);
883 void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
884 char **before, int beforec, char **after, int afterc)
888 if (!ProcessMachineContainer)
890 com_err(whoami, 0, "Process machines and containers disabled, skipping");
894 if ((beforec == 0) && (afterc == 0))
897 if (rc = moira_connect())
899 critical_alert("AD incremental", "Error contacting Moira server : %s",
904 if ((beforec != 0) && (afterc == 0)) /*delete a new container*/
906 com_err(whoami, 0, "deleting container %s", before[CONTAINER_NAME]);
907 container_delete(ldap_handle, dn_path, beforec, before);
908 Moira_container_group_delete(before);
913 if ((beforec == 0) && (afterc != 0)) /*create a container*/
915 com_err(whoami, 0, "creating container %s", after[CONTAINER_NAME]);
916 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
917 container_create(ldap_handle, dn_path, afterc, after);
918 Moira_container_group_create(after);
923 if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME]))
925 com_err(whoami, 0, "renaming container %s to %s",
926 before[CONTAINER_NAME], after[CONTAINER_NAME]);
927 container_rename(ldap_handle, dn_path, beforec, before, afterc, after);
928 Moira_container_group_update(before, after);
933 com_err(whoami, 0, "updating container %s information",
934 after[CONTAINER_NAME]);
935 container_update(ldap_handle, dn_path, beforec, before, afterc, after);
936 Moira_container_group_update(before, after);
941 #define L_LIST_DESC 9
944 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
945 char **before, int beforec, char **after, int afterc)
950 char group_membership[6];
955 char before_list_id[32];
956 char before_group_membership[1];
957 int before_security_flag;
958 char before_group_ou[256];
959 LK_ENTRY *ptr = NULL;
961 if (beforec == 0 && afterc == 0)
964 memset(list_id, '\0', sizeof(list_id));
965 memset(before_list_id, '\0', sizeof(before_list_id));
966 memset(before_group_ou, '\0', sizeof(before_group_ou));
967 memset(before_group_membership, '\0', sizeof(before_group_membership));
968 memset(group_ou, '\0', sizeof(group_ou));
969 memset(group_membership, '\0', sizeof(group_membership));
974 if (beforec < L_LIST_ID)
976 if (beforec > L_LIST_DESC)
978 strcpy(before_list_id, before[L_LIST_ID]);
980 before_security_flag = 0;
981 get_group_membership(before_group_membership, before_group_ou,
982 &before_security_flag, before);
987 if (afterc < L_LIST_ID)
989 if (afterc > L_LIST_DESC)
991 strcpy(list_id, after[L_LIST_ID]);
994 get_group_membership(group_membership, group_ou, &security_flag, after);
997 if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/
1006 if ((rc = process_group(ldap_handle, dn_path, before_list_id,
1007 before[L_NAME], before_group_ou,
1008 before_group_membership,
1009 before_security_flag, CHECK_GROUPS,
1010 before[L_MAILLIST])))
1012 if (rc == AD_NO_GROUPS_FOUND)
1016 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
1017 (rc == AD_MULTIPLE_GROUPS_FOUND))
1019 rc = process_group(ldap_handle, dn_path, before_list_id,
1020 before[L_NAME], before_group_ou,
1021 before_group_membership,
1022 before_security_flag, CLEANUP_GROUPS,
1023 before[L_MAILLIST]);
1025 if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0))
1027 com_err(whoami, 0, "Unable to process list %s",
1031 if (rc == AD_NO_GROUPS_FOUND)
1037 if ((beforec != 0) && (afterc != 0))
1039 if (((strcmp(after[L_NAME], before[L_NAME])) ||
1040 ((!strcmp(after[L_NAME], before[L_NAME])) &&
1041 (strcmp(before_group_ou, group_ou)))) &&
1044 com_err(whoami, 0, "Changing list name from %s to %s",
1045 before[L_NAME], after[L_NAME]);
1047 if ((strlen(before_group_ou) == 0) ||
1048 (strlen(before_group_membership) == 0) ||
1049 (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
1051 com_err(whoami, 0, "%s", "Unable to find the group OU's");
1055 memset(filter, '\0', sizeof(filter));
1057 if ((rc = group_rename(ldap_handle, dn_path,
1058 before[L_NAME], before_group_membership,
1059 before_group_ou, before_security_flag,
1060 before[L_LIST_DESC], after[L_NAME],
1061 group_membership, group_ou, security_flag,
1063 list_id, filter, after[L_MAILLIST])))
1065 if (rc != AD_NO_GROUPS_FOUND)
1068 "Unable to change list name from %s to %s",
1069 before[L_NAME], after[L_NAME]);
1082 if ((strlen(before_group_ou) == 0) ||
1083 (strlen(before_group_membership) == 0))
1086 "Unable to find the group OU for group %s", before[L_NAME]);
1090 com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
1091 rc = group_delete(ldap_handle, dn_path, before[L_NAME],
1092 before_group_membership, before_list_id);
1100 com_err(whoami, 0, "Creating group %s", after[L_NAME]);
1102 if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME],
1103 group_ou, group_membership,
1104 security_flag, CHECK_GROUPS,
1107 if (rc != AD_NO_GROUPS_FOUND)
1109 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
1110 (rc == AD_MULTIPLE_GROUPS_FOUND))
1112 rc = process_group(ldap_handle, dn_path, list_id,
1114 group_ou, group_membership,
1115 security_flag, CLEANUP_GROUPS,
1122 "Unable to create list %s", after[L_NAME]);
1129 com_err(whoami, 0, "Updating group %s information", after[L_NAME]);
1131 if (rc = moira_connect())
1133 critical_alert("AD incremental",
1134 "Error contacting Moira server : %s",
1141 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0,
1142 &ProcessGroup, after[L_MAILLIST]))
1147 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1,
1148 &ProcessGroup, after[L_MAILLIST]))
1152 if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME],
1153 group_ou, group_membership, security_flag,
1154 updateGroup, after[L_MAILLIST]))
1160 if (atoi(after[L_ACTIVE]))
1162 populate_group(ldap_handle, dn_path, after[L_NAME], group_ou,
1163 group_membership, security_flag, list_id);
1171 #define LM_EXTRA_ACTIVE (LM_END)
1172 #define LM_EXTRA_PUBLIC (LM_END+1)
1173 #define LM_EXTRA_HIDDEN (LM_END+2)
1174 #define LM_EXTRA_MAILLIST (LM_END+3)
1175 #define LM_EXTRA_GROUP (LM_END+4)
1176 #define LM_EXTRA_GID (LM_END+5)
1177 #define LMN_LIST_ID (LM_END+6)
1178 #define LM_LIST_ID (LM_END+7)
1179 #define LM_USER_ID (LM_END+8)
1180 #define LM_EXTRA_END (LM_END+9)
1182 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1183 char **before, int beforec, char **after, int afterc)
1185 LK_ENTRY *group_base;
1188 char *attr_array[3];
1189 char group_name[128];
1190 char user_name[128];
1191 char user_type[128];
1192 char moira_list_id[32];
1193 char moira_user_id[32];
1194 char group_membership[1];
1196 char machine_ou[256];
1204 char NewMachineName[1024];
1208 char *save_argv[U_END];
1212 memset(moira_list_id, '\0', sizeof(moira_list_id));
1213 memset(moira_user_id, '\0', sizeof(moira_user_id));
1217 if (afterc < LM_EXTRA_GID)
1220 if (!atoi(after[LM_EXTRA_ACTIVE]))
1223 "Unable to add %s to group %s : group not active",
1224 after[2], after[0]);
1230 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1233 strcpy(user_name, after[LM_MEMBER]);
1234 strcpy(group_name, after[LM_LIST]);
1235 strcpy(user_type, after[LM_TYPE]);
1237 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1239 if (afterc > LM_EXTRA_GROUP)
1241 strcpy(moira_list_id, after[LMN_LIST_ID]);
1242 strcpy(moira_user_id, after[LM_LIST_ID]);
1245 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1247 if (afterc > LMN_LIST_ID)
1249 strcpy(moira_list_id, after[LM_LIST_ID]);
1250 strcpy(moira_user_id, after[LM_USER_ID]);
1255 if (afterc > LM_EXTRA_GID)
1256 strcpy(moira_list_id, after[LMN_LIST_ID]);
1261 if (beforec < LM_EXTRA_GID)
1263 if (!atoi(before[LM_EXTRA_ACTIVE]))
1266 "Unable to add %s to group %s : group not active",
1267 before[2], before[0]);
1273 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1276 strcpy(user_name, before[LM_MEMBER]);
1277 strcpy(group_name, before[LM_LIST]);
1278 strcpy(user_type, before[LM_TYPE]);
1280 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1282 if (beforec > LM_EXTRA_GROUP)
1284 strcpy(moira_list_id, before[LMN_LIST_ID]);
1285 strcpy(moira_user_id, before[LM_LIST_ID]);
1288 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1290 if (beforec > LMN_LIST_ID)
1292 strcpy(moira_list_id, before[LM_LIST_ID]);
1293 strcpy(moira_user_id, before[LM_USER_ID]);
1298 if (beforec > LM_EXTRA_GID)
1299 strcpy(moira_list_id, before[LMN_LIST_ID]);
1306 "Unable to process group : beforec = %d, afterc = %d",
1311 args[L_NAME] = ptr[LM_LIST];
1312 args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
1313 args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
1314 args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
1315 args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
1316 args[L_GROUP] = ptr[LM_EXTRA_GROUP];
1317 args[L_GID] = ptr[LM_EXTRA_GID];
1320 memset(group_ou, '\0', sizeof(group_ou));
1321 get_group_membership(group_membership, group_ou, &security_flag, args);
1323 if (strlen(group_ou) == 0)
1325 com_err(whoami, 0, "Unable to find the group OU for group %s",
1330 if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name,
1331 group_ou, group_membership, security_flag,
1332 CHECK_GROUPS, args[L_MAILLIST]))
1334 if (rc != AD_NO_GROUPS_FOUND)
1336 if (rc = process_group(ldap_handle, dn_path, moira_list_id,
1337 group_name, group_ou, group_membership,
1338 security_flag, CLEANUP_GROUPS,
1341 if (rc != AD_NO_GROUPS_FOUND)
1344 com_err(whoami, 0, "Unable to add %s to group %s - "
1345 "unable to process group", user_name, group_name);
1347 com_err(whoami, 0, "Unable to remove %s from group %s - "
1348 "unable to process group", user_name, group_name);
1355 if (rc == AD_NO_GROUPS_FOUND)
1357 if (rc = moira_connect())
1359 critical_alert("AD incremental",
1360 "Error contacting Moira server : %s",
1365 com_err(whoami, 0, "creating group %s", group_name);
1368 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0,
1369 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
1374 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1,
1375 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
1379 if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST],
1380 group_ou, group_membership, security_flag, 0,
1381 ptr[LM_EXTRA_MAILLIST]))
1387 if (atoi(ptr[LM_EXTRA_ACTIVE]))
1389 populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou,
1390 group_membership, security_flag, moira_list_id);
1400 com_err(whoami, 0, "removing user %s from list %s", user_name,
1404 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1406 if (!ProcessMachineContainer)
1408 com_err(whoami, 0, "Process machines and containers disabled, "
1413 memset(machine_ou, '\0', sizeof(machine_ou));
1414 memset(NewMachineName, '\0', sizeof(NewMachineName));
1415 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER],
1416 machine_ou, NewMachineName))
1418 if (ptr[LM_MEMBER] != NULL)
1419 free(ptr[LM_MEMBER]);
1420 ptr[LM_MEMBER] = strdup(NewMachineName);
1421 pUserOu = machine_ou;
1424 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1426 strcpy(member, ptr[LM_MEMBER]);
1430 if((s = strchr(member, '@')) == (char *) NULL)
1432 strcat(member, "@mit.edu");
1434 if (ptr[LM_MEMBER] != NULL)
1435 free(ptr[LM_MEMBER]);
1436 ptr[LM_MEMBER] = strdup(member);
1439 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1441 s = strrchr(member, '.');
1443 strcat(s, ".mit.edu");
1445 if (ptr[LM_MEMBER] != NULL)
1446 free(ptr[LM_MEMBER]);
1447 ptr[LM_MEMBER] = strdup(member);
1451 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1455 pUserOu = contact_ou;
1457 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1459 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1463 pUserOu = kerberos_ou;
1466 if (rc = moira_connect()) {
1467 critical_alert("AD incremental",
1468 "Error contacting Moira server : %s",
1473 if (rc = populate_group(ldap_handle, dn_path, group_name,
1474 group_ou, group_membership,
1475 security_flag, moira_list_id))
1476 com_err(whoami, 0, "Unable to remove %s from group %s", user_name,
1481 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1483 if (rc = moira_connect())
1485 critical_alert("AD incremental",
1486 "Error contacting Moira server : %s",
1491 if (rc = populate_group(ldap_handle, dn_path, group_name,
1492 group_ou, group_membership, security_flag,
1494 com_err(whoami, 0, "Unable to remove %s from group %s",
1495 user_name, group_name);
1502 com_err(whoami, 0, "Adding %s to list %s", user_name, group_name);
1505 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1507 memset(machine_ou, '\0', sizeof(machine_ou));
1508 memset(NewMachineName, '\0', sizeof(NewMachineName));
1510 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou,
1514 if (ptr[LM_MEMBER] != NULL)
1515 free(ptr[LM_MEMBER]);
1517 ptr[LM_MEMBER] = strdup(NewMachineName);
1518 pUserOu = machine_ou;
1520 else if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1522 strcpy(member, ptr[LM_MEMBER]);
1526 if((s = strchr(member, '@')) == (char *) NULL)
1528 strcat(member, "@mit.edu");
1530 if (ptr[LM_MEMBER] != NULL)
1531 free(ptr[LM_MEMBER]);
1532 ptr[LM_MEMBER] = strdup(member);
1535 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1537 s = strrchr(member, '.');
1539 strcat(s, ".mit.edu");
1541 if (ptr[LM_MEMBER] != NULL)
1542 free(ptr[LM_MEMBER]);
1543 ptr[LM_MEMBER] = strdup(member);
1547 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1551 pUserOu = contact_ou;
1553 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1555 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1559 pUserOu = kerberos_ou;
1561 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1563 if ((rc = check_user(ldap_handle, dn_path, ptr[LM_MEMBER],
1564 moira_user_id)) == AD_NO_USER_FOUND)
1566 if (rc = moira_connect())
1568 critical_alert("AD incremental",
1569 "Error connection to Moira : %s",
1574 com_err(whoami, 0, "creating user %s", ptr[LM_MEMBER]);
1575 av[0] = ptr[LM_MEMBER];
1576 call_args[0] = (char *)ldap_handle;
1577 call_args[1] = dn_path;
1578 call_args[2] = moira_user_id;
1579 call_args[3] = NULL;
1588 sprintf(filter, "(&(objectClass=group)(cn=%s))", ptr[LM_MEMBER]);
1589 attr_array[0] = "cn";
1590 attr_array[1] = NULL;
1591 if ((rc = linklist_build(ldap_handle, dn_path, filter,
1592 attr_array, &group_base, &group_count,
1593 LDAP_SCOPE_SUBTREE)) != 0)
1595 com_err(whoami, 0, "Unable to process user %s : %s",
1596 ptr[LM_MEMBER], ldap_err2string(rc));
1602 com_err(whoami, 0, "Object already exists with name %s",
1607 linklist_free(group_base);
1612 if (rc = mr_query("get_user_account_by_login", 1, av,
1613 save_query_info, save_argv))
1616 com_err(whoami, 0, "Unable to create user %s : %s",
1617 ptr[LM_MEMBER], error_message(rc));
1621 if (rc = user_create(U_END, save_argv, call_args))
1624 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1631 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1643 if (rc = moira_connect()) {
1644 critical_alert("AD incremental",
1645 "Error contacting Moira server : %s",
1650 if (rc = populate_group(ldap_handle, dn_path, group_name,
1651 group_ou, group_membership, security_flag,
1653 com_err(whoami, 0, "Unable to add %s to group %s", user_name,
1658 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1660 if (rc = moira_connect())
1662 critical_alert("AD incremental",
1663 "Error contacting Moira server : %s",
1668 if (rc = populate_group(ldap_handle, dn_path, group_name,
1669 group_ou, group_membership, security_flag,
1671 com_err(whoami, 0, "Unable to add %s to group %s",
1672 user_name, group_name);
1681 #define U_USER_ID 10
1682 #define U_HOMEDIR 11
1683 #define U_PROFILEDIR 12
1685 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1686 char **before, int beforec, char **after,
1689 LK_ENTRY *group_base;
1692 char *attr_array[3];
1695 char after_user_id[32];
1696 char before_user_id[32];
1698 char *save_argv[U_END];
1700 if ((beforec == 0) && (afterc == 0))
1703 memset(after_user_id, '\0', sizeof(after_user_id));
1704 memset(before_user_id, '\0', sizeof(before_user_id));
1706 if (beforec > U_USER_ID)
1707 strcpy(before_user_id, before[U_USER_ID]);
1709 if (afterc > U_USER_ID)
1710 strcpy(after_user_id, after[U_USER_ID]);
1712 if ((beforec == 0) && (afterc == 0)) /*this case should never happen */
1715 if ((beforec == 0) && (afterc != 0))
1717 /*this case only happens when the account*/
1718 /*account is first created but not usable*/
1720 com_err(whoami, 0, "Unable to process user %s because the user account "
1721 "is not yet usable", after[U_NAME]);
1725 /*this case only happens when the account is expunged */
1727 if ((beforec != 0) && (afterc == 0))
1729 if (atoi(before[U_STATE]) == 0)
1731 com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]);
1732 user_delete(ldap_handle, dn_path, before[U_NAME], before_user_id);
1736 com_err(whoami, 0, "Unable to process because user %s has been "
1737 "previously expungeded", before[U_NAME]);
1742 /*process anything that gets here*/
1744 if ((rc = check_user(ldap_handle, dn_path, before[U_NAME],
1745 before_user_id)) == AD_NO_USER_FOUND)
1747 if (!check_string(after[U_NAME]))
1750 if (rc = moira_connect())
1752 critical_alert("AD incremental",
1753 "Error connection to Moira : %s",
1758 com_err(whoami, 0, "creating user %s", after[U_NAME]);
1760 av[0] = after[U_NAME];
1761 call_args[0] = (char *)ldap_handle;
1762 call_args[1] = dn_path;
1763 call_args[2] = after_user_id;
1764 call_args[3] = NULL;
1772 sprintf(filter, "(&(objectClass=group)(cn=%s))", after[U_NAME]);
1773 attr_array[0] = "cn";
1774 attr_array[1] = NULL;
1776 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
1777 &group_base, &group_count,
1778 LDAP_SCOPE_SUBTREE)) != 0)
1780 com_err(whoami, 0, "Unable to process user %s : %s",
1781 after[U_NAME], ldap_err2string(rc));
1785 if (group_count >= 1)
1787 com_err(whoami, 0, "Object already exists with name %s",
1792 linklist_free(group_base);
1797 if (rc = mr_query("get_user_account_by_login", 1, av,
1798 save_query_info, save_argv))
1801 com_err(whoami, 0, "Unable to create user %s : %s",
1802 after[U_NAME], error_message(rc));
1806 if (rc = user_create(U_END, save_argv, call_args))
1808 com_err(whoami, 0, "Unable to create user %s : %s",
1809 after[U_NAME], error_message(rc));
1816 com_err(whoami, 0, "Unable to create user %s", after[U_NAME]);
1828 if (strcmp(before[U_NAME], after[U_NAME]))
1830 if ((check_string(before[U_NAME])) && (check_string(after[U_NAME])))
1832 com_err(whoami, 0, "changing user %s to %s",
1833 before[U_NAME], after[U_NAME]);
1835 if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME],
1836 after[U_NAME])) != LDAP_SUCCESS)
1843 com_err(whoami, 0, "updating user %s information", after[U_NAME]);
1844 rc = user_update(ldap_handle, dn_path, after[U_NAME],
1845 after[U_UID], after[U_MITID],
1846 after_user_id, atoi(after[U_STATE]),
1847 after[U_HOMEDIR], after[U_PROFILEDIR],
1848 after[U_FIRST], after[U_MIDDLE], after[U_LAST],
1849 after[U_SHELL], after[U_CLASS]);
1854 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
1855 char *oldValue, char *newValue,
1856 char ***modvalues, int type)
1858 LK_ENTRY *linklist_ptr;
1862 if (((*modvalues) = calloc(1,
1863 (modvalue_count + 1) * sizeof(char *))) == NULL)
1868 for (i = 0; i < (modvalue_count + 1); i++)
1869 (*modvalues)[i] = NULL;
1871 if (modvalue_count != 0)
1873 linklist_ptr = linklist_base;
1874 for (i = 0; i < modvalue_count; i++)
1876 if ((oldValue != NULL) && (newValue != NULL))
1878 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1881 if (type == REPLACE)
1883 if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1886 memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1887 strcpy((*modvalues)[i], newValue);
1891 if (((*modvalues)[i] = calloc(1,
1892 (int)(cPtr - linklist_ptr->value) +
1893 (linklist_ptr->length -
1895 strlen(newValue) + 1)) == NULL)
1897 memset((*modvalues)[i], '\0',
1898 (int)(cPtr - linklist_ptr->value) +
1899 (linklist_ptr->length - strlen(oldValue)) +
1900 strlen(newValue) + 1);
1901 memcpy((*modvalues)[i], linklist_ptr->value,
1902 (int)(cPtr - linklist_ptr->value));
1903 strcat((*modvalues)[i], newValue);
1904 strcat((*modvalues)[i],
1905 &linklist_ptr->value[(int)(cPtr -
1906 linklist_ptr->value) + strlen(oldValue)]);
1911 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1912 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1913 memcpy((*modvalues)[i], linklist_ptr->value,
1914 linklist_ptr->length);
1919 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1920 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1921 memcpy((*modvalues)[i], linklist_ptr->value,
1922 linklist_ptr->length);
1924 linklist_ptr = linklist_ptr->next;
1926 (*modvalues)[i] = NULL;
1932 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
1933 char **attr_array, LK_ENTRY **linklist_base,
1934 int *linklist_count, unsigned long ScopeType)
1937 LDAPMessage *ldap_entry;
1941 (*linklist_base) = NULL;
1942 (*linklist_count) = 0;
1944 if ((rc = ldap_search_s(ldap_handle, dn_path, ScopeType,
1945 search_exp, attr_array, 0,
1946 &ldap_entry)) != LDAP_SUCCESS)
1948 if (rc != LDAP_SIZELIMIT_EXCEEDED)
1952 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base,
1955 ldap_msgfree(ldap_entry);
1959 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1960 LK_ENTRY **linklist_base, int *linklist_count)
1962 char distinguished_name[1024];
1963 LK_ENTRY *linklist_ptr;
1966 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1969 memset(distinguished_name, '\0', sizeof(distinguished_name));
1970 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1972 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1973 linklist_base)) != 0)
1976 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1978 memset(distinguished_name, '\0', sizeof(distinguished_name));
1979 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1981 if ((rc = retrieve_attributes(ldap_handle, ldap_entry,
1982 distinguished_name, linklist_base)) != 0)
1986 linklist_ptr = (*linklist_base);
1987 (*linklist_count) = 0;
1989 while (linklist_ptr != NULL)
1991 ++(*linklist_count);
1992 linklist_ptr = linklist_ptr->next;
1998 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1999 char *distinguished_name, LK_ENTRY **linklist_current)
2006 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry,
2009 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
2011 ldap_memfree(Attribute);
2012 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
2015 retrieve_values(ldap_handle, ldap_entry, Attribute,
2016 distinguished_name, linklist_current);
2017 ldap_memfree(Attribute);
2021 ldap_ber_free(ptr, 0);
2026 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
2027 char *Attribute, char *distinguished_name,
2028 LK_ENTRY **linklist_current)
2034 LK_ENTRY *linklist_previous;
2035 LDAP_BERVAL **ber_value;
2044 SID_IDENTIFIER_AUTHORITY *sid_auth;
2045 unsigned char *subauth_count;
2046 #endif /*LDAP_BEGUG*/
2049 memset(temp, '\0', sizeof(temp));
2051 if ((!strcmp(Attribute, "objectSid")) ||
2052 (!strcmp(Attribute, "objectGUID")))
2057 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
2058 Ptr = (void **)ber_value;
2063 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
2064 Ptr = (void **)str_value;
2072 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
2075 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
2076 linklist_previous->next = (*linklist_current);
2077 (*linklist_current) = linklist_previous;
2079 if (((*linklist_current)->attribute = calloc(1,
2080 strlen(Attribute) + 1)) == NULL)
2083 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
2084 strcpy((*linklist_current)->attribute, Attribute);
2088 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
2090 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
2093 memset((*linklist_current)->value, '\0', ber_length);
2094 memcpy((*linklist_current)->value,
2095 (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length);
2096 (*linklist_current)->length = ber_length;
2100 if (((*linklist_current)->value = calloc(1,
2101 strlen(*Ptr) + 1)) == NULL)
2104 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
2105 (*linklist_current)->length = strlen(*Ptr);
2106 strcpy((*linklist_current)->value, *Ptr);
2109 (*linklist_current)->ber_value = use_bervalue;
2111 if (((*linklist_current)->dn = calloc(1,
2112 strlen(distinguished_name) + 1)) == NULL)
2115 memset((*linklist_current)->dn, '\0',
2116 strlen(distinguished_name) + 1);
2117 strcpy((*linklist_current)->dn, distinguished_name);
2120 if (!strcmp(Attribute, "objectGUID"))
2122 guid = (GUID *)((*linklist_current)->value);
2124 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2125 guid->Data1, guid->Data2, guid->Data3,
2126 guid->Data4[0], guid->Data4[1], guid->Data4[2],
2127 guid->Data4[3], guid->Data4[4], guid->Data4[5],
2128 guid->Data4[6], guid->Data4[7]);
2129 print_to_screen(" %20s : {%s}\n", Attribute, temp);
2131 else if (!strcmp(Attribute, "objectSid"))
2133 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
2136 print_to_screen(" Revision = %d\n", sid->Revision);
2137 print_to_screen(" SID Identifier Authority:\n");
2138 sid_auth = &sid->IdentifierAuthority;
2139 if (sid_auth->Value[0])
2140 print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
2141 else if (sid_auth->Value[1])
2142 print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
2143 else if (sid_auth->Value[2])
2144 print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
2145 else if (sid_auth->Value[3])
2146 print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
2147 else if (sid_auth->Value[5])
2148 print_to_screen(" SECURITY_NT_AUTHORITY\n");
2150 print_to_screen(" UNKNOWN SID AUTHORITY\n");
2151 subauth_count = GetSidSubAuthorityCount(sid);
2152 print_to_screen(" SidSubAuthorityCount = %d\n",
2154 print_to_screen(" SidSubAuthority:\n");
2155 for (i = 0; i < *subauth_count; i++)
2157 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
2158 print_to_screen(" %u\n", *subauth);
2162 else if ((!memcmp(Attribute, "userAccountControl",
2163 strlen("userAccountControl"))) ||
2164 (!memcmp(Attribute, "sAMAccountType",
2165 strlen("sAmAccountType"))))
2167 intValue = atoi(*Ptr);
2168 print_to_screen(" %20s : %ld\n",Attribute, intValue);
2170 if (!memcmp(Attribute, "userAccountControl",
2171 strlen("userAccountControl")))
2173 if (intValue & UF_ACCOUNTDISABLE)
2174 print_to_screen(" %20s : %s\n",
2175 "", "Account disabled");
2177 print_to_screen(" %20s : %s\n",
2178 "", "Account active");
2179 if (intValue & UF_HOMEDIR_REQUIRED)
2180 print_to_screen(" %20s : %s\n",
2181 "", "Home directory required");
2182 if (intValue & UF_LOCKOUT)
2183 print_to_screen(" %20s : %s\n",
2184 "", "Account locked out");
2185 if (intValue & UF_PASSWD_NOTREQD)
2186 print_to_screen(" %20s : %s\n",
2187 "", "No password required");
2188 if (intValue & UF_PASSWD_CANT_CHANGE)
2189 print_to_screen(" %20s : %s\n",
2190 "", "Cannot change password");
2191 if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
2192 print_to_screen(" %20s : %s\n",
2193 "", "Temp duplicate account");
2194 if (intValue & UF_NORMAL_ACCOUNT)
2195 print_to_screen(" %20s : %s\n",
2196 "", "Normal account");
2197 if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
2198 print_to_screen(" %20s : %s\n",
2199 "", "Interdomain trust account");
2200 if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
2201 print_to_screen(" %20s : %s\n",
2202 "", "Workstation trust account");
2203 if (intValue & UF_SERVER_TRUST_ACCOUNT)
2204 print_to_screen(" %20s : %s\n",
2205 "", "Server trust account");
2210 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
2212 #endif /*LDAP_DEBUG*/
2215 if (str_value != NULL)
2216 ldap_value_free(str_value);
2218 if (ber_value != NULL)
2219 ldap_value_free_len(ber_value);
2222 (*linklist_current) = linklist_previous;
2227 int moira_connect(void)
2232 if (!mr_connections++)
2236 memset(HostName, '\0', sizeof(HostName));
2237 strcpy(HostName, "ttsp");
2238 rc = mr_connect_cl(HostName, "ldap.incr", QUERY_VERSION, 1);
2242 rc = mr_connect_cl(uts.nodename, "ldap.incr", QUERY_VERSION, 1);
2251 int check_winad(void)
2255 for (i = 0; file_exists(STOP_FILE); i++)
2259 critical_alert("AD incremental",
2260 "WINAD incremental failed (%s exists): %s",
2261 STOP_FILE, tbl_buf);
2271 int moira_disconnect(void)
2274 if (!--mr_connections)
2282 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
2283 char *distinguished_name)
2287 CName = ldap_get_dn(ldap_handle, ldap_entry);
2292 strcpy(distinguished_name, CName);
2293 ldap_memfree(CName);
2296 int linklist_create_entry(char *attribute, char *value,
2297 LK_ENTRY **linklist_entry)
2299 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
2301 if (!(*linklist_entry))
2306 memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
2307 (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
2308 memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
2309 strcpy((*linklist_entry)->attribute, attribute);
2310 (*linklist_entry)->value = calloc(1, strlen(value) + 1);
2311 memset((*linklist_entry)->value, '\0', strlen(value) + 1);
2312 strcpy((*linklist_entry)->value, value);
2313 (*linklist_entry)->length = strlen(value);
2314 (*linklist_entry)->next = NULL;
2319 void print_to_screen(const char *fmt, ...)
2323 va_start(pvar, fmt);
2324 vfprintf(stderr, fmt, pvar);
2329 int get_group_membership(char *group_membership, char *group_ou,
2330 int *security_flag, char **av)
2335 maillist_flag = atoi(av[L_MAILLIST]);
2336 group_flag = atoi(av[L_GROUP]);
2338 if (security_flag != NULL)
2339 (*security_flag) = 0;
2341 if ((maillist_flag) && (group_flag))
2343 if (group_membership != NULL)
2344 group_membership[0] = 'B';
2346 if (security_flag != NULL)
2347 (*security_flag) = 1;
2349 if (group_ou != NULL)
2350 strcpy(group_ou, group_ou_both);
2352 else if ((!maillist_flag) && (group_flag))
2354 if (group_membership != NULL)
2355 group_membership[0] = 'S';
2357 if (security_flag != NULL)
2358 (*security_flag) = 1;
2360 if (group_ou != NULL)
2361 strcpy(group_ou, group_ou_security);
2363 else if ((maillist_flag) && (!group_flag))
2365 if (group_membership != NULL)
2366 group_membership[0] = 'D';
2368 if (group_ou != NULL)
2369 strcpy(group_ou, group_ou_distribution);
2373 if (group_membership != NULL)
2374 group_membership[0] = 'N';
2376 if (group_ou != NULL)
2377 strcpy(group_ou, group_ou_neither);
2383 int group_rename(LDAP *ldap_handle, char *dn_path,
2384 char *before_group_name, char *before_group_membership,
2385 char *before_group_ou, int before_security_flag,
2386 char *before_desc, char *after_group_name,
2387 char *after_group_membership, char *after_group_ou,
2388 int after_security_flag, char *after_desc,
2389 char *MoiraId, char *filter, char *maillist)
2394 char new_dn_path[512];
2397 char mail_nickname[256];
2398 char proxy_address[256];
2399 char address_book[256];
2400 char *attr_array[3];
2401 char *mitMoiraId_v[] = {NULL, NULL};
2402 char *name_v[] = {NULL, NULL};
2403 char *samAccountName_v[] = {NULL, NULL};
2404 char *groupTypeControl_v[] = {NULL, NULL};
2405 char *mail_v[] = {NULL, NULL};
2406 char *proxy_address_v[] = {NULL, NULL};
2407 char *mail_nickname_v[] = {NULL, NULL};
2408 char *report_to_originator_v[] = {NULL, NULL};
2409 char *address_book_v[] = {NULL, NULL};
2410 char *legacy_exchange_dn_v[] = {NULL, NULL};
2411 u_int groupTypeControl;
2412 char groupTypeControlStr[80];
2413 char contact_mail[256];
2417 LK_ENTRY *group_base;
2419 int MailDisabled = 0;
2421 if(UseGroupUniversal)
2422 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2424 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2426 if (!check_string(before_group_name))
2429 "Unable to process invalid LDAP list name %s",
2431 return(AD_INVALID_NAME);
2434 if (!check_string(after_group_name))
2437 "Unable to process invalid LDAP list name %s", after_group_name);
2438 return(AD_INVALID_NAME);
2448 sprintf(filter, "(&(objectClass=user)(cn=%s))", after_group_name);
2449 attr_array[0] = "cn";
2450 attr_array[1] = NULL;
2452 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2453 &group_base, &group_count,
2454 LDAP_SCOPE_SUBTREE)) != 0)
2456 com_err(whoami, 0, "Unable to process group %s : %s",
2457 after_group_name, ldap_err2string(rc));
2463 com_err(whoami, 0, "Object already exists with name %s",
2468 linklist_free(group_base);
2477 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
2478 before_group_membership,
2479 MoiraId, "samAccountName", &group_base,
2480 &group_count, filter))
2483 if (group_count == 0)
2485 return(AD_NO_GROUPS_FOUND);
2488 if (group_count != 1)
2490 com_err(whoami, 0, "Unable to process multiple groups with "
2491 "MoiraId = %s exist in the AD", MoiraId);
2492 return(AD_MULTIPLE_GROUPS_FOUND);
2495 strcpy(old_dn, group_base->dn);
2497 linklist_free(group_base);
2500 attr_array[0] = "sAMAccountName";
2501 attr_array[1] = NULL;
2503 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2504 &group_base, &group_count,
2505 LDAP_SCOPE_SUBTREE)) != 0)
2507 com_err(whoami, 0, "Unable to get list %s dn : %s",
2508 after_group_name, ldap_err2string(rc));
2512 if (group_count != 1)
2515 "Unable to get sAMAccountName for group %s",
2517 return(AD_LDAP_FAILURE);
2520 strcpy(sam_name, group_base->value);
2521 linklist_free(group_base);
2525 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2526 sprintf(new_dn, "cn=%s", after_group_name);
2527 sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain));
2528 sprintf(contact_mail, "%s@mit.edu", after_group_name);
2529 sprintf(proxy_address, "SMTP:%s@%s", after_group_name,
2530 lowercase(ldap_domain));
2531 sprintf(mail_nickname, "%s", after_group_name);
2533 com_err(whoami, 0, "Old %s New %s,%s", old_dn, new_dn, new_dn_path);
2535 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
2536 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2538 com_err(whoami, 0, "Unable to rename list from %s to %s : %s",
2539 before_group_name, after_group_name, ldap_err2string(rc));
2543 name_v[0] = after_group_name;
2545 if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)],
2546 group_suffix, strlen(group_suffix)))
2548 sprintf(sam_name, "%s%s", after_group_name, group_suffix);
2553 "Unable to rename list from %s to %s : sAMAccountName not found",
2554 before_group_name, after_group_name);
2558 samAccountName_v[0] = sam_name;
2560 if (after_security_flag)
2561 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2563 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2564 groupTypeControl_v[0] = groupTypeControlStr;
2565 mitMoiraId_v[0] = MoiraId;
2567 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
2568 rc = attribute_update(ldap_handle, new_dn, after_desc, "description",
2571 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2572 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2573 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2574 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
2578 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2580 mail_nickname_v[0] = mail_nickname;
2581 proxy_address_v[0] = proxy_address;
2583 report_to_originator_v[0] = "TRUE";
2585 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2586 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2587 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2588 ADD_ATTR("reportToOriginator", report_to_originator_v,
2593 mail_nickname_v[0] = NULL;
2594 proxy_address_v[0] = NULL;
2596 legacy_exchange_dn_v[0] = NULL;
2597 address_book_v[0] = NULL;
2598 report_to_originator_v[0] = NULL;
2600 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2601 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2602 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2603 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2604 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2605 ADD_ATTR("reportToOriginator", report_to_originator_v,
2611 if(atoi(maillist) && email_isvalid(contact_mail))
2613 mail_v[0] = contact_mail;
2614 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2620 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2623 "Unable to modify list data for %s after renaming: %s",
2624 after_group_name, ldap_err2string(rc));
2627 for (i = 0; i < n; i++)
2633 int group_create(int ac, char **av, void *ptr)
2638 char new_group_name[256];
2639 char sam_group_name[256];
2640 char cn_group_name[256];
2642 char contact_mail[256];
2643 char mail_nickname[256];
2644 char proxy_address[256];
2645 char address_book[256];
2646 char *cn_v[] = {NULL, NULL};
2647 char *objectClass_v[] = {"top", "group", NULL};
2648 char *objectClass_ldap_v[] = {"top", "microsoftComTop", "securityPrincipal",
2649 "group", "mailRecipient", NULL};
2651 char *samAccountName_v[] = {NULL, NULL};
2652 char *altSecurityIdentities_v[] = {NULL, NULL};
2653 char *member_v[] = {NULL, NULL};
2654 char *name_v[] = {NULL, NULL};
2655 char *desc_v[] = {NULL, NULL};
2656 char *info_v[] = {NULL, NULL};
2657 char *mitMoiraId_v[] = {NULL, NULL};
2658 char *mitMoiraPublic_v[] = {NULL, NULL};
2659 char *mitMoiraHidden_v[] = {NULL, NULL};
2660 char *groupTypeControl_v[] = {NULL, NULL};
2661 char *mail_v[] = {NULL, NULL};
2662 char *proxy_address_v[] = {NULL, NULL};
2663 char *mail_nickname_v[] = {NULL, NULL};
2664 char *report_to_originator_v[] = {NULL, NULL};
2665 char *address_book_v[] = {NULL, NULL};
2666 char *legacy_exchange_dn_v[] = {NULL, NULL};
2667 char *gidNumber_v[] = {NULL, NULL};
2668 char groupTypeControlStr[80];
2669 char group_membership[1];
2672 u_int groupTypeControl;
2676 int MailDisabled = 0;
2678 LK_ENTRY *group_base;
2681 char *attr_array[3];
2685 if(UseGroupUniversal)
2686 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2688 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2690 if (!check_string(av[L_NAME]))
2692 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2694 return(AD_INVALID_NAME);
2697 updateGroup = (int)call_args[4];
2698 memset(group_ou, 0, sizeof(group_ou));
2699 memset(group_membership, 0, sizeof(group_membership));
2702 get_group_membership(group_membership, group_ou, &security_flag, av);
2704 strcpy(new_group_name, av[L_NAME]);
2705 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2706 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2707 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2708 sprintf(mail_nickname, "%s", av[L_NAME]);
2711 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2713 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2717 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2718 groupTypeControl_v[0] = groupTypeControlStr;
2720 strcpy(cn_group_name, av[L_NAME]);
2722 samAccountName_v[0] = sam_group_name;
2723 name_v[0] = new_group_name;
2724 cn_v[0] = new_group_name;
2727 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2731 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2735 mitMoiraPublic_v[0] = av[L_PUBLIC];
2736 mitMoiraHidden_v[0] = av[L_HIDDEN];
2737 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
2738 ADD_ATTR("mitMoiraPublic", mitMoiraPublic_v, LDAP_MOD_ADD);
2739 ADD_ATTR("mitMoiraHidden", mitMoiraHidden_v, LDAP_MOD_ADD);
2741 if(atoi(av[L_GROUP]))
2743 gidNumber_v[0] = av[L_GID];
2744 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_ADD);
2748 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2749 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2750 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2754 if(atoi(av[L_MAILLIST]))
2759 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2760 attr_array[0] = "cn";
2761 attr_array[1] = NULL;
2763 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2764 filter, attr_array, &group_base,
2766 LDAP_SCOPE_SUBTREE)) != 0)
2768 com_err(whoami, 0, "Unable to process group %s : %s",
2769 av[L_NAME], ldap_err2string(rc));
2775 com_err(whoami, 0, "Object already exists with name %s",
2780 linklist_free(group_base);
2785 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2787 mail_nickname_v[0] = mail_nickname;
2788 report_to_originator_v[0] = "TRUE";
2790 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2791 ADD_ATTR("reportToOriginator", report_to_originator_v,
2797 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2799 mail_v[0] = contact_mail;
2800 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2804 if (strlen(av[L_DESC]) != 0)
2806 desc_v[0] = av[L_DESC];
2807 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2810 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2812 if (strlen(av[L_ACE_NAME]) != 0)
2814 sprintf(info, "The Administrator of this list is: %s",
2817 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2820 if (strlen(call_args[5]) != 0)
2822 mitMoiraId_v[0] = call_args[5];
2823 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2828 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2830 for (i = 0; i < n; i++)
2833 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2835 com_err(whoami, 0, "Unable to create list %s in AD : %s",
2836 av[L_NAME], ldap_err2string(rc));
2842 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2844 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2845 "description", av[L_NAME]);
2846 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2848 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2853 if (strlen(call_args[5]) != 0)
2855 mitMoiraId_v[0] = call_args[5];
2856 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2859 if (!(atoi(av[L_ACTIVE])))
2862 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2865 if (!ActiveDirectory)
2867 mitMoiraPublic_v[0] = av[L_PUBLIC];
2868 mitMoiraHidden_v[0] = av[L_HIDDEN];
2869 ADD_ATTR("mitMoiraPublic", mitMoiraPublic_v, LDAP_MOD_REPLACE);
2870 ADD_ATTR("mitMoiraHidden", mitMoiraHidden_v, LDAP_MOD_REPLACE);
2872 if(atoi(av[L_GROUP]))
2874 gidNumber_v[0] = av[L_GID];
2875 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_REPLACE);
2879 ADD_ATTR("gidNumber", gidNumber_v, LDAP_MOD_REPLACE);
2885 if(atoi(av[L_MAILLIST]))
2890 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2891 attr_array[0] = "cn";
2892 attr_array[1] = NULL;
2894 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2895 filter, attr_array, &group_base,
2897 LDAP_SCOPE_SUBTREE)) != 0)
2899 com_err(whoami, 0, "Unable to process group %s : %s",
2900 av[L_NAME], ldap_err2string(rc));
2906 com_err(whoami, 0, "Object already exists with name %s",
2911 linklist_free(group_base);
2916 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2918 mail_nickname_v[0] = mail_nickname;
2919 report_to_originator_v[0] = "TRUE";
2921 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2922 ADD_ATTR("reportToOriginator", report_to_originator_v,
2928 mail_nickname_v[0] = NULL;
2929 proxy_address_v[0] = NULL;
2930 legacy_exchange_dn_v[0] = NULL;
2931 address_book_v[0] = NULL;
2932 report_to_originator_v[0] = NULL;
2934 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2935 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2936 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2937 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2939 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2940 ADD_ATTR("reportToOriginator", report_to_originator_v,
2946 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2948 mail_v[0] = contact_mail;
2949 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2954 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2963 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2965 for (i = 0; i < n; i++)
2968 if (rc != LDAP_SUCCESS)
2970 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2971 av[L_NAME], ldap_err2string(rc));
2978 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2979 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2981 return(LDAP_SUCCESS);
2984 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2985 char *TargetGroupName, int HiddenGroup,
2986 char *AceType, char *AceName)
2988 char filter_exp[1024];
2989 char *attr_array[5];
2990 char search_path[512];
2992 char TemplateDn[512];
2993 char TemplateSamName[128];
2995 char TargetSamName[128];
2996 char AceSamAccountName[128];
2998 unsigned char AceSid[128];
2999 unsigned char UserTemplateSid[128];
3000 char acBERBuf[N_SD_BER_BYTES];
3001 char GroupSecurityTemplate[256];
3002 char hide_addres_lists[256];
3003 char address_book[256];
3004 char *hide_address_lists_v[] = {NULL, NULL};
3005 char *address_book_v[] = {NULL, NULL};
3006 char *owner_v[] = {NULL, NULL};
3008 int UserTemplateSidCount;
3015 int array_count = 0;
3017 LK_ENTRY *group_base;
3018 LDAP_BERVAL **ppsValues;
3019 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3020 { N_SD_BER_BYTES, acBERBuf },
3023 LDAPControl *apsServerControls[] = {&sControl, NULL};
3026 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3027 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3028 BEREncodeSecurityBits(dwInfo, acBERBuf);
3030 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
3031 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
3032 attr_array[0] = "sAMAccountName";
3033 attr_array[1] = NULL;
3037 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3038 &group_base, &group_count,
3039 LDAP_SCOPE_SUBTREE) != 0))
3042 if (group_count != 1)
3044 linklist_free(group_base);
3048 strcpy(TargetDn, group_base->dn);
3049 strcpy(TargetSamName, group_base->value);
3050 linklist_free(group_base);
3054 UserTemplateSidCount = 0;
3055 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
3056 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
3057 memset(AceSid, '\0', sizeof(AceSid));
3062 if (strlen(AceName) != 0)
3064 if (!strcmp(AceType, "LIST"))
3066 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
3067 strcpy(root_ou, group_ou_root);
3069 else if (!strcmp(AceType, "USER"))
3071 sprintf(AceSamAccountName, "%s", AceName);
3072 strcpy(root_ou, user_ou);
3075 if (ActiveDirectory)
3077 if (strlen(AceSamAccountName) != 0)
3079 sprintf(search_path, "%s", dn_path);
3080 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
3081 attr_array[0] = "objectSid";
3082 attr_array[1] = NULL;
3086 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3087 attr_array, &group_base, &group_count,
3088 LDAP_SCOPE_SUBTREE) != 0))
3090 if (group_count == 1)
3092 strcpy(AceDn, group_base->dn);
3093 AceSidCount = group_base->length;
3094 memcpy(AceSid, group_base->value, AceSidCount);
3096 linklist_free(group_base);
3103 if (strlen(AceSamAccountName) != 0)
3105 sprintf(search_path, "%s", dn_path);
3106 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
3107 attr_array[0] = "samAccountName";
3108 attr_array[1] = NULL;
3112 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3113 attr_array, &group_base, &group_count,
3114 LDAP_SCOPE_SUBTREE) != 0))
3116 if (group_count == 1)
3118 strcpy(AceDn, group_base->dn);
3120 linklist_free(group_base);
3127 if (!ActiveDirectory)
3129 if (strlen(AceDn) != 0)
3131 owner_v[0] = strdup(AceDn);
3133 ADD_ATTR("owner", owner_v, LDAP_MOD_REPLACE);
3137 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3139 for (i = 0; i < n; i++)
3142 if (rc != LDAP_SUCCESS)
3143 com_err(whoami, 0, "Unable to set owner for group %s : %s",
3144 TargetGroupName, ldap_err2string(rc));
3150 if (AceSidCount == 0)
3152 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
3153 "have an AD SID.", TargetGroupName, AceName, AceType);
3154 com_err(whoami, 0, " Non-admin security group template will be used.");
3158 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3159 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
3160 attr_array[0] = "objectSid";
3161 attr_array[1] = NULL;
3166 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3167 attr_array, &group_base, &group_count,
3168 LDAP_SCOPE_SUBTREE) != 0))
3171 if ((rc != 0) || (group_count != 1))
3173 com_err(whoami, 0, "Unable to process user security template: %s",
3179 UserTemplateSidCount = group_base->length;
3180 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3182 linklist_free(group_base);
3189 if (AceSidCount == 0)
3191 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3192 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3196 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3197 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3202 if (AceSidCount == 0)
3204 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3205 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3209 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
3210 sprintf(filter_exp, "(sAMAccountName=%s)",
3211 NOT_HIDDEN_GROUP_WITH_ADMIN);
3215 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3216 attr_array[0] = "sAMAccountName";
3217 attr_array[1] = NULL;
3221 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3222 &group_base, &group_count,
3223 LDAP_SCOPE_SUBTREE) != 0))
3226 if (group_count != 1)
3228 linklist_free(group_base);
3229 com_err(whoami, 0, "Unable to process group security template: %s - "
3230 "security not set", GroupSecurityTemplate);
3234 strcpy(TemplateDn, group_base->dn);
3235 strcpy(TemplateSamName, group_base->value);
3236 linklist_free(group_base);
3240 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3241 rc = ldap_search_ext_s(ldap_handle,
3253 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3255 com_err(whoami, 0, "Unable to find group security template: %s - "
3256 "security not set", GroupSecurityTemplate);
3260 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3262 if (ppsValues == NULL)
3264 com_err(whoami, 0, "Unable to find group security descriptor for group "
3265 "%s - security not set", GroupSecurityTemplate);
3269 if (AceSidCount != 0)
3271 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3274 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3276 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3277 UserTemplateSidCount))
3279 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3287 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3288 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3294 hide_address_lists_v[0] = "TRUE";
3295 address_book_v[0] = NULL;
3296 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3298 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3300 hide_address_lists_v[0] = NULL;
3301 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3308 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3310 for (i = 0; i < n; i++)
3313 ldap_value_free_len(ppsValues);
3314 ldap_msgfree(psMsg);
3316 if (rc != LDAP_SUCCESS)
3318 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3319 TargetGroupName, ldap_err2string(rc));
3321 if (AceSidCount != 0)
3324 "Trying to set security for group %s without admin.",
3327 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3328 HiddenGroup, "", ""))
3330 com_err(whoami, 0, "Unable to set security for group %s.",
3341 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3342 char *group_membership, char *MoiraId)
3344 LK_ENTRY *group_base;
3350 if (!check_string(group_name))
3353 "Unable to process invalid LDAP list name %s", group_name);
3354 return(AD_INVALID_NAME);
3357 memset(filter, '\0', sizeof(filter));
3360 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3362 if (rc = ad_get_group(ldap_handle, temp, group_name,
3363 group_membership, MoiraId,
3364 "samAccountName", &group_base,
3365 &group_count, filter))
3368 if (group_count == 1)
3370 if ((rc = ldap_delete_s(ldap_handle, group_base->dn)) != LDAP_SUCCESS)
3372 linklist_free(group_base);
3373 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3374 group_name, ldap_err2string(rc));
3377 linklist_free(group_base);
3381 linklist_free(group_base);
3382 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
3383 return(AD_NO_GROUPS_FOUND);
3389 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3395 return(N_SD_BER_BYTES);
3398 int process_lists(int ac, char **av, void *ptr)
3403 char group_membership[2];
3409 memset(group_ou, '\0', sizeof(group_ou));
3410 memset(group_membership, '\0', sizeof(group_membership));
3411 get_group_membership(group_membership, group_ou, &security_flag, av);
3412 rc = populate_group((LDAP *)call_args[0], (char *)call_args[1],
3413 av[L_NAME], group_ou, group_membership,
3419 int member_list_build(int ac, char **av, void *ptr)
3427 strcpy(temp, av[ACE_NAME]);
3429 if (!check_string(temp))
3432 if (!strcmp(av[ACE_TYPE], "USER"))
3434 if (!((int)call_args[3] & MOIRA_USERS))
3437 else if (!strcmp(av[ACE_TYPE], "STRING"))
3441 if((s = strchr(temp, '@')) == (char *) NULL)
3443 strcat(temp, "@mit.edu");
3446 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3448 s = strrchr(temp, '.');
3450 strcat(s, ".mit.edu");
3454 if (!((int)call_args[3] & MOIRA_STRINGS))
3457 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3461 else if (!strcmp(av[ACE_TYPE], "LIST"))
3463 if (!((int)call_args[3] & MOIRA_LISTS))
3466 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3468 if (!((int)call_args[3] & MOIRA_KERBEROS))
3471 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3476 else if (!strcmp(av[ACE_TYPE], "MACHINE"))
3478 if (!((int)call_args[3] & MOIRA_MACHINE))
3484 linklist = member_base;
3488 if (!strcasecmp(temp, linklist->member))
3491 linklist = linklist->next;
3494 linklist = calloc(1, sizeof(LK_ENTRY));
3496 linklist->dn = NULL;
3497 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3498 strcpy(linklist->list, call_args[2]);
3499 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3500 strcpy(linklist->type, av[ACE_TYPE]);
3501 linklist->member = calloc(1, strlen(temp) + 1);
3502 strcpy(linklist->member, temp);
3503 linklist->next = member_base;
3504 member_base = linklist;
3509 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3510 char *group_ou, char *group_membership, char *user_name,
3511 char *UserOu, char *MoiraId)
3513 char distinguished_name[1024];
3517 char *attr_array[3];
3522 LK_ENTRY *group_base;
3526 if (!check_string(group_name))
3527 return(AD_INVALID_NAME);
3529 memset(filter, '\0', sizeof(filter));
3533 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3534 group_membership, MoiraId,
3535 "samAccountName", &group_base,
3536 &group_count, filter))
3539 if (group_count != 1)
3541 com_err(whoami, 0, "Unable to find list %s in AD",
3543 linklist_free(group_base);
3549 strcpy(distinguished_name, group_base->dn);
3550 linklist_free(group_base);
3556 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3560 if(!strcmp(UserOu, user_ou))
3561 sprintf(temp, "uid=%s,%s,%s", user_name, UserOu, dn_path);
3563 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3566 modvalues[0] = temp;
3567 modvalues[1] = NULL;
3570 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3572 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3574 for (i = 0; i < n; i++)
3577 if (rc == LDAP_UNWILLING_TO_PERFORM)
3580 if (rc != LDAP_SUCCESS)
3582 com_err(whoami, 0, "Unable to modify list %s members : %s",
3583 group_name, ldap_err2string(rc));
3587 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3591 if(!strcmp(UserOu, contact_ou) &&
3592 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3594 memset(temp, '\0', sizeof(temp));
3595 strcpy(temp, user_name);
3596 s = strchr(temp, '@');
3599 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3601 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3602 &group_base, &group_count,
3603 LDAP_SCOPE_SUBTREE) != 0))
3609 linklist_free(group_base);
3614 sprintf(filter, "(distinguishedName=%s)", temp);
3615 attr_array[0] = "memberOf";
3616 attr_array[1] = NULL;
3618 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3619 &group_base, &group_count,
3620 LDAP_SCOPE_SUBTREE) != 0))
3626 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3628 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3638 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3639 char *group_ou, char *group_membership, char *user_name,
3640 char *UserOu, char *MoiraId)
3642 char distinguished_name[1024];
3650 LK_ENTRY *group_base;
3653 if (!check_string(group_name))
3654 return(AD_INVALID_NAME);
3657 memset(filter, '\0', sizeof(filter));
3661 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3662 group_membership, MoiraId,
3663 "samAccountName", &group_base,
3664 &group_count, filter))
3667 if (group_count != 1)
3669 linklist_free(group_base);
3672 com_err(whoami, 0, "Unable to find list %s %d in AD",
3673 group_name, group_count);
3674 return(AD_MULTIPLE_GROUPS_FOUND);
3677 strcpy(distinguished_name, group_base->dn);
3678 linklist_free(group_base);
3684 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3688 if(!strcmp(UserOu, user_ou))
3689 sprintf(temp, "uid=%s,%s,%s", user_name, UserOu, dn_path);
3691 sprintf(temp, "cn=%s,%s,%s", user_name, UserOu, dn_path);
3694 modvalues[0] = temp;
3695 modvalues[1] = NULL;
3698 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3700 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3702 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
3705 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3707 if (rc == LDAP_UNWILLING_TO_PERFORM)
3711 for (i = 0; i < n; i++)
3714 if (rc != LDAP_SUCCESS)
3716 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3717 user_name, group_name, ldap_err2string(rc));
3723 int contact_remove_email(LDAP *ld, char *bind_path,
3724 LK_ENTRY **linklist_base, int linklist_current)
3728 char *mail_v[] = {NULL, NULL};
3736 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3737 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3738 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3739 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3742 gPtr = (*linklist_base);
3745 rc = ldap_modify_s(ld, gPtr->dn, mods);
3747 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3749 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3750 gPtr->dn, ldap_err2string(rc));
3757 for (i = 0; i < n; i++)
3763 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3766 LK_ENTRY *group_base;
3769 char cn_user_name[256];
3770 char contact_name[256];
3771 char mail_nickname[256];
3772 char proxy_address_internal[256];
3773 char proxy_address_external[256];
3774 char target_address[256];
3775 char internal_contact_name[256];
3778 char principal[256];
3779 char mit_address_book[256];
3780 char default_address_book[256];
3781 char contact_address_book[256];
3783 char *email_v[] = {NULL, NULL};
3784 char *cn_v[] = {NULL, NULL};
3785 char *contact_v[] = {NULL, NULL};
3786 char *uid_v[] = {NULL, NULL};
3787 char *mail_nickname_v[] = {NULL, NULL};
3788 char *proxy_address_internal_v[] = {NULL, NULL};
3789 char *proxy_address_external_v[] = {NULL, NULL};
3790 char *target_address_v[] = {NULL, NULL};
3791 char *mit_address_book_v[] = {NULL, NULL};
3792 char *default_address_book_v[] = {NULL, NULL};
3793 char *contact_address_book_v[] = {NULL, NULL};
3794 char *hide_address_lists_v[] = {NULL, NULL};
3795 char *attr_array[3];
3796 char *objectClass_v[] = {"top", "person",
3797 "organizationalPerson",
3799 char *objectClass_ldap_v[] = {"top", "person", "microsoftComTop",
3800 "inetOrgPerson", "organizationalPerson",
3801 "contact", "mailRecipient", "eduPerson",
3803 char *name_v[] = {NULL, NULL};
3804 char *desc_v[] = {NULL, NULL};
3811 char *mail_routing_v[] = {NULL, NULL};
3812 char *principal_v[] = {NULL, NULL};
3814 if (!check_string(user))
3816 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3817 return(AD_INVALID_NAME);
3821 strcpy(contact_name, mail);
3822 strcpy(internal_contact_name, mail);
3824 if((s = strchr(internal_contact_name, '@')) != NULL) {
3828 sprintf(cn_user_name,"CN=%s,%s,%s", escape_string(contact_name), group_ou,
3831 sprintf(target_address, "SMTP:%s", contact_name);
3832 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3833 sprintf(mail_nickname, "%s", internal_contact_name);
3835 cn_v[0] = cn_user_name;
3836 contact_v[0] = contact_name;
3839 desc_v[0] = "Auto account created by Moira";
3841 proxy_address_internal_v[0] = proxy_address_internal;
3842 proxy_address_external_v[0] = proxy_address_external;
3843 mail_nickname_v[0] = mail_nickname;
3844 target_address_v[0] = target_address;
3845 mit_address_book_v[0] = mit_address_book;
3846 default_address_book_v[0] = default_address_book;
3847 contact_address_book_v[0] = contact_address_book;
3848 strcpy(new_dn, cn_user_name);
3851 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3853 if(!ActiveDirectory)
3855 if(!strcmp(group_ou, contact_ou))
3856 sprintf(uid, "%s%s", contact_name, "_strings");
3858 if(!strcmp(group_ou, kerberos_ou))
3859 sprintf(uid, "%s%s", contact_name, "_kerberos");
3863 ADD_ATTR("sn", contact_v, LDAP_MOD_ADD);
3864 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
3869 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3873 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
3876 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3877 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3878 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3882 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3887 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3888 attr_array[0] = "cn";
3889 attr_array[1] = NULL;
3891 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3892 &group_base, &group_count,
3893 LDAP_SCOPE_SUBTREE)) != 0)
3895 com_err(whoami, 0, "Unable to process contact %s : %s",
3896 user, ldap_err2string(rc));
3902 com_err(whoami, 0, "Object already exists with name %s",
3907 linklist_free(group_base);
3911 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3912 attr_array[0] = "cn";
3913 attr_array[1] = NULL;
3915 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3916 &group_base, &group_count,
3917 LDAP_SCOPE_SUBTREE)) != 0)
3919 com_err(whoami, 0, "Unable to process contact %s : %s",
3920 user, ldap_err2string(rc));
3926 com_err(whoami, 0, "Object already exists with name %s",
3931 linklist_free(group_base);
3935 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3936 attr_array[0] = "cn";
3937 attr_array[1] = NULL;
3939 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3940 &group_base, &group_count,
3941 LDAP_SCOPE_SUBTREE)) != 0)
3943 com_err(whoami, 0, "Unable to process contact %s : %s",
3944 user, ldap_err2string(rc));
3950 com_err(whoami, 0, "Object already exists with name %s",
3955 linklist_free(group_base);
3959 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3960 attr_array[0] = "cn";
3961 attr_array[1] = NULL;
3963 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3964 &group_base, &group_count,
3965 LDAP_SCOPE_SUBTREE)) != 0)
3967 com_err(whoami, 0, "Unable to process contact %s : %s",
3968 user, ldap_err2string(rc));
3974 com_err(whoami, 0, "Object already exists with name %s",
3979 linklist_free(group_base);
3983 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3984 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3985 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3986 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3988 hide_address_lists_v[0] = "TRUE";
3989 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3994 if(!ActiveDirectory)
3996 if((c = strchr(mail, '@')) == NULL)
3997 sprintf(temp, "%s@mit.edu", mail);
3999 sprintf(temp, "%s", mail);
4001 mail_routing_v[0] = temp;
4003 principal_v[0] = principal;
4005 if(!strcmp(group_ou, contact_ou))
4007 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
4010 if(!strcmp(group_ou, contact_ou))
4012 ADD_ATTR("eduPersonPrincipalName", mail_routing_v, LDAP_MOD_ADD);
4018 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
4020 for (i = 0; i < n; i++)
4025 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS) &&
4026 !strcmp(group_ou, contact_ou) && email_isvalid(mail))
4030 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
4031 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4032 ADD_ATTR("proxyAddresses", proxy_address_external_v,
4034 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
4036 hide_address_lists_v[0] = "TRUE";
4037 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4041 rc = ldap_modify_s(ld, new_dn, mods);
4045 com_err(whoami, 0, "Unable to update contact %s", mail);
4048 for (i = 0; i < n; i++)
4053 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4056 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
4060 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4064 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
4067 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
4068 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4069 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
4071 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
4073 for (i = 0; i < n; i++)
4077 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4079 com_err(whoami, 0, "Unable to create contact %s : %s",
4080 user, ldap_err2string(rc));
4087 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
4088 char *Uid, char *MitId, char *MoiraId, int State,
4089 char *WinHomeDir, char *WinProfileDir, char *first,
4090 char *middle, char *last, char *shell, char *class)
4093 LK_ENTRY *group_base;
4095 char distinguished_name[512];
4096 char displayName[256];
4097 char *mitMoiraId_v[] = {NULL, NULL};
4098 char *mitMoiraClass_v[] = {NULL, NULL};
4099 char *mitMoiraStatus_v[] = {NULL, NULL};
4100 char *uid_v[] = {NULL, NULL};
4101 char *mitid_v[] = {NULL, NULL};
4102 char *homedir_v[] = {NULL, NULL};
4103 char *winProfile_v[] = {NULL, NULL};
4104 char *drives_v[] = {NULL, NULL};
4105 char *userAccountControl_v[] = {NULL, NULL};
4106 char *alt_recipient_v[] = {NULL, NULL};
4107 char *hide_address_lists_v[] = {NULL, NULL};
4108 char *mail_v[] = {NULL, NULL};
4109 char *gid_v[] = {NULL, NULL};
4110 char *loginshell_v[] = {NULL, NULL};
4111 char *principal_v[] = {NULL, NULL};
4112 char userAccountControlStr[80];
4117 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4118 UF_PASSWD_CANT_CHANGE;
4120 char *attr_array[3];
4123 char contact_mail[256];
4124 char filter_exp[1024];
4125 char search_path[512];
4126 char TemplateDn[512];
4127 char TemplateSamName[128];
4128 char alt_recipient[256];
4129 char principal[256];
4131 char acBERBuf[N_SD_BER_BYTES];
4132 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4133 { N_SD_BER_BYTES, acBERBuf },
4135 LDAPControl *apsServerControls[] = {&sControl, NULL};
4137 LDAP_BERVAL **ppsValues;
4141 char *homeServerName;
4143 char search_string[256];
4145 char *mail_routing_v[] = {NULL, NULL};
4148 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4149 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4150 BEREncodeSecurityBits(dwInfo, acBERBuf);
4152 if (!check_string(user_name))
4154 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4156 return(AD_INVALID_NAME);
4159 memset(contact_mail, '\0', sizeof(contact_mail));
4160 sprintf(contact_mail, "%s@mit.edu", user_name);
4161 memset(mail, '\0', sizeof(mail));
4162 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4163 memset(alt_recipient, '\0', sizeof(alt_recipient));
4164 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4166 sprintf(search_string, "@%s", uppercase(ldap_domain));
4170 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4172 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4179 memset(displayName, '\0', sizeof(displayName));
4181 if (strlen(MoiraId) != 0)
4185 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4190 "(&(objectClass=mitPerson)(mitMoiraId=%s))", MoiraId);
4193 attr_array[0] = "cn";
4194 attr_array[1] = NULL;
4195 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4196 &group_base, &group_count,
4197 LDAP_SCOPE_SUBTREE)) != 0)
4199 com_err(whoami, 0, "Unable to process user %s : %s",
4200 user_name, ldap_err2string(rc));
4205 if (group_count != 1)
4207 linklist_free(group_base);
4210 sprintf(filter, "(sAMAccountName=%s)", user_name);
4211 attr_array[0] = "cn";
4212 attr_array[1] = NULL;
4213 sprintf(temp, "%s,%s", user_ou, dn_path);
4214 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
4215 &group_base, &group_count,
4216 LDAP_SCOPE_SUBTREE)) != 0)
4218 com_err(whoami, 0, "Unable to process user %s : %s",
4219 user_name, ldap_err2string(rc));
4224 if (group_count != 1)
4226 com_err(whoami, 0, "Unable to find user %s in AD",
4228 linklist_free(group_base);
4229 return(AD_NO_USER_FOUND);
4232 strcpy(distinguished_name, group_base->dn);
4234 linklist_free(group_base);
4237 if(!ActiveDirectory)
4239 if (rc = moira_connect())
4241 critical_alert("AD incremental",
4242 "Error contacting Moira server : %s",
4247 argv[0] = user_name;
4249 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4252 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_REPLACE);
4254 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4256 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
4261 "Unable to set the mailRoutingAddress for %s : %s",
4262 user_name, ldap_err2string(rc));
4264 p = strdup(save_argv[3]);
4266 if((c = strchr(p, ',')) != NULL)
4271 if ((c = strchr(q, '@')) == NULL)
4272 sprintf(temp, "%s@mit.edu", q);
4274 sprintf(temp, "%s", q);
4276 if(email_isvalid(temp) && State != US_DELETED)
4278 mail_routing_v[0] = temp;
4281 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
4283 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4285 if (rc == LDAP_ALREADY_EXISTS ||
4286 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4291 "Unable to set the mailRoutingAddress for %s : %s",
4292 user_name, ldap_err2string(rc));
4295 while((q = strtok(NULL, ",")) != NULL) {
4298 if((c = strchr(q, '@')) == NULL)
4299 sprintf(temp, "%s@mit.edu", q);
4301 sprintf(temp, "%s", q);
4303 if(email_isvalid(temp) && State != US_DELETED)
4305 mail_routing_v[0] = temp;
4308 ADD_ATTR("mailRoutingAddress", mail_routing_v,
4311 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4313 if (rc == LDAP_ALREADY_EXISTS ||
4314 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4319 "Unable to set the mailRoutingAddress for "
4321 user_name, ldap_err2string(rc));
4327 if((c = strchr(p, '@')) == NULL)
4328 sprintf(temp, "%s@mit.edu", p);
4330 sprintf(temp, "%s", p);
4332 if(email_isvalid(temp) && State != US_DELETED)
4334 mail_routing_v[0] = temp;
4337 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
4339 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4341 if (rc == LDAP_ALREADY_EXISTS ||
4342 rc == LDAP_TYPE_OR_VALUE_EXISTS)
4347 "Unable to set the mailRoutingAddress for %s : %s",
4348 user_name, ldap_err2string(rc));
4355 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
4356 rc = attribute_update(ldap_handle, distinguished_name, MitId,
4357 "employeeID", user_name);
4359 rc = attribute_update(ldap_handle, distinguished_name, "none",
4360 "employeeID", user_name);
4363 strcat(displayName, first);
4366 if(strlen(middle)) {
4368 strcat(displayName, " ");
4370 strcat(displayName, middle);
4374 if(strlen(middle) || strlen(first))
4375 strcat(displayName, " ");
4377 strcat(displayName, last);
4380 if(strlen(displayName))
4381 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4382 "displayName", user_name);
4384 rc = attribute_update(ldap_handle, distinguished_name, user_name,
4385 "displayName", user_name);
4387 if(!ActiveDirectory)
4389 if(strlen(displayName))
4390 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4393 rc = attribute_update(ldap_handle, distinguished_name, user_name,
4397 if(!ActiveDirectory)
4399 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4400 "eduPersonNickname", user_name);
4404 rc = attribute_update(ldap_handle, distinguished_name, first,
4405 "givenName", user_name);
4407 rc = attribute_update(ldap_handle, distinguished_name, "",
4408 "givenName", user_name);
4410 if(strlen(middle) == 1)
4411 rc = attribute_update(ldap_handle, distinguished_name, middle,
4412 "initials", user_name);
4414 rc = attribute_update(ldap_handle, distinguished_name, "",
4415 "initials", user_name);
4418 rc = attribute_update(ldap_handle, distinguished_name, last,
4421 rc = attribute_update(ldap_handle, distinguished_name, "",
4426 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4431 rc = attribute_update(ldap_handle, distinguished_name, user_name, "uid",
4435 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4436 "mitMoiraId", user_name);
4445 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4449 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4454 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4455 sprintf(status, "%d", State);
4456 principal_v[0] = principal;
4457 loginshell_v[0] = shell;
4458 mitMoiraClass_v[0] = class;
4459 mitMoiraStatus_v[0] = status;
4461 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4462 ADD_ATTR("gidNumber", gid_v, LDAP_MOD_REPLACE);
4463 ADD_ATTR("loginShell", loginshell_v, LDAP_MOD_REPLACE);
4464 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_REPLACE);
4465 ADD_ATTR("mitMoiraClass", mitMoiraClass_v, LDAP_MOD_REPLACE);
4466 ADD_ATTR("mitMoiraStatus", mitMoiraStatus_v, LDAP_MOD_REPLACE);
4469 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4471 userAccountControl |= UF_ACCOUNTDISABLE;
4475 hide_address_lists_v[0] = "TRUE";
4476 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4484 hide_address_lists_v[0] = NULL;
4485 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4490 sprintf(userAccountControlStr, "%ld", userAccountControl);
4491 userAccountControl_v[0] = userAccountControlStr;
4492 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4496 if (rc = moira_connect())
4498 critical_alert("AD incremental",
4499 "Error contacting Moira server : %s",
4504 argv[0] = user_name;
4506 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4508 if(!strcmp(save_argv[1], "EXCHANGE") ||
4509 (strstr(save_argv[3], search_string) != NULL))
4511 alt_recipient_v[0] = NULL;
4512 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4514 argv[0] = exchange_acl;
4516 argv[2] = user_name;
4518 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4520 if ((rc) && (rc != MR_EXISTS))
4522 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4523 user_name, exchange_acl, error_message(rc));
4528 alt_recipient_v[0] = alt_recipient;
4529 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4531 argv[0] = exchange_acl;
4533 argv[2] = user_name;
4535 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4537 if ((rc) && (rc != MR_NO_MATCH))
4540 "Unable to remove user %s from %s: %s, %d",
4541 user_name, exchange_acl, error_message(rc), rc);
4547 alt_recipient_v[0] = alt_recipient;
4548 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4550 argv[0] = exchange_acl;
4552 argv[2] = user_name;
4554 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4556 if ((rc) && (rc != MR_NO_MATCH))
4559 "Unable to remove user %s from %s: %s, %d",
4560 user_name, exchange_acl, error_message(rc), rc);
4568 mail_v[0] = contact_mail;
4569 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4572 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4573 WinProfileDir, homedir_v, winProfile_v,
4574 drives_v, mods, LDAP_MOD_REPLACE, n);
4578 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4579 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4580 attr_array[0] = "sAMAccountName";
4581 attr_array[1] = NULL;
4585 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
4587 &group_base, &group_count,
4588 LDAP_SCOPE_SUBTREE) != 0))
4591 if (group_count != 1)
4593 com_err(whoami, 0, "Unable to process user security template: %s - "
4594 "security not set", "UserTemplate.u");
4598 strcpy(TemplateDn, group_base->dn);
4599 strcpy(TemplateSamName, group_base->value);
4600 linklist_free(group_base);
4604 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4605 filter_exp, NULL, 0, apsServerControls, NULL,
4608 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4610 com_err(whoami, 0, "Unable to find user security template: %s - "
4611 "security not set", "UserTemplate.u");
4615 ppsValues = ldap_get_values_len(ldap_handle, psMsg,
4616 "ntSecurityDescriptor");
4618 if (ppsValues == NULL)
4620 com_err(whoami, 0, "Unable to find user security template: %s - "
4621 "security not set", "UserTemplate.u");
4625 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4626 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4631 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4632 mods)) != LDAP_SUCCESS)
4634 OldUseSFU30 = UseSFU30;
4635 SwitchSFU(mods, &UseSFU30, n);
4636 if (OldUseSFU30 != UseSFU30)
4637 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4640 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4641 user_name, ldap_err2string(rc));
4645 for (i = 0; i < n; i++)
4651 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4659 char contact_mail[256];
4660 char proxy_address[256];
4661 char query_base_dn[256];
4663 char *userPrincipalName_v[] = {NULL, NULL};
4664 char *altSecurityIdentities_v[] = {NULL, NULL};
4665 char *name_v[] = {NULL, NULL};
4666 char *samAccountName_v[] = {NULL, NULL};
4667 char *mail_v[] = {NULL, NULL};
4668 char *mail_nickname_v[] = {NULL, NULL};
4669 char *proxy_address_v[] = {NULL, NULL};
4670 char *query_base_dn_v[] = {NULL, NULL};
4671 char *principal_v[] = {NULL, NULL};
4672 char principal[256];
4677 if (!check_string(before_user_name))
4680 "Unable to process invalid LDAP user name %s", before_user_name);
4681 return(AD_INVALID_NAME);
4684 if (!check_string(user_name))
4687 "Unable to process invalid LDAP user name %s", user_name);
4688 return(AD_INVALID_NAME);
4691 strcpy(user_name, user_name);
4694 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4696 sprintf(old_dn, "uid=%s,%s,%s", before_user_name, user_ou, dn_path);
4699 sprintf(new_dn, "cn=%s", user_name);
4701 sprintf(new_dn, "uid=%s", user_name);
4703 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4704 sprintf(contact_mail, "%s@mit.edu", user_name);
4705 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4706 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4708 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4709 NULL, NULL)) != LDAP_SUCCESS)
4711 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4712 before_user_name, user_name, ldap_err2string(rc));
4718 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4721 if(rc = ldap_delete_s(ldap_handle, temp))
4723 com_err(whoami, 0, "Unable to delete user contact for %s",
4727 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4729 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4733 name_v[0] = user_name;
4734 sprintf(upn, "%s@%s", user_name, ldap_domain);
4735 userPrincipalName_v[0] = upn;
4736 principal_v[0] = principal;
4737 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4738 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4739 altSecurityIdentities_v[0] = temp;
4740 samAccountName_v[0] = user_name;
4742 mail_nickname_v[0] = user_name;
4743 proxy_address_v[0] = proxy_address;
4744 query_base_dn_v[0] = query_base_dn;
4747 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4748 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4749 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4750 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4752 if(!ActiveDirectory)
4754 ADD_ATTR("uid", samAccountName_v, LDAP_MOD_REPLACE);
4755 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_REPLACE);
4756 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4757 ADD_ATTR("eduPersonNickname", name_v, LDAP_MOD_REPLACE);
4762 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4763 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4764 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4765 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4769 mail_v[0] = contact_mail;
4770 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4776 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4778 sprintf(new_dn, "uid=%s,%s,%s", user_name, user_ou, dn_path);
4780 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4783 "Unable to modify user data for %s after renaming : %s",
4784 user_name, ldap_err2string(rc));
4787 for (i = 0; i < n; i++)
4793 int user_create(int ac, char **av, void *ptr)
4797 char user_name[256];
4801 char contact_mail[256];
4802 char proxy_address[256];
4803 char mail_nickname[256];
4804 char query_base_dn[256];
4805 char displayName[256];
4806 char address_book[256];
4807 char alt_recipient[256];
4808 char *cn_v[] = {NULL, NULL};
4809 char *objectClass_v[] = {"top", "person", "organizationalPerson",
4811 char *objectClass_ldap_v[] = {"top",
4812 "eduPerson", "posixAccount",
4813 "apple-user", "shadowAccount",
4814 "microsoftComTop", "securityPrincipal",
4815 "inetOrgPerson", "user",
4816 "organizationalPerson", "person",
4817 "mailRecipient", NULL};
4819 char *samAccountName_v[] = {NULL, NULL};
4820 char *altSecurityIdentities_v[] = {NULL, NULL};
4821 char *mitMoiraId_v[] = {NULL, NULL};
4822 char *mitMoiraClass_v[] = {NULL, NULL};
4823 char *mitMoiraStatus_v[] = {NULL, NULL};
4824 char *name_v[] = {NULL, NULL};
4825 char *desc_v[] = {NULL, NULL};
4826 char *userPrincipalName_v[] = {NULL, NULL};
4827 char *userAccountControl_v[] = {NULL, NULL};
4828 char *uid_v[] = {NULL, NULL};
4829 char *gid_v[] = {NULL, NULL};
4830 char *mitid_v[] = {NULL, NULL};
4831 char *homedir_v[] = {NULL, NULL};
4832 char *winProfile_v[] = {NULL, NULL};
4833 char *drives_v[] = {NULL, NULL};
4834 char *mail_v[] = {NULL, NULL};
4835 char *givenName_v[] = {NULL, NULL};
4836 char *sn_v[] = {NULL, NULL};
4837 char *initials_v[] = {NULL, NULL};
4838 char *displayName_v[] = {NULL, NULL};
4839 char *proxy_address_v[] = {NULL, NULL};
4840 char *mail_nickname_v[] = {NULL, NULL};
4841 char *query_base_dn_v[] = {NULL, NULL};
4842 char *address_book_v[] = {NULL, NULL};
4843 char *homeMDB_v[] = {NULL, NULL};
4844 char *homeServerName_v[] = {NULL, NULL};
4845 char *mdbUseDefaults_v[] = {NULL, NULL};
4846 char *mailbox_guid_v[] = {NULL, NULL};
4847 char *user_culture_v[] = {NULL, NULL};
4848 char *user_account_control_v[] = {NULL, NULL};
4849 char *msexch_version_v[] = {NULL, NULL};
4850 char *alt_recipient_v[] = {NULL, NULL};
4851 char *hide_address_lists_v[] = {NULL, NULL};
4852 char *principal_v[] = {NULL, NULL};
4853 char *loginshell_v[] = {NULL, NULL};
4854 char userAccountControlStr[80];
4856 char principal[256];
4857 char filter_exp[1024];
4858 char search_path[512];
4859 char *attr_array[3];
4860 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4861 UF_PASSWD_CANT_CHANGE;
4867 char WinHomeDir[1024];
4868 char WinProfileDir[1024];
4870 char *homeServerName;
4872 char acBERBuf[N_SD_BER_BYTES];
4873 LK_ENTRY *group_base;
4875 char TemplateDn[512];
4876 char TemplateSamName[128];
4877 LDAP_BERVAL **ppsValues;
4878 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4879 { N_SD_BER_BYTES, acBERBuf },
4881 LDAPControl *apsServerControls[] = {&sControl, NULL};
4885 char search_string[256];
4886 char *o_v[] = {NULL, NULL};
4888 char *mail_routing_v[] = {NULL, NULL};
4893 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4894 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4895 BEREncodeSecurityBits(dwInfo, acBERBuf);
4897 if (!check_string(av[U_NAME]))
4899 callback_rc = AD_INVALID_NAME;
4900 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4902 return(AD_INVALID_NAME);
4905 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4906 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4907 memset(displayName, '\0', sizeof(displayName));
4908 memset(query_base_dn, '\0', sizeof(query_base_dn));
4909 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4910 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4911 strcpy(user_name, av[U_NAME]);
4912 sprintf(upn, "%s@%s", user_name, ldap_domain);
4913 sprintf(sam_name, "%s", av[U_NAME]);
4915 if(strlen(av[U_FIRST])) {
4916 strcat(displayName, av[U_FIRST]);
4919 if(strlen(av[U_MIDDLE])) {
4920 if(strlen(av[U_FIRST]))
4921 strcat(displayName, " ");
4923 strcat(displayName, av[U_MIDDLE]);
4926 if(strlen(av[U_LAST])) {
4927 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]))
4928 strcat(displayName, " ");
4930 strcat(displayName, av[U_LAST]);
4933 samAccountName_v[0] = sam_name;
4934 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4935 (atoi(av[U_STATE]) != US_REGISTERED))
4937 userAccountControl |= UF_ACCOUNTDISABLE;
4941 hide_address_lists_v[0] = "TRUE";
4942 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4947 sprintf(userAccountControlStr, "%ld", userAccountControl);
4948 userAccountControl_v[0] = userAccountControlStr;
4949 userPrincipalName_v[0] = upn;
4952 cn_v[0] = user_name;
4954 cn_v[0] = displayName;
4956 name_v[0] = user_name;
4957 desc_v[0] = "Auto account created by Moira";
4959 givenName_v[0] = av[U_FIRST];
4962 sn_v[0] = av[U_LAST];
4964 if(strlen(av[U_LAST]))
4965 sn_v[0] = av[U_LAST];
4967 sn_v[0] = av[U_NAME];
4969 displayName_v[0] = displayName;
4970 mail_nickname_v[0] = user_name;
4971 o_v[0] = "Massachusetts Institute of Technology";
4973 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4974 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4975 altSecurityIdentities_v[0] = temp;
4976 principal_v[0] = principal;
4979 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4981 sprintf(new_dn, "uid=%s,%s,%s", user_name, user_ou, call_args[1]);
4983 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4984 sprintf(contact_mail, "%s@mit.edu", user_name);
4985 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4986 query_base_dn_v[0] = query_base_dn;
4987 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4989 sprintf(search_string, "@%s", uppercase(ldap_domain));
4993 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4996 com_err(whoami, 0, "Unable to create user contact %s",
5000 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
5003 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
5007 com_err(whoami, 0, "homeMDB:%s", homeMDB);
5008 com_err(whoami, 0, "homeServerName:%s", homeServerName);
5010 homeMDB_v[0] = homeMDB;
5011 homeServerName_v[0] = homeServerName;
5016 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
5020 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
5024 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
5027 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
5028 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
5029 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
5030 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
5031 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
5035 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
5036 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
5037 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
5038 mdbUseDefaults_v[0] = "TRUE";
5039 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
5040 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
5042 argv[0] = user_name;
5044 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
5046 if(!strcmp(save_argv[1], "EXCHANGE") ||
5047 (strstr(save_argv[3], search_string) != NULL))
5049 argv[0] = exchange_acl;
5051 argv[2] = user_name;
5053 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
5055 if ((rc) && (rc != MR_EXISTS))
5057 com_err(whoami, 0, "Unable to add user %s to %s: %s",
5058 user_name, exchange_acl, error_message(rc));
5063 alt_recipient_v[0] = alt_recipient;
5064 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
5069 alt_recipient_v[0] = alt_recipient;
5070 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
5072 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
5077 mail_v[0] = contact_mail;
5078 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
5081 if(strlen(av[U_FIRST])) {
5082 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
5085 if(strlen(av[U_LAST]) || strlen(av[U_NAME])) {
5086 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
5089 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
5090 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
5092 if(!ActiveDirectory)
5094 ADD_ATTR("eduPersonNickname", displayName_v, LDAP_MOD_ADD);
5097 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
5099 if(!ActiveDirectory)
5101 ADD_ATTR("eduPersonNickname", name_v, LDAP_MOD_ADD);
5105 if (strlen(av[U_MIDDLE]) == 1) {
5106 initials_v[0] = av[U_MIDDLE];
5107 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
5110 if (strlen(call_args[2]) != 0)
5112 mitMoiraId_v[0] = call_args[2];
5113 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
5116 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
5118 if(!ActiveDirectory)
5120 loginshell_v[0] = av[U_SHELL];
5121 mitMoiraClass_v[0] = av[U_CLASS];
5122 mitMoiraStatus_v[0] = av[U_STATE];
5123 ADD_ATTR("loginShell", loginshell_v, LDAP_MOD_ADD);
5124 ADD_ATTR("uid", samAccountName_v, LDAP_MOD_ADD);
5125 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_ADD);
5126 ADD_ATTR("o", o_v, LDAP_MOD_ADD);
5127 ADD_ATTR("mitMoiraClass", mitMoiraClass_v, LDAP_MOD_ADD);
5128 ADD_ATTR("mitMoiraStatus", mitMoiraStatus_v, LDAP_MOD_ADD);
5131 if (strlen(av[U_UID]) != 0)
5133 uid_v[0] = av[U_UID];
5137 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
5142 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
5143 ADD_ATTR("gidNumber", gid_v, LDAP_MOD_ADD);
5150 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
5154 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
5159 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
5160 mitid_v[0] = av[U_MITID];
5162 mitid_v[0] = "none";
5164 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
5166 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn,
5167 WinHomeDir, WinProfileDir, homedir_v, winProfile_v,
5168 drives_v, mods, LDAP_MOD_ADD, n);
5172 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
5173 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
5174 attr_array[0] = "sAMAccountName";
5175 attr_array[1] = NULL;
5179 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
5180 attr_array, &group_base, &group_count,
5181 LDAP_SCOPE_SUBTREE) != 0))
5184 if (group_count != 1)
5186 com_err(whoami, 0, "Unable to process user security template: %s - "
5187 "security not set", "UserTemplate.u");
5191 strcpy(TemplateDn, group_base->dn);
5192 strcpy(TemplateSamName, group_base->value);
5193 linklist_free(group_base);
5197 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path,
5198 LDAP_SCOPE_SUBTREE, filter_exp, NULL, 0,
5199 apsServerControls, NULL,
5202 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
5204 com_err(whoami, 0, "Unable to find user security template: %s - "
5205 "security not set", "UserTemplate.u");
5209 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
5210 "ntSecurityDescriptor");
5211 if (ppsValues == NULL)
5213 com_err(whoami, 0, "Unable to find user security template: %s - "
5214 "security not set", "UserTemplate.u");
5218 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
5219 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
5224 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
5226 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
5228 OldUseSFU30 = UseSFU30;
5229 SwitchSFU(mods, &UseSFU30, n);
5230 if (OldUseSFU30 != UseSFU30)
5231 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
5234 for (i = 0; i < n; i++)
5237 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
5239 com_err(whoami, 0, "Unable to create user %s : %s",
5240 user_name, ldap_err2string(rc));
5245 if ((rc == LDAP_SUCCESS) && (SetPassword))
5247 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
5249 ad_kdc_disconnect();
5250 if (!ad_server_connect(default_server, ldap_domain))
5252 com_err(whoami, 0, "Unable to set password for user %s : %s",
5254 "cannot get changepw ticket from windows domain");
5258 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
5260 com_err(whoami, 0, "Unable to set password for user %s "
5261 ": %ld", user_name, rc);
5267 if(!ActiveDirectory)
5269 if (rc = moira_connect())
5271 critical_alert("AD incremental",
5272 "Error contacting Moira server : %s",
5277 argv[0] = user_name;
5279 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
5281 p = strdup(save_argv[3]);
5283 if((c = strchr(p, ',')) != NULL) {
5287 if ((c = strchr(q, '@')) == NULL)
5288 sprintf(temp, "%s@mit.edu", q);
5290 sprintf(temp, "%s", q);
5292 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5294 mail_routing_v[0] = temp;
5297 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5299 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5301 if (rc == LDAP_ALREADY_EXISTS ||
5302 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5307 "Unable to set the mailRoutingAddress for %s : %s",
5308 user_name, ldap_err2string(rc));
5311 while((q = strtok(NULL, ",")) != NULL) {
5314 if((c = strchr(q, '@')) == NULL)
5315 sprintf(temp, "%s@mit.edu", q);
5317 sprintf(temp, "%s", q);
5319 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5321 mail_routing_v[0] = temp;
5324 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5326 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5328 if (rc == LDAP_ALREADY_EXISTS ||
5329 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5334 "Unable to set the mailRoutingAddress for %s : %s",
5335 user_name, ldap_err2string(rc));
5341 if((c = strchr(p, '@')) == NULL)
5342 sprintf(temp, "%s@mit.edu", p);
5344 sprintf(temp, "%s", p);
5346 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5348 mail_routing_v[0] = temp;
5351 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5353 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5355 if (rc == LDAP_ALREADY_EXISTS ||
5356 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5361 "Unable to set the mailRoutingAddress for %s : %s",
5362 user_name, ldap_err2string(rc));
5372 int user_change_status(LDAP *ldap_handle, char *dn_path,
5373 char *user_name, char *MoiraId,
5377 char *attr_array[3];
5379 char distinguished_name[1024];
5381 char *mitMoiraId_v[] = {NULL, NULL};
5383 LK_ENTRY *group_base;
5390 if (!check_string(user_name))
5392 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
5394 return(AD_INVALID_NAME);
5400 if (strlen(MoiraId) != 0)
5402 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5403 attr_array[0] = "UserAccountControl";
5404 attr_array[1] = NULL;
5405 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5406 &group_base, &group_count,
5407 LDAP_SCOPE_SUBTREE)) != 0)
5409 com_err(whoami, 0, "Unable to process user %s : %s",
5410 user_name, ldap_err2string(rc));
5415 if (group_count != 1)
5417 linklist_free(group_base);
5420 sprintf(filter, "(sAMAccountName=%s)", user_name);
5421 attr_array[0] = "UserAccountControl";
5422 attr_array[1] = NULL;
5423 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5424 &group_base, &group_count,
5425 LDAP_SCOPE_SUBTREE)) != 0)
5427 com_err(whoami, 0, "Unable to process user %s : %s",
5428 user_name, ldap_err2string(rc));
5433 if (group_count != 1)
5435 linklist_free(group_base);
5436 com_err(whoami, 0, "Unable to find user %s in AD",
5438 return(LDAP_NO_SUCH_OBJECT);
5441 strcpy(distinguished_name, group_base->dn);
5442 ulongValue = atoi((*group_base).value);
5444 if (operation == MEMBER_DEACTIVATE)
5445 ulongValue |= UF_ACCOUNTDISABLE;
5447 ulongValue &= ~UF_ACCOUNTDISABLE;
5449 sprintf(temp, "%ld", ulongValue);
5451 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
5452 temp, &modvalues, REPLACE)) == 1)
5455 linklist_free(group_base);
5459 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
5461 if (strlen(MoiraId) != 0)
5463 mitMoiraId_v[0] = MoiraId;
5464 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
5468 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
5470 for (i = 0; i < n; i++)
5473 free_values(modvalues);
5475 if (rc != LDAP_SUCCESS)
5477 com_err(whoami, 0, "Unable to change status of user %s : %s",
5478 user_name, ldap_err2string(rc));
5485 int user_delete(LDAP *ldap_handle, char *dn_path,
5486 char *u_name, char *MoiraId)
5489 char *attr_array[3];
5490 char distinguished_name[1024];
5491 char user_name[512];
5492 LK_ENTRY *group_base;
5497 if (!check_string(u_name))
5498 return(AD_INVALID_NAME);
5500 strcpy(user_name, u_name);
5504 if (strlen(MoiraId) != 0)
5506 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5507 attr_array[0] = "name";
5508 attr_array[1] = NULL;
5509 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5510 &group_base, &group_count,
5511 LDAP_SCOPE_SUBTREE)) != 0)
5513 com_err(whoami, 0, "Unable to process user %s : %s",
5514 user_name, ldap_err2string(rc));
5519 if (group_count != 1)
5521 linklist_free(group_base);
5524 sprintf(filter, "(sAMAccountName=%s)", user_name);
5525 attr_array[0] = "name";
5526 attr_array[1] = NULL;
5527 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5528 &group_base, &group_count,
5529 LDAP_SCOPE_SUBTREE)) != 0)
5531 com_err(whoami, 0, "Unable to process user %s : %s",
5532 user_name, ldap_err2string(rc));
5537 if (group_count != 1)
5539 com_err(whoami, 0, "Unable to find user %s in AD",
5544 strcpy(distinguished_name, group_base->dn);
5546 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
5548 com_err(whoami, 0, "Unable to process user %s : %s",
5549 user_name, ldap_err2string(rc));
5552 /* Need to add code to delete mit.edu contact */
5556 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
5558 if(rc = ldap_delete_s(ldap_handle, temp))
5560 com_err(whoami, 0, "Unable to delete user contact for %s",
5566 linklist_free(group_base);
5571 void linklist_free(LK_ENTRY *linklist_base)
5573 LK_ENTRY *linklist_previous;
5575 while (linklist_base != NULL)
5577 if (linklist_base->dn != NULL)
5578 free(linklist_base->dn);
5580 if (linklist_base->attribute != NULL)
5581 free(linklist_base->attribute);
5583 if (linklist_base->value != NULL)
5584 free(linklist_base->value);
5586 if (linklist_base->member != NULL)
5587 free(linklist_base->member);
5589 if (linklist_base->type != NULL)
5590 free(linklist_base->type);
5592 if (linklist_base->list != NULL)
5593 free(linklist_base->list);
5595 linklist_previous = linklist_base;
5596 linklist_base = linklist_previous->next;
5597 free(linklist_previous);
5601 void free_values(char **modvalues)
5607 if (modvalues != NULL)
5609 while (modvalues[i] != NULL)
5612 modvalues[i] = NULL;
5619 static int illegalchars[] = {
5620 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5621 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
5622 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
5623 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
5624 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5625 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
5626 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5627 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5628 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5629 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5630 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5631 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5632 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5633 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5634 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5635 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5638 static int illegalchars_ldap[] = {
5639 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5640 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
5641 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, /* SPACE - / */
5642 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
5643 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5644 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, /* P - _ */
5645 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5646 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5647 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5648 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5649 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5650 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5651 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5652 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5653 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5654 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5657 int check_string(char *s)
5665 if (isupper(character))
5666 character = tolower(character);
5670 if (illegalchars[(unsigned) character])
5675 if (illegalchars_ldap[(unsigned) character])
5683 int check_container_name(char *s)
5691 if (isupper(character))
5692 character = tolower(character);
5694 if (character == ' ')
5697 if (illegalchars[(unsigned) character])
5704 int mr_connect_cl(char *server, char *client, int version, int auth)
5710 status = mr_connect(server);
5714 com_err(whoami, status, "while connecting to Moira");
5718 status = mr_motd(&motd);
5723 com_err(whoami, status, "while checking server status");
5729 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5730 com_err(whoami, status, temp);
5735 status = mr_version(version);
5739 if (status == MR_UNKNOWN_PROC)
5742 status = MR_VERSION_HIGH;
5744 status = MR_SUCCESS;
5747 if (status == MR_VERSION_HIGH)
5749 com_err(whoami, 0, "Warning: This client is running newer code "
5750 "than the server.");
5751 com_err(whoami, 0, "Some operations may not work.");
5753 else if (status && status != MR_VERSION_LOW)
5755 com_err(whoami, status, "while setting query version number.");
5763 status = mr_krb5_auth(client);
5766 com_err(whoami, status, "while authenticating to Moira.");
5775 void AfsToWinAfs(char* path, char* winPath)
5779 strcpy(winPath, WINAFS);
5780 pathPtr = path + strlen(AFS);
5781 winPathPtr = winPath + strlen(WINAFS);
5785 if (*pathPtr == '/')
5788 *winPathPtr = *pathPtr;
5795 int GetAceInfo(int ac, char **av, void *ptr)
5802 strcpy(call_args[0], av[L_ACE_TYPE]);
5803 strcpy(call_args[1], av[L_ACE_NAME]);
5805 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5806 return(LDAP_SUCCESS);
5809 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5812 char *attr_array[3];
5815 LK_ENTRY *group_base;
5820 sprintf(filter, "(sAMAccountName=%s)", Name);
5821 attr_array[0] = "sAMAccountName";
5822 attr_array[1] = NULL;
5824 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5825 &group_base, &group_count,
5826 LDAP_SCOPE_SUBTREE)) != 0)
5828 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5829 Name, ldap_err2string(rc));
5833 linklist_free(group_base);
5836 if (group_count == 0)
5844 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5845 int UpdateGroup, int *ProcessGroup, char *maillist)
5848 char GroupName[256];
5854 char AceMembership[2];
5857 char *save_argv[U_END];
5861 com_err(whoami, 0, "ProcessAce disabled, skipping");
5865 strcpy(GroupName, Name);
5867 if (strcasecmp(Type, "LIST"))
5873 AceInfo[0] = AceType;
5874 AceInfo[1] = AceName;
5875 AceInfo[2] = AceMembership;
5877 memset(AceType, '\0', sizeof(AceType));
5878 memset(AceName, '\0', sizeof(AceName));
5879 memset(AceMembership, '\0', sizeof(AceMembership));
5880 memset(AceOu, '\0', sizeof(AceOu));
5883 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5885 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5886 GroupName, error_message(rc));
5892 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5896 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5899 strcpy(temp, AceName);
5901 if (!strcasecmp(AceType, "LIST"))
5902 sprintf(temp, "%s%s", AceName, group_suffix);
5906 if (checkADname(ldap_handle, dn_path, temp))
5909 (*ProcessGroup) = 1;
5912 if (!strcasecmp(AceInfo[0], "LIST"))
5914 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5915 AceMembership, 0, UpdateGroup, maillist))
5918 else if (!strcasecmp(AceInfo[0], "USER"))
5921 call_args[0] = (char *)ldap_handle;
5922 call_args[1] = dn_path;
5924 call_args[3] = NULL;
5927 if (rc = mr_query("get_user_account_by_login", 1, av,
5928 save_query_info, save_argv))
5930 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5935 if (rc = user_create(U_END, save_argv, call_args))
5937 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5944 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5954 if (!strcasecmp(AceType, "LIST"))
5956 if (!strcasecmp(GroupName, AceName))
5960 strcpy(GroupName, AceName);
5966 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5967 char *group_name, char *group_ou, char *group_membership,
5968 int group_security_flag, int updateGroup, char *maillist)
5973 LK_ENTRY *group_base;
5976 char *attr_array[3];
5979 call_args[0] = (char *)ldap_handle;
5980 call_args[1] = dn_path;
5981 call_args[2] = group_name;
5982 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5983 call_args[4] = (char *)updateGroup;
5984 call_args[5] = MoiraId;
5986 call_args[7] = NULL;
5992 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5995 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
6003 com_err(whoami, 0, "Unable to create list %s", group_name);
6004 return(callback_rc);
6010 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
6011 char *group_ou, char *group_membership,
6012 int group_security_flag, char *MoiraId)
6027 char *member_v[] = {NULL, NULL};
6028 char *save_argv[U_END];
6029 char machine_ou[256];
6030 char NewMachineName[1024];
6032 com_err(whoami, 0, "Populating group %s", group_name);
6034 call_args[0] = (char *)ldap_handle;
6035 call_args[1] = dn_path;
6036 call_args[2] = group_name;
6037 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS |
6039 call_args[4] = NULL;
6042 if (rc = mr_query("get_end_members_of_list", 1, av,
6043 member_list_build, call_args))
6045 com_err(whoami, 0, "Unable to populate list %s : %s",
6046 group_name, error_message(rc));
6050 members = (char **)malloc(sizeof(char *) * 2);
6052 if (member_base != NULL)
6058 if (!strcasecmp(ptr->type, "LIST"))
6064 if (!strcasecmp(ptr->type, "MACHINE") && !ProcessMachineContainer)
6070 if(!strcasecmp(ptr->type, "USER"))
6072 if(!strcasecmp(ptr->member, PRODUCTION_PRINCIPAL) ||
6073 !strcasecmp(ptr->member, TEST_PRINCIPAL))
6079 if ((rc = check_user(ldap_handle, dn_path, ptr->member,
6080 "")) == AD_NO_USER_FOUND)
6082 com_err(whoami, 0, "creating user %s", ptr->member);
6084 av[0] = ptr->member;
6085 call_args[0] = (char *)ldap_handle;
6086 call_args[1] = dn_path;
6088 call_args[3] = NULL;
6091 if (rc = mr_query("get_user_account_by_login", 1, av,
6092 save_query_info, save_argv))
6094 com_err(whoami, 0, "Unable to create user %s "
6095 "while populating group %s.", ptr->member,
6101 if (rc = user_create(U_END, save_argv, call_args))
6103 com_err(whoami, 0, "Unable to create user %s "
6104 "while populating group %s.", ptr->member,
6112 com_err(whoami, 0, "Unable to create user %s "
6113 "while populating group %s", ptr->member,
6124 sprintf(member, "cn=%s,%s,%s", ptr->member, pUserOu,
6129 sprintf(member, "uid=%s,%s,%s", ptr->member, pUserOu,
6134 else if (!strcasecmp(ptr->type, "STRING"))
6136 if (contact_create(ldap_handle, dn_path, ptr->member,
6140 pUserOu = contact_ou;
6141 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6144 else if (!strcasecmp(ptr->type, "KERBEROS"))
6146 if (contact_create(ldap_handle, dn_path, ptr->member,
6150 pUserOu = kerberos_ou;
6151 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6154 else if (!strcasecmp(ptr->type, "MACHINE"))
6156 memset(machine_ou, '\0', sizeof(machine_ou));
6157 memset(NewMachineName, '\0', sizeof(NewMachineName));
6159 if (!get_machine_ou(ldap_handle, dn_path, ptr->member,
6160 machine_ou, NewMachineName))
6162 pUserOu = machine_ou;
6163 sprintf(member, "cn=%s,%s,%s", NewMachineName, pUserOu,
6174 members = (char **)realloc(members, ((i + 2) * sizeof(char *)));
6175 members[i++] = strdup(member);
6180 linklist_free(member_base);
6186 sprintf(group_dn, "cn=%s,%s,%s", group_name, group_ou, dn_path);
6188 if(GroupPopulateDelete)
6191 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
6194 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6195 mods)) != LDAP_SUCCESS)
6198 "Unable to populate group membership for %s: %s",
6199 group_dn, ldap_err2string(rc));
6202 for (i = 0; i < n; i++)
6207 ADD_ATTR("member", members, LDAP_MOD_REPLACE);
6210 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6211 mods)) != LDAP_SUCCESS)
6214 "Unable to populate group membership for %s: %s",
6215 group_dn, ldap_err2string(rc));
6218 for (i = 0; i < n; i++)
6226 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
6227 char *group_name, char *group_ou, char *group_membership,
6228 int group_security_flag, int type, char *maillist)
6230 char before_desc[512];
6231 char before_name[256];
6232 char before_group_ou[256];
6233 char before_group_membership[2];
6234 char distinguishedName[256];
6235 char ad_distinguishedName[256];
6237 char *attr_array[3];
6238 int before_security_flag;
6241 LK_ENTRY *group_base;
6244 char ou_security[512];
6245 char ou_distribution[512];
6246 char ou_neither[512];
6249 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
6250 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
6252 memset(filter, '\0', sizeof(filter));
6256 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6258 "samAccountName", &group_base,
6259 &group_count, filter))
6262 if (type == CHECK_GROUPS)
6264 if (group_count == 1)
6266 strcpy(group_dn, group_base->dn);
6268 if (!strcasecmp(group_dn, distinguishedName))
6270 linklist_free(group_base);
6275 linklist_free(group_base);
6277 if (group_count == 0)
6278 return(AD_NO_GROUPS_FOUND);
6280 if (group_count == 1)
6281 return(AD_WRONG_GROUP_DN_FOUND);
6283 return(AD_MULTIPLE_GROUPS_FOUND);
6286 if (group_count == 0)
6288 return(AD_NO_GROUPS_FOUND);
6291 if (group_count > 1)
6295 strcpy(group_dn, ptr->dn);
6299 if (!strcasecmp(group_dn, ptr->value))
6307 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
6313 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
6317 linklist_free(group_base);
6318 return(AD_MULTIPLE_GROUPS_FOUND);
6325 strcpy(group_dn, ptr->dn);
6327 if (strcasecmp(group_dn, ptr->value))
6328 rc = ldap_delete_s(ldap_handle, ptr->value);
6333 linklist_free(group_base);
6334 memset(filter, '\0', sizeof(filter));
6338 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6340 "samAccountName", &group_base,
6341 &group_count, filter))
6344 if (group_count == 0)
6345 return(AD_NO_GROUPS_FOUND);
6347 if (group_count > 1)
6348 return(AD_MULTIPLE_GROUPS_FOUND);
6351 strcpy(ad_distinguishedName, group_base->dn);
6352 linklist_free(group_base);
6356 attr_array[0] = "sAMAccountName";
6357 attr_array[1] = NULL;
6359 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6360 &group_base, &group_count,
6361 LDAP_SCOPE_SUBTREE)) != 0)
6363 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6364 MoiraId, ldap_err2string(rc));
6368 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
6370 if (!strcasecmp(ad_distinguishedName, distinguishedName))
6372 linklist_free(group_base);
6378 linklist_free(group_base);
6381 memset(ou_both, '\0', sizeof(ou_both));
6382 memset(ou_security, '\0', sizeof(ou_security));
6383 memset(ou_distribution, '\0', sizeof(ou_distribution));
6384 memset(ou_neither, '\0', sizeof(ou_neither));
6385 memset(before_name, '\0', sizeof(before_name));
6386 memset(before_desc, '\0', sizeof(before_desc));
6387 memset(before_group_membership, '\0', sizeof(before_group_membership));
6389 attr_array[0] = "name";
6390 attr_array[1] = NULL;
6392 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6393 &group_base, &group_count,
6394 LDAP_SCOPE_SUBTREE)) != 0)
6396 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
6397 MoiraId, ldap_err2string(rc));
6401 strcpy(before_name, group_base->value);
6402 linklist_free(group_base);
6406 attr_array[0] = "description";
6407 attr_array[1] = NULL;
6409 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6410 &group_base, &group_count,
6411 LDAP_SCOPE_SUBTREE)) != 0)
6414 "Unable to get list description with MoiraId = %s: %s",
6415 MoiraId, ldap_err2string(rc));
6419 if (group_count != 0)
6421 strcpy(before_desc, group_base->value);
6422 linklist_free(group_base);
6427 change_to_lower_case(ad_distinguishedName);
6428 strcpy(ou_both, group_ou_both);
6429 change_to_lower_case(ou_both);
6430 strcpy(ou_security, group_ou_security);
6431 change_to_lower_case(ou_security);
6432 strcpy(ou_distribution, group_ou_distribution);
6433 change_to_lower_case(ou_distribution);
6434 strcpy(ou_neither, group_ou_neither);
6435 change_to_lower_case(ou_neither);
6437 if (strstr(ad_distinguishedName, ou_both))
6439 strcpy(before_group_ou, group_ou_both);
6440 before_group_membership[0] = 'B';
6441 before_security_flag = 1;
6443 else if (strstr(ad_distinguishedName, ou_security))
6445 strcpy(before_group_ou, group_ou_security);
6446 before_group_membership[0] = 'S';
6447 before_security_flag = 1;
6449 else if (strstr(ad_distinguishedName, ou_distribution))
6451 strcpy(before_group_ou, group_ou_distribution);
6452 before_group_membership[0] = 'D';
6453 before_security_flag = 0;
6455 else if (strstr(ad_distinguishedName, ou_neither))
6457 strcpy(before_group_ou, group_ou_neither);
6458 before_group_membership[0] = 'N';
6459 before_security_flag = 0;
6462 return(AD_NO_OU_FOUND);
6464 rc = group_rename(ldap_handle, dn_path, before_name,
6465 before_group_membership,
6466 before_group_ou, before_security_flag, before_desc,
6467 group_name, group_membership, group_ou,
6468 group_security_flag,
6469 before_desc, MoiraId, filter, maillist);
6474 void change_to_lower_case(char *ptr)
6478 for (i = 0; i < (int)strlen(ptr); i++)
6480 ptr[i] = tolower(ptr[i]);
6484 int ad_get_group(LDAP *ldap_handle, char *dn_path,
6485 char *group_name, char *group_membership,
6486 char *MoiraId, char *attribute,
6487 LK_ENTRY **linklist_base, int *linklist_count,
6492 char *attr_array[3];
6496 (*linklist_base) = NULL;
6497 (*linklist_count) = 0;
6499 if (strlen(rFilter) != 0)
6501 strcpy(filter, rFilter);
6502 attr_array[0] = attribute;
6503 attr_array[1] = NULL;
6505 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6506 linklist_base, linklist_count,
6507 LDAP_SCOPE_SUBTREE)) != 0)
6509 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6510 MoiraId, ldap_err2string(rc));
6514 if ((*linklist_count) == 1)
6516 strcpy(rFilter, filter);
6521 linklist_free((*linklist_base));
6522 (*linklist_base) = NULL;
6523 (*linklist_count) = 0;
6525 if (strlen(MoiraId) != 0)
6527 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
6529 attr_array[0] = attribute;
6530 attr_array[1] = NULL;
6532 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6533 linklist_base, linklist_count,
6534 LDAP_SCOPE_SUBTREE)) != 0)
6536 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6537 MoiraId, ldap_err2string(rc));
6542 if ((*linklist_count) > 1)
6544 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
6545 pPtr = (*linklist_base);
6549 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
6554 linklist_free((*linklist_base));
6555 (*linklist_base) = NULL;
6556 (*linklist_count) = 0;
6559 if ((*linklist_count) == 1)
6562 pPtr = (*linklist_base);
6563 dn = strdup(pPtr->dn);
6566 if (!memcmp(dn, group_name, strlen(group_name)))
6568 strcpy(rFilter, filter);
6573 linklist_free((*linklist_base));
6574 (*linklist_base) = NULL;
6575 (*linklist_count) = 0;
6576 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
6578 attr_array[0] = attribute;
6579 attr_array[1] = NULL;
6581 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6582 linklist_base, linklist_count,
6583 LDAP_SCOPE_SUBTREE)) != 0)
6585 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6586 MoiraId, ldap_err2string(rc));
6590 if ((*linklist_count) == 1)
6592 strcpy(rFilter, filter);
6599 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
6602 char *attr_array[3];
6603 char SamAccountName[64];
6606 LK_ENTRY *group_base;
6612 if (strlen(MoiraId) != 0)
6614 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
6616 attr_array[0] = "sAMAccountName";
6617 attr_array[1] = NULL;
6618 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6619 &group_base, &group_count,
6620 LDAP_SCOPE_SUBTREE)) != 0)
6622 com_err(whoami, 0, "Unable to process user %s : %s",
6623 UserName, ldap_err2string(rc));
6627 if (group_count > 1)
6629 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
6635 com_err(whoami, 0, "user %s exist with MoiraId = %s",
6636 gPtr->value, MoiraId);
6642 if (group_count != 1)
6644 linklist_free(group_base);
6647 sprintf(filter, "(sAMAccountName=%s)", UserName);
6648 attr_array[0] = "sAMAccountName";
6649 attr_array[1] = NULL;
6651 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6652 &group_base, &group_count,
6653 LDAP_SCOPE_SUBTREE)) != 0)
6655 com_err(whoami, 0, "Unable to process user %s : %s",
6656 UserName, ldap_err2string(rc));
6661 if (group_count != 1)
6663 linklist_free(group_base);
6664 return(AD_NO_USER_FOUND);
6667 strcpy(SamAccountName, group_base->value);
6668 linklist_free(group_base);
6672 if (strcmp(SamAccountName, UserName))
6675 "User object %s with MoiraId %s has mismatched usernames "
6676 "(LDAP username %s, Moira username %s)", SamAccountName,
6677 MoiraId, SamAccountName, UserName);
6683 void container_get_dn(char *src, char *dest)
6690 memset(array, '\0', 20 * sizeof(array[0]));
6692 if (strlen(src) == 0)
6714 strcpy(dest, "OU=");
6718 strcat(dest, array[n-1]);
6722 strcat(dest, ",OU=");
6729 void container_get_name(char *src, char *dest)
6734 if (strlen(src) == 0)
6754 void container_check(LDAP *ldap_handle, char *dn_path, char *name)
6761 strcpy(cName, name);
6763 for (i = 0; i < (int)strlen(cName); i++)
6765 if (cName[i] == '/')
6768 av[CONTAINER_NAME] = cName;
6769 av[CONTAINER_DESC] = "";
6770 av[CONTAINER_LOCATION] = "";
6771 av[CONTAINER_CONTACT] = "";
6772 av[CONTAINER_TYPE] = "";
6773 av[CONTAINER_ID] = "";
6774 av[CONTAINER_ROWID] = "";
6775 rc = container_create(ldap_handle, dn_path, 7, av);
6777 if (rc == LDAP_SUCCESS)
6779 com_err(whoami, 0, "container %s created without a mitMoiraId",
6788 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
6789 char **before, int afterc, char **after)
6794 char new_dn_path[256];
6796 char distinguishedName[256];
6801 memset(cName, '\0', sizeof(cName));
6802 container_get_name(after[CONTAINER_NAME], cName);
6804 if (!check_container_name(cName))
6806 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6808 return(AD_INVALID_NAME);
6811 memset(distinguishedName, '\0', sizeof(distinguishedName));
6813 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6814 distinguishedName, beforec, before))
6817 if (strlen(distinguishedName) == 0)
6819 rc = container_create(ldap_handle, dn_path, afterc, after);
6823 strcpy(temp, after[CONTAINER_NAME]);
6826 for (i = 0; i < (int)strlen(temp); i++)
6836 container_get_dn(temp, dName);
6838 if (strlen(temp) != 0)
6839 sprintf(new_dn_path, "%s,%s", dName, dn_path);
6841 sprintf(new_dn_path, "%s", dn_path);
6843 sprintf(new_cn, "OU=%s", cName);
6845 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6847 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6848 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6850 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6851 before[CONTAINER_NAME], after[CONTAINER_NAME],
6852 ldap_err2string(rc));
6856 memset(dName, '\0', sizeof(dName));
6857 container_get_dn(after[CONTAINER_NAME], dName);
6858 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6863 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6865 char distinguishedName[256];
6868 memset(distinguishedName, '\0', sizeof(distinguishedName));
6870 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6871 distinguishedName, count, av))
6874 if (strlen(distinguishedName) == 0)
6877 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6879 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6880 container_move_objects(ldap_handle, dn_path, distinguishedName);
6882 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6883 av[CONTAINER_NAME], ldap_err2string(rc));
6889 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6891 char *attr_array[3];
6892 LK_ENTRY *group_base;
6895 char *objectClass_v[] = {"top",
6896 "organizationalUnit",
6899 char *ou_v[] = {NULL, NULL};
6900 char *name_v[] = {NULL, NULL};
6901 char *moiraId_v[] = {NULL, NULL};
6902 char *desc_v[] = {NULL, NULL};
6903 char *managedBy_v[] = {NULL, NULL};
6906 char managedByDN[256];
6913 memset(filter, '\0', sizeof(filter));
6914 memset(dName, '\0', sizeof(dName));
6915 memset(cName, '\0', sizeof(cName));
6916 memset(managedByDN, '\0', sizeof(managedByDN));
6917 container_get_dn(av[CONTAINER_NAME], dName);
6918 container_get_name(av[CONTAINER_NAME], cName);
6920 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6922 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6924 return(AD_INVALID_NAME);
6927 if (!check_container_name(cName))
6929 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6931 return(AD_INVALID_NAME);
6935 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6937 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6939 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6941 if (strlen(av[CONTAINER_ROWID]) != 0)
6943 moiraId_v[0] = av[CONTAINER_ROWID];
6944 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6947 if (strlen(av[CONTAINER_DESC]) != 0)
6949 desc_v[0] = av[CONTAINER_DESC];
6950 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6953 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6955 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6957 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6960 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6961 kerberos_ou, dn_path);
6962 managedBy_v[0] = managedByDN;
6963 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6968 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6970 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6971 "(objectClass=user)))", av[CONTAINER_ID]);
6974 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6976 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6980 if (strlen(filter) != 0)
6982 attr_array[0] = "distinguishedName";
6983 attr_array[1] = NULL;
6986 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6988 &group_base, &group_count,
6989 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6991 if (group_count == 1)
6993 strcpy(managedByDN, group_base->value);
6994 managedBy_v[0] = managedByDN;
6995 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6997 linklist_free(group_base);
7007 sprintf(temp, "%s,%s", dName, dn_path);
7008 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
7010 for (i = 0; i < n; i++)
7013 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
7015 com_err(whoami, 0, "Unable to create container %s : %s",
7016 cName, ldap_err2string(rc));
7020 if (rc == LDAP_ALREADY_EXISTS)
7022 if (strlen(av[CONTAINER_ROWID]) != 0)
7023 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
7029 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
7030 char **before, int afterc, char **after)
7032 char distinguishedName[256];
7035 memset(distinguishedName, '\0', sizeof(distinguishedName));
7037 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
7038 distinguishedName, afterc, after))
7041 if (strlen(distinguishedName) == 0)
7043 rc = container_create(ldap_handle, dn_path, afterc, after);
7047 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
7048 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
7054 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
7055 char *distinguishedName, int count,
7058 char *attr_array[3];
7059 LK_ENTRY *group_base;
7066 memset(filter, '\0', sizeof(filter));
7067 memset(dName, '\0', sizeof(dName));
7068 memset(cName, '\0', sizeof(cName));
7069 container_get_dn(av[CONTAINER_NAME], dName);
7070 container_get_name(av[CONTAINER_NAME], cName);
7072 if (strlen(dName) == 0)
7074 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7075 av[CONTAINER_NAME]);
7076 return(AD_INVALID_NAME);
7079 if (!check_container_name(cName))
7081 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7083 return(AD_INVALID_NAME);
7086 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7087 av[CONTAINER_ROWID]);
7088 attr_array[0] = "distinguishedName";
7089 attr_array[1] = NULL;
7093 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7094 &group_base, &group_count,
7095 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7097 if (group_count == 1)
7099 strcpy(distinguishedName, group_base->value);
7102 linklist_free(group_base);
7107 if (strlen(distinguishedName) == 0)
7109 sprintf(filter, "(&(objectClass=organizationalUnit)"
7110 "(distinguishedName=%s,%s))", dName, dn_path);
7111 attr_array[0] = "distinguishedName";
7112 attr_array[1] = NULL;
7116 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7117 &group_base, &group_count,
7118 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7120 if (group_count == 1)
7122 strcpy(distinguishedName, group_base->value);
7125 linklist_free(group_base);
7134 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
7135 char *distinguishedName, int count, char **av)
7137 char *attr_array[5];
7138 LK_ENTRY *group_base;
7143 char *moiraId_v[] = {NULL, NULL};
7144 char *desc_v[] = {NULL, NULL};
7145 char *managedBy_v[] = {NULL, NULL};
7146 char managedByDN[256];
7155 strcpy(ad_path, distinguishedName);
7157 if (strlen(dName) != 0)
7158 sprintf(ad_path, "%s,%s", dName, dn_path);
7160 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
7163 if (strlen(av[CONTAINER_ID]) != 0)
7164 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7165 av[CONTAINER_ROWID]);
7167 attr_array[0] = "mitMoiraId";
7168 attr_array[1] = "description";
7169 attr_array[2] = "managedBy";
7170 attr_array[3] = NULL;
7174 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7175 &group_base, &group_count,
7176 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7178 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
7179 av[CONTAINER_NAME], ldap_err2string(rc));
7183 memset(managedByDN, '\0', sizeof(managedByDN));
7184 memset(moiraId, '\0', sizeof(moiraId));
7185 memset(desc, '\0', sizeof(desc));
7190 if (!strcasecmp(pPtr->attribute, "description"))
7191 strcpy(desc, pPtr->value);
7192 else if (!strcasecmp(pPtr->attribute, "managedBy"))
7193 strcpy(managedByDN, pPtr->value);
7194 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
7195 strcpy(moiraId, pPtr->value);
7199 linklist_free(group_base);
7204 if (strlen(av[CONTAINER_ROWID]) != 0)
7206 moiraId_v[0] = av[CONTAINER_ROWID];
7207 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
7210 if (strlen(av[CONTAINER_DESC]) != 0)
7212 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
7217 if (strlen(desc) != 0)
7219 attribute_update(ldap_handle, ad_path, "", "description", dName);
7223 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
7225 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
7227 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
7230 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
7231 kerberos_ou, dn_path);
7232 managedBy_v[0] = managedByDN;
7233 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7237 if (strlen(managedByDN) != 0)
7239 attribute_update(ldap_handle, ad_path, "", "managedBy",
7246 memset(filter, '\0', sizeof(filter));
7248 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
7250 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
7251 "(objectClass=user)))", av[CONTAINER_ID]);
7254 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
7256 sprintf(filter, "(&(objectClass=group)(cn=%s))",
7260 if (strlen(filter) != 0)
7262 attr_array[0] = "distinguishedName";
7263 attr_array[1] = NULL;
7266 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7267 attr_array, &group_base, &group_count,
7268 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7270 if (group_count == 1)
7272 strcpy(managedByDN, group_base->value);
7273 managedBy_v[0] = managedByDN;
7274 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7278 if (strlen(managedByDN) != 0)
7280 attribute_update(ldap_handle, ad_path, "",
7281 "managedBy", dName);
7285 linklist_free(group_base);
7292 if (strlen(managedByDN) != 0)
7294 attribute_update(ldap_handle, ad_path, "", "managedBy",
7304 return(LDAP_SUCCESS);
7306 rc = ldap_modify_s(ldap_handle, ad_path, mods);
7308 for (i = 0; i < n; i++)
7311 if (rc != LDAP_SUCCESS)
7313 com_err(whoami, 0, "Unable to modify container info for %s : %s",
7314 av[CONTAINER_NAME], ldap_err2string(rc));
7321 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
7323 char *attr_array[3];
7324 LK_ENTRY *group_base;
7331 int NumberOfEntries = 10;
7335 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
7337 for (i = 0; i < 3; i++)
7339 memset(filter, '\0', sizeof(filter));
7343 strcpy(filter, "(!(|(objectClass=computer)"
7344 "(objectClass=organizationalUnit)))");
7345 attr_array[0] = "cn";
7346 attr_array[1] = NULL;
7350 strcpy(filter, "(objectClass=computer)");
7351 attr_array[0] = "cn";
7352 attr_array[1] = NULL;
7356 strcpy(filter, "(objectClass=organizationalUnit)");
7357 attr_array[0] = "ou";
7358 attr_array[1] = NULL;
7363 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
7364 &group_base, &group_count,
7365 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7370 if (group_count == 0)
7377 if (!strcasecmp(pPtr->attribute, "cn"))
7379 sprintf(new_cn, "cn=%s", pPtr->value);
7381 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
7383 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
7388 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
7390 if (rc == LDAP_ALREADY_EXISTS)
7392 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
7399 else if (!strcasecmp(pPtr->attribute, "ou"))
7401 rc = ldap_delete_s(ldap_handle, pPtr->dn);
7407 linklist_free(group_base);
7416 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
7417 char *machine_ou, char *NewMachineName)
7419 LK_ENTRY *group_base;
7423 char *attr_array[3];
7430 strcpy(NewMachineName, member);
7431 rc = moira_connect();
7432 rc = GetMachineName(NewMachineName);
7435 if (strlen(NewMachineName) == 0)
7437 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7443 pPtr = strchr(NewMachineName, '.');
7450 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
7451 attr_array[0] = "cn";
7452 attr_array[1] = NULL;
7453 sprintf(temp, "%s", dn_path);
7455 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
7456 &group_base, &group_count,
7457 LDAP_SCOPE_SUBTREE)) != 0)
7459 com_err(whoami, 0, "Unable to process machine %s : %s",
7460 member, ldap_err2string(rc));
7464 if (group_count != 1)
7469 strcpy(dn, group_base->dn);
7470 strcpy(cn, group_base->value);
7472 for (i = 0; i < (int)strlen(dn); i++)
7473 dn[i] = tolower(dn[i]);
7475 for (i = 0; i < (int)strlen(cn); i++)
7476 cn[i] = tolower(cn[i]);
7478 linklist_free(group_base);
7480 pPtr = strstr(dn, cn);
7484 com_err(whoami, 0, "Unable to process machine %s",
7489 pPtr += strlen(cn) + 1;
7490 strcpy(machine_ou, pPtr);
7492 pPtr = strstr(machine_ou, "dc=");
7496 com_err(whoami, 0, "Unable to process machine %s",
7507 int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
7508 char *MoiraMachineName, char *DestinationOu)
7512 char MachineName[128];
7514 char *attr_array[3];
7519 LK_ENTRY *group_base;
7524 strcpy(MachineName, MoiraMachineName);
7525 rc = GetMachineName(MachineName);
7527 if (strlen(MachineName) == 0)
7529 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7534 cPtr = strchr(MachineName, '.');
7539 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
7540 attr_array[0] = "sAMAccountName";
7541 attr_array[1] = NULL;
7543 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7545 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
7547 com_err(whoami, 0, "Unable to process machine %s : %s",
7548 MoiraMachineName, ldap_err2string(rc));
7552 if (group_count == 1)
7553 strcpy(OldDn, group_base->dn);
7555 linklist_free(group_base);
7558 if (group_count != 1)
7560 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
7565 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
7566 cPtr = strchr(OldDn, ',');
7571 if (!strcasecmp(cPtr, NewOu))
7575 sprintf(NewCn, "CN=%s", MachineName);
7576 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
7581 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
7587 memset(Name, '\0', sizeof(Name));
7588 strcpy(Name, machine_name);
7590 pPtr = strchr(Name, '.');
7596 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
7599 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
7600 char *machine_name, char *container_name)
7606 av[0] = machine_name;
7607 call_args[0] = (char *)container_name;
7608 rc = mr_query("get_machine_to_container_map", 1, av,
7609 machine_GetMoiraContainer, call_args);
7613 int machine_GetMoiraContainer(int ac, char **av, void *ptr)
7618 strcpy(call_args[0], av[1]);
7622 int Moira_container_group_create(char **after)
7628 memset(GroupName, '\0', sizeof(GroupName));
7629 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
7630 after[CONTAINER_ROWID]);
7634 argv[L_NAME] = GroupName;
7635 argv[L_ACTIVE] = "1";
7636 argv[L_PUBLIC] = "0";
7637 argv[L_HIDDEN] = "0";
7638 argv[L_MAILLIST] = "0";
7639 argv[L_GROUP] = "1";
7640 argv[L_GID] = UNIQUE_GID;
7641 argv[L_NFSGROUP] = "0";
7642 argv[L_MAILMAN] = "0";
7643 argv[L_MAILMAN_SERVER] = "[NONE]";
7644 argv[L_DESC] = "auto created container group";
7645 argv[L_ACE_TYPE] = "USER";
7646 argv[L_MEMACE_TYPE] = "USER";
7647 argv[L_ACE_NAME] = "sms";
7648 argv[L_MEMACE_NAME] = "sms";
7650 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
7653 "Unable to create container group %s for container %s: %s",
7654 GroupName, after[CONTAINER_NAME], error_message(rc));
7657 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
7658 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
7663 int Moira_container_group_update(char **before, char **after)
7666 char BeforeGroupName[64];
7667 char AfterGroupName[64];
7670 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
7673 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
7674 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
7675 if (strlen(BeforeGroupName) == 0)
7678 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
7679 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
7680 after[CONTAINER_ROWID]);
7684 if (strcasecmp(BeforeGroupName, AfterGroupName))
7686 argv[L_NAME] = BeforeGroupName;
7687 argv[L_NAME + 1] = AfterGroupName;
7688 argv[L_ACTIVE + 1] = "1";
7689 argv[L_PUBLIC + 1] = "0";
7690 argv[L_HIDDEN + 1] = "0";
7691 argv[L_MAILLIST + 1] = "0";
7692 argv[L_GROUP + 1] = "1";
7693 argv[L_GID + 1] = UNIQUE_GID;
7694 argv[L_NFSGROUP + 1] = "0";
7695 argv[L_MAILMAN + 1] = "0";
7696 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
7697 argv[L_DESC + 1] = "auto created container group";
7698 argv[L_ACE_TYPE + 1] = "USER";
7699 argv[L_MEMACE_TYPE + 1] = "USER";
7700 argv[L_ACE_NAME + 1] = "sms";
7701 argv[L_MEMACE_NAME + 1] = "sms";
7703 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
7706 "Unable to rename container group from %s to %s: %s",
7707 BeforeGroupName, AfterGroupName, error_message(rc));
7714 int Moira_container_group_delete(char **before)
7719 char ParentGroupName[64];
7721 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
7722 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
7724 memset(GroupName, '\0', sizeof(GroupName));
7726 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
7727 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
7729 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
7731 argv[0] = ParentGroupName;
7733 argv[2] = GroupName;
7735 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
7738 "Unable to delete container group %s from list: %s",
7739 GroupName, ParentGroupName, error_message(rc));
7743 if (strlen(GroupName) != 0)
7745 argv[0] = GroupName;
7747 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
7749 com_err(whoami, 0, "Unable to delete container group %s : %s",
7750 GroupName, error_message(rc));
7757 int Moira_groupname_create(char *GroupName, char *ContainerName,
7758 char *ContainerRowID)
7763 char newGroupName[64];
7764 char tempGroupName[64];
7770 strcpy(temp, ContainerName);
7772 ptr1 = strrchr(temp, '/');
7778 ptr1 = strrchr(temp, '/');
7782 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
7785 strcpy(tempgname, ptr);
7788 strcpy(tempgname, temp);
7790 if (strlen(tempgname) > 25)
7791 tempgname[25] ='\0';
7793 sprintf(newGroupName, "cnt-%s", tempgname);
7795 /* change everything to lower case */
7801 *ptr = tolower(*ptr);
7809 strcpy(tempGroupName, newGroupName);
7812 /* append 0-9 then a-z if a duplicate is found */
7815 argv[0] = newGroupName;
7817 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
7819 if (rc == MR_NO_MATCH)
7821 com_err(whoami, 0, "Moira error while creating group name for "
7822 "container %s : %s", ContainerName, error_message(rc));
7826 sprintf(newGroupName, "%s-%c", tempGroupName, i);
7830 com_err(whoami, 0, "Unable to find a unique group name for "
7831 "container %s: too many duplicate container names",
7842 strcpy(GroupName, newGroupName);
7846 int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7851 argv[0] = origContainerName;
7852 argv[1] = GroupName;
7854 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7857 "Unable to set container group %s in container %s: %s",
7858 GroupName, origContainerName, error_message(rc));
7864 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7866 char ContainerName[64];
7867 char ParentGroupName[64];
7871 strcpy(ContainerName, origContainerName);
7873 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7875 /* top-level container */
7876 if (strlen(ParentGroupName) == 0)
7879 argv[0] = ParentGroupName;
7881 argv[2] = GroupName;
7883 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7886 "Unable to add container group %s to parent group %s: %s",
7887 GroupName, ParentGroupName, error_message(rc));
7893 int Moira_getContainerGroup(int ac, char **av, void *ptr)
7898 strcpy(call_args[0], av[1]);
7903 int Moira_getGroupName(char *origContainerName, char *GroupName,
7906 char ContainerName[64];
7912 strcpy(ContainerName, origContainerName);
7916 ptr = strrchr(ContainerName, '/');
7924 argv[0] = ContainerName;
7926 call_args[0] = GroupName;
7927 call_args[1] = NULL;
7929 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7932 if (strlen(GroupName) != 0)
7937 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7938 ContainerName, error_message(rc));
7940 com_err(whoami, 0, "Unable to get container group from container %s",
7946 int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7952 if (strcmp(GroupName, "[none]") == 0)
7955 argv[0] = GroupName;
7956 argv[1] = "MACHINE";
7957 argv[2] = MachineName;
7960 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7962 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7966 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7967 MachineName, GroupName, error_message(rc));
7973 int GetMachineName(char *MachineName)
7976 char NewMachineName[1024];
7983 // If the address happens to be in the top-level MIT domain, great!
7984 strcpy(NewMachineName, MachineName);
7986 for (i = 0; i < (int)strlen(NewMachineName); i++)
7987 NewMachineName[i] = toupper(NewMachineName[i]);
7989 szDot = strchr(NewMachineName,'.');
7991 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7996 // If not, see if it has a Moira alias in the top-level MIT domain.
7997 memset(NewMachineName, '\0', sizeof(NewMachineName));
7999 args[1] = MachineName;
8000 call_args[0] = NewMachineName;
8001 call_args[1] = NULL;
8003 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
8005 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
8006 MachineName, error_message(rc));
8007 strcpy(MachineName, "");
8011 if (strlen(NewMachineName) != 0)
8012 strcpy(MachineName, NewMachineName);
8014 strcpy(MachineName, "");
8019 int ProcessMachineName(int ac, char **av, void *ptr)
8022 char MachineName[1024];
8028 if (strlen(call_args[0]) == 0)
8030 strcpy(MachineName, av[0]);
8032 for (i = 0; i < (int)strlen(MachineName); i++)
8033 MachineName[i] = toupper(MachineName[i]);
8035 szDot = strchr(MachineName,'.');
8037 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
8039 strcpy(call_args[0], MachineName);
8046 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
8052 for (i = 0; i < n; i++)
8054 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
8055 mods[i]->mod_type = "uidNumber";
8062 for (i = 0; i < n; i++)
8064 if (!strcmp(mods[i]->mod_type, "uidNumber"))
8065 mods[i]->mod_type = "msSFU30UidNumber";
8072 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
8073 char *DistinguishedName,
8074 char *WinHomeDir, char *WinProfileDir,
8075 char **homedir_v, char **winProfile_v,
8076 char **drives_v, LDAPMod **mods,
8083 char winProfile[1024];
8086 char apple_homedir[1024];
8087 char *apple_homedir_v[] = {NULL, NULL};
8091 LDAPMod *DelMods[20];
8093 char *save_argv[FS_END];
8094 char *fsgroup_save_argv[2];
8096 memset(homeDrive, '\0', sizeof(homeDrive));
8097 memset(path, '\0', sizeof(path));
8098 memset(winPath, '\0', sizeof(winPath));
8099 memset(winProfile, '\0', sizeof(winProfile));
8101 if(!ActiveDirectory)
8103 if (rc = moira_connect())
8105 critical_alert("AD incremental",
8106 "Error contacting Moira server : %s",
8111 argv[0] = user_name;
8113 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8116 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8117 !strcmp(save_argv[FS_TYPE], "MUL"))
8120 argv[0] = save_argv[FS_NAME];
8123 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8124 save_fsgroup_info, fsgroup_save_argv)))
8128 argv[0] = fsgroup_save_argv[0];
8130 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8131 save_query_info, save_argv)))
8133 strcpy(path, save_argv[FS_PACK]);
8140 strcpy(path, save_argv[FS_PACK]);
8148 if (!strnicmp(path, AFS, strlen(AFS)))
8150 sprintf(homedir, "%s", path);
8151 sprintf(apple_homedir, "%s/MacData", path);
8152 homedir_v[0] = homedir;
8153 apple_homedir_v[0] = apple_homedir;
8154 ADD_ATTR("homeDirectory", homedir_v, OpType);
8155 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8161 homedir_v[0] = "NONE";
8162 apple_homedir_v[0] = "NONE";
8163 ADD_ATTR("homeDirectory", homedir_v, OpType);
8164 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8171 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
8172 (!strcasecmp(WinProfileDir, "[afs]")))
8174 if (rc = moira_connect())
8176 critical_alert("AD incremental",
8177 "Error contacting Moira server : %s",
8182 argv[0] = user_name;
8184 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8187 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8188 !strcmp(save_argv[FS_TYPE], "MUL"))
8191 argv[0] = save_argv[FS_NAME];
8194 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8195 save_fsgroup_info, fsgroup_save_argv)))
8199 argv[0] = fsgroup_save_argv[0];
8201 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8202 save_query_info, save_argv)))
8204 strcpy(path, save_argv[FS_PACK]);
8211 strcpy(path, save_argv[FS_PACK]);
8219 if (!strnicmp(path, AFS, strlen(AFS)))
8221 AfsToWinAfs(path, winPath);
8222 strcpy(winProfile, winPath);
8223 strcat(winProfile, "\\.winprofile");
8230 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
8231 (!strcasecmp(WinProfileDir, "[dfs]")))
8233 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
8234 user_name[0], user_name);
8236 if (!strcasecmp(WinProfileDir, "[dfs]"))
8238 strcpy(winProfile, path);
8239 strcat(winProfile, "\\.winprofile");
8242 if (!strcasecmp(WinHomeDir, "[dfs]"))
8243 strcpy(winPath, path);
8246 if (!strcasecmp(WinHomeDir, "[local]"))
8247 memset(winPath, '\0', sizeof(winPath));
8248 else if (!strcasecmp(WinHomeDir, "[afs]") ||
8249 !strcasecmp(WinHomeDir, "[dfs]"))
8251 strcpy(homeDrive, "H:");
8255 strcpy(winPath, WinHomeDir);
8256 if (!strncmp(WinHomeDir, "\\\\", 2))
8258 strcpy(homeDrive, "H:");
8262 // nothing needs to be done if WinProfileDir is [afs].
8263 if (!strcasecmp(WinProfileDir, "[local]"))
8264 memset(winProfile, '\0', sizeof(winProfile));
8265 else if (strcasecmp(WinProfileDir, "[afs]") &&
8266 strcasecmp(WinProfileDir, "[dfs]"))
8268 strcpy(winProfile, WinProfileDir);
8271 if (strlen(winProfile) != 0)
8273 if (winProfile[strlen(winProfile) - 1] == '\\')
8274 winProfile[strlen(winProfile) - 1] = '\0';
8277 if (strlen(winPath) != 0)
8279 if (winPath[strlen(winPath) - 1] == '\\')
8280 winPath[strlen(winPath) - 1] = '\0';
8283 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
8284 strcat(winProfile, "\\");
8286 if ((winPath[1] == ':') && (strlen(winPath) == 2))
8287 strcat(winPath, "\\");
8289 if (strlen(winPath) == 0)
8291 if (OpType == LDAP_MOD_REPLACE)
8294 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
8296 //unset homeDirectory attribute for user.
8297 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8303 homedir_v[0] = strdup(winPath);
8304 ADD_ATTR("homeDirectory", homedir_v, OpType);
8307 if (strlen(winProfile) == 0)
8309 if (OpType == LDAP_MOD_REPLACE)
8312 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
8314 //unset profilePate attribute for user.
8315 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8321 winProfile_v[0] = strdup(winProfile);
8322 ADD_ATTR("profilePath", winProfile_v, OpType);
8325 if (strlen(homeDrive) == 0)
8327 if (OpType == LDAP_MOD_REPLACE)
8330 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
8332 //unset homeDrive attribute for user
8333 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8339 drives_v[0] = strdup(homeDrive);
8340 ADD_ATTR("homeDrive", drives_v, OpType);
8346 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
8347 char *attribute_value, char *attribute, char *user_name)
8349 char *mod_v[] = {NULL, NULL};
8350 LDAPMod *DelMods[20];
8356 if (strlen(attribute_value) == 0)
8359 DEL_ATTR(attribute, LDAP_MOD_DELETE);
8361 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
8367 mod_v[0] = attribute_value;
8368 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
8371 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8372 mods)) != LDAP_SUCCESS)
8376 mod_v[0] = attribute_value;
8377 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
8380 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8381 mods)) != LDAP_SUCCESS)
8383 com_err(whoami, 0, "Unable to change the %s attribute for %s "
8385 attribute, user_name, ldap_err2string(rc));
8395 void StringTrim(char *StringToTrim)
8400 save = strdup(StringToTrim);
8407 /* skip to end of string */
8412 strcpy(StringToTrim, save);
8416 for (t = s; *t; t++)
8432 strcpy(StringToTrim, s);
8436 int ReadConfigFile(char *DomainName)
8447 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
8449 if ((fptr = fopen(temp, "r")) != NULL)
8451 while (fgets(temp, sizeof(temp), fptr) != 0)
8453 for (i = 0; i < (int)strlen(temp); i++)
8454 temp[i] = toupper(temp[i]);
8456 if (temp[strlen(temp) - 1] == '\n')
8457 temp[strlen(temp) - 1] = '\0';
8461 if (strlen(temp) == 0)
8464 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8466 if (strlen(temp) > (strlen(DOMAIN)))
8468 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
8469 StringTrim(ldap_domain);
8472 else if (!strncmp(temp, REALM, strlen(REALM)))
8474 if (strlen(temp) > (strlen(REALM)))
8476 strcpy(ldap_realm, &temp[strlen(REALM)]);
8477 StringTrim(ldap_realm);
8480 else if (!strncmp(temp, PORT, strlen(PORT)))
8482 if (strlen(temp) > (strlen(PORT)))
8484 strcpy(ldap_port, &temp[strlen(PORT)]);
8485 StringTrim(ldap_port);
8488 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
8490 if (strlen(temp) > (strlen(PRINCIPALNAME)))
8492 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
8493 StringTrim(PrincipalName);
8496 else if (!strncmp(temp, SERVER, strlen(SERVER)))
8498 if (strlen(temp) > (strlen(SERVER)))
8500 ServerList[Count] = calloc(1, 256);
8501 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
8502 StringTrim(ServerList[Count]);
8506 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
8508 if (strlen(temp) > (strlen(MSSFU)))
8510 strcpy(temp1, &temp[strlen(MSSFU)]);
8512 if (!strcmp(temp1, SFUTYPE))
8516 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
8518 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
8520 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
8522 if (!strcasecmp(temp1, "NO"))
8525 memset(group_suffix, '\0', sizeof(group_suffix));
8529 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
8531 if (strlen(temp) > (strlen(GROUP_TYPE)))
8533 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
8535 if (!strcasecmp(temp1, "UNIVERSAL"))
8536 UseGroupUniversal = 1;
8539 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
8541 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
8543 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
8545 if (!strcasecmp(temp1, "NO"))
8549 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
8551 if (strlen(temp) > (strlen(SET_PASSWORD)))
8553 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
8555 if (!strcasecmp(temp1, "NO"))
8559 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
8561 if (strlen(temp) > (strlen(EXCHANGE)))
8563 strcpy(temp1, &temp[strlen(EXCHANGE)]);
8565 if (!strcasecmp(temp1, "YES"))
8569 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
8570 strlen(PROCESS_MACHINE_CONTAINER)))
8572 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
8574 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
8576 if (!strcasecmp(temp1, "NO"))
8577 ProcessMachineContainer = 0;
8580 else if (!strncmp(temp, ACTIVE_DIRECTORY,
8581 strlen(ACTIVE_DIRECTORY)))
8583 if (strlen(temp) > (strlen(ACTIVE_DIRECTORY)))
8585 strcpy(temp1, &temp[strlen(ACTIVE_DIRECTORY)]);
8587 if (!strcasecmp(temp1, "NO"))
8588 ActiveDirectory = 0;
8591 else if (!strncmp(temp, GROUP_POPULATE_MEMBERS,
8592 strlen(GROUP_POPULATE_MEMBERS)))
8594 if (strlen(temp) > (strlen(GROUP_POPULATE_MEMBERS)))
8596 strcpy(temp1, &temp[strlen(GROUP_POPULATE_MEMBERS)]);
8598 if (!strcasecmp(temp1, "DELETE"))
8600 GroupPopulateDelete = 1;
8606 if (strlen(ldap_domain) != 0)
8608 memset(ldap_domain, '\0', sizeof(ldap_domain));
8612 if (strlen(temp) != 0)
8613 strcpy(ldap_domain, temp);
8619 if (strlen(ldap_domain) == 0)
8621 strcpy(ldap_domain, DomainName);
8627 for (i = 0; i < Count; i++)
8629 if (ServerList[i] != 0)
8631 for (k = 0; k < (int)strlen(ServerList[i]); k++)
8632 ServerList[i][k] = toupper(ServerList[i][k]);
8639 int ReadDomainList()
8646 unsigned char c[11];
8647 unsigned char stuff[256];
8652 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
8654 if ((fptr = fopen(temp, "r")) != NULL)
8656 while (fgets(temp, sizeof(temp), fptr) != 0)
8658 for (i = 0; i < (int)strlen(temp); i++)
8659 temp[i] = toupper(temp[i]);
8661 if (temp[strlen(temp) - 1] == '\n')
8662 temp[strlen(temp) - 1] = '\0';
8666 if (strlen(temp) == 0)
8669 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8671 if (strlen(temp) > (strlen(DOMAIN)))
8673 strcpy(temp1, &temp[strlen(DOMAIN)]);
8675 strcpy(temp, temp1);
8679 strcpy(DomainNames[Count], temp);
8680 StringTrim(DomainNames[Count]);
8689 critical_alert("incremental", "%s", "ldap.incr cannot run due to a "
8690 "configuration error in ldap.cfg");
8697 int email_isvalid(const char *address) {
8699 const char *c, *domain;
8700 static char *rfc822_specials = "()<>@,;:\\\"[]";
8702 if(address[strlen(address) - 1] == '.')
8705 /* first we validate the name portion (name@domain) */
8706 for (c = address; *c; c++) {
8707 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
8712 if (*c == '\\' && (*++c == ' '))
8714 if (*c <= ' ' || *c >= 127)
8729 if (*c <= ' ' || *c >= 127)
8731 if (strchr(rfc822_specials, *c))
8735 if (c == address || *(c - 1) == '.')
8738 /* next we validate the domain portion (name@domain) */
8739 if (!*(domain = ++c)) return 0;
8742 if (c == domain || *(c - 1) == '.')
8746 if (*c <= ' ' || *c >= 127)
8748 if (strchr(rfc822_specials, *c))
8752 return (count >= 1);
8755 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
8756 char **homeServerName)
8758 LK_ENTRY *group_base;
8759 LK_ENTRY *sub_group_base;
8763 int sub_group_count;
8765 char sub_filter[1024];
8766 char search_path[1024];
8768 char *attr_array[3];
8770 int homeMDB_count = -1;
8774 int rangeStep = 1500;
8776 int rangeHigh = rangeLow + (rangeStep - 1);
8779 /* Grumble..... microsoft not making it searchable from the root *grr* */
8781 memset(filter, '\0', sizeof(filter));
8782 memset(search_path, '\0', sizeof(search_path));
8784 sprintf(filter, "(objectClass=msExchMDB)");
8785 sprintf(search_path, "CN=Configuration,%s", dn_path);
8786 attr_array[0] = "distinguishedName";
8787 attr_array[1] = NULL;
8792 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
8793 &group_base, &group_count,
8794 LDAP_SCOPE_SUBTREE)) != 0)
8796 com_err(whoami, 0, "Unable to find msExchMDB %s",
8797 ldap_err2string(rc));
8806 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
8807 ((s = strstr(gPtr->dn, "Recover")) != (char *) NULL) ||
8808 ((s = strstr(gPtr->dn, "Reserve")) != (char *) NULL))
8815 * Due to limits in active directory we need to use the LDAP
8816 * range semantics to query and return all the values in
8817 * large lists, we will stop increasing the range when
8818 * the result count is 0.
8826 memset(sub_filter, '\0', sizeof(sub_filter));
8827 memset(range, '\0', sizeof(range));
8828 sprintf(sub_filter, "(objectClass=msExchMDB)");
8831 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
8833 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
8835 attr_array[0] = range;
8836 attr_array[1] = NULL;
8838 sub_group_base = NULL;
8839 sub_group_count = 0;
8841 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
8842 attr_array, &sub_group_base,
8844 LDAP_SCOPE_SUBTREE)) != 0)
8846 com_err(whoami, 0, "Unable to find homeMDBBL %s",
8847 ldap_err2string(rc));
8851 if(!sub_group_count)
8857 rangeHigh = rangeLow + (rangeStep - 1);
8864 mdbbl_count += sub_group_count;
8865 rangeLow = rangeHigh + 1;
8866 rangeHigh = rangeLow + (rangeStep - 1);
8869 /* First time through, need to initialize or update the least used */
8871 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
8874 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
8876 homeMDB_count = mdbbl_count;
8877 *homeMDB = strdup(gPtr->dn);
8881 linklist_free(sub_group_base);
8885 linklist_free(group_base);
8888 * Ok found the server least allocated need to now query to get its
8889 * msExchHomeServerName so we can set it as a user attribute
8892 attr_array[0] = "legacyExchangeDN";
8893 attr_array[1] = NULL;
8898 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
8899 attr_array, &group_base,
8901 LDAP_SCOPE_SUBTREE)) != 0)
8903 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
8904 ldap_err2string(rc));
8910 *homeServerName = strdup(group_base->value);
8911 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
8917 linklist_free(group_base);
8922 char *lowercase(char *s)
8926 for (p = s; *p; p++)
8934 char *uppercase(char *s)
8938 for (p = s; *p; p++)
8946 char *escape_string(char *s)
8954 memset(string, '\0', sizeof(string));
8958 /* Replace leading spaces */
8960 while(isspace(*q)) {
8967 /* Escape any special characters */
8969 for(; *q != '\0'; q++) {
8992 return strdup(string);
8995 int save_query_info(int argc, char **argv, void *hint)
8998 char **nargv = hint;
9000 for(i = 0; i < argc; i++)
9001 nargv[i] = strdup(argv[i]);
9006 int save_fsgroup_info(int argc, char **argv, void *hint)
9009 char **nargv = hint;
9013 for(i = 0; i < argc; i++)
9014 nargv[i] = strdup(argv[i]);