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))
3460 else if (!strcmp(av[ACE_TYPE], "LIST"))
3462 if (!((int)call_args[3] & MOIRA_LISTS))
3465 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3467 if (!((int)call_args[3] & MOIRA_KERBEROS))
3470 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3475 else if (!strcmp(av[ACE_TYPE], "MACHINE"))
3477 if (!((int)call_args[3] & MOIRA_MACHINE))
3483 linklist = member_base;
3487 if (!strcasecmp(temp, linklist->member) &&
3488 !strcasecmp(av[ACE_TYPE], linklist->type))
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)))
5282 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_REPLACE);
5284 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5286 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
5291 "Unable to set the mailRoutingAddress for %s : %s",
5292 user_name, ldap_err2string(rc));
5294 p = strdup(save_argv[3]);
5296 if((c = strchr(p, ',')) != NULL) {
5300 if ((c = strchr(q, '@')) == NULL)
5301 sprintf(temp, "%s@mit.edu", q);
5303 sprintf(temp, "%s", q);
5305 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5307 mail_routing_v[0] = temp;
5310 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5312 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5314 if (rc == LDAP_ALREADY_EXISTS ||
5315 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5320 "Unable to set the mailRoutingAddress for %s : %s",
5321 user_name, ldap_err2string(rc));
5324 while((q = strtok(NULL, ",")) != NULL) {
5327 if((c = strchr(q, '@')) == NULL)
5328 sprintf(temp, "%s@mit.edu", q);
5330 sprintf(temp, "%s", q);
5332 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5334 mail_routing_v[0] = temp;
5337 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5339 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5341 if (rc == LDAP_ALREADY_EXISTS ||
5342 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5347 "Unable to set the mailRoutingAddress for %s : %s",
5348 user_name, ldap_err2string(rc));
5354 if((c = strchr(p, '@')) == NULL)
5355 sprintf(temp, "%s@mit.edu", p);
5357 sprintf(temp, "%s", p);
5359 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5361 mail_routing_v[0] = temp;
5364 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5366 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5368 if (rc == LDAP_ALREADY_EXISTS ||
5369 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5374 "Unable to set the mailRoutingAddress for %s : %s",
5375 user_name, ldap_err2string(rc));
5385 int user_change_status(LDAP *ldap_handle, char *dn_path,
5386 char *user_name, char *MoiraId,
5390 char *attr_array[3];
5392 char distinguished_name[1024];
5394 char *mitMoiraId_v[] = {NULL, NULL};
5396 LK_ENTRY *group_base;
5403 if (!check_string(user_name))
5405 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
5407 return(AD_INVALID_NAME);
5413 if (strlen(MoiraId) != 0)
5415 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5416 attr_array[0] = "UserAccountControl";
5417 attr_array[1] = NULL;
5418 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5419 &group_base, &group_count,
5420 LDAP_SCOPE_SUBTREE)) != 0)
5422 com_err(whoami, 0, "Unable to process user %s : %s",
5423 user_name, ldap_err2string(rc));
5428 if (group_count != 1)
5430 linklist_free(group_base);
5433 sprintf(filter, "(sAMAccountName=%s)", user_name);
5434 attr_array[0] = "UserAccountControl";
5435 attr_array[1] = NULL;
5436 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5437 &group_base, &group_count,
5438 LDAP_SCOPE_SUBTREE)) != 0)
5440 com_err(whoami, 0, "Unable to process user %s : %s",
5441 user_name, ldap_err2string(rc));
5446 if (group_count != 1)
5448 linklist_free(group_base);
5449 com_err(whoami, 0, "Unable to find user %s in AD",
5451 return(LDAP_NO_SUCH_OBJECT);
5454 strcpy(distinguished_name, group_base->dn);
5455 ulongValue = atoi((*group_base).value);
5457 if (operation == MEMBER_DEACTIVATE)
5458 ulongValue |= UF_ACCOUNTDISABLE;
5460 ulongValue &= ~UF_ACCOUNTDISABLE;
5462 sprintf(temp, "%ld", ulongValue);
5464 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
5465 temp, &modvalues, REPLACE)) == 1)
5468 linklist_free(group_base);
5472 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
5474 if (strlen(MoiraId) != 0)
5476 mitMoiraId_v[0] = MoiraId;
5477 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
5481 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
5483 for (i = 0; i < n; i++)
5486 free_values(modvalues);
5488 if (rc != LDAP_SUCCESS)
5490 com_err(whoami, 0, "Unable to change status of user %s : %s",
5491 user_name, ldap_err2string(rc));
5498 int user_delete(LDAP *ldap_handle, char *dn_path,
5499 char *u_name, char *MoiraId)
5502 char *attr_array[3];
5503 char distinguished_name[1024];
5504 char user_name[512];
5505 LK_ENTRY *group_base;
5510 if (!check_string(u_name))
5511 return(AD_INVALID_NAME);
5513 strcpy(user_name, u_name);
5517 if (strlen(MoiraId) != 0)
5519 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5520 attr_array[0] = "name";
5521 attr_array[1] = NULL;
5522 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5523 &group_base, &group_count,
5524 LDAP_SCOPE_SUBTREE)) != 0)
5526 com_err(whoami, 0, "Unable to process user %s : %s",
5527 user_name, ldap_err2string(rc));
5532 if (group_count != 1)
5534 linklist_free(group_base);
5537 sprintf(filter, "(sAMAccountName=%s)", user_name);
5538 attr_array[0] = "name";
5539 attr_array[1] = NULL;
5540 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5541 &group_base, &group_count,
5542 LDAP_SCOPE_SUBTREE)) != 0)
5544 com_err(whoami, 0, "Unable to process user %s : %s",
5545 user_name, ldap_err2string(rc));
5550 if (group_count != 1)
5552 com_err(whoami, 0, "Unable to find user %s in AD",
5557 strcpy(distinguished_name, group_base->dn);
5559 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
5561 com_err(whoami, 0, "Unable to process user %s : %s",
5562 user_name, ldap_err2string(rc));
5565 /* Need to add code to delete mit.edu contact */
5569 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
5571 if(rc = ldap_delete_s(ldap_handle, temp))
5573 com_err(whoami, 0, "Unable to delete user contact for %s",
5579 linklist_free(group_base);
5584 void linklist_free(LK_ENTRY *linklist_base)
5586 LK_ENTRY *linklist_previous;
5588 while (linklist_base != NULL)
5590 if (linklist_base->dn != NULL)
5591 free(linklist_base->dn);
5593 if (linklist_base->attribute != NULL)
5594 free(linklist_base->attribute);
5596 if (linklist_base->value != NULL)
5597 free(linklist_base->value);
5599 if (linklist_base->member != NULL)
5600 free(linklist_base->member);
5602 if (linklist_base->type != NULL)
5603 free(linklist_base->type);
5605 if (linklist_base->list != NULL)
5606 free(linklist_base->list);
5608 linklist_previous = linklist_base;
5609 linklist_base = linklist_previous->next;
5610 free(linklist_previous);
5614 void free_values(char **modvalues)
5620 if (modvalues != NULL)
5622 while (modvalues[i] != NULL)
5625 modvalues[i] = NULL;
5632 static int illegalchars[] = {
5633 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5634 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
5635 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
5636 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
5637 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5638 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
5639 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5641 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5642 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5643 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5644 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5645 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5646 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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,
5651 static int illegalchars_ldap[] = {
5652 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5653 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
5654 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, /* SPACE - / */
5655 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
5656 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5657 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, /* P - _ */
5658 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5659 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5660 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5661 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5662 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5663 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5664 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5665 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5666 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5667 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5670 int check_string(char *s)
5678 if (isupper(character))
5679 character = tolower(character);
5683 if (illegalchars[(unsigned) character])
5688 if (illegalchars_ldap[(unsigned) character])
5696 int check_container_name(char *s)
5704 if (isupper(character))
5705 character = tolower(character);
5707 if (character == ' ')
5710 if (illegalchars[(unsigned) character])
5717 int mr_connect_cl(char *server, char *client, int version, int auth)
5723 status = mr_connect(server);
5727 com_err(whoami, status, "while connecting to Moira");
5731 status = mr_motd(&motd);
5736 com_err(whoami, status, "while checking server status");
5742 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5743 com_err(whoami, status, temp);
5748 status = mr_version(version);
5752 if (status == MR_UNKNOWN_PROC)
5755 status = MR_VERSION_HIGH;
5757 status = MR_SUCCESS;
5760 if (status == MR_VERSION_HIGH)
5762 com_err(whoami, 0, "Warning: This client is running newer code "
5763 "than the server.");
5764 com_err(whoami, 0, "Some operations may not work.");
5766 else if (status && status != MR_VERSION_LOW)
5768 com_err(whoami, status, "while setting query version number.");
5776 status = mr_krb5_auth(client);
5779 com_err(whoami, status, "while authenticating to Moira.");
5788 void AfsToWinAfs(char* path, char* winPath)
5792 strcpy(winPath, WINAFS);
5793 pathPtr = path + strlen(AFS);
5794 winPathPtr = winPath + strlen(WINAFS);
5798 if (*pathPtr == '/')
5801 *winPathPtr = *pathPtr;
5808 int GetAceInfo(int ac, char **av, void *ptr)
5815 strcpy(call_args[0], av[L_ACE_TYPE]);
5816 strcpy(call_args[1], av[L_ACE_NAME]);
5818 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5819 return(LDAP_SUCCESS);
5822 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5825 char *attr_array[3];
5828 LK_ENTRY *group_base;
5833 sprintf(filter, "(sAMAccountName=%s)", Name);
5834 attr_array[0] = "sAMAccountName";
5835 attr_array[1] = NULL;
5837 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5838 &group_base, &group_count,
5839 LDAP_SCOPE_SUBTREE)) != 0)
5841 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5842 Name, ldap_err2string(rc));
5846 linklist_free(group_base);
5849 if (group_count == 0)
5857 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5858 int UpdateGroup, int *ProcessGroup, char *maillist)
5861 char GroupName[256];
5867 char AceMembership[2];
5870 char *save_argv[U_END];
5874 com_err(whoami, 0, "ProcessAce disabled, skipping");
5878 strcpy(GroupName, Name);
5880 if (strcasecmp(Type, "LIST"))
5886 AceInfo[0] = AceType;
5887 AceInfo[1] = AceName;
5888 AceInfo[2] = AceMembership;
5890 memset(AceType, '\0', sizeof(AceType));
5891 memset(AceName, '\0', sizeof(AceName));
5892 memset(AceMembership, '\0', sizeof(AceMembership));
5893 memset(AceOu, '\0', sizeof(AceOu));
5896 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5898 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5899 GroupName, error_message(rc));
5905 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5909 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5912 strcpy(temp, AceName);
5914 if (!strcasecmp(AceType, "LIST"))
5915 sprintf(temp, "%s%s", AceName, group_suffix);
5919 if (checkADname(ldap_handle, dn_path, temp))
5922 (*ProcessGroup) = 1;
5925 if (!strcasecmp(AceInfo[0], "LIST"))
5927 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5928 AceMembership, 0, UpdateGroup, maillist))
5931 else if (!strcasecmp(AceInfo[0], "USER"))
5934 call_args[0] = (char *)ldap_handle;
5935 call_args[1] = dn_path;
5937 call_args[3] = NULL;
5940 if (rc = mr_query("get_user_account_by_login", 1, av,
5941 save_query_info, save_argv))
5943 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5948 if (rc = user_create(U_END, save_argv, call_args))
5950 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5957 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5967 if (!strcasecmp(AceType, "LIST"))
5969 if (!strcasecmp(GroupName, AceName))
5973 strcpy(GroupName, AceName);
5979 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5980 char *group_name, char *group_ou, char *group_membership,
5981 int group_security_flag, int updateGroup, char *maillist)
5986 LK_ENTRY *group_base;
5989 char *attr_array[3];
5992 call_args[0] = (char *)ldap_handle;
5993 call_args[1] = dn_path;
5994 call_args[2] = group_name;
5995 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5996 call_args[4] = (char *)updateGroup;
5997 call_args[5] = MoiraId;
5999 call_args[7] = NULL;
6005 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
6008 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
6016 com_err(whoami, 0, "Unable to create list %s", group_name);
6017 return(callback_rc);
6023 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
6024 char *group_ou, char *group_membership,
6025 int group_security_flag, char *MoiraId)
6040 char *member_v[] = {NULL, NULL};
6041 char *save_argv[U_END];
6042 char machine_ou[256];
6043 char NewMachineName[1024];
6045 com_err(whoami, 0, "Populating group %s", group_name);
6047 call_args[0] = (char *)ldap_handle;
6048 call_args[1] = dn_path;
6049 call_args[2] = group_name;
6050 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS |
6052 call_args[4] = NULL;
6055 if (rc = mr_query("get_end_members_of_list", 1, av,
6056 member_list_build, call_args))
6058 com_err(whoami, 0, "Unable to populate list %s : %s",
6059 group_name, error_message(rc));
6063 members = (char **)malloc(sizeof(char *) * 2);
6065 if (member_base != NULL)
6071 if (!strcasecmp(ptr->type, "LIST"))
6077 if (!strcasecmp(ptr->type, "MACHINE") && !ProcessMachineContainer)
6083 if(!strcasecmp(ptr->type, "USER"))
6085 if(!strcasecmp(ptr->member, PRODUCTION_PRINCIPAL) ||
6086 !strcasecmp(ptr->member, TEST_PRINCIPAL))
6092 if ((rc = check_user(ldap_handle, dn_path, ptr->member,
6093 "")) == AD_NO_USER_FOUND)
6095 com_err(whoami, 0, "creating user %s", ptr->member);
6097 av[0] = ptr->member;
6098 call_args[0] = (char *)ldap_handle;
6099 call_args[1] = dn_path;
6101 call_args[3] = NULL;
6104 if (rc = mr_query("get_user_account_by_login", 1, av,
6105 save_query_info, save_argv))
6107 com_err(whoami, 0, "Unable to create user %s "
6108 "while populating group %s.", ptr->member,
6114 if (rc = user_create(U_END, save_argv, call_args))
6116 com_err(whoami, 0, "Unable to create user %s "
6117 "while populating group %s.", ptr->member,
6125 com_err(whoami, 0, "Unable to create user %s "
6126 "while populating group %s", ptr->member,
6137 sprintf(member, "cn=%s,%s,%s", ptr->member, pUserOu,
6142 sprintf(member, "uid=%s,%s,%s", ptr->member, pUserOu,
6147 else if (!strcasecmp(ptr->type, "STRING"))
6149 if (contact_create(ldap_handle, dn_path, ptr->member,
6153 pUserOu = contact_ou;
6154 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6157 else if (!strcasecmp(ptr->type, "KERBEROS"))
6159 if (contact_create(ldap_handle, dn_path, ptr->member,
6163 pUserOu = kerberos_ou;
6164 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6167 else if (!strcasecmp(ptr->type, "MACHINE"))
6169 memset(machine_ou, '\0', sizeof(machine_ou));
6170 memset(NewMachineName, '\0', sizeof(NewMachineName));
6172 if (!get_machine_ou(ldap_handle, dn_path, ptr->member,
6173 machine_ou, NewMachineName))
6175 pUserOu = machine_ou;
6176 sprintf(member, "cn=%s,%s,%s", NewMachineName, pUserOu,
6187 members = (char **)realloc(members, ((i + 2) * sizeof(char *)));
6188 members[i++] = strdup(member);
6193 linklist_free(member_base);
6199 sprintf(group_dn, "cn=%s,%s,%s", group_name, group_ou, dn_path);
6201 if(GroupPopulateDelete)
6204 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
6207 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6208 mods)) != LDAP_SUCCESS)
6211 "Unable to populate group membership for %s: %s",
6212 group_dn, ldap_err2string(rc));
6215 for (i = 0; i < n; i++)
6220 ADD_ATTR("member", members, LDAP_MOD_REPLACE);
6223 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6224 mods)) != LDAP_SUCCESS)
6227 "Unable to populate group membership for %s: %s",
6228 group_dn, ldap_err2string(rc));
6231 for (i = 0; i < n; i++)
6239 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
6240 char *group_name, char *group_ou, char *group_membership,
6241 int group_security_flag, int type, char *maillist)
6243 char before_desc[512];
6244 char before_name[256];
6245 char before_group_ou[256];
6246 char before_group_membership[2];
6247 char distinguishedName[256];
6248 char ad_distinguishedName[256];
6250 char *attr_array[3];
6251 int before_security_flag;
6254 LK_ENTRY *group_base;
6257 char ou_security[512];
6258 char ou_distribution[512];
6259 char ou_neither[512];
6262 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
6263 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
6265 memset(filter, '\0', sizeof(filter));
6269 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6271 "samAccountName", &group_base,
6272 &group_count, filter))
6275 if (type == CHECK_GROUPS)
6277 if (group_count == 1)
6279 strcpy(group_dn, group_base->dn);
6281 if (!strcasecmp(group_dn, distinguishedName))
6283 linklist_free(group_base);
6288 linklist_free(group_base);
6290 if (group_count == 0)
6291 return(AD_NO_GROUPS_FOUND);
6293 if (group_count == 1)
6294 return(AD_WRONG_GROUP_DN_FOUND);
6296 return(AD_MULTIPLE_GROUPS_FOUND);
6299 if (group_count == 0)
6301 return(AD_NO_GROUPS_FOUND);
6304 if (group_count > 1)
6308 strcpy(group_dn, ptr->dn);
6312 if (!strcasecmp(group_dn, ptr->value))
6320 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
6326 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
6330 linklist_free(group_base);
6331 return(AD_MULTIPLE_GROUPS_FOUND);
6338 strcpy(group_dn, ptr->dn);
6340 if (strcasecmp(group_dn, ptr->value))
6341 rc = ldap_delete_s(ldap_handle, ptr->value);
6346 linklist_free(group_base);
6347 memset(filter, '\0', sizeof(filter));
6351 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6353 "samAccountName", &group_base,
6354 &group_count, filter))
6357 if (group_count == 0)
6358 return(AD_NO_GROUPS_FOUND);
6360 if (group_count > 1)
6361 return(AD_MULTIPLE_GROUPS_FOUND);
6364 strcpy(ad_distinguishedName, group_base->dn);
6365 linklist_free(group_base);
6369 attr_array[0] = "sAMAccountName";
6370 attr_array[1] = NULL;
6372 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6373 &group_base, &group_count,
6374 LDAP_SCOPE_SUBTREE)) != 0)
6376 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6377 MoiraId, ldap_err2string(rc));
6381 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
6383 if (!strcasecmp(ad_distinguishedName, distinguishedName))
6385 linklist_free(group_base);
6391 linklist_free(group_base);
6394 memset(ou_both, '\0', sizeof(ou_both));
6395 memset(ou_security, '\0', sizeof(ou_security));
6396 memset(ou_distribution, '\0', sizeof(ou_distribution));
6397 memset(ou_neither, '\0', sizeof(ou_neither));
6398 memset(before_name, '\0', sizeof(before_name));
6399 memset(before_desc, '\0', sizeof(before_desc));
6400 memset(before_group_membership, '\0', sizeof(before_group_membership));
6402 attr_array[0] = "name";
6403 attr_array[1] = NULL;
6405 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6406 &group_base, &group_count,
6407 LDAP_SCOPE_SUBTREE)) != 0)
6409 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
6410 MoiraId, ldap_err2string(rc));
6414 strcpy(before_name, group_base->value);
6415 linklist_free(group_base);
6419 attr_array[0] = "description";
6420 attr_array[1] = NULL;
6422 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6423 &group_base, &group_count,
6424 LDAP_SCOPE_SUBTREE)) != 0)
6427 "Unable to get list description with MoiraId = %s: %s",
6428 MoiraId, ldap_err2string(rc));
6432 if (group_count != 0)
6434 strcpy(before_desc, group_base->value);
6435 linklist_free(group_base);
6440 change_to_lower_case(ad_distinguishedName);
6441 strcpy(ou_both, group_ou_both);
6442 change_to_lower_case(ou_both);
6443 strcpy(ou_security, group_ou_security);
6444 change_to_lower_case(ou_security);
6445 strcpy(ou_distribution, group_ou_distribution);
6446 change_to_lower_case(ou_distribution);
6447 strcpy(ou_neither, group_ou_neither);
6448 change_to_lower_case(ou_neither);
6450 if (strstr(ad_distinguishedName, ou_both))
6452 strcpy(before_group_ou, group_ou_both);
6453 before_group_membership[0] = 'B';
6454 before_security_flag = 1;
6456 else if (strstr(ad_distinguishedName, ou_security))
6458 strcpy(before_group_ou, group_ou_security);
6459 before_group_membership[0] = 'S';
6460 before_security_flag = 1;
6462 else if (strstr(ad_distinguishedName, ou_distribution))
6464 strcpy(before_group_ou, group_ou_distribution);
6465 before_group_membership[0] = 'D';
6466 before_security_flag = 0;
6468 else if (strstr(ad_distinguishedName, ou_neither))
6470 strcpy(before_group_ou, group_ou_neither);
6471 before_group_membership[0] = 'N';
6472 before_security_flag = 0;
6475 return(AD_NO_OU_FOUND);
6477 rc = group_rename(ldap_handle, dn_path, before_name,
6478 before_group_membership,
6479 before_group_ou, before_security_flag, before_desc,
6480 group_name, group_membership, group_ou,
6481 group_security_flag,
6482 before_desc, MoiraId, filter, maillist);
6487 void change_to_lower_case(char *ptr)
6491 for (i = 0; i < (int)strlen(ptr); i++)
6493 ptr[i] = tolower(ptr[i]);
6497 int ad_get_group(LDAP *ldap_handle, char *dn_path,
6498 char *group_name, char *group_membership,
6499 char *MoiraId, char *attribute,
6500 LK_ENTRY **linklist_base, int *linklist_count,
6505 char *attr_array[3];
6509 (*linklist_base) = NULL;
6510 (*linklist_count) = 0;
6512 if (strlen(rFilter) != 0)
6514 strcpy(filter, rFilter);
6515 attr_array[0] = attribute;
6516 attr_array[1] = NULL;
6518 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6519 linklist_base, linklist_count,
6520 LDAP_SCOPE_SUBTREE)) != 0)
6522 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6523 MoiraId, ldap_err2string(rc));
6527 if ((*linklist_count) == 1)
6529 strcpy(rFilter, filter);
6534 linklist_free((*linklist_base));
6535 (*linklist_base) = NULL;
6536 (*linklist_count) = 0;
6538 if (strlen(MoiraId) != 0)
6540 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
6542 attr_array[0] = attribute;
6543 attr_array[1] = NULL;
6545 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6546 linklist_base, linklist_count,
6547 LDAP_SCOPE_SUBTREE)) != 0)
6549 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6550 MoiraId, ldap_err2string(rc));
6555 if ((*linklist_count) > 1)
6557 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
6558 pPtr = (*linklist_base);
6562 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
6567 linklist_free((*linklist_base));
6568 (*linklist_base) = NULL;
6569 (*linklist_count) = 0;
6572 if ((*linklist_count) == 1)
6575 pPtr = (*linklist_base);
6576 dn = strdup(pPtr->dn);
6579 if (!memcmp(dn, group_name, strlen(group_name)))
6581 strcpy(rFilter, filter);
6586 linklist_free((*linklist_base));
6587 (*linklist_base) = NULL;
6588 (*linklist_count) = 0;
6589 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
6591 attr_array[0] = attribute;
6592 attr_array[1] = NULL;
6594 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6595 linklist_base, linklist_count,
6596 LDAP_SCOPE_SUBTREE)) != 0)
6598 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6599 MoiraId, ldap_err2string(rc));
6603 if ((*linklist_count) == 1)
6605 strcpy(rFilter, filter);
6612 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
6615 char *attr_array[3];
6616 char SamAccountName[64];
6619 LK_ENTRY *group_base;
6625 if (strlen(MoiraId) != 0)
6627 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
6629 attr_array[0] = "sAMAccountName";
6630 attr_array[1] = NULL;
6631 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6632 &group_base, &group_count,
6633 LDAP_SCOPE_SUBTREE)) != 0)
6635 com_err(whoami, 0, "Unable to process user %s : %s",
6636 UserName, ldap_err2string(rc));
6640 if (group_count > 1)
6642 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
6648 com_err(whoami, 0, "user %s exist with MoiraId = %s",
6649 gPtr->value, MoiraId);
6655 if (group_count != 1)
6657 linklist_free(group_base);
6660 sprintf(filter, "(sAMAccountName=%s)", UserName);
6661 attr_array[0] = "sAMAccountName";
6662 attr_array[1] = NULL;
6664 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6665 &group_base, &group_count,
6666 LDAP_SCOPE_SUBTREE)) != 0)
6668 com_err(whoami, 0, "Unable to process user %s : %s",
6669 UserName, ldap_err2string(rc));
6674 if (group_count != 1)
6676 linklist_free(group_base);
6677 return(AD_NO_USER_FOUND);
6680 strcpy(SamAccountName, group_base->value);
6681 linklist_free(group_base);
6685 if (strcmp(SamAccountName, UserName))
6688 "User object %s with MoiraId %s has mismatched usernames "
6689 "(LDAP username %s, Moira username %s)", SamAccountName,
6690 MoiraId, SamAccountName, UserName);
6696 void container_get_dn(char *src, char *dest)
6703 memset(array, '\0', 20 * sizeof(array[0]));
6705 if (strlen(src) == 0)
6727 strcpy(dest, "OU=");
6731 strcat(dest, array[n-1]);
6735 strcat(dest, ",OU=");
6742 void container_get_name(char *src, char *dest)
6747 if (strlen(src) == 0)
6767 void container_check(LDAP *ldap_handle, char *dn_path, char *name)
6774 strcpy(cName, name);
6776 for (i = 0; i < (int)strlen(cName); i++)
6778 if (cName[i] == '/')
6781 av[CONTAINER_NAME] = cName;
6782 av[CONTAINER_DESC] = "";
6783 av[CONTAINER_LOCATION] = "";
6784 av[CONTAINER_CONTACT] = "";
6785 av[CONTAINER_TYPE] = "";
6786 av[CONTAINER_ID] = "";
6787 av[CONTAINER_ROWID] = "";
6788 rc = container_create(ldap_handle, dn_path, 7, av);
6790 if (rc == LDAP_SUCCESS)
6792 com_err(whoami, 0, "container %s created without a mitMoiraId",
6801 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
6802 char **before, int afterc, char **after)
6807 char new_dn_path[256];
6809 char distinguishedName[256];
6814 memset(cName, '\0', sizeof(cName));
6815 container_get_name(after[CONTAINER_NAME], cName);
6817 if (!check_container_name(cName))
6819 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6821 return(AD_INVALID_NAME);
6824 memset(distinguishedName, '\0', sizeof(distinguishedName));
6826 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6827 distinguishedName, beforec, before))
6830 if (strlen(distinguishedName) == 0)
6832 rc = container_create(ldap_handle, dn_path, afterc, after);
6836 strcpy(temp, after[CONTAINER_NAME]);
6839 for (i = 0; i < (int)strlen(temp); i++)
6849 container_get_dn(temp, dName);
6851 if (strlen(temp) != 0)
6852 sprintf(new_dn_path, "%s,%s", dName, dn_path);
6854 sprintf(new_dn_path, "%s", dn_path);
6856 sprintf(new_cn, "OU=%s", cName);
6858 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6860 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6861 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6863 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6864 before[CONTAINER_NAME], after[CONTAINER_NAME],
6865 ldap_err2string(rc));
6869 memset(dName, '\0', sizeof(dName));
6870 container_get_dn(after[CONTAINER_NAME], dName);
6871 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6876 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6878 char distinguishedName[256];
6881 memset(distinguishedName, '\0', sizeof(distinguishedName));
6883 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6884 distinguishedName, count, av))
6887 if (strlen(distinguishedName) == 0)
6890 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6892 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6893 container_move_objects(ldap_handle, dn_path, distinguishedName);
6895 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6896 av[CONTAINER_NAME], ldap_err2string(rc));
6902 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6904 char *attr_array[3];
6905 LK_ENTRY *group_base;
6908 char *objectClass_v[] = {"top",
6909 "organizationalUnit",
6912 char *ou_v[] = {NULL, NULL};
6913 char *name_v[] = {NULL, NULL};
6914 char *moiraId_v[] = {NULL, NULL};
6915 char *desc_v[] = {NULL, NULL};
6916 char *managedBy_v[] = {NULL, NULL};
6919 char managedByDN[256];
6926 memset(filter, '\0', sizeof(filter));
6927 memset(dName, '\0', sizeof(dName));
6928 memset(cName, '\0', sizeof(cName));
6929 memset(managedByDN, '\0', sizeof(managedByDN));
6930 container_get_dn(av[CONTAINER_NAME], dName);
6931 container_get_name(av[CONTAINER_NAME], cName);
6933 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6935 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6937 return(AD_INVALID_NAME);
6940 if (!check_container_name(cName))
6942 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6944 return(AD_INVALID_NAME);
6948 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6950 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6952 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6954 if (strlen(av[CONTAINER_ROWID]) != 0)
6956 moiraId_v[0] = av[CONTAINER_ROWID];
6957 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6960 if (strlen(av[CONTAINER_DESC]) != 0)
6962 desc_v[0] = av[CONTAINER_DESC];
6963 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6966 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6968 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6970 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6973 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6974 kerberos_ou, dn_path);
6975 managedBy_v[0] = managedByDN;
6976 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6981 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6983 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6984 "(objectClass=user)))", av[CONTAINER_ID]);
6987 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6989 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6993 if (strlen(filter) != 0)
6995 attr_array[0] = "distinguishedName";
6996 attr_array[1] = NULL;
6999 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7001 &group_base, &group_count,
7002 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7004 if (group_count == 1)
7006 strcpy(managedByDN, group_base->value);
7007 managedBy_v[0] = managedByDN;
7008 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
7010 linklist_free(group_base);
7020 sprintf(temp, "%s,%s", dName, dn_path);
7021 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
7023 for (i = 0; i < n; i++)
7026 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
7028 com_err(whoami, 0, "Unable to create container %s : %s",
7029 cName, ldap_err2string(rc));
7033 if (rc == LDAP_ALREADY_EXISTS)
7035 if (strlen(av[CONTAINER_ROWID]) != 0)
7036 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
7042 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
7043 char **before, int afterc, char **after)
7045 char distinguishedName[256];
7048 memset(distinguishedName, '\0', sizeof(distinguishedName));
7050 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
7051 distinguishedName, afterc, after))
7054 if (strlen(distinguishedName) == 0)
7056 rc = container_create(ldap_handle, dn_path, afterc, after);
7060 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
7061 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
7067 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
7068 char *distinguishedName, int count,
7071 char *attr_array[3];
7072 LK_ENTRY *group_base;
7079 memset(filter, '\0', sizeof(filter));
7080 memset(dName, '\0', sizeof(dName));
7081 memset(cName, '\0', sizeof(cName));
7082 container_get_dn(av[CONTAINER_NAME], dName);
7083 container_get_name(av[CONTAINER_NAME], cName);
7085 if (strlen(dName) == 0)
7087 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7088 av[CONTAINER_NAME]);
7089 return(AD_INVALID_NAME);
7092 if (!check_container_name(cName))
7094 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7096 return(AD_INVALID_NAME);
7099 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7100 av[CONTAINER_ROWID]);
7101 attr_array[0] = "distinguishedName";
7102 attr_array[1] = NULL;
7106 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7107 &group_base, &group_count,
7108 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7110 if (group_count == 1)
7112 strcpy(distinguishedName, group_base->value);
7115 linklist_free(group_base);
7120 if (strlen(distinguishedName) == 0)
7122 sprintf(filter, "(&(objectClass=organizationalUnit)"
7123 "(distinguishedName=%s,%s))", dName, dn_path);
7124 attr_array[0] = "distinguishedName";
7125 attr_array[1] = NULL;
7129 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7130 &group_base, &group_count,
7131 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7133 if (group_count == 1)
7135 strcpy(distinguishedName, group_base->value);
7138 linklist_free(group_base);
7147 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
7148 char *distinguishedName, int count, char **av)
7150 char *attr_array[5];
7151 LK_ENTRY *group_base;
7156 char *moiraId_v[] = {NULL, NULL};
7157 char *desc_v[] = {NULL, NULL};
7158 char *managedBy_v[] = {NULL, NULL};
7159 char managedByDN[256];
7168 strcpy(ad_path, distinguishedName);
7170 if (strlen(dName) != 0)
7171 sprintf(ad_path, "%s,%s", dName, dn_path);
7173 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
7176 if (strlen(av[CONTAINER_ID]) != 0)
7177 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7178 av[CONTAINER_ROWID]);
7180 attr_array[0] = "mitMoiraId";
7181 attr_array[1] = "description";
7182 attr_array[2] = "managedBy";
7183 attr_array[3] = NULL;
7187 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7188 &group_base, &group_count,
7189 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7191 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
7192 av[CONTAINER_NAME], ldap_err2string(rc));
7196 memset(managedByDN, '\0', sizeof(managedByDN));
7197 memset(moiraId, '\0', sizeof(moiraId));
7198 memset(desc, '\0', sizeof(desc));
7203 if (!strcasecmp(pPtr->attribute, "description"))
7204 strcpy(desc, pPtr->value);
7205 else if (!strcasecmp(pPtr->attribute, "managedBy"))
7206 strcpy(managedByDN, pPtr->value);
7207 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
7208 strcpy(moiraId, pPtr->value);
7212 linklist_free(group_base);
7217 if (strlen(av[CONTAINER_ROWID]) != 0)
7219 moiraId_v[0] = av[CONTAINER_ROWID];
7220 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
7223 if (strlen(av[CONTAINER_DESC]) != 0)
7225 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
7230 if (strlen(desc) != 0)
7232 attribute_update(ldap_handle, ad_path, "", "description", dName);
7236 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
7238 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
7240 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
7243 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
7244 kerberos_ou, dn_path);
7245 managedBy_v[0] = managedByDN;
7246 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7250 if (strlen(managedByDN) != 0)
7252 attribute_update(ldap_handle, ad_path, "", "managedBy",
7259 memset(filter, '\0', sizeof(filter));
7261 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
7263 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
7264 "(objectClass=user)))", av[CONTAINER_ID]);
7267 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
7269 sprintf(filter, "(&(objectClass=group)(cn=%s))",
7273 if (strlen(filter) != 0)
7275 attr_array[0] = "distinguishedName";
7276 attr_array[1] = NULL;
7279 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7280 attr_array, &group_base, &group_count,
7281 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7283 if (group_count == 1)
7285 strcpy(managedByDN, group_base->value);
7286 managedBy_v[0] = managedByDN;
7287 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7291 if (strlen(managedByDN) != 0)
7293 attribute_update(ldap_handle, ad_path, "",
7294 "managedBy", dName);
7298 linklist_free(group_base);
7305 if (strlen(managedByDN) != 0)
7307 attribute_update(ldap_handle, ad_path, "", "managedBy",
7317 return(LDAP_SUCCESS);
7319 rc = ldap_modify_s(ldap_handle, ad_path, mods);
7321 for (i = 0; i < n; i++)
7324 if (rc != LDAP_SUCCESS)
7326 com_err(whoami, 0, "Unable to modify container info for %s : %s",
7327 av[CONTAINER_NAME], ldap_err2string(rc));
7334 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
7336 char *attr_array[3];
7337 LK_ENTRY *group_base;
7344 int NumberOfEntries = 10;
7348 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
7350 for (i = 0; i < 3; i++)
7352 memset(filter, '\0', sizeof(filter));
7356 strcpy(filter, "(!(|(objectClass=computer)"
7357 "(objectClass=organizationalUnit)))");
7358 attr_array[0] = "cn";
7359 attr_array[1] = NULL;
7363 strcpy(filter, "(objectClass=computer)");
7364 attr_array[0] = "cn";
7365 attr_array[1] = NULL;
7369 strcpy(filter, "(objectClass=organizationalUnit)");
7370 attr_array[0] = "ou";
7371 attr_array[1] = NULL;
7376 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
7377 &group_base, &group_count,
7378 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7383 if (group_count == 0)
7390 if (!strcasecmp(pPtr->attribute, "cn"))
7392 sprintf(new_cn, "cn=%s", pPtr->value);
7394 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
7396 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
7401 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
7403 if (rc == LDAP_ALREADY_EXISTS)
7405 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
7412 else if (!strcasecmp(pPtr->attribute, "ou"))
7414 rc = ldap_delete_s(ldap_handle, pPtr->dn);
7420 linklist_free(group_base);
7429 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
7430 char *machine_ou, char *NewMachineName)
7432 LK_ENTRY *group_base;
7436 char *attr_array[3];
7443 strcpy(NewMachineName, member);
7444 rc = moira_connect();
7445 rc = GetMachineName(NewMachineName);
7448 if (strlen(NewMachineName) == 0)
7450 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7456 pPtr = strchr(NewMachineName, '.');
7463 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
7464 attr_array[0] = "cn";
7465 attr_array[1] = NULL;
7466 sprintf(temp, "%s", dn_path);
7468 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
7469 &group_base, &group_count,
7470 LDAP_SCOPE_SUBTREE)) != 0)
7472 com_err(whoami, 0, "Unable to process machine %s : %s",
7473 member, ldap_err2string(rc));
7477 if (group_count != 1)
7482 strcpy(dn, group_base->dn);
7483 strcpy(cn, group_base->value);
7485 for (i = 0; i < (int)strlen(dn); i++)
7486 dn[i] = tolower(dn[i]);
7488 for (i = 0; i < (int)strlen(cn); i++)
7489 cn[i] = tolower(cn[i]);
7491 linklist_free(group_base);
7493 pPtr = strstr(dn, cn);
7497 com_err(whoami, 0, "Unable to process machine %s",
7502 pPtr += strlen(cn) + 1;
7503 strcpy(machine_ou, pPtr);
7505 pPtr = strstr(machine_ou, "dc=");
7509 com_err(whoami, 0, "Unable to process machine %s",
7520 int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
7521 char *MoiraMachineName, char *DestinationOu)
7525 char MachineName[128];
7527 char *attr_array[3];
7532 LK_ENTRY *group_base;
7537 strcpy(MachineName, MoiraMachineName);
7538 rc = GetMachineName(MachineName);
7540 if (strlen(MachineName) == 0)
7542 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7547 cPtr = strchr(MachineName, '.');
7552 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
7553 attr_array[0] = "sAMAccountName";
7554 attr_array[1] = NULL;
7556 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7558 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
7560 com_err(whoami, 0, "Unable to process machine %s : %s",
7561 MoiraMachineName, ldap_err2string(rc));
7565 if (group_count == 1)
7566 strcpy(OldDn, group_base->dn);
7568 linklist_free(group_base);
7571 if (group_count != 1)
7573 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
7578 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
7579 cPtr = strchr(OldDn, ',');
7584 if (!strcasecmp(cPtr, NewOu))
7588 sprintf(NewCn, "CN=%s", MachineName);
7589 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
7594 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
7600 memset(Name, '\0', sizeof(Name));
7601 strcpy(Name, machine_name);
7603 pPtr = strchr(Name, '.');
7609 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
7612 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
7613 char *machine_name, char *container_name)
7619 av[0] = machine_name;
7620 call_args[0] = (char *)container_name;
7621 rc = mr_query("get_machine_to_container_map", 1, av,
7622 machine_GetMoiraContainer, call_args);
7626 int machine_GetMoiraContainer(int ac, char **av, void *ptr)
7631 strcpy(call_args[0], av[1]);
7635 int Moira_container_group_create(char **after)
7641 memset(GroupName, '\0', sizeof(GroupName));
7642 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
7643 after[CONTAINER_ROWID]);
7647 argv[L_NAME] = GroupName;
7648 argv[L_ACTIVE] = "1";
7649 argv[L_PUBLIC] = "0";
7650 argv[L_HIDDEN] = "0";
7651 argv[L_MAILLIST] = "0";
7652 argv[L_GROUP] = "1";
7653 argv[L_GID] = UNIQUE_GID;
7654 argv[L_NFSGROUP] = "0";
7655 argv[L_MAILMAN] = "0";
7656 argv[L_MAILMAN_SERVER] = "[NONE]";
7657 argv[L_DESC] = "auto created container group";
7658 argv[L_ACE_TYPE] = "USER";
7659 argv[L_MEMACE_TYPE] = "USER";
7660 argv[L_ACE_NAME] = "sms";
7661 argv[L_MEMACE_NAME] = "sms";
7663 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
7666 "Unable to create container group %s for container %s: %s",
7667 GroupName, after[CONTAINER_NAME], error_message(rc));
7670 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
7671 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
7676 int Moira_container_group_update(char **before, char **after)
7679 char BeforeGroupName[64];
7680 char AfterGroupName[64];
7683 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
7686 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
7687 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
7688 if (strlen(BeforeGroupName) == 0)
7691 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
7692 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
7693 after[CONTAINER_ROWID]);
7697 if (strcasecmp(BeforeGroupName, AfterGroupName))
7699 argv[L_NAME] = BeforeGroupName;
7700 argv[L_NAME + 1] = AfterGroupName;
7701 argv[L_ACTIVE + 1] = "1";
7702 argv[L_PUBLIC + 1] = "0";
7703 argv[L_HIDDEN + 1] = "0";
7704 argv[L_MAILLIST + 1] = "0";
7705 argv[L_GROUP + 1] = "1";
7706 argv[L_GID + 1] = UNIQUE_GID;
7707 argv[L_NFSGROUP + 1] = "0";
7708 argv[L_MAILMAN + 1] = "0";
7709 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
7710 argv[L_DESC + 1] = "auto created container group";
7711 argv[L_ACE_TYPE + 1] = "USER";
7712 argv[L_MEMACE_TYPE + 1] = "USER";
7713 argv[L_ACE_NAME + 1] = "sms";
7714 argv[L_MEMACE_NAME + 1] = "sms";
7716 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
7719 "Unable to rename container group from %s to %s: %s",
7720 BeforeGroupName, AfterGroupName, error_message(rc));
7727 int Moira_container_group_delete(char **before)
7732 char ParentGroupName[64];
7734 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
7735 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
7737 memset(GroupName, '\0', sizeof(GroupName));
7739 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
7740 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
7742 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
7744 argv[0] = ParentGroupName;
7746 argv[2] = GroupName;
7748 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
7751 "Unable to delete container group %s from list: %s",
7752 GroupName, ParentGroupName, error_message(rc));
7756 if (strlen(GroupName) != 0)
7758 argv[0] = GroupName;
7760 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
7762 com_err(whoami, 0, "Unable to delete container group %s : %s",
7763 GroupName, error_message(rc));
7770 int Moira_groupname_create(char *GroupName, char *ContainerName,
7771 char *ContainerRowID)
7776 char newGroupName[64];
7777 char tempGroupName[64];
7783 strcpy(temp, ContainerName);
7785 ptr1 = strrchr(temp, '/');
7791 ptr1 = strrchr(temp, '/');
7795 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
7798 strcpy(tempgname, ptr);
7801 strcpy(tempgname, temp);
7803 if (strlen(tempgname) > 25)
7804 tempgname[25] ='\0';
7806 sprintf(newGroupName, "cnt-%s", tempgname);
7808 /* change everything to lower case */
7814 *ptr = tolower(*ptr);
7822 strcpy(tempGroupName, newGroupName);
7825 /* append 0-9 then a-z if a duplicate is found */
7828 argv[0] = newGroupName;
7830 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
7832 if (rc == MR_NO_MATCH)
7834 com_err(whoami, 0, "Moira error while creating group name for "
7835 "container %s : %s", ContainerName, error_message(rc));
7839 sprintf(newGroupName, "%s-%c", tempGroupName, i);
7843 com_err(whoami, 0, "Unable to find a unique group name for "
7844 "container %s: too many duplicate container names",
7855 strcpy(GroupName, newGroupName);
7859 int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7864 argv[0] = origContainerName;
7865 argv[1] = GroupName;
7867 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7870 "Unable to set container group %s in container %s: %s",
7871 GroupName, origContainerName, error_message(rc));
7877 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7879 char ContainerName[64];
7880 char ParentGroupName[64];
7884 strcpy(ContainerName, origContainerName);
7886 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7888 /* top-level container */
7889 if (strlen(ParentGroupName) == 0)
7892 argv[0] = ParentGroupName;
7894 argv[2] = GroupName;
7896 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7899 "Unable to add container group %s to parent group %s: %s",
7900 GroupName, ParentGroupName, error_message(rc));
7906 int Moira_getContainerGroup(int ac, char **av, void *ptr)
7911 strcpy(call_args[0], av[1]);
7916 int Moira_getGroupName(char *origContainerName, char *GroupName,
7919 char ContainerName[64];
7925 strcpy(ContainerName, origContainerName);
7929 ptr = strrchr(ContainerName, '/');
7937 argv[0] = ContainerName;
7939 call_args[0] = GroupName;
7940 call_args[1] = NULL;
7942 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7945 if (strlen(GroupName) != 0)
7950 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7951 ContainerName, error_message(rc));
7953 com_err(whoami, 0, "Unable to get container group from container %s",
7959 int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7965 if (strcmp(GroupName, "[none]") == 0)
7968 argv[0] = GroupName;
7969 argv[1] = "MACHINE";
7970 argv[2] = MachineName;
7973 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7975 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7979 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7980 MachineName, GroupName, error_message(rc));
7986 int GetMachineName(char *MachineName)
7989 char NewMachineName[1024];
7996 // If the address happens to be in the top-level MIT domain, great!
7997 strcpy(NewMachineName, MachineName);
7999 for (i = 0; i < (int)strlen(NewMachineName); i++)
8000 NewMachineName[i] = toupper(NewMachineName[i]);
8002 szDot = strchr(NewMachineName,'.');
8004 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
8009 // If not, see if it has a Moira alias in the top-level MIT domain.
8010 memset(NewMachineName, '\0', sizeof(NewMachineName));
8012 args[1] = MachineName;
8013 call_args[0] = NewMachineName;
8014 call_args[1] = NULL;
8016 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
8018 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
8019 MachineName, error_message(rc));
8020 strcpy(MachineName, "");
8024 if (strlen(NewMachineName) != 0)
8025 strcpy(MachineName, NewMachineName);
8027 strcpy(MachineName, "");
8032 int ProcessMachineName(int ac, char **av, void *ptr)
8035 char MachineName[1024];
8041 if (strlen(call_args[0]) == 0)
8043 strcpy(MachineName, av[0]);
8045 for (i = 0; i < (int)strlen(MachineName); i++)
8046 MachineName[i] = toupper(MachineName[i]);
8048 szDot = strchr(MachineName,'.');
8050 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
8052 strcpy(call_args[0], MachineName);
8059 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
8065 for (i = 0; i < n; i++)
8067 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
8068 mods[i]->mod_type = "uidNumber";
8075 for (i = 0; i < n; i++)
8077 if (!strcmp(mods[i]->mod_type, "uidNumber"))
8078 mods[i]->mod_type = "msSFU30UidNumber";
8085 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
8086 char *DistinguishedName,
8087 char *WinHomeDir, char *WinProfileDir,
8088 char **homedir_v, char **winProfile_v,
8089 char **drives_v, LDAPMod **mods,
8096 char winProfile[1024];
8099 char apple_homedir[1024];
8100 char *apple_homedir_v[] = {NULL, NULL};
8104 LDAPMod *DelMods[20];
8106 char *save_argv[FS_END];
8107 char *fsgroup_save_argv[2];
8109 memset(homeDrive, '\0', sizeof(homeDrive));
8110 memset(path, '\0', sizeof(path));
8111 memset(winPath, '\0', sizeof(winPath));
8112 memset(winProfile, '\0', sizeof(winProfile));
8114 if(!ActiveDirectory)
8116 if (rc = moira_connect())
8118 critical_alert("AD incremental",
8119 "Error contacting Moira server : %s",
8124 argv[0] = user_name;
8126 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8129 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8130 !strcmp(save_argv[FS_TYPE], "MUL"))
8133 argv[0] = save_argv[FS_NAME];
8136 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8137 save_fsgroup_info, fsgroup_save_argv)))
8141 argv[0] = fsgroup_save_argv[0];
8143 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8144 save_query_info, save_argv)))
8146 strcpy(path, save_argv[FS_PACK]);
8153 strcpy(path, save_argv[FS_PACK]);
8161 if (!strnicmp(path, AFS, strlen(AFS)))
8163 sprintf(homedir, "%s", path);
8164 sprintf(apple_homedir, "%s/MacData", path);
8165 homedir_v[0] = homedir;
8166 apple_homedir_v[0] = apple_homedir;
8167 ADD_ATTR("homeDirectory", homedir_v, OpType);
8168 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8174 homedir_v[0] = "NONE";
8175 apple_homedir_v[0] = "NONE";
8176 ADD_ATTR("homeDirectory", homedir_v, OpType);
8177 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8184 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
8185 (!strcasecmp(WinProfileDir, "[afs]")))
8187 if (rc = moira_connect())
8189 critical_alert("AD incremental",
8190 "Error contacting Moira server : %s",
8195 argv[0] = user_name;
8197 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8200 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8201 !strcmp(save_argv[FS_TYPE], "MUL"))
8204 argv[0] = save_argv[FS_NAME];
8207 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8208 save_fsgroup_info, fsgroup_save_argv)))
8212 argv[0] = fsgroup_save_argv[0];
8214 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8215 save_query_info, save_argv)))
8217 strcpy(path, save_argv[FS_PACK]);
8224 strcpy(path, save_argv[FS_PACK]);
8232 if (!strnicmp(path, AFS, strlen(AFS)))
8234 AfsToWinAfs(path, winPath);
8235 strcpy(winProfile, winPath);
8236 strcat(winProfile, "\\.winprofile");
8243 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
8244 (!strcasecmp(WinProfileDir, "[dfs]")))
8246 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
8247 user_name[0], user_name);
8249 if (!strcasecmp(WinProfileDir, "[dfs]"))
8251 strcpy(winProfile, path);
8252 strcat(winProfile, "\\.winprofile");
8255 if (!strcasecmp(WinHomeDir, "[dfs]"))
8256 strcpy(winPath, path);
8259 if (!strcasecmp(WinHomeDir, "[local]"))
8260 memset(winPath, '\0', sizeof(winPath));
8261 else if (!strcasecmp(WinHomeDir, "[afs]") ||
8262 !strcasecmp(WinHomeDir, "[dfs]"))
8264 strcpy(homeDrive, "H:");
8268 strcpy(winPath, WinHomeDir);
8269 if (!strncmp(WinHomeDir, "\\\\", 2))
8271 strcpy(homeDrive, "H:");
8275 // nothing needs to be done if WinProfileDir is [afs].
8276 if (!strcasecmp(WinProfileDir, "[local]"))
8277 memset(winProfile, '\0', sizeof(winProfile));
8278 else if (strcasecmp(WinProfileDir, "[afs]") &&
8279 strcasecmp(WinProfileDir, "[dfs]"))
8281 strcpy(winProfile, WinProfileDir);
8284 if (strlen(winProfile) != 0)
8286 if (winProfile[strlen(winProfile) - 1] == '\\')
8287 winProfile[strlen(winProfile) - 1] = '\0';
8290 if (strlen(winPath) != 0)
8292 if (winPath[strlen(winPath) - 1] == '\\')
8293 winPath[strlen(winPath) - 1] = '\0';
8296 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
8297 strcat(winProfile, "\\");
8299 if ((winPath[1] == ':') && (strlen(winPath) == 2))
8300 strcat(winPath, "\\");
8302 if (strlen(winPath) == 0)
8304 if (OpType == LDAP_MOD_REPLACE)
8307 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
8309 //unset homeDirectory attribute for user.
8310 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8316 homedir_v[0] = strdup(winPath);
8317 ADD_ATTR("homeDirectory", homedir_v, OpType);
8320 if (strlen(winProfile) == 0)
8322 if (OpType == LDAP_MOD_REPLACE)
8325 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
8327 //unset profilePate attribute for user.
8328 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8334 winProfile_v[0] = strdup(winProfile);
8335 ADD_ATTR("profilePath", winProfile_v, OpType);
8338 if (strlen(homeDrive) == 0)
8340 if (OpType == LDAP_MOD_REPLACE)
8343 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
8345 //unset homeDrive attribute for user
8346 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8352 drives_v[0] = strdup(homeDrive);
8353 ADD_ATTR("homeDrive", drives_v, OpType);
8359 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
8360 char *attribute_value, char *attribute, char *user_name)
8362 char *mod_v[] = {NULL, NULL};
8363 LDAPMod *DelMods[20];
8369 if (strlen(attribute_value) == 0)
8372 DEL_ATTR(attribute, LDAP_MOD_DELETE);
8374 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
8380 mod_v[0] = attribute_value;
8381 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
8384 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8385 mods)) != LDAP_SUCCESS)
8389 mod_v[0] = attribute_value;
8390 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
8393 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8394 mods)) != LDAP_SUCCESS)
8396 com_err(whoami, 0, "Unable to change the %s attribute for %s "
8398 attribute, user_name, ldap_err2string(rc));
8408 void StringTrim(char *StringToTrim)
8413 save = strdup(StringToTrim);
8420 /* skip to end of string */
8425 strcpy(StringToTrim, save);
8429 for (t = s; *t; t++)
8445 strcpy(StringToTrim, s);
8449 int ReadConfigFile(char *DomainName)
8460 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
8462 if ((fptr = fopen(temp, "r")) != NULL)
8464 while (fgets(temp, sizeof(temp), fptr) != 0)
8466 for (i = 0; i < (int)strlen(temp); i++)
8467 temp[i] = toupper(temp[i]);
8469 if (temp[strlen(temp) - 1] == '\n')
8470 temp[strlen(temp) - 1] = '\0';
8474 if (strlen(temp) == 0)
8477 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8479 if (strlen(temp) > (strlen(DOMAIN)))
8481 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
8482 StringTrim(ldap_domain);
8485 else if (!strncmp(temp, REALM, strlen(REALM)))
8487 if (strlen(temp) > (strlen(REALM)))
8489 strcpy(ldap_realm, &temp[strlen(REALM)]);
8490 StringTrim(ldap_realm);
8493 else if (!strncmp(temp, PORT, strlen(PORT)))
8495 if (strlen(temp) > (strlen(PORT)))
8497 strcpy(ldap_port, &temp[strlen(PORT)]);
8498 StringTrim(ldap_port);
8501 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
8503 if (strlen(temp) > (strlen(PRINCIPALNAME)))
8505 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
8506 StringTrim(PrincipalName);
8509 else if (!strncmp(temp, SERVER, strlen(SERVER)))
8511 if (strlen(temp) > (strlen(SERVER)))
8513 ServerList[Count] = calloc(1, 256);
8514 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
8515 StringTrim(ServerList[Count]);
8519 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
8521 if (strlen(temp) > (strlen(MSSFU)))
8523 strcpy(temp1, &temp[strlen(MSSFU)]);
8525 if (!strcmp(temp1, SFUTYPE))
8529 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
8531 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
8533 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
8535 if (!strcasecmp(temp1, "NO"))
8538 memset(group_suffix, '\0', sizeof(group_suffix));
8542 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
8544 if (strlen(temp) > (strlen(GROUP_TYPE)))
8546 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
8548 if (!strcasecmp(temp1, "UNIVERSAL"))
8549 UseGroupUniversal = 1;
8552 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
8554 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
8556 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
8558 if (!strcasecmp(temp1, "NO"))
8562 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
8564 if (strlen(temp) > (strlen(SET_PASSWORD)))
8566 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
8568 if (!strcasecmp(temp1, "NO"))
8572 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
8574 if (strlen(temp) > (strlen(EXCHANGE)))
8576 strcpy(temp1, &temp[strlen(EXCHANGE)]);
8578 if (!strcasecmp(temp1, "YES"))
8582 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
8583 strlen(PROCESS_MACHINE_CONTAINER)))
8585 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
8587 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
8589 if (!strcasecmp(temp1, "NO"))
8590 ProcessMachineContainer = 0;
8593 else if (!strncmp(temp, ACTIVE_DIRECTORY,
8594 strlen(ACTIVE_DIRECTORY)))
8596 if (strlen(temp) > (strlen(ACTIVE_DIRECTORY)))
8598 strcpy(temp1, &temp[strlen(ACTIVE_DIRECTORY)]);
8600 if (!strcasecmp(temp1, "NO"))
8601 ActiveDirectory = 0;
8604 else if (!strncmp(temp, GROUP_POPULATE_MEMBERS,
8605 strlen(GROUP_POPULATE_MEMBERS)))
8607 if (strlen(temp) > (strlen(GROUP_POPULATE_MEMBERS)))
8609 strcpy(temp1, &temp[strlen(GROUP_POPULATE_MEMBERS)]);
8611 if (!strcasecmp(temp1, "DELETE"))
8613 GroupPopulateDelete = 1;
8619 if (strlen(ldap_domain) != 0)
8621 memset(ldap_domain, '\0', sizeof(ldap_domain));
8625 if (strlen(temp) != 0)
8626 strcpy(ldap_domain, temp);
8632 if (strlen(ldap_domain) == 0)
8634 strcpy(ldap_domain, DomainName);
8640 for (i = 0; i < Count; i++)
8642 if (ServerList[i] != 0)
8644 for (k = 0; k < (int)strlen(ServerList[i]); k++)
8645 ServerList[i][k] = toupper(ServerList[i][k]);
8652 int ReadDomainList()
8659 unsigned char c[11];
8660 unsigned char stuff[256];
8665 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
8667 if ((fptr = fopen(temp, "r")) != NULL)
8669 while (fgets(temp, sizeof(temp), fptr) != 0)
8671 for (i = 0; i < (int)strlen(temp); i++)
8672 temp[i] = toupper(temp[i]);
8674 if (temp[strlen(temp) - 1] == '\n')
8675 temp[strlen(temp) - 1] = '\0';
8679 if (strlen(temp) == 0)
8682 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8684 if (strlen(temp) > (strlen(DOMAIN)))
8686 strcpy(temp1, &temp[strlen(DOMAIN)]);
8688 strcpy(temp, temp1);
8692 strcpy(DomainNames[Count], temp);
8693 StringTrim(DomainNames[Count]);
8702 critical_alert("incremental", "%s", "ldap.incr cannot run due to a "
8703 "configuration error in ldap.cfg");
8710 int email_isvalid(const char *address) {
8712 const char *c, *domain;
8713 static char *rfc822_specials = "()<>@,;:\\\"[]";
8715 if(address[strlen(address) - 1] == '.')
8718 /* first we validate the name portion (name@domain) */
8719 for (c = address; *c; c++) {
8720 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
8725 if (*c == '\\' && (*++c == ' '))
8727 if (*c <= ' ' || *c >= 127)
8742 if (*c <= ' ' || *c >= 127)
8744 if (strchr(rfc822_specials, *c))
8748 if (c == address || *(c - 1) == '.')
8751 /* next we validate the domain portion (name@domain) */
8752 if (!*(domain = ++c)) return 0;
8755 if (c == domain || *(c - 1) == '.')
8759 if (*c <= ' ' || *c >= 127)
8761 if (strchr(rfc822_specials, *c))
8765 return (count >= 1);
8768 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
8769 char **homeServerName)
8771 LK_ENTRY *group_base;
8772 LK_ENTRY *sub_group_base;
8776 int sub_group_count;
8778 char sub_filter[1024];
8779 char search_path[1024];
8781 char *attr_array[3];
8783 int homeMDB_count = -1;
8787 int rangeStep = 1500;
8789 int rangeHigh = rangeLow + (rangeStep - 1);
8792 /* Grumble..... microsoft not making it searchable from the root *grr* */
8794 memset(filter, '\0', sizeof(filter));
8795 memset(search_path, '\0', sizeof(search_path));
8797 sprintf(filter, "(objectClass=msExchMDB)");
8798 sprintf(search_path, "CN=Configuration,%s", dn_path);
8799 attr_array[0] = "distinguishedName";
8800 attr_array[1] = NULL;
8805 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
8806 &group_base, &group_count,
8807 LDAP_SCOPE_SUBTREE)) != 0)
8809 com_err(whoami, 0, "Unable to find msExchMDB %s",
8810 ldap_err2string(rc));
8819 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
8820 ((s = strstr(gPtr->dn, "Recover")) != (char *) NULL) ||
8821 ((s = strstr(gPtr->dn, "Reserve")) != (char *) NULL))
8828 * Due to limits in active directory we need to use the LDAP
8829 * range semantics to query and return all the values in
8830 * large lists, we will stop increasing the range when
8831 * the result count is 0.
8839 memset(sub_filter, '\0', sizeof(sub_filter));
8840 memset(range, '\0', sizeof(range));
8841 sprintf(sub_filter, "(objectClass=msExchMDB)");
8844 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
8846 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
8848 attr_array[0] = range;
8849 attr_array[1] = NULL;
8851 sub_group_base = NULL;
8852 sub_group_count = 0;
8854 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
8855 attr_array, &sub_group_base,
8857 LDAP_SCOPE_SUBTREE)) != 0)
8859 com_err(whoami, 0, "Unable to find homeMDBBL %s",
8860 ldap_err2string(rc));
8864 if(!sub_group_count)
8870 rangeHigh = rangeLow + (rangeStep - 1);
8877 mdbbl_count += sub_group_count;
8878 rangeLow = rangeHigh + 1;
8879 rangeHigh = rangeLow + (rangeStep - 1);
8882 /* First time through, need to initialize or update the least used */
8884 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
8887 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
8889 homeMDB_count = mdbbl_count;
8890 *homeMDB = strdup(gPtr->dn);
8894 linklist_free(sub_group_base);
8898 linklist_free(group_base);
8901 * Ok found the server least allocated need to now query to get its
8902 * msExchHomeServerName so we can set it as a user attribute
8905 attr_array[0] = "legacyExchangeDN";
8906 attr_array[1] = NULL;
8911 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
8912 attr_array, &group_base,
8914 LDAP_SCOPE_SUBTREE)) != 0)
8916 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
8917 ldap_err2string(rc));
8923 *homeServerName = strdup(group_base->value);
8924 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
8930 linklist_free(group_base);
8935 char *lowercase(char *s)
8939 for (p = s; *p; p++)
8947 char *uppercase(char *s)
8951 for (p = s; *p; p++)
8959 char *escape_string(char *s)
8967 memset(string, '\0', sizeof(string));
8971 /* Replace leading spaces */
8973 while(isspace(*q)) {
8980 /* Escape any special characters */
8982 for(; *q != '\0'; q++) {
9005 return strdup(string);
9008 int save_query_info(int argc, char **argv, void *hint)
9011 char **nargv = hint;
9013 for(i = 0; i < argc; i++)
9014 nargv[i] = strdup(argv[i]);
9019 int save_fsgroup_info(int argc, char **argv, void *hint)
9022 char **nargv = hint;
9026 for(i = 0; i < argc; i++)
9027 nargv[i] = strdup(argv[i]);