2 /* winad.incr arguments example
4 * arguments when moira creates the account - ignored by winad.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/winad/"
204 #define WINADCFG "winad.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 "winad.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
295 #define CHECK_GROUPS 1
296 #define CLEANUP_GROUPS 2
298 #define AD_NO_GROUPS_FOUND -1
299 #define AD_WRONG_GROUP_DN_FOUND -2
300 #define AD_MULTIPLE_GROUPS_FOUND -3
301 #define AD_INVALID_NAME -4
302 #define AD_LDAP_FAILURE -5
303 #define AD_INVALID_FILESYS -6
304 #define AD_NO_ATTRIBUTE_FOUND -7
305 #define AD_NO_OU_FOUND -8
306 #define AD_NO_USER_FOUND -9
308 /* container arguments */
309 #define CONTAINER_NAME 0
310 #define CONTAINER_DESC 1
311 #define CONTAINER_LOCATION 2
312 #define CONTAINER_CONTACT 3
313 #define CONTAINER_TYPE 4
314 #define CONTAINER_ID 5
315 #define CONTAINER_ROWID 6
316 #define CONTAINER_GROUP_NAME 7
318 /*mcntmap arguments*/
319 #define OU_MACHINE_NAME 0
320 #define OU_CONTAINER_NAME 1
321 #define OU_MACHINE_ID 2
322 #define OU_CONTAINER_ID 3
323 #define OU_CONTAINER_GROUP 4
325 typedef struct lk_entry {
335 struct lk_entry *next;
338 #define STOP_FILE "/moira/winad/nowinad"
339 #define file_exists(file) (access((file), F_OK) == 0)
341 #define N_SD_BER_BYTES 5
342 #define LDAP_BERVAL struct berval
343 #define MAX_SERVER_NAMES 32
345 #define HIDDEN_GROUP "HiddenGroup.g"
346 #define HIDDEN_GROUP_WITH_ADMIN "HiddenGroupWithAdmin.g"
347 #define NOT_HIDDEN_GROUP "NotHiddenGroup.g"
348 #define NOT_HIDDEN_GROUP_WITH_ADMIN "NotHiddenGroupWithAdmin.g"
350 #define ADDRESS_LIST_PREFIX "CN=MIT Directory,CN=All Address Lists,\
351 CN=Address Lists Container,CN=Massachusetts Institute of Technology,\
352 CN=Microsoft Exchange,CN=Services,CN=Configuration,"
354 #define ADD_ATTR(t, v, o) \
355 mods[n] = malloc(sizeof(LDAPMod)); \
356 mods[n]->mod_op = o; \
357 mods[n]->mod_type = t; \
358 mods[n++]->mod_values = v
360 #define DEL_ATTR(t, o) \
361 DelMods[i] = malloc(sizeof(LDAPMod)); \
362 DelMods[i]->mod_op = o; \
363 DelMods[i]->mod_type = t; \
364 DelMods[i++]->mod_values = NULL
366 #define DOMAIN_SUFFIX "MIT.EDU"
367 #define DOMAIN "DOMAIN:"
368 #define PRINCIPALNAME "PRINCIPAL:"
369 #define SERVER "SERVER:"
372 #define GROUP_SUFFIX "GROUP_SUFFIX:"
373 #define GROUP_TYPE "GROUP_TYPE:"
374 #define SET_GROUP_ACE "SET_GROUP_ACE:"
375 #define SET_PASSWORD "SET_PASSWORD:"
376 #define EXCHANGE "EXCHANGE:"
377 #define PROCESS_MACHINE_CONTAINER "PROCESS_MACHINE_CONTAINER:"
378 #define MAX_DOMAINS 10
379 char DomainNames[MAX_DOMAINS][128];
381 LK_ENTRY *member_base = NULL;
383 char PrincipalName[128];
384 static char tbl_buf[1024];
385 char kerberos_ou[] = "OU=kerberos,OU=moira";
386 char contact_ou[] = "OU=strings,OU=moira";
387 char user_ou[] = "OU=users,OU=moira";
388 char group_ou_distribution[] = "OU=mail,OU=lists,OU=moira";
389 char group_ou_root[] = "OU=lists,OU=moira";
390 char group_ou_security[] = "OU=group,OU=lists,OU=moira";
391 char group_ou_neither[] = "OU=special,OU=lists,OU=moira";
392 char group_ou_both[] = "OU=mail,OU=group,OU=lists,OU=moira";
393 char orphans_machines_ou[] = "OU=Machines,OU=Orphans";
394 char orphans_other_ou[] = "OU=Other,OU=Orphans";
395 char security_template_ou[] = "OU=security_templates";
397 char ldap_domain[256];
398 char *ServerList[MAX_SERVER_NAMES];
399 char default_server[256];
400 static char tbl_buf[1024];
401 char group_suffix[256];
402 char exchange_acl[256];
403 int mr_connections = 0;
406 int UseGroupSuffix = 1;
407 int UseGroupUniversal = 0;
411 int ProcessMachineContainer = 1;
412 int UpdateDomainList;
414 extern int set_password(char *user, char *password, char *domain);
416 int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name,
417 char *group_membership, char *MoiraId, char *attribute,
418 LK_ENTRY **linklist_base, int *linklist_count,
420 void AfsToWinAfs(char* path, char* winPath);
421 int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
422 char *Win2kPassword, char *Win2kUser, char *default_server,
423 int connect_to_kdc, char **ServerList);
424 void ad_kdc_disconnect();
425 int ad_server_connect(char *connectedServer, char *domain);
426 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
427 char *attribute_value, char *attribute, char *user_name);
428 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer);
429 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name);
430 int check_winad(void);
431 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName,
434 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
435 char *distinguishedName, int count, char **av);
436 void container_check(LDAP *ldap_handle, char *dn_path, char *name);
437 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av);
438 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av);
439 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
440 char *distinguishedName, int count,
442 void container_get_dn(char *src, char *dest);
443 void container_get_name(char *src, char *dest);
444 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName);
445 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
446 char **before, int afterc, char **after);
447 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
448 char **before, int afterc, char **after);
450 int GetAceInfo(int ac, char **av, void *ptr);
451 int get_group_membership(char *group_membership, char *group_ou,
452 int *security_flag, char **av);
453 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
454 char *machine_ou, char *pPtr);
455 int Moira_container_group_create(char **after);
456 int Moira_container_group_delete(char **before);
457 int Moira_groupname_create(char *GroupName, char *ContainerName,
458 char *ContainerRowID);
459 int Moira_container_group_update(char **before, char **after);
460 int Moira_process_machine_container_group(char *MachineName, char* groupName,
462 int Moira_addGroupToParent(char *origContainerName, char *GroupName);
463 int Moira_getContainerGroup(int ac, char **av, void *ptr);
464 int Moira_getGroupName(char *origContainerName, char *GroupName,
466 int Moira_setContainerGroup(char *ContainerName, char *GroupName);
467 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *group_name, char *Type,
468 int UpdateGroup, int *ProcessGroup, char *maillist);
469 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
470 char *group_name, char *group_ou, char *group_membership,
471 int group_security_flag, int type, char *maillist);
472 int process_lists(int ac, char **av, void *ptr);
473 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
474 char *TargetGroupName, int HiddenGroup,
475 char *AceType, char *AceName);
476 int ProcessMachineName(int ac, char **av, void *ptr);
477 int ReadConfigFile(char *DomainName);
478 int ReadDomainList();
479 void StringTrim(char *StringToTrim);
480 int save_query_info(int argc, char **argv, void *hint);
481 int user_create(int ac, char **av, void *ptr);
482 int user_change_status(LDAP *ldap_handle, char *dn_path,
483 char *user_name, char *MoiraId, int operation);
484 int user_delete(LDAP *ldap_handle, char *dn_path,
485 char *u_name, char *MoiraId);
486 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
488 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
489 char *uid, char *MitId, char *MoiraId, int State,
490 char *WinHomeDir, char *WinProfileDir, char *first,
491 char *middle, char *last);
492 void change_to_lower_case(char *ptr);
493 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
494 int contact_remove_email(LDAP *ld, char *bind_path,
495 LK_ENTRY **linklist_entry, int linklist_current);
496 int group_create(int ac, char **av, void *ptr);
497 int group_delete(LDAP *ldap_handle, char *dn_path,
498 char *group_name, char *group_membership, char *MoiraId);
499 int group_rename(LDAP *ldap_handle, char *dn_path,
500 char *before_group_name, char *before_group_membership,
501 char *before_group_ou, int before_security_flag,
502 char *before_desc, char *after_group_name,
503 char *after_group_membership, char *after_group_ou,
504 int after_security_flag, char *after_desc,
505 char *MoiraId, char *filter, char *maillist);
506 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name);
507 int machine_GetMoiraContainer(int ac, char **av, void *ptr);
508 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
509 char *machine_name, char *container_name);
510 int machine_move_to_ou(LDAP *ldap_handle, char *dn_path,
511 char *MoiraMachineName, char *DestinationOu);
512 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
513 char *group_name, char *group_ou, char *group_membership,
514 int group_security_flag, int updateGroup, char *maillist);
515 int member_list_build(int ac, char **av, void *ptr);
516 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
517 char *group_ou, char *group_membership,
518 char *user_name, char *pUserOu, char *MoiraId);
519 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
520 char *group_ou, char *group_membership, char *user_name,
521 char *pUserOu, char *MoiraId);
522 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
523 char *group_ou, char *group_membership,
524 int group_security_flag, char *MoiraId);
525 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
526 char *DistinguishedName,
527 char *WinHomeDir, char *WinProfileDir,
528 char **homedir_v, char **winProfile_v,
529 char **drives_v, LDAPMod **mods,
531 int sid_update(LDAP *ldap_handle, char *dn_path);
532 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n);
533 int check_string(char *s);
534 int check_container_name(char* s);
536 int mr_connect_cl(char *server, char *client, int version, int auth);
537 void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
538 char **before, int beforec, char **after, int afterc);
539 void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
540 char **before, int beforec, char **after, int afterc);
541 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
542 char **before, int beforec, char **after, int afterc);
543 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
544 char **before, int beforec, char **after, int afterc);
545 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
546 char **before, int beforec, char **after, int afterc);
547 void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
548 char **before, int beforec, char **after, int afterc);
549 int linklist_create_entry(char *attribute, char *value,
550 LK_ENTRY **linklist_entry);
551 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
552 char **attr_array, LK_ENTRY **linklist_base,
553 int *linklist_count, unsigned long ScopeType);
554 void linklist_free(LK_ENTRY *linklist_base);
556 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
557 char *distinguished_name, LK_ENTRY **linklist_current);
558 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
559 LK_ENTRY **linklist_base, int *linklist_count);
560 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
561 char *Attribute, char *distinguished_name,
562 LK_ENTRY **linklist_current);
564 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
565 char *oldValue, char *newValue,
566 char ***modvalues, int type);
567 void free_values(char **modvalues);
569 int convert_domain_to_dn(char *domain, char **bind_path);
570 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
571 char *distinguished_name);
572 int moira_disconnect(void);
573 int moira_connect(void);
574 void print_to_screen(const char *fmt, ...);
575 int GetMachineName(char *MachineName);
576 int tickets_get_k5();
577 int destroy_cache(void);
580 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
581 char **homeServerName);
583 int main(int argc, char **argv)
599 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
603 com_err(whoami, 0, "Unable to process %s", "argc < 4");
607 if (argc < (4 + atoi(argv[2]) + atoi(argv[3])))
609 com_err(whoami, 0, "Unable to process %s",
610 "argc < (4 + beforec + afterc)");
614 if (!strcmp(argv[1], "filesys"))
617 for (i = 1; i < argc; i++)
619 strcat(tbl_buf, argv[i]);
620 strcat(tbl_buf, " ");
623 com_err(whoami, 0, "%s", tbl_buf);
627 com_err(whoami, 0, "%s failed", "check_winad()");
631 initialize_sms_error_table();
632 initialize_krb_error_table();
634 UpdateDomainList = 0;
635 memset(DomainNames, '\0', sizeof(DomainNames[0]) * MAX_DOMAINS);
637 if (ReadDomainList())
639 com_err(whoami, 0, "%s failed", "ReadDomainList()");
643 for (i = 0; i < argc; i++)
646 for (k = 0; k < MAX_DOMAINS; k++)
648 if (strlen(DomainNames[k]) == 0)
650 for (i = 0; i < argc; i++)
652 if (orig_argv[i] != NULL)
654 orig_argv[i] = strdup(argv[i]);
657 memset(PrincipalName, '\0', sizeof(PrincipalName));
658 memset(ldap_domain, '\0', sizeof(ldap_domain));
659 memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES);
660 memset(default_server, '\0', sizeof(default_server));
661 memset(dn_path, '\0', sizeof(dn_path));
662 memset(group_suffix, '\0', sizeof(group_suffix));
663 memset(exchange_acl, '\0', sizeof(exchange_acl));
667 UseGroupUniversal = 0;
671 ProcessMachineContainer = 1;
673 sprintf(group_suffix, "%s", "_group");
674 sprintf(exchange_acl, "%s", "exchange-acl");
676 beforec = atoi(orig_argv[2]);
677 afterc = atoi(orig_argv[3]);
678 table = orig_argv[1];
679 before = &orig_argv[4];
680 after = &orig_argv[4 + beforec];
688 if (ReadConfigFile(DomainNames[k]))
691 OldUseSFU30 = UseSFU30;
693 for (i = 0; i < 5; i++)
695 ldap_handle = (LDAP *)NULL;
696 if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "",
697 default_server, 1, ServerList)))
699 com_err(whoami, 0, "connected to domain %s", DomainNames[k]);
704 if ((rc) || (ldap_handle == NULL))
706 critical_alert("incremental",
707 "winad.incr cannot connect to any server in "
708 "domain %s", DomainNames[k]);
712 for (i = 0; i < (int)strlen(table); i++)
713 table[i] = tolower(table[i]);
715 if (!strcmp(table, "users"))
716 do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
718 else if (!strcmp(table, "list"))
719 do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
721 else if (!strcmp(table, "imembers"))
722 do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
724 else if (!strcmp(table, "containers"))
725 do_container(ldap_handle, dn_path, ldap_domain, before, beforec, after,
727 else if (!strcmp(table, "mcntmap"))
728 do_mcntmap(ldap_handle, dn_path, ldap_domain, before, beforec, after,
733 for (i = 0; i < MAX_SERVER_NAMES; i++)
735 if (ServerList[i] != NULL)
738 ServerList[i] = NULL;
742 rc = ldap_unbind_s(ldap_handle);
748 void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
749 char **before, int beforec, char **after, int afterc)
751 char MoiraContainerName[128];
752 char ADContainerName[128];
753 char MachineName[1024];
754 char OriginalMachineName[1024];
757 char MoiraContainerGroup[64];
759 if (!ProcessMachineContainer)
761 com_err(whoami, 0, "Process machines and containers disabled, skipping");
766 memset(ADContainerName, '\0', sizeof(ADContainerName));
767 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
769 if ((beforec == 0) && (afterc == 0))
772 if (rc = moira_connect())
774 critical_alert("AD incremental",
775 "Error contacting Moira server : %s",
780 if ((beforec != 0) && (afterc == 0)) /*remove a machine*/
782 strcpy(OriginalMachineName, before[OU_MACHINE_NAME]);
783 strcpy(MachineName, before[OU_MACHINE_NAME]);
784 strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]);
786 com_err(whoami, 0, "removing machine %s from %s",
787 OriginalMachineName, before[OU_CONTAINER_NAME]);
789 else if ((beforec == 0) && (afterc != 0)) /*add a machine*/
791 strcpy(OriginalMachineName, after[OU_MACHINE_NAME]);
792 strcpy(MachineName, after[OU_MACHINE_NAME]);
793 strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]);
794 com_err(whoami, 0, "adding machine %s to container %s",
795 OriginalMachineName, after[OU_CONTAINER_NAME]);
803 rc = GetMachineName(MachineName);
805 if (strlen(MachineName) == 0)
808 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
809 OriginalMachineName);
813 Moira_process_machine_container_group(MachineName, MoiraContainerGroup,
816 if (machine_check(ldap_handle, dn_path, MachineName))
818 com_err(whoami, 0, "Unable to find machine %s (alias %s) in AD.",
819 OriginalMachineName, MachineName);
824 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
825 machine_get_moira_container(ldap_handle, dn_path, MachineName,
828 if (strlen(MoiraContainerName) == 0)
830 com_err(whoami, 0, "Unable to fine machine %s (alias %s) container "
831 "in Moira - moving to orphans OU.",
832 OriginalMachineName, MachineName);
833 machine_move_to_ou(ldap_handle, dn_path, MachineName,
834 orphans_machines_ou);
839 container_get_dn(MoiraContainerName, ADContainerName);
841 if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/')
842 strcat(MoiraContainerName, "/");
844 container_check(ldap_handle, dn_path, MoiraContainerName);
845 machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName);
850 void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
851 char **before, int beforec, char **after, int afterc)
855 if (!ProcessMachineContainer)
857 com_err(whoami, 0, "Process machines and containers disabled, skipping");
861 if ((beforec == 0) && (afterc == 0))
864 if (rc = moira_connect())
866 critical_alert("AD incremental", "Error contacting Moira server : %s",
871 if ((beforec != 0) && (afterc == 0)) /*delete a new container*/
873 com_err(whoami, 0, "deleting container %s", before[CONTAINER_NAME]);
874 container_delete(ldap_handle, dn_path, beforec, before);
875 Moira_container_group_delete(before);
880 if ((beforec == 0) && (afterc != 0)) /*create a container*/
882 com_err(whoami, 0, "creating container %s", after[CONTAINER_NAME]);
883 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
884 container_create(ldap_handle, dn_path, afterc, after);
885 Moira_container_group_create(after);
890 if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME]))
892 com_err(whoami, 0, "renaming container %s to %s",
893 before[CONTAINER_NAME], after[CONTAINER_NAME]);
894 container_rename(ldap_handle, dn_path, beforec, before, afterc, after);
895 Moira_container_group_update(before, after);
900 com_err(whoami, 0, "updating container %s information",
901 after[CONTAINER_NAME]);
902 container_update(ldap_handle, dn_path, beforec, before, afterc, after);
903 Moira_container_group_update(before, after);
908 #define L_LIST_DESC 9
911 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
912 char **before, int beforec, char **after, int afterc)
917 char group_membership[6];
922 char before_list_id[32];
923 char before_group_membership[1];
924 int before_security_flag;
925 char before_group_ou[256];
926 LK_ENTRY *ptr = NULL;
928 if (beforec == 0 && afterc == 0)
931 memset(list_id, '\0', sizeof(list_id));
932 memset(before_list_id, '\0', sizeof(before_list_id));
933 memset(before_group_ou, '\0', sizeof(before_group_ou));
934 memset(before_group_membership, '\0', sizeof(before_group_membership));
935 memset(group_ou, '\0', sizeof(group_ou));
936 memset(group_membership, '\0', sizeof(group_membership));
941 if (beforec < L_LIST_ID)
943 if (beforec > L_LIST_DESC)
945 strcpy(before_list_id, before[L_LIST_ID]);
947 before_security_flag = 0;
948 get_group_membership(before_group_membership, before_group_ou,
949 &before_security_flag, before);
954 if (afterc < L_LIST_ID)
956 if (afterc > L_LIST_DESC)
958 strcpy(list_id, after[L_LIST_ID]);
961 get_group_membership(group_membership, group_ou, &security_flag, after);
964 if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/
973 if ((rc = process_group(ldap_handle, dn_path, before_list_id,
974 before[L_NAME], before_group_ou,
975 before_group_membership,
976 before_security_flag, CHECK_GROUPS,
977 before[L_MAILLIST])))
979 if (rc == AD_NO_GROUPS_FOUND)
983 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
984 (rc == AD_MULTIPLE_GROUPS_FOUND))
986 rc = process_group(ldap_handle, dn_path, before_list_id,
987 before[L_NAME], before_group_ou,
988 before_group_membership,
989 before_security_flag, CLEANUP_GROUPS,
992 if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0))
994 com_err(whoami, 0, "Unable to process list %s",
998 if (rc == AD_NO_GROUPS_FOUND)
1004 if ((beforec != 0) && (afterc != 0))
1006 if (((strcmp(after[L_NAME], before[L_NAME])) ||
1007 ((!strcmp(after[L_NAME], before[L_NAME])) &&
1008 (strcmp(before_group_ou, group_ou)))) &&
1011 com_err(whoami, 0, "Changing list name from %s to %s",
1012 before[L_NAME], after[L_NAME]);
1014 if ((strlen(before_group_ou) == 0) ||
1015 (strlen(before_group_membership) == 0) ||
1016 (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
1018 com_err(whoami, 0, "%s", "Unable to find the group OU's");
1022 memset(filter, '\0', sizeof(filter));
1024 if ((rc = group_rename(ldap_handle, dn_path,
1025 before[L_NAME], before_group_membership,
1026 before_group_ou, before_security_flag,
1027 before[L_LIST_DESC], after[L_NAME],
1028 group_membership, group_ou, security_flag,
1030 list_id, filter, after[L_MAILLIST])))
1032 if (rc != AD_NO_GROUPS_FOUND)
1035 "Unable to change list name from %s to %s",
1036 before[L_NAME], after[L_NAME]);
1049 if ((strlen(before_group_ou) == 0) ||
1050 (strlen(before_group_membership) == 0))
1053 "Unable to find the group OU for group %s", before[L_NAME]);
1057 com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
1058 rc = group_delete(ldap_handle, dn_path, before[L_NAME],
1059 before_group_membership, before_list_id);
1067 com_err(whoami, 0, "Creating group %s", after[L_NAME]);
1069 if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME],
1070 group_ou, group_membership,
1071 security_flag, CHECK_GROUPS,
1074 if (rc != AD_NO_GROUPS_FOUND)
1076 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
1077 (rc == AD_MULTIPLE_GROUPS_FOUND))
1079 rc = process_group(ldap_handle, dn_path, list_id,
1081 group_ou, group_membership,
1082 security_flag, CLEANUP_GROUPS,
1089 "Unable to create list %s", after[L_NAME]);
1096 com_err(whoami, 0, "Updating group %s information", after[L_NAME]);
1098 if (rc = moira_connect())
1100 critical_alert("AD incremental",
1101 "Error contacting Moira server : %s",
1108 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0,
1109 &ProcessGroup, after[L_MAILLIST]))
1114 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1,
1115 &ProcessGroup, after[L_MAILLIST]))
1119 if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME],
1120 group_ou, group_membership, security_flag,
1121 updateGroup, after[L_MAILLIST]))
1127 if (atoi(after[L_ACTIVE]))
1129 populate_group(ldap_handle, dn_path, after[L_NAME], group_ou,
1130 group_membership, security_flag, list_id);
1138 #define LM_EXTRA_ACTIVE (LM_END)
1139 #define LM_EXTRA_PUBLIC (LM_END+1)
1140 #define LM_EXTRA_HIDDEN (LM_END+2)
1141 #define LM_EXTRA_MAILLIST (LM_END+3)
1142 #define LM_EXTRA_GROUP (LM_END+4)
1143 #define LM_EXTRA_GID (LM_END+5)
1144 #define LMN_LIST_ID (LM_END+6)
1145 #define LM_LIST_ID (LM_END+7)
1146 #define LM_USER_ID (LM_END+8)
1147 #define LM_EXTRA_END (LM_END+9)
1149 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1150 char **before, int beforec, char **after, int afterc)
1152 LK_ENTRY *group_base;
1155 char *attr_array[3];
1156 char group_name[128];
1157 char user_name[128];
1158 char user_type[128];
1159 char moira_list_id[32];
1160 char moira_user_id[32];
1161 char group_membership[1];
1163 char machine_ou[256];
1171 char NewMachineName[1024];
1175 char *save_argv[U_END];
1179 memset(moira_list_id, '\0', sizeof(moira_list_id));
1180 memset(moira_user_id, '\0', sizeof(moira_user_id));
1184 if (afterc < LM_EXTRA_GID)
1187 if (!atoi(after[LM_EXTRA_ACTIVE]))
1190 "Unable to add %s to group %s : group not active",
1191 after[2], after[0]);
1197 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1200 strcpy(user_name, after[LM_MEMBER]);
1201 strcpy(group_name, after[LM_LIST]);
1202 strcpy(user_type, after[LM_TYPE]);
1204 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1206 if (afterc > LM_EXTRA_GROUP)
1208 strcpy(moira_list_id, after[LMN_LIST_ID]);
1209 strcpy(moira_user_id, after[LM_LIST_ID]);
1212 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1214 if (afterc > LMN_LIST_ID)
1216 strcpy(moira_list_id, after[LM_LIST_ID]);
1217 strcpy(moira_user_id, after[LM_USER_ID]);
1222 if (afterc > LM_EXTRA_GID)
1223 strcpy(moira_list_id, after[LMN_LIST_ID]);
1228 if (beforec < LM_EXTRA_GID)
1230 if (!atoi(before[LM_EXTRA_ACTIVE]))
1233 "Unable to add %s to group %s : group not active",
1234 before[2], before[0]);
1240 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1243 strcpy(user_name, before[LM_MEMBER]);
1244 strcpy(group_name, before[LM_LIST]);
1245 strcpy(user_type, before[LM_TYPE]);
1247 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1249 if (beforec > LM_EXTRA_GROUP)
1251 strcpy(moira_list_id, before[LMN_LIST_ID]);
1252 strcpy(moira_user_id, before[LM_LIST_ID]);
1255 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1257 if (beforec > LMN_LIST_ID)
1259 strcpy(moira_list_id, before[LM_LIST_ID]);
1260 strcpy(moira_user_id, before[LM_USER_ID]);
1265 if (beforec > LM_EXTRA_GID)
1266 strcpy(moira_list_id, before[LMN_LIST_ID]);
1273 "Unable to process group : beforec = %d, afterc = %d",
1278 args[L_NAME] = ptr[LM_LIST];
1279 args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
1280 args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
1281 args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
1282 args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
1283 args[L_GROUP] = ptr[LM_EXTRA_GROUP];
1284 args[L_GID] = ptr[LM_EXTRA_GID];
1287 memset(group_ou, '\0', sizeof(group_ou));
1288 get_group_membership(group_membership, group_ou, &security_flag, args);
1290 if (strlen(group_ou) == 0)
1292 com_err(whoami, 0, "Unable to find the group OU for group %s",
1297 if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name,
1298 group_ou, group_membership, security_flag,
1299 CHECK_GROUPS, args[L_MAILLIST]))
1301 if (rc != AD_NO_GROUPS_FOUND)
1303 if (rc = process_group(ldap_handle, dn_path, moira_list_id,
1304 group_name, group_ou, group_membership,
1305 security_flag, CLEANUP_GROUPS,
1308 if (rc != AD_NO_GROUPS_FOUND)
1311 com_err(whoami, 0, "Unable to add %s to group %s - "
1312 "unable to process group", user_name, group_name);
1314 com_err(whoami, 0, "Unable to remove %s from group %s - "
1315 "unable to process group", user_name, group_name);
1322 if (rc == AD_NO_GROUPS_FOUND)
1324 if (rc = moira_connect())
1326 critical_alert("AD incremental",
1327 "Error contacting Moira server : %s",
1332 com_err(whoami, 0, "creating group %s", group_name);
1335 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0,
1336 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
1341 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1,
1342 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
1346 if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST],
1347 group_ou, group_membership, security_flag, 0,
1348 ptr[LM_EXTRA_MAILLIST]))
1354 if (atoi(ptr[LM_EXTRA_ACTIVE]))
1356 populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou,
1357 group_membership, security_flag, moira_list_id);
1367 com_err(whoami, 0, "removing user %s from list %s", user_name,
1371 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1373 memset(machine_ou, '\0', sizeof(machine_ou));
1374 memset(NewMachineName, '\0', sizeof(NewMachineName));
1375 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER],
1376 machine_ou, NewMachineName))
1378 if (ptr[LM_MEMBER] != NULL)
1379 free(ptr[LM_MEMBER]);
1380 ptr[LM_MEMBER] = strdup(NewMachineName);
1381 pUserOu = machine_ou;
1384 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1386 strcpy(member, ptr[LM_MEMBER]);
1390 if((s = strchr(member, '@')) == (char *) NULL)
1392 strcat(member, "@mit.edu");
1394 if (ptr[LM_MEMBER] != NULL)
1395 free(ptr[LM_MEMBER]);
1396 ptr[LM_MEMBER] = strdup(member);
1399 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1401 s = strrchr(member, '.');
1403 strcat(s, ".mit.edu");
1405 if (ptr[LM_MEMBER] != NULL)
1406 free(ptr[LM_MEMBER]);
1407 ptr[LM_MEMBER] = strdup(member);
1411 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1414 pUserOu = contact_ou;
1416 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1418 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1422 pUserOu = kerberos_ou;
1424 if (rc = member_remove(ldap_handle, dn_path, group_name,
1425 group_ou, group_membership, ptr[LM_MEMBER],
1426 pUserOu, moira_list_id))
1427 com_err(whoami, 0, "Unable to remove %s from group %s", user_name,
1430 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1432 if (rc = moira_connect())
1434 critical_alert("AD incremental",
1435 "Error contacting Moira server : %s",
1440 if (rc = populate_group(ldap_handle, dn_path, group_name,
1441 group_ou, group_membership, security_flag,
1443 com_err(whoami, 0, "Unable to remove %s from group %s",
1444 user_name, group_name);
1450 com_err(whoami, 0, "Adding %s to list %s", user_name, group_name);
1453 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1455 memset(machine_ou, '\0', sizeof(machine_ou));
1456 memset(NewMachineName, '\0', sizeof(NewMachineName));
1458 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou,
1462 if (ptr[LM_MEMBER] != NULL)
1463 free(ptr[LM_MEMBER]);
1465 ptr[LM_MEMBER] = strdup(NewMachineName);
1466 pUserOu = machine_ou;
1468 else if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1470 strcpy(member, ptr[LM_MEMBER]);
1474 if((s = strchr(member, '@')) == (char *) NULL)
1476 strcat(member, "@mit.edu");
1478 if (ptr[LM_MEMBER] != NULL)
1479 free(ptr[LM_MEMBER]);
1480 ptr[LM_MEMBER] = strdup(member);
1483 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1485 s = strrchr(member, '.');
1487 strcat(s, ".mit.edu");
1489 if (ptr[LM_MEMBER] != NULL)
1490 free(ptr[LM_MEMBER]);
1491 ptr[LM_MEMBER] = strdup(member);
1495 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1498 pUserOu = contact_ou;
1500 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1502 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
1505 pUserOu = kerberos_ou;
1507 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1509 if ((rc = check_user(ldap_handle, dn_path, ptr[LM_MEMBER],
1510 moira_user_id)) == AD_NO_USER_FOUND)
1512 if (rc = moira_connect())
1514 critical_alert("AD incremental",
1515 "Error connection to Moira : %s",
1520 com_err(whoami, 0, "creating user %s", ptr[LM_MEMBER]);
1521 av[0] = ptr[LM_MEMBER];
1522 call_args[0] = (char *)ldap_handle;
1523 call_args[1] = dn_path;
1524 call_args[2] = moira_user_id;
1525 call_args[3] = NULL;
1534 sprintf(filter, "(&(objectClass=group)(cn=%s))", ptr[LM_MEMBER]);
1535 attr_array[0] = "cn";
1536 attr_array[1] = NULL;
1537 if ((rc = linklist_build(ldap_handle, dn_path, filter,
1538 attr_array, &group_base, &group_count,
1539 LDAP_SCOPE_SUBTREE)) != 0)
1541 com_err(whoami, 0, "Unable to process user %s : %s",
1542 ptr[LM_MEMBER], ldap_err2string(rc));
1548 com_err(whoami, 0, "Object already exists with name %s",
1553 linklist_free(group_base);
1558 if (rc = mr_query("get_user_account_by_login", 1, av,
1559 save_query_info, save_argv))
1562 com_err(whoami, 0, "Unable to create user %s : %s",
1563 ptr[LM_MEMBER], error_message(rc));
1567 if (rc = user_create(U_END, save_argv, call_args))
1570 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1577 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1589 if (rc = member_add(ldap_handle, dn_path, group_name,
1590 group_ou, group_membership, ptr[LM_MEMBER],
1591 pUserOu, moira_list_id))
1592 com_err(whoami, 0, "Unable to add %s to group %s", user_name, group_name);
1594 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1596 if (rc = moira_connect())
1598 critical_alert("AD incremental",
1599 "Error contacting Moira server : %s",
1604 if (rc = populate_group(ldap_handle, dn_path, group_name,
1605 group_ou, group_membership, security_flag,
1607 com_err(whoami, 0, "Unable to add %s to group %s",
1608 user_name, group_name);
1617 #define U_USER_ID 10
1618 #define U_HOMEDIR 11
1619 #define U_PROFILEDIR 12
1621 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1622 char **before, int beforec, char **after,
1625 LK_ENTRY *group_base;
1628 char *attr_array[3];
1631 char after_user_id[32];
1632 char before_user_id[32];
1634 char *save_argv[U_END];
1636 if ((beforec == 0) && (afterc == 0))
1639 memset(after_user_id, '\0', sizeof(after_user_id));
1640 memset(before_user_id, '\0', sizeof(before_user_id));
1642 if (beforec > U_USER_ID)
1643 strcpy(before_user_id, before[U_USER_ID]);
1645 if (afterc > U_USER_ID)
1646 strcpy(after_user_id, after[U_USER_ID]);
1648 if ((beforec == 0) && (afterc == 0)) /*this case should never happen */
1651 if ((beforec == 0) && (afterc != 0))
1653 /*this case only happens when the account*/
1654 /*account is first created but not usable*/
1656 com_err(whoami, 0, "Unable to process user %s because the user account "
1657 "is not yet usable", after[U_NAME]);
1661 /*this case only happens when the account is expunged */
1663 if ((beforec != 0) && (afterc == 0))
1665 if (atoi(before[U_STATE]) == 0)
1667 com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]);
1668 user_delete(ldap_handle, dn_path, before[U_NAME], before_user_id);
1672 com_err(whoami, 0, "Unable to process because user %s has been "
1673 "previously expungeded", before[U_NAME]);
1678 /*process anything that gets here*/
1680 if ((rc = check_user(ldap_handle, dn_path, before[U_NAME],
1681 before_user_id)) == AD_NO_USER_FOUND)
1683 if (!check_string(after[U_NAME]))
1686 if (rc = moira_connect())
1688 critical_alert("AD incremental",
1689 "Error connection to Moira : %s",
1694 com_err(whoami, 0, "creating user %s", after[U_NAME]);
1696 av[0] = after[U_NAME];
1697 call_args[0] = (char *)ldap_handle;
1698 call_args[1] = dn_path;
1699 call_args[2] = after_user_id;
1700 call_args[3] = NULL;
1708 sprintf(filter, "(&(objectClass=group)(cn=%s))", after[U_NAME]);
1709 attr_array[0] = "cn";
1710 attr_array[1] = NULL;
1712 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
1713 &group_base, &group_count,
1714 LDAP_SCOPE_SUBTREE)) != 0)
1716 com_err(whoami, 0, "Unable to process user %s : %s",
1717 after[U_NAME], ldap_err2string(rc));
1721 if (group_count >= 1)
1723 com_err(whoami, 0, "Object already exists with name %s",
1728 linklist_free(group_base);
1733 if (rc = mr_query("get_user_account_by_login", 1, av,
1734 save_query_info, save_argv))
1737 com_err(whoami, 0, "Unable to create user %s : %s",
1738 after[U_NAME], error_message(rc));
1742 if (rc = user_create(U_END, save_argv, call_args))
1744 com_err(whoami, 0, "Unable to create user %s : %s",
1745 after[U_NAME], error_message(rc));
1752 com_err(whoami, 0, "Unable to create user %s", after[U_NAME]);
1764 if (strcmp(before[U_NAME], after[U_NAME]))
1766 if ((check_string(before[U_NAME])) && (check_string(after[U_NAME])))
1768 com_err(whoami, 0, "changing user %s to %s",
1769 before[U_NAME], after[U_NAME]);
1771 if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME],
1772 after[U_NAME])) != LDAP_SUCCESS)
1779 com_err(whoami, 0, "updating user %s information", after[U_NAME]);
1780 rc = user_update(ldap_handle, dn_path, after[U_NAME],
1781 after[U_UID], after[U_MITID],
1782 after_user_id, atoi(after[U_STATE]),
1783 after[U_HOMEDIR], after[U_PROFILEDIR],
1784 after[U_FIRST], after[U_MIDDLE], after[U_LAST]);
1789 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
1790 char *oldValue, char *newValue,
1791 char ***modvalues, int type)
1793 LK_ENTRY *linklist_ptr;
1797 if (((*modvalues) = calloc(1,
1798 (modvalue_count + 1) * sizeof(char *))) == NULL)
1803 for (i = 0; i < (modvalue_count + 1); i++)
1804 (*modvalues)[i] = NULL;
1806 if (modvalue_count != 0)
1808 linklist_ptr = linklist_base;
1809 for (i = 0; i < modvalue_count; i++)
1811 if ((oldValue != NULL) && (newValue != NULL))
1813 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1816 if (type == REPLACE)
1818 if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1821 memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1822 strcpy((*modvalues)[i], newValue);
1826 if (((*modvalues)[i] = calloc(1,
1827 (int)(cPtr - linklist_ptr->value) +
1828 (linklist_ptr->length -
1830 strlen(newValue) + 1)) == NULL)
1832 memset((*modvalues)[i], '\0',
1833 (int)(cPtr - linklist_ptr->value) +
1834 (linklist_ptr->length - strlen(oldValue)) +
1835 strlen(newValue) + 1);
1836 memcpy((*modvalues)[i], linklist_ptr->value,
1837 (int)(cPtr - linklist_ptr->value));
1838 strcat((*modvalues)[i], newValue);
1839 strcat((*modvalues)[i],
1840 &linklist_ptr->value[(int)(cPtr -
1841 linklist_ptr->value) + strlen(oldValue)]);
1846 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1847 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1848 memcpy((*modvalues)[i], linklist_ptr->value,
1849 linklist_ptr->length);
1854 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1855 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1856 memcpy((*modvalues)[i], linklist_ptr->value,
1857 linklist_ptr->length);
1859 linklist_ptr = linklist_ptr->next;
1861 (*modvalues)[i] = NULL;
1867 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
1868 char **attr_array, LK_ENTRY **linklist_base,
1869 int *linklist_count, unsigned long ScopeType)
1872 LDAPMessage *ldap_entry;
1876 (*linklist_base) = NULL;
1877 (*linklist_count) = 0;
1879 if ((rc = ldap_search_s(ldap_handle, dn_path, ScopeType,
1880 search_exp, attr_array, 0,
1881 &ldap_entry)) != LDAP_SUCCESS)
1883 if (rc != LDAP_SIZELIMIT_EXCEEDED)
1887 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base,
1890 ldap_msgfree(ldap_entry);
1894 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1895 LK_ENTRY **linklist_base, int *linklist_count)
1897 char distinguished_name[1024];
1898 LK_ENTRY *linklist_ptr;
1901 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1904 memset(distinguished_name, '\0', sizeof(distinguished_name));
1905 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1907 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1908 linklist_base)) != 0)
1911 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1913 memset(distinguished_name, '\0', sizeof(distinguished_name));
1914 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1916 if ((rc = retrieve_attributes(ldap_handle, ldap_entry,
1917 distinguished_name, linklist_base)) != 0)
1921 linklist_ptr = (*linklist_base);
1922 (*linklist_count) = 0;
1924 while (linklist_ptr != NULL)
1926 ++(*linklist_count);
1927 linklist_ptr = linklist_ptr->next;
1933 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1934 char *distinguished_name, LK_ENTRY **linklist_current)
1941 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry,
1944 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1946 ldap_memfree(Attribute);
1947 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
1950 retrieve_values(ldap_handle, ldap_entry, Attribute,
1951 distinguished_name, linklist_current);
1952 ldap_memfree(Attribute);
1956 ldap_ber_free(ptr, 0);
1961 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1962 char *Attribute, char *distinguished_name,
1963 LK_ENTRY **linklist_current)
1969 LK_ENTRY *linklist_previous;
1970 LDAP_BERVAL **ber_value;
1979 SID_IDENTIFIER_AUTHORITY *sid_auth;
1980 unsigned char *subauth_count;
1981 #endif /*LDAP_BEGUG*/
1984 memset(temp, '\0', sizeof(temp));
1986 if ((!strcmp(Attribute, "objectSid")) ||
1987 (!strcmp(Attribute, "objectGUID")))
1992 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1993 Ptr = (void **)ber_value;
1998 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1999 Ptr = (void **)str_value;
2007 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
2010 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
2011 linklist_previous->next = (*linklist_current);
2012 (*linklist_current) = linklist_previous;
2014 if (((*linklist_current)->attribute = calloc(1,
2015 strlen(Attribute) + 1)) == NULL)
2018 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
2019 strcpy((*linklist_current)->attribute, Attribute);
2023 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
2025 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
2028 memset((*linklist_current)->value, '\0', ber_length);
2029 memcpy((*linklist_current)->value,
2030 (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length);
2031 (*linklist_current)->length = ber_length;
2035 if (((*linklist_current)->value = calloc(1,
2036 strlen(*Ptr) + 1)) == NULL)
2039 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
2040 (*linklist_current)->length = strlen(*Ptr);
2041 strcpy((*linklist_current)->value, *Ptr);
2044 (*linklist_current)->ber_value = use_bervalue;
2046 if (((*linklist_current)->dn = calloc(1,
2047 strlen(distinguished_name) + 1)) == NULL)
2050 memset((*linklist_current)->dn, '\0',
2051 strlen(distinguished_name) + 1);
2052 strcpy((*linklist_current)->dn, distinguished_name);
2055 if (!strcmp(Attribute, "objectGUID"))
2057 guid = (GUID *)((*linklist_current)->value);
2059 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2060 guid->Data1, guid->Data2, guid->Data3,
2061 guid->Data4[0], guid->Data4[1], guid->Data4[2],
2062 guid->Data4[3], guid->Data4[4], guid->Data4[5],
2063 guid->Data4[6], guid->Data4[7]);
2064 print_to_screen(" %20s : {%s}\n", Attribute, temp);
2066 else if (!strcmp(Attribute, "objectSid"))
2068 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
2071 print_to_screen(" Revision = %d\n", sid->Revision);
2072 print_to_screen(" SID Identifier Authority:\n");
2073 sid_auth = &sid->IdentifierAuthority;
2074 if (sid_auth->Value[0])
2075 print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
2076 else if (sid_auth->Value[1])
2077 print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
2078 else if (sid_auth->Value[2])
2079 print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
2080 else if (sid_auth->Value[3])
2081 print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
2082 else if (sid_auth->Value[5])
2083 print_to_screen(" SECURITY_NT_AUTHORITY\n");
2085 print_to_screen(" UNKNOWN SID AUTHORITY\n");
2086 subauth_count = GetSidSubAuthorityCount(sid);
2087 print_to_screen(" SidSubAuthorityCount = %d\n",
2089 print_to_screen(" SidSubAuthority:\n");
2090 for (i = 0; i < *subauth_count; i++)
2092 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
2093 print_to_screen(" %u\n", *subauth);
2097 else if ((!memcmp(Attribute, "userAccountControl",
2098 strlen("userAccountControl"))) ||
2099 (!memcmp(Attribute, "sAMAccountType",
2100 strlen("sAmAccountType"))))
2102 intValue = atoi(*Ptr);
2103 print_to_screen(" %20s : %ld\n",Attribute, intValue);
2105 if (!memcmp(Attribute, "userAccountControl",
2106 strlen("userAccountControl")))
2108 if (intValue & UF_ACCOUNTDISABLE)
2109 print_to_screen(" %20s : %s\n",
2110 "", "Account disabled");
2112 print_to_screen(" %20s : %s\n",
2113 "", "Account active");
2114 if (intValue & UF_HOMEDIR_REQUIRED)
2115 print_to_screen(" %20s : %s\n",
2116 "", "Home directory required");
2117 if (intValue & UF_LOCKOUT)
2118 print_to_screen(" %20s : %s\n",
2119 "", "Account locked out");
2120 if (intValue & UF_PASSWD_NOTREQD)
2121 print_to_screen(" %20s : %s\n",
2122 "", "No password required");
2123 if (intValue & UF_PASSWD_CANT_CHANGE)
2124 print_to_screen(" %20s : %s\n",
2125 "", "Cannot change password");
2126 if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
2127 print_to_screen(" %20s : %s\n",
2128 "", "Temp duplicate account");
2129 if (intValue & UF_NORMAL_ACCOUNT)
2130 print_to_screen(" %20s : %s\n",
2131 "", "Normal account");
2132 if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
2133 print_to_screen(" %20s : %s\n",
2134 "", "Interdomain trust account");
2135 if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
2136 print_to_screen(" %20s : %s\n",
2137 "", "Workstation trust account");
2138 if (intValue & UF_SERVER_TRUST_ACCOUNT)
2139 print_to_screen(" %20s : %s\n",
2140 "", "Server trust account");
2145 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
2147 #endif /*LDAP_DEBUG*/
2150 if (str_value != NULL)
2151 ldap_value_free(str_value);
2153 if (ber_value != NULL)
2154 ldap_value_free_len(ber_value);
2157 (*linklist_current) = linklist_previous;
2162 int moira_connect(void)
2167 if (!mr_connections++)
2171 memset(HostName, '\0', sizeof(HostName));
2172 strcpy(HostName, "ttsp");
2173 rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
2177 rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
2186 int check_winad(void)
2190 for (i = 0; file_exists(STOP_FILE); i++)
2194 critical_alert("AD incremental",
2195 "WINAD incremental failed (%s exists): %s",
2196 STOP_FILE, tbl_buf);
2206 int moira_disconnect(void)
2209 if (!--mr_connections)
2217 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
2218 char *distinguished_name)
2222 CName = ldap_get_dn(ldap_handle, ldap_entry);
2227 strcpy(distinguished_name, CName);
2228 ldap_memfree(CName);
2231 int linklist_create_entry(char *attribute, char *value,
2232 LK_ENTRY **linklist_entry)
2234 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
2236 if (!(*linklist_entry))
2241 memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
2242 (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
2243 memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
2244 strcpy((*linklist_entry)->attribute, attribute);
2245 (*linklist_entry)->value = calloc(1, strlen(value) + 1);
2246 memset((*linklist_entry)->value, '\0', strlen(value) + 1);
2247 strcpy((*linklist_entry)->value, value);
2248 (*linklist_entry)->length = strlen(value);
2249 (*linklist_entry)->next = NULL;
2254 void print_to_screen(const char *fmt, ...)
2258 va_start(pvar, fmt);
2259 vfprintf(stderr, fmt, pvar);
2264 int get_group_membership(char *group_membership, char *group_ou,
2265 int *security_flag, char **av)
2270 maillist_flag = atoi(av[L_MAILLIST]);
2271 group_flag = atoi(av[L_GROUP]);
2273 if (security_flag != NULL)
2274 (*security_flag) = 0;
2276 if ((maillist_flag) && (group_flag))
2278 if (group_membership != NULL)
2279 group_membership[0] = 'B';
2281 if (security_flag != NULL)
2282 (*security_flag) = 1;
2284 if (group_ou != NULL)
2285 strcpy(group_ou, group_ou_both);
2287 else if ((!maillist_flag) && (group_flag))
2289 if (group_membership != NULL)
2290 group_membership[0] = 'S';
2292 if (security_flag != NULL)
2293 (*security_flag) = 1;
2295 if (group_ou != NULL)
2296 strcpy(group_ou, group_ou_security);
2298 else if ((maillist_flag) && (!group_flag))
2300 if (group_membership != NULL)
2301 group_membership[0] = 'D';
2303 if (group_ou != NULL)
2304 strcpy(group_ou, group_ou_distribution);
2308 if (group_membership != NULL)
2309 group_membership[0] = 'N';
2311 if (group_ou != NULL)
2312 strcpy(group_ou, group_ou_neither);
2318 int group_rename(LDAP *ldap_handle, char *dn_path,
2319 char *before_group_name, char *before_group_membership,
2320 char *before_group_ou, int before_security_flag,
2321 char *before_desc, char *after_group_name,
2322 char *after_group_membership, char *after_group_ou,
2323 int after_security_flag, char *after_desc,
2324 char *MoiraId, char *filter, char *maillist)
2329 char new_dn_path[512];
2332 char mail_nickname[256];
2333 char proxy_address[256];
2334 char address_book[256];
2335 char *attr_array[3];
2336 char *mitMoiraId_v[] = {NULL, NULL};
2337 char *name_v[] = {NULL, NULL};
2338 char *samAccountName_v[] = {NULL, NULL};
2339 char *groupTypeControl_v[] = {NULL, NULL};
2340 char *mail_v[] = {NULL, NULL};
2341 char *proxy_address_v[] = {NULL, NULL};
2342 char *mail_nickname_v[] = {NULL, NULL};
2343 char *report_to_originator_v[] = {NULL, NULL};
2344 char *address_book_v[] = {NULL, NULL};
2345 char *legacy_exchange_dn_v[] = {NULL, NULL};
2346 u_int groupTypeControl;
2347 char groupTypeControlStr[80];
2348 char contact_mail[256];
2352 LK_ENTRY *group_base;
2354 int MailDisabled = 0;
2356 if(UseGroupUniversal)
2357 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2359 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2361 if (!check_string(before_group_name))
2364 "Unable to process invalid LDAP list name %s",
2366 return(AD_INVALID_NAME);
2369 if (!check_string(after_group_name))
2372 "Unable to process invalid LDAP list name %s", after_group_name);
2373 return(AD_INVALID_NAME);
2383 sprintf(filter, "(&(objectClass=user)(cn=%s))", after_group_name);
2384 attr_array[0] = "cn";
2385 attr_array[1] = NULL;
2387 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2388 &group_base, &group_count,
2389 LDAP_SCOPE_SUBTREE)) != 0)
2391 com_err(whoami, 0, "Unable to process group %s : %s",
2392 after_group_name, ldap_err2string(rc));
2398 com_err(whoami, 0, "Object already exists with name %s",
2403 linklist_free(group_base);
2412 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
2413 before_group_membership,
2414 MoiraId, "distinguishedName", &group_base,
2415 &group_count, filter))
2418 if (group_count == 0)
2420 return(AD_NO_GROUPS_FOUND);
2423 if (group_count != 1)
2425 com_err(whoami, 0, "Unable to process multiple groups with "
2426 "MoiraId = %s exist in the AD", MoiraId);
2427 return(AD_MULTIPLE_GROUPS_FOUND);
2430 strcpy(old_dn, group_base->value);
2432 linklist_free(group_base);
2435 attr_array[0] = "sAMAccountName";
2436 attr_array[1] = NULL;
2438 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2439 &group_base, &group_count,
2440 LDAP_SCOPE_SUBTREE)) != 0)
2442 com_err(whoami, 0, "Unable to get list %s dn : %s",
2443 after_group_name, ldap_err2string(rc));
2447 if (group_count != 1)
2450 "Unable to get sAMAccountName for group %s",
2452 return(AD_LDAP_FAILURE);
2455 strcpy(sam_name, group_base->value);
2456 linklist_free(group_base);
2460 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2461 sprintf(new_dn, "cn=%s", after_group_name);
2462 sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain));
2463 sprintf(contact_mail, "%s@mit.edu", after_group_name);
2464 sprintf(proxy_address, "SMTP:%s@%s", after_group_name,
2465 lowercase(ldap_domain));
2466 sprintf(mail_nickname, "%s", after_group_name);
2468 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
2469 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2471 com_err(whoami, 0, "Unable to rename list from %s to %s : %s",
2472 before_group_name, after_group_name, ldap_err2string(rc));
2476 name_v[0] = after_group_name;
2478 if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)],
2479 group_suffix, strlen(group_suffix)))
2481 sprintf(sam_name, "%s%s", after_group_name, group_suffix);
2486 "Unable to rename list from %s to %s : sAMAccountName not found",
2487 before_group_name, after_group_name);
2491 samAccountName_v[0] = sam_name;
2493 if (after_security_flag)
2494 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2496 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2497 groupTypeControl_v[0] = groupTypeControlStr;
2498 mitMoiraId_v[0] = MoiraId;
2500 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
2501 rc = attribute_update(ldap_handle, new_dn, after_desc, "description",
2504 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2505 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2506 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2507 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
2511 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2513 mail_nickname_v[0] = mail_nickname;
2514 proxy_address_v[0] = proxy_address;
2516 report_to_originator_v[0] = "TRUE";
2518 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2519 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2520 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2521 ADD_ATTR("reportToOriginator", report_to_originator_v,
2526 mail_nickname_v[0] = NULL;
2527 proxy_address_v[0] = NULL;
2529 legacy_exchange_dn_v[0] = NULL;
2530 address_book_v[0] = NULL;
2531 report_to_originator_v[0] = NULL;
2533 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2534 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2535 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2536 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2537 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2538 ADD_ATTR("reportToOriginator", report_to_originator_v,
2544 if(atoi(maillist) && email_isvalid(contact_mail))
2546 mail_v[0] = contact_mail;
2547 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2553 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2556 "Unable to modify list data for %s after renaming: %s",
2557 after_group_name, ldap_err2string(rc));
2560 for (i = 0; i < n; i++)
2566 int group_create(int ac, char **av, void *ptr)
2571 char new_group_name[256];
2572 char sam_group_name[256];
2573 char cn_group_name[256];
2575 char contact_mail[256];
2576 char mail_nickname[256];
2577 char proxy_address[256];
2578 char address_book[256];
2579 char *cn_v[] = {NULL, NULL};
2580 char *objectClass_v[] = {"top", "group", NULL};
2582 char *samAccountName_v[] = {NULL, NULL};
2583 char *altSecurityIdentities_v[] = {NULL, NULL};
2584 char *member_v[] = {NULL, NULL};
2585 char *name_v[] = {NULL, NULL};
2586 char *desc_v[] = {NULL, NULL};
2587 char *info_v[] = {NULL, NULL};
2588 char *mitMoiraId_v[] = {NULL, NULL};
2589 char *groupTypeControl_v[] = {NULL, NULL};
2590 char *mail_v[] = {NULL, NULL};
2591 char *proxy_address_v[] = {NULL, NULL};
2592 char *mail_nickname_v[] = {NULL, NULL};
2593 char *report_to_originator_v[] = {NULL, NULL};
2594 char *address_book_v[] = {NULL, NULL};
2595 char *legacy_exchange_dn_v[] = {NULL, NULL};
2596 char groupTypeControlStr[80];
2597 char group_membership[1];
2600 u_int groupTypeControl;
2604 int MailDisabled = 0;
2606 LK_ENTRY *group_base;
2609 char *attr_array[3];
2613 if(UseGroupUniversal)
2614 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2616 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2618 if (!check_string(av[L_NAME]))
2620 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2622 return(AD_INVALID_NAME);
2625 updateGroup = (int)call_args[4];
2626 memset(group_ou, 0, sizeof(group_ou));
2627 memset(group_membership, 0, sizeof(group_membership));
2630 get_group_membership(group_membership, group_ou, &security_flag, av);
2632 strcpy(new_group_name, av[L_NAME]);
2633 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2634 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2635 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2636 sprintf(mail_nickname, "%s", av[L_NAME]);
2639 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2641 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2645 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2646 groupTypeControl_v[0] = groupTypeControlStr;
2648 strcpy(cn_group_name, av[L_NAME]);
2650 samAccountName_v[0] = sam_group_name;
2651 name_v[0] = new_group_name;
2652 cn_v[0] = new_group_name;
2655 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2656 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2657 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2658 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2659 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2663 if(atoi(av[L_MAILLIST]))
2668 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2669 attr_array[0] = "cn";
2670 attr_array[1] = NULL;
2672 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2673 filter, attr_array, &group_base,
2675 LDAP_SCOPE_SUBTREE)) != 0)
2677 com_err(whoami, 0, "Unable to process group %s : %s",
2678 av[L_NAME], ldap_err2string(rc));
2684 com_err(whoami, 0, "Object already exists with name %s",
2689 linklist_free(group_base);
2694 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2696 mail_nickname_v[0] = mail_nickname;
2697 report_to_originator_v[0] = "TRUE";
2699 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2700 ADD_ATTR("reportToOriginator", report_to_originator_v,
2706 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2708 mail_v[0] = contact_mail;
2709 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2713 if (strlen(av[L_DESC]) != 0)
2715 desc_v[0] = av[L_DESC];
2716 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2719 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2721 if (strlen(av[L_ACE_NAME]) != 0)
2723 sprintf(info, "The Administrator of this list is: %s",
2726 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2729 if (strlen(call_args[5]) != 0)
2731 mitMoiraId_v[0] = call_args[5];
2732 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2737 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2739 for (i = 0; i < n; i++)
2742 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2744 com_err(whoami, 0, "Unable to create list %s in AD : %s",
2745 av[L_NAME], ldap_err2string(rc));
2751 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2753 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2754 "description", av[L_NAME]);
2755 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2756 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2760 if (strlen(call_args[5]) != 0)
2762 mitMoiraId_v[0] = call_args[5];
2763 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2766 if (!(atoi(av[L_ACTIVE])))
2769 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2774 if(atoi(av[L_MAILLIST]))
2779 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2780 attr_array[0] = "cn";
2781 attr_array[1] = NULL;
2783 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2784 filter, attr_array, &group_base,
2786 LDAP_SCOPE_SUBTREE)) != 0)
2788 com_err(whoami, 0, "Unable to process group %s : %s",
2789 av[L_NAME], ldap_err2string(rc));
2795 com_err(whoami, 0, "Object already exists with name %s",
2800 linklist_free(group_base);
2805 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2807 mail_nickname_v[0] = mail_nickname;
2808 report_to_originator_v[0] = "TRUE";
2810 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2811 ADD_ATTR("reportToOriginator", report_to_originator_v,
2817 mail_nickname_v[0] = NULL;
2818 proxy_address_v[0] = NULL;
2819 legacy_exchange_dn_v[0] = NULL;
2820 address_book_v[0] = NULL;
2821 report_to_originator_v[0] = NULL;
2823 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2824 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2825 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2826 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2828 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2829 ADD_ATTR("reportToOriginator", report_to_originator_v,
2835 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2837 mail_v[0] = contact_mail;
2838 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2843 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2852 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2854 for (i = 0; i < n; i++)
2857 if (rc != LDAP_SUCCESS)
2859 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2860 av[L_NAME], ldap_err2string(rc));
2867 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2868 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2870 return(LDAP_SUCCESS);
2873 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2874 char *TargetGroupName, int HiddenGroup,
2875 char *AceType, char *AceName)
2877 char filter_exp[1024];
2878 char *attr_array[5];
2879 char search_path[512];
2881 char TemplateDn[512];
2882 char TemplateSamName[128];
2884 char TargetSamName[128];
2885 char AceSamAccountName[128];
2887 unsigned char AceSid[128];
2888 unsigned char UserTemplateSid[128];
2889 char acBERBuf[N_SD_BER_BYTES];
2890 char GroupSecurityTemplate[256];
2891 char hide_addres_lists[256];
2892 char address_book[256];
2893 char *hide_address_lists_v[] = {NULL, NULL};
2894 char *address_book_v[] = {NULL, NULL};
2896 int UserTemplateSidCount;
2903 int array_count = 0;
2905 LK_ENTRY *group_base;
2906 LDAP_BERVAL **ppsValues;
2907 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2908 { N_SD_BER_BYTES, acBERBuf },
2911 LDAPControl *apsServerControls[] = {&sControl, NULL};
2914 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
2915 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
2916 BEREncodeSecurityBits(dwInfo, acBERBuf);
2918 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
2919 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
2920 attr_array[0] = "sAMAccountName";
2921 attr_array[1] = NULL;
2925 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2926 &group_base, &group_count,
2927 LDAP_SCOPE_SUBTREE) != 0))
2930 if (group_count != 1)
2932 linklist_free(group_base);
2936 strcpy(TargetDn, group_base->dn);
2937 strcpy(TargetSamName, group_base->value);
2938 linklist_free(group_base);
2942 UserTemplateSidCount = 0;
2943 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2944 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2945 memset(AceSid, '\0', sizeof(AceSid));
2950 if (strlen(AceName) != 0)
2952 if (!strcmp(AceType, "LIST"))
2954 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
2955 strcpy(root_ou, group_ou_root);
2957 else if (!strcmp(AceType, "USER"))
2959 sprintf(AceSamAccountName, "%s", AceName);
2960 strcpy(root_ou, user_ou);
2963 if (strlen(AceSamAccountName) != 0)
2965 sprintf(search_path, "%s", dn_path);
2966 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2967 attr_array[0] = "objectSid";
2968 attr_array[1] = NULL;
2972 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2973 attr_array, &group_base, &group_count,
2974 LDAP_SCOPE_SUBTREE) != 0))
2976 if (group_count == 1)
2978 strcpy(AceDn, group_base->dn);
2979 AceSidCount = group_base->length;
2980 memcpy(AceSid, group_base->value, AceSidCount);
2982 linklist_free(group_base);
2988 if (AceSidCount == 0)
2990 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
2991 "have an AD SID.", TargetGroupName, AceName, AceType);
2992 com_err(whoami, 0, " Non-admin security group template will be used.");
2996 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2997 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
2998 attr_array[0] = "objectSid";
2999 attr_array[1] = NULL;
3004 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3005 attr_array, &group_base, &group_count,
3006 LDAP_SCOPE_SUBTREE) != 0))
3009 if ((rc != 0) || (group_count != 1))
3011 com_err(whoami, 0, "Unable to process user security template: %s",
3017 UserTemplateSidCount = group_base->length;
3018 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3020 linklist_free(group_base);
3027 if (AceSidCount == 0)
3029 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3030 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3034 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3035 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3040 if (AceSidCount == 0)
3042 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3043 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3047 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
3048 sprintf(filter_exp, "(sAMAccountName=%s)",
3049 NOT_HIDDEN_GROUP_WITH_ADMIN);
3053 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3054 attr_array[0] = "sAMAccountName";
3055 attr_array[1] = NULL;
3059 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3060 &group_base, &group_count,
3061 LDAP_SCOPE_SUBTREE) != 0))
3064 if (group_count != 1)
3066 linklist_free(group_base);
3067 com_err(whoami, 0, "Unable to process group security template: %s - "
3068 "security not set", GroupSecurityTemplate);
3072 strcpy(TemplateDn, group_base->dn);
3073 strcpy(TemplateSamName, group_base->value);
3074 linklist_free(group_base);
3078 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3079 rc = ldap_search_ext_s(ldap_handle,
3091 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3093 com_err(whoami, 0, "Unable to find group security template: %s - "
3094 "security not set", GroupSecurityTemplate);
3098 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3100 if (ppsValues == NULL)
3102 com_err(whoami, 0, "Unable to find group security descriptor for group "
3103 "%s - security not set", GroupSecurityTemplate);
3107 if (AceSidCount != 0)
3109 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3112 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3114 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3115 UserTemplateSidCount))
3117 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3125 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3126 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3132 hide_address_lists_v[0] = "TRUE";
3133 address_book_v[0] = NULL;
3134 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3136 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3138 hide_address_lists_v[0] = NULL;
3139 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3146 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3148 for (i = 0; i < n; i++)
3151 ldap_value_free_len(ppsValues);
3152 ldap_msgfree(psMsg);
3154 if (rc != LDAP_SUCCESS)
3156 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3157 TargetGroupName, ldap_err2string(rc));
3159 if (AceSidCount != 0)
3162 "Trying to set security for group %s without admin.",
3165 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3166 HiddenGroup, "", ""))
3168 com_err(whoami, 0, "Unable to set security for group %s.",
3179 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3180 char *group_membership, char *MoiraId)
3182 LK_ENTRY *group_base;
3188 if (!check_string(group_name))
3191 "Unable to process invalid LDAP list name %s", group_name);
3192 return(AD_INVALID_NAME);
3195 memset(filter, '\0', sizeof(filter));
3198 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3200 if (rc = ad_get_group(ldap_handle, temp, group_name,
3201 group_membership, MoiraId,
3202 "distinguishedName", &group_base,
3203 &group_count, filter))
3206 if (group_count == 1)
3208 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
3210 linklist_free(group_base);
3211 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3212 group_name, ldap_err2string(rc));
3215 linklist_free(group_base);
3219 linklist_free(group_base);
3220 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
3221 return(AD_NO_GROUPS_FOUND);
3227 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3233 return(N_SD_BER_BYTES);
3236 int process_lists(int ac, char **av, void *ptr)
3241 char group_membership[2];
3247 memset(group_ou, '\0', sizeof(group_ou));
3248 memset(group_membership, '\0', sizeof(group_membership));
3249 get_group_membership(group_membership, group_ou, &security_flag, av);
3250 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
3251 group_ou, group_membership, call_args[2],
3252 (char *)call_args[3], "");
3256 int member_list_build(int ac, char **av, void *ptr)
3264 strcpy(temp, av[ACE_NAME]);
3266 if (!check_string(temp))
3269 if (!strcmp(av[ACE_TYPE], "USER"))
3271 if (!((int)call_args[3] & MOIRA_USERS))
3274 else if (!strcmp(av[ACE_TYPE], "STRING"))
3278 if((s = strchr(temp, '@')) == (char *) NULL)
3280 strcat(temp, "@mit.edu");
3283 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3285 s = strrchr(temp, '.');
3287 strcat(s, ".mit.edu");
3291 if (!((int)call_args[3] & MOIRA_STRINGS))
3294 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3298 else if (!strcmp(av[ACE_TYPE], "LIST"))
3300 if (!((int)call_args[3] & MOIRA_LISTS))
3303 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3305 if (!((int)call_args[3] & MOIRA_KERBEROS))
3308 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3316 linklist = member_base;
3320 if (!strcasecmp(temp, linklist->member))
3323 linklist = linklist->next;
3326 linklist = calloc(1, sizeof(LK_ENTRY));
3328 linklist->dn = NULL;
3329 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3330 strcpy(linklist->list, call_args[2]);
3331 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3332 strcpy(linklist->type, av[ACE_TYPE]);
3333 linklist->member = calloc(1, strlen(temp) + 1);
3334 strcpy(linklist->member, temp);
3335 linklist->next = member_base;
3336 member_base = linklist;
3341 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3342 char *group_ou, char *group_membership, char *user_name,
3343 char *UserOu, char *MoiraId)
3345 char distinguished_name[1024];
3349 char *attr_array[3];
3354 LK_ENTRY *group_base;
3358 if (!check_string(group_name))
3359 return(AD_INVALID_NAME);
3361 memset(filter, '\0', sizeof(filter));
3365 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3366 group_membership, MoiraId,
3367 "distinguishedName", &group_base,
3368 &group_count, filter))
3371 if (group_count != 1)
3373 com_err(whoami, 0, "Unable to find list %s in AD",
3375 linklist_free(group_base);
3381 strcpy(distinguished_name, group_base->value);
3382 linklist_free(group_base);
3386 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3388 modvalues[0] = temp;
3389 modvalues[1] = NULL;
3392 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3394 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3396 for (i = 0; i < n; i++)
3399 if (rc == LDAP_UNWILLING_TO_PERFORM)
3402 if (rc != LDAP_SUCCESS)
3404 com_err(whoami, 0, "Unable to modify list %s members : %s",
3405 group_name, ldap_err2string(rc));
3409 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3413 if(!strcmp(UserOu, contact_ou) &&
3414 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3416 memset(temp, '\0', sizeof(temp));
3417 strcpy(temp, user_name);
3418 s = strchr(temp, '@');
3421 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3423 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3424 &group_base, &group_count,
3425 LDAP_SCOPE_SUBTREE) != 0))
3431 linklist_free(group_base);
3436 sprintf(filter, "(distinguishedName=%s)", temp);
3437 attr_array[0] = "memberOf";
3438 attr_array[1] = NULL;
3440 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3441 &group_base, &group_count,
3442 LDAP_SCOPE_SUBTREE) != 0))
3448 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3450 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3460 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3461 char *group_ou, char *group_membership, char *user_name,
3462 char *UserOu, char *MoiraId)
3464 char distinguished_name[1024];
3472 LK_ENTRY *group_base;
3475 if (!check_string(group_name))
3476 return(AD_INVALID_NAME);
3479 memset(filter, '\0', sizeof(filter));
3483 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3484 group_membership, MoiraId,
3485 "distinguishedName", &group_base,
3486 &group_count, filter))
3489 if (group_count != 1)
3491 linklist_free(group_base);
3494 com_err(whoami, 0, "Unable to find list %s in AD",
3496 return(AD_MULTIPLE_GROUPS_FOUND);
3499 strcpy(distinguished_name, group_base->value);
3500 linklist_free(group_base);
3504 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3505 modvalues[0] = temp;
3506 modvalues[1] = NULL;
3509 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3511 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3513 if (rc == LDAP_ALREADY_EXISTS)
3516 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3518 if (rc == LDAP_UNWILLING_TO_PERFORM)
3522 for (i = 0; i < n; i++)
3525 if (rc != LDAP_SUCCESS)
3527 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3528 user_name, group_name, ldap_err2string(rc));
3534 int contact_remove_email(LDAP *ld, char *bind_path,
3535 LK_ENTRY **linklist_base, int linklist_current)
3539 char *mail_v[] = {NULL, NULL};
3547 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3548 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3549 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3550 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3553 gPtr = (*linklist_base);
3556 rc = ldap_modify_s(ld, gPtr->dn, mods);
3558 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3560 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3561 gPtr->dn, ldap_err2string(rc));
3568 for (i = 0; i < n; i++)
3574 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3577 LK_ENTRY *group_base;
3580 char cn_user_name[256];
3581 char contact_name[256];
3582 char mail_nickname[256];
3583 char proxy_address_internal[256];
3584 char proxy_address_external[256];
3585 char target_address[256];
3586 char internal_contact_name[256];
3589 char mit_address_book[256];
3590 char default_address_book[256];
3591 char contact_address_book[256];
3592 char *email_v[] = {NULL, NULL};
3593 char *cn_v[] = {NULL, NULL};
3594 char *contact_v[] = {NULL, NULL};
3595 char *mail_nickname_v[] = {NULL, NULL};
3596 char *proxy_address_internal_v[] = {NULL, NULL};
3597 char *proxy_address_external_v[] = {NULL, NULL};
3598 char *target_address_v[] = {NULL, NULL};
3599 char *mit_address_book_v[] = {NULL, NULL};
3600 char *default_address_book_v[] = {NULL, NULL};
3601 char *contact_address_book_v[] = {NULL, NULL};
3602 char *hide_address_lists_v[] = {NULL, NULL};
3603 char *attr_array[3];
3605 char *objectClass_v[] = {"top", "person",
3606 "organizationalPerson",
3608 char *name_v[] = {NULL, NULL};
3609 char *desc_v[] = {NULL, NULL};
3615 if (!check_string(user))
3617 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3618 return(AD_INVALID_NAME);
3622 strcpy(contact_name, mail);
3623 strcpy(internal_contact_name, mail);
3625 if((s = strchr(internal_contact_name, '@')) != NULL) {
3629 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
3630 sprintf(target_address, "SMTP:%s", contact_name);
3631 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3632 sprintf(mail_nickname, "%s", internal_contact_name);
3634 cn_v[0] = cn_user_name;
3635 contact_v[0] = contact_name;
3637 desc_v[0] = "Auto account created by Moira";
3639 proxy_address_internal_v[0] = proxy_address_internal;
3640 proxy_address_external_v[0] = proxy_address_external;
3641 mail_nickname_v[0] = mail_nickname;
3642 target_address_v[0] = target_address;
3643 mit_address_book_v[0] = mit_address_book;
3644 default_address_book_v[0] = default_address_book;
3645 contact_address_book_v[0] = contact_address_book;
3646 strcpy(new_dn, cn_user_name);
3649 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3650 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3651 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3652 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3653 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3657 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3662 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3663 attr_array[0] = "cn";
3664 attr_array[1] = NULL;
3666 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3667 &group_base, &group_count,
3668 LDAP_SCOPE_SUBTREE)) != 0)
3670 com_err(whoami, 0, "Unable to process contact %s : %s",
3671 user, ldap_err2string(rc));
3677 com_err(whoami, 0, "Object already exists with name %s",
3682 linklist_free(group_base);
3686 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3687 attr_array[0] = "cn";
3688 attr_array[1] = NULL;
3690 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3691 &group_base, &group_count,
3692 LDAP_SCOPE_SUBTREE)) != 0)
3694 com_err(whoami, 0, "Unable to process contact %s : %s",
3695 user, ldap_err2string(rc));
3701 com_err(whoami, 0, "Object already exists with name %s",
3706 linklist_free(group_base);
3710 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3711 attr_array[0] = "cn";
3712 attr_array[1] = NULL;
3714 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3715 &group_base, &group_count,
3716 LDAP_SCOPE_SUBTREE)) != 0)
3718 com_err(whoami, 0, "Unable to process contact %s : %s",
3719 user, ldap_err2string(rc));
3725 com_err(whoami, 0, "Object already exists with name %s",
3730 linklist_free(group_base);
3734 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3735 attr_array[0] = "cn";
3736 attr_array[1] = NULL;
3738 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3739 &group_base, &group_count,
3740 LDAP_SCOPE_SUBTREE)) != 0)
3742 com_err(whoami, 0, "Unable to process contact %s : %s",
3743 user, ldap_err2string(rc));
3749 com_err(whoami, 0, "Object already exists with name %s",
3754 linklist_free(group_base);
3758 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3759 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3760 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3761 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3763 hide_address_lists_v[0] = "TRUE";
3764 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3771 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3773 for (i = 0; i < n; i++)
3778 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS))
3782 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
3783 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
3784 ADD_ATTR("proxyAddresses", proxy_address_external_v,
3786 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
3788 hide_address_lists_v[0] = "TRUE";
3789 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3793 rc = ldap_modify_s(ld, new_dn, mods);
3797 com_err(whoami, 0, "Unable to update contact %s", mail);
3800 for (i = 0; i < n; i++)
3805 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3808 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3809 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3810 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3811 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3812 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3814 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3816 for (i = 0; i < n; i++)
3820 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3822 com_err(whoami, 0, "Unable to create contact %s : %s",
3823 user, ldap_err2string(rc));
3830 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3831 char *Uid, char *MitId, char *MoiraId, int State,
3832 char *WinHomeDir, char *WinProfileDir, char *first,
3833 char *middle, char *last)
3836 LK_ENTRY *group_base;
3838 char distinguished_name[512];
3839 char displayName[256];
3840 char *mitMoiraId_v[] = {NULL, NULL};
3841 char *uid_v[] = {NULL, NULL};
3842 char *mitid_v[] = {NULL, NULL};
3843 char *homedir_v[] = {NULL, NULL};
3844 char *winProfile_v[] = {NULL, NULL};
3845 char *drives_v[] = {NULL, NULL};
3846 char *userAccountControl_v[] = {NULL, NULL};
3847 char *alt_recipient_v[] = {NULL, NULL};
3848 char *hide_address_lists_v[] = {NULL, NULL};
3849 char *mail_v[] = {NULL, NULL};
3850 char userAccountControlStr[80];
3855 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
3856 UF_PASSWD_CANT_CHANGE;
3858 char *attr_array[3];
3861 char contact_mail[256];
3862 char filter_exp[1024];
3863 char search_path[512];
3864 char TemplateDn[512];
3865 char TemplateSamName[128];
3866 char alt_recipient[256];
3867 char acBERBuf[N_SD_BER_BYTES];
3868 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3869 { N_SD_BER_BYTES, acBERBuf },
3871 LDAPControl *apsServerControls[] = {&sControl, NULL};
3873 LDAP_BERVAL **ppsValues;
3877 char *homeServerName;
3879 char search_string[256];
3881 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3882 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3883 BEREncodeSecurityBits(dwInfo, acBERBuf);
3885 if (!check_string(user_name))
3887 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
3889 return(AD_INVALID_NAME);
3892 memset(contact_mail, '\0', sizeof(contact_mail));
3893 sprintf(contact_mail, "%s@mit.edu", user_name);
3894 memset(mail, '\0', sizeof(mail));
3895 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
3896 memset(alt_recipient, '\0', sizeof(alt_recipient));
3897 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
3899 sprintf(search_string, "@%s", uppercase(ldap_domain));
3903 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
3905 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
3912 memset(displayName, '\0', sizeof(displayName));
3914 if (strlen(MoiraId) != 0)
3916 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
3917 attr_array[0] = "cn";
3918 attr_array[1] = NULL;
3919 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3920 &group_base, &group_count,
3921 LDAP_SCOPE_SUBTREE)) != 0)
3923 com_err(whoami, 0, "Unable to process user %s : %s",
3924 user_name, ldap_err2string(rc));
3929 if (group_count != 1)
3931 linklist_free(group_base);
3934 sprintf(filter, "(sAMAccountName=%s)", user_name);
3935 attr_array[0] = "cn";
3936 attr_array[1] = NULL;
3937 sprintf(temp, "%s,%s", user_ou, dn_path);
3938 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
3939 &group_base, &group_count,
3940 LDAP_SCOPE_SUBTREE)) != 0)
3942 com_err(whoami, 0, "Unable to process user %s : %s",
3943 user_name, ldap_err2string(rc));
3948 if (group_count != 1)
3950 com_err(whoami, 0, "Unable to find user %s in AD",
3952 linklist_free(group_base);
3953 return(AD_NO_USER_FOUND);
3956 strcpy(distinguished_name, group_base->dn);
3958 linklist_free(group_base);
3961 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
3962 rc = attribute_update(ldap_handle, distinguished_name, MitId,
3963 "employeeID", user_name);
3965 rc = attribute_update(ldap_handle, distinguished_name, "none",
3966 "employeeID", user_name);
3969 strcat(displayName, first);
3972 if(strlen(middle)) {
3974 strcat(displayName, " ");
3976 strcat(displayName, middle);
3980 if(strlen(middle) || strlen(first))
3981 strcat(displayName, " ");
3983 strcat(displayName, last);
3986 if(strlen(displayName))
3987 rc = attribute_update(ldap_handle, distinguished_name, displayName,
3988 "displayName", user_name);
3990 rc = attribute_update(ldap_handle, distinguished_name, user_name,
3991 "displayName", user_name);
3994 rc = attribute_update(ldap_handle, distinguished_name, first,
3995 "givenName", user_name);
3997 rc = attribute_update(ldap_handle, distinguished_name, "",
3998 "givenName", user_name);
4000 if(strlen(middle) == 1)
4001 rc = attribute_update(ldap_handle, distinguished_name, middle,
4002 "initials", user_name);
4004 rc = attribute_update(ldap_handle, distinguished_name, "",
4005 "initials", user_name);
4008 rc = attribute_update(ldap_handle, distinguished_name, last,
4011 rc = attribute_update(ldap_handle, distinguished_name, "",
4014 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4016 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4017 "mitMoiraId", user_name);
4024 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4028 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4031 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4033 userAccountControl |= UF_ACCOUNTDISABLE;
4037 hide_address_lists_v[0] = "TRUE";
4038 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4046 hide_address_lists_v[0] = NULL;
4047 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4052 sprintf(userAccountControlStr, "%ld", userAccountControl);
4053 userAccountControl_v[0] = userAccountControlStr;
4054 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4058 if (rc = moira_connect())
4060 critical_alert("AD incremental",
4061 "Error contacting Moira server : %s",
4066 argv[0] = user_name;
4068 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4070 if(!strcmp(save_argv[1], "EXCHANGE") ||
4071 (strstr(save_argv[3], search_string) != NULL))
4073 alt_recipient_v[0] = NULL;
4074 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4076 argv[0] = exchange_acl;
4078 argv[2] = user_name;
4080 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4082 if ((rc) && (rc != MR_EXISTS))
4084 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4085 user_name, exchange_acl, error_message(rc));
4090 alt_recipient_v[0] = alt_recipient;
4091 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4093 argv[0] = exchange_acl;
4095 argv[2] = user_name;
4097 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4099 if ((rc) && (rc != MR_NO_MATCH))
4102 "Unable to remove user %s from %s: %s, %d",
4103 user_name, exchange_acl, error_message(rc), rc);
4109 alt_recipient_v[0] = alt_recipient;
4110 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4112 argv[0] = exchange_acl;
4114 argv[2] = user_name;
4116 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4118 if ((rc) && (rc != MR_NO_MATCH))
4121 "Unable to remove user %s from %s: %s, %d",
4122 user_name, exchange_acl, error_message(rc), rc);
4130 mail_v[0] = contact_mail;
4131 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4134 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4135 WinProfileDir, homedir_v, winProfile_v,
4136 drives_v, mods, LDAP_MOD_REPLACE, n);
4138 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4139 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4140 attr_array[0] = "sAMAccountName";
4141 attr_array[1] = NULL;
4145 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
4146 &group_base, &group_count,
4147 LDAP_SCOPE_SUBTREE) != 0))
4150 if (group_count != 1)
4152 com_err(whoami, 0, "Unable to process user security template: %s - "
4153 "security not set", "UserTemplate.u");
4157 strcpy(TemplateDn, group_base->dn);
4158 strcpy(TemplateSamName, group_base->value);
4159 linklist_free(group_base);
4163 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4164 filter_exp, NULL, 0, apsServerControls, NULL,
4167 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4169 com_err(whoami, 0, "Unable to find user security template: %s - "
4170 "security not set", "UserTemplate.u");
4174 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
4176 if (ppsValues == NULL)
4178 com_err(whoami, 0, "Unable to find user security template: %s - "
4179 "security not set", "UserTemplate.u");
4183 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4184 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4188 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4189 mods)) != LDAP_SUCCESS)
4191 OldUseSFU30 = UseSFU30;
4192 SwitchSFU(mods, &UseSFU30, n);
4193 if (OldUseSFU30 != UseSFU30)
4194 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4197 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4198 user_name, ldap_err2string(rc));
4202 for (i = 0; i < n; i++)
4208 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4216 char contact_mail[256];
4217 char proxy_address[256];
4218 char query_base_dn[256];
4220 char *userPrincipalName_v[] = {NULL, NULL};
4221 char *altSecurityIdentities_v[] = {NULL, NULL};
4222 char *name_v[] = {NULL, NULL};
4223 char *samAccountName_v[] = {NULL, NULL};
4224 char *mail_v[] = {NULL, NULL};
4225 char *mail_nickname_v[] = {NULL, NULL};
4226 char *proxy_address_v[] = {NULL, NULL};
4227 char *query_base_dn_v[] = {NULL, NULL};
4232 if (!check_string(before_user_name))
4235 "Unable to process invalid LDAP user name %s", before_user_name);
4236 return(AD_INVALID_NAME);
4239 if (!check_string(user_name))
4242 "Unable to process invalid LDAP user name %s", user_name);
4243 return(AD_INVALID_NAME);
4246 strcpy(user_name, user_name);
4247 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4248 sprintf(new_dn, "cn=%s", user_name);
4249 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4250 sprintf(contact_mail, "%s@mit.edu", user_name);
4251 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4253 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4254 NULL, NULL)) != LDAP_SUCCESS)
4256 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4257 before_user_name, user_name, ldap_err2string(rc));
4263 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4266 if(rc = ldap_delete_s(ldap_handle, temp))
4268 com_err(whoami, 0, "Unable to delete user contact for %s",
4272 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4274 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4278 name_v[0] = user_name;
4279 sprintf(upn, "%s@%s", user_name, ldap_domain);
4280 userPrincipalName_v[0] = upn;
4281 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4282 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4283 altSecurityIdentities_v[0] = temp;
4284 samAccountName_v[0] = user_name;
4286 mail_nickname_v[0] = user_name;
4287 proxy_address_v[0] = proxy_address;
4288 query_base_dn_v[0] = query_base_dn;
4291 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4292 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4293 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4294 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4298 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4299 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4300 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4301 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4305 mail_v[0] = contact_mail;
4306 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4311 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4313 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4316 "Unable to modify user data for %s after renaming : %s",
4317 user_name, ldap_err2string(rc));
4320 for (i = 0; i < n; i++)
4326 int user_create(int ac, char **av, void *ptr)
4330 char user_name[256];
4334 char contact_mail[256];
4335 char proxy_address[256];
4336 char mail_nickname[256];
4337 char query_base_dn[256];
4338 char displayName[256];
4339 char address_book[256];
4340 char alt_recipient[256];
4341 char *cn_v[] = {NULL, NULL};
4342 char *objectClass_v[] = {"top", "person",
4343 "organizationalPerson",
4346 char *samAccountName_v[] = {NULL, NULL};
4347 char *altSecurityIdentities_v[] = {NULL, NULL};
4348 char *mitMoiraId_v[] = {NULL, NULL};
4349 char *name_v[] = {NULL, NULL};
4350 char *desc_v[] = {NULL, NULL};
4351 char *userPrincipalName_v[] = {NULL, NULL};
4352 char *userAccountControl_v[] = {NULL, NULL};
4353 char *uid_v[] = {NULL, NULL};
4354 char *mitid_v[] = {NULL, NULL};
4355 char *homedir_v[] = {NULL, NULL};
4356 char *winProfile_v[] = {NULL, NULL};
4357 char *drives_v[] = {NULL, NULL};
4358 char *mail_v[] = {NULL, NULL};
4359 char *givenName_v[] = {NULL, NULL};
4360 char *sn_v[] = {NULL, NULL};
4361 char *initials_v[] = {NULL, NULL};
4362 char *displayName_v[] = {NULL, NULL};
4363 char *proxy_address_v[] = {NULL, NULL};
4364 char *mail_nickname_v[] = {NULL, NULL};
4365 char *query_base_dn_v[] = {NULL, NULL};
4366 char *address_book_v[] = {NULL, NULL};
4367 char *homeMDB_v[] = {NULL, NULL};
4368 char *homeServerName_v[] = {NULL, NULL};
4369 char *mdbUseDefaults_v[] = {NULL, NULL};
4370 char *mailbox_guid_v[] = {NULL, NULL};
4371 char *user_culture_v[] = {NULL, NULL};
4372 char *user_account_control_v[] = {NULL, NULL};
4373 char *msexch_version_v[] = {NULL, NULL};
4374 char *alt_recipient_v[] = {NULL, NULL};
4375 char *hide_address_lists_v[] = {NULL, NULL};
4376 char userAccountControlStr[80];
4378 char filter_exp[1024];
4379 char search_path[512];
4380 char *attr_array[3];
4381 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4382 UF_PASSWD_CANT_CHANGE;
4388 char WinHomeDir[1024];
4389 char WinProfileDir[1024];
4391 char *homeServerName;
4393 char acBERBuf[N_SD_BER_BYTES];
4394 LK_ENTRY *group_base;
4396 char TemplateDn[512];
4397 char TemplateSamName[128];
4398 LDAP_BERVAL **ppsValues;
4399 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4400 { N_SD_BER_BYTES, acBERBuf },
4402 LDAPControl *apsServerControls[] = {&sControl, NULL};
4406 char search_string[256];
4410 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4411 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4412 BEREncodeSecurityBits(dwInfo, acBERBuf);
4414 if (!check_string(av[U_NAME]))
4416 callback_rc = AD_INVALID_NAME;
4417 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4419 return(AD_INVALID_NAME);
4422 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4423 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4424 memset(displayName, '\0', sizeof(displayName));
4425 memset(query_base_dn, '\0', sizeof(query_base_dn));
4426 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4427 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4428 strcpy(user_name, av[U_NAME]);
4429 sprintf(upn, "%s@%s", user_name, ldap_domain);
4430 sprintf(sam_name, "%s", av[U_NAME]);
4432 if(strlen(av[U_FIRST])) {
4433 strcat(displayName, av[U_FIRST]);
4436 if(strlen(av[U_MIDDLE])) {
4437 if(strlen(av[U_FIRST]))
4438 strcat(displayName, " ");
4440 strcat(displayName, av[U_MIDDLE]);
4443 if(strlen(av[U_LAST])) {
4444 if(strlen(av[U_FIRST]) || strlen(av[U_LAST]))
4445 strcat(displayName, " ");
4447 strcat(displayName, av[U_LAST]);
4450 samAccountName_v[0] = sam_name;
4451 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4452 (atoi(av[U_STATE]) != US_REGISTERED))
4454 userAccountControl |= UF_ACCOUNTDISABLE;
4458 hide_address_lists_v[0] = "TRUE";
4459 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4464 sprintf(userAccountControlStr, "%ld", userAccountControl);
4465 userAccountControl_v[0] = userAccountControlStr;
4466 userPrincipalName_v[0] = upn;
4467 cn_v[0] = user_name;
4468 name_v[0] = user_name;
4469 desc_v[0] = "Auto account created by Moira";
4471 givenName_v[0] = av[U_FIRST];
4472 sn_v[0] = av[U_LAST];
4473 displayName_v[0] = displayName;
4474 mail_nickname_v[0] = user_name;
4476 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4477 altSecurityIdentities_v[0] = temp;
4478 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4479 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4480 sprintf(contact_mail, "%s@mit.edu", user_name);
4481 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4482 query_base_dn_v[0] = query_base_dn;
4483 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4485 sprintf(search_string, "@%s", uppercase(ldap_domain));
4490 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4493 com_err(whoami, 0, "Unable to create user contact %s",
4497 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4500 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4504 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4505 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4507 homeMDB_v[0] = homeMDB;
4508 homeServerName_v[0] = homeServerName;
4512 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4513 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4514 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
4515 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
4516 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
4517 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
4518 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
4522 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
4523 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4524 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
4525 mdbUseDefaults_v[0] = "TRUE";
4526 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
4527 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
4529 argv[0] = user_name;
4531 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4533 if(!strcmp(save_argv[1], "EXCHANGE") ||
4534 (strstr(save_argv[3], search_string) != NULL))
4536 argv[0] = exchange_acl;
4538 argv[2] = user_name;
4540 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4542 if ((rc) && (rc != MR_EXISTS))
4544 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4545 user_name, exchange_acl, error_message(rc));
4550 alt_recipient_v[0] = alt_recipient;
4551 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4556 alt_recipient_v[0] = alt_recipient;
4557 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4559 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
4564 mail_v[0] = contact_mail;
4565 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
4568 if(strlen(av[U_FIRST])) {
4569 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
4572 if(strlen(av[U_LAST])) {
4573 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
4576 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
4577 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
4579 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4582 if (strlen(av[U_MIDDLE]) == 1) {
4583 initials_v[0] = av[U_MIDDLE];
4584 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
4587 if (strlen(call_args[2]) != 0)
4589 mitMoiraId_v[0] = call_args[2];
4590 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
4593 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
4595 if (strlen(av[U_UID]) != 0)
4597 uid_v[0] = av[U_UID];
4598 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
4602 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
4606 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
4610 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
4611 mitid_v[0] = av[U_MITID];
4613 mitid_v[0] = "none";
4615 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
4617 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
4618 WinProfileDir, homedir_v, winProfile_v,
4619 drives_v, mods, LDAP_MOD_ADD, n);
4621 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4622 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
4623 attr_array[0] = "sAMAccountName";
4624 attr_array[1] = NULL;
4628 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
4629 attr_array, &group_base, &group_count,
4630 LDAP_SCOPE_SUBTREE) != 0))
4633 if (group_count != 1)
4635 com_err(whoami, 0, "Unable to process user security template: %s - "
4636 "security not set", "UserTemplate.u");
4640 strcpy(TemplateDn, group_base->dn);
4641 strcpy(TemplateSamName, group_base->value);
4642 linklist_free(group_base);
4646 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE,
4647 filter_exp, NULL, 0, apsServerControls, NULL,
4650 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
4652 com_err(whoami, 0, "Unable to find user security template: %s - "
4653 "security not set", "UserTemplate.u");
4657 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
4658 "ntSecurityDescriptor");
4659 if (ppsValues == NULL)
4661 com_err(whoami, 0, "Unable to find user security template: %s - "
4662 "security not set", "UserTemplate.u");
4666 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4667 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4671 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4673 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4675 OldUseSFU30 = UseSFU30;
4676 SwitchSFU(mods, &UseSFU30, n);
4677 if (OldUseSFU30 != UseSFU30)
4678 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4681 for (i = 0; i < n; i++)
4684 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4686 com_err(whoami, 0, "Unable to create user %s : %s",
4687 user_name, ldap_err2string(rc));
4692 if ((rc == LDAP_SUCCESS) && (SetPassword))
4694 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4696 ad_kdc_disconnect();
4697 if (!ad_server_connect(default_server, ldap_domain))
4699 com_err(whoami, 0, "Unable to set password for user %s : %s",
4701 "cannot get changepw ticket from windows domain");
4705 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4707 com_err(whoami, 0, "Unable to set password for user %s "
4708 ": %ld", user_name, rc);
4717 int user_change_status(LDAP *ldap_handle, char *dn_path,
4718 char *user_name, char *MoiraId,
4722 char *attr_array[3];
4724 char distinguished_name[1024];
4726 char *mitMoiraId_v[] = {NULL, NULL};
4728 LK_ENTRY *group_base;
4735 if (!check_string(user_name))
4737 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4739 return(AD_INVALID_NAME);
4745 if (strlen(MoiraId) != 0)
4747 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4748 attr_array[0] = "UserAccountControl";
4749 attr_array[1] = NULL;
4750 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4751 &group_base, &group_count,
4752 LDAP_SCOPE_SUBTREE)) != 0)
4754 com_err(whoami, 0, "Unable to process user %s : %s",
4755 user_name, ldap_err2string(rc));
4760 if (group_count != 1)
4762 linklist_free(group_base);
4765 sprintf(filter, "(sAMAccountName=%s)", user_name);
4766 attr_array[0] = "UserAccountControl";
4767 attr_array[1] = NULL;
4768 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4769 &group_base, &group_count,
4770 LDAP_SCOPE_SUBTREE)) != 0)
4772 com_err(whoami, 0, "Unable to process user %s : %s",
4773 user_name, ldap_err2string(rc));
4778 if (group_count != 1)
4780 linklist_free(group_base);
4781 com_err(whoami, 0, "Unable to find user %s in AD",
4783 return(LDAP_NO_SUCH_OBJECT);
4786 strcpy(distinguished_name, group_base->dn);
4787 ulongValue = atoi((*group_base).value);
4789 if (operation == MEMBER_DEACTIVATE)
4790 ulongValue |= UF_ACCOUNTDISABLE;
4792 ulongValue &= ~UF_ACCOUNTDISABLE;
4794 sprintf(temp, "%ld", ulongValue);
4796 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
4797 temp, &modvalues, REPLACE)) == 1)
4800 linklist_free(group_base);
4804 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
4806 if (strlen(MoiraId) != 0)
4808 mitMoiraId_v[0] = MoiraId;
4809 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
4813 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4815 for (i = 0; i < n; i++)
4818 free_values(modvalues);
4820 if (rc != LDAP_SUCCESS)
4822 com_err(whoami, 0, "Unable to change status of user %s : %s",
4823 user_name, ldap_err2string(rc));
4830 int user_delete(LDAP *ldap_handle, char *dn_path,
4831 char *u_name, char *MoiraId)
4834 char *attr_array[3];
4835 char distinguished_name[1024];
4836 char user_name[512];
4837 LK_ENTRY *group_base;
4842 if (!check_string(u_name))
4843 return(AD_INVALID_NAME);
4845 strcpy(user_name, u_name);
4849 if (strlen(MoiraId) != 0)
4851 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4852 attr_array[0] = "name";
4853 attr_array[1] = NULL;
4854 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4855 &group_base, &group_count,
4856 LDAP_SCOPE_SUBTREE)) != 0)
4858 com_err(whoami, 0, "Unable to process user %s : %s",
4859 user_name, ldap_err2string(rc));
4864 if (group_count != 1)
4866 linklist_free(group_base);
4869 sprintf(filter, "(sAMAccountName=%s)", user_name);
4870 attr_array[0] = "name";
4871 attr_array[1] = NULL;
4872 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4873 &group_base, &group_count,
4874 LDAP_SCOPE_SUBTREE)) != 0)
4876 com_err(whoami, 0, "Unable to process user %s : %s",
4877 user_name, ldap_err2string(rc));
4882 if (group_count != 1)
4884 com_err(whoami, 0, "Unable to find user %s in AD",
4889 strcpy(distinguished_name, group_base->dn);
4891 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
4893 com_err(whoami, 0, "Unable to process user %s : %s",
4894 user_name, ldap_err2string(rc));
4897 /* Need to add code to delete mit.edu contact */
4901 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
4903 if(rc = ldap_delete_s(ldap_handle, temp))
4905 com_err(whoami, 0, "Unable to delete user contact for %s",
4911 linklist_free(group_base);
4916 void linklist_free(LK_ENTRY *linklist_base)
4918 LK_ENTRY *linklist_previous;
4920 while (linklist_base != NULL)
4922 if (linklist_base->dn != NULL)
4923 free(linklist_base->dn);
4925 if (linklist_base->attribute != NULL)
4926 free(linklist_base->attribute);
4928 if (linklist_base->value != NULL)
4929 free(linklist_base->value);
4931 if (linklist_base->member != NULL)
4932 free(linklist_base->member);
4934 if (linklist_base->type != NULL)
4935 free(linklist_base->type);
4937 if (linklist_base->list != NULL)
4938 free(linklist_base->list);
4940 linklist_previous = linklist_base;
4941 linklist_base = linklist_previous->next;
4942 free(linklist_previous);
4946 void free_values(char **modvalues)
4952 if (modvalues != NULL)
4954 while (modvalues[i] != NULL)
4957 modvalues[i] = NULL;
4964 static int illegalchars[] = {
4965 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
4966 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
4967 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
4968 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
4969 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
4970 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
4971 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
4972 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
4973 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4974 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4975 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4976 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4977 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4978 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4979 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4980 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4983 int check_string(char *s)
4991 if (isupper(character))
4992 character = tolower(character);
4994 if (illegalchars[(unsigned) character])
5001 int check_container_name(char *s)
5009 if (isupper(character))
5010 character = tolower(character);
5012 if (character == ' ')
5015 if (illegalchars[(unsigned) character])
5022 int mr_connect_cl(char *server, char *client, int version, int auth)
5028 status = mr_connect(server);
5032 com_err(whoami, status, "while connecting to Moira");
5036 status = mr_motd(&motd);
5041 com_err(whoami, status, "while checking server status");
5047 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5048 com_err(whoami, status, temp);
5053 status = mr_version(version);
5057 if (status == MR_UNKNOWN_PROC)
5060 status = MR_VERSION_HIGH;
5062 status = MR_SUCCESS;
5065 if (status == MR_VERSION_HIGH)
5067 com_err(whoami, 0, "Warning: This client is running newer code "
5068 "than the server.");
5069 com_err(whoami, 0, "Some operations may not work.");
5071 else if (status && status != MR_VERSION_LOW)
5073 com_err(whoami, status, "while setting query version number.");
5081 status = mr_krb5_auth(client);
5084 com_err(whoami, status, "while authenticating to Moira.");
5093 void AfsToWinAfs(char* path, char* winPath)
5097 strcpy(winPath, WINAFS);
5098 pathPtr = path + strlen(AFS);
5099 winPathPtr = winPath + strlen(WINAFS);
5103 if (*pathPtr == '/')
5106 *winPathPtr = *pathPtr;
5113 int GetAceInfo(int ac, char **av, void *ptr)
5120 strcpy(call_args[0], av[L_ACE_TYPE]);
5121 strcpy(call_args[1], av[L_ACE_NAME]);
5123 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5124 return(LDAP_SUCCESS);
5127 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5130 char *attr_array[3];
5133 LK_ENTRY *group_base;
5138 sprintf(filter, "(sAMAccountName=%s)", Name);
5139 attr_array[0] = "sAMAccountName";
5140 attr_array[1] = NULL;
5142 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5143 &group_base, &group_count,
5144 LDAP_SCOPE_SUBTREE)) != 0)
5146 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5147 Name, ldap_err2string(rc));
5151 linklist_free(group_base);
5154 if (group_count == 0)
5162 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5163 int UpdateGroup, int *ProcessGroup, char *maillist)
5166 char GroupName[256];
5172 char AceMembership[2];
5175 char *save_argv[U_END];
5179 com_err(whoami, 0, "ProcessAce disabled, skipping");
5183 strcpy(GroupName, Name);
5185 if (strcasecmp(Type, "LIST"))
5191 AceInfo[0] = AceType;
5192 AceInfo[1] = AceName;
5193 AceInfo[2] = AceMembership;
5195 memset(AceType, '\0', sizeof(AceType));
5196 memset(AceName, '\0', sizeof(AceName));
5197 memset(AceMembership, '\0', sizeof(AceMembership));
5198 memset(AceOu, '\0', sizeof(AceOu));
5201 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5203 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5204 GroupName, error_message(rc));
5210 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5214 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5217 strcpy(temp, AceName);
5219 if (!strcasecmp(AceType, "LIST"))
5220 sprintf(temp, "%s%s", AceName, group_suffix);
5224 if (checkADname(ldap_handle, dn_path, temp))
5226 (*ProcessGroup) = 1;
5229 if (!strcasecmp(AceInfo[0], "LIST"))
5231 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5232 AceMembership, 0, UpdateGroup, maillist))
5235 else if (!strcasecmp(AceInfo[0], "USER"))
5238 call_args[0] = (char *)ldap_handle;
5239 call_args[1] = dn_path;
5241 call_args[3] = NULL;
5244 if (rc = mr_query("get_user_account_by_login", 1, av,
5245 save_query_info, save_argv))
5247 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5252 if (rc = user_create(U_END, save_argv, call_args))
5254 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5261 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5271 if (!strcasecmp(AceType, "LIST"))
5273 if (!strcasecmp(GroupName, AceName))
5277 strcpy(GroupName, AceName);
5283 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5284 char *group_name, char *group_ou, char *group_membership,
5285 int group_security_flag, int updateGroup, char *maillist)
5290 LK_ENTRY *group_base;
5293 char *attr_array[3];
5296 call_args[0] = (char *)ldap_handle;
5297 call_args[1] = dn_path;
5298 call_args[2] = group_name;
5299 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5300 call_args[4] = (char *)updateGroup;
5301 call_args[5] = MoiraId;
5303 call_args[7] = NULL;
5309 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5312 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5320 com_err(whoami, 0, "Unable to create list %s", group_name);
5321 return(callback_rc);
5327 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
5328 char *group_ou, char *group_membership,
5329 int group_security_flag, char *MoiraId)
5339 com_err(whoami, 0, "Populating group %s", group_name);
5341 call_args[0] = (char *)ldap_handle;
5342 call_args[1] = dn_path;
5343 call_args[2] = group_name;
5344 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5345 call_args[4] = NULL;
5348 if (rc = mr_query("get_end_members_of_list", 1, av,
5349 member_list_build, call_args))
5351 com_err(whoami, 0, "Unable to populate list %s : %s",
5352 group_name, error_message(rc));
5356 if (member_base != NULL)
5362 if (!strcasecmp(ptr->type, "LIST"))
5370 if (!strcasecmp(ptr->type, "STRING"))
5372 if (contact_create(ldap_handle, dn_path, ptr->member,
5376 pUserOu = contact_ou;
5378 else if (!strcasecmp(ptr->type, "KERBEROS"))
5380 if (contact_create(ldap_handle, dn_path, ptr->member,
5384 pUserOu = kerberos_ou;
5387 rc = member_add(ldap_handle, dn_path, group_name,
5388 group_ou, group_membership, ptr->member,
5393 linklist_free(member_base);
5400 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5401 char *group_name, char *group_ou, char *group_membership,
5402 int group_security_flag, int type, char *maillist)
5404 char before_desc[512];
5405 char before_name[256];
5406 char before_group_ou[256];
5407 char before_group_membership[2];
5408 char distinguishedName[256];
5409 char ad_distinguishedName[256];
5411 char *attr_array[3];
5412 int before_security_flag;
5415 LK_ENTRY *group_base;
5418 char ou_security[512];
5419 char ou_distribution[512];
5420 char ou_neither[512];
5422 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
5423 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
5425 memset(filter, '\0', sizeof(filter));
5429 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5431 "distinguishedName", &group_base,
5432 &group_count, filter))
5435 if (type == CHECK_GROUPS)
5437 if (group_count == 1)
5439 if (!strcasecmp(group_base->value, distinguishedName))
5441 linklist_free(group_base);
5446 linklist_free(group_base);
5448 if (group_count == 0)
5449 return(AD_NO_GROUPS_FOUND);
5451 if (group_count == 1)
5452 return(AD_WRONG_GROUP_DN_FOUND);
5454 return(AD_MULTIPLE_GROUPS_FOUND);
5457 if (group_count == 0)
5459 return(AD_NO_GROUPS_FOUND);
5462 if (group_count > 1)
5468 if (!strcasecmp(distinguishedName, ptr->value))
5476 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
5482 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
5486 linklist_free(group_base);
5487 return(AD_MULTIPLE_GROUPS_FOUND);
5494 if (strcasecmp(distinguishedName, ptr->value))
5495 rc = ldap_delete_s(ldap_handle, ptr->value);
5500 linklist_free(group_base);
5501 memset(filter, '\0', sizeof(filter));
5505 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5507 "distinguishedName", &group_base,
5508 &group_count, filter))
5511 if (group_count == 0)
5512 return(AD_NO_GROUPS_FOUND);
5514 if (group_count > 1)
5515 return(AD_MULTIPLE_GROUPS_FOUND);
5518 strcpy(ad_distinguishedName, group_base->value);
5519 linklist_free(group_base);
5523 attr_array[0] = "sAMAccountName";
5524 attr_array[1] = NULL;
5526 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5527 &group_base, &group_count,
5528 LDAP_SCOPE_SUBTREE)) != 0)
5530 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5531 MoiraId, ldap_err2string(rc));
5535 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
5537 if (!strcasecmp(ad_distinguishedName, distinguishedName))
5539 linklist_free(group_base);
5545 linklist_free(group_base);
5548 memset(ou_both, '\0', sizeof(ou_both));
5549 memset(ou_security, '\0', sizeof(ou_security));
5550 memset(ou_distribution, '\0', sizeof(ou_distribution));
5551 memset(ou_neither, '\0', sizeof(ou_neither));
5552 memset(before_name, '\0', sizeof(before_name));
5553 memset(before_desc, '\0', sizeof(before_desc));
5554 memset(before_group_membership, '\0', sizeof(before_group_membership));
5555 attr_array[0] = "name";
5556 attr_array[1] = NULL;
5558 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5559 &group_base, &group_count,
5560 LDAP_SCOPE_SUBTREE)) != 0)
5562 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
5563 MoiraId, ldap_err2string(rc));
5567 strcpy(before_name, group_base->value);
5568 linklist_free(group_base);
5571 attr_array[0] = "description";
5572 attr_array[1] = NULL;
5574 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5575 &group_base, &group_count,
5576 LDAP_SCOPE_SUBTREE)) != 0)
5579 "Unable to get list description with MoiraId = %s: %s",
5580 MoiraId, ldap_err2string(rc));
5584 if (group_count != 0)
5586 strcpy(before_desc, group_base->value);
5587 linklist_free(group_base);
5592 change_to_lower_case(ad_distinguishedName);
5593 strcpy(ou_both, group_ou_both);
5594 change_to_lower_case(ou_both);
5595 strcpy(ou_security, group_ou_security);
5596 change_to_lower_case(ou_security);
5597 strcpy(ou_distribution, group_ou_distribution);
5598 change_to_lower_case(ou_distribution);
5599 strcpy(ou_neither, group_ou_neither);
5600 change_to_lower_case(ou_neither);
5602 if (strstr(ad_distinguishedName, ou_both))
5604 strcpy(before_group_ou, group_ou_both);
5605 before_group_membership[0] = 'B';
5606 before_security_flag = 1;
5608 else if (strstr(ad_distinguishedName, ou_security))
5610 strcpy(before_group_ou, group_ou_security);
5611 before_group_membership[0] = 'S';
5612 before_security_flag = 1;
5614 else if (strstr(ad_distinguishedName, ou_distribution))
5616 strcpy(before_group_ou, group_ou_distribution);
5617 before_group_membership[0] = 'D';
5618 before_security_flag = 0;
5620 else if (strstr(ad_distinguishedName, ou_neither))
5622 strcpy(before_group_ou, group_ou_neither);
5623 before_group_membership[0] = 'N';
5624 before_security_flag = 0;
5627 return(AD_NO_OU_FOUND);
5629 rc = group_rename(ldap_handle, dn_path, before_name,
5630 before_group_membership,
5631 before_group_ou, before_security_flag, before_desc,
5632 group_name, group_membership, group_ou,
5633 group_security_flag,
5634 before_desc, MoiraId, filter, maillist);
5639 void change_to_lower_case(char *ptr)
5643 for (i = 0; i < (int)strlen(ptr); i++)
5645 ptr[i] = tolower(ptr[i]);
5649 int ad_get_group(LDAP *ldap_handle, char *dn_path,
5650 char *group_name, char *group_membership,
5651 char *MoiraId, char *attribute,
5652 LK_ENTRY **linklist_base, int *linklist_count,
5657 char *attr_array[3];
5660 (*linklist_base) = NULL;
5661 (*linklist_count) = 0;
5663 if (strlen(rFilter) != 0)
5665 strcpy(filter, rFilter);
5666 attr_array[0] = attribute;
5667 attr_array[1] = NULL;
5669 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5670 linklist_base, linklist_count,
5671 LDAP_SCOPE_SUBTREE)) != 0)
5673 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5674 MoiraId, ldap_err2string(rc));
5678 if ((*linklist_count) == 1)
5680 strcpy(rFilter, filter);
5685 linklist_free((*linklist_base));
5686 (*linklist_base) = NULL;
5687 (*linklist_count) = 0;
5689 if (strlen(MoiraId) != 0)
5691 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
5692 attr_array[0] = attribute;
5693 attr_array[1] = NULL;
5695 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5696 linklist_base, linklist_count,
5697 LDAP_SCOPE_SUBTREE)) != 0)
5699 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5700 MoiraId, ldap_err2string(rc));
5705 if ((*linklist_count) > 1)
5707 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
5708 pPtr = (*linklist_base);
5712 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
5717 linklist_free((*linklist_base));
5718 (*linklist_base) = NULL;
5719 (*linklist_count) = 0;
5722 if ((*linklist_count) == 1)
5724 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
5726 strcpy(rFilter, filter);
5731 linklist_free((*linklist_base));
5732 (*linklist_base) = NULL;
5733 (*linklist_count) = 0;
5734 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
5735 attr_array[0] = attribute;
5736 attr_array[1] = NULL;
5738 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5739 linklist_base, linklist_count,
5740 LDAP_SCOPE_SUBTREE)) != 0)
5742 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5743 MoiraId, ldap_err2string(rc));
5747 if ((*linklist_count) == 1)
5749 strcpy(rFilter, filter);
5756 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5759 char *attr_array[3];
5760 char SamAccountName[64];
5763 LK_ENTRY *group_base;
5769 if (strlen(MoiraId) != 0)
5771 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5772 attr_array[0] = "sAMAccountName";
5773 attr_array[1] = NULL;
5774 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5775 &group_base, &group_count,
5776 LDAP_SCOPE_SUBTREE)) != 0)
5778 com_err(whoami, 0, "Unable to process user %s : %s",
5779 UserName, ldap_err2string(rc));
5783 if (group_count > 1)
5785 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5791 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5792 gPtr->value, MoiraId);
5798 if (group_count != 1)
5800 linklist_free(group_base);
5803 sprintf(filter, "(sAMAccountName=%s)", UserName);
5804 attr_array[0] = "sAMAccountName";
5805 attr_array[1] = NULL;
5807 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5808 &group_base, &group_count,
5809 LDAP_SCOPE_SUBTREE)) != 0)
5811 com_err(whoami, 0, "Unable to process user %s : %s",
5812 UserName, ldap_err2string(rc));
5817 if (group_count != 1)
5819 linklist_free(group_base);
5820 return(AD_NO_USER_FOUND);
5823 strcpy(SamAccountName, group_base->value);
5824 linklist_free(group_base);
5828 if (strcmp(SamAccountName, UserName))
5830 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5837 void container_get_dn(char *src, char *dest)
5844 memset(array, '\0', 20 * sizeof(array[0]));
5846 if (strlen(src) == 0)
5868 strcpy(dest, "OU=");
5872 strcat(dest, array[n-1]);
5876 strcat(dest, ",OU=");
5883 void container_get_name(char *src, char *dest)
5888 if (strlen(src) == 0)
5908 void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5915 strcpy(cName, name);
5917 for (i = 0; i < (int)strlen(cName); i++)
5919 if (cName[i] == '/')
5922 av[CONTAINER_NAME] = cName;
5923 av[CONTAINER_DESC] = "";
5924 av[CONTAINER_LOCATION] = "";
5925 av[CONTAINER_CONTACT] = "";
5926 av[CONTAINER_TYPE] = "";
5927 av[CONTAINER_ID] = "";
5928 av[CONTAINER_ROWID] = "";
5929 rc = container_create(ldap_handle, dn_path, 7, av);
5931 if (rc == LDAP_SUCCESS)
5933 com_err(whoami, 0, "container %s created without a mitMoiraId",
5942 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5943 char **before, int afterc, char **after)
5948 char new_dn_path[256];
5950 char distinguishedName[256];
5955 memset(cName, '\0', sizeof(cName));
5956 container_get_name(after[CONTAINER_NAME], cName);
5958 if (!check_container_name(cName))
5960 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5962 return(AD_INVALID_NAME);
5965 memset(distinguishedName, '\0', sizeof(distinguishedName));
5967 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5968 distinguishedName, beforec, before))
5971 if (strlen(distinguishedName) == 0)
5973 rc = container_create(ldap_handle, dn_path, afterc, after);
5977 strcpy(temp, after[CONTAINER_NAME]);
5980 for (i = 0; i < (int)strlen(temp); i++)
5990 container_get_dn(temp, dName);
5992 if (strlen(temp) != 0)
5993 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5995 sprintf(new_dn_path, "%s", dn_path);
5997 sprintf(new_cn, "OU=%s", cName);
5999 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6001 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6002 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6004 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6005 before[CONTAINER_NAME], after[CONTAINER_NAME],
6006 ldap_err2string(rc));
6010 memset(dName, '\0', sizeof(dName));
6011 container_get_dn(after[CONTAINER_NAME], dName);
6012 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6017 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6019 char distinguishedName[256];
6022 memset(distinguishedName, '\0', sizeof(distinguishedName));
6024 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6025 distinguishedName, count, av))
6028 if (strlen(distinguishedName) == 0)
6031 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6033 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6034 container_move_objects(ldap_handle, dn_path, distinguishedName);
6036 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6037 av[CONTAINER_NAME], ldap_err2string(rc));
6043 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6045 char *attr_array[3];
6046 LK_ENTRY *group_base;
6049 char *objectClass_v[] = {"top",
6050 "organizationalUnit",
6053 char *ou_v[] = {NULL, NULL};
6054 char *name_v[] = {NULL, NULL};
6055 char *moiraId_v[] = {NULL, NULL};
6056 char *desc_v[] = {NULL, NULL};
6057 char *managedBy_v[] = {NULL, NULL};
6060 char managedByDN[256];
6067 memset(filter, '\0', sizeof(filter));
6068 memset(dName, '\0', sizeof(dName));
6069 memset(cName, '\0', sizeof(cName));
6070 memset(managedByDN, '\0', sizeof(managedByDN));
6071 container_get_dn(av[CONTAINER_NAME], dName);
6072 container_get_name(av[CONTAINER_NAME], cName);
6074 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6076 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6078 return(AD_INVALID_NAME);
6081 if (!check_container_name(cName))
6083 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6085 return(AD_INVALID_NAME);
6089 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6091 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6093 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6095 if (strlen(av[CONTAINER_ROWID]) != 0)
6097 moiraId_v[0] = av[CONTAINER_ROWID];
6098 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6101 if (strlen(av[CONTAINER_DESC]) != 0)
6103 desc_v[0] = av[CONTAINER_DESC];
6104 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6107 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6109 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6111 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6114 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6115 kerberos_ou, dn_path);
6116 managedBy_v[0] = managedByDN;
6117 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6122 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6124 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6125 "(objectClass=user)))", av[CONTAINER_ID]);
6128 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6130 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6134 if (strlen(filter) != 0)
6136 attr_array[0] = "distinguishedName";
6137 attr_array[1] = NULL;
6140 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6142 &group_base, &group_count,
6143 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6145 if (group_count == 1)
6147 strcpy(managedByDN, group_base->value);
6148 managedBy_v[0] = managedByDN;
6149 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6151 linklist_free(group_base);
6161 sprintf(temp, "%s,%s", dName, dn_path);
6162 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
6164 for (i = 0; i < n; i++)
6167 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6169 com_err(whoami, 0, "Unable to create container %s : %s",
6170 cName, ldap_err2string(rc));
6174 if (rc == LDAP_ALREADY_EXISTS)
6176 if (strlen(av[CONTAINER_ROWID]) != 0)
6177 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6183 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6184 char **before, int afterc, char **after)
6186 char distinguishedName[256];
6189 memset(distinguishedName, '\0', sizeof(distinguishedName));
6191 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6192 distinguishedName, afterc, after))
6195 if (strlen(distinguishedName) == 0)
6197 rc = container_create(ldap_handle, dn_path, afterc, after);
6201 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6202 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6208 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6209 char *distinguishedName, int count,
6212 char *attr_array[3];
6213 LK_ENTRY *group_base;
6220 memset(filter, '\0', sizeof(filter));
6221 memset(dName, '\0', sizeof(dName));
6222 memset(cName, '\0', sizeof(cName));
6223 container_get_dn(av[CONTAINER_NAME], dName);
6224 container_get_name(av[CONTAINER_NAME], cName);
6226 if (strlen(dName) == 0)
6228 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6229 av[CONTAINER_NAME]);
6230 return(AD_INVALID_NAME);
6233 if (!check_container_name(cName))
6235 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6237 return(AD_INVALID_NAME);
6240 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6241 av[CONTAINER_ROWID]);
6242 attr_array[0] = "distinguishedName";
6243 attr_array[1] = NULL;
6247 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6248 &group_base, &group_count,
6249 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6251 if (group_count == 1)
6253 strcpy(distinguishedName, group_base->value);
6256 linklist_free(group_base);
6261 if (strlen(distinguishedName) == 0)
6263 sprintf(filter, "(&(objectClass=organizationalUnit)"
6264 "(distinguishedName=%s,%s))", dName, dn_path);
6265 attr_array[0] = "distinguishedName";
6266 attr_array[1] = NULL;
6270 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6271 &group_base, &group_count,
6272 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6274 if (group_count == 1)
6276 strcpy(distinguishedName, group_base->value);
6279 linklist_free(group_base);
6288 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6289 char *distinguishedName, int count, char **av)
6291 char *attr_array[5];
6292 LK_ENTRY *group_base;
6297 char *moiraId_v[] = {NULL, NULL};
6298 char *desc_v[] = {NULL, NULL};
6299 char *managedBy_v[] = {NULL, NULL};
6300 char managedByDN[256];
6309 strcpy(ad_path, distinguishedName);
6311 if (strlen(dName) != 0)
6312 sprintf(ad_path, "%s,%s", dName, dn_path);
6314 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6317 if (strlen(av[CONTAINER_ID]) != 0)
6318 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6319 av[CONTAINER_ROWID]);
6321 attr_array[0] = "mitMoiraId";
6322 attr_array[1] = "description";
6323 attr_array[2] = "managedBy";
6324 attr_array[3] = NULL;
6328 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6329 &group_base, &group_count,
6330 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6332 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6333 av[CONTAINER_NAME], ldap_err2string(rc));
6337 memset(managedByDN, '\0', sizeof(managedByDN));
6338 memset(moiraId, '\0', sizeof(moiraId));
6339 memset(desc, '\0', sizeof(desc));
6344 if (!strcasecmp(pPtr->attribute, "description"))
6345 strcpy(desc, pPtr->value);
6346 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6347 strcpy(managedByDN, pPtr->value);
6348 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6349 strcpy(moiraId, pPtr->value);
6353 linklist_free(group_base);
6358 if (strlen(av[CONTAINER_ROWID]) != 0)
6360 moiraId_v[0] = av[CONTAINER_ROWID];
6361 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6364 if (strlen(av[CONTAINER_DESC]) != 0)
6366 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6371 if (strlen(desc) != 0)
6373 attribute_update(ldap_handle, ad_path, "", "description", dName);
6377 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6379 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6381 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6384 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6385 kerberos_ou, dn_path);
6386 managedBy_v[0] = managedByDN;
6387 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6391 if (strlen(managedByDN) != 0)
6393 attribute_update(ldap_handle, ad_path, "", "managedBy",
6400 memset(filter, '\0', sizeof(filter));
6402 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6404 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6405 "(objectClass=user)))", av[CONTAINER_ID]);
6408 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6410 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6414 if (strlen(filter) != 0)
6416 attr_array[0] = "distinguishedName";
6417 attr_array[1] = NULL;
6420 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6421 attr_array, &group_base, &group_count,
6422 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6424 if (group_count == 1)
6426 strcpy(managedByDN, group_base->value);
6427 managedBy_v[0] = managedByDN;
6428 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6432 if (strlen(managedByDN) != 0)
6434 attribute_update(ldap_handle, ad_path, "",
6435 "managedBy", dName);
6439 linklist_free(group_base);
6446 if (strlen(managedByDN) != 0)
6448 attribute_update(ldap_handle, ad_path, "", "managedBy",
6458 return(LDAP_SUCCESS);
6460 rc = ldap_modify_s(ldap_handle, ad_path, mods);
6462 for (i = 0; i < n; i++)
6465 if (rc != LDAP_SUCCESS)
6467 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6468 av[CONTAINER_NAME], ldap_err2string(rc));
6475 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6477 char *attr_array[3];
6478 LK_ENTRY *group_base;
6485 int NumberOfEntries = 10;
6489 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6491 for (i = 0; i < 3; i++)
6493 memset(filter, '\0', sizeof(filter));
6497 strcpy(filter, "(!(|(objectClass=computer)"
6498 "(objectClass=organizationalUnit)))");
6499 attr_array[0] = "cn";
6500 attr_array[1] = NULL;
6504 strcpy(filter, "(objectClass=computer)");
6505 attr_array[0] = "cn";
6506 attr_array[1] = NULL;
6510 strcpy(filter, "(objectClass=organizationalUnit)");
6511 attr_array[0] = "ou";
6512 attr_array[1] = NULL;
6517 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
6518 &group_base, &group_count,
6519 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6524 if (group_count == 0)
6531 if (!strcasecmp(pPtr->attribute, "cn"))
6533 sprintf(new_cn, "cn=%s", pPtr->value);
6535 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6537 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6542 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6544 if (rc == LDAP_ALREADY_EXISTS)
6546 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6553 else if (!strcasecmp(pPtr->attribute, "ou"))
6555 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6561 linklist_free(group_base);
6570 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6571 char *machine_ou, char *NewMachineName)
6573 LK_ENTRY *group_base;
6577 char *attr_array[3];
6584 strcpy(NewMachineName, member);
6585 rc = moira_connect();
6586 rc = GetMachineName(NewMachineName);
6589 if (strlen(NewMachineName) == 0)
6591 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6597 pPtr = strchr(NewMachineName, '.');
6604 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
6605 attr_array[0] = "cn";
6606 attr_array[1] = NULL;
6607 sprintf(temp, "%s", dn_path);
6609 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
6610 &group_base, &group_count,
6611 LDAP_SCOPE_SUBTREE)) != 0)
6613 com_err(whoami, 0, "Unable to process machine %s : %s",
6614 member, ldap_err2string(rc));
6618 if (group_count != 1)
6621 "Unable to process machine %s : machine not found in AD",
6626 strcpy(dn, group_base->dn);
6627 strcpy(cn, group_base->value);
6629 for (i = 0; i < (int)strlen(dn); i++)
6630 dn[i] = tolower(dn[i]);
6632 for (i = 0; i < (int)strlen(cn); i++)
6633 cn[i] = tolower(cn[i]);
6635 linklist_free(group_base);
6637 pPtr = strstr(dn, cn);
6641 com_err(whoami, 0, "Unable to process machine %s",
6646 pPtr += strlen(cn) + 1;
6647 strcpy(machine_ou, pPtr);
6649 pPtr = strstr(machine_ou, "dc=");
6653 com_err(whoami, 0, "Unable to process machine %s",
6664 int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6665 char *MoiraMachineName, char *DestinationOu)
6669 char MachineName[128];
6671 char *attr_array[3];
6676 LK_ENTRY *group_base;
6681 strcpy(MachineName, MoiraMachineName);
6682 rc = GetMachineName(MachineName);
6684 if (strlen(MachineName) == 0)
6686 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6691 cPtr = strchr(MachineName, '.');
6696 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6697 attr_array[0] = "sAMAccountName";
6698 attr_array[1] = NULL;
6700 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6702 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
6704 com_err(whoami, 0, "Unable to process machine %s : %s",
6705 MoiraMachineName, ldap_err2string(rc));
6709 if (group_count == 1)
6710 strcpy(OldDn, group_base->dn);
6712 linklist_free(group_base);
6715 if (group_count != 1)
6717 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6722 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6723 cPtr = strchr(OldDn, ',');
6728 if (!strcasecmp(cPtr, NewOu))
6732 sprintf(NewCn, "CN=%s", MachineName);
6733 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6738 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6744 memset(Name, '\0', sizeof(Name));
6745 strcpy(Name, machine_name);
6747 pPtr = strchr(Name, '.');
6753 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
6756 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6757 char *machine_name, char *container_name)
6763 av[0] = machine_name;
6764 call_args[0] = (char *)container_name;
6765 rc = mr_query("get_machine_to_container_map", 1, av,
6766 machine_GetMoiraContainer, call_args);
6770 int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6775 strcpy(call_args[0], av[1]);
6779 int Moira_container_group_create(char **after)
6785 memset(GroupName, '\0', sizeof(GroupName));
6786 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6787 after[CONTAINER_ROWID]);
6791 argv[L_NAME] = GroupName;
6792 argv[L_ACTIVE] = "1";
6793 argv[L_PUBLIC] = "0";
6794 argv[L_HIDDEN] = "0";
6795 argv[L_MAILLIST] = "0";
6796 argv[L_GROUP] = "1";
6797 argv[L_GID] = UNIQUE_GID;
6798 argv[L_NFSGROUP] = "0";
6799 argv[L_MAILMAN] = "0";
6800 argv[L_MAILMAN_SERVER] = "[NONE]";
6801 argv[L_DESC] = "auto created container group";
6802 argv[L_ACE_TYPE] = "USER";
6803 argv[L_MEMACE_TYPE] = "USER";
6804 argv[L_ACE_NAME] = "sms";
6805 argv[L_MEMACE_NAME] = "sms";
6807 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
6810 "Unable to create container group %s for container %s: %s",
6811 GroupName, after[CONTAINER_NAME], error_message(rc));
6814 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6815 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6820 int Moira_container_group_update(char **before, char **after)
6823 char BeforeGroupName[64];
6824 char AfterGroupName[64];
6827 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6830 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6831 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6832 if (strlen(BeforeGroupName) == 0)
6835 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6836 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6837 after[CONTAINER_ROWID]);
6841 if (strcasecmp(BeforeGroupName, AfterGroupName))
6843 argv[L_NAME] = BeforeGroupName;
6844 argv[L_NAME + 1] = AfterGroupName;
6845 argv[L_ACTIVE + 1] = "1";
6846 argv[L_PUBLIC + 1] = "0";
6847 argv[L_HIDDEN + 1] = "0";
6848 argv[L_MAILLIST + 1] = "0";
6849 argv[L_GROUP + 1] = "1";
6850 argv[L_GID + 1] = UNIQUE_GID;
6851 argv[L_NFSGROUP + 1] = "0";
6852 argv[L_MAILMAN + 1] = "0";
6853 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
6854 argv[L_DESC + 1] = "auto created container group";
6855 argv[L_ACE_TYPE + 1] = "USER";
6856 argv[L_MEMACE_TYPE + 1] = "USER";
6857 argv[L_ACE_NAME + 1] = "sms";
6858 argv[L_MEMACE_NAME + 1] = "sms";
6860 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
6863 "Unable to rename container group from %s to %s: %s",
6864 BeforeGroupName, AfterGroupName, error_message(rc));
6871 int Moira_container_group_delete(char **before)
6876 char ParentGroupName[64];
6878 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6879 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6881 memset(GroupName, '\0', sizeof(GroupName));
6883 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6884 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6886 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6888 argv[0] = ParentGroupName;
6890 argv[2] = GroupName;
6892 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6895 "Unable to delete container group %s from list: %s",
6896 GroupName, ParentGroupName, error_message(rc));
6900 if (strlen(GroupName) != 0)
6902 argv[0] = GroupName;
6904 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6906 com_err(whoami, 0, "Unable to delete container group %s : %s",
6907 GroupName, error_message(rc));
6914 int Moira_groupname_create(char *GroupName, char *ContainerName,
6915 char *ContainerRowID)
6920 char newGroupName[64];
6921 char tempGroupName[64];
6927 strcpy(temp, ContainerName);
6929 ptr1 = strrchr(temp, '/');
6935 ptr1 = strrchr(temp, '/');
6939 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6942 strcpy(tempgname, ptr);
6945 strcpy(tempgname, temp);
6947 if (strlen(tempgname) > 25)
6948 tempgname[25] ='\0';
6950 sprintf(newGroupName, "cnt-%s", tempgname);
6952 /* change everything to lower case */
6958 *ptr = tolower(*ptr);
6966 strcpy(tempGroupName, newGroupName);
6969 /* append 0-9 then a-z if a duplicate is found */
6972 argv[0] = newGroupName;
6974 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6976 if (rc == MR_NO_MATCH)
6978 com_err(whoami, 0, "Moira error while creating group name for "
6979 "container %s : %s", ContainerName, error_message(rc));
6983 sprintf(newGroupName, "%s-%c", tempGroupName, i);
6987 com_err(whoami, 0, "Unable to find a unique group name for "
6988 "container %s: too many duplicate container names",
6999 strcpy(GroupName, newGroupName);
7003 int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7008 argv[0] = origContainerName;
7009 argv[1] = GroupName;
7011 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7014 "Unable to set container group %s in container %s: %s",
7015 GroupName, origContainerName, error_message(rc));
7021 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7023 char ContainerName[64];
7024 char ParentGroupName[64];
7028 strcpy(ContainerName, origContainerName);
7030 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7032 /* top-level container */
7033 if (strlen(ParentGroupName) == 0)
7036 argv[0] = ParentGroupName;
7038 argv[2] = GroupName;
7040 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7043 "Unable to add container group %s to parent group %s: %s",
7044 GroupName, ParentGroupName, error_message(rc));
7050 int Moira_getContainerGroup(int ac, char **av, void *ptr)
7055 strcpy(call_args[0], av[1]);
7060 int Moira_getGroupName(char *origContainerName, char *GroupName,
7063 char ContainerName[64];
7069 strcpy(ContainerName, origContainerName);
7073 ptr = strrchr(ContainerName, '/');
7081 argv[0] = ContainerName;
7083 call_args[0] = GroupName;
7084 call_args[1] = NULL;
7086 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7089 if (strlen(GroupName) != 0)
7094 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7095 ContainerName, error_message(rc));
7097 com_err(whoami, 0, "Unable to get container group from container %s",
7103 int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7109 if (strcmp(GroupName, "[none]") == 0)
7112 argv[0] = GroupName;
7113 argv[1] = "MACHINE";
7114 argv[2] = MachineName;
7117 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7119 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7123 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7124 MachineName, GroupName, error_message(rc));
7130 int GetMachineName(char *MachineName)
7133 char NewMachineName[1024];
7140 // If the address happens to be in the top-level MIT domain, great!
7141 strcpy(NewMachineName, MachineName);
7143 for (i = 0; i < (int)strlen(NewMachineName); i++)
7144 NewMachineName[i] = toupper(NewMachineName[i]);
7146 szDot = strchr(NewMachineName,'.');
7148 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7153 // If not, see if it has a Moira alias in the top-level MIT domain.
7154 memset(NewMachineName, '\0', sizeof(NewMachineName));
7156 args[1] = MachineName;
7157 call_args[0] = NewMachineName;
7158 call_args[1] = NULL;
7160 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7162 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7163 MachineName, error_message(rc));
7164 strcpy(MachineName, "");
7168 if (strlen(NewMachineName) != 0)
7169 strcpy(MachineName, NewMachineName);
7171 strcpy(MachineName, "");
7176 int ProcessMachineName(int ac, char **av, void *ptr)
7179 char MachineName[1024];
7185 if (strlen(call_args[0]) == 0)
7187 strcpy(MachineName, av[0]);
7189 for (i = 0; i < (int)strlen(MachineName); i++)
7190 MachineName[i] = toupper(MachineName[i]);
7192 szDot = strchr(MachineName,'.');
7194 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
7196 strcpy(call_args[0], MachineName);
7203 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7209 for (i = 0; i < n; i++)
7211 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7212 mods[i]->mod_type = "uidNumber";
7219 for (i = 0; i < n; i++)
7221 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7222 mods[i]->mod_type = "msSFU30UidNumber";
7229 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7230 char *DistinguishedName,
7231 char *WinHomeDir, char *WinProfileDir,
7232 char **homedir_v, char **winProfile_v,
7233 char **drives_v, LDAPMod **mods,
7241 char winProfile[1024];
7246 LDAPMod *DelMods[20];
7248 memset(homeDrive, '\0', sizeof(homeDrive));
7249 memset(path, '\0', sizeof(path));
7250 memset(winPath, '\0', sizeof(winPath));
7251 memset(winProfile, '\0', sizeof(winProfile));
7254 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7255 (!strcasecmp(WinProfileDir, "[afs]")))
7257 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
7259 memset(cWeight, 0, sizeof(cWeight));
7260 memset(cPath, 0, sizeof(cPath));
7264 while (hp[i] != NULL)
7266 if (sscanf(hp[i], "%*s %s", cPath))
7268 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
7270 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
7272 if (atoi(cWeight) < last_weight)
7274 strcpy(path, cPath);
7275 last_weight = (int)atoi(cWeight);
7279 strcpy(path, cPath);
7287 if (!strnicmp(path, AFS, strlen(AFS)))
7289 AfsToWinAfs(path, winPath);
7290 strcpy(winProfile, winPath);
7291 strcat(winProfile, "\\.winprofile");
7299 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7300 (!strcasecmp(WinProfileDir, "[dfs]")))
7302 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7303 user_name[0], user_name);
7305 if (!strcasecmp(WinProfileDir, "[dfs]"))
7307 strcpy(winProfile, path);
7308 strcat(winProfile, "\\.winprofile");
7311 if (!strcasecmp(WinHomeDir, "[dfs]"))
7312 strcpy(winPath, path);
7325 if (!strcasecmp(WinHomeDir, "[local]"))
7326 memset(winPath, '\0', sizeof(winPath));
7327 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7328 !strcasecmp(WinHomeDir, "[dfs]"))
7330 strcpy(homeDrive, "H:");
7334 strcpy(winPath, WinHomeDir);
7335 if (!strncmp(WinHomeDir, "\\\\", 2))
7337 strcpy(homeDrive, "H:");
7341 // nothing needs to be done if WinProfileDir is [afs].
7342 if (!strcasecmp(WinProfileDir, "[local]"))
7343 memset(winProfile, '\0', sizeof(winProfile));
7344 else if (strcasecmp(WinProfileDir, "[afs]") &&
7345 strcasecmp(WinProfileDir, "[dfs]"))
7347 strcpy(winProfile, WinProfileDir);
7350 if (strlen(winProfile) != 0)
7352 if (winProfile[strlen(winProfile) - 1] == '\\')
7353 winProfile[strlen(winProfile) - 1] = '\0';
7356 if (strlen(winPath) != 0)
7358 if (winPath[strlen(winPath) - 1] == '\\')
7359 winPath[strlen(winPath) - 1] = '\0';
7362 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
7363 strcat(winProfile, "\\");
7365 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7366 strcat(winPath, "\\");
7368 if (strlen(winPath) == 0)
7370 if (OpType == LDAP_MOD_REPLACE)
7373 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7375 //unset homeDirectory attribute for user.
7376 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7382 homedir_v[0] = strdup(winPath);
7383 ADD_ATTR("homeDirectory", homedir_v, OpType);
7386 if (strlen(winProfile) == 0)
7388 if (OpType == LDAP_MOD_REPLACE)
7391 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7393 //unset profilePate attribute for user.
7394 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7400 winProfile_v[0] = strdup(winProfile);
7401 ADD_ATTR("profilePath", winProfile_v, OpType);
7404 if (strlen(homeDrive) == 0)
7406 if (OpType == LDAP_MOD_REPLACE)
7409 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7411 //unset homeDrive attribute for user
7412 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7418 drives_v[0] = strdup(homeDrive);
7419 ADD_ATTR("homeDrive", drives_v, OpType);
7425 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
7426 char *attribute_value, char *attribute, char *user_name)
7428 char *mod_v[] = {NULL, NULL};
7429 LDAPMod *DelMods[20];
7435 if (strlen(attribute_value) == 0)
7438 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7440 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7446 mod_v[0] = attribute_value;
7447 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7450 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7451 mods)) != LDAP_SUCCESS)
7455 mod_v[0] = attribute_value;
7456 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7459 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7460 mods)) != LDAP_SUCCESS)
7462 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7464 attribute, user_name, ldap_err2string(rc));
7474 void StringTrim(char *StringToTrim)
7479 save = strdup(StringToTrim);
7486 /* skip to end of string */
7491 strcpy(StringToTrim, save);
7495 for (t = s; *t; t++)
7511 strcpy(StringToTrim, s);
7515 int ReadConfigFile(char *DomainName)
7526 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
7528 if ((fptr = fopen(temp, "r")) != NULL)
7530 while (fgets(temp, sizeof(temp), fptr) != 0)
7532 for (i = 0; i < (int)strlen(temp); i++)
7533 temp[i] = toupper(temp[i]);
7535 if (temp[strlen(temp) - 1] == '\n')
7536 temp[strlen(temp) - 1] = '\0';
7540 if (strlen(temp) == 0)
7543 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7545 if (strlen(temp) > (strlen(DOMAIN)))
7547 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7548 StringTrim(ldap_domain);
7551 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
7553 if (strlen(temp) > (strlen(PRINCIPALNAME)))
7555 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7556 StringTrim(PrincipalName);
7559 else if (!strncmp(temp, SERVER, strlen(SERVER)))
7561 if (strlen(temp) > (strlen(SERVER)))
7563 ServerList[Count] = calloc(1, 256);
7564 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7565 StringTrim(ServerList[Count]);
7569 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
7571 if (strlen(temp) > (strlen(MSSFU)))
7573 strcpy(temp1, &temp[strlen(MSSFU)]);
7575 if (!strcmp(temp1, SFUTYPE))
7579 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7581 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7583 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7585 if (!strcasecmp(temp1, "NO"))
7588 memset(group_suffix, '\0', sizeof(group_suffix));
7592 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7594 if (strlen(temp) > (strlen(GROUP_TYPE)))
7596 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7598 if (!strcasecmp(temp1, "UNIVERSAL"))
7599 UseGroupUniversal = 1;
7602 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7604 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7606 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7608 if (!strcasecmp(temp1, "NO"))
7612 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7614 if (strlen(temp) > (strlen(SET_PASSWORD)))
7616 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7618 if (!strcasecmp(temp1, "NO"))
7622 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7624 if (strlen(temp) > (strlen(EXCHANGE)))
7626 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7628 if (!strcasecmp(temp1, "YES"))
7632 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7633 strlen(PROCESS_MACHINE_CONTAINER)))
7635 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7637 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7639 if (!strcasecmp(temp1, "NO"))
7640 ProcessMachineContainer = 0;
7645 if (strlen(ldap_domain) != 0)
7647 memset(ldap_domain, '\0', sizeof(ldap_domain));
7651 if (strlen(temp) != 0)
7652 strcpy(ldap_domain, temp);
7658 if (strlen(ldap_domain) == 0)
7660 strcpy(ldap_domain, DomainName);
7666 for (i = 0; i < Count; i++)
7668 if (ServerList[i] != 0)
7670 strcat(ServerList[i], ".");
7671 strcat(ServerList[i], ldap_domain);
7672 for (k = 0; k < (int)strlen(ServerList[i]); k++)
7673 ServerList[i][k] = toupper(ServerList[i][k]);
7680 int ReadDomainList()
7687 unsigned char c[11];
7688 unsigned char stuff[256];
7693 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
7695 if ((fptr = fopen(temp, "r")) != NULL)
7697 while (fgets(temp, sizeof(temp), fptr) != 0)
7699 for (i = 0; i < (int)strlen(temp); i++)
7700 temp[i] = toupper(temp[i]);
7702 if (temp[strlen(temp) - 1] == '\n')
7703 temp[strlen(temp) - 1] = '\0';
7707 if (strlen(temp) == 0)
7710 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7712 if (strlen(temp) > (strlen(DOMAIN)))
7714 strcpy(temp1, &temp[strlen(DOMAIN)]);
7716 strcpy(temp, temp1);
7720 strcpy(DomainNames[Count], temp);
7721 StringTrim(DomainNames[Count]);
7730 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7731 "configuration error in winad.cfg");
7738 int email_isvalid(const char *address) {
7740 const char *c, *domain;
7741 static char *rfc822_specials = "()<>@,;:\\\"[]";
7743 if(address[strlen(address) - 1] == '.')
7746 /* first we validate the name portion (name@domain) */
7747 for (c = address; *c; c++) {
7748 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7753 if (*c == '\\' && (*++c == ' '))
7755 if (*c <= ' ' || *c >= 127)
7770 if (*c <= ' ' || *c >= 127)
7772 if (strchr(rfc822_specials, *c))
7776 if (c == address || *(c - 1) == '.')
7779 /* next we validate the domain portion (name@domain) */
7780 if (!*(domain = ++c)) return 0;
7783 if (c == domain || *(c - 1) == '.')
7787 if (*c <= ' ' || *c >= 127)
7789 if (strchr(rfc822_specials, *c))
7793 return (count >= 1);
7796 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7797 char **homeServerName)
7799 LK_ENTRY *group_base;
7800 LK_ENTRY *sub_group_base;
7804 int sub_group_count;
7806 char sub_filter[1024];
7807 char search_path[1024];
7809 char *attr_array[3];
7811 int homeMDB_count = -1;
7815 int rangeStep = 1500;
7817 int rangeHigh = rangeLow + (rangeStep - 1);
7820 /* Grumble..... microsoft not making it searchable from the root *grr* */
7822 memset(filter, '\0', sizeof(filter));
7823 memset(search_path, '\0', sizeof(search_path));
7825 sprintf(filter, "(objectClass=msExchMDB)");
7826 sprintf(search_path, "CN=Configuration,%s", dn_path);
7827 attr_array[0] = "distinguishedName";
7828 attr_array[1] = NULL;
7833 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7834 &group_base, &group_count,
7835 LDAP_SCOPE_SUBTREE)) != 0)
7837 com_err(whoami, 0, "Unable to find msExchMDB %s",
7838 ldap_err2string(rc));
7847 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
7848 ((s = strstr(gPtr->dn, "Recovery")) != (char *) NULL))
7855 * Due to limits in active directory we need to use the LDAP
7856 * range semantics to query and return all the values in
7857 * large lists, we will stop increasing the range when
7858 * the result count is 0.
7866 memset(sub_filter, '\0', sizeof(sub_filter));
7867 memset(range, '\0', sizeof(range));
7868 sprintf(sub_filter, "(objectClass=msExchMDB)");
7871 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
7873 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
7875 attr_array[0] = range;
7876 attr_array[1] = NULL;
7878 sub_group_base = NULL;
7879 sub_group_count = 0;
7881 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
7882 attr_array, &sub_group_base,
7884 LDAP_SCOPE_SUBTREE)) != 0)
7886 com_err(whoami, 0, "Unable to find homeMDBBL %s",
7887 ldap_err2string(rc));
7891 if(!sub_group_count)
7897 rangeHigh = rangeLow + (rangeStep - 1);
7904 mdbbl_count += sub_group_count;
7905 rangeLow = rangeHigh + 1;
7906 rangeHigh = rangeLow + (rangeStep - 1);
7909 /* First time through, need to initialize or update the least used */
7911 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
7914 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
7916 homeMDB_count = mdbbl_count;
7917 *homeMDB = strdup(gPtr->dn);
7921 linklist_free(sub_group_base);
7925 linklist_free(group_base);
7928 * Ok found the server least allocated need to now query to get its
7929 * msExchHomeServerName so we can set it as a user attribute
7932 attr_array[0] = "legacyExchangeDN";
7933 attr_array[1] = NULL;
7938 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
7939 attr_array, &group_base,
7941 LDAP_SCOPE_SUBTREE)) != 0)
7943 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
7944 ldap_err2string(rc));
7950 *homeServerName = strdup(group_base->value);
7951 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
7957 linklist_free(group_base);
7962 char *lowercase(char *s)
7966 for (p = s; *p; p++)
7974 char *uppercase(char *s)
7978 for (p = s; *p; p++)
7986 int save_query_info(int argc, char **argv, void *hint)
7989 char **nargv = hint;
7991 for(i = 0; i < argc; i++)
7992 nargv[i] = strdup(argv[i]);