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;
2355 char search_filter[1024];
2357 if(UseGroupUniversal)
2358 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2360 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2362 if (!check_string(before_group_name))
2365 "Unable to process invalid LDAP list name %s",
2367 return(AD_INVALID_NAME);
2370 if (!check_string(after_group_name))
2373 "Unable to process invalid LDAP list name %s", after_group_name);
2374 return(AD_INVALID_NAME);
2384 sprintf(search_filter, "(&(objectClass=user)(cn=%s))",
2386 attr_array[0] = "cn";
2387 attr_array[1] = NULL;
2389 if ((rc = linklist_build(ldap_handle, dn_path, search_filter,
2390 attr_array, &group_base, &group_count,
2391 LDAP_SCOPE_SUBTREE)) != 0)
2393 com_err(whoami, 0, "Unable to process group %s : %s",
2394 after_group_name, ldap_err2string(rc));
2400 com_err(whoami, 0, "Object already exists with name %s",
2405 linklist_free(group_base);
2414 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
2415 before_group_membership,
2416 MoiraId, "distinguishedName", &group_base,
2417 &group_count, filter))
2420 if (group_count == 0)
2422 return(AD_NO_GROUPS_FOUND);
2425 if (group_count != 1)
2427 com_err(whoami, 0, "Unable to process multiple groups with "
2428 "MoiraId = %s exist in the AD", MoiraId);
2429 return(AD_MULTIPLE_GROUPS_FOUND);
2432 strcpy(old_dn, group_base->value);
2434 linklist_free(group_base);
2437 attr_array[0] = "sAMAccountName";
2438 attr_array[1] = NULL;
2440 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2441 &group_base, &group_count,
2442 LDAP_SCOPE_SUBTREE)) != 0)
2444 com_err(whoami, 0, "Unable to get list %s dn : %s",
2445 after_group_name, ldap_err2string(rc));
2449 if (group_count != 1)
2452 "Unable to get sAMAccountName for group %s",
2454 return(AD_LDAP_FAILURE);
2457 strcpy(sam_name, group_base->value);
2458 linklist_free(group_base);
2462 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2463 sprintf(new_dn, "cn=%s", after_group_name);
2464 sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain));
2465 sprintf(contact_mail, "%s@mit.edu", after_group_name);
2466 sprintf(proxy_address, "SMTP:%s@%s", after_group_name,
2467 lowercase(ldap_domain));
2468 sprintf(mail_nickname, "%s", after_group_name);
2470 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
2471 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2473 com_err(whoami, 0, "Unable to rename list from %s to %s : %s",
2474 before_group_name, after_group_name, ldap_err2string(rc));
2478 name_v[0] = after_group_name;
2480 if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)],
2481 group_suffix, strlen(group_suffix)))
2483 sprintf(sam_name, "%s%s", after_group_name, group_suffix);
2488 "Unable to rename list from %s to %s : sAMAccountName not found",
2489 before_group_name, after_group_name);
2493 samAccountName_v[0] = sam_name;
2495 if (after_security_flag)
2496 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2498 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2499 groupTypeControl_v[0] = groupTypeControlStr;
2500 mitMoiraId_v[0] = MoiraId;
2502 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
2503 rc = attribute_update(ldap_handle, new_dn, after_desc, "description",
2506 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2507 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2508 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2509 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
2513 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2515 mail_nickname_v[0] = mail_nickname;
2516 proxy_address_v[0] = proxy_address;
2518 report_to_originator_v[0] = "TRUE";
2520 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2521 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2522 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2523 ADD_ATTR("reportToOriginator", report_to_originator_v,
2528 mail_nickname_v[0] = NULL;
2529 proxy_address_v[0] = NULL;
2531 legacy_exchange_dn_v[0] = NULL;
2532 address_book_v[0] = NULL;
2533 report_to_originator_v[0] = NULL;
2535 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2536 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2537 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2538 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2539 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2540 ADD_ATTR("reportToOriginator", report_to_originator_v,
2546 if(atoi(maillist) && email_isvalid(contact_mail))
2548 mail_v[0] = contact_mail;
2549 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2555 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2558 "Unable to modify list data for %s after renaming: %s",
2559 after_group_name, ldap_err2string(rc));
2562 for (i = 0; i < n; i++)
2568 int group_create(int ac, char **av, void *ptr)
2573 char new_group_name[256];
2574 char sam_group_name[256];
2575 char cn_group_name[256];
2577 char contact_mail[256];
2578 char mail_nickname[256];
2579 char proxy_address[256];
2580 char address_book[256];
2581 char *cn_v[] = {NULL, NULL};
2582 char *objectClass_v[] = {"top", "group", NULL};
2584 char *samAccountName_v[] = {NULL, NULL};
2585 char *altSecurityIdentities_v[] = {NULL, NULL};
2586 char *member_v[] = {NULL, NULL};
2587 char *name_v[] = {NULL, NULL};
2588 char *desc_v[] = {NULL, NULL};
2589 char *info_v[] = {NULL, NULL};
2590 char *mitMoiraId_v[] = {NULL, NULL};
2591 char *groupTypeControl_v[] = {NULL, NULL};
2592 char *mail_v[] = {NULL, NULL};
2593 char *proxy_address_v[] = {NULL, NULL};
2594 char *mail_nickname_v[] = {NULL, NULL};
2595 char *report_to_originator_v[] = {NULL, NULL};
2596 char *address_book_v[] = {NULL, NULL};
2597 char *legacy_exchange_dn_v[] = {NULL, NULL};
2598 char groupTypeControlStr[80];
2599 char group_membership[1];
2602 u_int groupTypeControl;
2606 int MailDisabled = 0;
2608 LK_ENTRY *group_base;
2611 char *attr_array[3];
2615 if(UseGroupUniversal)
2616 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2618 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2620 if (!check_string(av[L_NAME]))
2622 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2624 return(AD_INVALID_NAME);
2627 updateGroup = (int)call_args[4];
2628 memset(group_ou, 0, sizeof(group_ou));
2629 memset(group_membership, 0, sizeof(group_membership));
2632 get_group_membership(group_membership, group_ou, &security_flag, av);
2634 strcpy(new_group_name, av[L_NAME]);
2635 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2636 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2637 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2638 sprintf(mail_nickname, "%s", av[L_NAME]);
2641 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2643 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2647 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2648 groupTypeControl_v[0] = groupTypeControlStr;
2650 strcpy(cn_group_name, av[L_NAME]);
2652 samAccountName_v[0] = sam_group_name;
2653 name_v[0] = new_group_name;
2654 cn_v[0] = new_group_name;
2657 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2658 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2659 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2660 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2661 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2665 if(atoi(av[L_MAILLIST]))
2670 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2671 attr_array[0] = "cn";
2672 attr_array[1] = NULL;
2674 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2675 filter, attr_array, &group_base,
2677 LDAP_SCOPE_SUBTREE)) != 0)
2679 com_err(whoami, 0, "Unable to process group %s : %s",
2680 av[L_NAME], ldap_err2string(rc));
2686 com_err(whoami, 0, "Object already exists with name %s",
2691 linklist_free(group_base);
2696 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2698 mail_nickname_v[0] = mail_nickname;
2699 report_to_originator_v[0] = "TRUE";
2701 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2702 ADD_ATTR("reportToOriginator", report_to_originator_v,
2708 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2710 mail_v[0] = contact_mail;
2711 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2715 if (strlen(av[L_DESC]) != 0)
2717 desc_v[0] = av[L_DESC];
2718 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2721 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2723 if (strlen(av[L_ACE_NAME]) != 0)
2725 sprintf(info, "The Administrator of this list is: %s",
2728 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2731 if (strlen(call_args[5]) != 0)
2733 mitMoiraId_v[0] = call_args[5];
2734 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2739 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2741 for (i = 0; i < n; i++)
2744 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2746 com_err(whoami, 0, "Unable to create list %s in AD : %s",
2747 av[L_NAME], ldap_err2string(rc));
2753 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2755 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2756 "description", av[L_NAME]);
2757 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2758 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2762 if (strlen(call_args[5]) != 0)
2764 mitMoiraId_v[0] = call_args[5];
2765 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2768 if (!(atoi(av[L_ACTIVE])))
2771 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2776 if(atoi(av[L_MAILLIST]))
2781 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2782 attr_array[0] = "cn";
2783 attr_array[1] = NULL;
2785 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2786 filter, attr_array, &group_base,
2788 LDAP_SCOPE_SUBTREE)) != 0)
2790 com_err(whoami, 0, "Unable to process group %s : %s",
2791 av[L_NAME], ldap_err2string(rc));
2797 com_err(whoami, 0, "Object already exists with name %s",
2802 linklist_free(group_base);
2807 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2809 mail_nickname_v[0] = mail_nickname;
2810 report_to_originator_v[0] = "TRUE";
2812 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2813 ADD_ATTR("reportToOriginator", report_to_originator_v,
2819 mail_nickname_v[0] = NULL;
2820 proxy_address_v[0] = NULL;
2821 legacy_exchange_dn_v[0] = NULL;
2822 address_book_v[0] = NULL;
2823 report_to_originator_v[0] = NULL;
2825 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2826 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2827 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2828 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2830 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2831 ADD_ATTR("reportToOriginator", report_to_originator_v,
2837 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2839 mail_v[0] = contact_mail;
2840 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2845 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2854 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2856 for (i = 0; i < n; i++)
2859 if (rc != LDAP_SUCCESS)
2861 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2862 av[L_NAME], ldap_err2string(rc));
2869 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2870 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2872 return(LDAP_SUCCESS);
2875 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2876 char *TargetGroupName, int HiddenGroup,
2877 char *AceType, char *AceName)
2879 char filter_exp[1024];
2880 char *attr_array[5];
2881 char search_path[512];
2883 char TemplateDn[512];
2884 char TemplateSamName[128];
2886 char TargetSamName[128];
2887 char AceSamAccountName[128];
2889 unsigned char AceSid[128];
2890 unsigned char UserTemplateSid[128];
2891 char acBERBuf[N_SD_BER_BYTES];
2892 char GroupSecurityTemplate[256];
2893 char hide_addres_lists[256];
2894 char address_book[256];
2895 char *hide_address_lists_v[] = {NULL, NULL};
2896 char *address_book_v[] = {NULL, NULL};
2898 int UserTemplateSidCount;
2905 int array_count = 0;
2907 LK_ENTRY *group_base;
2908 LDAP_BERVAL **ppsValues;
2909 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2910 { N_SD_BER_BYTES, acBERBuf },
2913 LDAPControl *apsServerControls[] = {&sControl, NULL};
2916 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
2917 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
2918 BEREncodeSecurityBits(dwInfo, acBERBuf);
2920 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
2921 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
2922 attr_array[0] = "sAMAccountName";
2923 attr_array[1] = NULL;
2927 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2928 &group_base, &group_count,
2929 LDAP_SCOPE_SUBTREE) != 0))
2932 if (group_count != 1)
2934 linklist_free(group_base);
2938 strcpy(TargetDn, group_base->dn);
2939 strcpy(TargetSamName, group_base->value);
2940 linklist_free(group_base);
2944 UserTemplateSidCount = 0;
2945 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2946 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2947 memset(AceSid, '\0', sizeof(AceSid));
2952 if (strlen(AceName) != 0)
2954 if (!strcmp(AceType, "LIST"))
2956 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
2957 strcpy(root_ou, group_ou_root);
2959 else if (!strcmp(AceType, "USER"))
2961 sprintf(AceSamAccountName, "%s", AceName);
2962 strcpy(root_ou, user_ou);
2965 if (strlen(AceSamAccountName) != 0)
2967 sprintf(search_path, "%s", dn_path);
2968 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2969 attr_array[0] = "objectSid";
2970 attr_array[1] = NULL;
2974 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2975 attr_array, &group_base, &group_count,
2976 LDAP_SCOPE_SUBTREE) != 0))
2978 if (group_count == 1)
2980 strcpy(AceDn, group_base->dn);
2981 AceSidCount = group_base->length;
2982 memcpy(AceSid, group_base->value, AceSidCount);
2984 linklist_free(group_base);
2990 if (AceSidCount == 0)
2992 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
2993 "have an AD SID.", TargetGroupName, AceName, AceType);
2994 com_err(whoami, 0, " Non-admin security group template will be used.");
2998 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2999 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
3000 attr_array[0] = "objectSid";
3001 attr_array[1] = NULL;
3006 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3007 attr_array, &group_base, &group_count,
3008 LDAP_SCOPE_SUBTREE) != 0))
3011 if ((rc != 0) || (group_count != 1))
3013 com_err(whoami, 0, "Unable to process user security template: %s",
3019 UserTemplateSidCount = group_base->length;
3020 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3022 linklist_free(group_base);
3029 if (AceSidCount == 0)
3031 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3032 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3036 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3037 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3042 if (AceSidCount == 0)
3044 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3045 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3049 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
3050 sprintf(filter_exp, "(sAMAccountName=%s)",
3051 NOT_HIDDEN_GROUP_WITH_ADMIN);
3055 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3056 attr_array[0] = "sAMAccountName";
3057 attr_array[1] = NULL;
3061 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3062 &group_base, &group_count,
3063 LDAP_SCOPE_SUBTREE) != 0))
3066 if (group_count != 1)
3068 linklist_free(group_base);
3069 com_err(whoami, 0, "Unable to process group security template: %s - "
3070 "security not set", GroupSecurityTemplate);
3074 strcpy(TemplateDn, group_base->dn);
3075 strcpy(TemplateSamName, group_base->value);
3076 linklist_free(group_base);
3080 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3081 rc = ldap_search_ext_s(ldap_handle,
3093 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3095 com_err(whoami, 0, "Unable to find group security template: %s - "
3096 "security not set", GroupSecurityTemplate);
3100 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3102 if (ppsValues == NULL)
3104 com_err(whoami, 0, "Unable to find group security descriptor for group "
3105 "%s - security not set", GroupSecurityTemplate);
3109 if (AceSidCount != 0)
3111 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3114 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3116 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3117 UserTemplateSidCount))
3119 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3127 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3128 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3134 hide_address_lists_v[0] = "TRUE";
3135 address_book_v[0] = NULL;
3136 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3138 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3140 hide_address_lists_v[0] = NULL;
3141 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3148 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3150 for (i = 0; i < n; i++)
3153 ldap_value_free_len(ppsValues);
3154 ldap_msgfree(psMsg);
3156 if (rc != LDAP_SUCCESS)
3158 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3159 TargetGroupName, ldap_err2string(rc));
3161 if (AceSidCount != 0)
3164 "Trying to set security for group %s without admin.",
3167 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3168 HiddenGroup, "", ""))
3170 com_err(whoami, 0, "Unable to set security for group %s.",
3181 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3182 char *group_membership, char *MoiraId)
3184 LK_ENTRY *group_base;
3190 if (!check_string(group_name))
3193 "Unable to process invalid LDAP list name %s", group_name);
3194 return(AD_INVALID_NAME);
3197 memset(filter, '\0', sizeof(filter));
3200 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3202 if (rc = ad_get_group(ldap_handle, temp, group_name,
3203 group_membership, MoiraId,
3204 "distinguishedName", &group_base,
3205 &group_count, filter))
3208 if (group_count == 1)
3210 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
3212 linklist_free(group_base);
3213 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3214 group_name, ldap_err2string(rc));
3217 linklist_free(group_base);
3221 linklist_free(group_base);
3222 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
3223 return(AD_NO_GROUPS_FOUND);
3229 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3235 return(N_SD_BER_BYTES);
3238 int process_lists(int ac, char **av, void *ptr)
3243 char group_membership[2];
3249 memset(group_ou, '\0', sizeof(group_ou));
3250 memset(group_membership, '\0', sizeof(group_membership));
3251 get_group_membership(group_membership, group_ou, &security_flag, av);
3252 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
3253 group_ou, group_membership, call_args[2],
3254 (char *)call_args[3], "");
3258 int member_list_build(int ac, char **av, void *ptr)
3266 strcpy(temp, av[ACE_NAME]);
3268 if (!check_string(temp))
3271 if (!strcmp(av[ACE_TYPE], "USER"))
3273 if (!((int)call_args[3] & MOIRA_USERS))
3276 else if (!strcmp(av[ACE_TYPE], "STRING"))
3280 if((s = strchr(temp, '@')) == (char *) NULL)
3282 strcat(temp, "@mit.edu");
3285 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3287 s = strrchr(temp, '.');
3289 strcat(s, ".mit.edu");
3293 if (!((int)call_args[3] & MOIRA_STRINGS))
3296 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3300 else if (!strcmp(av[ACE_TYPE], "LIST"))
3302 if (!((int)call_args[3] & MOIRA_LISTS))
3305 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3307 if (!((int)call_args[3] & MOIRA_KERBEROS))
3310 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3318 linklist = member_base;
3322 if (!strcasecmp(temp, linklist->member))
3325 linklist = linklist->next;
3328 linklist = calloc(1, sizeof(LK_ENTRY));
3330 linklist->dn = NULL;
3331 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3332 strcpy(linklist->list, call_args[2]);
3333 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3334 strcpy(linklist->type, av[ACE_TYPE]);
3335 linklist->member = calloc(1, strlen(temp) + 1);
3336 strcpy(linklist->member, temp);
3337 linklist->next = member_base;
3338 member_base = linklist;
3343 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3344 char *group_ou, char *group_membership, char *user_name,
3345 char *UserOu, char *MoiraId)
3347 char distinguished_name[1024];
3351 char *attr_array[3];
3356 LK_ENTRY *group_base;
3360 if (!check_string(group_name))
3361 return(AD_INVALID_NAME);
3363 memset(filter, '\0', sizeof(filter));
3367 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3368 group_membership, MoiraId,
3369 "distinguishedName", &group_base,
3370 &group_count, filter))
3373 if (group_count != 1)
3375 com_err(whoami, 0, "Unable to find list %s in AD",
3377 linklist_free(group_base);
3383 strcpy(distinguished_name, group_base->value);
3384 linklist_free(group_base);
3388 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3390 modvalues[0] = temp;
3391 modvalues[1] = NULL;
3394 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3396 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3398 for (i = 0; i < n; i++)
3401 if (rc == LDAP_UNWILLING_TO_PERFORM)
3404 if (rc != LDAP_SUCCESS)
3406 com_err(whoami, 0, "Unable to modify list %s members : %s",
3407 group_name, ldap_err2string(rc));
3411 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3415 if(!strcmp(UserOu, contact_ou) &&
3416 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3418 memset(temp, '\0', sizeof(temp));
3419 strcpy(temp, user_name);
3420 s = strchr(temp, '@');
3423 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3425 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3426 &group_base, &group_count,
3427 LDAP_SCOPE_SUBTREE) != 0))
3433 linklist_free(group_base);
3438 sprintf(filter, "(distinguishedName=%s)", temp);
3439 attr_array[0] = "memberOf";
3440 attr_array[1] = NULL;
3442 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3443 &group_base, &group_count,
3444 LDAP_SCOPE_SUBTREE) != 0))
3450 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3452 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3462 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3463 char *group_ou, char *group_membership, char *user_name,
3464 char *UserOu, char *MoiraId)
3466 char distinguished_name[1024];
3474 LK_ENTRY *group_base;
3477 if (!check_string(group_name))
3478 return(AD_INVALID_NAME);
3481 memset(filter, '\0', sizeof(filter));
3485 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3486 group_membership, MoiraId,
3487 "distinguishedName", &group_base,
3488 &group_count, filter))
3491 if (group_count != 1)
3493 linklist_free(group_base);
3496 com_err(whoami, 0, "Unable to find list %s in AD",
3498 return(AD_MULTIPLE_GROUPS_FOUND);
3501 strcpy(distinguished_name, group_base->value);
3502 linklist_free(group_base);
3506 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3507 modvalues[0] = temp;
3508 modvalues[1] = NULL;
3511 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3513 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3515 if (rc == LDAP_ALREADY_EXISTS)
3518 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3520 if (rc == LDAP_UNWILLING_TO_PERFORM)
3524 for (i = 0; i < n; i++)
3527 if (rc != LDAP_SUCCESS)
3529 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3530 user_name, group_name, ldap_err2string(rc));
3536 int contact_remove_email(LDAP *ld, char *bind_path,
3537 LK_ENTRY **linklist_base, int linklist_current)
3541 char *mail_v[] = {NULL, NULL};
3549 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3550 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3551 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3552 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3555 gPtr = (*linklist_base);
3558 rc = ldap_modify_s(ld, gPtr->dn, mods);
3560 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3562 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3563 gPtr->dn, ldap_err2string(rc));
3570 for (i = 0; i < n; i++)
3576 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3579 LK_ENTRY *group_base;
3582 char cn_user_name[256];
3583 char contact_name[256];
3584 char mail_nickname[256];
3585 char proxy_address_internal[256];
3586 char proxy_address_external[256];
3587 char target_address[256];
3588 char internal_contact_name[256];
3591 char mit_address_book[256];
3592 char default_address_book[256];
3593 char contact_address_book[256];
3594 char *email_v[] = {NULL, NULL};
3595 char *cn_v[] = {NULL, NULL};
3596 char *contact_v[] = {NULL, NULL};
3597 char *mail_nickname_v[] = {NULL, NULL};
3598 char *proxy_address_internal_v[] = {NULL, NULL};
3599 char *proxy_address_external_v[] = {NULL, NULL};
3600 char *target_address_v[] = {NULL, NULL};
3601 char *mit_address_book_v[] = {NULL, NULL};
3602 char *default_address_book_v[] = {NULL, NULL};
3603 char *contact_address_book_v[] = {NULL, NULL};
3604 char *hide_address_lists_v[] = {NULL, NULL};
3605 char *attr_array[3];
3607 char *objectClass_v[] = {"top", "person",
3608 "organizationalPerson",
3610 char *name_v[] = {NULL, NULL};
3611 char *desc_v[] = {NULL, NULL};
3617 if (!check_string(user))
3619 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3620 return(AD_INVALID_NAME);
3624 strcpy(contact_name, mail);
3625 strcpy(internal_contact_name, mail);
3627 if((s = strchr(internal_contact_name, '@')) != NULL) {
3631 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
3632 sprintf(target_address, "SMTP:%s", contact_name);
3633 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3634 sprintf(mail_nickname, "%s", internal_contact_name);
3636 cn_v[0] = cn_user_name;
3637 contact_v[0] = contact_name;
3639 desc_v[0] = "Auto account created by Moira";
3641 proxy_address_internal_v[0] = proxy_address_internal;
3642 proxy_address_external_v[0] = proxy_address_external;
3643 mail_nickname_v[0] = mail_nickname;
3644 target_address_v[0] = target_address;
3645 mit_address_book_v[0] = mit_address_book;
3646 default_address_book_v[0] = default_address_book;
3647 contact_address_book_v[0] = contact_address_book;
3648 strcpy(new_dn, cn_user_name);
3651 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3652 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3653 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3654 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3655 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3659 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3664 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3665 attr_array[0] = "cn";
3666 attr_array[1] = NULL;
3668 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3669 &group_base, &group_count,
3670 LDAP_SCOPE_SUBTREE)) != 0)
3672 com_err(whoami, 0, "Unable to process contact %s : %s",
3673 user, ldap_err2string(rc));
3679 com_err(whoami, 0, "Object already exists with name %s",
3684 linklist_free(group_base);
3688 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3689 attr_array[0] = "cn";
3690 attr_array[1] = NULL;
3692 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3693 &group_base, &group_count,
3694 LDAP_SCOPE_SUBTREE)) != 0)
3696 com_err(whoami, 0, "Unable to process contact %s : %s",
3697 user, ldap_err2string(rc));
3703 com_err(whoami, 0, "Object already exists with name %s",
3708 linklist_free(group_base);
3712 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3713 attr_array[0] = "cn";
3714 attr_array[1] = NULL;
3716 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3717 &group_base, &group_count,
3718 LDAP_SCOPE_SUBTREE)) != 0)
3720 com_err(whoami, 0, "Unable to process contact %s : %s",
3721 user, ldap_err2string(rc));
3727 com_err(whoami, 0, "Object already exists with name %s",
3732 linklist_free(group_base);
3736 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3737 attr_array[0] = "cn";
3738 attr_array[1] = NULL;
3740 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3741 &group_base, &group_count,
3742 LDAP_SCOPE_SUBTREE)) != 0)
3744 com_err(whoami, 0, "Unable to process contact %s : %s",
3745 user, ldap_err2string(rc));
3751 com_err(whoami, 0, "Object already exists with name %s",
3756 linklist_free(group_base);
3760 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3761 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3762 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3763 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3765 hide_address_lists_v[0] = "TRUE";
3766 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3773 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3775 for (i = 0; i < n; i++)
3781 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS) &&
3782 !strcmp(group_ou, contact_ou) && email_isvalid(mail))
3786 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
3787 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
3788 ADD_ATTR("proxyAddresses", proxy_address_external_v,
3790 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
3792 hide_address_lists_v[0] = "TRUE";
3793 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3797 rc = ldap_modify_s(ld, new_dn, mods);
3801 com_err(whoami, 0, "Unable to update contact %s", mail);
3804 for (i = 0; i < n; i++)
3809 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3812 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3813 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3814 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3815 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3816 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3818 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3820 for (i = 0; i < n; i++)
3824 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3826 com_err(whoami, 0, "Unable to create contact %s : %s",
3827 user, ldap_err2string(rc));
3834 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3835 char *Uid, char *MitId, char *MoiraId, int State,
3836 char *WinHomeDir, char *WinProfileDir, char *first,
3837 char *middle, char *last)
3840 LK_ENTRY *group_base;
3842 char distinguished_name[512];
3843 char displayName[256];
3844 char *mitMoiraId_v[] = {NULL, NULL};
3845 char *uid_v[] = {NULL, NULL};
3846 char *mitid_v[] = {NULL, NULL};
3847 char *homedir_v[] = {NULL, NULL};
3848 char *winProfile_v[] = {NULL, NULL};
3849 char *drives_v[] = {NULL, NULL};
3850 char *userAccountControl_v[] = {NULL, NULL};
3851 char *alt_recipient_v[] = {NULL, NULL};
3852 char *hide_address_lists_v[] = {NULL, NULL};
3853 char *mail_v[] = {NULL, NULL};
3854 char userAccountControlStr[80];
3859 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
3860 UF_PASSWD_CANT_CHANGE;
3862 char *attr_array[3];
3865 char contact_mail[256];
3866 char filter_exp[1024];
3867 char search_path[512];
3868 char TemplateDn[512];
3869 char TemplateSamName[128];
3870 char alt_recipient[256];
3871 char acBERBuf[N_SD_BER_BYTES];
3872 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3873 { N_SD_BER_BYTES, acBERBuf },
3875 LDAPControl *apsServerControls[] = {&sControl, NULL};
3877 LDAP_BERVAL **ppsValues;
3881 char *homeServerName;
3883 char search_string[256];
3885 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3886 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3887 BEREncodeSecurityBits(dwInfo, acBERBuf);
3889 if (!check_string(user_name))
3891 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
3893 return(AD_INVALID_NAME);
3896 memset(contact_mail, '\0', sizeof(contact_mail));
3897 sprintf(contact_mail, "%s@mit.edu", user_name);
3898 memset(mail, '\0', sizeof(mail));
3899 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
3900 memset(alt_recipient, '\0', sizeof(alt_recipient));
3901 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
3903 sprintf(search_string, "@%s", uppercase(ldap_domain));
3907 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
3909 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
3916 memset(displayName, '\0', sizeof(displayName));
3918 if (strlen(MoiraId) != 0)
3920 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
3921 attr_array[0] = "cn";
3922 attr_array[1] = NULL;
3923 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3924 &group_base, &group_count,
3925 LDAP_SCOPE_SUBTREE)) != 0)
3927 com_err(whoami, 0, "Unable to process user %s : %s",
3928 user_name, ldap_err2string(rc));
3933 if (group_count != 1)
3935 linklist_free(group_base);
3938 sprintf(filter, "(sAMAccountName=%s)", user_name);
3939 attr_array[0] = "cn";
3940 attr_array[1] = NULL;
3941 sprintf(temp, "%s,%s", user_ou, dn_path);
3942 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
3943 &group_base, &group_count,
3944 LDAP_SCOPE_SUBTREE)) != 0)
3946 com_err(whoami, 0, "Unable to process user %s : %s",
3947 user_name, ldap_err2string(rc));
3952 if (group_count != 1)
3954 com_err(whoami, 0, "Unable to find user %s in AD",
3956 linklist_free(group_base);
3957 return(AD_NO_USER_FOUND);
3960 strcpy(distinguished_name, group_base->dn);
3962 linklist_free(group_base);
3965 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
3966 rc = attribute_update(ldap_handle, distinguished_name, MitId,
3967 "employeeID", user_name);
3969 rc = attribute_update(ldap_handle, distinguished_name, "none",
3970 "employeeID", user_name);
3973 strcat(displayName, first);
3976 if(strlen(middle)) {
3978 strcat(displayName, " ");
3980 strcat(displayName, middle);
3984 if(strlen(middle) || strlen(first))
3985 strcat(displayName, " ");
3987 strcat(displayName, last);
3990 if(strlen(displayName))
3991 rc = attribute_update(ldap_handle, distinguished_name, displayName,
3992 "displayName", user_name);
3994 rc = attribute_update(ldap_handle, distinguished_name, user_name,
3995 "displayName", user_name);
3998 rc = attribute_update(ldap_handle, distinguished_name, first,
3999 "givenName", user_name);
4001 rc = attribute_update(ldap_handle, distinguished_name, "",
4002 "givenName", user_name);
4004 if(strlen(middle) == 1)
4005 rc = attribute_update(ldap_handle, distinguished_name, middle,
4006 "initials", user_name);
4008 rc = attribute_update(ldap_handle, distinguished_name, "",
4009 "initials", user_name);
4012 rc = attribute_update(ldap_handle, distinguished_name, last,
4015 rc = attribute_update(ldap_handle, distinguished_name, "",
4018 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4020 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4021 "mitMoiraId", user_name);
4028 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4032 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4035 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4037 userAccountControl |= UF_ACCOUNTDISABLE;
4041 hide_address_lists_v[0] = "TRUE";
4042 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4050 hide_address_lists_v[0] = NULL;
4051 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4056 sprintf(userAccountControlStr, "%ld", userAccountControl);
4057 userAccountControl_v[0] = userAccountControlStr;
4058 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4062 if (rc = moira_connect())
4064 critical_alert("AD incremental",
4065 "Error contacting Moira server : %s",
4070 argv[0] = user_name;
4072 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4074 if(!strcmp(save_argv[1], "EXCHANGE") ||
4075 (strstr(save_argv[3], search_string) != NULL))
4077 alt_recipient_v[0] = NULL;
4078 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4080 argv[0] = exchange_acl;
4082 argv[2] = user_name;
4084 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4086 if ((rc) && (rc != MR_EXISTS))
4088 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4089 user_name, exchange_acl, error_message(rc));
4094 alt_recipient_v[0] = alt_recipient;
4095 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4097 argv[0] = exchange_acl;
4099 argv[2] = user_name;
4101 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4103 if ((rc) && (rc != MR_NO_MATCH))
4106 "Unable to remove user %s from %s: %s, %d",
4107 user_name, exchange_acl, error_message(rc), rc);
4113 alt_recipient_v[0] = alt_recipient;
4114 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4116 argv[0] = exchange_acl;
4118 argv[2] = user_name;
4120 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4122 if ((rc) && (rc != MR_NO_MATCH))
4125 "Unable to remove user %s from %s: %s, %d",
4126 user_name, exchange_acl, error_message(rc), rc);
4134 mail_v[0] = contact_mail;
4135 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4138 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4139 WinProfileDir, homedir_v, winProfile_v,
4140 drives_v, mods, LDAP_MOD_REPLACE, n);
4142 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4143 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4144 attr_array[0] = "sAMAccountName";
4145 attr_array[1] = NULL;
4149 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
4150 &group_base, &group_count,
4151 LDAP_SCOPE_SUBTREE) != 0))
4154 if (group_count != 1)
4156 com_err(whoami, 0, "Unable to process user security template: %s - "
4157 "security not set", "UserTemplate.u");
4161 strcpy(TemplateDn, group_base->dn);
4162 strcpy(TemplateSamName, group_base->value);
4163 linklist_free(group_base);
4167 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4168 filter_exp, NULL, 0, apsServerControls, NULL,
4171 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4173 com_err(whoami, 0, "Unable to find user security template: %s - "
4174 "security not set", "UserTemplate.u");
4178 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
4180 if (ppsValues == NULL)
4182 com_err(whoami, 0, "Unable to find user security template: %s - "
4183 "security not set", "UserTemplate.u");
4187 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4188 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4192 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4193 mods)) != LDAP_SUCCESS)
4195 OldUseSFU30 = UseSFU30;
4196 SwitchSFU(mods, &UseSFU30, n);
4197 if (OldUseSFU30 != UseSFU30)
4198 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4201 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4202 user_name, ldap_err2string(rc));
4206 for (i = 0; i < n; i++)
4212 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4220 char contact_mail[256];
4221 char proxy_address[256];
4222 char query_base_dn[256];
4224 char *userPrincipalName_v[] = {NULL, NULL};
4225 char *altSecurityIdentities_v[] = {NULL, NULL};
4226 char *name_v[] = {NULL, NULL};
4227 char *samAccountName_v[] = {NULL, NULL};
4228 char *mail_v[] = {NULL, NULL};
4229 char *mail_nickname_v[] = {NULL, NULL};
4230 char *proxy_address_v[] = {NULL, NULL};
4231 char *query_base_dn_v[] = {NULL, NULL};
4236 if (!check_string(before_user_name))
4239 "Unable to process invalid LDAP user name %s", before_user_name);
4240 return(AD_INVALID_NAME);
4243 if (!check_string(user_name))
4246 "Unable to process invalid LDAP user name %s", user_name);
4247 return(AD_INVALID_NAME);
4250 strcpy(user_name, user_name);
4251 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4252 sprintf(new_dn, "cn=%s", user_name);
4253 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4254 sprintf(contact_mail, "%s@mit.edu", user_name);
4255 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4257 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4258 NULL, NULL)) != LDAP_SUCCESS)
4260 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4261 before_user_name, user_name, ldap_err2string(rc));
4267 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4270 if(rc = ldap_delete_s(ldap_handle, temp))
4272 com_err(whoami, 0, "Unable to delete user contact for %s",
4276 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4278 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4282 name_v[0] = user_name;
4283 sprintf(upn, "%s@%s", user_name, ldap_domain);
4284 userPrincipalName_v[0] = upn;
4285 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4286 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4287 altSecurityIdentities_v[0] = temp;
4288 samAccountName_v[0] = user_name;
4290 mail_nickname_v[0] = user_name;
4291 proxy_address_v[0] = proxy_address;
4292 query_base_dn_v[0] = query_base_dn;
4295 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4296 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4297 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4298 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4302 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4303 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4304 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4305 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4309 mail_v[0] = contact_mail;
4310 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4315 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4317 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4320 "Unable to modify user data for %s after renaming : %s",
4321 user_name, ldap_err2string(rc));
4324 for (i = 0; i < n; i++)
4330 int user_create(int ac, char **av, void *ptr)
4334 char user_name[256];
4338 char contact_mail[256];
4339 char proxy_address[256];
4340 char mail_nickname[256];
4341 char query_base_dn[256];
4342 char displayName[256];
4343 char address_book[256];
4344 char alt_recipient[256];
4345 char *cn_v[] = {NULL, NULL};
4346 char *objectClass_v[] = {"top", "person",
4347 "organizationalPerson",
4350 char *samAccountName_v[] = {NULL, NULL};
4351 char *altSecurityIdentities_v[] = {NULL, NULL};
4352 char *mitMoiraId_v[] = {NULL, NULL};
4353 char *name_v[] = {NULL, NULL};
4354 char *desc_v[] = {NULL, NULL};
4355 char *userPrincipalName_v[] = {NULL, NULL};
4356 char *userAccountControl_v[] = {NULL, NULL};
4357 char *uid_v[] = {NULL, NULL};
4358 char *mitid_v[] = {NULL, NULL};
4359 char *homedir_v[] = {NULL, NULL};
4360 char *winProfile_v[] = {NULL, NULL};
4361 char *drives_v[] = {NULL, NULL};
4362 char *mail_v[] = {NULL, NULL};
4363 char *givenName_v[] = {NULL, NULL};
4364 char *sn_v[] = {NULL, NULL};
4365 char *initials_v[] = {NULL, NULL};
4366 char *displayName_v[] = {NULL, NULL};
4367 char *proxy_address_v[] = {NULL, NULL};
4368 char *mail_nickname_v[] = {NULL, NULL};
4369 char *query_base_dn_v[] = {NULL, NULL};
4370 char *address_book_v[] = {NULL, NULL};
4371 char *homeMDB_v[] = {NULL, NULL};
4372 char *homeServerName_v[] = {NULL, NULL};
4373 char *mdbUseDefaults_v[] = {NULL, NULL};
4374 char *mailbox_guid_v[] = {NULL, NULL};
4375 char *user_culture_v[] = {NULL, NULL};
4376 char *user_account_control_v[] = {NULL, NULL};
4377 char *msexch_version_v[] = {NULL, NULL};
4378 char *alt_recipient_v[] = {NULL, NULL};
4379 char *hide_address_lists_v[] = {NULL, NULL};
4380 char userAccountControlStr[80];
4382 char filter_exp[1024];
4383 char search_path[512];
4384 char *attr_array[3];
4385 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4386 UF_PASSWD_CANT_CHANGE;
4392 char WinHomeDir[1024];
4393 char WinProfileDir[1024];
4395 char *homeServerName;
4397 char acBERBuf[N_SD_BER_BYTES];
4398 LK_ENTRY *group_base;
4400 char TemplateDn[512];
4401 char TemplateSamName[128];
4402 LDAP_BERVAL **ppsValues;
4403 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4404 { N_SD_BER_BYTES, acBERBuf },
4406 LDAPControl *apsServerControls[] = {&sControl, NULL};
4410 char search_string[256];
4414 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4415 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4416 BEREncodeSecurityBits(dwInfo, acBERBuf);
4418 if (!check_string(av[U_NAME]))
4420 callback_rc = AD_INVALID_NAME;
4421 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4423 return(AD_INVALID_NAME);
4426 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4427 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4428 memset(displayName, '\0', sizeof(displayName));
4429 memset(query_base_dn, '\0', sizeof(query_base_dn));
4430 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4431 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4432 strcpy(user_name, av[U_NAME]);
4433 sprintf(upn, "%s@%s", user_name, ldap_domain);
4434 sprintf(sam_name, "%s", av[U_NAME]);
4436 if(strlen(av[U_FIRST])) {
4437 strcat(displayName, av[U_FIRST]);
4440 if(strlen(av[U_MIDDLE])) {
4441 if(strlen(av[U_FIRST]))
4442 strcat(displayName, " ");
4444 strcat(displayName, av[U_MIDDLE]);
4447 if(strlen(av[U_LAST])) {
4448 if(strlen(av[U_FIRST]) || strlen(av[U_LAST]))
4449 strcat(displayName, " ");
4451 strcat(displayName, av[U_LAST]);
4454 samAccountName_v[0] = sam_name;
4455 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4456 (atoi(av[U_STATE]) != US_REGISTERED))
4458 userAccountControl |= UF_ACCOUNTDISABLE;
4462 hide_address_lists_v[0] = "TRUE";
4463 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4468 sprintf(userAccountControlStr, "%ld", userAccountControl);
4469 userAccountControl_v[0] = userAccountControlStr;
4470 userPrincipalName_v[0] = upn;
4471 cn_v[0] = user_name;
4472 name_v[0] = user_name;
4473 desc_v[0] = "Auto account created by Moira";
4475 givenName_v[0] = av[U_FIRST];
4476 sn_v[0] = av[U_LAST];
4477 displayName_v[0] = displayName;
4478 mail_nickname_v[0] = user_name;
4480 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4481 altSecurityIdentities_v[0] = temp;
4482 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4483 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4484 sprintf(contact_mail, "%s@mit.edu", user_name);
4485 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4486 query_base_dn_v[0] = query_base_dn;
4487 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4489 sprintf(search_string, "@%s", uppercase(ldap_domain));
4494 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4497 com_err(whoami, 0, "Unable to create user contact %s",
4501 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4504 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4508 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4509 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4511 homeMDB_v[0] = homeMDB;
4512 homeServerName_v[0] = homeServerName;
4516 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4517 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4518 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
4519 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
4520 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
4521 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
4522 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
4526 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
4527 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4528 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
4529 mdbUseDefaults_v[0] = "TRUE";
4530 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
4531 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
4533 argv[0] = user_name;
4535 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4537 if(!strcmp(save_argv[1], "EXCHANGE") ||
4538 (strstr(save_argv[3], search_string) != NULL))
4540 argv[0] = exchange_acl;
4542 argv[2] = user_name;
4544 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4546 if ((rc) && (rc != MR_EXISTS))
4548 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4549 user_name, exchange_acl, error_message(rc));
4554 alt_recipient_v[0] = alt_recipient;
4555 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4560 alt_recipient_v[0] = alt_recipient;
4561 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4563 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
4568 mail_v[0] = contact_mail;
4569 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
4572 if(strlen(av[U_FIRST])) {
4573 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
4576 if(strlen(av[U_LAST])) {
4577 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
4580 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
4581 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
4583 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4586 if (strlen(av[U_MIDDLE]) == 1) {
4587 initials_v[0] = av[U_MIDDLE];
4588 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
4591 if (strlen(call_args[2]) != 0)
4593 mitMoiraId_v[0] = call_args[2];
4594 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
4597 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
4599 if (strlen(av[U_UID]) != 0)
4601 uid_v[0] = av[U_UID];
4602 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
4606 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
4610 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
4614 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
4615 mitid_v[0] = av[U_MITID];
4617 mitid_v[0] = "none";
4619 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
4621 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
4622 WinProfileDir, homedir_v, winProfile_v,
4623 drives_v, mods, LDAP_MOD_ADD, n);
4625 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4626 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
4627 attr_array[0] = "sAMAccountName";
4628 attr_array[1] = NULL;
4632 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
4633 attr_array, &group_base, &group_count,
4634 LDAP_SCOPE_SUBTREE) != 0))
4637 if (group_count != 1)
4639 com_err(whoami, 0, "Unable to process user security template: %s - "
4640 "security not set", "UserTemplate.u");
4644 strcpy(TemplateDn, group_base->dn);
4645 strcpy(TemplateSamName, group_base->value);
4646 linklist_free(group_base);
4650 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE,
4651 filter_exp, NULL, 0, apsServerControls, NULL,
4654 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
4656 com_err(whoami, 0, "Unable to find user security template: %s - "
4657 "security not set", "UserTemplate.u");
4661 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
4662 "ntSecurityDescriptor");
4663 if (ppsValues == NULL)
4665 com_err(whoami, 0, "Unable to find user security template: %s - "
4666 "security not set", "UserTemplate.u");
4670 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4671 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4675 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4677 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4679 OldUseSFU30 = UseSFU30;
4680 SwitchSFU(mods, &UseSFU30, n);
4681 if (OldUseSFU30 != UseSFU30)
4682 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4685 for (i = 0; i < n; i++)
4688 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4690 com_err(whoami, 0, "Unable to create user %s : %s",
4691 user_name, ldap_err2string(rc));
4696 if ((rc == LDAP_SUCCESS) && (SetPassword))
4698 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4700 ad_kdc_disconnect();
4701 if (!ad_server_connect(default_server, ldap_domain))
4703 com_err(whoami, 0, "Unable to set password for user %s : %s",
4705 "cannot get changepw ticket from windows domain");
4709 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4711 com_err(whoami, 0, "Unable to set password for user %s "
4712 ": %ld", user_name, rc);
4721 int user_change_status(LDAP *ldap_handle, char *dn_path,
4722 char *user_name, char *MoiraId,
4726 char *attr_array[3];
4728 char distinguished_name[1024];
4730 char *mitMoiraId_v[] = {NULL, NULL};
4732 LK_ENTRY *group_base;
4739 if (!check_string(user_name))
4741 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4743 return(AD_INVALID_NAME);
4749 if (strlen(MoiraId) != 0)
4751 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4752 attr_array[0] = "UserAccountControl";
4753 attr_array[1] = NULL;
4754 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4755 &group_base, &group_count,
4756 LDAP_SCOPE_SUBTREE)) != 0)
4758 com_err(whoami, 0, "Unable to process user %s : %s",
4759 user_name, ldap_err2string(rc));
4764 if (group_count != 1)
4766 linklist_free(group_base);
4769 sprintf(filter, "(sAMAccountName=%s)", user_name);
4770 attr_array[0] = "UserAccountControl";
4771 attr_array[1] = NULL;
4772 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4773 &group_base, &group_count,
4774 LDAP_SCOPE_SUBTREE)) != 0)
4776 com_err(whoami, 0, "Unable to process user %s : %s",
4777 user_name, ldap_err2string(rc));
4782 if (group_count != 1)
4784 linklist_free(group_base);
4785 com_err(whoami, 0, "Unable to find user %s in AD",
4787 return(LDAP_NO_SUCH_OBJECT);
4790 strcpy(distinguished_name, group_base->dn);
4791 ulongValue = atoi((*group_base).value);
4793 if (operation == MEMBER_DEACTIVATE)
4794 ulongValue |= UF_ACCOUNTDISABLE;
4796 ulongValue &= ~UF_ACCOUNTDISABLE;
4798 sprintf(temp, "%ld", ulongValue);
4800 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
4801 temp, &modvalues, REPLACE)) == 1)
4804 linklist_free(group_base);
4808 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
4810 if (strlen(MoiraId) != 0)
4812 mitMoiraId_v[0] = MoiraId;
4813 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
4817 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4819 for (i = 0; i < n; i++)
4822 free_values(modvalues);
4824 if (rc != LDAP_SUCCESS)
4826 com_err(whoami, 0, "Unable to change status of user %s : %s",
4827 user_name, ldap_err2string(rc));
4834 int user_delete(LDAP *ldap_handle, char *dn_path,
4835 char *u_name, char *MoiraId)
4838 char *attr_array[3];
4839 char distinguished_name[1024];
4840 char user_name[512];
4841 LK_ENTRY *group_base;
4846 if (!check_string(u_name))
4847 return(AD_INVALID_NAME);
4849 strcpy(user_name, u_name);
4853 if (strlen(MoiraId) != 0)
4855 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4856 attr_array[0] = "name";
4857 attr_array[1] = NULL;
4858 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4859 &group_base, &group_count,
4860 LDAP_SCOPE_SUBTREE)) != 0)
4862 com_err(whoami, 0, "Unable to process user %s : %s",
4863 user_name, ldap_err2string(rc));
4868 if (group_count != 1)
4870 linklist_free(group_base);
4873 sprintf(filter, "(sAMAccountName=%s)", user_name);
4874 attr_array[0] = "name";
4875 attr_array[1] = NULL;
4876 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4877 &group_base, &group_count,
4878 LDAP_SCOPE_SUBTREE)) != 0)
4880 com_err(whoami, 0, "Unable to process user %s : %s",
4881 user_name, ldap_err2string(rc));
4886 if (group_count != 1)
4888 com_err(whoami, 0, "Unable to find user %s in AD",
4893 strcpy(distinguished_name, group_base->dn);
4895 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
4897 com_err(whoami, 0, "Unable to process user %s : %s",
4898 user_name, ldap_err2string(rc));
4901 /* Need to add code to delete mit.edu contact */
4905 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
4907 if(rc = ldap_delete_s(ldap_handle, temp))
4909 com_err(whoami, 0, "Unable to delete user contact for %s",
4915 linklist_free(group_base);
4920 void linklist_free(LK_ENTRY *linklist_base)
4922 LK_ENTRY *linklist_previous;
4924 while (linklist_base != NULL)
4926 if (linklist_base->dn != NULL)
4927 free(linklist_base->dn);
4929 if (linklist_base->attribute != NULL)
4930 free(linklist_base->attribute);
4932 if (linklist_base->value != NULL)
4933 free(linklist_base->value);
4935 if (linklist_base->member != NULL)
4936 free(linklist_base->member);
4938 if (linklist_base->type != NULL)
4939 free(linklist_base->type);
4941 if (linklist_base->list != NULL)
4942 free(linklist_base->list);
4944 linklist_previous = linklist_base;
4945 linklist_base = linklist_previous->next;
4946 free(linklist_previous);
4950 void free_values(char **modvalues)
4956 if (modvalues != NULL)
4958 while (modvalues[i] != NULL)
4961 modvalues[i] = NULL;
4968 static int illegalchars[] = {
4969 1, 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, 1, /* ^P - ^_ */
4971 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
4972 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
4973 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
4974 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
4975 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
4976 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
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,
4981 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4982 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4983 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4984 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4987 int check_string(char *s)
4995 if (isupper(character))
4996 character = tolower(character);
4998 if (illegalchars[(unsigned) character])
5005 int check_container_name(char *s)
5013 if (isupper(character))
5014 character = tolower(character);
5016 if (character == ' ')
5019 if (illegalchars[(unsigned) character])
5026 int mr_connect_cl(char *server, char *client, int version, int auth)
5032 status = mr_connect(server);
5036 com_err(whoami, status, "while connecting to Moira");
5040 status = mr_motd(&motd);
5045 com_err(whoami, status, "while checking server status");
5051 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5052 com_err(whoami, status, temp);
5057 status = mr_version(version);
5061 if (status == MR_UNKNOWN_PROC)
5064 status = MR_VERSION_HIGH;
5066 status = MR_SUCCESS;
5069 if (status == MR_VERSION_HIGH)
5071 com_err(whoami, 0, "Warning: This client is running newer code "
5072 "than the server.");
5073 com_err(whoami, 0, "Some operations may not work.");
5075 else if (status && status != MR_VERSION_LOW)
5077 com_err(whoami, status, "while setting query version number.");
5085 status = mr_krb5_auth(client);
5088 com_err(whoami, status, "while authenticating to Moira.");
5097 void AfsToWinAfs(char* path, char* winPath)
5101 strcpy(winPath, WINAFS);
5102 pathPtr = path + strlen(AFS);
5103 winPathPtr = winPath + strlen(WINAFS);
5107 if (*pathPtr == '/')
5110 *winPathPtr = *pathPtr;
5117 int GetAceInfo(int ac, char **av, void *ptr)
5124 strcpy(call_args[0], av[L_ACE_TYPE]);
5125 strcpy(call_args[1], av[L_ACE_NAME]);
5127 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5128 return(LDAP_SUCCESS);
5131 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5134 char *attr_array[3];
5137 LK_ENTRY *group_base;
5142 sprintf(filter, "(sAMAccountName=%s)", Name);
5143 attr_array[0] = "sAMAccountName";
5144 attr_array[1] = NULL;
5146 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5147 &group_base, &group_count,
5148 LDAP_SCOPE_SUBTREE)) != 0)
5150 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5151 Name, ldap_err2string(rc));
5155 linklist_free(group_base);
5158 if (group_count == 0)
5166 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5167 int UpdateGroup, int *ProcessGroup, char *maillist)
5170 char GroupName[256];
5176 char AceMembership[2];
5179 char *save_argv[U_END];
5183 com_err(whoami, 0, "ProcessAce disabled, skipping");
5187 strcpy(GroupName, Name);
5189 if (strcasecmp(Type, "LIST"))
5195 AceInfo[0] = AceType;
5196 AceInfo[1] = AceName;
5197 AceInfo[2] = AceMembership;
5199 memset(AceType, '\0', sizeof(AceType));
5200 memset(AceName, '\0', sizeof(AceName));
5201 memset(AceMembership, '\0', sizeof(AceMembership));
5202 memset(AceOu, '\0', sizeof(AceOu));
5205 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5207 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5208 GroupName, error_message(rc));
5214 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5218 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5221 strcpy(temp, AceName);
5223 if (!strcasecmp(AceType, "LIST"))
5224 sprintf(temp, "%s%s", AceName, group_suffix);
5228 if (checkADname(ldap_handle, dn_path, temp))
5230 (*ProcessGroup) = 1;
5233 if (!strcasecmp(AceInfo[0], "LIST"))
5235 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5236 AceMembership, 0, UpdateGroup, maillist))
5239 else if (!strcasecmp(AceInfo[0], "USER"))
5242 call_args[0] = (char *)ldap_handle;
5243 call_args[1] = dn_path;
5245 call_args[3] = NULL;
5248 if (rc = mr_query("get_user_account_by_login", 1, av,
5249 save_query_info, save_argv))
5251 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5256 if (rc = user_create(U_END, save_argv, call_args))
5258 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5265 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5275 if (!strcasecmp(AceType, "LIST"))
5277 if (!strcasecmp(GroupName, AceName))
5281 strcpy(GroupName, AceName);
5287 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5288 char *group_name, char *group_ou, char *group_membership,
5289 int group_security_flag, int updateGroup, char *maillist)
5294 LK_ENTRY *group_base;
5297 char *attr_array[3];
5300 call_args[0] = (char *)ldap_handle;
5301 call_args[1] = dn_path;
5302 call_args[2] = group_name;
5303 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5304 call_args[4] = (char *)updateGroup;
5305 call_args[5] = MoiraId;
5307 call_args[7] = NULL;
5313 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5316 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5324 com_err(whoami, 0, "Unable to create list %s", group_name);
5325 return(callback_rc);
5331 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
5332 char *group_ou, char *group_membership,
5333 int group_security_flag, char *MoiraId)
5343 com_err(whoami, 0, "Populating group %s", group_name);
5345 call_args[0] = (char *)ldap_handle;
5346 call_args[1] = dn_path;
5347 call_args[2] = group_name;
5348 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5349 call_args[4] = NULL;
5352 if (rc = mr_query("get_end_members_of_list", 1, av,
5353 member_list_build, call_args))
5355 com_err(whoami, 0, "Unable to populate list %s : %s",
5356 group_name, error_message(rc));
5360 if (member_base != NULL)
5366 if (!strcasecmp(ptr->type, "LIST"))
5374 if (!strcasecmp(ptr->type, "STRING"))
5376 if (contact_create(ldap_handle, dn_path, ptr->member,
5380 pUserOu = contact_ou;
5382 else if (!strcasecmp(ptr->type, "KERBEROS"))
5384 if (contact_create(ldap_handle, dn_path, ptr->member,
5388 pUserOu = kerberos_ou;
5391 rc = member_add(ldap_handle, dn_path, group_name,
5392 group_ou, group_membership, ptr->member,
5397 linklist_free(member_base);
5404 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5405 char *group_name, char *group_ou, char *group_membership,
5406 int group_security_flag, int type, char *maillist)
5408 char before_desc[512];
5409 char before_name[256];
5410 char before_group_ou[256];
5411 char before_group_membership[2];
5412 char distinguishedName[256];
5413 char ad_distinguishedName[256];
5415 char *attr_array[3];
5416 int before_security_flag;
5419 LK_ENTRY *group_base;
5422 char ou_security[512];
5423 char ou_distribution[512];
5424 char ou_neither[512];
5426 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
5427 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
5429 memset(filter, '\0', sizeof(filter));
5433 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5435 "distinguishedName", &group_base,
5436 &group_count, filter))
5439 if (type == CHECK_GROUPS)
5441 if (group_count == 1)
5443 if (!strcasecmp(group_base->value, distinguishedName))
5445 linklist_free(group_base);
5450 linklist_free(group_base);
5452 if (group_count == 0)
5453 return(AD_NO_GROUPS_FOUND);
5455 if (group_count == 1)
5456 return(AD_WRONG_GROUP_DN_FOUND);
5458 return(AD_MULTIPLE_GROUPS_FOUND);
5461 if (group_count == 0)
5463 return(AD_NO_GROUPS_FOUND);
5466 if (group_count > 1)
5472 if (!strcasecmp(distinguishedName, ptr->value))
5480 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
5486 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
5490 linklist_free(group_base);
5491 return(AD_MULTIPLE_GROUPS_FOUND);
5498 if (strcasecmp(distinguishedName, ptr->value))
5499 rc = ldap_delete_s(ldap_handle, ptr->value);
5504 linklist_free(group_base);
5505 memset(filter, '\0', sizeof(filter));
5509 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5511 "distinguishedName", &group_base,
5512 &group_count, filter))
5515 if (group_count == 0)
5516 return(AD_NO_GROUPS_FOUND);
5518 if (group_count > 1)
5519 return(AD_MULTIPLE_GROUPS_FOUND);
5522 strcpy(ad_distinguishedName, group_base->value);
5523 linklist_free(group_base);
5527 attr_array[0] = "sAMAccountName";
5528 attr_array[1] = NULL;
5530 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5531 &group_base, &group_count,
5532 LDAP_SCOPE_SUBTREE)) != 0)
5534 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5535 MoiraId, ldap_err2string(rc));
5539 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
5541 if (!strcasecmp(ad_distinguishedName, distinguishedName))
5543 linklist_free(group_base);
5549 linklist_free(group_base);
5552 memset(ou_both, '\0', sizeof(ou_both));
5553 memset(ou_security, '\0', sizeof(ou_security));
5554 memset(ou_distribution, '\0', sizeof(ou_distribution));
5555 memset(ou_neither, '\0', sizeof(ou_neither));
5556 memset(before_name, '\0', sizeof(before_name));
5557 memset(before_desc, '\0', sizeof(before_desc));
5558 memset(before_group_membership, '\0', sizeof(before_group_membership));
5559 attr_array[0] = "name";
5560 attr_array[1] = NULL;
5562 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5563 &group_base, &group_count,
5564 LDAP_SCOPE_SUBTREE)) != 0)
5566 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
5567 MoiraId, ldap_err2string(rc));
5571 strcpy(before_name, group_base->value);
5572 linklist_free(group_base);
5575 attr_array[0] = "description";
5576 attr_array[1] = NULL;
5578 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5579 &group_base, &group_count,
5580 LDAP_SCOPE_SUBTREE)) != 0)
5583 "Unable to get list description with MoiraId = %s: %s",
5584 MoiraId, ldap_err2string(rc));
5588 if (group_count != 0)
5590 strcpy(before_desc, group_base->value);
5591 linklist_free(group_base);
5596 change_to_lower_case(ad_distinguishedName);
5597 strcpy(ou_both, group_ou_both);
5598 change_to_lower_case(ou_both);
5599 strcpy(ou_security, group_ou_security);
5600 change_to_lower_case(ou_security);
5601 strcpy(ou_distribution, group_ou_distribution);
5602 change_to_lower_case(ou_distribution);
5603 strcpy(ou_neither, group_ou_neither);
5604 change_to_lower_case(ou_neither);
5606 if (strstr(ad_distinguishedName, ou_both))
5608 strcpy(before_group_ou, group_ou_both);
5609 before_group_membership[0] = 'B';
5610 before_security_flag = 1;
5612 else if (strstr(ad_distinguishedName, ou_security))
5614 strcpy(before_group_ou, group_ou_security);
5615 before_group_membership[0] = 'S';
5616 before_security_flag = 1;
5618 else if (strstr(ad_distinguishedName, ou_distribution))
5620 strcpy(before_group_ou, group_ou_distribution);
5621 before_group_membership[0] = 'D';
5622 before_security_flag = 0;
5624 else if (strstr(ad_distinguishedName, ou_neither))
5626 strcpy(before_group_ou, group_ou_neither);
5627 before_group_membership[0] = 'N';
5628 before_security_flag = 0;
5631 return(AD_NO_OU_FOUND);
5633 rc = group_rename(ldap_handle, dn_path, before_name,
5634 before_group_membership,
5635 before_group_ou, before_security_flag, before_desc,
5636 group_name, group_membership, group_ou,
5637 group_security_flag,
5638 before_desc, MoiraId, filter, maillist);
5643 void change_to_lower_case(char *ptr)
5647 for (i = 0; i < (int)strlen(ptr); i++)
5649 ptr[i] = tolower(ptr[i]);
5653 int ad_get_group(LDAP *ldap_handle, char *dn_path,
5654 char *group_name, char *group_membership,
5655 char *MoiraId, char *attribute,
5656 LK_ENTRY **linklist_base, int *linklist_count,
5661 char *attr_array[3];
5664 (*linklist_base) = NULL;
5665 (*linklist_count) = 0;
5667 if (strlen(rFilter) != 0)
5669 strcpy(filter, rFilter);
5670 attr_array[0] = attribute;
5671 attr_array[1] = NULL;
5673 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5674 linklist_base, linklist_count,
5675 LDAP_SCOPE_SUBTREE)) != 0)
5677 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5678 MoiraId, ldap_err2string(rc));
5682 if ((*linklist_count) == 1)
5684 strcpy(rFilter, filter);
5689 linklist_free((*linklist_base));
5690 (*linklist_base) = NULL;
5691 (*linklist_count) = 0;
5693 if (strlen(MoiraId) != 0)
5695 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
5696 attr_array[0] = attribute;
5697 attr_array[1] = NULL;
5699 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5700 linklist_base, linklist_count,
5701 LDAP_SCOPE_SUBTREE)) != 0)
5703 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5704 MoiraId, ldap_err2string(rc));
5709 if ((*linklist_count) > 1)
5711 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
5712 pPtr = (*linklist_base);
5716 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
5721 linklist_free((*linklist_base));
5722 (*linklist_base) = NULL;
5723 (*linklist_count) = 0;
5726 if ((*linklist_count) == 1)
5728 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
5730 strcpy(rFilter, filter);
5735 linklist_free((*linklist_base));
5736 (*linklist_base) = NULL;
5737 (*linklist_count) = 0;
5738 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
5739 attr_array[0] = attribute;
5740 attr_array[1] = NULL;
5742 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5743 linklist_base, linklist_count,
5744 LDAP_SCOPE_SUBTREE)) != 0)
5746 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5747 MoiraId, ldap_err2string(rc));
5751 if ((*linklist_count) == 1)
5753 strcpy(rFilter, filter);
5760 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5763 char *attr_array[3];
5764 char SamAccountName[64];
5767 LK_ENTRY *group_base;
5773 if (strlen(MoiraId) != 0)
5775 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5776 attr_array[0] = "sAMAccountName";
5777 attr_array[1] = NULL;
5778 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5779 &group_base, &group_count,
5780 LDAP_SCOPE_SUBTREE)) != 0)
5782 com_err(whoami, 0, "Unable to process user %s : %s",
5783 UserName, ldap_err2string(rc));
5787 if (group_count > 1)
5789 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5795 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5796 gPtr->value, MoiraId);
5802 if (group_count != 1)
5804 linklist_free(group_base);
5807 sprintf(filter, "(sAMAccountName=%s)", UserName);
5808 attr_array[0] = "sAMAccountName";
5809 attr_array[1] = NULL;
5811 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5812 &group_base, &group_count,
5813 LDAP_SCOPE_SUBTREE)) != 0)
5815 com_err(whoami, 0, "Unable to process user %s : %s",
5816 UserName, ldap_err2string(rc));
5821 if (group_count != 1)
5823 linklist_free(group_base);
5824 return(AD_NO_USER_FOUND);
5827 strcpy(SamAccountName, group_base->value);
5828 linklist_free(group_base);
5832 if (strcmp(SamAccountName, UserName))
5834 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5841 void container_get_dn(char *src, char *dest)
5848 memset(array, '\0', 20 * sizeof(array[0]));
5850 if (strlen(src) == 0)
5872 strcpy(dest, "OU=");
5876 strcat(dest, array[n-1]);
5880 strcat(dest, ",OU=");
5887 void container_get_name(char *src, char *dest)
5892 if (strlen(src) == 0)
5912 void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5919 strcpy(cName, name);
5921 for (i = 0; i < (int)strlen(cName); i++)
5923 if (cName[i] == '/')
5926 av[CONTAINER_NAME] = cName;
5927 av[CONTAINER_DESC] = "";
5928 av[CONTAINER_LOCATION] = "";
5929 av[CONTAINER_CONTACT] = "";
5930 av[CONTAINER_TYPE] = "";
5931 av[CONTAINER_ID] = "";
5932 av[CONTAINER_ROWID] = "";
5933 rc = container_create(ldap_handle, dn_path, 7, av);
5935 if (rc == LDAP_SUCCESS)
5937 com_err(whoami, 0, "container %s created without a mitMoiraId",
5946 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5947 char **before, int afterc, char **after)
5952 char new_dn_path[256];
5954 char distinguishedName[256];
5959 memset(cName, '\0', sizeof(cName));
5960 container_get_name(after[CONTAINER_NAME], cName);
5962 if (!check_container_name(cName))
5964 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5966 return(AD_INVALID_NAME);
5969 memset(distinguishedName, '\0', sizeof(distinguishedName));
5971 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5972 distinguishedName, beforec, before))
5975 if (strlen(distinguishedName) == 0)
5977 rc = container_create(ldap_handle, dn_path, afterc, after);
5981 strcpy(temp, after[CONTAINER_NAME]);
5984 for (i = 0; i < (int)strlen(temp); i++)
5994 container_get_dn(temp, dName);
5996 if (strlen(temp) != 0)
5997 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5999 sprintf(new_dn_path, "%s", dn_path);
6001 sprintf(new_cn, "OU=%s", cName);
6003 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6005 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6006 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6008 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6009 before[CONTAINER_NAME], after[CONTAINER_NAME],
6010 ldap_err2string(rc));
6014 memset(dName, '\0', sizeof(dName));
6015 container_get_dn(after[CONTAINER_NAME], dName);
6016 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6021 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6023 char distinguishedName[256];
6026 memset(distinguishedName, '\0', sizeof(distinguishedName));
6028 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6029 distinguishedName, count, av))
6032 if (strlen(distinguishedName) == 0)
6035 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6037 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6038 container_move_objects(ldap_handle, dn_path, distinguishedName);
6040 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6041 av[CONTAINER_NAME], ldap_err2string(rc));
6047 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6049 char *attr_array[3];
6050 LK_ENTRY *group_base;
6053 char *objectClass_v[] = {"top",
6054 "organizationalUnit",
6057 char *ou_v[] = {NULL, NULL};
6058 char *name_v[] = {NULL, NULL};
6059 char *moiraId_v[] = {NULL, NULL};
6060 char *desc_v[] = {NULL, NULL};
6061 char *managedBy_v[] = {NULL, NULL};
6064 char managedByDN[256];
6071 memset(filter, '\0', sizeof(filter));
6072 memset(dName, '\0', sizeof(dName));
6073 memset(cName, '\0', sizeof(cName));
6074 memset(managedByDN, '\0', sizeof(managedByDN));
6075 container_get_dn(av[CONTAINER_NAME], dName);
6076 container_get_name(av[CONTAINER_NAME], cName);
6078 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6080 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6082 return(AD_INVALID_NAME);
6085 if (!check_container_name(cName))
6087 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6089 return(AD_INVALID_NAME);
6093 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6095 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6097 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6099 if (strlen(av[CONTAINER_ROWID]) != 0)
6101 moiraId_v[0] = av[CONTAINER_ROWID];
6102 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6105 if (strlen(av[CONTAINER_DESC]) != 0)
6107 desc_v[0] = av[CONTAINER_DESC];
6108 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6111 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6113 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6115 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6118 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6119 kerberos_ou, dn_path);
6120 managedBy_v[0] = managedByDN;
6121 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6126 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6128 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6129 "(objectClass=user)))", av[CONTAINER_ID]);
6132 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6134 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6138 if (strlen(filter) != 0)
6140 attr_array[0] = "distinguishedName";
6141 attr_array[1] = NULL;
6144 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6146 &group_base, &group_count,
6147 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6149 if (group_count == 1)
6151 strcpy(managedByDN, group_base->value);
6152 managedBy_v[0] = managedByDN;
6153 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6155 linklist_free(group_base);
6165 sprintf(temp, "%s,%s", dName, dn_path);
6166 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
6168 for (i = 0; i < n; i++)
6171 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6173 com_err(whoami, 0, "Unable to create container %s : %s",
6174 cName, ldap_err2string(rc));
6178 if (rc == LDAP_ALREADY_EXISTS)
6180 if (strlen(av[CONTAINER_ROWID]) != 0)
6181 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6187 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6188 char **before, int afterc, char **after)
6190 char distinguishedName[256];
6193 memset(distinguishedName, '\0', sizeof(distinguishedName));
6195 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6196 distinguishedName, afterc, after))
6199 if (strlen(distinguishedName) == 0)
6201 rc = container_create(ldap_handle, dn_path, afterc, after);
6205 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6206 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6212 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6213 char *distinguishedName, int count,
6216 char *attr_array[3];
6217 LK_ENTRY *group_base;
6224 memset(filter, '\0', sizeof(filter));
6225 memset(dName, '\0', sizeof(dName));
6226 memset(cName, '\0', sizeof(cName));
6227 container_get_dn(av[CONTAINER_NAME], dName);
6228 container_get_name(av[CONTAINER_NAME], cName);
6230 if (strlen(dName) == 0)
6232 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6233 av[CONTAINER_NAME]);
6234 return(AD_INVALID_NAME);
6237 if (!check_container_name(cName))
6239 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6241 return(AD_INVALID_NAME);
6244 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6245 av[CONTAINER_ROWID]);
6246 attr_array[0] = "distinguishedName";
6247 attr_array[1] = NULL;
6251 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6252 &group_base, &group_count,
6253 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6255 if (group_count == 1)
6257 strcpy(distinguishedName, group_base->value);
6260 linklist_free(group_base);
6265 if (strlen(distinguishedName) == 0)
6267 sprintf(filter, "(&(objectClass=organizationalUnit)"
6268 "(distinguishedName=%s,%s))", dName, dn_path);
6269 attr_array[0] = "distinguishedName";
6270 attr_array[1] = NULL;
6274 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6275 &group_base, &group_count,
6276 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6278 if (group_count == 1)
6280 strcpy(distinguishedName, group_base->value);
6283 linklist_free(group_base);
6292 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6293 char *distinguishedName, int count, char **av)
6295 char *attr_array[5];
6296 LK_ENTRY *group_base;
6301 char *moiraId_v[] = {NULL, NULL};
6302 char *desc_v[] = {NULL, NULL};
6303 char *managedBy_v[] = {NULL, NULL};
6304 char managedByDN[256];
6313 strcpy(ad_path, distinguishedName);
6315 if (strlen(dName) != 0)
6316 sprintf(ad_path, "%s,%s", dName, dn_path);
6318 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6321 if (strlen(av[CONTAINER_ID]) != 0)
6322 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6323 av[CONTAINER_ROWID]);
6325 attr_array[0] = "mitMoiraId";
6326 attr_array[1] = "description";
6327 attr_array[2] = "managedBy";
6328 attr_array[3] = NULL;
6332 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6333 &group_base, &group_count,
6334 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6336 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6337 av[CONTAINER_NAME], ldap_err2string(rc));
6341 memset(managedByDN, '\0', sizeof(managedByDN));
6342 memset(moiraId, '\0', sizeof(moiraId));
6343 memset(desc, '\0', sizeof(desc));
6348 if (!strcasecmp(pPtr->attribute, "description"))
6349 strcpy(desc, pPtr->value);
6350 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6351 strcpy(managedByDN, pPtr->value);
6352 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6353 strcpy(moiraId, pPtr->value);
6357 linklist_free(group_base);
6362 if (strlen(av[CONTAINER_ROWID]) != 0)
6364 moiraId_v[0] = av[CONTAINER_ROWID];
6365 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6368 if (strlen(av[CONTAINER_DESC]) != 0)
6370 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6375 if (strlen(desc) != 0)
6377 attribute_update(ldap_handle, ad_path, "", "description", dName);
6381 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6383 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6385 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6388 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6389 kerberos_ou, dn_path);
6390 managedBy_v[0] = managedByDN;
6391 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6395 if (strlen(managedByDN) != 0)
6397 attribute_update(ldap_handle, ad_path, "", "managedBy",
6404 memset(filter, '\0', sizeof(filter));
6406 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6408 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6409 "(objectClass=user)))", av[CONTAINER_ID]);
6412 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6414 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6418 if (strlen(filter) != 0)
6420 attr_array[0] = "distinguishedName";
6421 attr_array[1] = NULL;
6424 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6425 attr_array, &group_base, &group_count,
6426 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6428 if (group_count == 1)
6430 strcpy(managedByDN, group_base->value);
6431 managedBy_v[0] = managedByDN;
6432 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6436 if (strlen(managedByDN) != 0)
6438 attribute_update(ldap_handle, ad_path, "",
6439 "managedBy", dName);
6443 linklist_free(group_base);
6450 if (strlen(managedByDN) != 0)
6452 attribute_update(ldap_handle, ad_path, "", "managedBy",
6462 return(LDAP_SUCCESS);
6464 rc = ldap_modify_s(ldap_handle, ad_path, mods);
6466 for (i = 0; i < n; i++)
6469 if (rc != LDAP_SUCCESS)
6471 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6472 av[CONTAINER_NAME], ldap_err2string(rc));
6479 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6481 char *attr_array[3];
6482 LK_ENTRY *group_base;
6489 int NumberOfEntries = 10;
6493 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6495 for (i = 0; i < 3; i++)
6497 memset(filter, '\0', sizeof(filter));
6501 strcpy(filter, "(!(|(objectClass=computer)"
6502 "(objectClass=organizationalUnit)))");
6503 attr_array[0] = "cn";
6504 attr_array[1] = NULL;
6508 strcpy(filter, "(objectClass=computer)");
6509 attr_array[0] = "cn";
6510 attr_array[1] = NULL;
6514 strcpy(filter, "(objectClass=organizationalUnit)");
6515 attr_array[0] = "ou";
6516 attr_array[1] = NULL;
6521 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
6522 &group_base, &group_count,
6523 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6528 if (group_count == 0)
6535 if (!strcasecmp(pPtr->attribute, "cn"))
6537 sprintf(new_cn, "cn=%s", pPtr->value);
6539 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6541 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6546 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6548 if (rc == LDAP_ALREADY_EXISTS)
6550 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6557 else if (!strcasecmp(pPtr->attribute, "ou"))
6559 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6565 linklist_free(group_base);
6574 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6575 char *machine_ou, char *NewMachineName)
6577 LK_ENTRY *group_base;
6581 char *attr_array[3];
6588 strcpy(NewMachineName, member);
6589 rc = moira_connect();
6590 rc = GetMachineName(NewMachineName);
6593 if (strlen(NewMachineName) == 0)
6595 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6601 pPtr = strchr(NewMachineName, '.');
6608 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
6609 attr_array[0] = "cn";
6610 attr_array[1] = NULL;
6611 sprintf(temp, "%s", dn_path);
6613 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
6614 &group_base, &group_count,
6615 LDAP_SCOPE_SUBTREE)) != 0)
6617 com_err(whoami, 0, "Unable to process machine %s : %s",
6618 member, ldap_err2string(rc));
6622 if (group_count != 1)
6625 "Unable to process machine %s : machine not found in AD",
6630 strcpy(dn, group_base->dn);
6631 strcpy(cn, group_base->value);
6633 for (i = 0; i < (int)strlen(dn); i++)
6634 dn[i] = tolower(dn[i]);
6636 for (i = 0; i < (int)strlen(cn); i++)
6637 cn[i] = tolower(cn[i]);
6639 linklist_free(group_base);
6641 pPtr = strstr(dn, cn);
6645 com_err(whoami, 0, "Unable to process machine %s",
6650 pPtr += strlen(cn) + 1;
6651 strcpy(machine_ou, pPtr);
6653 pPtr = strstr(machine_ou, "dc=");
6657 com_err(whoami, 0, "Unable to process machine %s",
6668 int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6669 char *MoiraMachineName, char *DestinationOu)
6673 char MachineName[128];
6675 char *attr_array[3];
6680 LK_ENTRY *group_base;
6685 strcpy(MachineName, MoiraMachineName);
6686 rc = GetMachineName(MachineName);
6688 if (strlen(MachineName) == 0)
6690 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6695 cPtr = strchr(MachineName, '.');
6700 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6701 attr_array[0] = "sAMAccountName";
6702 attr_array[1] = NULL;
6704 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6706 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
6708 com_err(whoami, 0, "Unable to process machine %s : %s",
6709 MoiraMachineName, ldap_err2string(rc));
6713 if (group_count == 1)
6714 strcpy(OldDn, group_base->dn);
6716 linklist_free(group_base);
6719 if (group_count != 1)
6721 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6726 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6727 cPtr = strchr(OldDn, ',');
6732 if (!strcasecmp(cPtr, NewOu))
6736 sprintf(NewCn, "CN=%s", MachineName);
6737 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6742 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6748 memset(Name, '\0', sizeof(Name));
6749 strcpy(Name, machine_name);
6751 pPtr = strchr(Name, '.');
6757 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
6760 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6761 char *machine_name, char *container_name)
6767 av[0] = machine_name;
6768 call_args[0] = (char *)container_name;
6769 rc = mr_query("get_machine_to_container_map", 1, av,
6770 machine_GetMoiraContainer, call_args);
6774 int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6779 strcpy(call_args[0], av[1]);
6783 int Moira_container_group_create(char **after)
6789 memset(GroupName, '\0', sizeof(GroupName));
6790 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6791 after[CONTAINER_ROWID]);
6795 argv[L_NAME] = GroupName;
6796 argv[L_ACTIVE] = "1";
6797 argv[L_PUBLIC] = "0";
6798 argv[L_HIDDEN] = "0";
6799 argv[L_MAILLIST] = "0";
6800 argv[L_GROUP] = "1";
6801 argv[L_GID] = UNIQUE_GID;
6802 argv[L_NFSGROUP] = "0";
6803 argv[L_MAILMAN] = "0";
6804 argv[L_MAILMAN_SERVER] = "[NONE]";
6805 argv[L_DESC] = "auto created container group";
6806 argv[L_ACE_TYPE] = "USER";
6807 argv[L_MEMACE_TYPE] = "USER";
6808 argv[L_ACE_NAME] = "sms";
6809 argv[L_MEMACE_NAME] = "sms";
6811 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
6814 "Unable to create container group %s for container %s: %s",
6815 GroupName, after[CONTAINER_NAME], error_message(rc));
6818 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6819 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6824 int Moira_container_group_update(char **before, char **after)
6827 char BeforeGroupName[64];
6828 char AfterGroupName[64];
6831 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6834 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6835 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6836 if (strlen(BeforeGroupName) == 0)
6839 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6840 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6841 after[CONTAINER_ROWID]);
6845 if (strcasecmp(BeforeGroupName, AfterGroupName))
6847 argv[L_NAME] = BeforeGroupName;
6848 argv[L_NAME + 1] = AfterGroupName;
6849 argv[L_ACTIVE + 1] = "1";
6850 argv[L_PUBLIC + 1] = "0";
6851 argv[L_HIDDEN + 1] = "0";
6852 argv[L_MAILLIST + 1] = "0";
6853 argv[L_GROUP + 1] = "1";
6854 argv[L_GID + 1] = UNIQUE_GID;
6855 argv[L_NFSGROUP + 1] = "0";
6856 argv[L_MAILMAN + 1] = "0";
6857 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
6858 argv[L_DESC + 1] = "auto created container group";
6859 argv[L_ACE_TYPE + 1] = "USER";
6860 argv[L_MEMACE_TYPE + 1] = "USER";
6861 argv[L_ACE_NAME + 1] = "sms";
6862 argv[L_MEMACE_NAME + 1] = "sms";
6864 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
6867 "Unable to rename container group from %s to %s: %s",
6868 BeforeGroupName, AfterGroupName, error_message(rc));
6875 int Moira_container_group_delete(char **before)
6880 char ParentGroupName[64];
6882 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6883 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6885 memset(GroupName, '\0', sizeof(GroupName));
6887 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6888 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6890 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6892 argv[0] = ParentGroupName;
6894 argv[2] = GroupName;
6896 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6899 "Unable to delete container group %s from list: %s",
6900 GroupName, ParentGroupName, error_message(rc));
6904 if (strlen(GroupName) != 0)
6906 argv[0] = GroupName;
6908 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6910 com_err(whoami, 0, "Unable to delete container group %s : %s",
6911 GroupName, error_message(rc));
6918 int Moira_groupname_create(char *GroupName, char *ContainerName,
6919 char *ContainerRowID)
6924 char newGroupName[64];
6925 char tempGroupName[64];
6931 strcpy(temp, ContainerName);
6933 ptr1 = strrchr(temp, '/');
6939 ptr1 = strrchr(temp, '/');
6943 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6946 strcpy(tempgname, ptr);
6949 strcpy(tempgname, temp);
6951 if (strlen(tempgname) > 25)
6952 tempgname[25] ='\0';
6954 sprintf(newGroupName, "cnt-%s", tempgname);
6956 /* change everything to lower case */
6962 *ptr = tolower(*ptr);
6970 strcpy(tempGroupName, newGroupName);
6973 /* append 0-9 then a-z if a duplicate is found */
6976 argv[0] = newGroupName;
6978 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6980 if (rc == MR_NO_MATCH)
6982 com_err(whoami, 0, "Moira error while creating group name for "
6983 "container %s : %s", ContainerName, error_message(rc));
6987 sprintf(newGroupName, "%s-%c", tempGroupName, i);
6991 com_err(whoami, 0, "Unable to find a unique group name for "
6992 "container %s: too many duplicate container names",
7003 strcpy(GroupName, newGroupName);
7007 int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7012 argv[0] = origContainerName;
7013 argv[1] = GroupName;
7015 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7018 "Unable to set container group %s in container %s: %s",
7019 GroupName, origContainerName, error_message(rc));
7025 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7027 char ContainerName[64];
7028 char ParentGroupName[64];
7032 strcpy(ContainerName, origContainerName);
7034 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7036 /* top-level container */
7037 if (strlen(ParentGroupName) == 0)
7040 argv[0] = ParentGroupName;
7042 argv[2] = GroupName;
7044 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7047 "Unable to add container group %s to parent group %s: %s",
7048 GroupName, ParentGroupName, error_message(rc));
7054 int Moira_getContainerGroup(int ac, char **av, void *ptr)
7059 strcpy(call_args[0], av[1]);
7064 int Moira_getGroupName(char *origContainerName, char *GroupName,
7067 char ContainerName[64];
7073 strcpy(ContainerName, origContainerName);
7077 ptr = strrchr(ContainerName, '/');
7085 argv[0] = ContainerName;
7087 call_args[0] = GroupName;
7088 call_args[1] = NULL;
7090 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7093 if (strlen(GroupName) != 0)
7098 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7099 ContainerName, error_message(rc));
7101 com_err(whoami, 0, "Unable to get container group from container %s",
7107 int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7113 if (strcmp(GroupName, "[none]") == 0)
7116 argv[0] = GroupName;
7117 argv[1] = "MACHINE";
7118 argv[2] = MachineName;
7121 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7123 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7127 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7128 MachineName, GroupName, error_message(rc));
7134 int GetMachineName(char *MachineName)
7137 char NewMachineName[1024];
7144 // If the address happens to be in the top-level MIT domain, great!
7145 strcpy(NewMachineName, MachineName);
7147 for (i = 0; i < (int)strlen(NewMachineName); i++)
7148 NewMachineName[i] = toupper(NewMachineName[i]);
7150 szDot = strchr(NewMachineName,'.');
7152 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7157 // If not, see if it has a Moira alias in the top-level MIT domain.
7158 memset(NewMachineName, '\0', sizeof(NewMachineName));
7160 args[1] = MachineName;
7161 call_args[0] = NewMachineName;
7162 call_args[1] = NULL;
7164 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7166 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7167 MachineName, error_message(rc));
7168 strcpy(MachineName, "");
7172 if (strlen(NewMachineName) != 0)
7173 strcpy(MachineName, NewMachineName);
7175 strcpy(MachineName, "");
7180 int ProcessMachineName(int ac, char **av, void *ptr)
7183 char MachineName[1024];
7189 if (strlen(call_args[0]) == 0)
7191 strcpy(MachineName, av[0]);
7193 for (i = 0; i < (int)strlen(MachineName); i++)
7194 MachineName[i] = toupper(MachineName[i]);
7196 szDot = strchr(MachineName,'.');
7198 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
7200 strcpy(call_args[0], MachineName);
7207 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7213 for (i = 0; i < n; i++)
7215 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7216 mods[i]->mod_type = "uidNumber";
7223 for (i = 0; i < n; i++)
7225 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7226 mods[i]->mod_type = "msSFU30UidNumber";
7233 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7234 char *DistinguishedName,
7235 char *WinHomeDir, char *WinProfileDir,
7236 char **homedir_v, char **winProfile_v,
7237 char **drives_v, LDAPMod **mods,
7245 char winProfile[1024];
7250 LDAPMod *DelMods[20];
7252 memset(homeDrive, '\0', sizeof(homeDrive));
7253 memset(path, '\0', sizeof(path));
7254 memset(winPath, '\0', sizeof(winPath));
7255 memset(winProfile, '\0', sizeof(winProfile));
7258 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7259 (!strcasecmp(WinProfileDir, "[afs]")))
7261 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
7263 memset(cWeight, 0, sizeof(cWeight));
7264 memset(cPath, 0, sizeof(cPath));
7268 while (hp[i] != NULL)
7270 if (sscanf(hp[i], "%*s %s", cPath))
7272 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
7274 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
7276 if (atoi(cWeight) < last_weight)
7278 strcpy(path, cPath);
7279 last_weight = (int)atoi(cWeight);
7283 strcpy(path, cPath);
7291 if (!strnicmp(path, AFS, strlen(AFS)))
7293 AfsToWinAfs(path, winPath);
7294 strcpy(winProfile, winPath);
7295 strcat(winProfile, "\\.winprofile");
7303 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7304 (!strcasecmp(WinProfileDir, "[dfs]")))
7306 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7307 user_name[0], user_name);
7309 if (!strcasecmp(WinProfileDir, "[dfs]"))
7311 strcpy(winProfile, path);
7312 strcat(winProfile, "\\.winprofile");
7315 if (!strcasecmp(WinHomeDir, "[dfs]"))
7316 strcpy(winPath, path);
7329 if (!strcasecmp(WinHomeDir, "[local]"))
7330 memset(winPath, '\0', sizeof(winPath));
7331 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7332 !strcasecmp(WinHomeDir, "[dfs]"))
7334 strcpy(homeDrive, "H:");
7338 strcpy(winPath, WinHomeDir);
7339 if (!strncmp(WinHomeDir, "\\\\", 2))
7341 strcpy(homeDrive, "H:");
7345 // nothing needs to be done if WinProfileDir is [afs].
7346 if (!strcasecmp(WinProfileDir, "[local]"))
7347 memset(winProfile, '\0', sizeof(winProfile));
7348 else if (strcasecmp(WinProfileDir, "[afs]") &&
7349 strcasecmp(WinProfileDir, "[dfs]"))
7351 strcpy(winProfile, WinProfileDir);
7354 if (strlen(winProfile) != 0)
7356 if (winProfile[strlen(winProfile) - 1] == '\\')
7357 winProfile[strlen(winProfile) - 1] = '\0';
7360 if (strlen(winPath) != 0)
7362 if (winPath[strlen(winPath) - 1] == '\\')
7363 winPath[strlen(winPath) - 1] = '\0';
7366 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
7367 strcat(winProfile, "\\");
7369 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7370 strcat(winPath, "\\");
7372 if (strlen(winPath) == 0)
7374 if (OpType == LDAP_MOD_REPLACE)
7377 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7379 //unset homeDirectory attribute for user.
7380 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7386 homedir_v[0] = strdup(winPath);
7387 ADD_ATTR("homeDirectory", homedir_v, OpType);
7390 if (strlen(winProfile) == 0)
7392 if (OpType == LDAP_MOD_REPLACE)
7395 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7397 //unset profilePate attribute for user.
7398 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7404 winProfile_v[0] = strdup(winProfile);
7405 ADD_ATTR("profilePath", winProfile_v, OpType);
7408 if (strlen(homeDrive) == 0)
7410 if (OpType == LDAP_MOD_REPLACE)
7413 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7415 //unset homeDrive attribute for user
7416 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7422 drives_v[0] = strdup(homeDrive);
7423 ADD_ATTR("homeDrive", drives_v, OpType);
7429 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
7430 char *attribute_value, char *attribute, char *user_name)
7432 char *mod_v[] = {NULL, NULL};
7433 LDAPMod *DelMods[20];
7439 if (strlen(attribute_value) == 0)
7442 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7444 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7450 mod_v[0] = attribute_value;
7451 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7454 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7455 mods)) != LDAP_SUCCESS)
7459 mod_v[0] = attribute_value;
7460 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7463 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7464 mods)) != LDAP_SUCCESS)
7466 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7468 attribute, user_name, ldap_err2string(rc));
7478 void StringTrim(char *StringToTrim)
7483 save = strdup(StringToTrim);
7490 /* skip to end of string */
7495 strcpy(StringToTrim, save);
7499 for (t = s; *t; t++)
7515 strcpy(StringToTrim, s);
7519 int ReadConfigFile(char *DomainName)
7530 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
7532 if ((fptr = fopen(temp, "r")) != NULL)
7534 while (fgets(temp, sizeof(temp), fptr) != 0)
7536 for (i = 0; i < (int)strlen(temp); i++)
7537 temp[i] = toupper(temp[i]);
7539 if (temp[strlen(temp) - 1] == '\n')
7540 temp[strlen(temp) - 1] = '\0';
7544 if (strlen(temp) == 0)
7547 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7549 if (strlen(temp) > (strlen(DOMAIN)))
7551 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7552 StringTrim(ldap_domain);
7555 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
7557 if (strlen(temp) > (strlen(PRINCIPALNAME)))
7559 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7560 StringTrim(PrincipalName);
7563 else if (!strncmp(temp, SERVER, strlen(SERVER)))
7565 if (strlen(temp) > (strlen(SERVER)))
7567 ServerList[Count] = calloc(1, 256);
7568 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7569 StringTrim(ServerList[Count]);
7573 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
7575 if (strlen(temp) > (strlen(MSSFU)))
7577 strcpy(temp1, &temp[strlen(MSSFU)]);
7579 if (!strcmp(temp1, SFUTYPE))
7583 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7585 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7587 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7589 if (!strcasecmp(temp1, "NO"))
7592 memset(group_suffix, '\0', sizeof(group_suffix));
7596 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7598 if (strlen(temp) > (strlen(GROUP_TYPE)))
7600 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7602 if (!strcasecmp(temp1, "UNIVERSAL"))
7603 UseGroupUniversal = 1;
7606 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7608 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7610 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7612 if (!strcasecmp(temp1, "NO"))
7616 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7618 if (strlen(temp) > (strlen(SET_PASSWORD)))
7620 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7622 if (!strcasecmp(temp1, "NO"))
7626 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7628 if (strlen(temp) > (strlen(EXCHANGE)))
7630 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7632 if (!strcasecmp(temp1, "YES"))
7636 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7637 strlen(PROCESS_MACHINE_CONTAINER)))
7639 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7641 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7643 if (!strcasecmp(temp1, "NO"))
7644 ProcessMachineContainer = 0;
7649 if (strlen(ldap_domain) != 0)
7651 memset(ldap_domain, '\0', sizeof(ldap_domain));
7655 if (strlen(temp) != 0)
7656 strcpy(ldap_domain, temp);
7662 if (strlen(ldap_domain) == 0)
7664 strcpy(ldap_domain, DomainName);
7670 for (i = 0; i < Count; i++)
7672 if (ServerList[i] != 0)
7674 strcat(ServerList[i], ".");
7675 strcat(ServerList[i], ldap_domain);
7676 for (k = 0; k < (int)strlen(ServerList[i]); k++)
7677 ServerList[i][k] = toupper(ServerList[i][k]);
7684 int ReadDomainList()
7691 unsigned char c[11];
7692 unsigned char stuff[256];
7697 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
7699 if ((fptr = fopen(temp, "r")) != NULL)
7701 while (fgets(temp, sizeof(temp), fptr) != 0)
7703 for (i = 0; i < (int)strlen(temp); i++)
7704 temp[i] = toupper(temp[i]);
7706 if (temp[strlen(temp) - 1] == '\n')
7707 temp[strlen(temp) - 1] = '\0';
7711 if (strlen(temp) == 0)
7714 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7716 if (strlen(temp) > (strlen(DOMAIN)))
7718 strcpy(temp1, &temp[strlen(DOMAIN)]);
7720 strcpy(temp, temp1);
7724 strcpy(DomainNames[Count], temp);
7725 StringTrim(DomainNames[Count]);
7734 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7735 "configuration error in winad.cfg");
7742 int email_isvalid(const char *address) {
7744 const char *c, *domain;
7745 static char *rfc822_specials = "()<>@,;:\\\"[]";
7747 if(address[strlen(address) - 1] == '.')
7750 /* first we validate the name portion (name@domain) */
7751 for (c = address; *c; c++) {
7752 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7757 if (*c == '\\' && (*++c == ' '))
7759 if (*c <= ' ' || *c >= 127)
7774 if (*c <= ' ' || *c >= 127)
7776 if (strchr(rfc822_specials, *c))
7780 if (c == address || *(c - 1) == '.')
7783 /* next we validate the domain portion (name@domain) */
7784 if (!*(domain = ++c)) return 0;
7787 if (c == domain || *(c - 1) == '.')
7791 if (*c <= ' ' || *c >= 127)
7793 if (strchr(rfc822_specials, *c))
7797 return (count >= 1);
7800 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7801 char **homeServerName)
7803 LK_ENTRY *group_base;
7804 LK_ENTRY *sub_group_base;
7808 int sub_group_count;
7810 char sub_filter[1024];
7811 char search_path[1024];
7813 char *attr_array[3];
7815 int homeMDB_count = -1;
7819 int rangeStep = 1500;
7821 int rangeHigh = rangeLow + (rangeStep - 1);
7824 /* Grumble..... microsoft not making it searchable from the root *grr* */
7826 memset(filter, '\0', sizeof(filter));
7827 memset(search_path, '\0', sizeof(search_path));
7829 sprintf(filter, "(objectClass=msExchMDB)");
7830 sprintf(search_path, "CN=Configuration,%s", dn_path);
7831 attr_array[0] = "distinguishedName";
7832 attr_array[1] = NULL;
7837 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7838 &group_base, &group_count,
7839 LDAP_SCOPE_SUBTREE)) != 0)
7841 com_err(whoami, 0, "Unable to find msExchMDB %s",
7842 ldap_err2string(rc));
7851 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
7852 ((s = strstr(gPtr->dn, "Recovery")) != (char *) NULL))
7859 * Due to limits in active directory we need to use the LDAP
7860 * range semantics to query and return all the values in
7861 * large lists, we will stop increasing the range when
7862 * the result count is 0.
7870 memset(sub_filter, '\0', sizeof(sub_filter));
7871 memset(range, '\0', sizeof(range));
7872 sprintf(sub_filter, "(objectClass=msExchMDB)");
7875 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
7877 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
7879 attr_array[0] = range;
7880 attr_array[1] = NULL;
7882 sub_group_base = NULL;
7883 sub_group_count = 0;
7885 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
7886 attr_array, &sub_group_base,
7888 LDAP_SCOPE_SUBTREE)) != 0)
7890 com_err(whoami, 0, "Unable to find homeMDBBL %s",
7891 ldap_err2string(rc));
7895 if(!sub_group_count)
7901 rangeHigh = rangeLow + (rangeStep - 1);
7908 mdbbl_count += sub_group_count;
7909 rangeLow = rangeHigh + 1;
7910 rangeHigh = rangeLow + (rangeStep - 1);
7913 /* First time through, need to initialize or update the least used */
7915 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
7918 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
7920 homeMDB_count = mdbbl_count;
7921 *homeMDB = strdup(gPtr->dn);
7925 linklist_free(sub_group_base);
7929 linklist_free(group_base);
7932 * Ok found the server least allocated need to now query to get its
7933 * msExchHomeServerName so we can set it as a user attribute
7936 attr_array[0] = "legacyExchangeDN";
7937 attr_array[1] = NULL;
7942 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
7943 attr_array, &group_base,
7945 LDAP_SCOPE_SUBTREE)) != 0)
7947 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
7948 ldap_err2string(rc));
7954 *homeServerName = strdup(group_base->value);
7955 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
7961 linklist_free(group_base);
7966 char *lowercase(char *s)
7970 for (p = s; *p; p++)
7978 char *uppercase(char *s)
7982 for (p = s; *p; p++)
7990 int save_query_info(int argc, char **argv, void *hint)
7993 char **nargv = hint;
7995 for(i = 0; i < argc; i++)
7996 nargv[i] = strdup(argv[i]);