2 /* winad.incr arguments example
4 * arguments when moira creates the account - ignored by winad.incr since the
5 * account is unusable. users 0 11 #45198 45198 /bin/cmd cmd Last First Middle
6 * 0 950000001 2000 121049
8 * login, unix_uid, shell, winconsoleshell, last,
9 * first, middle, status, mitid, type, moiraid
11 * arguments for creating or updating a user account
12 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
13 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
14 * First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
15 * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF
16 * 121058 PathToHomeDir PathToProfileDir newuser 45206 /bin/cmd cmd Last
17 * First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
19 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
20 * mitid, type, moiraid
22 * arguments for deactivating/deleting a user account
23 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
24 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
25 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
26 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
27 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
28 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
30 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
31 * mitid, type, moiraid
33 * arguments for reactivating a user account
34 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
35 * 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
37 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
38 * 121058 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 12105
40 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
41 * mitid, type, moiraid
43 * arguments for changing user name
44 * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001
45 * STAFF 121058 PathToHomeDir PathToProfileDir newusername 45206 /bin/cmd cmd
46 * Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
48 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
49 * mitid, type, moiraid
51 * arguments for expunging a user
52 * users 11 0 username 45198 /bin/cmd cmd Last First Middle 0 950000001 2000
55 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
56 * mitid, type, moiraid
58 * arguments for creating a "special" group/list
59 * list 0 11 listname 1 1 0 0 0 -1 NONE 0 description 92616
61 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
62 * acl_id, description, moiraid
64 * arguments for creating a "mail" group/list
65 * list 0 11 listname 1 1 0 1 0 -1 NONE 0 description 92616
67 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
68 * acl_id, description, moiraid
70 * arguments for creating a "group" group/list
71 * list 0 11 listname 1 1 0 0 1 -1 NONE 0 description 92616
73 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
74 * acl_id, description, moiraid
76 * arguments for creating a "group/mail" group/list
77 * list 0 11 listname 1 1 0 1 1 -1 NONE 0 description 92616
79 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
80 * acl_id, description, moiraid
82 * arguments to add a USER member to group/list
83 * imembers 0 12 listname USER userName 1 1 0 0 0 -1 1 92616 121047
85 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
86 * gid, userStatus, moiraListId, moiraUserId
88 * arguments to add a STRING or KERBEROS member to group/list
89 * imembers 0 10 listname STRING stringName 1 1 0 0 0 -1 92616
90 * imembers 0 10 listlistnameName KERBEROS kerberosName 1 1 0 0 0 -1 92616
92 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
95 * NOTE: group members of type LIST are ignored.
97 * arguments to remove a USER member to group/list
98 * imembers 12 0 listname USER userName 1 1 0 0 0 -1 1 92616 121047
100 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
101 * gid, userStatus, moiraListId, moiraUserId
103 * arguments to remove a STRING or KERBEROS member to group/list
104 * imembers 10 0 listname STRING stringName 1 1 0 0 0 -1 92616
105 * imembers 10 0 listname KERBEROS kerberosName 1 1 0 0 0 -1 92616
107 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
110 * NOTE: group members of type LIST are ignored.
112 * arguments for renaming a group/list
113 * list 11 11 oldlistname 1 1 0 0 0 -1 NONE 0 description 92616 newlistname 1
114 * 1 0 0 0 -1 description 0 92616
116 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
117 * acl_id, description, moiraListId
119 * arguments for deleting a group/list
120 * list 11 0 listname 1 1 0 0 0 -1 NONE 0 description 92616
122 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
123 * acl_id, description, moiraListId
125 * arguments for adding a file system
126 * filesys 0 12 username AFS ATHENA.MIT.EDU
127 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
128 * wheel 1 HOMEDIR 101727
130 * arguments for deleting a file system
131 * filesys 12 0 username AFS ATHENA.MIT.EDU
132 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
133 * wheel 1 HOMEDIR 101727
135 * arguments when moira creates a container (OU).
136 * containers 0 8 machines/test/bottom description location contact USER
139 * arguments when moira deletes a container (OU).
140 * containers 8 0 machines/test/bottom description location contact USER
141 * 105316 2222 groupname
143 * arguments when moira modifies a container information (OU).
144 * containers 8 8 machines/test/bottom description location contact USER
145 * 105316 2222 groupname machines/test/bottom description1 location contact
146 * USER 105316 2222 groupname
148 * arguments when moira adds a machine from an OU
149 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
150 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
152 * arguments when moira removes a machine from an OU
153 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
154 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
158 #include <mit-copyright.h>
161 #include <winsock2.h>
165 #include <lmaccess.h>
173 #include <moira_site.h>
174 #include <mrclient.h>
182 #define ECONNABORTED WSAECONNABORTED
185 #define ECONNREFUSED WSAECONNREFUSED
188 #define EHOSTUNREACH WSAEHOSTUNREACH
190 #define krb5_xfree free
192 #define sleep(A) Sleep(A * 1000);
196 #include <sys/types.h>
197 #include <netinet/in.h>
198 #include <arpa/nameser.h>
200 #include <sys/utsname.h>
203 #define CFG_PATH "/moira/winad/"
204 #define WINADCFG "winad.cfg"
205 #define strnicmp(A,B,C) strncasecmp(A,B,C)
206 #define UCHAR unsigned char
208 #define UF_SCRIPT 0x0001
209 #define UF_ACCOUNTDISABLE 0x0002
210 #define UF_HOMEDIR_REQUIRED 0x0008
211 #define UF_LOCKOUT 0x0010
212 #define UF_PASSWD_NOTREQD 0x0020
213 #define UF_PASSWD_CANT_CHANGE 0x0040
214 #define UF_DONT_EXPIRE_PASSWD 0x10000
216 #define UF_TEMP_DUPLICATE_ACCOUNT 0x0100
217 #define UF_NORMAL_ACCOUNT 0x0200
218 #define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800
219 #define UF_WORKSTATION_TRUST_ACCOUNT 0x1000
220 #define UF_SERVER_TRUST_ACCOUNT 0x2000
222 #define OWNER_SECURITY_INFORMATION (0x00000001L)
223 #define GROUP_SECURITY_INFORMATION (0x00000002L)
224 #define DACL_SECURITY_INFORMATION (0x00000004L)
225 #define SACL_SECURITY_INFORMATION (0x00000008L)
228 #define BYTE unsigned char
230 typedef unsigned int DWORD;
231 typedef unsigned long ULONG;
236 unsigned short Data2;
237 unsigned short Data3;
238 unsigned char Data4[8];
241 typedef struct _SID_IDENTIFIER_AUTHORITY {
243 } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
245 typedef struct _SID {
247 BYTE SubAuthorityCount;
248 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
249 DWORD SubAuthority[512];
254 #define WINADCFG "winad.cfg"
262 #define WINAFS "\\\\afs\\all\\"
264 #define ADS_GROUP_TYPE_GLOBAL_GROUP 0x00000002
265 #define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP 0x00000004
266 #define ADS_GROUP_TYPE_LOCAL_GROUP 0x00000004
267 #define ADS_GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
268 #define ADS_GROUP_TYPE_SECURITY_ENABLED 0x80000000
270 #define QUERY_VERSION -1
271 #define PRIMARY_REALM "ATHENA.MIT.EDU"
272 #define PRIMARY_DOMAIN "win.mit.edu"
273 #define PRODUCTION_PRINCIPAL "sms"
274 #define TEST_PRINCIPAL "smstest"
283 #define MEMBER_REMOVE 2
284 #define MEMBER_CHANGE_NAME 3
285 #define MEMBER_ACTIVATE 4
286 #define MEMBER_DEACTIVATE 5
287 #define MEMBER_CREATE 6
289 #define MOIRA_ALL 0x0
290 #define MOIRA_USERS 0x1
291 #define MOIRA_KERBEROS 0x2
292 #define MOIRA_STRINGS 0x4
293 #define MOIRA_LISTS 0x8
295 #define CHECK_GROUPS 1
296 #define CLEANUP_GROUPS 2
298 #define AD_NO_GROUPS_FOUND -1
299 #define AD_WRONG_GROUP_DN_FOUND -2
300 #define AD_MULTIPLE_GROUPS_FOUND -3
301 #define AD_INVALID_NAME -4
302 #define AD_LDAP_FAILURE -5
303 #define AD_INVALID_FILESYS -6
304 #define AD_NO_ATTRIBUTE_FOUND -7
305 #define AD_NO_OU_FOUND -8
306 #define AD_NO_USER_FOUND -9
308 /* container arguments */
309 #define CONTAINER_NAME 0
310 #define CONTAINER_DESC 1
311 #define CONTAINER_LOCATION 2
312 #define CONTAINER_CONTACT 3
313 #define CONTAINER_TYPE 4
314 #define CONTAINER_ID 5
315 #define CONTAINER_ROWID 6
316 #define CONTAINER_GROUP_NAME 7
318 /*mcntmap arguments*/
319 #define OU_MACHINE_NAME 0
320 #define OU_CONTAINER_NAME 1
321 #define OU_MACHINE_ID 2
322 #define OU_CONTAINER_ID 3
323 #define OU_CONTAINER_GROUP 4
325 typedef struct lk_entry {
335 struct lk_entry *next;
338 #define STOP_FILE "/moira/winad/nowinad"
339 #define file_exists(file) (access((file), F_OK) == 0)
341 #define N_SD_BER_BYTES 5
342 #define LDAP_BERVAL struct berval
343 #define MAX_SERVER_NAMES 32
345 #define HIDDEN_GROUP "HiddenGroup.g"
346 #define HIDDEN_GROUP_WITH_ADMIN "HiddenGroupWithAdmin.g"
347 #define NOT_HIDDEN_GROUP "NotHiddenGroup.g"
348 #define NOT_HIDDEN_GROUP_WITH_ADMIN "NotHiddenGroupWithAdmin.g"
350 #define ADDRESS_LIST_PREFIX "CN=MIT Directory,CN=All Address Lists,\
351 CN=Address Lists Container,CN=Massachusetts Institute of Technology,\
352 CN=Microsoft Exchange,CN=Services,CN=Configuration,"
354 #define ADD_ATTR(t, v, o) \
355 mods[n] = malloc(sizeof(LDAPMod)); \
356 mods[n]->mod_op = o; \
357 mods[n]->mod_type = t; \
358 mods[n++]->mod_values = v
360 #define DEL_ATTR(t, o) \
361 DelMods[i] = malloc(sizeof(LDAPMod)); \
362 DelMods[i]->mod_op = o; \
363 DelMods[i]->mod_type = t; \
364 DelMods[i++]->mod_values = NULL
366 #define DOMAIN_SUFFIX "MIT.EDU"
367 #define DOMAIN "DOMAIN:"
368 #define PRINCIPALNAME "PRINCIPAL:"
369 #define SERVER "SERVER:"
372 #define GROUP_SUFFIX "GROUP_SUFFIX:"
373 #define GROUP_TYPE "GROUP_TYPE:"
374 #define SET_GROUP_ACE "SET_GROUP_ACE:"
375 #define SET_PASSWORD "SET_PASSWORD:"
376 #define EXCHANGE "EXCHANGE:"
377 #define PROCESS_MACHINE_CONTAINER "PROCESS_MACHINE_CONTAINER:"
378 #define MAX_DOMAINS 10
379 char DomainNames[MAX_DOMAINS][128];
381 LK_ENTRY *member_base = NULL;
383 char PrincipalName[128];
384 static char tbl_buf[1024];
385 char kerberos_ou[] = "OU=kerberos,OU=moira";
386 char contact_ou[] = "OU=strings,OU=moira";
387 char user_ou[] = "OU=users,OU=moira";
388 char group_ou_distribution[] = "OU=mail,OU=lists,OU=moira";
389 char group_ou_root[] = "OU=lists,OU=moira";
390 char group_ou_security[] = "OU=group,OU=lists,OU=moira";
391 char group_ou_neither[] = "OU=special,OU=lists,OU=moira";
392 char group_ou_both[] = "OU=mail,OU=group,OU=lists,OU=moira";
393 char orphans_machines_ou[] = "OU=Machines,OU=Orphans";
394 char orphans_other_ou[] = "OU=Other,OU=Orphans";
395 char security_template_ou[] = "OU=security_templates";
397 char ldap_domain[256];
398 char *ServerList[MAX_SERVER_NAMES];
399 char default_server[256];
400 static char tbl_buf[1024];
401 char group_suffix[256];
402 char exchange_acl[256];
403 int mr_connections = 0;
406 int UseGroupSuffix = 1;
407 int UseGroupUniversal = 0;
411 int ProcessMachineContainer = 1;
412 int UpdateDomainList;
414 extern int set_password(char *user, char *password, char *domain);
416 int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name,
417 char *group_membership, char *MoiraId, char *attribute,
418 LK_ENTRY **linklist_base, int *linklist_count,
420 void AfsToWinAfs(char* path, char* winPath);
421 int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
422 char *Win2kPassword, char *Win2kUser, char *default_server,
423 int connect_to_kdc, char **ServerList);
424 void ad_kdc_disconnect();
425 int ad_server_connect(char *connectedServer, char *domain);
426 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
427 char *attribute_value, char *attribute, char *user_name);
428 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer);
429 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name);
430 int check_winad(void);
431 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName,
434 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
435 char *distinguishedName, int count, char **av);
436 void container_check(LDAP *ldap_handle, char *dn_path, char *name);
437 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av);
438 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av);
439 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
440 char *distinguishedName, int count,
442 void container_get_dn(char *src, char *dest);
443 void container_get_name(char *src, char *dest);
444 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName);
445 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
446 char **before, int afterc, char **after);
447 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
448 char **before, int afterc, char **after);
450 int GetAceInfo(int ac, char **av, void *ptr);
451 int get_group_membership(char *group_membership, char *group_ou,
452 int *security_flag, char **av);
453 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
454 char *machine_ou, char *pPtr);
455 int Moira_container_group_create(char **after);
456 int Moira_container_group_delete(char **before);
457 int Moira_groupname_create(char *GroupName, char *ContainerName,
458 char *ContainerRowID);
459 int Moira_container_group_update(char **before, char **after);
460 int Moira_process_machine_container_group(char *MachineName, char* groupName,
462 int Moira_addGroupToParent(char *origContainerName, char *GroupName);
463 int Moira_getContainerGroup(int ac, char **av, void *ptr);
464 int Moira_getGroupName(char *origContainerName, char *GroupName,
466 int Moira_setContainerGroup(char *ContainerName, char *GroupName);
467 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *group_name, char *Type,
468 int UpdateGroup, int *ProcessGroup, char *maillist);
469 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
470 char *group_name, char *group_ou, char *group_membership,
471 int group_security_flag, int type, char *maillist);
472 int process_lists(int ac, char **av, void *ptr);
473 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
474 char *TargetGroupName, int HiddenGroup,
475 char *AceType, char *AceName);
476 int ProcessMachineName(int ac, char **av, void *ptr);
477 int ReadConfigFile(char *DomainName);
478 int ReadDomainList();
479 void StringTrim(char *StringToTrim);
480 int save_query_info(int argc, char **argv, void *hint);
481 int user_create(int ac, char **av, void *ptr);
482 int user_change_status(LDAP *ldap_handle, char *dn_path,
483 char *user_name, char *MoiraId, int operation);
484 int user_delete(LDAP *ldap_handle, char *dn_path,
485 char *u_name, char *MoiraId);
486 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
488 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
489 char *uid, char *MitId, char *MoiraId, int State,
490 char *WinHomeDir, char *WinProfileDir, char *first,
491 char *middle, char *last);
492 void change_to_lower_case(char *ptr);
493 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
494 int contact_remove_email(LDAP *ld, char *bind_path,
495 LK_ENTRY **linklist_entry, int linklist_current);
496 int group_create(int ac, char **av, void *ptr);
497 int group_delete(LDAP *ldap_handle, char *dn_path,
498 char *group_name, char *group_membership, char *MoiraId);
499 int group_rename(LDAP *ldap_handle, char *dn_path,
500 char *before_group_name, char *before_group_membership,
501 char *before_group_ou, int before_security_flag,
502 char *before_desc, char *after_group_name,
503 char *after_group_membership, char *after_group_ou,
504 int after_security_flag, char *after_desc,
505 char *MoiraId, char *filter, char *maillist);
506 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name);
507 int machine_GetMoiraContainer(int ac, char **av, void *ptr);
508 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
509 char *machine_name, char *container_name);
510 int machine_move_to_ou(LDAP *ldap_handle, char *dn_path,
511 char *MoiraMachineName, char *DestinationOu);
512 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
513 char *group_name, char *group_ou, char *group_membership,
514 int group_security_flag, int updateGroup, char *maillist);
515 int member_list_build(int ac, char **av, void *ptr);
516 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
517 char *group_ou, char *group_membership,
518 char *user_name, char *pUserOu, char *MoiraId);
519 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
520 char *group_ou, char *group_membership, char *user_name,
521 char *pUserOu, char *MoiraId);
522 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
523 char *group_ou, char *group_membership,
524 int group_security_flag, char *MoiraId);
525 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
526 char *DistinguishedName,
527 char *WinHomeDir, char *WinProfileDir,
528 char **homedir_v, char **winProfile_v,
529 char **drives_v, LDAPMod **mods,
531 int sid_update(LDAP *ldap_handle, char *dn_path);
532 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n);
533 int check_string(char *s);
534 int check_container_name(char* s);
536 int mr_connect_cl(char *server, char *client, int version, int auth);
537 void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
538 char **before, int beforec, char **after, int afterc);
539 void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
540 char **before, int beforec, char **after, int afterc);
541 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
542 char **before, int beforec, char **after, int afterc);
543 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
544 char **before, int beforec, char **after, int afterc);
545 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
546 char **before, int beforec, char **after, int afterc);
547 void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
548 char **before, int beforec, char **after, int afterc);
549 int linklist_create_entry(char *attribute, char *value,
550 LK_ENTRY **linklist_entry);
551 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
552 char **attr_array, LK_ENTRY **linklist_base,
553 int *linklist_count, unsigned long ScopeType);
554 void linklist_free(LK_ENTRY *linklist_base);
556 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
557 char *distinguished_name, LK_ENTRY **linklist_current);
558 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
559 LK_ENTRY **linklist_base, int *linklist_count);
560 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
561 char *Attribute, char *distinguished_name,
562 LK_ENTRY **linklist_current);
564 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
565 char *oldValue, char *newValue,
566 char ***modvalues, int type);
567 void free_values(char **modvalues);
569 int convert_domain_to_dn(char *domain, char **bind_path);
570 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
571 char *distinguished_name);
572 int moira_disconnect(void);
573 int moira_connect(void);
574 void print_to_screen(const char *fmt, ...);
575 int GetMachineName(char *MachineName);
576 int tickets_get_k5();
577 int destroy_cache(void);
580 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
581 char **homeServerName);
583 int main(int argc, char **argv)
599 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
603 com_err(whoami, 0, "Unable to process %s", "argc < 4");
607 if (argc < (4 + atoi(argv[2]) + atoi(argv[3])))
609 com_err(whoami, 0, "Unable to process %s",
610 "argc < (4 + beforec + afterc)");
614 if (!strcmp(argv[1], "filesys"))
617 for (i = 1; i < argc; i++)
619 strcat(tbl_buf, argv[i]);
620 strcat(tbl_buf, " ");
623 com_err(whoami, 0, "%s", tbl_buf);
627 com_err(whoami, 0, "%s failed", "check_winad()");
631 initialize_sms_error_table();
632 initialize_krb_error_table();
634 UpdateDomainList = 0;
635 memset(DomainNames, '\0', sizeof(DomainNames[0]) * MAX_DOMAINS);
637 if (ReadDomainList())
639 com_err(whoami, 0, "%s failed", "ReadDomainList()");
643 for (i = 0; i < argc; i++)
646 for (k = 0; k < MAX_DOMAINS; k++)
648 if (strlen(DomainNames[k]) == 0)
650 for (i = 0; i < argc; i++)
652 if (orig_argv[i] != NULL)
654 orig_argv[i] = strdup(argv[i]);
657 memset(PrincipalName, '\0', sizeof(PrincipalName));
658 memset(ldap_domain, '\0', sizeof(ldap_domain));
659 memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES);
660 memset(default_server, '\0', sizeof(default_server));
661 memset(dn_path, '\0', sizeof(dn_path));
662 memset(group_suffix, '\0', sizeof(group_suffix));
663 memset(exchange_acl, '\0', sizeof(exchange_acl));
667 UseGroupUniversal = 0;
671 ProcessMachineContainer = 1;
673 sprintf(group_suffix, "%s", "_group");
674 sprintf(exchange_acl, "%s", "exchange-acl");
676 beforec = atoi(orig_argv[2]);
677 afterc = atoi(orig_argv[3]);
678 table = orig_argv[1];
679 before = &orig_argv[4];
680 after = &orig_argv[4 + beforec];
688 if (ReadConfigFile(DomainNames[k]))
691 OldUseSFU30 = UseSFU30;
693 for (i = 0; i < 5; i++)
695 ldap_handle = (LDAP *)NULL;
696 if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "",
697 default_server, 1, ServerList)))
699 com_err(whoami, 0, "connected to domain %s", DomainNames[k]);
704 if ((rc) || (ldap_handle == NULL))
706 critical_alert("incremental",
707 "winad.incr cannot connect to any server in "
708 "domain %s", DomainNames[k]);
712 for (i = 0; i < (int)strlen(table); i++)
713 table[i] = tolower(table[i]);
715 if (!strcmp(table, "users"))
716 do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
718 else if (!strcmp(table, "list"))
719 do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
721 else if (!strcmp(table, "imembers"))
722 do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
724 else if (!strcmp(table, "containers"))
725 do_container(ldap_handle, dn_path, ldap_domain, before, beforec, after,
727 else if (!strcmp(table, "mcntmap"))
728 do_mcntmap(ldap_handle, dn_path, ldap_domain, before, beforec, after,
733 for (i = 0; i < MAX_SERVER_NAMES; i++)
735 if (ServerList[i] != NULL)
738 ServerList[i] = NULL;
742 rc = ldap_unbind_s(ldap_handle);
748 void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
749 char **before, int beforec, char **after, int afterc)
751 char MoiraContainerName[128];
752 char ADContainerName[128];
753 char MachineName[1024];
754 char OriginalMachineName[1024];
757 char MoiraContainerGroup[64];
759 if (!ProcessMachineContainer)
761 com_err(whoami, 0, "Process machines and containers disabled, skipping");
766 memset(ADContainerName, '\0', sizeof(ADContainerName));
767 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
769 if ((beforec == 0) && (afterc == 0))
772 if (rc = moira_connect())
774 critical_alert("AD incremental",
775 "Error contacting Moira server : %s",
780 if ((beforec != 0) && (afterc == 0)) /*remove a machine*/
782 strcpy(OriginalMachineName, before[OU_MACHINE_NAME]);
783 strcpy(MachineName, before[OU_MACHINE_NAME]);
784 strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]);
786 com_err(whoami, 0, "removing machine %s from %s",
787 OriginalMachineName, before[OU_CONTAINER_NAME]);
789 else if ((beforec == 0) && (afterc != 0)) /*add a machine*/
791 strcpy(OriginalMachineName, after[OU_MACHINE_NAME]);
792 strcpy(MachineName, after[OU_MACHINE_NAME]);
793 strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]);
794 com_err(whoami, 0, "adding machine %s to container %s",
795 OriginalMachineName, after[OU_CONTAINER_NAME]);
803 rc = GetMachineName(MachineName);
805 if (strlen(MachineName) == 0)
808 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
809 OriginalMachineName);
813 Moira_process_machine_container_group(MachineName, MoiraContainerGroup,
816 if (machine_check(ldap_handle, dn_path, MachineName))
818 com_err(whoami, 0, "Unable to find machine %s (alias %s) in AD.",
819 OriginalMachineName, MachineName);
824 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
825 machine_get_moira_container(ldap_handle, dn_path, MachineName,
828 if (strlen(MoiraContainerName) == 0)
830 com_err(whoami, 0, "Unable to fine machine %s (alias %s) container "
831 "in Moira - moving to orphans OU.",
832 OriginalMachineName, MachineName);
833 machine_move_to_ou(ldap_handle, dn_path, MachineName,
834 orphans_machines_ou);
839 container_get_dn(MoiraContainerName, ADContainerName);
841 if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/')
842 strcat(MoiraContainerName, "/");
844 container_check(ldap_handle, dn_path, MoiraContainerName);
845 machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName);
850 void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
851 char **before, int beforec, char **after, int afterc)
855 if (!ProcessMachineContainer)
857 com_err(whoami, 0, "Process machines and containers disabled, skipping");
861 if ((beforec == 0) && (afterc == 0))
864 if (rc = moira_connect())
866 critical_alert("AD incremental", "Error contacting Moira server : %s",
871 if ((beforec != 0) && (afterc == 0)) /*delete a new container*/
873 com_err(whoami, 0, "deleting container %s", before[CONTAINER_NAME]);
874 container_delete(ldap_handle, dn_path, beforec, before);
875 Moira_container_group_delete(before);
880 if ((beforec == 0) && (afterc != 0)) /*create a container*/
882 com_err(whoami, 0, "creating container %s", after[CONTAINER_NAME]);
883 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
884 container_create(ldap_handle, dn_path, afterc, after);
885 Moira_container_group_create(after);
890 if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME]))
892 com_err(whoami, 0, "renaming container %s to %s",
893 before[CONTAINER_NAME], after[CONTAINER_NAME]);
894 container_rename(ldap_handle, dn_path, beforec, before, afterc, after);
895 Moira_container_group_update(before, after);
900 com_err(whoami, 0, "updating container %s information",
901 after[CONTAINER_NAME]);
902 container_update(ldap_handle, dn_path, beforec, before, afterc, after);
903 Moira_container_group_update(before, after);
908 #define L_LIST_DESC 9
911 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
912 char **before, int beforec, char **after, int afterc)
917 char group_membership[6];
922 char before_list_id[32];
923 char before_group_membership[1];
924 int before_security_flag;
925 char before_group_ou[256];
926 LK_ENTRY *ptr = NULL;
928 if (beforec == 0 && afterc == 0)
931 memset(list_id, '\0', sizeof(list_id));
932 memset(before_list_id, '\0', sizeof(before_list_id));
933 memset(before_group_ou, '\0', sizeof(before_group_ou));
934 memset(before_group_membership, '\0', sizeof(before_group_membership));
935 memset(group_ou, '\0', sizeof(group_ou));
936 memset(group_membership, '\0', sizeof(group_membership));
941 if (beforec < L_LIST_ID)
943 if (beforec > L_LIST_DESC)
945 strcpy(before_list_id, before[L_LIST_ID]);
947 before_security_flag = 0;
948 get_group_membership(before_group_membership, before_group_ou,
949 &before_security_flag, before);
954 if (afterc < L_LIST_ID)
956 if (afterc > L_LIST_DESC)
958 strcpy(list_id, after[L_LIST_ID]);
961 get_group_membership(group_membership, group_ou, &security_flag, after);
964 if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/
973 if ((rc = process_group(ldap_handle, dn_path, before_list_id,
974 before[L_NAME], before_group_ou,
975 before_group_membership,
976 before_security_flag, CHECK_GROUPS,
977 before[L_MAILLIST])))
979 if (rc == AD_NO_GROUPS_FOUND)
983 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
984 (rc == AD_MULTIPLE_GROUPS_FOUND))
986 rc = process_group(ldap_handle, dn_path, before_list_id,
987 before[L_NAME], before_group_ou,
988 before_group_membership,
989 before_security_flag, CLEANUP_GROUPS,
992 if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0))
994 com_err(whoami, 0, "Unable to process list %s",
998 if (rc == AD_NO_GROUPS_FOUND)
1004 if ((beforec != 0) && (afterc != 0))
1006 if (((strcmp(after[L_NAME], before[L_NAME])) ||
1007 ((!strcmp(after[L_NAME], before[L_NAME])) &&
1008 (strcmp(before_group_ou, group_ou)))) &&
1011 com_err(whoami, 0, "Changing list name from %s to %s",
1012 before[L_NAME], after[L_NAME]);
1014 if ((strlen(before_group_ou) == 0) ||
1015 (strlen(before_group_membership) == 0) ||
1016 (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
1018 com_err(whoami, 0, "%s", "Unable to find the group OU's");
1022 memset(filter, '\0', sizeof(filter));
1024 if ((rc = group_rename(ldap_handle, dn_path,
1025 before[L_NAME], before_group_membership,
1026 before_group_ou, before_security_flag,
1027 before[L_LIST_DESC], after[L_NAME],
1028 group_membership, group_ou, security_flag,
1030 list_id, filter, after[L_MAILLIST])))
1032 if (rc != AD_NO_GROUPS_FOUND)
1035 "Unable to change list name from %s to %s",
1036 before[L_NAME], after[L_NAME]);
1049 if ((strlen(before_group_ou) == 0) ||
1050 (strlen(before_group_membership) == 0))
1053 "Unable to find the group OU for group %s", before[L_NAME]);
1057 com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
1058 rc = group_delete(ldap_handle, dn_path, before[L_NAME],
1059 before_group_membership, before_list_id);
1067 com_err(whoami, 0, "Creating group %s", after[L_NAME]);
1069 if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME],
1070 group_ou, group_membership,
1071 security_flag, CHECK_GROUPS,
1074 if (rc != AD_NO_GROUPS_FOUND)
1076 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
1077 (rc == AD_MULTIPLE_GROUPS_FOUND))
1079 rc = process_group(ldap_handle, dn_path, list_id,
1081 group_ou, group_membership,
1082 security_flag, CLEANUP_GROUPS,
1089 "Unable to create list %s", after[L_NAME]);
1096 com_err(whoami, 0, "Updating group %s information", after[L_NAME]);
1098 if (rc = moira_connect())
1100 critical_alert("AD incremental",
1101 "Error contacting Moira server : %s",
1108 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0,
1109 &ProcessGroup, after[L_MAILLIST]))
1114 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1,
1115 &ProcessGroup, after[L_MAILLIST]))
1119 if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME],
1120 group_ou, group_membership, security_flag,
1121 updateGroup, after[L_MAILLIST]))
1127 if (atoi(after[L_ACTIVE]))
1129 populate_group(ldap_handle, dn_path, after[L_NAME], group_ou,
1130 group_membership, security_flag, list_id);
1138 #define LM_EXTRA_ACTIVE (LM_END)
1139 #define LM_EXTRA_PUBLIC (LM_END+1)
1140 #define LM_EXTRA_HIDDEN (LM_END+2)
1141 #define LM_EXTRA_MAILLIST (LM_END+3)
1142 #define LM_EXTRA_GROUP (LM_END+4)
1143 #define LM_EXTRA_GID (LM_END+5)
1144 #define LMN_LIST_ID (LM_END+6)
1145 #define LM_LIST_ID (LM_END+7)
1146 #define LM_USER_ID (LM_END+8)
1147 #define LM_EXTRA_END (LM_END+9)
1149 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1150 char **before, int beforec, char **after, int afterc)
1152 LK_ENTRY *group_base;
1155 char *attr_array[3];
1156 char group_name[128];
1157 char user_name[128];
1158 char user_type[128];
1159 char moira_list_id[32];
1160 char moira_user_id[32];
1161 char group_membership[1];
1163 char machine_ou[256];
1171 char NewMachineName[1024];
1175 char *save_argv[U_END];
1179 memset(moira_list_id, '\0', sizeof(moira_list_id));
1180 memset(moira_user_id, '\0', sizeof(moira_user_id));
1184 if (afterc < LM_EXTRA_GID)
1187 if (!atoi(after[LM_EXTRA_ACTIVE]))
1190 "Unable to add %s to group %s : group not active",
1191 after[2], after[0]);
1197 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1200 strcpy(user_name, after[LM_MEMBER]);
1201 strcpy(group_name, after[LM_LIST]);
1202 strcpy(user_type, after[LM_TYPE]);
1204 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1206 if (afterc > LM_EXTRA_GROUP)
1208 strcpy(moira_list_id, after[LMN_LIST_ID]);
1209 strcpy(moira_user_id, after[LM_LIST_ID]);
1212 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1214 if (afterc > LMN_LIST_ID)
1216 strcpy(moira_list_id, after[LM_LIST_ID]);
1217 strcpy(moira_user_id, after[LM_USER_ID]);
1222 if (afterc > LM_EXTRA_GID)
1223 strcpy(moira_list_id, after[LMN_LIST_ID]);
1228 if (beforec < LM_EXTRA_GID)
1230 if (!atoi(before[LM_EXTRA_ACTIVE]))
1233 "Unable to add %s to group %s : group not active",
1234 before[2], before[0]);
1240 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1243 strcpy(user_name, before[LM_MEMBER]);
1244 strcpy(group_name, before[LM_LIST]);
1245 strcpy(user_type, before[LM_TYPE]);
1247 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1249 if (beforec > LM_EXTRA_GROUP)
1251 strcpy(moira_list_id, before[LMN_LIST_ID]);
1252 strcpy(moira_user_id, before[LM_LIST_ID]);
1255 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1257 if (beforec > LMN_LIST_ID)
1259 strcpy(moira_list_id, before[LM_LIST_ID]);
1260 strcpy(moira_user_id, before[LM_USER_ID]);
1265 if (beforec > LM_EXTRA_GID)
1266 strcpy(moira_list_id, before[LMN_LIST_ID]);
1273 "Unable to process group : beforec = %d, afterc = %d",
1278 args[L_NAME] = ptr[LM_LIST];
1279 args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
1280 args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
1281 args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
1282 args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
1283 args[L_GROUP] = ptr[LM_EXTRA_GROUP];
1284 args[L_GID] = ptr[LM_EXTRA_GID];
1287 memset(group_ou, '\0', sizeof(group_ou));
1288 get_group_membership(group_membership, group_ou, &security_flag, args);
1290 if (strlen(group_ou) == 0)
1292 com_err(whoami, 0, "Unable to find the group OU for group %s",
1297 if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name,
1298 group_ou, group_membership, security_flag,
1299 CHECK_GROUPS, args[L_MAILLIST]))
1301 if (rc != AD_NO_GROUPS_FOUND)
1303 if (rc = process_group(ldap_handle, dn_path, moira_list_id,
1304 group_name, group_ou, group_membership,
1305 security_flag, CLEANUP_GROUPS,
1308 if (rc != AD_NO_GROUPS_FOUND)
1311 com_err(whoami, 0, "Unable to add %s to group %s - "
1312 "unable to process group", user_name, group_name);
1314 com_err(whoami, 0, "Unable to remove %s from group %s - "
1315 "unable to process group", user_name, group_name);
1322 if (rc == AD_NO_GROUPS_FOUND)
1324 if (rc = moira_connect())
1326 critical_alert("AD incremental",
1327 "Error contacting Moira server : %s",
1332 com_err(whoami, 0, "creating group %s", group_name);
1335 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0,
1336 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
1341 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1,
1342 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
1346 if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST],
1347 group_ou, group_membership, security_flag, 0,
1348 ptr[LM_EXTRA_MAILLIST]))
1354 if (atoi(ptr[LM_EXTRA_ACTIVE]))
1356 populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou,
1357 group_membership, security_flag, moira_list_id);
1367 com_err(whoami, 0, "removing user %s from list %s", user_name,
1371 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1373 memset(machine_ou, '\0', sizeof(machine_ou));
1374 memset(NewMachineName, '\0', sizeof(NewMachineName));
1375 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER],
1376 machine_ou, NewMachineName))
1378 if (ptr[LM_MEMBER] != NULL)
1379 free(ptr[LM_MEMBER]);
1380 ptr[LM_MEMBER] = strdup(NewMachineName);
1381 pUserOu = machine_ou;
1384 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1386 strcpy(member, ptr[LM_MEMBER]);
1390 if((s = strchr(member, '@')) == (char *) NULL)
1392 strcat(member, "@mit.edu");
1394 if (ptr[LM_MEMBER] != NULL)
1395 free(ptr[LM_MEMBER]);
1396 ptr[LM_MEMBER] = strdup(member);
1399 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1401 s = strrchr(member, '.');
1403 strcat(s, ".mit.edu");
1405 if (ptr[LM_MEMBER] != NULL)
1406 free(ptr[LM_MEMBER]);
1407 ptr[LM_MEMBER] = strdup(member);
1411 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1414 pUserOu = contact_ou;
1416 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1418 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1422 pUserOu = kerberos_ou;
1424 if (rc = member_remove(ldap_handle, dn_path, group_name,
1425 group_ou, group_membership, ptr[LM_MEMBER],
1426 pUserOu, moira_list_id))
1427 com_err(whoami, 0, "Unable to remove %s from group %s", user_name,
1430 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1432 if (rc = moira_connect())
1434 critical_alert("AD incremental",
1435 "Error contacting Moira server : %s",
1440 if (rc = populate_group(ldap_handle, dn_path, group_name,
1441 group_ou, group_membership, security_flag,
1443 com_err(whoami, 0, "Unable to remove %s from group %s",
1444 user_name, group_name);
1450 com_err(whoami, 0, "Adding %s to list %s", user_name, group_name);
1453 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1455 memset(machine_ou, '\0', sizeof(machine_ou));
1456 memset(NewMachineName, '\0', sizeof(NewMachineName));
1458 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou,
1462 if (ptr[LM_MEMBER] != NULL)
1463 free(ptr[LM_MEMBER]);
1465 ptr[LM_MEMBER] = strdup(NewMachineName);
1466 pUserOu = machine_ou;
1468 else if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1470 strcpy(member, ptr[LM_MEMBER]);
1474 if((s = strchr(member, '@')) == (char *) NULL)
1476 strcat(member, "@mit.edu");
1478 if (ptr[LM_MEMBER] != NULL)
1479 free(ptr[LM_MEMBER]);
1480 ptr[LM_MEMBER] = strdup(member);
1483 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1485 s = strrchr(member, '.');
1487 strcat(s, ".mit.edu");
1489 if (ptr[LM_MEMBER] != NULL)
1490 free(ptr[LM_MEMBER]);
1491 ptr[LM_MEMBER] = strdup(member);
1495 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1498 pUserOu = contact_ou;
1500 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1502 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
1505 pUserOu = kerberos_ou;
1507 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1509 if ((rc = check_user(ldap_handle, dn_path, ptr[LM_MEMBER],
1510 moira_user_id)) == AD_NO_USER_FOUND)
1512 if (rc = moira_connect())
1514 critical_alert("AD incremental",
1515 "Error connection to Moira : %s",
1520 com_err(whoami, 0, "creating user %s", ptr[LM_MEMBER]);
1521 av[0] = ptr[LM_MEMBER];
1522 call_args[0] = (char *)ldap_handle;
1523 call_args[1] = dn_path;
1524 call_args[2] = moira_user_id;
1525 call_args[3] = NULL;
1534 sprintf(filter, "(&(objectClass=group)(cn=%s))", ptr[LM_MEMBER]);
1535 attr_array[0] = "cn";
1536 attr_array[1] = NULL;
1537 if ((rc = linklist_build(ldap_handle, dn_path, filter,
1538 attr_array, &group_base, &group_count,
1539 LDAP_SCOPE_SUBTREE)) != 0)
1541 com_err(whoami, 0, "Unable to process user %s : %s",
1542 ptr[LM_MEMBER], ldap_err2string(rc));
1548 com_err(whoami, 0, "Object already exists with name %s",
1553 linklist_free(group_base);
1558 if (rc = mr_query("get_user_account_by_login", 1, av,
1559 save_query_info, save_argv))
1562 com_err(whoami, 0, "Unable to create user %s : %s",
1563 ptr[LM_MEMBER], error_message(rc));
1567 if (rc = user_create(U_END, save_argv, call_args))
1570 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1577 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1589 if (rc = member_add(ldap_handle, dn_path, group_name,
1590 group_ou, group_membership, ptr[LM_MEMBER],
1591 pUserOu, moira_list_id))
1592 com_err(whoami, 0, "Unable to add %s to group %s", user_name, group_name);
1594 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1596 if (rc = moira_connect())
1598 critical_alert("AD incremental",
1599 "Error contacting Moira server : %s",
1604 if (rc = populate_group(ldap_handle, dn_path, group_name,
1605 group_ou, group_membership, security_flag,
1607 com_err(whoami, 0, "Unable to add %s to group %s",
1608 user_name, group_name);
1617 #define U_USER_ID 10
1618 #define U_HOMEDIR 11
1619 #define U_PROFILEDIR 12
1621 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1622 char **before, int beforec, char **after,
1625 LK_ENTRY *group_base;
1628 char *attr_array[3];
1631 char after_user_id[32];
1632 char before_user_id[32];
1634 char *save_argv[U_END];
1636 if ((beforec == 0) && (afterc == 0))
1639 memset(after_user_id, '\0', sizeof(after_user_id));
1640 memset(before_user_id, '\0', sizeof(before_user_id));
1642 if (beforec > U_USER_ID)
1643 strcpy(before_user_id, before[U_USER_ID]);
1645 if (afterc > U_USER_ID)
1646 strcpy(after_user_id, after[U_USER_ID]);
1648 if ((beforec == 0) && (afterc == 0)) /*this case should never happen */
1651 if ((beforec == 0) && (afterc != 0))
1653 /*this case only happens when the account*/
1654 /*account is first created but not usable*/
1656 com_err(whoami, 0, "Unable to process user %s because the user account "
1657 "is not yet usable", after[U_NAME]);
1661 /*this case only happens when the account is expunged */
1663 if ((beforec != 0) && (afterc == 0))
1665 if (atoi(before[U_STATE]) == 0)
1667 com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]);
1668 user_delete(ldap_handle, dn_path, before[U_NAME], before_user_id);
1672 com_err(whoami, 0, "Unable to process because user %s has been "
1673 "previously expungeded", before[U_NAME]);
1678 /*process anything that gets here*/
1680 if ((rc = check_user(ldap_handle, dn_path, before[U_NAME],
1681 before_user_id)) == AD_NO_USER_FOUND)
1683 if (!check_string(after[U_NAME]))
1686 if (rc = moira_connect())
1688 critical_alert("AD incremental",
1689 "Error connection to Moira : %s",
1694 com_err(whoami, 0, "creating user %s", after[U_NAME]);
1696 av[0] = after[U_NAME];
1697 call_args[0] = (char *)ldap_handle;
1698 call_args[1] = dn_path;
1699 call_args[2] = after_user_id;
1700 call_args[3] = NULL;
1708 sprintf(filter, "(&(objectClass=group)(cn=%s))", after[U_NAME]);
1709 attr_array[0] = "cn";
1710 attr_array[1] = NULL;
1712 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
1713 &group_base, &group_count,
1714 LDAP_SCOPE_SUBTREE)) != 0)
1716 com_err(whoami, 0, "Unable to process user %s : %s",
1717 after[U_NAME], ldap_err2string(rc));
1721 if (group_count >= 1)
1723 com_err(whoami, 0, "Object already exists with name %s",
1728 linklist_free(group_base);
1733 if (rc = mr_query("get_user_account_by_login", 1, av,
1734 save_query_info, save_argv))
1737 com_err(whoami, 0, "Unable to create user %s : %s",
1738 after[U_NAME], error_message(rc));
1742 if (rc = user_create(U_END, save_argv, call_args))
1744 com_err(whoami, 0, "Unable to create user %s : %s",
1745 after[U_NAME], error_message(rc));
1752 com_err(whoami, 0, "Unable to create user %s", after[U_NAME]);
1764 if (strcmp(before[U_NAME], after[U_NAME]))
1766 if ((check_string(before[U_NAME])) && (check_string(after[U_NAME])))
1768 com_err(whoami, 0, "changing user %s to %s",
1769 before[U_NAME], after[U_NAME]);
1771 if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME],
1772 after[U_NAME])) != LDAP_SUCCESS)
1779 com_err(whoami, 0, "updating user %s information", after[U_NAME]);
1780 rc = user_update(ldap_handle, dn_path, after[U_NAME],
1781 after[U_UID], after[U_MITID],
1782 after_user_id, atoi(after[U_STATE]),
1783 after[U_HOMEDIR], after[U_PROFILEDIR],
1784 after[U_FIRST], after[U_MIDDLE], after[U_LAST]);
1789 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
1790 char *oldValue, char *newValue,
1791 char ***modvalues, int type)
1793 LK_ENTRY *linklist_ptr;
1797 if (((*modvalues) = calloc(1,
1798 (modvalue_count + 1) * sizeof(char *))) == NULL)
1803 for (i = 0; i < (modvalue_count + 1); i++)
1804 (*modvalues)[i] = NULL;
1806 if (modvalue_count != 0)
1808 linklist_ptr = linklist_base;
1809 for (i = 0; i < modvalue_count; i++)
1811 if ((oldValue != NULL) && (newValue != NULL))
1813 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1816 if (type == REPLACE)
1818 if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1821 memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1822 strcpy((*modvalues)[i], newValue);
1826 if (((*modvalues)[i] = calloc(1,
1827 (int)(cPtr - linklist_ptr->value) +
1828 (linklist_ptr->length -
1830 strlen(newValue) + 1)) == NULL)
1832 memset((*modvalues)[i], '\0',
1833 (int)(cPtr - linklist_ptr->value) +
1834 (linklist_ptr->length - strlen(oldValue)) +
1835 strlen(newValue) + 1);
1836 memcpy((*modvalues)[i], linklist_ptr->value,
1837 (int)(cPtr - linklist_ptr->value));
1838 strcat((*modvalues)[i], newValue);
1839 strcat((*modvalues)[i],
1840 &linklist_ptr->value[(int)(cPtr -
1841 linklist_ptr->value) + strlen(oldValue)]);
1846 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1847 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1848 memcpy((*modvalues)[i], linklist_ptr->value,
1849 linklist_ptr->length);
1854 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1855 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1856 memcpy((*modvalues)[i], linklist_ptr->value,
1857 linklist_ptr->length);
1859 linklist_ptr = linklist_ptr->next;
1861 (*modvalues)[i] = NULL;
1867 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
1868 char **attr_array, LK_ENTRY **linklist_base,
1869 int *linklist_count, unsigned long ScopeType)
1872 LDAPMessage *ldap_entry;
1876 (*linklist_base) = NULL;
1877 (*linklist_count) = 0;
1879 if ((rc = ldap_search_s(ldap_handle, dn_path, ScopeType,
1880 search_exp, attr_array, 0,
1881 &ldap_entry)) != LDAP_SUCCESS)
1883 if (rc != LDAP_SIZELIMIT_EXCEEDED)
1887 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base,
1890 ldap_msgfree(ldap_entry);
1894 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1895 LK_ENTRY **linklist_base, int *linklist_count)
1897 char distinguished_name[1024];
1898 LK_ENTRY *linklist_ptr;
1901 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1904 memset(distinguished_name, '\0', sizeof(distinguished_name));
1905 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1907 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1908 linklist_base)) != 0)
1911 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1913 memset(distinguished_name, '\0', sizeof(distinguished_name));
1914 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1916 if ((rc = retrieve_attributes(ldap_handle, ldap_entry,
1917 distinguished_name, linklist_base)) != 0)
1921 linklist_ptr = (*linklist_base);
1922 (*linklist_count) = 0;
1924 while (linklist_ptr != NULL)
1926 ++(*linklist_count);
1927 linklist_ptr = linklist_ptr->next;
1933 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1934 char *distinguished_name, LK_ENTRY **linklist_current)
1941 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry,
1944 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1946 ldap_memfree(Attribute);
1947 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
1950 retrieve_values(ldap_handle, ldap_entry, Attribute,
1951 distinguished_name, linklist_current);
1952 ldap_memfree(Attribute);
1956 ldap_ber_free(ptr, 0);
1961 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1962 char *Attribute, char *distinguished_name,
1963 LK_ENTRY **linklist_current)
1969 LK_ENTRY *linklist_previous;
1970 LDAP_BERVAL **ber_value;
1979 SID_IDENTIFIER_AUTHORITY *sid_auth;
1980 unsigned char *subauth_count;
1981 #endif /*LDAP_BEGUG*/
1984 memset(temp, '\0', sizeof(temp));
1986 if ((!strcmp(Attribute, "objectSid")) ||
1987 (!strcmp(Attribute, "objectGUID")))
1992 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1993 Ptr = (void **)ber_value;
1998 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1999 Ptr = (void **)str_value;
2007 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
2010 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
2011 linklist_previous->next = (*linklist_current);
2012 (*linklist_current) = linklist_previous;
2014 if (((*linklist_current)->attribute = calloc(1,
2015 strlen(Attribute) + 1)) == NULL)
2018 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
2019 strcpy((*linklist_current)->attribute, Attribute);
2023 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
2025 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
2028 memset((*linklist_current)->value, '\0', ber_length);
2029 memcpy((*linklist_current)->value,
2030 (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length);
2031 (*linklist_current)->length = ber_length;
2035 if (((*linklist_current)->value = calloc(1,
2036 strlen(*Ptr) + 1)) == NULL)
2039 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
2040 (*linklist_current)->length = strlen(*Ptr);
2041 strcpy((*linklist_current)->value, *Ptr);
2044 (*linklist_current)->ber_value = use_bervalue;
2046 if (((*linklist_current)->dn = calloc(1,
2047 strlen(distinguished_name) + 1)) == NULL)
2050 memset((*linklist_current)->dn, '\0',
2051 strlen(distinguished_name) + 1);
2052 strcpy((*linklist_current)->dn, distinguished_name);
2055 if (!strcmp(Attribute, "objectGUID"))
2057 guid = (GUID *)((*linklist_current)->value);
2059 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2060 guid->Data1, guid->Data2, guid->Data3,
2061 guid->Data4[0], guid->Data4[1], guid->Data4[2],
2062 guid->Data4[3], guid->Data4[4], guid->Data4[5],
2063 guid->Data4[6], guid->Data4[7]);
2064 print_to_screen(" %20s : {%s}\n", Attribute, temp);
2066 else if (!strcmp(Attribute, "objectSid"))
2068 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
2071 print_to_screen(" Revision = %d\n", sid->Revision);
2072 print_to_screen(" SID Identifier Authority:\n");
2073 sid_auth = &sid->IdentifierAuthority;
2074 if (sid_auth->Value[0])
2075 print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
2076 else if (sid_auth->Value[1])
2077 print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
2078 else if (sid_auth->Value[2])
2079 print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
2080 else if (sid_auth->Value[3])
2081 print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
2082 else if (sid_auth->Value[5])
2083 print_to_screen(" SECURITY_NT_AUTHORITY\n");
2085 print_to_screen(" UNKNOWN SID AUTHORITY\n");
2086 subauth_count = GetSidSubAuthorityCount(sid);
2087 print_to_screen(" SidSubAuthorityCount = %d\n",
2089 print_to_screen(" SidSubAuthority:\n");
2090 for (i = 0; i < *subauth_count; i++)
2092 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
2093 print_to_screen(" %u\n", *subauth);
2097 else if ((!memcmp(Attribute, "userAccountControl",
2098 strlen("userAccountControl"))) ||
2099 (!memcmp(Attribute, "sAMAccountType",
2100 strlen("sAmAccountType"))))
2102 intValue = atoi(*Ptr);
2103 print_to_screen(" %20s : %ld\n",Attribute, intValue);
2105 if (!memcmp(Attribute, "userAccountControl",
2106 strlen("userAccountControl")))
2108 if (intValue & UF_ACCOUNTDISABLE)
2109 print_to_screen(" %20s : %s\n",
2110 "", "Account disabled");
2112 print_to_screen(" %20s : %s\n",
2113 "", "Account active");
2114 if (intValue & UF_HOMEDIR_REQUIRED)
2115 print_to_screen(" %20s : %s\n",
2116 "", "Home directory required");
2117 if (intValue & UF_LOCKOUT)
2118 print_to_screen(" %20s : %s\n",
2119 "", "Account locked out");
2120 if (intValue & UF_PASSWD_NOTREQD)
2121 print_to_screen(" %20s : %s\n",
2122 "", "No password required");
2123 if (intValue & UF_PASSWD_CANT_CHANGE)
2124 print_to_screen(" %20s : %s\n",
2125 "", "Cannot change password");
2126 if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
2127 print_to_screen(" %20s : %s\n",
2128 "", "Temp duplicate account");
2129 if (intValue & UF_NORMAL_ACCOUNT)
2130 print_to_screen(" %20s : %s\n",
2131 "", "Normal account");
2132 if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
2133 print_to_screen(" %20s : %s\n",
2134 "", "Interdomain trust account");
2135 if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
2136 print_to_screen(" %20s : %s\n",
2137 "", "Workstation trust account");
2138 if (intValue & UF_SERVER_TRUST_ACCOUNT)
2139 print_to_screen(" %20s : %s\n",
2140 "", "Server trust account");
2145 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
2147 #endif /*LDAP_DEBUG*/
2150 if (str_value != NULL)
2151 ldap_value_free(str_value);
2153 if (ber_value != NULL)
2154 ldap_value_free_len(ber_value);
2157 (*linklist_current) = linklist_previous;
2162 int moira_connect(void)
2167 if (!mr_connections++)
2171 memset(HostName, '\0', sizeof(HostName));
2172 strcpy(HostName, "ttsp");
2173 rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
2177 rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
2186 int check_winad(void)
2190 for (i = 0; file_exists(STOP_FILE); i++)
2194 critical_alert("AD incremental",
2195 "WINAD incremental failed (%s exists): %s",
2196 STOP_FILE, tbl_buf);
2206 int moira_disconnect(void)
2209 if (!--mr_connections)
2217 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
2218 char *distinguished_name)
2222 CName = ldap_get_dn(ldap_handle, ldap_entry);
2227 strcpy(distinguished_name, CName);
2228 ldap_memfree(CName);
2231 int linklist_create_entry(char *attribute, char *value,
2232 LK_ENTRY **linklist_entry)
2234 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
2236 if (!(*linklist_entry))
2241 memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
2242 (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
2243 memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
2244 strcpy((*linklist_entry)->attribute, attribute);
2245 (*linklist_entry)->value = calloc(1, strlen(value) + 1);
2246 memset((*linklist_entry)->value, '\0', strlen(value) + 1);
2247 strcpy((*linklist_entry)->value, value);
2248 (*linklist_entry)->length = strlen(value);
2249 (*linklist_entry)->next = NULL;
2254 void print_to_screen(const char *fmt, ...)
2258 va_start(pvar, fmt);
2259 vfprintf(stderr, fmt, pvar);
2264 int get_group_membership(char *group_membership, char *group_ou,
2265 int *security_flag, char **av)
2270 maillist_flag = atoi(av[L_MAILLIST]);
2271 group_flag = atoi(av[L_GROUP]);
2273 if (security_flag != NULL)
2274 (*security_flag) = 0;
2276 if ((maillist_flag) && (group_flag))
2278 if (group_membership != NULL)
2279 group_membership[0] = 'B';
2281 if (security_flag != NULL)
2282 (*security_flag) = 1;
2284 if (group_ou != NULL)
2285 strcpy(group_ou, group_ou_both);
2287 else if ((!maillist_flag) && (group_flag))
2289 if (group_membership != NULL)
2290 group_membership[0] = 'S';
2292 if (security_flag != NULL)
2293 (*security_flag) = 1;
2295 if (group_ou != NULL)
2296 strcpy(group_ou, group_ou_security);
2298 else if ((maillist_flag) && (!group_flag))
2300 if (group_membership != NULL)
2301 group_membership[0] = 'D';
2303 if (group_ou != NULL)
2304 strcpy(group_ou, group_ou_distribution);
2308 if (group_membership != NULL)
2309 group_membership[0] = 'N';
2311 if (group_ou != NULL)
2312 strcpy(group_ou, group_ou_neither);
2318 int group_rename(LDAP *ldap_handle, char *dn_path,
2319 char *before_group_name, char *before_group_membership,
2320 char *before_group_ou, int before_security_flag,
2321 char *before_desc, char *after_group_name,
2322 char *after_group_membership, char *after_group_ou,
2323 int after_security_flag, char *after_desc,
2324 char *MoiraId, char *filter, char *maillist)
2329 char new_dn_path[512];
2332 char mail_nickname[256];
2333 char proxy_address[256];
2334 char address_book[256];
2335 char *attr_array[3];
2336 char *mitMoiraId_v[] = {NULL, NULL};
2337 char *name_v[] = {NULL, NULL};
2338 char *samAccountName_v[] = {NULL, NULL};
2339 char *groupTypeControl_v[] = {NULL, NULL};
2340 char *mail_v[] = {NULL, NULL};
2341 char *proxy_address_v[] = {NULL, NULL};
2342 char *mail_nickname_v[] = {NULL, NULL};
2343 char *report_to_originator_v[] = {NULL, NULL};
2344 char *address_book_v[] = {NULL, NULL};
2345 char *legacy_exchange_dn_v[] = {NULL, NULL};
2346 u_int groupTypeControl;
2347 char groupTypeControlStr[80];
2348 char contact_mail[256];
2352 LK_ENTRY *group_base;
2354 int MailDisabled = 0;
2356 if(UseGroupUniversal)
2357 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2359 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2361 if (!check_string(before_group_name))
2364 "Unable to process invalid LDAP list name %s",
2366 return(AD_INVALID_NAME);
2369 if (!check_string(after_group_name))
2372 "Unable to process invalid LDAP list name %s", after_group_name);
2373 return(AD_INVALID_NAME);
2383 sprintf(filter, "(&(objectClass=user)(cn=%s))", after_group_name);
2384 attr_array[0] = "cn";
2385 attr_array[1] = NULL;
2387 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2388 &group_base, &group_count,
2389 LDAP_SCOPE_SUBTREE)) != 0)
2391 com_err(whoami, 0, "Unable to process group %s : %s",
2392 after_group_name, ldap_err2string(rc));
2398 com_err(whoami, 0, "Object already exists with name %s",
2403 linklist_free(group_base);
2412 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
2413 before_group_membership,
2414 MoiraId, "distinguishedName", &group_base,
2415 &group_count, filter))
2418 if (group_count == 0)
2420 return(AD_NO_GROUPS_FOUND);
2423 if (group_count != 1)
2425 com_err(whoami, 0, "Unable to process multiple groups with "
2426 "MoiraId = %s exist in the AD", MoiraId);
2427 return(AD_MULTIPLE_GROUPS_FOUND);
2430 strcpy(old_dn, group_base->value);
2432 linklist_free(group_base);
2435 attr_array[0] = "sAMAccountName";
2436 attr_array[1] = NULL;
2438 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2439 &group_base, &group_count,
2440 LDAP_SCOPE_SUBTREE)) != 0)
2442 com_err(whoami, 0, "Unable to get list %s dn : %s",
2443 after_group_name, ldap_err2string(rc));
2447 if (group_count != 1)
2450 "Unable to get sAMAccountName for group %s",
2452 return(AD_LDAP_FAILURE);
2455 strcpy(sam_name, group_base->value);
2456 linklist_free(group_base);
2460 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2461 sprintf(new_dn, "cn=%s", after_group_name);
2462 sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain));
2463 sprintf(contact_mail, "%s@mit.edu", after_group_name);
2464 sprintf(proxy_address, "SMTP:%s@%s", after_group_name,
2465 lowercase(ldap_domain));
2466 sprintf(mail_nickname, "%s", after_group_name);
2468 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
2469 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2471 com_err(whoami, 0, "Unable to rename list from %s to %s : %s",
2472 before_group_name, after_group_name, ldap_err2string(rc));
2476 name_v[0] = after_group_name;
2478 if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)],
2479 group_suffix, strlen(group_suffix)))
2481 sprintf(sam_name, "%s%s", after_group_name, group_suffix);
2486 "Unable to rename list from %s to %s : sAMAccountName not found",
2487 before_group_name, after_group_name);
2491 samAccountName_v[0] = sam_name;
2493 if (after_security_flag)
2494 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2496 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2497 groupTypeControl_v[0] = groupTypeControlStr;
2498 mitMoiraId_v[0] = MoiraId;
2500 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
2501 rc = attribute_update(ldap_handle, new_dn, after_desc, "description",
2504 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2505 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2506 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2507 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
2511 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2513 mail_nickname_v[0] = mail_nickname;
2514 proxy_address_v[0] = proxy_address;
2516 report_to_originator_v[0] = "TRUE";
2518 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2519 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2520 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2521 ADD_ATTR("reportToOriginator", report_to_originator_v,
2526 mail_nickname_v[0] = NULL;
2527 proxy_address_v[0] = NULL;
2529 legacy_exchange_dn_v[0] = NULL;
2530 address_book_v[0] = NULL;
2531 report_to_originator_v[0] = NULL;
2533 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2534 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2535 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2536 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2537 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2538 ADD_ATTR("reportToOriginator", report_to_originator_v,
2544 if(atoi(maillist) && email_isvalid(contact_mail))
2546 mail_v[0] = contact_mail;
2547 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2553 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2556 "Unable to modify list data for %s after renaming: %s",
2557 after_group_name, ldap_err2string(rc));
2560 for (i = 0; i < n; i++)
2566 int group_create(int ac, char **av, void *ptr)
2571 char new_group_name[256];
2572 char sam_group_name[256];
2573 char cn_group_name[256];
2575 char contact_mail[256];
2576 char mail_nickname[256];
2577 char proxy_address[256];
2578 char address_book[256];
2579 char *cn_v[] = {NULL, NULL};
2580 char *objectClass_v[] = {"top", "group", NULL};
2582 char *samAccountName_v[] = {NULL, NULL};
2583 char *altSecurityIdentities_v[] = {NULL, NULL};
2584 char *member_v[] = {NULL, NULL};
2585 char *name_v[] = {NULL, NULL};
2586 char *desc_v[] = {NULL, NULL};
2587 char *info_v[] = {NULL, NULL};
2588 char *mitMoiraId_v[] = {NULL, NULL};
2589 char *groupTypeControl_v[] = {NULL, NULL};
2590 char *mail_v[] = {NULL, NULL};
2591 char *proxy_address_v[] = {NULL, NULL};
2592 char *mail_nickname_v[] = {NULL, NULL};
2593 char *report_to_originator_v[] = {NULL, NULL};
2594 char *address_book_v[] = {NULL, NULL};
2595 char *legacy_exchange_dn_v[] = {NULL, NULL};
2596 char groupTypeControlStr[80];
2597 char group_membership[1];
2600 u_int groupTypeControl;
2604 int MailDisabled = 0;
2606 LK_ENTRY *group_base;
2609 char *attr_array[3];
2613 if(UseGroupUniversal)
2614 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2616 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2618 if (!check_string(av[L_NAME]))
2620 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2622 return(AD_INVALID_NAME);
2625 updateGroup = (int)call_args[4];
2626 memset(group_ou, 0, sizeof(group_ou));
2627 memset(group_membership, 0, sizeof(group_membership));
2630 get_group_membership(group_membership, group_ou, &security_flag, av);
2632 strcpy(new_group_name, av[L_NAME]);
2633 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2634 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2635 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2636 sprintf(mail_nickname, "%s", av[L_NAME]);
2639 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2641 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2645 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2646 groupTypeControl_v[0] = groupTypeControlStr;
2648 strcpy(cn_group_name, av[L_NAME]);
2650 samAccountName_v[0] = sam_group_name;
2651 name_v[0] = new_group_name;
2652 cn_v[0] = new_group_name;
2655 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2656 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2657 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2658 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2659 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2663 if(atoi(av[L_MAILLIST]))
2668 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2669 attr_array[0] = "cn";
2670 attr_array[1] = NULL;
2672 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2673 filter, attr_array, &group_base,
2675 LDAP_SCOPE_SUBTREE)) != 0)
2677 com_err(whoami, 0, "Unable to process group %s : %s",
2678 av[L_NAME], ldap_err2string(rc));
2684 com_err(whoami, 0, "Object already exists with name %s",
2689 linklist_free(group_base);
2694 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2696 mail_nickname_v[0] = mail_nickname;
2697 report_to_originator_v[0] = "TRUE";
2699 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2700 ADD_ATTR("reportToOriginator", report_to_originator_v,
2706 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2708 mail_v[0] = contact_mail;
2709 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2713 if (strlen(av[L_DESC]) != 0)
2715 desc_v[0] = av[L_DESC];
2716 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2719 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2721 if (strlen(av[L_ACE_NAME]) != 0)
2723 sprintf(info, "The Administrator of this list is: %s",
2726 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2729 if (strlen(call_args[5]) != 0)
2731 mitMoiraId_v[0] = call_args[5];
2732 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2737 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2739 for (i = 0; i < n; i++)
2742 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2744 com_err(whoami, 0, "Unable to create list %s in AD : %s",
2745 av[L_NAME], ldap_err2string(rc));
2751 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2753 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2754 "description", av[L_NAME]);
2755 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2756 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2760 if (strlen(call_args[5]) != 0)
2762 mitMoiraId_v[0] = call_args[5];
2763 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2766 if (!(atoi(av[L_ACTIVE])))
2769 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2774 if(atoi(av[L_MAILLIST]))
2779 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2780 attr_array[0] = "cn";
2781 attr_array[1] = NULL;
2783 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2784 filter, attr_array, &group_base,
2786 LDAP_SCOPE_SUBTREE)) != 0)
2788 com_err(whoami, 0, "Unable to process group %s : %s",
2789 av[L_NAME], ldap_err2string(rc));
2795 com_err(whoami, 0, "Object already exists with name %s",
2800 linklist_free(group_base);
2805 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2807 mail_nickname_v[0] = mail_nickname;
2808 report_to_originator_v[0] = "TRUE";
2810 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2811 ADD_ATTR("reportToOriginator", report_to_originator_v,
2817 mail_nickname_v[0] = NULL;
2818 proxy_address_v[0] = NULL;
2819 legacy_exchange_dn_v[0] = NULL;
2820 address_book_v[0] = NULL;
2821 report_to_originator_v[0] = NULL;
2823 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2824 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2825 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2826 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2828 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2829 ADD_ATTR("reportToOriginator", report_to_originator_v,
2835 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2837 mail_v[0] = contact_mail;
2838 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2843 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2852 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2854 for (i = 0; i < n; i++)
2857 if (rc != LDAP_SUCCESS)
2859 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2860 av[L_NAME], ldap_err2string(rc));
2867 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2868 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2870 return(LDAP_SUCCESS);
2873 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2874 char *TargetGroupName, int HiddenGroup,
2875 char *AceType, char *AceName)
2877 char filter_exp[1024];
2878 char *attr_array[5];
2879 char search_path[512];
2881 char TemplateDn[512];
2882 char TemplateSamName[128];
2884 char TargetSamName[128];
2885 char AceSamAccountName[128];
2887 unsigned char AceSid[128];
2888 unsigned char UserTemplateSid[128];
2889 char acBERBuf[N_SD_BER_BYTES];
2890 char GroupSecurityTemplate[256];
2891 char hide_addres_lists[256];
2892 char address_book[256];
2893 char *hide_address_lists_v[] = {NULL, NULL};
2894 char *address_book_v[] = {NULL, NULL};
2896 int UserTemplateSidCount;
2903 int array_count = 0;
2905 LK_ENTRY *group_base;
2906 LDAP_BERVAL **ppsValues;
2907 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2908 { N_SD_BER_BYTES, acBERBuf },
2911 LDAPControl *apsServerControls[] = {&sControl, NULL};
2914 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
2915 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
2916 BEREncodeSecurityBits(dwInfo, acBERBuf);
2918 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
2919 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
2920 attr_array[0] = "sAMAccountName";
2921 attr_array[1] = NULL;
2925 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2926 &group_base, &group_count,
2927 LDAP_SCOPE_SUBTREE) != 0))
2930 if (group_count != 1)
2932 linklist_free(group_base);
2936 strcpy(TargetDn, group_base->dn);
2937 strcpy(TargetSamName, group_base->value);
2938 linklist_free(group_base);
2942 UserTemplateSidCount = 0;
2943 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2944 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2945 memset(AceSid, '\0', sizeof(AceSid));
2950 if (strlen(AceName) != 0)
2952 if (!strcmp(AceType, "LIST"))
2954 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
2955 strcpy(root_ou, group_ou_root);
2957 else if (!strcmp(AceType, "USER"))
2959 sprintf(AceSamAccountName, "%s", AceName);
2960 strcpy(root_ou, user_ou);
2963 if (strlen(AceSamAccountName) != 0)
2965 sprintf(search_path, "%s", dn_path);
2966 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2967 attr_array[0] = "objectSid";
2968 attr_array[1] = NULL;
2972 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2973 attr_array, &group_base, &group_count,
2974 LDAP_SCOPE_SUBTREE) != 0))
2976 if (group_count == 1)
2978 strcpy(AceDn, group_base->dn);
2979 AceSidCount = group_base->length;
2980 memcpy(AceSid, group_base->value, AceSidCount);
2982 linklist_free(group_base);
2988 if (AceSidCount == 0)
2990 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
2991 "have an AD SID.", TargetGroupName, AceName, AceType);
2992 com_err(whoami, 0, " Non-admin security group template will be used.");
2996 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2997 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
2998 attr_array[0] = "objectSid";
2999 attr_array[1] = NULL;
3004 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3005 attr_array, &group_base, &group_count,
3006 LDAP_SCOPE_SUBTREE) != 0))
3009 if ((rc != 0) || (group_count != 1))
3011 com_err(whoami, 0, "Unable to process user security template: %s",
3017 UserTemplateSidCount = group_base->length;
3018 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3020 linklist_free(group_base);
3027 if (AceSidCount == 0)
3029 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3030 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3034 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3035 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3040 if (AceSidCount == 0)
3042 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3043 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3047 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
3048 sprintf(filter_exp, "(sAMAccountName=%s)",
3049 NOT_HIDDEN_GROUP_WITH_ADMIN);
3053 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3054 attr_array[0] = "sAMAccountName";
3055 attr_array[1] = NULL;
3059 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3060 &group_base, &group_count,
3061 LDAP_SCOPE_SUBTREE) != 0))
3064 if (group_count != 1)
3066 linklist_free(group_base);
3067 com_err(whoami, 0, "Unable to process group security template: %s - "
3068 "security not set", GroupSecurityTemplate);
3072 strcpy(TemplateDn, group_base->dn);
3073 strcpy(TemplateSamName, group_base->value);
3074 linklist_free(group_base);
3078 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3079 rc = ldap_search_ext_s(ldap_handle,
3091 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3093 com_err(whoami, 0, "Unable to find group security template: %s - "
3094 "security not set", GroupSecurityTemplate);
3098 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3100 if (ppsValues == NULL)
3102 com_err(whoami, 0, "Unable to find group security descriptor for group "
3103 "%s - security not set", GroupSecurityTemplate);
3107 if (AceSidCount != 0)
3109 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3112 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3114 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3115 UserTemplateSidCount))
3117 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3125 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3126 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3132 hide_address_lists_v[0] = "TRUE";
3133 address_book_v[0] = NULL;
3134 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3136 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3138 hide_address_lists_v[0] = NULL;
3139 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3146 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3148 for (i = 0; i < n; i++)
3151 ldap_value_free_len(ppsValues);
3152 ldap_msgfree(psMsg);
3154 if (rc != LDAP_SUCCESS)
3156 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3157 TargetGroupName, ldap_err2string(rc));
3159 if (AceSidCount != 0)
3162 "Trying to set security for group %s without admin.",
3165 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3166 HiddenGroup, "", ""))
3168 com_err(whoami, 0, "Unable to set security for group %s.",
3179 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3180 char *group_membership, char *MoiraId)
3182 LK_ENTRY *group_base;
3188 if (!check_string(group_name))
3191 "Unable to process invalid LDAP list name %s", group_name);
3192 return(AD_INVALID_NAME);
3195 memset(filter, '\0', sizeof(filter));
3198 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3200 if (rc = ad_get_group(ldap_handle, temp, group_name,
3201 group_membership, MoiraId,
3202 "distinguishedName", &group_base,
3203 &group_count, filter))
3206 if (group_count == 1)
3208 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
3210 linklist_free(group_base);
3211 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3212 group_name, ldap_err2string(rc));
3215 linklist_free(group_base);
3219 linklist_free(group_base);
3220 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
3221 return(AD_NO_GROUPS_FOUND);
3227 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3233 return(N_SD_BER_BYTES);
3236 int process_lists(int ac, char **av, void *ptr)
3241 char group_membership[2];
3247 memset(group_ou, '\0', sizeof(group_ou));
3248 memset(group_membership, '\0', sizeof(group_membership));
3249 get_group_membership(group_membership, group_ou, &security_flag, av);
3250 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
3251 group_ou, group_membership, call_args[2],
3252 (char *)call_args[3], "");
3256 int member_list_build(int ac, char **av, void *ptr)
3264 strcpy(temp, av[ACE_NAME]);
3266 if (!check_string(temp))
3269 if (!strcmp(av[ACE_TYPE], "USER"))
3271 if (!((int)call_args[3] & MOIRA_USERS))
3274 else if (!strcmp(av[ACE_TYPE], "STRING"))
3278 if((s = strchr(temp, '@')) == (char *) NULL)
3280 strcat(temp, "@mit.edu");
3283 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3285 s = strrchr(temp, '.');
3287 strcat(s, ".mit.edu");
3291 if (!((int)call_args[3] & MOIRA_STRINGS))
3294 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3298 else if (!strcmp(av[ACE_TYPE], "LIST"))
3300 if (!((int)call_args[3] & MOIRA_LISTS))
3303 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3305 if (!((int)call_args[3] & MOIRA_KERBEROS))
3308 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3316 linklist = member_base;
3320 if (!strcasecmp(temp, linklist->member))
3323 linklist = linklist->next;
3326 linklist = calloc(1, sizeof(LK_ENTRY));
3328 linklist->dn = NULL;
3329 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3330 strcpy(linklist->list, call_args[2]);
3331 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3332 strcpy(linklist->type, av[ACE_TYPE]);
3333 linklist->member = calloc(1, strlen(temp) + 1);
3334 strcpy(linklist->member, temp);
3335 linklist->next = member_base;
3336 member_base = linklist;
3341 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3342 char *group_ou, char *group_membership, char *user_name,
3343 char *UserOu, char *MoiraId)
3345 char distinguished_name[1024];
3349 char *attr_array[3];
3354 LK_ENTRY *group_base;
3358 if (!check_string(group_name))
3359 return(AD_INVALID_NAME);
3361 memset(filter, '\0', sizeof(filter));
3365 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3366 group_membership, MoiraId,
3367 "distinguishedName", &group_base,
3368 &group_count, filter))
3371 if (group_count != 1)
3373 com_err(whoami, 0, "Unable to find list %s in AD",
3375 linklist_free(group_base);
3381 strcpy(distinguished_name, group_base->value);
3382 linklist_free(group_base);
3386 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3388 modvalues[0] = temp;
3389 modvalues[1] = NULL;
3392 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3394 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3396 for (i = 0; i < n; i++)
3399 if (rc == LDAP_UNWILLING_TO_PERFORM)
3402 if (rc != LDAP_SUCCESS)
3404 com_err(whoami, 0, "Unable to modify list %s members : %s",
3405 group_name, ldap_err2string(rc));
3409 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3413 if(!strcmp(UserOu, contact_ou) &&
3414 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3416 memset(temp, '\0', sizeof(temp));
3417 strcpy(temp, user_name);
3418 s = strchr(temp, '@');
3421 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3423 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3424 &group_base, &group_count,
3425 LDAP_SCOPE_SUBTREE) != 0))
3431 linklist_free(group_base);
3436 sprintf(filter, "(distinguishedName=%s)", temp);
3437 attr_array[0] = "memberOf";
3438 attr_array[1] = NULL;
3440 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3441 &group_base, &group_count,
3442 LDAP_SCOPE_SUBTREE) != 0))
3448 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3450 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3460 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3461 char *group_ou, char *group_membership, char *user_name,
3462 char *UserOu, char *MoiraId)
3464 char distinguished_name[1024];
3472 LK_ENTRY *group_base;
3475 if (!check_string(group_name))
3476 return(AD_INVALID_NAME);
3479 memset(filter, '\0', sizeof(filter));
3483 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3484 group_membership, MoiraId,
3485 "distinguishedName", &group_base,
3486 &group_count, filter))
3489 if (group_count != 1)
3491 linklist_free(group_base);
3494 com_err(whoami, 0, "Unable to find list %s in AD",
3496 return(AD_MULTIPLE_GROUPS_FOUND);
3499 strcpy(distinguished_name, group_base->value);
3500 linklist_free(group_base);
3504 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3505 modvalues[0] = temp;
3506 modvalues[1] = NULL;
3509 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3511 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3513 if (rc == LDAP_ALREADY_EXISTS)
3516 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3518 if (rc == LDAP_UNWILLING_TO_PERFORM)
3522 for (i = 0; i < n; i++)
3525 if (rc != LDAP_SUCCESS)
3527 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3528 user_name, group_name, ldap_err2string(rc));
3534 int contact_remove_email(LDAP *ld, char *bind_path,
3535 LK_ENTRY **linklist_base, int linklist_current)
3539 char *mail_v[] = {NULL, NULL};
3547 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3548 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3549 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3550 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3553 gPtr = (*linklist_base);
3556 rc = ldap_modify_s(ld, gPtr->dn, mods);
3558 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3560 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3561 gPtr->dn, ldap_err2string(rc));
3568 for (i = 0; i < n; i++)
3574 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3577 LK_ENTRY *group_base;
3580 char cn_user_name[256];
3581 char contact_name[256];
3582 char mail_nickname[256];
3583 char proxy_address_internal[256];
3584 char proxy_address_external[256];
3585 char target_address[256];
3586 char internal_contact_name[256];
3589 char mit_address_book[256];
3590 char default_address_book[256];
3591 char contact_address_book[256];
3592 char *email_v[] = {NULL, NULL};
3593 char *cn_v[] = {NULL, NULL};
3594 char *contact_v[] = {NULL, NULL};
3595 char *mail_nickname_v[] = {NULL, NULL};
3596 char *proxy_address_internal_v[] = {NULL, NULL};
3597 char *proxy_address_external_v[] = {NULL, NULL};
3598 char *target_address_v[] = {NULL, NULL};
3599 char *mit_address_book_v[] = {NULL, NULL};
3600 char *default_address_book_v[] = {NULL, NULL};
3601 char *contact_address_book_v[] = {NULL, NULL};
3602 char *hide_address_lists_v[] = {NULL, NULL};
3603 char *attr_array[3];
3605 char *objectClass_v[] = {"top", "person",
3606 "organizationalPerson",
3608 char *name_v[] = {NULL, NULL};
3609 char *desc_v[] = {NULL, NULL};
3615 if (!check_string(user))
3617 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3618 return(AD_INVALID_NAME);
3622 strcpy(contact_name, mail);
3623 strcpy(internal_contact_name, mail);
3625 if((s = strchr(internal_contact_name, '@')) != NULL) {
3629 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
3630 sprintf(target_address, "SMTP:%s", contact_name);
3631 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3632 sprintf(mail_nickname, "%s", internal_contact_name);
3634 cn_v[0] = cn_user_name;
3635 contact_v[0] = contact_name;
3637 desc_v[0] = "Auto account created by Moira";
3639 proxy_address_internal_v[0] = proxy_address_internal;
3640 proxy_address_external_v[0] = proxy_address_external;
3641 mail_nickname_v[0] = mail_nickname;
3642 target_address_v[0] = target_address;
3643 mit_address_book_v[0] = mit_address_book;
3644 default_address_book_v[0] = default_address_book;
3645 contact_address_book_v[0] = contact_address_book;
3646 strcpy(new_dn, cn_user_name);
3649 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3650 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3651 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3652 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3653 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3657 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3662 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3663 attr_array[0] = "cn";
3664 attr_array[1] = NULL;
3666 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3667 &group_base, &group_count,
3668 LDAP_SCOPE_SUBTREE)) != 0)
3670 com_err(whoami, 0, "Unable to process contact %s : %s",
3671 user, ldap_err2string(rc));
3677 com_err(whoami, 0, "Object already exists with name %s",
3682 linklist_free(group_base);
3686 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3687 attr_array[0] = "cn";
3688 attr_array[1] = NULL;
3690 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3691 &group_base, &group_count,
3692 LDAP_SCOPE_SUBTREE)) != 0)
3694 com_err(whoami, 0, "Unable to process contact %s : %s",
3695 user, ldap_err2string(rc));
3701 com_err(whoami, 0, "Object already exists with name %s",
3706 linklist_free(group_base);
3710 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3711 attr_array[0] = "cn";
3712 attr_array[1] = NULL;
3714 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3715 &group_base, &group_count,
3716 LDAP_SCOPE_SUBTREE)) != 0)
3718 com_err(whoami, 0, "Unable to process contact %s : %s",
3719 user, ldap_err2string(rc));
3725 com_err(whoami, 0, "Object already exists with name %s",
3730 linklist_free(group_base);
3734 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3735 attr_array[0] = "cn";
3736 attr_array[1] = NULL;
3738 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3739 &group_base, &group_count,
3740 LDAP_SCOPE_SUBTREE)) != 0)
3742 com_err(whoami, 0, "Unable to process contact %s : %s",
3743 user, ldap_err2string(rc));
3749 com_err(whoami, 0, "Object already exists with name %s",
3754 linklist_free(group_base);
3758 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3759 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3760 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3761 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3763 hide_address_lists_v[0] = "TRUE";
3764 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3771 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3773 for (i = 0; i < n; i++)
3779 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS) &&
3780 !strcmp(group_ou, contact_ou) && email_isvalid(mail))
3784 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
3785 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
3786 ADD_ATTR("proxyAddresses", proxy_address_external_v,
3788 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
3790 hide_address_lists_v[0] = "TRUE";
3791 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3795 rc = ldap_modify_s(ld, new_dn, mods);
3799 com_err(whoami, 0, "Unable to update contact %s", mail);
3802 for (i = 0; i < n; i++)
3807 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3810 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3811 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3812 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3813 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3814 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3816 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3818 for (i = 0; i < n; i++)
3822 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3824 com_err(whoami, 0, "Unable to create contact %s : %s",
3825 user, ldap_err2string(rc));
3832 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3833 char *Uid, char *MitId, char *MoiraId, int State,
3834 char *WinHomeDir, char *WinProfileDir, char *first,
3835 char *middle, char *last)
3838 LK_ENTRY *group_base;
3840 char distinguished_name[512];
3841 char displayName[256];
3842 char *mitMoiraId_v[] = {NULL, NULL};
3843 char *uid_v[] = {NULL, NULL};
3844 char *mitid_v[] = {NULL, NULL};
3845 char *homedir_v[] = {NULL, NULL};
3846 char *winProfile_v[] = {NULL, NULL};
3847 char *drives_v[] = {NULL, NULL};
3848 char *userAccountControl_v[] = {NULL, NULL};
3849 char *alt_recipient_v[] = {NULL, NULL};
3850 char *hide_address_lists_v[] = {NULL, NULL};
3851 char *mail_v[] = {NULL, NULL};
3852 char userAccountControlStr[80];
3857 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
3858 UF_PASSWD_CANT_CHANGE;
3860 char *attr_array[3];
3863 char contact_mail[256];
3864 char filter_exp[1024];
3865 char search_path[512];
3866 char TemplateDn[512];
3867 char TemplateSamName[128];
3868 char alt_recipient[256];
3869 char acBERBuf[N_SD_BER_BYTES];
3870 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3871 { N_SD_BER_BYTES, acBERBuf },
3873 LDAPControl *apsServerControls[] = {&sControl, NULL};
3875 LDAP_BERVAL **ppsValues;
3879 char *homeServerName;
3881 char search_string[256];
3883 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3884 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3885 BEREncodeSecurityBits(dwInfo, acBERBuf);
3887 if (!check_string(user_name))
3889 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
3891 return(AD_INVALID_NAME);
3894 memset(contact_mail, '\0', sizeof(contact_mail));
3895 sprintf(contact_mail, "%s@mit.edu", user_name);
3896 memset(mail, '\0', sizeof(mail));
3897 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
3898 memset(alt_recipient, '\0', sizeof(alt_recipient));
3899 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
3901 sprintf(search_string, "@%s", uppercase(ldap_domain));
3905 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
3907 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
3914 memset(displayName, '\0', sizeof(displayName));
3916 if (strlen(MoiraId) != 0)
3918 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
3919 attr_array[0] = "cn";
3920 attr_array[1] = NULL;
3921 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3922 &group_base, &group_count,
3923 LDAP_SCOPE_SUBTREE)) != 0)
3925 com_err(whoami, 0, "Unable to process user %s : %s",
3926 user_name, ldap_err2string(rc));
3931 if (group_count != 1)
3933 linklist_free(group_base);
3936 sprintf(filter, "(sAMAccountName=%s)", user_name);
3937 attr_array[0] = "cn";
3938 attr_array[1] = NULL;
3939 sprintf(temp, "%s,%s", user_ou, dn_path);
3940 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
3941 &group_base, &group_count,
3942 LDAP_SCOPE_SUBTREE)) != 0)
3944 com_err(whoami, 0, "Unable to process user %s : %s",
3945 user_name, ldap_err2string(rc));
3950 if (group_count != 1)
3952 com_err(whoami, 0, "Unable to find user %s in AD",
3954 linklist_free(group_base);
3955 return(AD_NO_USER_FOUND);
3958 strcpy(distinguished_name, group_base->dn);
3960 linklist_free(group_base);
3963 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
3964 rc = attribute_update(ldap_handle, distinguished_name, MitId,
3965 "employeeID", user_name);
3967 rc = attribute_update(ldap_handle, distinguished_name, "none",
3968 "employeeID", user_name);
3971 strcat(displayName, first);
3974 if(strlen(middle)) {
3976 strcat(displayName, " ");
3978 strcat(displayName, middle);
3982 if(strlen(middle) || strlen(first))
3983 strcat(displayName, " ");
3985 strcat(displayName, last);
3988 if(strlen(displayName))
3989 rc = attribute_update(ldap_handle, distinguished_name, displayName,
3990 "displayName", user_name);
3992 rc = attribute_update(ldap_handle, distinguished_name, user_name,
3993 "displayName", user_name);
3996 rc = attribute_update(ldap_handle, distinguished_name, first,
3997 "givenName", user_name);
3999 rc = attribute_update(ldap_handle, distinguished_name, "",
4000 "givenName", user_name);
4002 if(strlen(middle) == 1)
4003 rc = attribute_update(ldap_handle, distinguished_name, middle,
4004 "initials", user_name);
4006 rc = attribute_update(ldap_handle, distinguished_name, "",
4007 "initials", user_name);
4010 rc = attribute_update(ldap_handle, distinguished_name, last,
4013 rc = attribute_update(ldap_handle, distinguished_name, "",
4016 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4018 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4019 "mitMoiraId", user_name);
4026 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4030 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4033 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4035 userAccountControl |= UF_ACCOUNTDISABLE;
4039 hide_address_lists_v[0] = "TRUE";
4040 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4048 hide_address_lists_v[0] = NULL;
4049 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4054 sprintf(userAccountControlStr, "%ld", userAccountControl);
4055 userAccountControl_v[0] = userAccountControlStr;
4056 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4060 if (rc = moira_connect())
4062 critical_alert("AD incremental",
4063 "Error contacting Moira server : %s",
4068 argv[0] = user_name;
4070 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4072 if(!strcmp(save_argv[1], "EXCHANGE") ||
4073 (strstr(save_argv[3], search_string) != NULL))
4075 alt_recipient_v[0] = NULL;
4076 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4078 argv[0] = exchange_acl;
4080 argv[2] = user_name;
4082 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4084 if ((rc) && (rc != MR_EXISTS))
4086 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4087 user_name, exchange_acl, error_message(rc));
4092 alt_recipient_v[0] = alt_recipient;
4093 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4095 argv[0] = exchange_acl;
4097 argv[2] = user_name;
4099 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4101 if ((rc) && (rc != MR_NO_MATCH))
4104 "Unable to remove user %s from %s: %s, %d",
4105 user_name, exchange_acl, error_message(rc), rc);
4111 alt_recipient_v[0] = alt_recipient;
4112 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4114 argv[0] = exchange_acl;
4116 argv[2] = user_name;
4118 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4120 if ((rc) && (rc != MR_NO_MATCH))
4123 "Unable to remove user %s from %s: %s, %d",
4124 user_name, exchange_acl, error_message(rc), rc);
4132 mail_v[0] = contact_mail;
4133 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4136 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4137 WinProfileDir, homedir_v, winProfile_v,
4138 drives_v, mods, LDAP_MOD_REPLACE, n);
4140 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4141 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4142 attr_array[0] = "sAMAccountName";
4143 attr_array[1] = NULL;
4147 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
4148 &group_base, &group_count,
4149 LDAP_SCOPE_SUBTREE) != 0))
4152 if (group_count != 1)
4154 com_err(whoami, 0, "Unable to process user security template: %s - "
4155 "security not set", "UserTemplate.u");
4159 strcpy(TemplateDn, group_base->dn);
4160 strcpy(TemplateSamName, group_base->value);
4161 linklist_free(group_base);
4165 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4166 filter_exp, NULL, 0, apsServerControls, NULL,
4169 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4171 com_err(whoami, 0, "Unable to find user security template: %s - "
4172 "security not set", "UserTemplate.u");
4176 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
4178 if (ppsValues == NULL)
4180 com_err(whoami, 0, "Unable to find user security template: %s - "
4181 "security not set", "UserTemplate.u");
4185 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4186 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4190 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4191 mods)) != LDAP_SUCCESS)
4193 OldUseSFU30 = UseSFU30;
4194 SwitchSFU(mods, &UseSFU30, n);
4195 if (OldUseSFU30 != UseSFU30)
4196 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4199 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4200 user_name, ldap_err2string(rc));
4204 for (i = 0; i < n; i++)
4210 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4218 char contact_mail[256];
4219 char proxy_address[256];
4220 char query_base_dn[256];
4222 char *userPrincipalName_v[] = {NULL, NULL};
4223 char *altSecurityIdentities_v[] = {NULL, NULL};
4224 char *name_v[] = {NULL, NULL};
4225 char *samAccountName_v[] = {NULL, NULL};
4226 char *mail_v[] = {NULL, NULL};
4227 char *mail_nickname_v[] = {NULL, NULL};
4228 char *proxy_address_v[] = {NULL, NULL};
4229 char *query_base_dn_v[] = {NULL, NULL};
4234 if (!check_string(before_user_name))
4237 "Unable to process invalid LDAP user name %s", before_user_name);
4238 return(AD_INVALID_NAME);
4241 if (!check_string(user_name))
4244 "Unable to process invalid LDAP user name %s", user_name);
4245 return(AD_INVALID_NAME);
4248 strcpy(user_name, user_name);
4249 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4250 sprintf(new_dn, "cn=%s", user_name);
4251 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4252 sprintf(contact_mail, "%s@mit.edu", user_name);
4253 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4255 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4256 NULL, NULL)) != LDAP_SUCCESS)
4258 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4259 before_user_name, user_name, ldap_err2string(rc));
4265 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4268 if(rc = ldap_delete_s(ldap_handle, temp))
4270 com_err(whoami, 0, "Unable to delete user contact for %s",
4274 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4276 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4280 name_v[0] = user_name;
4281 sprintf(upn, "%s@%s", user_name, ldap_domain);
4282 userPrincipalName_v[0] = upn;
4283 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4284 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4285 altSecurityIdentities_v[0] = temp;
4286 samAccountName_v[0] = user_name;
4288 mail_nickname_v[0] = user_name;
4289 proxy_address_v[0] = proxy_address;
4290 query_base_dn_v[0] = query_base_dn;
4293 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4294 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4295 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4296 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4300 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4301 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4302 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4303 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4307 mail_v[0] = contact_mail;
4308 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4313 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4315 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4318 "Unable to modify user data for %s after renaming : %s",
4319 user_name, ldap_err2string(rc));
4322 for (i = 0; i < n; i++)
4328 int user_create(int ac, char **av, void *ptr)
4332 char user_name[256];
4336 char contact_mail[256];
4337 char proxy_address[256];
4338 char mail_nickname[256];
4339 char query_base_dn[256];
4340 char displayName[256];
4341 char address_book[256];
4342 char alt_recipient[256];
4343 char *cn_v[] = {NULL, NULL};
4344 char *objectClass_v[] = {"top", "person",
4345 "organizationalPerson",
4348 char *samAccountName_v[] = {NULL, NULL};
4349 char *altSecurityIdentities_v[] = {NULL, NULL};
4350 char *mitMoiraId_v[] = {NULL, NULL};
4351 char *name_v[] = {NULL, NULL};
4352 char *desc_v[] = {NULL, NULL};
4353 char *userPrincipalName_v[] = {NULL, NULL};
4354 char *userAccountControl_v[] = {NULL, NULL};
4355 char *uid_v[] = {NULL, NULL};
4356 char *mitid_v[] = {NULL, NULL};
4357 char *homedir_v[] = {NULL, NULL};
4358 char *winProfile_v[] = {NULL, NULL};
4359 char *drives_v[] = {NULL, NULL};
4360 char *mail_v[] = {NULL, NULL};
4361 char *givenName_v[] = {NULL, NULL};
4362 char *sn_v[] = {NULL, NULL};
4363 char *initials_v[] = {NULL, NULL};
4364 char *displayName_v[] = {NULL, NULL};
4365 char *proxy_address_v[] = {NULL, NULL};
4366 char *mail_nickname_v[] = {NULL, NULL};
4367 char *query_base_dn_v[] = {NULL, NULL};
4368 char *address_book_v[] = {NULL, NULL};
4369 char *homeMDB_v[] = {NULL, NULL};
4370 char *homeServerName_v[] = {NULL, NULL};
4371 char *mdbUseDefaults_v[] = {NULL, NULL};
4372 char *mailbox_guid_v[] = {NULL, NULL};
4373 char *user_culture_v[] = {NULL, NULL};
4374 char *user_account_control_v[] = {NULL, NULL};
4375 char *msexch_version_v[] = {NULL, NULL};
4376 char *alt_recipient_v[] = {NULL, NULL};
4377 char *hide_address_lists_v[] = {NULL, NULL};
4378 char userAccountControlStr[80];
4380 char filter_exp[1024];
4381 char search_path[512];
4382 char *attr_array[3];
4383 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4384 UF_PASSWD_CANT_CHANGE;
4390 char WinHomeDir[1024];
4391 char WinProfileDir[1024];
4393 char *homeServerName;
4395 char acBERBuf[N_SD_BER_BYTES];
4396 LK_ENTRY *group_base;
4398 char TemplateDn[512];
4399 char TemplateSamName[128];
4400 LDAP_BERVAL **ppsValues;
4401 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4402 { N_SD_BER_BYTES, acBERBuf },
4404 LDAPControl *apsServerControls[] = {&sControl, NULL};
4408 char search_string[256];
4412 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4413 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4414 BEREncodeSecurityBits(dwInfo, acBERBuf);
4416 if (!check_string(av[U_NAME]))
4418 callback_rc = AD_INVALID_NAME;
4419 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4421 return(AD_INVALID_NAME);
4424 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4425 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4426 memset(displayName, '\0', sizeof(displayName));
4427 memset(query_base_dn, '\0', sizeof(query_base_dn));
4428 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4429 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4430 strcpy(user_name, av[U_NAME]);
4431 sprintf(upn, "%s@%s", user_name, ldap_domain);
4432 sprintf(sam_name, "%s", av[U_NAME]);
4434 if(strlen(av[U_FIRST])) {
4435 strcat(displayName, av[U_FIRST]);
4438 if(strlen(av[U_MIDDLE])) {
4439 if(strlen(av[U_FIRST]))
4440 strcat(displayName, " ");
4442 strcat(displayName, av[U_MIDDLE]);
4445 if(strlen(av[U_LAST])) {
4446 if(strlen(av[U_FIRST]) || strlen(av[U_LAST]))
4447 strcat(displayName, " ");
4449 strcat(displayName, av[U_LAST]);
4452 samAccountName_v[0] = sam_name;
4453 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4454 (atoi(av[U_STATE]) != US_REGISTERED))
4456 userAccountControl |= UF_ACCOUNTDISABLE;
4460 hide_address_lists_v[0] = "TRUE";
4461 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4466 sprintf(userAccountControlStr, "%ld", userAccountControl);
4467 userAccountControl_v[0] = userAccountControlStr;
4468 userPrincipalName_v[0] = upn;
4469 cn_v[0] = user_name;
4470 name_v[0] = user_name;
4471 desc_v[0] = "Auto account created by Moira";
4473 givenName_v[0] = av[U_FIRST];
4474 sn_v[0] = av[U_LAST];
4475 displayName_v[0] = displayName;
4476 mail_nickname_v[0] = user_name;
4478 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4479 altSecurityIdentities_v[0] = temp;
4480 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4481 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4482 sprintf(contact_mail, "%s@mit.edu", user_name);
4483 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4484 query_base_dn_v[0] = query_base_dn;
4485 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4487 sprintf(search_string, "@%s", uppercase(ldap_domain));
4492 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4495 com_err(whoami, 0, "Unable to create user contact %s",
4499 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4502 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4506 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4507 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4509 homeMDB_v[0] = homeMDB;
4510 homeServerName_v[0] = homeServerName;
4514 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4515 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4516 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
4517 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
4518 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
4519 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
4520 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
4524 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
4525 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4526 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
4527 mdbUseDefaults_v[0] = "TRUE";
4528 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
4529 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
4531 argv[0] = user_name;
4533 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4535 if(!strcmp(save_argv[1], "EXCHANGE") ||
4536 (strstr(save_argv[3], search_string) != NULL))
4538 argv[0] = exchange_acl;
4540 argv[2] = user_name;
4542 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4544 if ((rc) && (rc != MR_EXISTS))
4546 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4547 user_name, exchange_acl, error_message(rc));
4552 alt_recipient_v[0] = alt_recipient;
4553 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4558 alt_recipient_v[0] = alt_recipient;
4559 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4561 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
4566 mail_v[0] = contact_mail;
4567 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
4570 if(strlen(av[U_FIRST])) {
4571 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
4574 if(strlen(av[U_LAST])) {
4575 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
4578 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
4579 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
4581 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4584 if (strlen(av[U_MIDDLE]) == 1) {
4585 initials_v[0] = av[U_MIDDLE];
4586 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
4589 if (strlen(call_args[2]) != 0)
4591 mitMoiraId_v[0] = call_args[2];
4592 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
4595 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
4597 if (strlen(av[U_UID]) != 0)
4599 uid_v[0] = av[U_UID];
4600 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
4604 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
4608 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
4612 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
4613 mitid_v[0] = av[U_MITID];
4615 mitid_v[0] = "none";
4617 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
4619 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
4620 WinProfileDir, homedir_v, winProfile_v,
4621 drives_v, mods, LDAP_MOD_ADD, n);
4623 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4624 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
4625 attr_array[0] = "sAMAccountName";
4626 attr_array[1] = NULL;
4630 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
4631 attr_array, &group_base, &group_count,
4632 LDAP_SCOPE_SUBTREE) != 0))
4635 if (group_count != 1)
4637 com_err(whoami, 0, "Unable to process user security template: %s - "
4638 "security not set", "UserTemplate.u");
4642 strcpy(TemplateDn, group_base->dn);
4643 strcpy(TemplateSamName, group_base->value);
4644 linklist_free(group_base);
4648 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE,
4649 filter_exp, NULL, 0, apsServerControls, NULL,
4652 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
4654 com_err(whoami, 0, "Unable to find user security template: %s - "
4655 "security not set", "UserTemplate.u");
4659 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
4660 "ntSecurityDescriptor");
4661 if (ppsValues == NULL)
4663 com_err(whoami, 0, "Unable to find user security template: %s - "
4664 "security not set", "UserTemplate.u");
4668 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4669 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4673 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4675 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4677 OldUseSFU30 = UseSFU30;
4678 SwitchSFU(mods, &UseSFU30, n);
4679 if (OldUseSFU30 != UseSFU30)
4680 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4683 for (i = 0; i < n; i++)
4686 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4688 com_err(whoami, 0, "Unable to create user %s : %s",
4689 user_name, ldap_err2string(rc));
4694 if ((rc == LDAP_SUCCESS) && (SetPassword))
4696 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4698 ad_kdc_disconnect();
4699 if (!ad_server_connect(default_server, ldap_domain))
4701 com_err(whoami, 0, "Unable to set password for user %s : %s",
4703 "cannot get changepw ticket from windows domain");
4707 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4709 com_err(whoami, 0, "Unable to set password for user %s "
4710 ": %ld", user_name, rc);
4719 int user_change_status(LDAP *ldap_handle, char *dn_path,
4720 char *user_name, char *MoiraId,
4724 char *attr_array[3];
4726 char distinguished_name[1024];
4728 char *mitMoiraId_v[] = {NULL, NULL};
4730 LK_ENTRY *group_base;
4737 if (!check_string(user_name))
4739 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4741 return(AD_INVALID_NAME);
4747 if (strlen(MoiraId) != 0)
4749 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4750 attr_array[0] = "UserAccountControl";
4751 attr_array[1] = NULL;
4752 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4753 &group_base, &group_count,
4754 LDAP_SCOPE_SUBTREE)) != 0)
4756 com_err(whoami, 0, "Unable to process user %s : %s",
4757 user_name, ldap_err2string(rc));
4762 if (group_count != 1)
4764 linklist_free(group_base);
4767 sprintf(filter, "(sAMAccountName=%s)", user_name);
4768 attr_array[0] = "UserAccountControl";
4769 attr_array[1] = NULL;
4770 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4771 &group_base, &group_count,
4772 LDAP_SCOPE_SUBTREE)) != 0)
4774 com_err(whoami, 0, "Unable to process user %s : %s",
4775 user_name, ldap_err2string(rc));
4780 if (group_count != 1)
4782 linklist_free(group_base);
4783 com_err(whoami, 0, "Unable to find user %s in AD",
4785 return(LDAP_NO_SUCH_OBJECT);
4788 strcpy(distinguished_name, group_base->dn);
4789 ulongValue = atoi((*group_base).value);
4791 if (operation == MEMBER_DEACTIVATE)
4792 ulongValue |= UF_ACCOUNTDISABLE;
4794 ulongValue &= ~UF_ACCOUNTDISABLE;
4796 sprintf(temp, "%ld", ulongValue);
4798 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
4799 temp, &modvalues, REPLACE)) == 1)
4802 linklist_free(group_base);
4806 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
4808 if (strlen(MoiraId) != 0)
4810 mitMoiraId_v[0] = MoiraId;
4811 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
4815 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4817 for (i = 0; i < n; i++)
4820 free_values(modvalues);
4822 if (rc != LDAP_SUCCESS)
4824 com_err(whoami, 0, "Unable to change status of user %s : %s",
4825 user_name, ldap_err2string(rc));
4832 int user_delete(LDAP *ldap_handle, char *dn_path,
4833 char *u_name, char *MoiraId)
4836 char *attr_array[3];
4837 char distinguished_name[1024];
4838 char user_name[512];
4839 LK_ENTRY *group_base;
4844 if (!check_string(u_name))
4845 return(AD_INVALID_NAME);
4847 strcpy(user_name, u_name);
4851 if (strlen(MoiraId) != 0)
4853 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4854 attr_array[0] = "name";
4855 attr_array[1] = NULL;
4856 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4857 &group_base, &group_count,
4858 LDAP_SCOPE_SUBTREE)) != 0)
4860 com_err(whoami, 0, "Unable to process user %s : %s",
4861 user_name, ldap_err2string(rc));
4866 if (group_count != 1)
4868 linklist_free(group_base);
4871 sprintf(filter, "(sAMAccountName=%s)", user_name);
4872 attr_array[0] = "name";
4873 attr_array[1] = NULL;
4874 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4875 &group_base, &group_count,
4876 LDAP_SCOPE_SUBTREE)) != 0)
4878 com_err(whoami, 0, "Unable to process user %s : %s",
4879 user_name, ldap_err2string(rc));
4884 if (group_count != 1)
4886 com_err(whoami, 0, "Unable to find user %s in AD",
4891 strcpy(distinguished_name, group_base->dn);
4893 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
4895 com_err(whoami, 0, "Unable to process user %s : %s",
4896 user_name, ldap_err2string(rc));
4899 /* Need to add code to delete mit.edu contact */
4903 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
4905 if(rc = ldap_delete_s(ldap_handle, temp))
4907 com_err(whoami, 0, "Unable to delete user contact for %s",
4913 linklist_free(group_base);
4918 void linklist_free(LK_ENTRY *linklist_base)
4920 LK_ENTRY *linklist_previous;
4922 while (linklist_base != NULL)
4924 if (linklist_base->dn != NULL)
4925 free(linklist_base->dn);
4927 if (linklist_base->attribute != NULL)
4928 free(linklist_base->attribute);
4930 if (linklist_base->value != NULL)
4931 free(linklist_base->value);
4933 if (linklist_base->member != NULL)
4934 free(linklist_base->member);
4936 if (linklist_base->type != NULL)
4937 free(linklist_base->type);
4939 if (linklist_base->list != NULL)
4940 free(linklist_base->list);
4942 linklist_previous = linklist_base;
4943 linklist_base = linklist_previous->next;
4944 free(linklist_previous);
4948 void free_values(char **modvalues)
4954 if (modvalues != NULL)
4956 while (modvalues[i] != NULL)
4959 modvalues[i] = NULL;
4966 static int illegalchars[] = {
4967 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
4968 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
4969 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
4970 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
4971 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
4972 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
4973 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
4974 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
4975 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4976 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4977 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4978 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4979 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4980 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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,
4985 int check_string(char *s)
4993 if (isupper(character))
4994 character = tolower(character);
4996 if (illegalchars[(unsigned) character])
5003 int check_container_name(char *s)
5011 if (isupper(character))
5012 character = tolower(character);
5014 if (character == ' ')
5017 if (illegalchars[(unsigned) character])
5024 int mr_connect_cl(char *server, char *client, int version, int auth)
5030 status = mr_connect(server);
5034 com_err(whoami, status, "while connecting to Moira");
5038 status = mr_motd(&motd);
5043 com_err(whoami, status, "while checking server status");
5049 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5050 com_err(whoami, status, temp);
5055 status = mr_version(version);
5059 if (status == MR_UNKNOWN_PROC)
5062 status = MR_VERSION_HIGH;
5064 status = MR_SUCCESS;
5067 if (status == MR_VERSION_HIGH)
5069 com_err(whoami, 0, "Warning: This client is running newer code "
5070 "than the server.");
5071 com_err(whoami, 0, "Some operations may not work.");
5073 else if (status && status != MR_VERSION_LOW)
5075 com_err(whoami, status, "while setting query version number.");
5083 status = mr_krb5_auth(client);
5086 com_err(whoami, status, "while authenticating to Moira.");
5095 void AfsToWinAfs(char* path, char* winPath)
5099 strcpy(winPath, WINAFS);
5100 pathPtr = path + strlen(AFS);
5101 winPathPtr = winPath + strlen(WINAFS);
5105 if (*pathPtr == '/')
5108 *winPathPtr = *pathPtr;
5115 int GetAceInfo(int ac, char **av, void *ptr)
5122 strcpy(call_args[0], av[L_ACE_TYPE]);
5123 strcpy(call_args[1], av[L_ACE_NAME]);
5125 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5126 return(LDAP_SUCCESS);
5129 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5132 char *attr_array[3];
5135 LK_ENTRY *group_base;
5140 sprintf(filter, "(sAMAccountName=%s)", Name);
5141 attr_array[0] = "sAMAccountName";
5142 attr_array[1] = NULL;
5144 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5145 &group_base, &group_count,
5146 LDAP_SCOPE_SUBTREE)) != 0)
5148 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5149 Name, ldap_err2string(rc));
5153 linklist_free(group_base);
5156 if (group_count == 0)
5164 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5165 int UpdateGroup, int *ProcessGroup, char *maillist)
5168 char GroupName[256];
5174 char AceMembership[2];
5177 char *save_argv[U_END];
5181 com_err(whoami, 0, "ProcessAce disabled, skipping");
5185 strcpy(GroupName, Name);
5187 if (strcasecmp(Type, "LIST"))
5193 AceInfo[0] = AceType;
5194 AceInfo[1] = AceName;
5195 AceInfo[2] = AceMembership;
5197 memset(AceType, '\0', sizeof(AceType));
5198 memset(AceName, '\0', sizeof(AceName));
5199 memset(AceMembership, '\0', sizeof(AceMembership));
5200 memset(AceOu, '\0', sizeof(AceOu));
5203 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5205 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5206 GroupName, error_message(rc));
5212 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5216 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5219 strcpy(temp, AceName);
5221 if (!strcasecmp(AceType, "LIST"))
5222 sprintf(temp, "%s%s", AceName, group_suffix);
5226 if (checkADname(ldap_handle, dn_path, temp))
5228 (*ProcessGroup) = 1;
5231 if (!strcasecmp(AceInfo[0], "LIST"))
5233 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5234 AceMembership, 0, UpdateGroup, maillist))
5237 else if (!strcasecmp(AceInfo[0], "USER"))
5240 call_args[0] = (char *)ldap_handle;
5241 call_args[1] = dn_path;
5243 call_args[3] = NULL;
5246 if (rc = mr_query("get_user_account_by_login", 1, av,
5247 save_query_info, save_argv))
5249 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5254 if (rc = user_create(U_END, save_argv, call_args))
5256 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5263 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5273 if (!strcasecmp(AceType, "LIST"))
5275 if (!strcasecmp(GroupName, AceName))
5279 strcpy(GroupName, AceName);
5285 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5286 char *group_name, char *group_ou, char *group_membership,
5287 int group_security_flag, int updateGroup, char *maillist)
5292 LK_ENTRY *group_base;
5295 char *attr_array[3];
5298 call_args[0] = (char *)ldap_handle;
5299 call_args[1] = dn_path;
5300 call_args[2] = group_name;
5301 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5302 call_args[4] = (char *)updateGroup;
5303 call_args[5] = MoiraId;
5305 call_args[7] = NULL;
5311 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5314 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5322 com_err(whoami, 0, "Unable to create list %s", group_name);
5323 return(callback_rc);
5329 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
5330 char *group_ou, char *group_membership,
5331 int group_security_flag, char *MoiraId)
5341 com_err(whoami, 0, "Populating group %s", group_name);
5343 call_args[0] = (char *)ldap_handle;
5344 call_args[1] = dn_path;
5345 call_args[2] = group_name;
5346 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5347 call_args[4] = NULL;
5350 if (rc = mr_query("get_end_members_of_list", 1, av,
5351 member_list_build, call_args))
5353 com_err(whoami, 0, "Unable to populate list %s : %s",
5354 group_name, error_message(rc));
5358 if (member_base != NULL)
5364 if (!strcasecmp(ptr->type, "LIST"))
5372 if (!strcasecmp(ptr->type, "STRING"))
5374 if (contact_create(ldap_handle, dn_path, ptr->member,
5378 pUserOu = contact_ou;
5380 else if (!strcasecmp(ptr->type, "KERBEROS"))
5382 if (contact_create(ldap_handle, dn_path, ptr->member,
5386 pUserOu = kerberos_ou;
5389 rc = member_add(ldap_handle, dn_path, group_name,
5390 group_ou, group_membership, ptr->member,
5395 linklist_free(member_base);
5402 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5403 char *group_name, char *group_ou, char *group_membership,
5404 int group_security_flag, int type, char *maillist)
5406 char before_desc[512];
5407 char before_name[256];
5408 char before_group_ou[256];
5409 char before_group_membership[2];
5410 char distinguishedName[256];
5411 char ad_distinguishedName[256];
5413 char *attr_array[3];
5414 int before_security_flag;
5417 LK_ENTRY *group_base;
5420 char ou_security[512];
5421 char ou_distribution[512];
5422 char ou_neither[512];
5424 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
5425 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
5427 memset(filter, '\0', sizeof(filter));
5431 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5433 "distinguishedName", &group_base,
5434 &group_count, filter))
5437 if (type == CHECK_GROUPS)
5439 if (group_count == 1)
5441 if (!strcasecmp(group_base->value, distinguishedName))
5443 linklist_free(group_base);
5448 linklist_free(group_base);
5450 if (group_count == 0)
5451 return(AD_NO_GROUPS_FOUND);
5453 if (group_count == 1)
5454 return(AD_WRONG_GROUP_DN_FOUND);
5456 return(AD_MULTIPLE_GROUPS_FOUND);
5459 if (group_count == 0)
5461 return(AD_NO_GROUPS_FOUND);
5464 if (group_count > 1)
5470 if (!strcasecmp(distinguishedName, ptr->value))
5478 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
5484 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
5488 linklist_free(group_base);
5489 return(AD_MULTIPLE_GROUPS_FOUND);
5496 if (strcasecmp(distinguishedName, ptr->value))
5497 rc = ldap_delete_s(ldap_handle, ptr->value);
5502 linklist_free(group_base);
5503 memset(filter, '\0', sizeof(filter));
5507 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5509 "distinguishedName", &group_base,
5510 &group_count, filter))
5513 if (group_count == 0)
5514 return(AD_NO_GROUPS_FOUND);
5516 if (group_count > 1)
5517 return(AD_MULTIPLE_GROUPS_FOUND);
5520 strcpy(ad_distinguishedName, group_base->value);
5521 linklist_free(group_base);
5525 attr_array[0] = "sAMAccountName";
5526 attr_array[1] = NULL;
5528 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5529 &group_base, &group_count,
5530 LDAP_SCOPE_SUBTREE)) != 0)
5532 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5533 MoiraId, ldap_err2string(rc));
5537 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
5539 if (!strcasecmp(ad_distinguishedName, distinguishedName))
5541 linklist_free(group_base);
5547 linklist_free(group_base);
5550 memset(ou_both, '\0', sizeof(ou_both));
5551 memset(ou_security, '\0', sizeof(ou_security));
5552 memset(ou_distribution, '\0', sizeof(ou_distribution));
5553 memset(ou_neither, '\0', sizeof(ou_neither));
5554 memset(before_name, '\0', sizeof(before_name));
5555 memset(before_desc, '\0', sizeof(before_desc));
5556 memset(before_group_membership, '\0', sizeof(before_group_membership));
5557 attr_array[0] = "name";
5558 attr_array[1] = NULL;
5560 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5561 &group_base, &group_count,
5562 LDAP_SCOPE_SUBTREE)) != 0)
5564 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
5565 MoiraId, ldap_err2string(rc));
5569 strcpy(before_name, group_base->value);
5570 linklist_free(group_base);
5573 attr_array[0] = "description";
5574 attr_array[1] = NULL;
5576 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5577 &group_base, &group_count,
5578 LDAP_SCOPE_SUBTREE)) != 0)
5581 "Unable to get list description with MoiraId = %s: %s",
5582 MoiraId, ldap_err2string(rc));
5586 if (group_count != 0)
5588 strcpy(before_desc, group_base->value);
5589 linklist_free(group_base);
5594 change_to_lower_case(ad_distinguishedName);
5595 strcpy(ou_both, group_ou_both);
5596 change_to_lower_case(ou_both);
5597 strcpy(ou_security, group_ou_security);
5598 change_to_lower_case(ou_security);
5599 strcpy(ou_distribution, group_ou_distribution);
5600 change_to_lower_case(ou_distribution);
5601 strcpy(ou_neither, group_ou_neither);
5602 change_to_lower_case(ou_neither);
5604 if (strstr(ad_distinguishedName, ou_both))
5606 strcpy(before_group_ou, group_ou_both);
5607 before_group_membership[0] = 'B';
5608 before_security_flag = 1;
5610 else if (strstr(ad_distinguishedName, ou_security))
5612 strcpy(before_group_ou, group_ou_security);
5613 before_group_membership[0] = 'S';
5614 before_security_flag = 1;
5616 else if (strstr(ad_distinguishedName, ou_distribution))
5618 strcpy(before_group_ou, group_ou_distribution);
5619 before_group_membership[0] = 'D';
5620 before_security_flag = 0;
5622 else if (strstr(ad_distinguishedName, ou_neither))
5624 strcpy(before_group_ou, group_ou_neither);
5625 before_group_membership[0] = 'N';
5626 before_security_flag = 0;
5629 return(AD_NO_OU_FOUND);
5631 rc = group_rename(ldap_handle, dn_path, before_name,
5632 before_group_membership,
5633 before_group_ou, before_security_flag, before_desc,
5634 group_name, group_membership, group_ou,
5635 group_security_flag,
5636 before_desc, MoiraId, filter, maillist);
5641 void change_to_lower_case(char *ptr)
5645 for (i = 0; i < (int)strlen(ptr); i++)
5647 ptr[i] = tolower(ptr[i]);
5651 int ad_get_group(LDAP *ldap_handle, char *dn_path,
5652 char *group_name, char *group_membership,
5653 char *MoiraId, char *attribute,
5654 LK_ENTRY **linklist_base, int *linklist_count,
5659 char *attr_array[3];
5662 (*linklist_base) = NULL;
5663 (*linklist_count) = 0;
5665 if (strlen(rFilter) != 0)
5667 strcpy(filter, rFilter);
5668 attr_array[0] = attribute;
5669 attr_array[1] = NULL;
5671 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5672 linklist_base, linklist_count,
5673 LDAP_SCOPE_SUBTREE)) != 0)
5675 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5676 MoiraId, ldap_err2string(rc));
5680 if ((*linklist_count) == 1)
5682 strcpy(rFilter, filter);
5687 linklist_free((*linklist_base));
5688 (*linklist_base) = NULL;
5689 (*linklist_count) = 0;
5691 if (strlen(MoiraId) != 0)
5693 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
5694 attr_array[0] = attribute;
5695 attr_array[1] = NULL;
5697 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5698 linklist_base, linklist_count,
5699 LDAP_SCOPE_SUBTREE)) != 0)
5701 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5702 MoiraId, ldap_err2string(rc));
5707 if ((*linklist_count) > 1)
5709 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
5710 pPtr = (*linklist_base);
5714 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
5719 linklist_free((*linklist_base));
5720 (*linklist_base) = NULL;
5721 (*linklist_count) = 0;
5724 if ((*linklist_count) == 1)
5726 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
5728 strcpy(rFilter, filter);
5733 linklist_free((*linklist_base));
5734 (*linklist_base) = NULL;
5735 (*linklist_count) = 0;
5736 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
5737 attr_array[0] = attribute;
5738 attr_array[1] = NULL;
5740 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5741 linklist_base, linklist_count,
5742 LDAP_SCOPE_SUBTREE)) != 0)
5744 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5745 MoiraId, ldap_err2string(rc));
5749 if ((*linklist_count) == 1)
5751 strcpy(rFilter, filter);
5758 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5761 char *attr_array[3];
5762 char SamAccountName[64];
5765 LK_ENTRY *group_base;
5771 if (strlen(MoiraId) != 0)
5773 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5774 attr_array[0] = "sAMAccountName";
5775 attr_array[1] = NULL;
5776 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5777 &group_base, &group_count,
5778 LDAP_SCOPE_SUBTREE)) != 0)
5780 com_err(whoami, 0, "Unable to process user %s : %s",
5781 UserName, ldap_err2string(rc));
5785 if (group_count > 1)
5787 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5793 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5794 gPtr->value, MoiraId);
5800 if (group_count != 1)
5802 linklist_free(group_base);
5805 sprintf(filter, "(sAMAccountName=%s)", UserName);
5806 attr_array[0] = "sAMAccountName";
5807 attr_array[1] = NULL;
5809 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5810 &group_base, &group_count,
5811 LDAP_SCOPE_SUBTREE)) != 0)
5813 com_err(whoami, 0, "Unable to process user %s : %s",
5814 UserName, ldap_err2string(rc));
5819 if (group_count != 1)
5821 linklist_free(group_base);
5822 return(AD_NO_USER_FOUND);
5825 strcpy(SamAccountName, group_base->value);
5826 linklist_free(group_base);
5830 if (strcmp(SamAccountName, UserName))
5832 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5839 void container_get_dn(char *src, char *dest)
5846 memset(array, '\0', 20 * sizeof(array[0]));
5848 if (strlen(src) == 0)
5870 strcpy(dest, "OU=");
5874 strcat(dest, array[n-1]);
5878 strcat(dest, ",OU=");
5885 void container_get_name(char *src, char *dest)
5890 if (strlen(src) == 0)
5910 void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5917 strcpy(cName, name);
5919 for (i = 0; i < (int)strlen(cName); i++)
5921 if (cName[i] == '/')
5924 av[CONTAINER_NAME] = cName;
5925 av[CONTAINER_DESC] = "";
5926 av[CONTAINER_LOCATION] = "";
5927 av[CONTAINER_CONTACT] = "";
5928 av[CONTAINER_TYPE] = "";
5929 av[CONTAINER_ID] = "";
5930 av[CONTAINER_ROWID] = "";
5931 rc = container_create(ldap_handle, dn_path, 7, av);
5933 if (rc == LDAP_SUCCESS)
5935 com_err(whoami, 0, "container %s created without a mitMoiraId",
5944 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5945 char **before, int afterc, char **after)
5950 char new_dn_path[256];
5952 char distinguishedName[256];
5957 memset(cName, '\0', sizeof(cName));
5958 container_get_name(after[CONTAINER_NAME], cName);
5960 if (!check_container_name(cName))
5962 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5964 return(AD_INVALID_NAME);
5967 memset(distinguishedName, '\0', sizeof(distinguishedName));
5969 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5970 distinguishedName, beforec, before))
5973 if (strlen(distinguishedName) == 0)
5975 rc = container_create(ldap_handle, dn_path, afterc, after);
5979 strcpy(temp, after[CONTAINER_NAME]);
5982 for (i = 0; i < (int)strlen(temp); i++)
5992 container_get_dn(temp, dName);
5994 if (strlen(temp) != 0)
5995 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5997 sprintf(new_dn_path, "%s", dn_path);
5999 sprintf(new_cn, "OU=%s", cName);
6001 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6003 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6004 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6006 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6007 before[CONTAINER_NAME], after[CONTAINER_NAME],
6008 ldap_err2string(rc));
6012 memset(dName, '\0', sizeof(dName));
6013 container_get_dn(after[CONTAINER_NAME], dName);
6014 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6019 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6021 char distinguishedName[256];
6024 memset(distinguishedName, '\0', sizeof(distinguishedName));
6026 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6027 distinguishedName, count, av))
6030 if (strlen(distinguishedName) == 0)
6033 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6035 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6036 container_move_objects(ldap_handle, dn_path, distinguishedName);
6038 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6039 av[CONTAINER_NAME], ldap_err2string(rc));
6045 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6047 char *attr_array[3];
6048 LK_ENTRY *group_base;
6051 char *objectClass_v[] = {"top",
6052 "organizationalUnit",
6055 char *ou_v[] = {NULL, NULL};
6056 char *name_v[] = {NULL, NULL};
6057 char *moiraId_v[] = {NULL, NULL};
6058 char *desc_v[] = {NULL, NULL};
6059 char *managedBy_v[] = {NULL, NULL};
6062 char managedByDN[256];
6069 memset(filter, '\0', sizeof(filter));
6070 memset(dName, '\0', sizeof(dName));
6071 memset(cName, '\0', sizeof(cName));
6072 memset(managedByDN, '\0', sizeof(managedByDN));
6073 container_get_dn(av[CONTAINER_NAME], dName);
6074 container_get_name(av[CONTAINER_NAME], cName);
6076 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6078 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6080 return(AD_INVALID_NAME);
6083 if (!check_container_name(cName))
6085 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6087 return(AD_INVALID_NAME);
6091 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6093 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6095 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6097 if (strlen(av[CONTAINER_ROWID]) != 0)
6099 moiraId_v[0] = av[CONTAINER_ROWID];
6100 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6103 if (strlen(av[CONTAINER_DESC]) != 0)
6105 desc_v[0] = av[CONTAINER_DESC];
6106 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6109 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6111 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6113 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6116 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6117 kerberos_ou, dn_path);
6118 managedBy_v[0] = managedByDN;
6119 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6124 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6126 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6127 "(objectClass=user)))", av[CONTAINER_ID]);
6130 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6132 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6136 if (strlen(filter) != 0)
6138 attr_array[0] = "distinguishedName";
6139 attr_array[1] = NULL;
6142 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6144 &group_base, &group_count,
6145 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6147 if (group_count == 1)
6149 strcpy(managedByDN, group_base->value);
6150 managedBy_v[0] = managedByDN;
6151 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6153 linklist_free(group_base);
6163 sprintf(temp, "%s,%s", dName, dn_path);
6164 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
6166 for (i = 0; i < n; i++)
6169 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6171 com_err(whoami, 0, "Unable to create container %s : %s",
6172 cName, ldap_err2string(rc));
6176 if (rc == LDAP_ALREADY_EXISTS)
6178 if (strlen(av[CONTAINER_ROWID]) != 0)
6179 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6185 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6186 char **before, int afterc, char **after)
6188 char distinguishedName[256];
6191 memset(distinguishedName, '\0', sizeof(distinguishedName));
6193 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6194 distinguishedName, afterc, after))
6197 if (strlen(distinguishedName) == 0)
6199 rc = container_create(ldap_handle, dn_path, afterc, after);
6203 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6204 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6210 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6211 char *distinguishedName, int count,
6214 char *attr_array[3];
6215 LK_ENTRY *group_base;
6222 memset(filter, '\0', sizeof(filter));
6223 memset(dName, '\0', sizeof(dName));
6224 memset(cName, '\0', sizeof(cName));
6225 container_get_dn(av[CONTAINER_NAME], dName);
6226 container_get_name(av[CONTAINER_NAME], cName);
6228 if (strlen(dName) == 0)
6230 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6231 av[CONTAINER_NAME]);
6232 return(AD_INVALID_NAME);
6235 if (!check_container_name(cName))
6237 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6239 return(AD_INVALID_NAME);
6242 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6243 av[CONTAINER_ROWID]);
6244 attr_array[0] = "distinguishedName";
6245 attr_array[1] = NULL;
6249 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6250 &group_base, &group_count,
6251 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6253 if (group_count == 1)
6255 strcpy(distinguishedName, group_base->value);
6258 linklist_free(group_base);
6263 if (strlen(distinguishedName) == 0)
6265 sprintf(filter, "(&(objectClass=organizationalUnit)"
6266 "(distinguishedName=%s,%s))", dName, dn_path);
6267 attr_array[0] = "distinguishedName";
6268 attr_array[1] = NULL;
6272 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6273 &group_base, &group_count,
6274 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6276 if (group_count == 1)
6278 strcpy(distinguishedName, group_base->value);
6281 linklist_free(group_base);
6290 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6291 char *distinguishedName, int count, char **av)
6293 char *attr_array[5];
6294 LK_ENTRY *group_base;
6299 char *moiraId_v[] = {NULL, NULL};
6300 char *desc_v[] = {NULL, NULL};
6301 char *managedBy_v[] = {NULL, NULL};
6302 char managedByDN[256];
6311 strcpy(ad_path, distinguishedName);
6313 if (strlen(dName) != 0)
6314 sprintf(ad_path, "%s,%s", dName, dn_path);
6316 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6319 if (strlen(av[CONTAINER_ID]) != 0)
6320 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6321 av[CONTAINER_ROWID]);
6323 attr_array[0] = "mitMoiraId";
6324 attr_array[1] = "description";
6325 attr_array[2] = "managedBy";
6326 attr_array[3] = NULL;
6330 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6331 &group_base, &group_count,
6332 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6334 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6335 av[CONTAINER_NAME], ldap_err2string(rc));
6339 memset(managedByDN, '\0', sizeof(managedByDN));
6340 memset(moiraId, '\0', sizeof(moiraId));
6341 memset(desc, '\0', sizeof(desc));
6346 if (!strcasecmp(pPtr->attribute, "description"))
6347 strcpy(desc, pPtr->value);
6348 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6349 strcpy(managedByDN, pPtr->value);
6350 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6351 strcpy(moiraId, pPtr->value);
6355 linklist_free(group_base);
6360 if (strlen(av[CONTAINER_ROWID]) != 0)
6362 moiraId_v[0] = av[CONTAINER_ROWID];
6363 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6366 if (strlen(av[CONTAINER_DESC]) != 0)
6368 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6373 if (strlen(desc) != 0)
6375 attribute_update(ldap_handle, ad_path, "", "description", dName);
6379 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6381 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6383 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6386 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6387 kerberos_ou, dn_path);
6388 managedBy_v[0] = managedByDN;
6389 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6393 if (strlen(managedByDN) != 0)
6395 attribute_update(ldap_handle, ad_path, "", "managedBy",
6402 memset(filter, '\0', sizeof(filter));
6404 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6406 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6407 "(objectClass=user)))", av[CONTAINER_ID]);
6410 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6412 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6416 if (strlen(filter) != 0)
6418 attr_array[0] = "distinguishedName";
6419 attr_array[1] = NULL;
6422 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6423 attr_array, &group_base, &group_count,
6424 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6426 if (group_count == 1)
6428 strcpy(managedByDN, group_base->value);
6429 managedBy_v[0] = managedByDN;
6430 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6434 if (strlen(managedByDN) != 0)
6436 attribute_update(ldap_handle, ad_path, "",
6437 "managedBy", dName);
6441 linklist_free(group_base);
6448 if (strlen(managedByDN) != 0)
6450 attribute_update(ldap_handle, ad_path, "", "managedBy",
6460 return(LDAP_SUCCESS);
6462 rc = ldap_modify_s(ldap_handle, ad_path, mods);
6464 for (i = 0; i < n; i++)
6467 if (rc != LDAP_SUCCESS)
6469 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6470 av[CONTAINER_NAME], ldap_err2string(rc));
6477 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6479 char *attr_array[3];
6480 LK_ENTRY *group_base;
6487 int NumberOfEntries = 10;
6491 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6493 for (i = 0; i < 3; i++)
6495 memset(filter, '\0', sizeof(filter));
6499 strcpy(filter, "(!(|(objectClass=computer)"
6500 "(objectClass=organizationalUnit)))");
6501 attr_array[0] = "cn";
6502 attr_array[1] = NULL;
6506 strcpy(filter, "(objectClass=computer)");
6507 attr_array[0] = "cn";
6508 attr_array[1] = NULL;
6512 strcpy(filter, "(objectClass=organizationalUnit)");
6513 attr_array[0] = "ou";
6514 attr_array[1] = NULL;
6519 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
6520 &group_base, &group_count,
6521 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6526 if (group_count == 0)
6533 if (!strcasecmp(pPtr->attribute, "cn"))
6535 sprintf(new_cn, "cn=%s", pPtr->value);
6537 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6539 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6544 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6546 if (rc == LDAP_ALREADY_EXISTS)
6548 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6555 else if (!strcasecmp(pPtr->attribute, "ou"))
6557 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6563 linklist_free(group_base);
6572 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6573 char *machine_ou, char *NewMachineName)
6575 LK_ENTRY *group_base;
6579 char *attr_array[3];
6586 strcpy(NewMachineName, member);
6587 rc = moira_connect();
6588 rc = GetMachineName(NewMachineName);
6591 if (strlen(NewMachineName) == 0)
6593 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6599 pPtr = strchr(NewMachineName, '.');
6606 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
6607 attr_array[0] = "cn";
6608 attr_array[1] = NULL;
6609 sprintf(temp, "%s", dn_path);
6611 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
6612 &group_base, &group_count,
6613 LDAP_SCOPE_SUBTREE)) != 0)
6615 com_err(whoami, 0, "Unable to process machine %s : %s",
6616 member, ldap_err2string(rc));
6620 if (group_count != 1)
6623 "Unable to process machine %s : machine not found in AD",
6628 strcpy(dn, group_base->dn);
6629 strcpy(cn, group_base->value);
6631 for (i = 0; i < (int)strlen(dn); i++)
6632 dn[i] = tolower(dn[i]);
6634 for (i = 0; i < (int)strlen(cn); i++)
6635 cn[i] = tolower(cn[i]);
6637 linklist_free(group_base);
6639 pPtr = strstr(dn, cn);
6643 com_err(whoami, 0, "Unable to process machine %s",
6648 pPtr += strlen(cn) + 1;
6649 strcpy(machine_ou, pPtr);
6651 pPtr = strstr(machine_ou, "dc=");
6655 com_err(whoami, 0, "Unable to process machine %s",
6666 int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6667 char *MoiraMachineName, char *DestinationOu)
6671 char MachineName[128];
6673 char *attr_array[3];
6678 LK_ENTRY *group_base;
6683 strcpy(MachineName, MoiraMachineName);
6684 rc = GetMachineName(MachineName);
6686 if (strlen(MachineName) == 0)
6688 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6693 cPtr = strchr(MachineName, '.');
6698 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6699 attr_array[0] = "sAMAccountName";
6700 attr_array[1] = NULL;
6702 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6704 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
6706 com_err(whoami, 0, "Unable to process machine %s : %s",
6707 MoiraMachineName, ldap_err2string(rc));
6711 if (group_count == 1)
6712 strcpy(OldDn, group_base->dn);
6714 linklist_free(group_base);
6717 if (group_count != 1)
6719 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6724 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6725 cPtr = strchr(OldDn, ',');
6730 if (!strcasecmp(cPtr, NewOu))
6734 sprintf(NewCn, "CN=%s", MachineName);
6735 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6740 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6746 memset(Name, '\0', sizeof(Name));
6747 strcpy(Name, machine_name);
6749 pPtr = strchr(Name, '.');
6755 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
6758 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6759 char *machine_name, char *container_name)
6765 av[0] = machine_name;
6766 call_args[0] = (char *)container_name;
6767 rc = mr_query("get_machine_to_container_map", 1, av,
6768 machine_GetMoiraContainer, call_args);
6772 int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6777 strcpy(call_args[0], av[1]);
6781 int Moira_container_group_create(char **after)
6787 memset(GroupName, '\0', sizeof(GroupName));
6788 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6789 after[CONTAINER_ROWID]);
6793 argv[L_NAME] = GroupName;
6794 argv[L_ACTIVE] = "1";
6795 argv[L_PUBLIC] = "0";
6796 argv[L_HIDDEN] = "0";
6797 argv[L_MAILLIST] = "0";
6798 argv[L_GROUP] = "1";
6799 argv[L_GID] = UNIQUE_GID;
6800 argv[L_NFSGROUP] = "0";
6801 argv[L_MAILMAN] = "0";
6802 argv[L_MAILMAN_SERVER] = "[NONE]";
6803 argv[L_DESC] = "auto created container group";
6804 argv[L_ACE_TYPE] = "USER";
6805 argv[L_MEMACE_TYPE] = "USER";
6806 argv[L_ACE_NAME] = "sms";
6807 argv[L_MEMACE_NAME] = "sms";
6809 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
6812 "Unable to create container group %s for container %s: %s",
6813 GroupName, after[CONTAINER_NAME], error_message(rc));
6816 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6817 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6822 int Moira_container_group_update(char **before, char **after)
6825 char BeforeGroupName[64];
6826 char AfterGroupName[64];
6829 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6832 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6833 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6834 if (strlen(BeforeGroupName) == 0)
6837 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6838 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6839 after[CONTAINER_ROWID]);
6843 if (strcasecmp(BeforeGroupName, AfterGroupName))
6845 argv[L_NAME] = BeforeGroupName;
6846 argv[L_NAME + 1] = AfterGroupName;
6847 argv[L_ACTIVE + 1] = "1";
6848 argv[L_PUBLIC + 1] = "0";
6849 argv[L_HIDDEN + 1] = "0";
6850 argv[L_MAILLIST + 1] = "0";
6851 argv[L_GROUP + 1] = "1";
6852 argv[L_GID + 1] = UNIQUE_GID;
6853 argv[L_NFSGROUP + 1] = "0";
6854 argv[L_MAILMAN + 1] = "0";
6855 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
6856 argv[L_DESC + 1] = "auto created container group";
6857 argv[L_ACE_TYPE + 1] = "USER";
6858 argv[L_MEMACE_TYPE + 1] = "USER";
6859 argv[L_ACE_NAME + 1] = "sms";
6860 argv[L_MEMACE_NAME + 1] = "sms";
6862 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
6865 "Unable to rename container group from %s to %s: %s",
6866 BeforeGroupName, AfterGroupName, error_message(rc));
6873 int Moira_container_group_delete(char **before)
6878 char ParentGroupName[64];
6880 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6881 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6883 memset(GroupName, '\0', sizeof(GroupName));
6885 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6886 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6888 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6890 argv[0] = ParentGroupName;
6892 argv[2] = GroupName;
6894 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6897 "Unable to delete container group %s from list: %s",
6898 GroupName, ParentGroupName, error_message(rc));
6902 if (strlen(GroupName) != 0)
6904 argv[0] = GroupName;
6906 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6908 com_err(whoami, 0, "Unable to delete container group %s : %s",
6909 GroupName, error_message(rc));
6916 int Moira_groupname_create(char *GroupName, char *ContainerName,
6917 char *ContainerRowID)
6922 char newGroupName[64];
6923 char tempGroupName[64];
6929 strcpy(temp, ContainerName);
6931 ptr1 = strrchr(temp, '/');
6937 ptr1 = strrchr(temp, '/');
6941 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6944 strcpy(tempgname, ptr);
6947 strcpy(tempgname, temp);
6949 if (strlen(tempgname) > 25)
6950 tempgname[25] ='\0';
6952 sprintf(newGroupName, "cnt-%s", tempgname);
6954 /* change everything to lower case */
6960 *ptr = tolower(*ptr);
6968 strcpy(tempGroupName, newGroupName);
6971 /* append 0-9 then a-z if a duplicate is found */
6974 argv[0] = newGroupName;
6976 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6978 if (rc == MR_NO_MATCH)
6980 com_err(whoami, 0, "Moira error while creating group name for "
6981 "container %s : %s", ContainerName, error_message(rc));
6985 sprintf(newGroupName, "%s-%c", tempGroupName, i);
6989 com_err(whoami, 0, "Unable to find a unique group name for "
6990 "container %s: too many duplicate container names",
7001 strcpy(GroupName, newGroupName);
7005 int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7010 argv[0] = origContainerName;
7011 argv[1] = GroupName;
7013 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7016 "Unable to set container group %s in container %s: %s",
7017 GroupName, origContainerName, error_message(rc));
7023 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7025 char ContainerName[64];
7026 char ParentGroupName[64];
7030 strcpy(ContainerName, origContainerName);
7032 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7034 /* top-level container */
7035 if (strlen(ParentGroupName) == 0)
7038 argv[0] = ParentGroupName;
7040 argv[2] = GroupName;
7042 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7045 "Unable to add container group %s to parent group %s: %s",
7046 GroupName, ParentGroupName, error_message(rc));
7052 int Moira_getContainerGroup(int ac, char **av, void *ptr)
7057 strcpy(call_args[0], av[1]);
7062 int Moira_getGroupName(char *origContainerName, char *GroupName,
7065 char ContainerName[64];
7071 strcpy(ContainerName, origContainerName);
7075 ptr = strrchr(ContainerName, '/');
7083 argv[0] = ContainerName;
7085 call_args[0] = GroupName;
7086 call_args[1] = NULL;
7088 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7091 if (strlen(GroupName) != 0)
7096 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7097 ContainerName, error_message(rc));
7099 com_err(whoami, 0, "Unable to get container group from container %s",
7105 int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7111 if (strcmp(GroupName, "[none]") == 0)
7114 argv[0] = GroupName;
7115 argv[1] = "MACHINE";
7116 argv[2] = MachineName;
7119 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7121 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7125 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7126 MachineName, GroupName, error_message(rc));
7132 int GetMachineName(char *MachineName)
7135 char NewMachineName[1024];
7142 // If the address happens to be in the top-level MIT domain, great!
7143 strcpy(NewMachineName, MachineName);
7145 for (i = 0; i < (int)strlen(NewMachineName); i++)
7146 NewMachineName[i] = toupper(NewMachineName[i]);
7148 szDot = strchr(NewMachineName,'.');
7150 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7155 // If not, see if it has a Moira alias in the top-level MIT domain.
7156 memset(NewMachineName, '\0', sizeof(NewMachineName));
7158 args[1] = MachineName;
7159 call_args[0] = NewMachineName;
7160 call_args[1] = NULL;
7162 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7164 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7165 MachineName, error_message(rc));
7166 strcpy(MachineName, "");
7170 if (strlen(NewMachineName) != 0)
7171 strcpy(MachineName, NewMachineName);
7173 strcpy(MachineName, "");
7178 int ProcessMachineName(int ac, char **av, void *ptr)
7181 char MachineName[1024];
7187 if (strlen(call_args[0]) == 0)
7189 strcpy(MachineName, av[0]);
7191 for (i = 0; i < (int)strlen(MachineName); i++)
7192 MachineName[i] = toupper(MachineName[i]);
7194 szDot = strchr(MachineName,'.');
7196 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
7198 strcpy(call_args[0], MachineName);
7205 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7211 for (i = 0; i < n; i++)
7213 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7214 mods[i]->mod_type = "uidNumber";
7221 for (i = 0; i < n; i++)
7223 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7224 mods[i]->mod_type = "msSFU30UidNumber";
7231 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7232 char *DistinguishedName,
7233 char *WinHomeDir, char *WinProfileDir,
7234 char **homedir_v, char **winProfile_v,
7235 char **drives_v, LDAPMod **mods,
7243 char winProfile[1024];
7248 LDAPMod *DelMods[20];
7250 memset(homeDrive, '\0', sizeof(homeDrive));
7251 memset(path, '\0', sizeof(path));
7252 memset(winPath, '\0', sizeof(winPath));
7253 memset(winProfile, '\0', sizeof(winProfile));
7256 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7257 (!strcasecmp(WinProfileDir, "[afs]")))
7259 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
7261 memset(cWeight, 0, sizeof(cWeight));
7262 memset(cPath, 0, sizeof(cPath));
7266 while (hp[i] != NULL)
7268 if (sscanf(hp[i], "%*s %s", cPath))
7270 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
7272 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
7274 if (atoi(cWeight) < last_weight)
7276 strcpy(path, cPath);
7277 last_weight = (int)atoi(cWeight);
7281 strcpy(path, cPath);
7289 if (!strnicmp(path, AFS, strlen(AFS)))
7291 AfsToWinAfs(path, winPath);
7292 strcpy(winProfile, winPath);
7293 strcat(winProfile, "\\.winprofile");
7301 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7302 (!strcasecmp(WinProfileDir, "[dfs]")))
7304 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7305 user_name[0], user_name);
7307 if (!strcasecmp(WinProfileDir, "[dfs]"))
7309 strcpy(winProfile, path);
7310 strcat(winProfile, "\\.winprofile");
7313 if (!strcasecmp(WinHomeDir, "[dfs]"))
7314 strcpy(winPath, path);
7327 if (!strcasecmp(WinHomeDir, "[local]"))
7328 memset(winPath, '\0', sizeof(winPath));
7329 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7330 !strcasecmp(WinHomeDir, "[dfs]"))
7332 strcpy(homeDrive, "H:");
7336 strcpy(winPath, WinHomeDir);
7337 if (!strncmp(WinHomeDir, "\\\\", 2))
7339 strcpy(homeDrive, "H:");
7343 // nothing needs to be done if WinProfileDir is [afs].
7344 if (!strcasecmp(WinProfileDir, "[local]"))
7345 memset(winProfile, '\0', sizeof(winProfile));
7346 else if (strcasecmp(WinProfileDir, "[afs]") &&
7347 strcasecmp(WinProfileDir, "[dfs]"))
7349 strcpy(winProfile, WinProfileDir);
7352 if (strlen(winProfile) != 0)
7354 if (winProfile[strlen(winProfile) - 1] == '\\')
7355 winProfile[strlen(winProfile) - 1] = '\0';
7358 if (strlen(winPath) != 0)
7360 if (winPath[strlen(winPath) - 1] == '\\')
7361 winPath[strlen(winPath) - 1] = '\0';
7364 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
7365 strcat(winProfile, "\\");
7367 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7368 strcat(winPath, "\\");
7370 if (strlen(winPath) == 0)
7372 if (OpType == LDAP_MOD_REPLACE)
7375 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7377 //unset homeDirectory attribute for user.
7378 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7384 homedir_v[0] = strdup(winPath);
7385 ADD_ATTR("homeDirectory", homedir_v, OpType);
7388 if (strlen(winProfile) == 0)
7390 if (OpType == LDAP_MOD_REPLACE)
7393 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7395 //unset profilePate attribute for user.
7396 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7402 winProfile_v[0] = strdup(winProfile);
7403 ADD_ATTR("profilePath", winProfile_v, OpType);
7406 if (strlen(homeDrive) == 0)
7408 if (OpType == LDAP_MOD_REPLACE)
7411 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7413 //unset homeDrive attribute for user
7414 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7420 drives_v[0] = strdup(homeDrive);
7421 ADD_ATTR("homeDrive", drives_v, OpType);
7427 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
7428 char *attribute_value, char *attribute, char *user_name)
7430 char *mod_v[] = {NULL, NULL};
7431 LDAPMod *DelMods[20];
7437 if (strlen(attribute_value) == 0)
7440 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7442 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7448 mod_v[0] = attribute_value;
7449 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7452 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7453 mods)) != LDAP_SUCCESS)
7457 mod_v[0] = attribute_value;
7458 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7461 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7462 mods)) != LDAP_SUCCESS)
7464 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7466 attribute, user_name, ldap_err2string(rc));
7476 void StringTrim(char *StringToTrim)
7481 save = strdup(StringToTrim);
7488 /* skip to end of string */
7493 strcpy(StringToTrim, save);
7497 for (t = s; *t; t++)
7513 strcpy(StringToTrim, s);
7517 int ReadConfigFile(char *DomainName)
7528 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
7530 if ((fptr = fopen(temp, "r")) != NULL)
7532 while (fgets(temp, sizeof(temp), fptr) != 0)
7534 for (i = 0; i < (int)strlen(temp); i++)
7535 temp[i] = toupper(temp[i]);
7537 if (temp[strlen(temp) - 1] == '\n')
7538 temp[strlen(temp) - 1] = '\0';
7542 if (strlen(temp) == 0)
7545 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7547 if (strlen(temp) > (strlen(DOMAIN)))
7549 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7550 StringTrim(ldap_domain);
7553 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
7555 if (strlen(temp) > (strlen(PRINCIPALNAME)))
7557 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7558 StringTrim(PrincipalName);
7561 else if (!strncmp(temp, SERVER, strlen(SERVER)))
7563 if (strlen(temp) > (strlen(SERVER)))
7565 ServerList[Count] = calloc(1, 256);
7566 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7567 StringTrim(ServerList[Count]);
7571 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
7573 if (strlen(temp) > (strlen(MSSFU)))
7575 strcpy(temp1, &temp[strlen(MSSFU)]);
7577 if (!strcmp(temp1, SFUTYPE))
7581 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7583 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7585 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7587 if (!strcasecmp(temp1, "NO"))
7590 memset(group_suffix, '\0', sizeof(group_suffix));
7594 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7596 if (strlen(temp) > (strlen(GROUP_TYPE)))
7598 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7600 if (!strcasecmp(temp1, "UNIVERSAL"))
7601 UseGroupUniversal = 1;
7604 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7606 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7608 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7610 if (!strcasecmp(temp1, "NO"))
7614 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7616 if (strlen(temp) > (strlen(SET_PASSWORD)))
7618 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7620 if (!strcasecmp(temp1, "NO"))
7624 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7626 if (strlen(temp) > (strlen(EXCHANGE)))
7628 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7630 if (!strcasecmp(temp1, "YES"))
7634 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7635 strlen(PROCESS_MACHINE_CONTAINER)))
7637 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7639 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7641 if (!strcasecmp(temp1, "NO"))
7642 ProcessMachineContainer = 0;
7647 if (strlen(ldap_domain) != 0)
7649 memset(ldap_domain, '\0', sizeof(ldap_domain));
7653 if (strlen(temp) != 0)
7654 strcpy(ldap_domain, temp);
7660 if (strlen(ldap_domain) == 0)
7662 strcpy(ldap_domain, DomainName);
7668 for (i = 0; i < Count; i++)
7670 if (ServerList[i] != 0)
7672 strcat(ServerList[i], ".");
7673 strcat(ServerList[i], ldap_domain);
7674 for (k = 0; k < (int)strlen(ServerList[i]); k++)
7675 ServerList[i][k] = toupper(ServerList[i][k]);
7682 int ReadDomainList()
7689 unsigned char c[11];
7690 unsigned char stuff[256];
7695 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
7697 if ((fptr = fopen(temp, "r")) != NULL)
7699 while (fgets(temp, sizeof(temp), fptr) != 0)
7701 for (i = 0; i < (int)strlen(temp); i++)
7702 temp[i] = toupper(temp[i]);
7704 if (temp[strlen(temp) - 1] == '\n')
7705 temp[strlen(temp) - 1] = '\0';
7709 if (strlen(temp) == 0)
7712 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7714 if (strlen(temp) > (strlen(DOMAIN)))
7716 strcpy(temp1, &temp[strlen(DOMAIN)]);
7718 strcpy(temp, temp1);
7722 strcpy(DomainNames[Count], temp);
7723 StringTrim(DomainNames[Count]);
7732 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7733 "configuration error in winad.cfg");
7740 int email_isvalid(const char *address) {
7742 const char *c, *domain;
7743 static char *rfc822_specials = "()<>@,;:\\\"[]";
7745 if(address[strlen(address) - 1] == '.')
7748 /* first we validate the name portion (name@domain) */
7749 for (c = address; *c; c++) {
7750 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7755 if (*c == '\\' && (*++c == ' '))
7757 if (*c <= ' ' || *c >= 127)
7772 if (*c <= ' ' || *c >= 127)
7774 if (strchr(rfc822_specials, *c))
7778 if (c == address || *(c - 1) == '.')
7781 /* next we validate the domain portion (name@domain) */
7782 if (!*(domain = ++c)) return 0;
7785 if (c == domain || *(c - 1) == '.')
7789 if (*c <= ' ' || *c >= 127)
7791 if (strchr(rfc822_specials, *c))
7795 return (count >= 1);
7798 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7799 char **homeServerName)
7801 LK_ENTRY *group_base;
7802 LK_ENTRY *sub_group_base;
7806 int sub_group_count;
7808 char sub_filter[1024];
7809 char search_path[1024];
7811 char *attr_array[3];
7813 int homeMDB_count = -1;
7817 int rangeStep = 1500;
7819 int rangeHigh = rangeLow + (rangeStep - 1);
7822 /* Grumble..... microsoft not making it searchable from the root *grr* */
7824 memset(filter, '\0', sizeof(filter));
7825 memset(search_path, '\0', sizeof(search_path));
7827 sprintf(filter, "(objectClass=msExchMDB)");
7828 sprintf(search_path, "CN=Configuration,%s", dn_path);
7829 attr_array[0] = "distinguishedName";
7830 attr_array[1] = NULL;
7835 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7836 &group_base, &group_count,
7837 LDAP_SCOPE_SUBTREE)) != 0)
7839 com_err(whoami, 0, "Unable to find msExchMDB %s",
7840 ldap_err2string(rc));
7849 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
7850 ((s = strstr(gPtr->dn, "Recovery")) != (char *) NULL))
7857 * Due to limits in active directory we need to use the LDAP
7858 * range semantics to query and return all the values in
7859 * large lists, we will stop increasing the range when
7860 * the result count is 0.
7868 memset(sub_filter, '\0', sizeof(sub_filter));
7869 memset(range, '\0', sizeof(range));
7870 sprintf(sub_filter, "(objectClass=msExchMDB)");
7873 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
7875 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
7877 attr_array[0] = range;
7878 attr_array[1] = NULL;
7880 sub_group_base = NULL;
7881 sub_group_count = 0;
7883 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
7884 attr_array, &sub_group_base,
7886 LDAP_SCOPE_SUBTREE)) != 0)
7888 com_err(whoami, 0, "Unable to find homeMDBBL %s",
7889 ldap_err2string(rc));
7893 if(!sub_group_count)
7899 rangeHigh = rangeLow + (rangeStep - 1);
7906 mdbbl_count += sub_group_count;
7907 rangeLow = rangeHigh + 1;
7908 rangeHigh = rangeLow + (rangeStep - 1);
7911 /* First time through, need to initialize or update the least used */
7913 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
7916 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
7918 homeMDB_count = mdbbl_count;
7919 *homeMDB = strdup(gPtr->dn);
7923 linklist_free(sub_group_base);
7927 linklist_free(group_base);
7930 * Ok found the server least allocated need to now query to get its
7931 * msExchHomeServerName so we can set it as a user attribute
7934 attr_array[0] = "legacyExchangeDN";
7935 attr_array[1] = NULL;
7940 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
7941 attr_array, &group_base,
7943 LDAP_SCOPE_SUBTREE)) != 0)
7945 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
7946 ldap_err2string(rc));
7952 *homeServerName = strdup(group_base->value);
7953 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
7959 linklist_free(group_base);
7964 char *lowercase(char *s)
7968 for (p = s; *p; p++)
7976 char *uppercase(char *s)
7980 for (p = s; *p; p++)
7988 int save_query_info(int argc, char **argv, void *hint)
7991 char **nargv = hint;
7993 for(i = 0; i < argc; i++)
7994 nargv[i] = strdup(argv[i]);