2 /* winad.incr arguments example
4 * arguments when moira creates the account - ignored by winad.incr since the
5 * account is unusable. users 0 11 #45198 45198 /bin/cmd cmd Last First Middle
6 * 0 950000001 2000 121049
8 * login, unix_uid, shell, winconsoleshell, last,
9 * first, middle, status, mitid, type, moiraid
11 * arguments for creating or updating a user account
12 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
13 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
14 * First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
15 * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF
16 * 121058 PathToHomeDir PathToProfileDir newuser 45206 /bin/cmd cmd Last
17 * First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
19 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
20 * mitid, type, moiraid
22 * arguments for deactivating/deleting a user account
23 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
24 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
25 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
26 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
27 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
28 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
30 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
31 * mitid, type, moiraid
33 * arguments for reactivating a user account
34 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
35 * 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
37 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
38 * 121058 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 12105
40 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
41 * mitid, type, moiraid
43 * arguments for changing user name
44 * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001
45 * STAFF 121058 PathToHomeDir PathToProfileDir newusername 45206 /bin/cmd cmd
46 * Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
48 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
49 * mitid, type, moiraid
51 * arguments for expunging a user
52 * users 11 0 username 45198 /bin/cmd cmd Last First Middle 0 950000001 2000
55 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
56 * mitid, type, moiraid
58 * arguments for creating a "special" group/list
59 * list 0 11 listname 1 1 0 0 0 -1 NONE 0 description 92616
61 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
62 * acl_id, description, moiraid
64 * arguments for creating a "mail" group/list
65 * list 0 11 listname 1 1 0 1 0 -1 NONE 0 description 92616
67 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
68 * acl_id, description, moiraid
70 * arguments for creating a "group" group/list
71 * list 0 11 listname 1 1 0 0 1 -1 NONE 0 description 92616
73 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
74 * acl_id, description, moiraid
76 * arguments for creating a "group/mail" group/list
77 * list 0 11 listname 1 1 0 1 1 -1 NONE 0 description 92616
79 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
80 * acl_id, description, moiraid
82 * arguments to add a USER member to group/list
83 * imembers 0 12 listname USER userName 1 1 0 0 0 -1 1 92616 121047
85 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
86 * gid, userStatus, moiraListId, moiraUserId
88 * arguments to add a STRING or KERBEROS member to group/list
89 * imembers 0 10 listname STRING stringName 1 1 0 0 0 -1 92616
90 * imembers 0 10 listlistnameName KERBEROS kerberosName 1 1 0 0 0 -1 92616
92 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
95 * NOTE: group members of type LIST are ignored.
97 * arguments to remove a USER member to group/list
98 * imembers 12 0 listname USER userName 1 1 0 0 0 -1 1 92616 121047
100 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
101 * gid, userStatus, moiraListId, moiraUserId
103 * arguments to remove a STRING or KERBEROS member to group/list
104 * imembers 10 0 listname STRING stringName 1 1 0 0 0 -1 92616
105 * imembers 10 0 listname KERBEROS kerberosName 1 1 0 0 0 -1 92616
107 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
110 * NOTE: group members of type LIST are ignored.
112 * arguments for renaming a group/list
113 * list 11 11 oldlistname 1 1 0 0 0 -1 NONE 0 description 92616 newlistname 1
114 * 1 0 0 0 -1 description 0 92616
116 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
117 * acl_id, description, moiraListId
119 * arguments for deleting a group/list
120 * list 11 0 listname 1 1 0 0 0 -1 NONE 0 description 92616
122 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
123 * acl_id, description, moiraListId
125 * arguments for adding a file system
126 * filesys 0 12 username AFS ATHENA.MIT.EDU
127 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
128 * wheel 1 HOMEDIR 101727
130 * arguments for deleting a file system
131 * filesys 12 0 username AFS ATHENA.MIT.EDU
132 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
133 * wheel 1 HOMEDIR 101727
135 * arguments when moira creates a container (OU).
136 * containers 0 8 machines/test/bottom description location contact USER
139 * arguments when moira deletes a container (OU).
140 * containers 8 0 machines/test/bottom description location contact USER
141 * 105316 2222 groupname
143 * arguments when moira modifies a container information (OU).
144 * containers 8 8 machines/test/bottom description location contact USER
145 * 105316 2222 groupname machines/test/bottom description1 location contact
146 * USER 105316 2222 groupname
148 * arguments when moira adds a machine from an OU
149 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
150 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
152 * arguments when moira removes a machine from an OU
153 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
154 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
158 #include <mit-copyright.h>
161 #include <winsock2.h>
165 #include <lmaccess.h>
173 #include <moira_site.h>
174 #include <mrclient.h>
182 #define ECONNABORTED WSAECONNABORTED
185 #define ECONNREFUSED WSAECONNREFUSED
188 #define EHOSTUNREACH WSAEHOSTUNREACH
190 #define krb5_xfree free
192 #define sleep(A) Sleep(A * 1000);
196 #include <sys/types.h>
197 #include <netinet/in.h>
198 #include <arpa/nameser.h>
200 #include <sys/utsname.h>
203 #define CFG_PATH "/moira/winad/"
204 #define WINADCFG "winad.cfg"
205 #define strnicmp(A,B,C) strncasecmp(A,B,C)
206 #define UCHAR unsigned char
208 #define UF_SCRIPT 0x0001
209 #define UF_ACCOUNTDISABLE 0x0002
210 #define UF_HOMEDIR_REQUIRED 0x0008
211 #define UF_LOCKOUT 0x0010
212 #define UF_PASSWD_NOTREQD 0x0020
213 #define UF_PASSWD_CANT_CHANGE 0x0040
214 #define UF_DONT_EXPIRE_PASSWD 0x10000
216 #define UF_TEMP_DUPLICATE_ACCOUNT 0x0100
217 #define UF_NORMAL_ACCOUNT 0x0200
218 #define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800
219 #define UF_WORKSTATION_TRUST_ACCOUNT 0x1000
220 #define UF_SERVER_TRUST_ACCOUNT 0x2000
222 #define OWNER_SECURITY_INFORMATION (0x00000001L)
223 #define GROUP_SECURITY_INFORMATION (0x00000002L)
224 #define DACL_SECURITY_INFORMATION (0x00000004L)
225 #define SACL_SECURITY_INFORMATION (0x00000008L)
228 #define BYTE unsigned char
230 typedef unsigned int DWORD;
231 typedef unsigned long ULONG;
236 unsigned short Data2;
237 unsigned short Data3;
238 unsigned char Data4[8];
241 typedef struct _SID_IDENTIFIER_AUTHORITY {
243 } SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
245 typedef struct _SID {
247 BYTE SubAuthorityCount;
248 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
249 DWORD SubAuthority[512];
254 #define WINADCFG "winad.cfg"
262 #define WINAFS "\\\\afs\\all\\"
264 #define ADS_GROUP_TYPE_GLOBAL_GROUP 0x00000002
265 #define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP 0x00000004
266 #define ADS_GROUP_TYPE_LOCAL_GROUP 0x00000004
267 #define ADS_GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
268 #define ADS_GROUP_TYPE_SECURITY_ENABLED 0x80000000
270 #define QUERY_VERSION -1
271 #define PRIMARY_REALM "ATHENA.MIT.EDU"
272 #define PRIMARY_DOMAIN "win.mit.edu"
273 #define PRODUCTION_PRINCIPAL "sms"
274 #define TEST_PRINCIPAL "smstest"
283 #define MEMBER_REMOVE 2
284 #define MEMBER_CHANGE_NAME 3
285 #define MEMBER_ACTIVATE 4
286 #define MEMBER_DEACTIVATE 5
287 #define MEMBER_CREATE 6
289 #define MOIRA_ALL 0x0
290 #define MOIRA_USERS 0x1
291 #define MOIRA_KERBEROS 0x2
292 #define MOIRA_STRINGS 0x4
293 #define MOIRA_LISTS 0x8
295 #define CHECK_GROUPS 1
296 #define CLEANUP_GROUPS 2
298 #define AD_NO_GROUPS_FOUND -1
299 #define AD_WRONG_GROUP_DN_FOUND -2
300 #define AD_MULTIPLE_GROUPS_FOUND -3
301 #define AD_INVALID_NAME -4
302 #define AD_LDAP_FAILURE -5
303 #define AD_INVALID_FILESYS -6
304 #define AD_NO_ATTRIBUTE_FOUND -7
305 #define AD_NO_OU_FOUND -8
306 #define AD_NO_USER_FOUND -9
308 /* container arguments */
309 #define CONTAINER_NAME 0
310 #define CONTAINER_DESC 1
311 #define CONTAINER_LOCATION 2
312 #define CONTAINER_CONTACT 3
313 #define CONTAINER_TYPE 4
314 #define CONTAINER_ID 5
315 #define CONTAINER_ROWID 6
316 #define CONTAINER_GROUP_NAME 7
318 /*mcntmap arguments*/
319 #define OU_MACHINE_NAME 0
320 #define OU_CONTAINER_NAME 1
321 #define OU_MACHINE_ID 2
322 #define OU_CONTAINER_ID 3
323 #define OU_CONTAINER_GROUP 4
325 typedef struct lk_entry {
335 struct lk_entry *next;
338 #define STOP_FILE "/moira/winad/nowinad"
339 #define file_exists(file) (access((file), F_OK) == 0)
341 #define N_SD_BER_BYTES 5
342 #define LDAP_BERVAL struct berval
343 #define MAX_SERVER_NAMES 32
345 #define HIDDEN_GROUP "HiddenGroup.g"
346 #define HIDDEN_GROUP_WITH_ADMIN "HiddenGroupWithAdmin.g"
347 #define NOT_HIDDEN_GROUP "NotHiddenGroup.g"
348 #define NOT_HIDDEN_GROUP_WITH_ADMIN "NotHiddenGroupWithAdmin.g"
350 #define ADDRESS_LIST_PREFIX "CN=MIT Directory,CN=All Address Lists,\
351 CN=Address Lists Container,CN=Massachusetts Institute of Technology,\
352 CN=Microsoft Exchange,CN=Services,CN=Configuration,"
354 #define ADD_ATTR(t, v, o) \
355 mods[n] = malloc(sizeof(LDAPMod)); \
356 mods[n]->mod_op = o; \
357 mods[n]->mod_type = t; \
358 mods[n++]->mod_values = v
360 #define DEL_ATTR(t, o) \
361 DelMods[i] = malloc(sizeof(LDAPMod)); \
362 DelMods[i]->mod_op = o; \
363 DelMods[i]->mod_type = t; \
364 DelMods[i++]->mod_values = NULL
366 #define DOMAIN_SUFFIX "MIT.EDU"
367 #define DOMAIN "DOMAIN:"
368 #define PRINCIPALNAME "PRINCIPAL:"
369 #define SERVER "SERVER:"
372 #define GROUP_SUFFIX "GROUP_SUFFIX:"
373 #define GROUP_TYPE "GROUP_TYPE:"
374 #define SET_GROUP_ACE "SET_GROUP_ACE:"
375 #define SET_PASSWORD "SET_PASSWORD:"
376 #define EXCHANGE "EXCHANGE:"
377 #define PROCESS_MACHINE_CONTAINER "PROCESS_MACHINE_CONTAINER:"
378 #define MAX_DOMAINS 10
379 char DomainNames[MAX_DOMAINS][128];
381 LK_ENTRY *member_base = NULL;
383 char PrincipalName[128];
384 static char tbl_buf[1024];
385 char kerberos_ou[] = "OU=kerberos,OU=moira";
386 char contact_ou[] = "OU=strings,OU=moira";
387 char user_ou[] = "OU=users,OU=moira";
388 char group_ou_distribution[] = "OU=mail,OU=lists,OU=moira";
389 char group_ou_root[] = "OU=lists,OU=moira";
390 char group_ou_security[] = "OU=group,OU=lists,OU=moira";
391 char group_ou_neither[] = "OU=special,OU=lists,OU=moira";
392 char group_ou_both[] = "OU=mail,OU=group,OU=lists,OU=moira";
393 char orphans_machines_ou[] = "OU=Machines,OU=Orphans";
394 char orphans_other_ou[] = "OU=Other,OU=Orphans";
395 char security_template_ou[] = "OU=security_templates";
397 char ldap_domain[256];
398 char *ServerList[MAX_SERVER_NAMES];
399 char default_server[256];
400 static char tbl_buf[1024];
401 char group_suffix[256];
402 char exchange_acl[256];
403 int mr_connections = 0;
406 int UseGroupSuffix = 1;
407 int UseGroupUniversal = 0;
411 int ProcessMachineContainer = 1;
412 int UpdateDomainList;
414 extern int set_password(char *user, char *password, char *domain);
416 int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name,
417 char *group_membership, char *MoiraId, char *attribute,
418 LK_ENTRY **linklist_base, int *linklist_count,
420 void AfsToWinAfs(char* path, char* winPath);
421 int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
422 char *Win2kPassword, char *Win2kUser, char *default_server,
423 int connect_to_kdc, char **ServerList);
424 void ad_kdc_disconnect();
425 int ad_server_connect(char *connectedServer, char *domain);
426 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
427 char *attribute_value, char *attribute, char *user_name);
428 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer);
429 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name);
430 int check_winad(void);
431 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName,
434 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
435 char *distinguishedName, int count, char **av);
436 void container_check(LDAP *ldap_handle, char *dn_path, char *name);
437 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av);
438 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av);
439 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
440 char *distinguishedName, int count,
442 void container_get_dn(char *src, char *dest);
443 void container_get_name(char *src, char *dest);
444 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName);
445 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
446 char **before, int afterc, char **after);
447 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
448 char **before, int afterc, char **after);
450 int GetAceInfo(int ac, char **av, void *ptr);
451 int get_group_membership(char *group_membership, char *group_ou,
452 int *security_flag, char **av);
453 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
454 char *machine_ou, char *pPtr);
455 int Moira_container_group_create(char **after);
456 int Moira_container_group_delete(char **before);
457 int Moira_groupname_create(char *GroupName, char *ContainerName,
458 char *ContainerRowID);
459 int Moira_container_group_update(char **before, char **after);
460 int Moira_process_machine_container_group(char *MachineName, char* groupName,
462 int Moira_addGroupToParent(char *origContainerName, char *GroupName);
463 int Moira_getContainerGroup(int ac, char **av, void *ptr);
464 int Moira_getGroupName(char *origContainerName, char *GroupName,
466 int Moira_setContainerGroup(char *ContainerName, char *GroupName);
467 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *group_name, char *Type,
468 int UpdateGroup, int *ProcessGroup, char *maillist);
469 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
470 char *group_name, char *group_ou, char *group_membership,
471 int group_security_flag, int type, char *maillist);
472 int process_lists(int ac, char **av, void *ptr);
473 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
474 char *TargetGroupName, int HiddenGroup,
475 char *AceType, char *AceName);
476 int ProcessMachineName(int ac, char **av, void *ptr);
477 int ReadConfigFile(char *DomainName);
478 int ReadDomainList();
479 void StringTrim(char *StringToTrim);
480 int save_query_info(int argc, char **argv, void *hint);
481 int user_create(int ac, char **av, void *ptr);
482 int user_change_status(LDAP *ldap_handle, char *dn_path,
483 char *user_name, char *MoiraId, int operation);
484 int user_delete(LDAP *ldap_handle, char *dn_path,
485 char *u_name, char *MoiraId);
486 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
488 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
489 char *uid, char *MitId, char *MoiraId, int State,
490 char *WinHomeDir, char *WinProfileDir, char *first,
491 char *middle, char *last);
492 void change_to_lower_case(char *ptr);
493 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
494 int contact_remove_email(LDAP *ld, char *bind_path,
495 LK_ENTRY **linklist_entry, int linklist_current);
496 int group_create(int ac, char **av, void *ptr);
497 int group_delete(LDAP *ldap_handle, char *dn_path,
498 char *group_name, char *group_membership, char *MoiraId);
499 int group_rename(LDAP *ldap_handle, char *dn_path,
500 char *before_group_name, char *before_group_membership,
501 char *before_group_ou, int before_security_flag,
502 char *before_desc, char *after_group_name,
503 char *after_group_membership, char *after_group_ou,
504 int after_security_flag, char *after_desc,
505 char *MoiraId, char *filter, char *maillist);
506 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name);
507 int machine_GetMoiraContainer(int ac, char **av, void *ptr);
508 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
509 char *machine_name, char *container_name);
510 int machine_move_to_ou(LDAP *ldap_handle, char *dn_path,
511 char *MoiraMachineName, char *DestinationOu);
512 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
513 char *group_name, char *group_ou, char *group_membership,
514 int group_security_flag, int updateGroup, char *maillist);
515 int member_list_build(int ac, char **av, void *ptr);
516 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
517 char *group_ou, char *group_membership,
518 char *user_name, char *pUserOu, char *MoiraId);
519 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
520 char *group_ou, char *group_membership, char *user_name,
521 char *pUserOu, char *MoiraId);
522 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
523 char *group_ou, char *group_membership,
524 int group_security_flag, char *MoiraId);
525 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
526 char *DistinguishedName,
527 char *WinHomeDir, char *WinProfileDir,
528 char **homedir_v, char **winProfile_v,
529 char **drives_v, LDAPMod **mods,
531 int sid_update(LDAP *ldap_handle, char *dn_path);
532 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n);
533 int check_string(char *s);
534 int check_container_name(char* s);
536 int mr_connect_cl(char *server, char *client, int version, int auth);
537 void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
538 char **before, int beforec, char **after, int afterc);
539 void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
540 char **before, int beforec, char **after, int afterc);
541 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
542 char **before, int beforec, char **after, int afterc);
543 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
544 char **before, int beforec, char **after, int afterc);
545 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
546 char **before, int beforec, char **after, int afterc);
547 void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
548 char **before, int beforec, char **after, int afterc);
549 int linklist_create_entry(char *attribute, char *value,
550 LK_ENTRY **linklist_entry);
551 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
552 char **attr_array, LK_ENTRY **linklist_base,
553 int *linklist_count, unsigned long ScopeType);
554 void linklist_free(LK_ENTRY *linklist_base);
556 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
557 char *distinguished_name, LK_ENTRY **linklist_current);
558 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
559 LK_ENTRY **linklist_base, int *linklist_count);
560 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
561 char *Attribute, char *distinguished_name,
562 LK_ENTRY **linklist_current);
564 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
565 char *oldValue, char *newValue,
566 char ***modvalues, int type);
567 void free_values(char **modvalues);
569 int convert_domain_to_dn(char *domain, char **bind_path);
570 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
571 char *distinguished_name);
572 int moira_disconnect(void);
573 int moira_connect(void);
574 void print_to_screen(const char *fmt, ...);
575 int GetMachineName(char *MachineName);
576 int tickets_get_k5();
577 int destroy_cache(void);
580 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
581 char **homeServerName);
583 int main(int argc, char **argv)
599 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
603 com_err(whoami, 0, "Unable to process %s", "argc < 4");
607 if (argc < (4 + atoi(argv[2]) + atoi(argv[3])))
609 com_err(whoami, 0, "Unable to process %s",
610 "argc < (4 + beforec + afterc)");
614 if (!strcmp(argv[1], "filesys"))
617 for (i = 1; i < argc; i++)
619 strcat(tbl_buf, argv[i]);
620 strcat(tbl_buf, " ");
623 com_err(whoami, 0, "%s", tbl_buf);
627 com_err(whoami, 0, "%s failed", "check_winad()");
631 initialize_sms_error_table();
632 initialize_krb_error_table();
634 UpdateDomainList = 0;
635 memset(DomainNames, '\0', sizeof(DomainNames[0]) * MAX_DOMAINS);
637 if (ReadDomainList())
639 com_err(whoami, 0, "%s failed", "ReadDomainList()");
643 for (i = 0; i < argc; i++)
646 for (k = 0; k < MAX_DOMAINS; k++)
648 if (strlen(DomainNames[k]) == 0)
650 for (i = 0; i < argc; i++)
652 if (orig_argv[i] != NULL)
654 orig_argv[i] = strdup(argv[i]);
657 memset(PrincipalName, '\0', sizeof(PrincipalName));
658 memset(ldap_domain, '\0', sizeof(ldap_domain));
659 memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES);
660 memset(default_server, '\0', sizeof(default_server));
661 memset(dn_path, '\0', sizeof(dn_path));
662 memset(group_suffix, '\0', sizeof(group_suffix));
663 memset(exchange_acl, '\0', sizeof(exchange_acl));
667 UseGroupUniversal = 0;
671 ProcessMachineContainer = 1;
673 sprintf(group_suffix, "%s", "_group");
674 sprintf(exchange_acl, "%s", "exchange-acl");
676 beforec = atoi(orig_argv[2]);
677 afterc = atoi(orig_argv[3]);
678 table = orig_argv[1];
679 before = &orig_argv[4];
680 after = &orig_argv[4 + beforec];
688 if (ReadConfigFile(DomainNames[k]))
691 OldUseSFU30 = UseSFU30;
693 for (i = 0; i < 5; i++)
695 ldap_handle = (LDAP *)NULL;
696 if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "",
697 default_server, 1, ServerList)))
699 com_err(whoami, 0, "connected to domain %s", DomainNames[k]);
704 if ((rc) || (ldap_handle == NULL))
706 critical_alert("incremental",
707 "winad.incr cannot connect to any server in "
708 "domain %s", DomainNames[k]);
712 for (i = 0; i < (int)strlen(table); i++)
713 table[i] = tolower(table[i]);
715 if (!strcmp(table, "users"))
716 do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
718 else if (!strcmp(table, "list"))
719 do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
721 else if (!strcmp(table, "imembers"))
722 do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
724 else if (!strcmp(table, "containers"))
725 do_container(ldap_handle, dn_path, ldap_domain, before, beforec, after,
727 else if (!strcmp(table, "mcntmap"))
728 do_mcntmap(ldap_handle, dn_path, ldap_domain, before, beforec, after,
733 for (i = 0; i < MAX_SERVER_NAMES; i++)
735 if (ServerList[i] != NULL)
738 ServerList[i] = NULL;
742 rc = ldap_unbind_s(ldap_handle);
748 void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
749 char **before, int beforec, char **after, int afterc)
751 char MoiraContainerName[128];
752 char ADContainerName[128];
753 char MachineName[1024];
754 char OriginalMachineName[1024];
757 char MoiraContainerGroup[64];
759 if (!ProcessMachineContainer)
761 com_err(whoami, 0, "Process machines and containers disabled, skipping");
766 memset(ADContainerName, '\0', sizeof(ADContainerName));
767 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
769 if ((beforec == 0) && (afterc == 0))
772 if (rc = moira_connect())
774 critical_alert("AD incremental",
775 "Error contacting Moira server : %s",
780 if ((beforec != 0) && (afterc == 0)) /*remove a machine*/
782 strcpy(OriginalMachineName, before[OU_MACHINE_NAME]);
783 strcpy(MachineName, before[OU_MACHINE_NAME]);
784 strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]);
786 com_err(whoami, 0, "removing machine %s from %s",
787 OriginalMachineName, before[OU_CONTAINER_NAME]);
789 else if ((beforec == 0) && (afterc != 0)) /*add a machine*/
791 strcpy(OriginalMachineName, after[OU_MACHINE_NAME]);
792 strcpy(MachineName, after[OU_MACHINE_NAME]);
793 strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]);
794 com_err(whoami, 0, "adding machine %s to container %s",
795 OriginalMachineName, after[OU_CONTAINER_NAME]);
803 rc = GetMachineName(MachineName);
805 if (strlen(MachineName) == 0)
808 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
809 OriginalMachineName);
813 Moira_process_machine_container_group(MachineName, MoiraContainerGroup,
816 if (machine_check(ldap_handle, dn_path, MachineName))
818 com_err(whoami, 0, "Unable to find machine %s (alias %s) in AD.",
819 OriginalMachineName, MachineName);
824 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
825 machine_get_moira_container(ldap_handle, dn_path, MachineName,
828 if (strlen(MoiraContainerName) == 0)
830 com_err(whoami, 0, "Unable to fine machine %s (alias %s) container "
831 "in Moira - moving to orphans OU.",
832 OriginalMachineName, MachineName);
833 machine_move_to_ou(ldap_handle, dn_path, MachineName,
834 orphans_machines_ou);
839 container_get_dn(MoiraContainerName, ADContainerName);
841 if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/')
842 strcat(MoiraContainerName, "/");
844 container_check(ldap_handle, dn_path, MoiraContainerName);
845 machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName);
850 void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
851 char **before, int beforec, char **after, int afterc)
855 if (!ProcessMachineContainer)
857 com_err(whoami, 0, "Process machines and containers disabled, skipping");
861 if ((beforec == 0) && (afterc == 0))
864 if (rc = moira_connect())
866 critical_alert("AD incremental", "Error contacting Moira server : %s",
871 if ((beforec != 0) && (afterc == 0)) /*delete a new container*/
873 com_err(whoami, 0, "deleting container %s", before[CONTAINER_NAME]);
874 container_delete(ldap_handle, dn_path, beforec, before);
875 Moira_container_group_delete(before);
880 if ((beforec == 0) && (afterc != 0)) /*create a container*/
882 com_err(whoami, 0, "creating container %s", after[CONTAINER_NAME]);
883 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
884 container_create(ldap_handle, dn_path, afterc, after);
885 Moira_container_group_create(after);
890 if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME]))
892 com_err(whoami, 0, "renaming container %s to %s",
893 before[CONTAINER_NAME], after[CONTAINER_NAME]);
894 container_rename(ldap_handle, dn_path, beforec, before, afterc, after);
895 Moira_container_group_update(before, after);
900 com_err(whoami, 0, "updating container %s information",
901 after[CONTAINER_NAME]);
902 container_update(ldap_handle, dn_path, beforec, before, afterc, after);
903 Moira_container_group_update(before, after);
908 #define L_LIST_DESC 9
911 void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
912 char **before, int beforec, char **after, int afterc)
917 char group_membership[6];
922 char before_list_id[32];
923 char before_group_membership[1];
924 int before_security_flag;
925 char before_group_ou[256];
926 LK_ENTRY *ptr = NULL;
928 if (beforec == 0 && afterc == 0)
931 memset(list_id, '\0', sizeof(list_id));
932 memset(before_list_id, '\0', sizeof(before_list_id));
933 memset(before_group_ou, '\0', sizeof(before_group_ou));
934 memset(before_group_membership, '\0', sizeof(before_group_membership));
935 memset(group_ou, '\0', sizeof(group_ou));
936 memset(group_membership, '\0', sizeof(group_membership));
941 if (beforec < L_LIST_ID)
943 if (beforec > L_LIST_DESC)
945 strcpy(before_list_id, before[L_LIST_ID]);
947 before_security_flag = 0;
948 get_group_membership(before_group_membership, before_group_ou,
949 &before_security_flag, before);
954 if (afterc < L_LIST_ID)
956 if (afterc > L_LIST_DESC)
958 strcpy(list_id, after[L_LIST_ID]);
961 get_group_membership(group_membership, group_ou, &security_flag, after);
964 if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/
973 if ((rc = process_group(ldap_handle, dn_path, before_list_id,
974 before[L_NAME], before_group_ou,
975 before_group_membership,
976 before_security_flag, CHECK_GROUPS,
977 before[L_MAILLIST])))
979 if (rc == AD_NO_GROUPS_FOUND)
983 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
984 (rc == AD_MULTIPLE_GROUPS_FOUND))
986 rc = process_group(ldap_handle, dn_path, before_list_id,
987 before[L_NAME], before_group_ou,
988 before_group_membership,
989 before_security_flag, CLEANUP_GROUPS,
992 if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0))
994 com_err(whoami, 0, "Unable to process list %s",
998 if (rc == AD_NO_GROUPS_FOUND)
1004 if ((beforec != 0) && (afterc != 0))
1006 if (((strcmp(after[L_NAME], before[L_NAME])) ||
1007 ((!strcmp(after[L_NAME], before[L_NAME])) &&
1008 (strcmp(before_group_ou, group_ou)))) &&
1011 com_err(whoami, 0, "Changing list name from %s to %s",
1012 before[L_NAME], after[L_NAME]);
1014 if ((strlen(before_group_ou) == 0) ||
1015 (strlen(before_group_membership) == 0) ||
1016 (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
1018 com_err(whoami, 0, "%s", "Unable to find the group OU's");
1022 memset(filter, '\0', sizeof(filter));
1024 if ((rc = group_rename(ldap_handle, dn_path,
1025 before[L_NAME], before_group_membership,
1026 before_group_ou, before_security_flag,
1027 before[L_LIST_DESC], after[L_NAME],
1028 group_membership, group_ou, security_flag,
1030 list_id, filter, after[L_MAILLIST])))
1032 if (rc != AD_NO_GROUPS_FOUND)
1035 "Unable to change list name from %s to %s",
1036 before[L_NAME], after[L_NAME]);
1049 if ((strlen(before_group_ou) == 0) ||
1050 (strlen(before_group_membership) == 0))
1053 "Unable to find the group OU for group %s", before[L_NAME]);
1057 com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
1058 rc = group_delete(ldap_handle, dn_path, before[L_NAME],
1059 before_group_membership, before_list_id);
1067 com_err(whoami, 0, "Creating group %s", after[L_NAME]);
1069 if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME],
1070 group_ou, group_membership,
1071 security_flag, CHECK_GROUPS,
1074 if (rc != AD_NO_GROUPS_FOUND)
1076 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
1077 (rc == AD_MULTIPLE_GROUPS_FOUND))
1079 rc = process_group(ldap_handle, dn_path, list_id,
1081 group_ou, group_membership,
1082 security_flag, CLEANUP_GROUPS,
1089 "Unable to create list %s", after[L_NAME]);
1096 com_err(whoami, 0, "Updating group %s information", after[L_NAME]);
1098 if (rc = moira_connect())
1100 critical_alert("AD incremental",
1101 "Error contacting Moira server : %s",
1108 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0,
1109 &ProcessGroup, after[L_MAILLIST]))
1114 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1,
1115 &ProcessGroup, after[L_MAILLIST]))
1119 if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME],
1120 group_ou, group_membership, security_flag,
1121 updateGroup, after[L_MAILLIST]))
1127 if (atoi(after[L_ACTIVE]))
1129 populate_group(ldap_handle, dn_path, after[L_NAME], group_ou,
1130 group_membership, security_flag, list_id);
1138 #define LM_EXTRA_ACTIVE (LM_END)
1139 #define LM_EXTRA_PUBLIC (LM_END+1)
1140 #define LM_EXTRA_HIDDEN (LM_END+2)
1141 #define LM_EXTRA_MAILLIST (LM_END+3)
1142 #define LM_EXTRA_GROUP (LM_END+4)
1143 #define LM_EXTRA_GID (LM_END+5)
1144 #define LMN_LIST_ID (LM_END+6)
1145 #define LM_LIST_ID (LM_END+7)
1146 #define LM_USER_ID (LM_END+8)
1147 #define LM_EXTRA_END (LM_END+9)
1149 void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1150 char **before, int beforec, char **after, int afterc)
1152 LK_ENTRY *group_base;
1155 char *attr_array[3];
1156 char group_name[128];
1157 char user_name[128];
1158 char user_type[128];
1159 char moira_list_id[32];
1160 char moira_user_id[32];
1161 char group_membership[1];
1163 char machine_ou[256];
1171 char NewMachineName[1024];
1175 char *save_argv[U_END];
1179 memset(moira_list_id, '\0', sizeof(moira_list_id));
1180 memset(moira_user_id, '\0', sizeof(moira_user_id));
1184 if (afterc < LM_EXTRA_GID)
1187 if (!atoi(after[LM_EXTRA_ACTIVE]))
1190 "Unable to add %s to group %s : group not active",
1191 after[2], after[0]);
1197 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1200 strcpy(user_name, after[LM_MEMBER]);
1201 strcpy(group_name, after[LM_LIST]);
1202 strcpy(user_type, after[LM_TYPE]);
1204 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1206 if (afterc > LM_EXTRA_GROUP)
1208 strcpy(moira_list_id, after[LMN_LIST_ID]);
1209 strcpy(moira_user_id, after[LM_LIST_ID]);
1212 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1214 if (afterc > LMN_LIST_ID)
1216 strcpy(moira_list_id, after[LM_LIST_ID]);
1217 strcpy(moira_user_id, after[LM_USER_ID]);
1222 if (afterc > LM_EXTRA_GID)
1223 strcpy(moira_list_id, after[LMN_LIST_ID]);
1228 if (beforec < LM_EXTRA_GID)
1230 if (!atoi(before[LM_EXTRA_ACTIVE]))
1233 "Unable to add %s to group %s : group not active",
1234 before[2], before[0]);
1240 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
1243 strcpy(user_name, before[LM_MEMBER]);
1244 strcpy(group_name, before[LM_LIST]);
1245 strcpy(user_type, before[LM_TYPE]);
1247 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1249 if (beforec > LM_EXTRA_GROUP)
1251 strcpy(moira_list_id, before[LMN_LIST_ID]);
1252 strcpy(moira_user_id, before[LM_LIST_ID]);
1255 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1257 if (beforec > LMN_LIST_ID)
1259 strcpy(moira_list_id, before[LM_LIST_ID]);
1260 strcpy(moira_user_id, before[LM_USER_ID]);
1265 if (beforec > LM_EXTRA_GID)
1266 strcpy(moira_list_id, before[LMN_LIST_ID]);
1273 "Unable to process group : beforec = %d, afterc = %d",
1278 args[L_NAME] = ptr[LM_LIST];
1279 args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
1280 args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
1281 args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
1282 args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
1283 args[L_GROUP] = ptr[LM_EXTRA_GROUP];
1284 args[L_GID] = ptr[LM_EXTRA_GID];
1287 memset(group_ou, '\0', sizeof(group_ou));
1288 get_group_membership(group_membership, group_ou, &security_flag, args);
1290 if (strlen(group_ou) == 0)
1292 com_err(whoami, 0, "Unable to find the group OU for group %s",
1297 if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name,
1298 group_ou, group_membership, security_flag,
1299 CHECK_GROUPS, args[L_MAILLIST]))
1301 if (rc != AD_NO_GROUPS_FOUND)
1303 if (rc = process_group(ldap_handle, dn_path, moira_list_id,
1304 group_name, group_ou, group_membership,
1305 security_flag, CLEANUP_GROUPS,
1308 if (rc != AD_NO_GROUPS_FOUND)
1311 com_err(whoami, 0, "Unable to add %s to group %s - "
1312 "unable to process group", user_name, group_name);
1314 com_err(whoami, 0, "Unable to remove %s from group %s - "
1315 "unable to process group", user_name, group_name);
1322 if (rc == AD_NO_GROUPS_FOUND)
1324 if (rc = moira_connect())
1326 critical_alert("AD incremental",
1327 "Error contacting Moira server : %s",
1332 com_err(whoami, 0, "creating group %s", group_name);
1335 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0,
1336 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
1341 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1,
1342 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
1346 if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST],
1347 group_ou, group_membership, security_flag, 0,
1348 ptr[LM_EXTRA_MAILLIST]))
1354 if (atoi(ptr[LM_EXTRA_ACTIVE]))
1356 populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou,
1357 group_membership, security_flag, moira_list_id);
1367 com_err(whoami, 0, "removing user %s from list %s", user_name,
1371 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1373 memset(machine_ou, '\0', sizeof(machine_ou));
1374 memset(NewMachineName, '\0', sizeof(NewMachineName));
1375 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER],
1376 machine_ou, NewMachineName))
1378 if (ptr[LM_MEMBER] != NULL)
1379 free(ptr[LM_MEMBER]);
1380 ptr[LM_MEMBER] = strdup(NewMachineName);
1381 pUserOu = machine_ou;
1384 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1386 strcpy(member, ptr[LM_MEMBER]);
1390 if((s = strchr(member, '@')) == (char *) NULL)
1392 strcat(member, "@mit.edu");
1394 if (ptr[LM_MEMBER] != NULL)
1395 free(ptr[LM_MEMBER]);
1396 ptr[LM_MEMBER] = strdup(member);
1399 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1401 s = strrchr(member, '.');
1403 strcat(s, ".mit.edu");
1405 if (ptr[LM_MEMBER] != NULL)
1406 free(ptr[LM_MEMBER]);
1407 ptr[LM_MEMBER] = strdup(member);
1411 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1414 pUserOu = contact_ou;
1416 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1418 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1422 pUserOu = kerberos_ou;
1424 if (rc = member_remove(ldap_handle, dn_path, group_name,
1425 group_ou, group_membership, ptr[LM_MEMBER],
1426 pUserOu, moira_list_id))
1427 com_err(whoami, 0, "Unable to remove %s from group %s", user_name,
1430 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1432 if (rc = moira_connect())
1434 critical_alert("AD incremental",
1435 "Error contacting Moira server : %s",
1440 if (rc = populate_group(ldap_handle, dn_path, group_name,
1441 group_ou, group_membership, security_flag,
1443 com_err(whoami, 0, "Unable to remove %s from group %s",
1444 user_name, group_name);
1450 com_err(whoami, 0, "Adding %s to list %s", user_name, group_name);
1453 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1455 memset(machine_ou, '\0', sizeof(machine_ou));
1456 memset(NewMachineName, '\0', sizeof(NewMachineName));
1458 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou,
1462 if (ptr[LM_MEMBER] != NULL)
1463 free(ptr[LM_MEMBER]);
1465 ptr[LM_MEMBER] = strdup(NewMachineName);
1466 pUserOu = machine_ou;
1468 else if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1470 strcpy(member, ptr[LM_MEMBER]);
1474 if((s = strchr(member, '@')) == (char *) NULL)
1476 strcat(member, "@mit.edu");
1478 if (ptr[LM_MEMBER] != NULL)
1479 free(ptr[LM_MEMBER]);
1480 ptr[LM_MEMBER] = strdup(member);
1483 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1485 s = strrchr(member, '.');
1487 strcat(s, ".mit.edu");
1489 if (ptr[LM_MEMBER] != NULL)
1490 free(ptr[LM_MEMBER]);
1491 ptr[LM_MEMBER] = strdup(member);
1495 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1498 pUserOu = contact_ou;
1500 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1502 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
1505 pUserOu = kerberos_ou;
1507 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1509 if ((rc = check_user(ldap_handle, dn_path, ptr[LM_MEMBER],
1510 moira_user_id)) == AD_NO_USER_FOUND)
1512 if (rc = moira_connect())
1514 critical_alert("AD incremental",
1515 "Error connection to Moira : %s",
1520 com_err(whoami, 0, "creating user %s", ptr[LM_MEMBER]);
1521 av[0] = ptr[LM_MEMBER];
1522 call_args[0] = (char *)ldap_handle;
1523 call_args[1] = dn_path;
1524 call_args[2] = moira_user_id;
1525 call_args[3] = NULL;
1534 sprintf(filter, "(&(objectClass=group)(cn=%s))", ptr[LM_MEMBER]);
1535 attr_array[0] = "cn";
1536 attr_array[1] = NULL;
1537 if ((rc = linklist_build(ldap_handle, dn_path, filter,
1538 attr_array, &group_base, &group_count,
1539 LDAP_SCOPE_SUBTREE)) != 0)
1541 com_err(whoami, 0, "Unable to process user %s : %s",
1542 ptr[LM_MEMBER], ldap_err2string(rc));
1548 com_err(whoami, 0, "Object already exists with name %s",
1553 linklist_free(group_base);
1558 if (rc = mr_query("get_user_account_by_login", 1, av,
1559 save_query_info, save_argv))
1562 com_err(whoami, 0, "Unable to create user %s : %s",
1563 ptr[LM_MEMBER], error_message(rc));
1567 if (rc = user_create(U_END, save_argv, call_args))
1570 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1577 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1589 if (rc = member_add(ldap_handle, dn_path, group_name,
1590 group_ou, group_membership, ptr[LM_MEMBER],
1591 pUserOu, moira_list_id))
1592 com_err(whoami, 0, "Unable to add %s to group %s", user_name, group_name);
1594 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1596 if (rc = moira_connect())
1598 critical_alert("AD incremental",
1599 "Error contacting Moira server : %s",
1604 if (rc = populate_group(ldap_handle, dn_path, group_name,
1605 group_ou, group_membership, security_flag,
1607 com_err(whoami, 0, "Unable to add %s to group %s",
1608 user_name, group_name);
1617 #define U_USER_ID 10
1618 #define U_HOMEDIR 11
1619 #define U_PROFILEDIR 12
1621 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1622 char **before, int beforec, char **after,
1625 LK_ENTRY *group_base;
1628 char *attr_array[3];
1631 char after_user_id[32];
1632 char before_user_id[32];
1634 char *save_argv[U_END];
1636 if ((beforec == 0) && (afterc == 0))
1639 memset(after_user_id, '\0', sizeof(after_user_id));
1640 memset(before_user_id, '\0', sizeof(before_user_id));
1642 if (beforec > U_USER_ID)
1643 strcpy(before_user_id, before[U_USER_ID]);
1645 if (afterc > U_USER_ID)
1646 strcpy(after_user_id, after[U_USER_ID]);
1648 if ((beforec == 0) && (afterc == 0)) /*this case should never happen */
1651 if ((beforec == 0) && (afterc != 0))
1653 /*this case only happens when the account*/
1654 /*account is first created but not usable*/
1656 com_err(whoami, 0, "Unable to process user %s because the user account "
1657 "is not yet usable", after[U_NAME]);
1661 /*this case only happens when the account is expunged */
1663 if ((beforec != 0) && (afterc == 0))
1665 if (atoi(before[U_STATE]) == 0)
1667 com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]);
1668 user_delete(ldap_handle, dn_path, before[U_NAME], before_user_id);
1672 com_err(whoami, 0, "Unable to process because user %s has been "
1673 "previously expungeded", before[U_NAME]);
1678 /*process anything that gets here*/
1680 if ((rc = check_user(ldap_handle, dn_path, before[U_NAME],
1681 before_user_id)) == AD_NO_USER_FOUND)
1683 if (!check_string(after[U_NAME]))
1686 if (rc = moira_connect())
1688 critical_alert("AD incremental",
1689 "Error connection to Moira : %s",
1694 com_err(whoami, 0, "creating user %s", after[U_NAME]);
1696 av[0] = after[U_NAME];
1697 call_args[0] = (char *)ldap_handle;
1698 call_args[1] = dn_path;
1699 call_args[2] = after_user_id;
1700 call_args[3] = NULL;
1708 sprintf(filter, "(&(objectClass=group)(cn=%s))", after[U_NAME]);
1709 attr_array[0] = "cn";
1710 attr_array[1] = NULL;
1712 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
1713 &group_base, &group_count,
1714 LDAP_SCOPE_SUBTREE)) != 0)
1716 com_err(whoami, 0, "Unable to process user %s : %s",
1717 after[U_NAME], ldap_err2string(rc));
1721 if (group_count >= 1)
1723 com_err(whoami, 0, "Object already exists with name %s",
1728 linklist_free(group_base);
1733 if (rc = mr_query("get_user_account_by_login", 1, av,
1734 save_query_info, save_argv))
1737 com_err(whoami, 0, "Unable to create user %s : %s",
1738 after[U_NAME], error_message(rc));
1742 if (rc = user_create(U_END, save_argv, call_args))
1744 com_err(whoami, 0, "Unable to create user %s : %s",
1745 after[U_NAME], error_message(rc));
1752 com_err(whoami, 0, "Unable to create user %s", after[U_NAME]);
1764 if (strcmp(before[U_NAME], after[U_NAME]))
1766 if ((check_string(before[U_NAME])) && (check_string(after[U_NAME])))
1768 com_err(whoami, 0, "changing user %s to %s",
1769 before[U_NAME], after[U_NAME]);
1771 if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME],
1772 after[U_NAME])) != LDAP_SUCCESS)
1779 com_err(whoami, 0, "updating user %s information", after[U_NAME]);
1780 rc = user_update(ldap_handle, dn_path, after[U_NAME],
1781 after[U_UID], after[U_MITID],
1782 after_user_id, atoi(after[U_STATE]),
1783 after[U_HOMEDIR], after[U_PROFILEDIR],
1784 after[U_FIRST], after[U_MIDDLE], after[U_LAST]);
1789 int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
1790 char *oldValue, char *newValue,
1791 char ***modvalues, int type)
1793 LK_ENTRY *linklist_ptr;
1797 if (((*modvalues) = calloc(1,
1798 (modvalue_count + 1) * sizeof(char *))) == NULL)
1803 for (i = 0; i < (modvalue_count + 1); i++)
1804 (*modvalues)[i] = NULL;
1806 if (modvalue_count != 0)
1808 linklist_ptr = linklist_base;
1809 for (i = 0; i < modvalue_count; i++)
1811 if ((oldValue != NULL) && (newValue != NULL))
1813 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
1816 if (type == REPLACE)
1818 if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1821 memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1822 strcpy((*modvalues)[i], newValue);
1826 if (((*modvalues)[i] = calloc(1,
1827 (int)(cPtr - linklist_ptr->value) +
1828 (linklist_ptr->length -
1830 strlen(newValue) + 1)) == NULL)
1832 memset((*modvalues)[i], '\0',
1833 (int)(cPtr - linklist_ptr->value) +
1834 (linklist_ptr->length - strlen(oldValue)) +
1835 strlen(newValue) + 1);
1836 memcpy((*modvalues)[i], linklist_ptr->value,
1837 (int)(cPtr - linklist_ptr->value));
1838 strcat((*modvalues)[i], newValue);
1839 strcat((*modvalues)[i],
1840 &linklist_ptr->value[(int)(cPtr -
1841 linklist_ptr->value) + strlen(oldValue)]);
1846 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1847 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1848 memcpy((*modvalues)[i], linklist_ptr->value,
1849 linklist_ptr->length);
1854 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1855 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1856 memcpy((*modvalues)[i], linklist_ptr->value,
1857 linklist_ptr->length);
1859 linklist_ptr = linklist_ptr->next;
1861 (*modvalues)[i] = NULL;
1867 int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
1868 char **attr_array, LK_ENTRY **linklist_base,
1869 int *linklist_count, unsigned long ScopeType)
1872 LDAPMessage *ldap_entry;
1876 (*linklist_base) = NULL;
1877 (*linklist_count) = 0;
1879 if ((rc = ldap_search_s(ldap_handle, dn_path, ScopeType,
1880 search_exp, attr_array, 0,
1881 &ldap_entry)) != LDAP_SUCCESS)
1883 if (rc != LDAP_SIZELIMIT_EXCEEDED)
1887 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base,
1890 ldap_msgfree(ldap_entry);
1894 int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1895 LK_ENTRY **linklist_base, int *linklist_count)
1897 char distinguished_name[1024];
1898 LK_ENTRY *linklist_ptr;
1901 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1904 memset(distinguished_name, '\0', sizeof(distinguished_name));
1905 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1907 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1908 linklist_base)) != 0)
1911 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1913 memset(distinguished_name, '\0', sizeof(distinguished_name));
1914 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1916 if ((rc = retrieve_attributes(ldap_handle, ldap_entry,
1917 distinguished_name, linklist_base)) != 0)
1921 linklist_ptr = (*linklist_base);
1922 (*linklist_count) = 0;
1924 while (linklist_ptr != NULL)
1926 ++(*linklist_count);
1927 linklist_ptr = linklist_ptr->next;
1933 int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1934 char *distinguished_name, LK_ENTRY **linklist_current)
1941 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry,
1944 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1946 ldap_memfree(Attribute);
1947 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
1950 retrieve_values(ldap_handle, ldap_entry, Attribute,
1951 distinguished_name, linklist_current);
1952 ldap_memfree(Attribute);
1956 ldap_ber_free(ptr, 0);
1961 int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1962 char *Attribute, char *distinguished_name,
1963 LK_ENTRY **linklist_current)
1969 LK_ENTRY *linklist_previous;
1970 LDAP_BERVAL **ber_value;
1979 SID_IDENTIFIER_AUTHORITY *sid_auth;
1980 unsigned char *subauth_count;
1981 #endif /*LDAP_BEGUG*/
1984 memset(temp, '\0', sizeof(temp));
1986 if ((!strcmp(Attribute, "objectSid")) ||
1987 (!strcmp(Attribute, "objectGUID")))
1992 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1993 Ptr = (void **)ber_value;
1998 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1999 Ptr = (void **)str_value;
2007 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
2010 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
2011 linklist_previous->next = (*linklist_current);
2012 (*linklist_current) = linklist_previous;
2014 if (((*linklist_current)->attribute = calloc(1,
2015 strlen(Attribute) + 1)) == NULL)
2018 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
2019 strcpy((*linklist_current)->attribute, Attribute);
2023 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
2025 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
2028 memset((*linklist_current)->value, '\0', ber_length);
2029 memcpy((*linklist_current)->value,
2030 (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length);
2031 (*linklist_current)->length = ber_length;
2035 if (((*linklist_current)->value = calloc(1,
2036 strlen(*Ptr) + 1)) == NULL)
2039 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
2040 (*linklist_current)->length = strlen(*Ptr);
2041 strcpy((*linklist_current)->value, *Ptr);
2044 (*linklist_current)->ber_value = use_bervalue;
2046 if (((*linklist_current)->dn = calloc(1,
2047 strlen(distinguished_name) + 1)) == NULL)
2050 memset((*linklist_current)->dn, '\0',
2051 strlen(distinguished_name) + 1);
2052 strcpy((*linklist_current)->dn, distinguished_name);
2055 if (!strcmp(Attribute, "objectGUID"))
2057 guid = (GUID *)((*linklist_current)->value);
2059 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
2060 guid->Data1, guid->Data2, guid->Data3,
2061 guid->Data4[0], guid->Data4[1], guid->Data4[2],
2062 guid->Data4[3], guid->Data4[4], guid->Data4[5],
2063 guid->Data4[6], guid->Data4[7]);
2064 print_to_screen(" %20s : {%s}\n", Attribute, temp);
2066 else if (!strcmp(Attribute, "objectSid"))
2068 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
2071 print_to_screen(" Revision = %d\n", sid->Revision);
2072 print_to_screen(" SID Identifier Authority:\n");
2073 sid_auth = &sid->IdentifierAuthority;
2074 if (sid_auth->Value[0])
2075 print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
2076 else if (sid_auth->Value[1])
2077 print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
2078 else if (sid_auth->Value[2])
2079 print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
2080 else if (sid_auth->Value[3])
2081 print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
2082 else if (sid_auth->Value[5])
2083 print_to_screen(" SECURITY_NT_AUTHORITY\n");
2085 print_to_screen(" UNKNOWN SID AUTHORITY\n");
2086 subauth_count = GetSidSubAuthorityCount(sid);
2087 print_to_screen(" SidSubAuthorityCount = %d\n",
2089 print_to_screen(" SidSubAuthority:\n");
2090 for (i = 0; i < *subauth_count; i++)
2092 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
2093 print_to_screen(" %u\n", *subauth);
2097 else if ((!memcmp(Attribute, "userAccountControl",
2098 strlen("userAccountControl"))) ||
2099 (!memcmp(Attribute, "sAMAccountType",
2100 strlen("sAmAccountType"))))
2102 intValue = atoi(*Ptr);
2103 print_to_screen(" %20s : %ld\n",Attribute, intValue);
2105 if (!memcmp(Attribute, "userAccountControl",
2106 strlen("userAccountControl")))
2108 if (intValue & UF_ACCOUNTDISABLE)
2109 print_to_screen(" %20s : %s\n",
2110 "", "Account disabled");
2112 print_to_screen(" %20s : %s\n",
2113 "", "Account active");
2114 if (intValue & UF_HOMEDIR_REQUIRED)
2115 print_to_screen(" %20s : %s\n",
2116 "", "Home directory required");
2117 if (intValue & UF_LOCKOUT)
2118 print_to_screen(" %20s : %s\n",
2119 "", "Account locked out");
2120 if (intValue & UF_PASSWD_NOTREQD)
2121 print_to_screen(" %20s : %s\n",
2122 "", "No password required");
2123 if (intValue & UF_PASSWD_CANT_CHANGE)
2124 print_to_screen(" %20s : %s\n",
2125 "", "Cannot change password");
2126 if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
2127 print_to_screen(" %20s : %s\n",
2128 "", "Temp duplicate account");
2129 if (intValue & UF_NORMAL_ACCOUNT)
2130 print_to_screen(" %20s : %s\n",
2131 "", "Normal account");
2132 if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
2133 print_to_screen(" %20s : %s\n",
2134 "", "Interdomain trust account");
2135 if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
2136 print_to_screen(" %20s : %s\n",
2137 "", "Workstation trust account");
2138 if (intValue & UF_SERVER_TRUST_ACCOUNT)
2139 print_to_screen(" %20s : %s\n",
2140 "", "Server trust account");
2145 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
2147 #endif /*LDAP_DEBUG*/
2150 if (str_value != NULL)
2151 ldap_value_free(str_value);
2153 if (ber_value != NULL)
2154 ldap_value_free_len(ber_value);
2157 (*linklist_current) = linklist_previous;
2162 int moira_connect(void)
2167 if (!mr_connections++)
2171 memset(HostName, '\0', sizeof(HostName));
2172 strcpy(HostName, "ttsp");
2173 rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
2177 rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
2186 int check_winad(void)
2190 for (i = 0; file_exists(STOP_FILE); i++)
2194 critical_alert("AD incremental",
2195 "WINAD incremental failed (%s exists): %s",
2196 STOP_FILE, tbl_buf);
2206 int moira_disconnect(void)
2209 if (!--mr_connections)
2217 void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
2218 char *distinguished_name)
2222 CName = ldap_get_dn(ldap_handle, ldap_entry);
2227 strcpy(distinguished_name, CName);
2228 ldap_memfree(CName);
2231 int linklist_create_entry(char *attribute, char *value,
2232 LK_ENTRY **linklist_entry)
2234 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
2236 if (!(*linklist_entry))
2241 memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
2242 (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
2243 memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
2244 strcpy((*linklist_entry)->attribute, attribute);
2245 (*linklist_entry)->value = calloc(1, strlen(value) + 1);
2246 memset((*linklist_entry)->value, '\0', strlen(value) + 1);
2247 strcpy((*linklist_entry)->value, value);
2248 (*linklist_entry)->length = strlen(value);
2249 (*linklist_entry)->next = NULL;
2254 void print_to_screen(const char *fmt, ...)
2258 va_start(pvar, fmt);
2259 vfprintf(stderr, fmt, pvar);
2264 int get_group_membership(char *group_membership, char *group_ou,
2265 int *security_flag, char **av)
2270 maillist_flag = atoi(av[L_MAILLIST]);
2271 group_flag = atoi(av[L_GROUP]);
2273 if (security_flag != NULL)
2274 (*security_flag) = 0;
2276 if ((maillist_flag) && (group_flag))
2278 if (group_membership != NULL)
2279 group_membership[0] = 'B';
2281 if (security_flag != NULL)
2282 (*security_flag) = 1;
2284 if (group_ou != NULL)
2285 strcpy(group_ou, group_ou_both);
2287 else if ((!maillist_flag) && (group_flag))
2289 if (group_membership != NULL)
2290 group_membership[0] = 'S';
2292 if (security_flag != NULL)
2293 (*security_flag) = 1;
2295 if (group_ou != NULL)
2296 strcpy(group_ou, group_ou_security);
2298 else if ((maillist_flag) && (!group_flag))
2300 if (group_membership != NULL)
2301 group_membership[0] = 'D';
2303 if (group_ou != NULL)
2304 strcpy(group_ou, group_ou_distribution);
2308 if (group_membership != NULL)
2309 group_membership[0] = 'N';
2311 if (group_ou != NULL)
2312 strcpy(group_ou, group_ou_neither);
2318 int group_rename(LDAP *ldap_handle, char *dn_path,
2319 char *before_group_name, char *before_group_membership,
2320 char *before_group_ou, int before_security_flag,
2321 char *before_desc, char *after_group_name,
2322 char *after_group_membership, char *after_group_ou,
2323 int after_security_flag, char *after_desc,
2324 char *MoiraId, char *filter, char *maillist)
2329 char new_dn_path[512];
2332 char mail_nickname[256];
2333 char proxy_address[256];
2334 char address_book[256];
2335 char *attr_array[3];
2336 char *mitMoiraId_v[] = {NULL, NULL};
2337 char *name_v[] = {NULL, NULL};
2338 char *samAccountName_v[] = {NULL, NULL};
2339 char *groupTypeControl_v[] = {NULL, NULL};
2340 char *mail_v[] = {NULL, NULL};
2341 char *proxy_address_v[] = {NULL, NULL};
2342 char *mail_nickname_v[] = {NULL, NULL};
2343 char *report_to_originator_v[] = {NULL, NULL};
2344 char *address_book_v[] = {NULL, NULL};
2345 char *legacy_exchange_dn_v[] = {NULL, NULL};
2346 u_int groupTypeControl;
2347 char groupTypeControlStr[80];
2348 char contact_mail[256];
2352 LK_ENTRY *group_base;
2354 int MailDisabled = 0;
2355 char search_filter[1024];
2357 if(UseGroupUniversal)
2358 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2360 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2362 if (!check_string(before_group_name))
2365 "Unable to process invalid LDAP list name %s",
2367 return(AD_INVALID_NAME);
2370 if (!check_string(after_group_name))
2373 "Unable to process invalid LDAP list name %s", after_group_name);
2374 return(AD_INVALID_NAME);
2384 sprintf(search_filter, "(&(objectClass=user)(cn=%s))",
2386 attr_array[0] = "cn";
2387 attr_array[1] = NULL;
2389 if ((rc = linklist_build(ldap_handle, dn_path, search_filter,
2390 attr_array, &group_base, &group_count,
2391 LDAP_SCOPE_SUBTREE)) != 0)
2393 com_err(whoami, 0, "Unable to process group %s : %s",
2394 after_group_name, ldap_err2string(rc));
2400 com_err(whoami, 0, "Object already exists with name %s",
2405 linklist_free(group_base);
2414 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
2415 before_group_membership,
2416 MoiraId, "distinguishedName", &group_base,
2417 &group_count, filter))
2420 if (group_count == 0)
2422 return(AD_NO_GROUPS_FOUND);
2425 if (group_count != 1)
2427 com_err(whoami, 0, "Unable to process multiple groups with "
2428 "MoiraId = %s exist in the AD", MoiraId);
2429 return(AD_MULTIPLE_GROUPS_FOUND);
2432 strcpy(old_dn, group_base->value);
2434 linklist_free(group_base);
2437 attr_array[0] = "sAMAccountName";
2438 attr_array[1] = NULL;
2440 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2441 &group_base, &group_count,
2442 LDAP_SCOPE_SUBTREE)) != 0)
2444 com_err(whoami, 0, "Unable to get list %s dn : %s",
2445 after_group_name, ldap_err2string(rc));
2449 if (group_count != 1)
2452 "Unable to get sAMAccountName for group %s",
2454 return(AD_LDAP_FAILURE);
2457 strcpy(sam_name, group_base->value);
2458 linklist_free(group_base);
2462 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2463 sprintf(new_dn, "cn=%s", after_group_name);
2464 sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain));
2465 sprintf(contact_mail, "%s@mit.edu", after_group_name);
2466 sprintf(proxy_address, "SMTP:%s@%s", after_group_name,
2467 lowercase(ldap_domain));
2468 sprintf(mail_nickname, "%s", after_group_name);
2470 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
2471 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2473 com_err(whoami, 0, "Unable to rename list from %s to %s : %s",
2474 before_group_name, after_group_name, ldap_err2string(rc));
2478 name_v[0] = after_group_name;
2480 if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)],
2481 group_suffix, strlen(group_suffix)))
2483 sprintf(sam_name, "%s%s", after_group_name, group_suffix);
2488 "Unable to rename list from %s to %s : sAMAccountName not found",
2489 before_group_name, after_group_name);
2493 samAccountName_v[0] = sam_name;
2495 if (after_security_flag)
2496 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2498 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2499 groupTypeControl_v[0] = groupTypeControlStr;
2500 mitMoiraId_v[0] = MoiraId;
2502 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
2503 rc = attribute_update(ldap_handle, new_dn, after_desc, "description",
2506 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2507 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2508 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2509 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
2513 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2515 mail_nickname_v[0] = mail_nickname;
2516 proxy_address_v[0] = proxy_address;
2518 report_to_originator_v[0] = "TRUE";
2520 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2521 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2522 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2523 ADD_ATTR("reportToOriginator", report_to_originator_v,
2528 mail_nickname_v[0] = NULL;
2529 proxy_address_v[0] = NULL;
2531 legacy_exchange_dn_v[0] = NULL;
2532 address_book_v[0] = NULL;
2533 report_to_originator_v[0] = NULL;
2535 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2536 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2537 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2538 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2539 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2540 ADD_ATTR("reportToOriginator", report_to_originator_v,
2546 if(atoi(maillist) && email_isvalid(contact_mail))
2548 mail_v[0] = contact_mail;
2549 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2555 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2558 "Unable to modify list data for %s after renaming: %s",
2559 after_group_name, ldap_err2string(rc));
2562 for (i = 0; i < n; i++)
2568 int group_create(int ac, char **av, void *ptr)
2573 char new_group_name[256];
2574 char sam_group_name[256];
2575 char cn_group_name[256];
2577 char contact_mail[256];
2578 char mail_nickname[256];
2579 char proxy_address[256];
2580 char address_book[256];
2581 char *cn_v[] = {NULL, NULL};
2582 char *objectClass_v[] = {"top", "group", NULL};
2584 char *samAccountName_v[] = {NULL, NULL};
2585 char *altSecurityIdentities_v[] = {NULL, NULL};
2586 char *member_v[] = {NULL, NULL};
2587 char *name_v[] = {NULL, NULL};
2588 char *desc_v[] = {NULL, NULL};
2589 char *info_v[] = {NULL, NULL};
2590 char *mitMoiraId_v[] = {NULL, NULL};
2591 char *groupTypeControl_v[] = {NULL, NULL};
2592 char *mail_v[] = {NULL, NULL};
2593 char *proxy_address_v[] = {NULL, NULL};
2594 char *mail_nickname_v[] = {NULL, NULL};
2595 char *report_to_originator_v[] = {NULL, NULL};
2596 char *address_book_v[] = {NULL, NULL};
2597 char *legacy_exchange_dn_v[] = {NULL, NULL};
2598 char groupTypeControlStr[80];
2599 char group_membership[1];
2602 u_int groupTypeControl;
2606 int MailDisabled = 0;
2608 LK_ENTRY *group_base;
2611 char *attr_array[3];
2615 if(UseGroupUniversal)
2616 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2618 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2620 if (!check_string(av[L_NAME]))
2622 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2624 return(AD_INVALID_NAME);
2627 updateGroup = (int)call_args[4];
2628 memset(group_ou, 0, sizeof(group_ou));
2629 memset(group_membership, 0, sizeof(group_membership));
2632 get_group_membership(group_membership, group_ou, &security_flag, av);
2634 strcpy(new_group_name, av[L_NAME]);
2635 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2636 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2637 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2638 sprintf(mail_nickname, "%s", av[L_NAME]);
2641 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2643 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2647 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2648 groupTypeControl_v[0] = groupTypeControlStr;
2650 strcpy(cn_group_name, av[L_NAME]);
2652 samAccountName_v[0] = sam_group_name;
2653 name_v[0] = new_group_name;
2654 cn_v[0] = new_group_name;
2657 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2658 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2659 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2660 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2661 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2665 if(atoi(av[L_MAILLIST]))
2670 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2671 attr_array[0] = "cn";
2672 attr_array[1] = NULL;
2674 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2675 filter, attr_array, &group_base,
2677 LDAP_SCOPE_SUBTREE)) != 0)
2679 com_err(whoami, 0, "Unable to process group %s : %s",
2680 av[L_NAME], ldap_err2string(rc));
2686 com_err(whoami, 0, "Object already exists with name %s",
2691 linklist_free(group_base);
2696 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2698 mail_nickname_v[0] = mail_nickname;
2699 report_to_originator_v[0] = "TRUE";
2701 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2702 ADD_ATTR("reportToOriginator", report_to_originator_v,
2708 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2710 mail_v[0] = contact_mail;
2711 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2715 if (strlen(av[L_DESC]) != 0)
2717 desc_v[0] = av[L_DESC];
2718 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2721 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2723 if (strlen(av[L_ACE_NAME]) != 0)
2725 sprintf(info, "The Administrator of this list is: %s",
2728 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2731 if (strlen(call_args[5]) != 0)
2733 mitMoiraId_v[0] = call_args[5];
2734 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2739 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2741 for (i = 0; i < n; i++)
2744 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2746 com_err(whoami, 0, "Unable to create list %s in AD : %s",
2747 av[L_NAME], ldap_err2string(rc));
2753 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2755 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2756 "description", av[L_NAME]);
2757 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2758 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2762 if (strlen(call_args[5]) != 0)
2764 mitMoiraId_v[0] = call_args[5];
2765 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2768 if (!(atoi(av[L_ACTIVE])))
2771 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2776 if(atoi(av[L_MAILLIST]))
2781 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2782 attr_array[0] = "cn";
2783 attr_array[1] = NULL;
2785 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2786 filter, attr_array, &group_base,
2788 LDAP_SCOPE_SUBTREE)) != 0)
2790 com_err(whoami, 0, "Unable to process group %s : %s",
2791 av[L_NAME], ldap_err2string(rc));
2797 com_err(whoami, 0, "Object already exists with name %s",
2802 linklist_free(group_base);
2807 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2809 mail_nickname_v[0] = mail_nickname;
2810 report_to_originator_v[0] = "TRUE";
2812 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2813 ADD_ATTR("reportToOriginator", report_to_originator_v,
2819 mail_nickname_v[0] = NULL;
2820 proxy_address_v[0] = NULL;
2821 legacy_exchange_dn_v[0] = NULL;
2822 address_book_v[0] = NULL;
2823 report_to_originator_v[0] = NULL;
2825 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2826 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2827 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2828 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2830 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2831 ADD_ATTR("reportToOriginator", report_to_originator_v,
2837 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2839 mail_v[0] = contact_mail;
2840 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2845 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2854 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2856 for (i = 0; i < n; i++)
2859 if (rc != LDAP_SUCCESS)
2861 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2862 av[L_NAME], ldap_err2string(rc));
2869 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2870 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2872 return(LDAP_SUCCESS);
2875 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2876 char *TargetGroupName, int HiddenGroup,
2877 char *AceType, char *AceName)
2879 char filter_exp[1024];
2880 char *attr_array[5];
2881 char search_path[512];
2883 char TemplateDn[512];
2884 char TemplateSamName[128];
2886 char TargetSamName[128];
2887 char AceSamAccountName[128];
2889 unsigned char AceSid[128];
2890 unsigned char UserTemplateSid[128];
2891 char acBERBuf[N_SD_BER_BYTES];
2892 char GroupSecurityTemplate[256];
2893 char hide_addres_lists[256];
2894 char address_book[256];
2895 char *hide_address_lists_v[] = {NULL, NULL};
2896 char *address_book_v[] = {NULL, NULL};
2898 int UserTemplateSidCount;
2905 int array_count = 0;
2907 LK_ENTRY *group_base;
2908 LDAP_BERVAL **ppsValues;
2909 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2910 { N_SD_BER_BYTES, acBERBuf },
2913 LDAPControl *apsServerControls[] = {&sControl, NULL};
2916 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
2917 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
2918 BEREncodeSecurityBits(dwInfo, acBERBuf);
2920 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
2921 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
2922 attr_array[0] = "sAMAccountName";
2923 attr_array[1] = NULL;
2927 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2928 &group_base, &group_count,
2929 LDAP_SCOPE_SUBTREE) != 0))
2932 if (group_count != 1)
2934 linklist_free(group_base);
2938 strcpy(TargetDn, group_base->dn);
2939 strcpy(TargetSamName, group_base->value);
2940 linklist_free(group_base);
2944 UserTemplateSidCount = 0;
2945 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2946 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2947 memset(AceSid, '\0', sizeof(AceSid));
2952 if (strlen(AceName) != 0)
2954 if (!strcmp(AceType, "LIST"))
2956 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
2957 strcpy(root_ou, group_ou_root);
2959 else if (!strcmp(AceType, "USER"))
2961 sprintf(AceSamAccountName, "%s", AceName);
2962 strcpy(root_ou, user_ou);
2965 if (strlen(AceSamAccountName) != 0)
2967 sprintf(search_path, "%s", dn_path);
2968 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2969 attr_array[0] = "objectSid";
2970 attr_array[1] = NULL;
2974 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2975 attr_array, &group_base, &group_count,
2976 LDAP_SCOPE_SUBTREE) != 0))
2978 if (group_count == 1)
2980 strcpy(AceDn, group_base->dn);
2981 AceSidCount = group_base->length;
2982 memcpy(AceSid, group_base->value, AceSidCount);
2984 linklist_free(group_base);
2990 if (AceSidCount == 0)
2992 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
2993 "have an AD SID.", TargetGroupName, AceName, AceType);
2994 com_err(whoami, 0, " Non-admin security group template will be used.");
2998 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2999 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
3000 attr_array[0] = "objectSid";
3001 attr_array[1] = NULL;
3006 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3007 attr_array, &group_base, &group_count,
3008 LDAP_SCOPE_SUBTREE) != 0))
3011 if ((rc != 0) || (group_count != 1))
3013 com_err(whoami, 0, "Unable to process user security template: %s",
3019 UserTemplateSidCount = group_base->length;
3020 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3022 linklist_free(group_base);
3029 if (AceSidCount == 0)
3031 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3032 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3036 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3037 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3042 if (AceSidCount == 0)
3044 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3045 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3049 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
3050 sprintf(filter_exp, "(sAMAccountName=%s)",
3051 NOT_HIDDEN_GROUP_WITH_ADMIN);
3055 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3056 attr_array[0] = "sAMAccountName";
3057 attr_array[1] = NULL;
3061 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3062 &group_base, &group_count,
3063 LDAP_SCOPE_SUBTREE) != 0))
3066 if (group_count != 1)
3068 linklist_free(group_base);
3069 com_err(whoami, 0, "Unable to process group security template: %s - "
3070 "security not set", GroupSecurityTemplate);
3074 strcpy(TemplateDn, group_base->dn);
3075 strcpy(TemplateSamName, group_base->value);
3076 linklist_free(group_base);
3080 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3081 rc = ldap_search_ext_s(ldap_handle,
3093 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3095 com_err(whoami, 0, "Unable to find group security template: %s - "
3096 "security not set", GroupSecurityTemplate);
3100 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3102 if (ppsValues == NULL)
3104 com_err(whoami, 0, "Unable to find group security descriptor for group "
3105 "%s - security not set", GroupSecurityTemplate);
3109 if (AceSidCount != 0)
3111 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3114 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3116 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3117 UserTemplateSidCount))
3119 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3127 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3128 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3134 hide_address_lists_v[0] = "TRUE";
3135 address_book_v[0] = NULL;
3136 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3138 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3140 hide_address_lists_v[0] = NULL;
3141 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3148 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3150 for (i = 0; i < n; i++)
3153 ldap_value_free_len(ppsValues);
3154 ldap_msgfree(psMsg);
3156 if (rc != LDAP_SUCCESS)
3158 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3159 TargetGroupName, ldap_err2string(rc));
3161 if (AceSidCount != 0)
3164 "Trying to set security for group %s without admin.",
3167 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3168 HiddenGroup, "", ""))
3170 com_err(whoami, 0, "Unable to set security for group %s.",
3181 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3182 char *group_membership, char *MoiraId)
3184 LK_ENTRY *group_base;
3190 if (!check_string(group_name))
3193 "Unable to process invalid LDAP list name %s", group_name);
3194 return(AD_INVALID_NAME);
3197 memset(filter, '\0', sizeof(filter));
3200 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3202 if (rc = ad_get_group(ldap_handle, temp, group_name,
3203 group_membership, MoiraId,
3204 "distinguishedName", &group_base,
3205 &group_count, filter))
3208 if (group_count == 1)
3210 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
3212 linklist_free(group_base);
3213 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3214 group_name, ldap_err2string(rc));
3217 linklist_free(group_base);
3221 linklist_free(group_base);
3222 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
3223 return(AD_NO_GROUPS_FOUND);
3229 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3235 return(N_SD_BER_BYTES);
3238 int process_lists(int ac, char **av, void *ptr)
3243 char group_membership[2];
3249 memset(group_ou, '\0', sizeof(group_ou));
3250 memset(group_membership, '\0', sizeof(group_membership));
3251 get_group_membership(group_membership, group_ou, &security_flag, av);
3252 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
3253 group_ou, group_membership, call_args[2],
3254 (char *)call_args[3], "");
3258 int member_list_build(int ac, char **av, void *ptr)
3266 strcpy(temp, av[ACE_NAME]);
3268 if (!check_string(temp))
3271 if (!strcmp(av[ACE_TYPE], "USER"))
3273 if (!((int)call_args[3] & MOIRA_USERS))
3276 else if (!strcmp(av[ACE_TYPE], "STRING"))
3280 if((s = strchr(temp, '@')) == (char *) NULL)
3282 strcat(temp, "@mit.edu");
3285 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3287 s = strrchr(temp, '.');
3289 strcat(s, ".mit.edu");
3293 if (!((int)call_args[3] & MOIRA_STRINGS))
3296 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3300 else if (!strcmp(av[ACE_TYPE], "LIST"))
3302 if (!((int)call_args[3] & MOIRA_LISTS))
3305 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3307 if (!((int)call_args[3] & MOIRA_KERBEROS))
3310 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3318 linklist = member_base;
3322 if (!strcasecmp(temp, linklist->member))
3325 linklist = linklist->next;
3328 linklist = calloc(1, sizeof(LK_ENTRY));
3330 linklist->dn = NULL;
3331 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3332 strcpy(linklist->list, call_args[2]);
3333 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3334 strcpy(linklist->type, av[ACE_TYPE]);
3335 linklist->member = calloc(1, strlen(temp) + 1);
3336 strcpy(linklist->member, temp);
3337 linklist->next = member_base;
3338 member_base = linklist;
3343 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3344 char *group_ou, char *group_membership, char *user_name,
3345 char *UserOu, char *MoiraId)
3347 char distinguished_name[1024];
3351 char *attr_array[3];
3356 LK_ENTRY *group_base;
3360 if (!check_string(group_name))
3361 return(AD_INVALID_NAME);
3363 memset(filter, '\0', sizeof(filter));
3367 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3368 group_membership, MoiraId,
3369 "distinguishedName", &group_base,
3370 &group_count, filter))
3373 if (group_count != 1)
3375 com_err(whoami, 0, "Unable to find list %s in AD",
3377 linklist_free(group_base);
3383 strcpy(distinguished_name, group_base->value);
3384 linklist_free(group_base);
3388 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3390 modvalues[0] = temp;
3391 modvalues[1] = NULL;
3394 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3396 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3398 for (i = 0; i < n; i++)
3401 if (rc == LDAP_UNWILLING_TO_PERFORM)
3404 if (rc != LDAP_SUCCESS)
3406 com_err(whoami, 0, "Unable to modify list %s members : %s",
3407 group_name, ldap_err2string(rc));
3411 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3415 if(!strcmp(UserOu, contact_ou) &&
3416 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3418 memset(temp, '\0', sizeof(temp));
3419 strcpy(temp, user_name);
3420 s = strchr(temp, '@');
3423 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3425 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3426 &group_base, &group_count,
3427 LDAP_SCOPE_SUBTREE) != 0))
3433 linklist_free(group_base);
3438 sprintf(filter, "(distinguishedName=%s)", temp);
3439 attr_array[0] = "memberOf";
3440 attr_array[1] = NULL;
3442 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3443 &group_base, &group_count,
3444 LDAP_SCOPE_SUBTREE) != 0))
3450 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3452 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3462 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3463 char *group_ou, char *group_membership, char *user_name,
3464 char *UserOu, char *MoiraId)
3466 char distinguished_name[1024];
3474 LK_ENTRY *group_base;
3477 if (!check_string(group_name))
3478 return(AD_INVALID_NAME);
3481 memset(filter, '\0', sizeof(filter));
3485 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3486 group_membership, MoiraId,
3487 "distinguishedName", &group_base,
3488 &group_count, filter))
3491 if (group_count != 1)
3493 linklist_free(group_base);
3496 com_err(whoami, 0, "Unable to find list %s in AD",
3498 return(AD_MULTIPLE_GROUPS_FOUND);
3501 strcpy(distinguished_name, group_base->value);
3502 linklist_free(group_base);
3506 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3507 modvalues[0] = temp;
3508 modvalues[1] = NULL;
3511 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3513 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3515 if (rc == LDAP_ALREADY_EXISTS)
3518 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3520 if (rc == LDAP_UNWILLING_TO_PERFORM)
3524 for (i = 0; i < n; i++)
3527 if (rc != LDAP_SUCCESS)
3529 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3530 user_name, group_name, ldap_err2string(rc));
3536 int contact_remove_email(LDAP *ld, char *bind_path,
3537 LK_ENTRY **linklist_base, int linklist_current)
3541 char *mail_v[] = {NULL, NULL};
3549 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3550 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3551 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3552 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3555 gPtr = (*linklist_base);
3558 rc = ldap_modify_s(ld, gPtr->dn, mods);
3560 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3562 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3563 gPtr->dn, ldap_err2string(rc));
3570 for (i = 0; i < n; i++)
3576 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3579 LK_ENTRY *group_base;
3582 char cn_user_name[256];
3583 char contact_name[256];
3584 char mail_nickname[256];
3585 char proxy_address_internal[256];
3586 char proxy_address_external[256];
3587 char target_address[256];
3588 char internal_contact_name[256];
3591 char mit_address_book[256];
3592 char default_address_book[256];
3593 char contact_address_book[256];
3594 char *email_v[] = {NULL, NULL};
3595 char *cn_v[] = {NULL, NULL};
3596 char *contact_v[] = {NULL, NULL};
3597 char *mail_nickname_v[] = {NULL, NULL};
3598 char *proxy_address_internal_v[] = {NULL, NULL};
3599 char *proxy_address_external_v[] = {NULL, NULL};
3600 char *target_address_v[] = {NULL, NULL};
3601 char *mit_address_book_v[] = {NULL, NULL};
3602 char *default_address_book_v[] = {NULL, NULL};
3603 char *contact_address_book_v[] = {NULL, NULL};
3604 char *hide_address_lists_v[] = {NULL, NULL};
3605 char *attr_array[3];
3607 char *objectClass_v[] = {"top", "person",
3608 "organizationalPerson",
3610 char *name_v[] = {NULL, NULL};
3611 char *desc_v[] = {NULL, NULL};
3617 if (!check_string(user))
3619 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3620 return(AD_INVALID_NAME);
3624 strcpy(contact_name, mail);
3625 strcpy(internal_contact_name, mail);
3627 if((s = strchr(internal_contact_name, '@')) != NULL) {
3631 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
3632 sprintf(target_address, "SMTP:%s", contact_name);
3633 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3634 sprintf(mail_nickname, "%s", internal_contact_name);
3636 cn_v[0] = cn_user_name;
3637 contact_v[0] = contact_name;
3639 desc_v[0] = "Auto account created by Moira";
3641 proxy_address_internal_v[0] = proxy_address_internal;
3642 proxy_address_external_v[0] = proxy_address_external;
3643 mail_nickname_v[0] = mail_nickname;
3644 target_address_v[0] = target_address;
3645 mit_address_book_v[0] = mit_address_book;
3646 default_address_book_v[0] = default_address_book;
3647 contact_address_book_v[0] = contact_address_book;
3648 strcpy(new_dn, cn_user_name);
3651 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3652 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3653 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3654 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3655 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3659 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3664 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3665 attr_array[0] = "cn";
3666 attr_array[1] = NULL;
3668 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3669 &group_base, &group_count,
3670 LDAP_SCOPE_SUBTREE)) != 0)
3672 com_err(whoami, 0, "Unable to process contact %s : %s",
3673 user, ldap_err2string(rc));
3679 com_err(whoami, 0, "Object already exists with name %s",
3684 linklist_free(group_base);
3688 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3689 attr_array[0] = "cn";
3690 attr_array[1] = NULL;
3692 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3693 &group_base, &group_count,
3694 LDAP_SCOPE_SUBTREE)) != 0)
3696 com_err(whoami, 0, "Unable to process contact %s : %s",
3697 user, ldap_err2string(rc));
3703 com_err(whoami, 0, "Object already exists with name %s",
3708 linklist_free(group_base);
3712 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3713 attr_array[0] = "cn";
3714 attr_array[1] = NULL;
3716 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3717 &group_base, &group_count,
3718 LDAP_SCOPE_SUBTREE)) != 0)
3720 com_err(whoami, 0, "Unable to process contact %s : %s",
3721 user, ldap_err2string(rc));
3727 com_err(whoami, 0, "Object already exists with name %s",
3732 linklist_free(group_base);
3736 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3737 attr_array[0] = "cn";
3738 attr_array[1] = NULL;
3740 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3741 &group_base, &group_count,
3742 LDAP_SCOPE_SUBTREE)) != 0)
3744 com_err(whoami, 0, "Unable to process contact %s : %s",
3745 user, ldap_err2string(rc));
3751 com_err(whoami, 0, "Object already exists with name %s",
3756 linklist_free(group_base);
3760 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3761 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3762 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3763 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3765 hide_address_lists_v[0] = "TRUE";
3766 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3773 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3775 for (i = 0; i < n; i++)
3781 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS) &&
3782 !strcmp(group_ou, contact_ou) && email_isvalid(mail))
3786 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
3787 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
3788 ADD_ATTR("proxyAddresses", proxy_address_external_v,
3790 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
3792 hide_address_lists_v[0] = "TRUE";
3793 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3797 rc = ldap_modify_s(ld, new_dn, mods);
3801 com_err(whoami, 0, "Unable to update contact %s", mail);
3804 for (i = 0; i < n; i++)
3809 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3812 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3813 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3814 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3815 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3816 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3818 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3820 for (i = 0; i < n; i++)
3824 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3826 com_err(whoami, 0, "Unable to create contact %s : %s",
3827 user, ldap_err2string(rc));
3834 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3835 char *Uid, char *MitId, char *MoiraId, int State,
3836 char *WinHomeDir, char *WinProfileDir, char *first,
3837 char *middle, char *last)
3840 LK_ENTRY *group_base;
3842 char distinguished_name[512];
3843 char displayName[256];
3844 char *mitMoiraId_v[] = {NULL, NULL};
3845 char *uid_v[] = {NULL, NULL};
3846 char *mitid_v[] = {NULL, NULL};
3847 char *homedir_v[] = {NULL, NULL};
3848 char *winProfile_v[] = {NULL, NULL};
3849 char *drives_v[] = {NULL, NULL};
3850 char *userAccountControl_v[] = {NULL, NULL};
3851 char *alt_recipient_v[] = {NULL, NULL};
3852 char *hide_address_lists_v[] = {NULL, NULL};
3853 char *mail_v[] = {NULL, NULL};
3854 char userAccountControlStr[80];
3859 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
3860 UF_PASSWD_CANT_CHANGE;
3862 char *attr_array[3];
3865 char contact_mail[256];
3866 char filter_exp[1024];
3867 char search_path[512];
3868 char TemplateDn[512];
3869 char TemplateSamName[128];
3870 char alt_recipient[256];
3871 char acBERBuf[N_SD_BER_BYTES];
3872 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3873 { N_SD_BER_BYTES, acBERBuf },
3875 LDAPControl *apsServerControls[] = {&sControl, NULL};
3877 LDAP_BERVAL **ppsValues;
3881 char *homeServerName;
3883 char search_string[256];
3885 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3886 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3887 BEREncodeSecurityBits(dwInfo, acBERBuf);
3889 if (!check_string(user_name))
3891 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
3893 return(AD_INVALID_NAME);
3896 memset(contact_mail, '\0', sizeof(contact_mail));
3897 sprintf(contact_mail, "%s@mit.edu", user_name);
3898 memset(mail, '\0', sizeof(mail));
3899 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
3900 memset(alt_recipient, '\0', sizeof(alt_recipient));
3901 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
3903 sprintf(search_string, "@%s", uppercase(ldap_domain));
3907 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
3909 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
3916 memset(displayName, '\0', sizeof(displayName));
3918 if (strlen(MoiraId) != 0)
3920 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
3921 attr_array[0] = "cn";
3922 attr_array[1] = NULL;
3923 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3924 &group_base, &group_count,
3925 LDAP_SCOPE_SUBTREE)) != 0)
3927 com_err(whoami, 0, "Unable to process user %s : %s",
3928 user_name, ldap_err2string(rc));
3933 if (group_count != 1)
3935 linklist_free(group_base);
3938 sprintf(filter, "(sAMAccountName=%s)", user_name);
3939 attr_array[0] = "cn";
3940 attr_array[1] = NULL;
3941 sprintf(temp, "%s,%s", user_ou, dn_path);
3942 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
3943 &group_base, &group_count,
3944 LDAP_SCOPE_SUBTREE)) != 0)
3946 com_err(whoami, 0, "Unable to process user %s : %s",
3947 user_name, ldap_err2string(rc));
3952 if (group_count != 1)
3954 com_err(whoami, 0, "Unable to find user %s in AD",
3956 linklist_free(group_base);
3957 return(AD_NO_USER_FOUND);
3960 strcpy(distinguished_name, group_base->dn);
3962 linklist_free(group_base);
3965 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
3966 rc = attribute_update(ldap_handle, distinguished_name, MitId,
3967 "employeeID", user_name);
3969 rc = attribute_update(ldap_handle, distinguished_name, "none",
3970 "employeeID", user_name);
3973 strcat(displayName, first);
3976 if(strlen(middle)) {
3978 strcat(displayName, " ");
3980 strcat(displayName, middle);
3984 if(strlen(middle) || strlen(first))
3985 strcat(displayName, " ");
3987 strcat(displayName, last);
3990 if(strlen(displayName))
3991 rc = attribute_update(ldap_handle, distinguished_name, displayName,
3992 "displayName", user_name);
3994 rc = attribute_update(ldap_handle, distinguished_name, user_name,
3995 "displayName", user_name);
3998 rc = attribute_update(ldap_handle, distinguished_name, first,
3999 "givenName", user_name);
4001 rc = attribute_update(ldap_handle, distinguished_name, "",
4002 "givenName", user_name);
4004 if(strlen(middle) == 1)
4005 rc = attribute_update(ldap_handle, distinguished_name, middle,
4006 "initials", user_name);
4008 rc = attribute_update(ldap_handle, distinguished_name, "",
4009 "initials", user_name);
4012 rc = attribute_update(ldap_handle, distinguished_name, last,
4015 rc = attribute_update(ldap_handle, distinguished_name, "",
4018 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4020 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4021 "mitMoiraId", user_name);
4028 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4032 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4035 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4037 userAccountControl |= UF_ACCOUNTDISABLE;
4041 hide_address_lists_v[0] = "TRUE";
4042 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4050 hide_address_lists_v[0] = NULL;
4051 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4056 sprintf(userAccountControlStr, "%ld", userAccountControl);
4057 userAccountControl_v[0] = userAccountControlStr;
4058 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4062 if (rc = moira_connect())
4064 critical_alert("AD incremental",
4065 "Error contacting Moira server : %s",
4070 argv[0] = user_name;
4072 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4074 if(!strcmp(save_argv[1], "EXCHANGE") ||
4075 (strstr(save_argv[3], search_string) != NULL))
4077 alt_recipient_v[0] = NULL;
4078 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4080 argv[0] = exchange_acl;
4082 argv[2] = user_name;
4084 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4086 if ((rc) && (rc != MR_EXISTS))
4088 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4089 user_name, exchange_acl, error_message(rc));
4094 alt_recipient_v[0] = alt_recipient;
4095 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4097 argv[0] = exchange_acl;
4099 argv[2] = user_name;
4101 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4103 if ((rc) && (rc != MR_NO_MATCH))
4106 "Unable to remove user %s from %s: %s, %d",
4107 user_name, exchange_acl, error_message(rc), rc);
4113 alt_recipient_v[0] = alt_recipient;
4114 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4116 argv[0] = exchange_acl;
4118 argv[2] = user_name;
4120 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4122 if ((rc) && (rc != MR_NO_MATCH))
4125 "Unable to remove user %s from %s: %s, %d",
4126 user_name, exchange_acl, error_message(rc), rc);
4134 mail_v[0] = contact_mail;
4135 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4138 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4139 WinProfileDir, homedir_v, winProfile_v,
4140 drives_v, mods, LDAP_MOD_REPLACE, n);
4142 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4143 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4144 attr_array[0] = "sAMAccountName";
4145 attr_array[1] = NULL;
4149 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
4150 &group_base, &group_count,
4151 LDAP_SCOPE_SUBTREE) != 0))
4154 if (group_count != 1)
4156 com_err(whoami, 0, "Unable to process user security template: %s - "
4157 "security not set", "UserTemplate.u");
4161 strcpy(TemplateDn, group_base->dn);
4162 strcpy(TemplateSamName, group_base->value);
4163 linklist_free(group_base);
4167 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4168 filter_exp, NULL, 0, apsServerControls, NULL,
4171 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4173 com_err(whoami, 0, "Unable to find user security template: %s - "
4174 "security not set", "UserTemplate.u");
4178 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
4180 if (ppsValues == NULL)
4182 com_err(whoami, 0, "Unable to find user security template: %s - "
4183 "security not set", "UserTemplate.u");
4187 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4188 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4192 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4193 mods)) != LDAP_SUCCESS)
4195 OldUseSFU30 = UseSFU30;
4196 SwitchSFU(mods, &UseSFU30, n);
4197 if (OldUseSFU30 != UseSFU30)
4198 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4201 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4202 user_name, ldap_err2string(rc));
4206 for (i = 0; i < n; i++)
4212 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4220 char contact_mail[256];
4221 char proxy_address[256];
4222 char query_base_dn[256];
4224 char *userPrincipalName_v[] = {NULL, NULL};
4225 char *altSecurityIdentities_v[] = {NULL, NULL};
4226 char *name_v[] = {NULL, NULL};
4227 char *samAccountName_v[] = {NULL, NULL};
4228 char *mail_v[] = {NULL, NULL};
4229 char *mail_nickname_v[] = {NULL, NULL};
4230 char *proxy_address_v[] = {NULL, NULL};
4231 char *query_base_dn_v[] = {NULL, NULL};
4236 if (!check_string(before_user_name))
4239 "Unable to process invalid LDAP user name %s", before_user_name);
4240 return(AD_INVALID_NAME);
4243 if (!check_string(user_name))
4246 "Unable to process invalid LDAP user name %s", user_name);
4247 return(AD_INVALID_NAME);
4250 strcpy(user_name, user_name);
4251 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4252 sprintf(new_dn, "cn=%s", user_name);
4253 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4254 sprintf(contact_mail, "%s@mit.edu", user_name);
4255 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4257 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4258 NULL, NULL)) != LDAP_SUCCESS)
4260 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4261 before_user_name, user_name, ldap_err2string(rc));
4267 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4270 if(rc = ldap_delete_s(ldap_handle, temp))
4272 com_err(whoami, 0, "Unable to delete user contact for %s",
4276 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4278 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4282 name_v[0] = user_name;
4283 sprintf(upn, "%s@%s", user_name, ldap_domain);
4284 userPrincipalName_v[0] = upn;
4285 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4286 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4287 altSecurityIdentities_v[0] = temp;
4288 samAccountName_v[0] = user_name;
4290 mail_nickname_v[0] = user_name;
4291 proxy_address_v[0] = proxy_address;
4292 query_base_dn_v[0] = query_base_dn;
4295 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4296 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4297 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4298 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4302 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4303 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4304 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4305 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4309 mail_v[0] = contact_mail;
4310 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4315 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4317 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4320 "Unable to modify user data for %s after renaming : %s",
4321 user_name, ldap_err2string(rc));
4324 for (i = 0; i < n; i++)
4330 int user_create(int ac, char **av, void *ptr)
4334 char user_name[256];
4338 char contact_mail[256];
4339 char proxy_address[256];
4340 char mail_nickname[256];
4341 char query_base_dn[256];
4342 char displayName[256];
4343 char address_book[256];
4344 char alt_recipient[256];
4345 char *cn_v[] = {NULL, NULL};
4346 char *objectClass_v[] = {"top", "person",
4347 "organizationalPerson",
4350 char *samAccountName_v[] = {NULL, NULL};
4351 char *altSecurityIdentities_v[] = {NULL, NULL};
4352 char *mitMoiraId_v[] = {NULL, NULL};
4353 char *name_v[] = {NULL, NULL};
4354 char *desc_v[] = {NULL, NULL};
4355 char *userPrincipalName_v[] = {NULL, NULL};
4356 char *userAccountControl_v[] = {NULL, NULL};
4357 char *uid_v[] = {NULL, NULL};
4358 char *mitid_v[] = {NULL, NULL};
4359 char *homedir_v[] = {NULL, NULL};
4360 char *winProfile_v[] = {NULL, NULL};
4361 char *drives_v[] = {NULL, NULL};
4362 char *mail_v[] = {NULL, NULL};
4363 char *givenName_v[] = {NULL, NULL};
4364 char *sn_v[] = {NULL, NULL};
4365 char *initials_v[] = {NULL, NULL};
4366 char *displayName_v[] = {NULL, NULL};
4367 char *proxy_address_v[] = {NULL, NULL};
4368 char *mail_nickname_v[] = {NULL, NULL};
4369 char *query_base_dn_v[] = {NULL, NULL};
4370 char *address_book_v[] = {NULL, NULL};
4371 char *homeMDB_v[] = {NULL, NULL};
4372 char *homeServerName_v[] = {NULL, NULL};
4373 char *mdbUseDefaults_v[] = {NULL, NULL};
4374 char *mailbox_guid_v[] = {NULL, NULL};
4375 char *user_culture_v[] = {NULL, NULL};
4376 char *user_account_control_v[] = {NULL, NULL};
4377 char *msexch_version_v[] = {NULL, NULL};
4378 char *alt_recipient_v[] = {NULL, NULL};
4379 char *hide_address_lists_v[] = {NULL, NULL};
4380 char userAccountControlStr[80];
4382 char filter_exp[1024];
4383 char search_path[512];
4384 char *attr_array[3];
4385 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4386 UF_PASSWD_CANT_CHANGE;
4392 char WinHomeDir[1024];
4393 char WinProfileDir[1024];
4395 char *homeServerName;
4397 char acBERBuf[N_SD_BER_BYTES];
4398 LK_ENTRY *group_base;
4400 char TemplateDn[512];
4401 char TemplateSamName[128];
4402 LDAP_BERVAL **ppsValues;
4403 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4404 { N_SD_BER_BYTES, acBERBuf },
4406 LDAPControl *apsServerControls[] = {&sControl, NULL};
4410 char search_string[256];
4414 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4415 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4416 BEREncodeSecurityBits(dwInfo, acBERBuf);
4418 if (!check_string(av[U_NAME]))
4420 callback_rc = AD_INVALID_NAME;
4421 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4423 return(AD_INVALID_NAME);
4426 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4427 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4428 memset(displayName, '\0', sizeof(displayName));
4429 memset(query_base_dn, '\0', sizeof(query_base_dn));
4430 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4431 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4432 strcpy(user_name, av[U_NAME]);
4433 sprintf(upn, "%s@%s", user_name, ldap_domain);
4434 sprintf(sam_name, "%s", av[U_NAME]);
4436 if(strlen(av[U_FIRST])) {
4437 strcat(displayName, av[U_FIRST]);
4440 if(strlen(av[U_MIDDLE])) {
4441 if(strlen(av[U_FIRST]))
4442 strcat(displayName, " ");
4444 strcat(displayName, av[U_MIDDLE]);
4447 if(strlen(av[U_LAST])) {
4448 if(strlen(av[U_FIRST]) || strlen(av[U_LAST]))
4449 strcat(displayName, " ");
4451 strcat(displayName, av[U_LAST]);
4454 samAccountName_v[0] = sam_name;
4455 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4456 (atoi(av[U_STATE]) != US_REGISTERED))
4458 userAccountControl |= UF_ACCOUNTDISABLE;
4462 hide_address_lists_v[0] = "TRUE";
4463 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4468 sprintf(userAccountControlStr, "%ld", userAccountControl);
4469 userAccountControl_v[0] = userAccountControlStr;
4470 userPrincipalName_v[0] = upn;
4471 cn_v[0] = user_name;
4472 name_v[0] = user_name;
4473 desc_v[0] = "Auto account created by Moira";
4475 givenName_v[0] = av[U_FIRST];
4476 sn_v[0] = av[U_LAST];
4477 displayName_v[0] = displayName;
4478 mail_nickname_v[0] = user_name;
4480 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4481 altSecurityIdentities_v[0] = temp;
4482 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4483 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4484 sprintf(contact_mail, "%s@mit.edu", user_name);
4485 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4486 query_base_dn_v[0] = query_base_dn;
4487 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4489 sprintf(search_string, "@%s", uppercase(ldap_domain));
4494 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4497 com_err(whoami, 0, "Unable to create user contact %s",
4501 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4504 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4508 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4509 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4511 homeMDB_v[0] = homeMDB;
4512 homeServerName_v[0] = homeServerName;
4516 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4517 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4518 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
4519 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
4520 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
4521 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
4522 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
4526 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
4527 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4528 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
4529 mdbUseDefaults_v[0] = "TRUE";
4530 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
4531 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
4533 argv[0] = user_name;
4535 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4537 if(!strcmp(save_argv[1], "EXCHANGE") ||
4538 (strstr(save_argv[3], search_string) != NULL))
4540 argv[0] = exchange_acl;
4542 argv[2] = user_name;
4544 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4546 if ((rc) && (rc != MR_EXISTS))
4548 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4549 user_name, exchange_acl, error_message(rc));
4554 alt_recipient_v[0] = alt_recipient;
4555 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4560 alt_recipient_v[0] = alt_recipient;
4561 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4563 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
4568 mail_v[0] = contact_mail;
4569 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
4572 if(strlen(av[U_FIRST])) {
4573 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
4576 if(strlen(av[U_LAST])) {
4577 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
4580 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
4581 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
4583 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4586 if (strlen(av[U_MIDDLE]) == 1) {
4587 initials_v[0] = av[U_MIDDLE];
4588 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
4591 if (strlen(call_args[2]) != 0)
4593 mitMoiraId_v[0] = call_args[2];
4594 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
4597 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
4599 if (strlen(av[U_UID]) != 0)
4601 uid_v[0] = av[U_UID];
4602 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
4606 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
4610 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
4614 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
4615 mitid_v[0] = av[U_MITID];
4617 mitid_v[0] = "none";
4619 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
4621 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
4622 WinProfileDir, homedir_v, winProfile_v,
4623 drives_v, mods, LDAP_MOD_ADD, n);
4625 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4626 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
4627 attr_array[0] = "sAMAccountName";
4628 attr_array[1] = NULL;
4632 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
4633 attr_array, &group_base, &group_count,
4634 LDAP_SCOPE_SUBTREE) != 0))
4637 if (group_count != 1)
4639 com_err(whoami, 0, "Unable to process user security template: %s - "
4640 "security not set", "UserTemplate.u");
4644 strcpy(TemplateDn, group_base->dn);
4645 strcpy(TemplateSamName, group_base->value);
4646 linklist_free(group_base);
4650 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE,
4651 filter_exp, NULL, 0, apsServerControls, NULL,
4654 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
4656 com_err(whoami, 0, "Unable to find user security template: %s - "
4657 "security not set", "UserTemplate.u");
4661 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
4662 "ntSecurityDescriptor");
4663 if (ppsValues == NULL)
4665 com_err(whoami, 0, "Unable to find user security template: %s - "
4666 "security not set", "UserTemplate.u");
4670 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4671 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4675 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4677 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4679 OldUseSFU30 = UseSFU30;
4680 SwitchSFU(mods, &UseSFU30, n);
4681 if (OldUseSFU30 != UseSFU30)
4682 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4685 for (i = 0; i < n; i++)
4688 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4690 com_err(whoami, 0, "Unable to create user %s : %s",
4691 user_name, ldap_err2string(rc));
4696 if ((rc == LDAP_SUCCESS) && (SetPassword))
4698 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4700 ad_kdc_disconnect();
4701 if (!ad_server_connect(default_server, ldap_domain))
4703 com_err(whoami, 0, "Unable to set password for user %s : %s",
4705 "cannot get changepw ticket from windows domain");
4709 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4711 com_err(whoami, 0, "Unable to set password for user %s "
4712 ": %ld", user_name, rc);
4721 int user_change_status(LDAP *ldap_handle, char *dn_path,
4722 char *user_name, char *MoiraId,
4726 char *attr_array[3];
4728 char distinguished_name[1024];
4730 char *mitMoiraId_v[] = {NULL, NULL};
4732 LK_ENTRY *group_base;
4739 if (!check_string(user_name))
4741 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4743 return(AD_INVALID_NAME);
4749 if (strlen(MoiraId) != 0)
4751 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4752 attr_array[0] = "UserAccountControl";
4753 attr_array[1] = NULL;
4754 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4755 &group_base, &group_count,
4756 LDAP_SCOPE_SUBTREE)) != 0)
4758 com_err(whoami, 0, "Unable to process user %s : %s",
4759 user_name, ldap_err2string(rc));
4764 if (group_count != 1)
4766 linklist_free(group_base);
4769 sprintf(filter, "(sAMAccountName=%s)", user_name);
4770 attr_array[0] = "UserAccountControl";
4771 attr_array[1] = NULL;
4772 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4773 &group_base, &group_count,
4774 LDAP_SCOPE_SUBTREE)) != 0)
4776 com_err(whoami, 0, "Unable to process user %s : %s",
4777 user_name, ldap_err2string(rc));
4782 if (group_count != 1)
4784 linklist_free(group_base);
4785 com_err(whoami, 0, "Unable to find user %s in AD",
4787 return(LDAP_NO_SUCH_OBJECT);
4790 strcpy(distinguished_name, group_base->dn);
4791 ulongValue = atoi((*group_base).value);
4793 if (operation == MEMBER_DEACTIVATE)
4794 ulongValue |= UF_ACCOUNTDISABLE;
4796 ulongValue &= ~UF_ACCOUNTDISABLE;
4798 sprintf(temp, "%ld", ulongValue);
4800 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
4801 temp, &modvalues, REPLACE)) == 1)
4804 linklist_free(group_base);
4808 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
4810 if (strlen(MoiraId) != 0)
4812 mitMoiraId_v[0] = MoiraId;
4813 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
4817 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4819 for (i = 0; i < n; i++)
4822 free_values(modvalues);
4824 if (rc != LDAP_SUCCESS)
4826 com_err(whoami, 0, "Unable to change status of user %s : %s",
4827 user_name, ldap_err2string(rc));
4834 int user_delete(LDAP *ldap_handle, char *dn_path,
4835 char *u_name, char *MoiraId)
4838 char *attr_array[3];
4839 char distinguished_name[1024];
4840 char user_name[512];
4841 LK_ENTRY *group_base;
4846 if (!check_string(u_name))
4847 return(AD_INVALID_NAME);
4849 strcpy(user_name, u_name);
4853 if (strlen(MoiraId) != 0)
4855 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4856 attr_array[0] = "name";
4857 attr_array[1] = NULL;
4858 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4859 &group_base, &group_count,
4860 LDAP_SCOPE_SUBTREE)) != 0)
4862 com_err(whoami, 0, "Unable to process user %s : %s",
4863 user_name, ldap_err2string(rc));
4868 if (group_count != 1)
4870 linklist_free(group_base);
4873 sprintf(filter, "(sAMAccountName=%s)", user_name);
4874 attr_array[0] = "name";
4875 attr_array[1] = NULL;
4876 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4877 &group_base, &group_count,
4878 LDAP_SCOPE_SUBTREE)) != 0)
4880 com_err(whoami, 0, "Unable to process user %s : %s",
4881 user_name, ldap_err2string(rc));
4886 if (group_count != 1)
4888 com_err(whoami, 0, "Unable to find user %s in AD",
4893 strcpy(distinguished_name, group_base->dn);
4895 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
4897 com_err(whoami, 0, "Unable to process user %s : %s",
4898 user_name, ldap_err2string(rc));
4901 /* Need to add code to delete mit.edu contact */
4905 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
4907 if(rc = ldap_delete_s(ldap_handle, temp))
4909 com_err(whoami, 0, "Unable to delete user contact for %s",
4915 linklist_free(group_base);
4920 void linklist_free(LK_ENTRY *linklist_base)
4922 LK_ENTRY *linklist_previous;
4924 while (linklist_base != NULL)
4926 if (linklist_base->dn != NULL)
4927 free(linklist_base->dn);
4929 if (linklist_base->attribute != NULL)
4930 free(linklist_base->attribute);
4932 if (linklist_base->value != NULL)
4933 free(linklist_base->value);
4935 if (linklist_base->member != NULL)
4936 free(linklist_base->member);
4938 if (linklist_base->type != NULL)
4939 free(linklist_base->type);
4941 if (linklist_base->list != NULL)
4942 free(linklist_base->list);
4944 linklist_previous = linklist_base;
4945 linklist_base = linklist_previous->next;
4946 free(linklist_previous);
4950 void free_values(char **modvalues)
4956 if (modvalues != NULL)
4958 while (modvalues[i] != NULL)
4961 modvalues[i] = NULL;
4968 static int illegalchars[] = {
4969 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
4970 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
4971 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
4972 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
4973 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
4974 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
4975 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
4976 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
4977 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4978 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4979 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4980 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4981 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4982 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4983 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4984 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4987 int check_string(char *s)
4995 if (isupper(character))
4996 character = tolower(character);
4998 if (illegalchars[(unsigned) character])
5005 int check_container_name(char *s)
5013 if (isupper(character))
5014 character = tolower(character);
5016 if (character == ' ')
5019 if (illegalchars[(unsigned) character])
5026 int mr_connect_cl(char *server, char *client, int version, int auth)
5032 status = mr_connect(server);
5036 com_err(whoami, status, "while connecting to Moira");
5040 status = mr_motd(&motd);
5045 com_err(whoami, status, "while checking server status");
5051 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5052 com_err(whoami, status, temp);
5057 status = mr_version(version);
5061 if (status == MR_UNKNOWN_PROC)
5064 status = MR_VERSION_HIGH;
5066 status = MR_SUCCESS;
5069 if (status == MR_VERSION_HIGH)
5071 com_err(whoami, 0, "Warning: This client is running newer code "
5072 "than the server.");
5073 com_err(whoami, 0, "Some operations may not work.");
5075 else if (status && status != MR_VERSION_LOW)
5077 com_err(whoami, status, "while setting query version number.");
5085 status = mr_krb5_auth(client);
5088 com_err(whoami, status, "while authenticating to Moira.");
5097 void AfsToWinAfs(char* path, char* winPath)
5101 strcpy(winPath, WINAFS);
5102 pathPtr = path + strlen(AFS);
5103 winPathPtr = winPath + strlen(WINAFS);
5107 if (*pathPtr == '/')
5110 *winPathPtr = *pathPtr;
5117 int GetAceInfo(int ac, char **av, void *ptr)
5124 strcpy(call_args[0], av[L_ACE_TYPE]);
5125 strcpy(call_args[1], av[L_ACE_NAME]);
5127 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5128 return(LDAP_SUCCESS);
5131 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5134 char *attr_array[3];
5137 LK_ENTRY *group_base;
5142 sprintf(filter, "(sAMAccountName=%s)", Name);
5143 attr_array[0] = "sAMAccountName";
5144 attr_array[1] = NULL;
5146 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5147 &group_base, &group_count,
5148 LDAP_SCOPE_SUBTREE)) != 0)
5150 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5151 Name, ldap_err2string(rc));
5155 linklist_free(group_base);
5158 if (group_count == 0)
5166 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5167 int UpdateGroup, int *ProcessGroup, char *maillist)
5170 char GroupName[256];
5176 char AceMembership[2];
5179 char *save_argv[U_END];
5183 com_err(whoami, 0, "ProcessAce disabled, skipping");
5187 strcpy(GroupName, Name);
5189 if (strcasecmp(Type, "LIST"))
5195 AceInfo[0] = AceType;
5196 AceInfo[1] = AceName;
5197 AceInfo[2] = AceMembership;
5199 memset(AceType, '\0', sizeof(AceType));
5200 memset(AceName, '\0', sizeof(AceName));
5201 memset(AceMembership, '\0', sizeof(AceMembership));
5202 memset(AceOu, '\0', sizeof(AceOu));
5205 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5207 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5208 GroupName, error_message(rc));
5214 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5218 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5221 strcpy(temp, AceName);
5223 if (!strcasecmp(AceType, "LIST"))
5224 sprintf(temp, "%s%s", AceName, group_suffix);
5228 if (checkADname(ldap_handle, dn_path, temp))
5230 (*ProcessGroup) = 1;
5233 if (!strcasecmp(AceInfo[0], "LIST"))
5235 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5236 AceMembership, 0, UpdateGroup, maillist))
5239 else if (!strcasecmp(AceInfo[0], "USER"))
5242 call_args[0] = (char *)ldap_handle;
5243 call_args[1] = dn_path;
5245 call_args[3] = NULL;
5248 if (rc = mr_query("get_user_account_by_login", 1, av,
5249 save_query_info, save_argv))
5251 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5256 if (rc = user_create(U_END, save_argv, call_args))
5258 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5265 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5275 if (!strcasecmp(AceType, "LIST"))
5277 if (!strcasecmp(GroupName, AceName))
5281 strcpy(GroupName, AceName);
5287 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5288 char *group_name, char *group_ou, char *group_membership,
5289 int group_security_flag, int updateGroup, char *maillist)
5294 LK_ENTRY *group_base;
5297 char *attr_array[3];
5300 call_args[0] = (char *)ldap_handle;
5301 call_args[1] = dn_path;
5302 call_args[2] = group_name;
5303 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5304 call_args[4] = (char *)updateGroup;
5305 call_args[5] = MoiraId;
5307 call_args[7] = NULL;
5313 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5316 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5324 com_err(whoami, 0, "Unable to create list %s", group_name);
5325 return(callback_rc);
5331 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
5332 char *group_ou, char *group_membership,
5333 int group_security_flag, char *MoiraId)
5343 com_err(whoami, 0, "Populating group %s", group_name);
5345 call_args[0] = (char *)ldap_handle;
5346 call_args[1] = dn_path;
5347 call_args[2] = group_name;
5348 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5349 call_args[4] = NULL;
5352 if (rc = mr_query("get_end_members_of_list", 1, av,
5353 member_list_build, call_args))
5355 com_err(whoami, 0, "Unable to populate list %s : %s",
5356 group_name, error_message(rc));
5360 if (member_base != NULL)
5366 if (!strcasecmp(ptr->type, "LIST"))
5374 if (!strcasecmp(ptr->type, "STRING"))
5376 if (contact_create(ldap_handle, dn_path, ptr->member,
5380 pUserOu = contact_ou;
5382 else if (!strcasecmp(ptr->type, "KERBEROS"))
5384 if (contact_create(ldap_handle, dn_path, ptr->member,
5388 pUserOu = kerberos_ou;
5391 rc = member_add(ldap_handle, dn_path, group_name,
5392 group_ou, group_membership, ptr->member,
5397 linklist_free(member_base);
5404 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5405 char *group_name, char *group_ou, char *group_membership,
5406 int group_security_flag, int type, char *maillist)
5408 char before_desc[512];
5409 char before_name[256];
5410 char before_group_ou[256];
5411 char before_group_membership[2];
5412 char distinguishedName[256];
5413 char ad_distinguishedName[256];
5415 char *attr_array[3];
5416 int before_security_flag;
5419 LK_ENTRY *group_base;
5422 char ou_security[512];
5423 char ou_distribution[512];
5424 char ou_neither[512];
5426 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
5427 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
5429 memset(filter, '\0', sizeof(filter));
5433 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5435 "distinguishedName", &group_base,
5436 &group_count, filter))
5439 if (type == CHECK_GROUPS)
5441 if (group_count == 1)
5443 if (!strcasecmp(group_base->value, distinguishedName))
5445 linklist_free(group_base);
5450 linklist_free(group_base);
5452 if (group_count == 0)
5453 return(AD_NO_GROUPS_FOUND);
5455 if (group_count == 1)
5456 return(AD_WRONG_GROUP_DN_FOUND);
5458 return(AD_MULTIPLE_GROUPS_FOUND);
5461 if (group_count == 0)
5463 return(AD_NO_GROUPS_FOUND);
5466 if (group_count > 1)
5472 if (!strcasecmp(distinguishedName, ptr->value))
5480 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
5486 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
5490 linklist_free(group_base);
5491 return(AD_MULTIPLE_GROUPS_FOUND);
5498 if (strcasecmp(distinguishedName, ptr->value))
5499 rc = ldap_delete_s(ldap_handle, ptr->value);
5504 linklist_free(group_base);
5505 memset(filter, '\0', sizeof(filter));
5509 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5511 "distinguishedName", &group_base,
5512 &group_count, filter))
5515 if (group_count == 0)
5516 return(AD_NO_GROUPS_FOUND);
5518 if (group_count > 1)
5519 return(AD_MULTIPLE_GROUPS_FOUND);
5522 strcpy(ad_distinguishedName, group_base->value);
5523 linklist_free(group_base);
5527 attr_array[0] = "sAMAccountName";
5528 attr_array[1] = NULL;
5530 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5531 &group_base, &group_count,
5532 LDAP_SCOPE_SUBTREE)) != 0)
5534 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5535 MoiraId, ldap_err2string(rc));
5539 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
5541 if (!strcasecmp(ad_distinguishedName, distinguishedName))
5543 linklist_free(group_base);
5549 linklist_free(group_base);
5552 memset(ou_both, '\0', sizeof(ou_both));
5553 memset(ou_security, '\0', sizeof(ou_security));
5554 memset(ou_distribution, '\0', sizeof(ou_distribution));
5555 memset(ou_neither, '\0', sizeof(ou_neither));
5556 memset(before_name, '\0', sizeof(before_name));
5557 memset(before_desc, '\0', sizeof(before_desc));
5558 memset(before_group_membership, '\0', sizeof(before_group_membership));
5559 attr_array[0] = "name";
5560 attr_array[1] = NULL;
5562 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5563 &group_base, &group_count,
5564 LDAP_SCOPE_SUBTREE)) != 0)
5566 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
5567 MoiraId, ldap_err2string(rc));
5571 strcpy(before_name, group_base->value);
5572 linklist_free(group_base);
5575 attr_array[0] = "description";
5576 attr_array[1] = NULL;
5578 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5579 &group_base, &group_count,
5580 LDAP_SCOPE_SUBTREE)) != 0)
5583 "Unable to get list description with MoiraId = %s: %s",
5584 MoiraId, ldap_err2string(rc));
5588 if (group_count != 0)
5590 strcpy(before_desc, group_base->value);
5591 linklist_free(group_base);
5596 change_to_lower_case(ad_distinguishedName);
5597 strcpy(ou_both, group_ou_both);
5598 change_to_lower_case(ou_both);
5599 strcpy(ou_security, group_ou_security);
5600 change_to_lower_case(ou_security);
5601 strcpy(ou_distribution, group_ou_distribution);
5602 change_to_lower_case(ou_distribution);
5603 strcpy(ou_neither, group_ou_neither);
5604 change_to_lower_case(ou_neither);
5606 if (strstr(ad_distinguishedName, ou_both))
5608 strcpy(before_group_ou, group_ou_both);
5609 before_group_membership[0] = 'B';
5610 before_security_flag = 1;
5612 else if (strstr(ad_distinguishedName, ou_security))
5614 strcpy(before_group_ou, group_ou_security);
5615 before_group_membership[0] = 'S';
5616 before_security_flag = 1;
5618 else if (strstr(ad_distinguishedName, ou_distribution))
5620 strcpy(before_group_ou, group_ou_distribution);
5621 before_group_membership[0] = 'D';
5622 before_security_flag = 0;
5624 else if (strstr(ad_distinguishedName, ou_neither))
5626 strcpy(before_group_ou, group_ou_neither);
5627 before_group_membership[0] = 'N';
5628 before_security_flag = 0;
5631 return(AD_NO_OU_FOUND);
5633 rc = group_rename(ldap_handle, dn_path, before_name,
5634 before_group_membership,
5635 before_group_ou, before_security_flag, before_desc,
5636 group_name, group_membership, group_ou,
5637 group_security_flag,
5638 before_desc, MoiraId, filter, maillist);
5643 void change_to_lower_case(char *ptr)
5647 for (i = 0; i < (int)strlen(ptr); i++)
5649 ptr[i] = tolower(ptr[i]);
5653 int ad_get_group(LDAP *ldap_handle, char *dn_path,
5654 char *group_name, char *group_membership,
5655 char *MoiraId, char *attribute,
5656 LK_ENTRY **linklist_base, int *linklist_count,
5661 char *attr_array[3];
5664 (*linklist_base) = NULL;
5665 (*linklist_count) = 0;
5667 if (strlen(rFilter) != 0)
5669 strcpy(filter, rFilter);
5670 attr_array[0] = attribute;
5671 attr_array[1] = NULL;
5673 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5674 linklist_base, linklist_count,
5675 LDAP_SCOPE_SUBTREE)) != 0)
5677 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5678 MoiraId, ldap_err2string(rc));
5682 if ((*linklist_count) == 1)
5684 strcpy(rFilter, filter);
5689 linklist_free((*linklist_base));
5690 (*linklist_base) = NULL;
5691 (*linklist_count) = 0;
5693 if (strlen(MoiraId) != 0)
5695 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
5696 attr_array[0] = attribute;
5697 attr_array[1] = NULL;
5699 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5700 linklist_base, linklist_count,
5701 LDAP_SCOPE_SUBTREE)) != 0)
5703 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5704 MoiraId, ldap_err2string(rc));
5709 if ((*linklist_count) > 1)
5711 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
5712 pPtr = (*linklist_base);
5716 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
5721 linklist_free((*linklist_base));
5722 (*linklist_base) = NULL;
5723 (*linklist_count) = 0;
5726 if ((*linklist_count) == 1)
5728 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
5730 strcpy(rFilter, filter);
5735 linklist_free((*linklist_base));
5736 (*linklist_base) = NULL;
5737 (*linklist_count) = 0;
5738 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
5739 com_err(whoami, 0, "AD_GET_GROUP: samname is %s%s", group_name, group_suffix);
5740 attr_array[0] = attribute;
5741 attr_array[1] = NULL;
5743 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5744 linklist_base, linklist_count,
5745 LDAP_SCOPE_SUBTREE)) != 0)
5747 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5748 MoiraId, ldap_err2string(rc));
5752 if ((*linklist_count) == 1)
5754 strcpy(rFilter, filter);
5761 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5764 char *attr_array[3];
5765 char SamAccountName[64];
5768 LK_ENTRY *group_base;
5774 if (strlen(MoiraId) != 0)
5776 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5777 attr_array[0] = "sAMAccountName";
5778 attr_array[1] = NULL;
5779 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5780 &group_base, &group_count,
5781 LDAP_SCOPE_SUBTREE)) != 0)
5783 com_err(whoami, 0, "Unable to process user %s : %s",
5784 UserName, ldap_err2string(rc));
5788 if (group_count > 1)
5790 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5796 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5797 gPtr->value, MoiraId);
5803 if (group_count != 1)
5805 linklist_free(group_base);
5808 sprintf(filter, "(sAMAccountName=%s)", UserName);
5809 attr_array[0] = "sAMAccountName";
5810 attr_array[1] = NULL;
5812 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5813 &group_base, &group_count,
5814 LDAP_SCOPE_SUBTREE)) != 0)
5816 com_err(whoami, 0, "Unable to process user %s : %s",
5817 UserName, ldap_err2string(rc));
5822 if (group_count != 1)
5824 linklist_free(group_base);
5825 return(AD_NO_USER_FOUND);
5828 strcpy(SamAccountName, group_base->value);
5829 linklist_free(group_base);
5833 if (strcmp(SamAccountName, UserName))
5835 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5842 void container_get_dn(char *src, char *dest)
5849 memset(array, '\0', 20 * sizeof(array[0]));
5851 if (strlen(src) == 0)
5873 strcpy(dest, "OU=");
5877 strcat(dest, array[n-1]);
5881 strcat(dest, ",OU=");
5888 void container_get_name(char *src, char *dest)
5893 if (strlen(src) == 0)
5913 void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5920 strcpy(cName, name);
5922 for (i = 0; i < (int)strlen(cName); i++)
5924 if (cName[i] == '/')
5927 av[CONTAINER_NAME] = cName;
5928 av[CONTAINER_DESC] = "";
5929 av[CONTAINER_LOCATION] = "";
5930 av[CONTAINER_CONTACT] = "";
5931 av[CONTAINER_TYPE] = "";
5932 av[CONTAINER_ID] = "";
5933 av[CONTAINER_ROWID] = "";
5934 rc = container_create(ldap_handle, dn_path, 7, av);
5936 if (rc == LDAP_SUCCESS)
5938 com_err(whoami, 0, "container %s created without a mitMoiraId",
5947 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5948 char **before, int afterc, char **after)
5953 char new_dn_path[256];
5955 char distinguishedName[256];
5960 memset(cName, '\0', sizeof(cName));
5961 container_get_name(after[CONTAINER_NAME], cName);
5963 if (!check_container_name(cName))
5965 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5967 return(AD_INVALID_NAME);
5970 memset(distinguishedName, '\0', sizeof(distinguishedName));
5972 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5973 distinguishedName, beforec, before))
5976 if (strlen(distinguishedName) == 0)
5978 rc = container_create(ldap_handle, dn_path, afterc, after);
5982 strcpy(temp, after[CONTAINER_NAME]);
5985 for (i = 0; i < (int)strlen(temp); i++)
5995 container_get_dn(temp, dName);
5997 if (strlen(temp) != 0)
5998 sprintf(new_dn_path, "%s,%s", dName, dn_path);
6000 sprintf(new_dn_path, "%s", dn_path);
6002 sprintf(new_cn, "OU=%s", cName);
6004 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6006 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6007 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6009 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6010 before[CONTAINER_NAME], after[CONTAINER_NAME],
6011 ldap_err2string(rc));
6015 memset(dName, '\0', sizeof(dName));
6016 container_get_dn(after[CONTAINER_NAME], dName);
6017 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6022 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6024 char distinguishedName[256];
6027 memset(distinguishedName, '\0', sizeof(distinguishedName));
6029 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6030 distinguishedName, count, av))
6033 if (strlen(distinguishedName) == 0)
6036 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6038 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6039 container_move_objects(ldap_handle, dn_path, distinguishedName);
6041 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6042 av[CONTAINER_NAME], ldap_err2string(rc));
6048 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6050 char *attr_array[3];
6051 LK_ENTRY *group_base;
6054 char *objectClass_v[] = {"top",
6055 "organizationalUnit",
6058 char *ou_v[] = {NULL, NULL};
6059 char *name_v[] = {NULL, NULL};
6060 char *moiraId_v[] = {NULL, NULL};
6061 char *desc_v[] = {NULL, NULL};
6062 char *managedBy_v[] = {NULL, NULL};
6065 char managedByDN[256];
6072 memset(filter, '\0', sizeof(filter));
6073 memset(dName, '\0', sizeof(dName));
6074 memset(cName, '\0', sizeof(cName));
6075 memset(managedByDN, '\0', sizeof(managedByDN));
6076 container_get_dn(av[CONTAINER_NAME], dName);
6077 container_get_name(av[CONTAINER_NAME], cName);
6079 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6081 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6083 return(AD_INVALID_NAME);
6086 if (!check_container_name(cName))
6088 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6090 return(AD_INVALID_NAME);
6094 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6096 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6098 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6100 if (strlen(av[CONTAINER_ROWID]) != 0)
6102 moiraId_v[0] = av[CONTAINER_ROWID];
6103 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6106 if (strlen(av[CONTAINER_DESC]) != 0)
6108 desc_v[0] = av[CONTAINER_DESC];
6109 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6112 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6114 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6116 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6119 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6120 kerberos_ou, dn_path);
6121 managedBy_v[0] = managedByDN;
6122 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6127 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6129 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6130 "(objectClass=user)))", av[CONTAINER_ID]);
6133 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6135 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6139 if (strlen(filter) != 0)
6141 attr_array[0] = "distinguishedName";
6142 attr_array[1] = NULL;
6145 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6147 &group_base, &group_count,
6148 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6150 if (group_count == 1)
6152 strcpy(managedByDN, group_base->value);
6153 managedBy_v[0] = managedByDN;
6154 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6156 linklist_free(group_base);
6166 sprintf(temp, "%s,%s", dName, dn_path);
6167 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
6169 for (i = 0; i < n; i++)
6172 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6174 com_err(whoami, 0, "Unable to create container %s : %s",
6175 cName, ldap_err2string(rc));
6179 if (rc == LDAP_ALREADY_EXISTS)
6181 if (strlen(av[CONTAINER_ROWID]) != 0)
6182 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6188 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6189 char **before, int afterc, char **after)
6191 char distinguishedName[256];
6194 memset(distinguishedName, '\0', sizeof(distinguishedName));
6196 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6197 distinguishedName, afterc, after))
6200 if (strlen(distinguishedName) == 0)
6202 rc = container_create(ldap_handle, dn_path, afterc, after);
6206 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6207 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6213 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6214 char *distinguishedName, int count,
6217 char *attr_array[3];
6218 LK_ENTRY *group_base;
6225 memset(filter, '\0', sizeof(filter));
6226 memset(dName, '\0', sizeof(dName));
6227 memset(cName, '\0', sizeof(cName));
6228 container_get_dn(av[CONTAINER_NAME], dName);
6229 container_get_name(av[CONTAINER_NAME], cName);
6231 if (strlen(dName) == 0)
6233 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6234 av[CONTAINER_NAME]);
6235 return(AD_INVALID_NAME);
6238 if (!check_container_name(cName))
6240 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6242 return(AD_INVALID_NAME);
6245 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6246 av[CONTAINER_ROWID]);
6247 attr_array[0] = "distinguishedName";
6248 attr_array[1] = NULL;
6252 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6253 &group_base, &group_count,
6254 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6256 if (group_count == 1)
6258 strcpy(distinguishedName, group_base->value);
6261 linklist_free(group_base);
6266 if (strlen(distinguishedName) == 0)
6268 sprintf(filter, "(&(objectClass=organizationalUnit)"
6269 "(distinguishedName=%s,%s))", dName, dn_path);
6270 attr_array[0] = "distinguishedName";
6271 attr_array[1] = NULL;
6275 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6276 &group_base, &group_count,
6277 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6279 if (group_count == 1)
6281 strcpy(distinguishedName, group_base->value);
6284 linklist_free(group_base);
6293 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6294 char *distinguishedName, int count, char **av)
6296 char *attr_array[5];
6297 LK_ENTRY *group_base;
6302 char *moiraId_v[] = {NULL, NULL};
6303 char *desc_v[] = {NULL, NULL};
6304 char *managedBy_v[] = {NULL, NULL};
6305 char managedByDN[256];
6314 strcpy(ad_path, distinguishedName);
6316 if (strlen(dName) != 0)
6317 sprintf(ad_path, "%s,%s", dName, dn_path);
6319 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6322 if (strlen(av[CONTAINER_ID]) != 0)
6323 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6324 av[CONTAINER_ROWID]);
6326 attr_array[0] = "mitMoiraId";
6327 attr_array[1] = "description";
6328 attr_array[2] = "managedBy";
6329 attr_array[3] = NULL;
6333 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6334 &group_base, &group_count,
6335 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6337 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6338 av[CONTAINER_NAME], ldap_err2string(rc));
6342 memset(managedByDN, '\0', sizeof(managedByDN));
6343 memset(moiraId, '\0', sizeof(moiraId));
6344 memset(desc, '\0', sizeof(desc));
6349 if (!strcasecmp(pPtr->attribute, "description"))
6350 strcpy(desc, pPtr->value);
6351 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6352 strcpy(managedByDN, pPtr->value);
6353 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6354 strcpy(moiraId, pPtr->value);
6358 linklist_free(group_base);
6363 if (strlen(av[CONTAINER_ROWID]) != 0)
6365 moiraId_v[0] = av[CONTAINER_ROWID];
6366 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6369 if (strlen(av[CONTAINER_DESC]) != 0)
6371 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6376 if (strlen(desc) != 0)
6378 attribute_update(ldap_handle, ad_path, "", "description", dName);
6382 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6384 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6386 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6389 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6390 kerberos_ou, dn_path);
6391 managedBy_v[0] = managedByDN;
6392 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6396 if (strlen(managedByDN) != 0)
6398 attribute_update(ldap_handle, ad_path, "", "managedBy",
6405 memset(filter, '\0', sizeof(filter));
6407 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6409 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6410 "(objectClass=user)))", av[CONTAINER_ID]);
6413 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6415 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6419 if (strlen(filter) != 0)
6421 attr_array[0] = "distinguishedName";
6422 attr_array[1] = NULL;
6425 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6426 attr_array, &group_base, &group_count,
6427 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6429 if (group_count == 1)
6431 strcpy(managedByDN, group_base->value);
6432 managedBy_v[0] = managedByDN;
6433 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6437 if (strlen(managedByDN) != 0)
6439 attribute_update(ldap_handle, ad_path, "",
6440 "managedBy", dName);
6444 linklist_free(group_base);
6451 if (strlen(managedByDN) != 0)
6453 attribute_update(ldap_handle, ad_path, "", "managedBy",
6463 return(LDAP_SUCCESS);
6465 rc = ldap_modify_s(ldap_handle, ad_path, mods);
6467 for (i = 0; i < n; i++)
6470 if (rc != LDAP_SUCCESS)
6472 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6473 av[CONTAINER_NAME], ldap_err2string(rc));
6480 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6482 char *attr_array[3];
6483 LK_ENTRY *group_base;
6490 int NumberOfEntries = 10;
6494 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6496 for (i = 0; i < 3; i++)
6498 memset(filter, '\0', sizeof(filter));
6502 strcpy(filter, "(!(|(objectClass=computer)"
6503 "(objectClass=organizationalUnit)))");
6504 attr_array[0] = "cn";
6505 attr_array[1] = NULL;
6509 strcpy(filter, "(objectClass=computer)");
6510 attr_array[0] = "cn";
6511 attr_array[1] = NULL;
6515 strcpy(filter, "(objectClass=organizationalUnit)");
6516 attr_array[0] = "ou";
6517 attr_array[1] = NULL;
6522 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
6523 &group_base, &group_count,
6524 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6529 if (group_count == 0)
6536 if (!strcasecmp(pPtr->attribute, "cn"))
6538 sprintf(new_cn, "cn=%s", pPtr->value);
6540 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6542 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6547 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6549 if (rc == LDAP_ALREADY_EXISTS)
6551 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6558 else if (!strcasecmp(pPtr->attribute, "ou"))
6560 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6566 linklist_free(group_base);
6575 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6576 char *machine_ou, char *NewMachineName)
6578 LK_ENTRY *group_base;
6582 char *attr_array[3];
6589 strcpy(NewMachineName, member);
6590 rc = moira_connect();
6591 rc = GetMachineName(NewMachineName);
6594 if (strlen(NewMachineName) == 0)
6596 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6602 pPtr = strchr(NewMachineName, '.');
6609 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
6610 attr_array[0] = "cn";
6611 attr_array[1] = NULL;
6612 sprintf(temp, "%s", dn_path);
6614 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
6615 &group_base, &group_count,
6616 LDAP_SCOPE_SUBTREE)) != 0)
6618 com_err(whoami, 0, "Unable to process machine %s : %s",
6619 member, ldap_err2string(rc));
6623 if (group_count != 1)
6626 "Unable to process machine %s : machine not found in AD",
6631 strcpy(dn, group_base->dn);
6632 strcpy(cn, group_base->value);
6634 for (i = 0; i < (int)strlen(dn); i++)
6635 dn[i] = tolower(dn[i]);
6637 for (i = 0; i < (int)strlen(cn); i++)
6638 cn[i] = tolower(cn[i]);
6640 linklist_free(group_base);
6642 pPtr = strstr(dn, cn);
6646 com_err(whoami, 0, "Unable to process machine %s",
6651 pPtr += strlen(cn) + 1;
6652 strcpy(machine_ou, pPtr);
6654 pPtr = strstr(machine_ou, "dc=");
6658 com_err(whoami, 0, "Unable to process machine %s",
6669 int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6670 char *MoiraMachineName, char *DestinationOu)
6674 char MachineName[128];
6676 char *attr_array[3];
6681 LK_ENTRY *group_base;
6686 strcpy(MachineName, MoiraMachineName);
6687 rc = GetMachineName(MachineName);
6689 if (strlen(MachineName) == 0)
6691 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6696 cPtr = strchr(MachineName, '.');
6701 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6702 attr_array[0] = "sAMAccountName";
6703 attr_array[1] = NULL;
6705 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6707 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
6709 com_err(whoami, 0, "Unable to process machine %s : %s",
6710 MoiraMachineName, ldap_err2string(rc));
6714 if (group_count == 1)
6715 strcpy(OldDn, group_base->dn);
6717 linklist_free(group_base);
6720 if (group_count != 1)
6722 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6727 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6728 cPtr = strchr(OldDn, ',');
6733 if (!strcasecmp(cPtr, NewOu))
6737 sprintf(NewCn, "CN=%s", MachineName);
6738 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6743 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6749 memset(Name, '\0', sizeof(Name));
6750 strcpy(Name, machine_name);
6752 pPtr = strchr(Name, '.');
6758 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
6761 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6762 char *machine_name, char *container_name)
6768 av[0] = machine_name;
6769 call_args[0] = (char *)container_name;
6770 rc = mr_query("get_machine_to_container_map", 1, av,
6771 machine_GetMoiraContainer, call_args);
6775 int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6780 strcpy(call_args[0], av[1]);
6784 int Moira_container_group_create(char **after)
6790 memset(GroupName, '\0', sizeof(GroupName));
6791 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6792 after[CONTAINER_ROWID]);
6796 argv[L_NAME] = GroupName;
6797 argv[L_ACTIVE] = "1";
6798 argv[L_PUBLIC] = "0";
6799 argv[L_HIDDEN] = "0";
6800 argv[L_MAILLIST] = "0";
6801 argv[L_GROUP] = "1";
6802 argv[L_GID] = UNIQUE_GID;
6803 argv[L_NFSGROUP] = "0";
6804 argv[L_MAILMAN] = "0";
6805 argv[L_MAILMAN_SERVER] = "[NONE]";
6806 argv[L_DESC] = "auto created container group";
6807 argv[L_ACE_TYPE] = "USER";
6808 argv[L_MEMACE_TYPE] = "USER";
6809 argv[L_ACE_NAME] = "sms";
6810 argv[L_MEMACE_NAME] = "sms";
6812 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
6815 "Unable to create container group %s for container %s: %s",
6816 GroupName, after[CONTAINER_NAME], error_message(rc));
6819 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6820 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6825 int Moira_container_group_update(char **before, char **after)
6828 char BeforeGroupName[64];
6829 char AfterGroupName[64];
6832 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6835 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6836 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6837 if (strlen(BeforeGroupName) == 0)
6840 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6841 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6842 after[CONTAINER_ROWID]);
6846 if (strcasecmp(BeforeGroupName, AfterGroupName))
6848 argv[L_NAME] = BeforeGroupName;
6849 argv[L_NAME + 1] = AfterGroupName;
6850 argv[L_ACTIVE + 1] = "1";
6851 argv[L_PUBLIC + 1] = "0";
6852 argv[L_HIDDEN + 1] = "0";
6853 argv[L_MAILLIST + 1] = "0";
6854 argv[L_GROUP + 1] = "1";
6855 argv[L_GID + 1] = UNIQUE_GID;
6856 argv[L_NFSGROUP + 1] = "0";
6857 argv[L_MAILMAN + 1] = "0";
6858 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
6859 argv[L_DESC + 1] = "auto created container group";
6860 argv[L_ACE_TYPE + 1] = "USER";
6861 argv[L_MEMACE_TYPE + 1] = "USER";
6862 argv[L_ACE_NAME + 1] = "sms";
6863 argv[L_MEMACE_NAME + 1] = "sms";
6865 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
6868 "Unable to rename container group from %s to %s: %s",
6869 BeforeGroupName, AfterGroupName, error_message(rc));
6876 int Moira_container_group_delete(char **before)
6881 char ParentGroupName[64];
6883 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6884 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6886 memset(GroupName, '\0', sizeof(GroupName));
6888 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6889 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6891 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6893 argv[0] = ParentGroupName;
6895 argv[2] = GroupName;
6897 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6900 "Unable to delete container group %s from list: %s",
6901 GroupName, ParentGroupName, error_message(rc));
6905 if (strlen(GroupName) != 0)
6907 argv[0] = GroupName;
6909 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6911 com_err(whoami, 0, "Unable to delete container group %s : %s",
6912 GroupName, error_message(rc));
6919 int Moira_groupname_create(char *GroupName, char *ContainerName,
6920 char *ContainerRowID)
6925 char newGroupName[64];
6926 char tempGroupName[64];
6932 strcpy(temp, ContainerName);
6934 ptr1 = strrchr(temp, '/');
6940 ptr1 = strrchr(temp, '/');
6944 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6947 strcpy(tempgname, ptr);
6950 strcpy(tempgname, temp);
6952 if (strlen(tempgname) > 25)
6953 tempgname[25] ='\0';
6955 sprintf(newGroupName, "cnt-%s", tempgname);
6957 /* change everything to lower case */
6963 *ptr = tolower(*ptr);
6971 strcpy(tempGroupName, newGroupName);
6974 /* append 0-9 then a-z if a duplicate is found */
6977 argv[0] = newGroupName;
6979 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6981 if (rc == MR_NO_MATCH)
6983 com_err(whoami, 0, "Moira error while creating group name for "
6984 "container %s : %s", ContainerName, error_message(rc));
6988 sprintf(newGroupName, "%s-%c", tempGroupName, i);
6992 com_err(whoami, 0, "Unable to find a unique group name for "
6993 "container %s: too many duplicate container names",
7004 strcpy(GroupName, newGroupName);
7008 int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7013 argv[0] = origContainerName;
7014 argv[1] = GroupName;
7016 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7019 "Unable to set container group %s in container %s: %s",
7020 GroupName, origContainerName, error_message(rc));
7026 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7028 char ContainerName[64];
7029 char ParentGroupName[64];
7033 strcpy(ContainerName, origContainerName);
7035 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7037 /* top-level container */
7038 if (strlen(ParentGroupName) == 0)
7041 argv[0] = ParentGroupName;
7043 argv[2] = GroupName;
7045 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7048 "Unable to add container group %s to parent group %s: %s",
7049 GroupName, ParentGroupName, error_message(rc));
7055 int Moira_getContainerGroup(int ac, char **av, void *ptr)
7060 strcpy(call_args[0], av[1]);
7065 int Moira_getGroupName(char *origContainerName, char *GroupName,
7068 char ContainerName[64];
7074 strcpy(ContainerName, origContainerName);
7078 ptr = strrchr(ContainerName, '/');
7086 argv[0] = ContainerName;
7088 call_args[0] = GroupName;
7089 call_args[1] = NULL;
7091 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7094 if (strlen(GroupName) != 0)
7099 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7100 ContainerName, error_message(rc));
7102 com_err(whoami, 0, "Unable to get container group from container %s",
7108 int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7114 if (strcmp(GroupName, "[none]") == 0)
7117 argv[0] = GroupName;
7118 argv[1] = "MACHINE";
7119 argv[2] = MachineName;
7122 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7124 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7128 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7129 MachineName, GroupName, error_message(rc));
7135 int GetMachineName(char *MachineName)
7138 char NewMachineName[1024];
7145 // If the address happens to be in the top-level MIT domain, great!
7146 strcpy(NewMachineName, MachineName);
7148 for (i = 0; i < (int)strlen(NewMachineName); i++)
7149 NewMachineName[i] = toupper(NewMachineName[i]);
7151 szDot = strchr(NewMachineName,'.');
7153 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7158 // If not, see if it has a Moira alias in the top-level MIT domain.
7159 memset(NewMachineName, '\0', sizeof(NewMachineName));
7161 args[1] = MachineName;
7162 call_args[0] = NewMachineName;
7163 call_args[1] = NULL;
7165 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7167 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7168 MachineName, error_message(rc));
7169 strcpy(MachineName, "");
7173 if (strlen(NewMachineName) != 0)
7174 strcpy(MachineName, NewMachineName);
7176 strcpy(MachineName, "");
7181 int ProcessMachineName(int ac, char **av, void *ptr)
7184 char MachineName[1024];
7190 if (strlen(call_args[0]) == 0)
7192 strcpy(MachineName, av[0]);
7194 for (i = 0; i < (int)strlen(MachineName); i++)
7195 MachineName[i] = toupper(MachineName[i]);
7197 szDot = strchr(MachineName,'.');
7199 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
7201 strcpy(call_args[0], MachineName);
7208 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7214 for (i = 0; i < n; i++)
7216 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7217 mods[i]->mod_type = "uidNumber";
7224 for (i = 0; i < n; i++)
7226 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7227 mods[i]->mod_type = "msSFU30UidNumber";
7234 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7235 char *DistinguishedName,
7236 char *WinHomeDir, char *WinProfileDir,
7237 char **homedir_v, char **winProfile_v,
7238 char **drives_v, LDAPMod **mods,
7246 char winProfile[1024];
7251 LDAPMod *DelMods[20];
7253 memset(homeDrive, '\0', sizeof(homeDrive));
7254 memset(path, '\0', sizeof(path));
7255 memset(winPath, '\0', sizeof(winPath));
7256 memset(winProfile, '\0', sizeof(winProfile));
7259 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7260 (!strcasecmp(WinProfileDir, "[afs]")))
7262 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
7264 memset(cWeight, 0, sizeof(cWeight));
7265 memset(cPath, 0, sizeof(cPath));
7269 while (hp[i] != NULL)
7271 if (sscanf(hp[i], "%*s %s", cPath))
7273 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
7275 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
7277 if (atoi(cWeight) < last_weight)
7279 strcpy(path, cPath);
7280 last_weight = (int)atoi(cWeight);
7284 strcpy(path, cPath);
7292 if (!strnicmp(path, AFS, strlen(AFS)))
7294 AfsToWinAfs(path, winPath);
7295 strcpy(winProfile, winPath);
7296 strcat(winProfile, "\\.winprofile");
7304 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7305 (!strcasecmp(WinProfileDir, "[dfs]")))
7307 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7308 user_name[0], user_name);
7310 if (!strcasecmp(WinProfileDir, "[dfs]"))
7312 strcpy(winProfile, path);
7313 strcat(winProfile, "\\.winprofile");
7316 if (!strcasecmp(WinHomeDir, "[dfs]"))
7317 strcpy(winPath, path);
7330 if (!strcasecmp(WinHomeDir, "[local]"))
7331 memset(winPath, '\0', sizeof(winPath));
7332 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7333 !strcasecmp(WinHomeDir, "[dfs]"))
7335 strcpy(homeDrive, "H:");
7339 strcpy(winPath, WinHomeDir);
7340 if (!strncmp(WinHomeDir, "\\\\", 2))
7342 strcpy(homeDrive, "H:");
7346 // nothing needs to be done if WinProfileDir is [afs].
7347 if (!strcasecmp(WinProfileDir, "[local]"))
7348 memset(winProfile, '\0', sizeof(winProfile));
7349 else if (strcasecmp(WinProfileDir, "[afs]") &&
7350 strcasecmp(WinProfileDir, "[dfs]"))
7352 strcpy(winProfile, WinProfileDir);
7355 if (strlen(winProfile) != 0)
7357 if (winProfile[strlen(winProfile) - 1] == '\\')
7358 winProfile[strlen(winProfile) - 1] = '\0';
7361 if (strlen(winPath) != 0)
7363 if (winPath[strlen(winPath) - 1] == '\\')
7364 winPath[strlen(winPath) - 1] = '\0';
7367 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
7368 strcat(winProfile, "\\");
7370 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7371 strcat(winPath, "\\");
7373 if (strlen(winPath) == 0)
7375 if (OpType == LDAP_MOD_REPLACE)
7378 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7380 //unset homeDirectory attribute for user.
7381 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7387 homedir_v[0] = strdup(winPath);
7388 ADD_ATTR("homeDirectory", homedir_v, OpType);
7391 if (strlen(winProfile) == 0)
7393 if (OpType == LDAP_MOD_REPLACE)
7396 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7398 //unset profilePate attribute for user.
7399 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7405 winProfile_v[0] = strdup(winProfile);
7406 ADD_ATTR("profilePath", winProfile_v, OpType);
7409 if (strlen(homeDrive) == 0)
7411 if (OpType == LDAP_MOD_REPLACE)
7414 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7416 //unset homeDrive attribute for user
7417 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7423 drives_v[0] = strdup(homeDrive);
7424 ADD_ATTR("homeDrive", drives_v, OpType);
7430 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
7431 char *attribute_value, char *attribute, char *user_name)
7433 char *mod_v[] = {NULL, NULL};
7434 LDAPMod *DelMods[20];
7440 if (strlen(attribute_value) == 0)
7443 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7445 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7451 mod_v[0] = attribute_value;
7452 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7455 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7456 mods)) != LDAP_SUCCESS)
7460 mod_v[0] = attribute_value;
7461 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7464 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7465 mods)) != LDAP_SUCCESS)
7467 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7469 attribute, user_name, ldap_err2string(rc));
7479 void StringTrim(char *StringToTrim)
7484 save = strdup(StringToTrim);
7491 /* skip to end of string */
7496 strcpy(StringToTrim, save);
7500 for (t = s; *t; t++)
7516 strcpy(StringToTrim, s);
7520 int ReadConfigFile(char *DomainName)
7531 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
7533 if ((fptr = fopen(temp, "r")) != NULL)
7535 while (fgets(temp, sizeof(temp), fptr) != 0)
7537 for (i = 0; i < (int)strlen(temp); i++)
7538 temp[i] = toupper(temp[i]);
7540 if (temp[strlen(temp) - 1] == '\n')
7541 temp[strlen(temp) - 1] = '\0';
7545 if (strlen(temp) == 0)
7548 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7550 if (strlen(temp) > (strlen(DOMAIN)))
7552 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7553 StringTrim(ldap_domain);
7556 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
7558 if (strlen(temp) > (strlen(PRINCIPALNAME)))
7560 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7561 StringTrim(PrincipalName);
7564 else if (!strncmp(temp, SERVER, strlen(SERVER)))
7566 if (strlen(temp) > (strlen(SERVER)))
7568 ServerList[Count] = calloc(1, 256);
7569 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7570 StringTrim(ServerList[Count]);
7574 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
7576 if (strlen(temp) > (strlen(MSSFU)))
7578 strcpy(temp1, &temp[strlen(MSSFU)]);
7580 if (!strcmp(temp1, SFUTYPE))
7584 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7586 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7588 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7590 if (!strcasecmp(temp1, "NO"))
7593 memset(group_suffix, '\0', sizeof(group_suffix));
7597 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7599 if (strlen(temp) > (strlen(GROUP_TYPE)))
7601 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7603 if (!strcasecmp(temp1, "UNIVERSAL"))
7604 UseGroupUniversal = 1;
7607 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7609 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7611 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7613 if (!strcasecmp(temp1, "NO"))
7617 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7619 if (strlen(temp) > (strlen(SET_PASSWORD)))
7621 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7623 if (!strcasecmp(temp1, "NO"))
7627 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7629 if (strlen(temp) > (strlen(EXCHANGE)))
7631 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7633 if (!strcasecmp(temp1, "YES"))
7637 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7638 strlen(PROCESS_MACHINE_CONTAINER)))
7640 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7642 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7644 if (!strcasecmp(temp1, "NO"))
7645 ProcessMachineContainer = 0;
7650 if (strlen(ldap_domain) != 0)
7652 memset(ldap_domain, '\0', sizeof(ldap_domain));
7656 if (strlen(temp) != 0)
7657 strcpy(ldap_domain, temp);
7663 if (strlen(ldap_domain) == 0)
7665 strcpy(ldap_domain, DomainName);
7671 for (i = 0; i < Count; i++)
7673 if (ServerList[i] != 0)
7675 strcat(ServerList[i], ".");
7676 strcat(ServerList[i], ldap_domain);
7677 for (k = 0; k < (int)strlen(ServerList[i]); k++)
7678 ServerList[i][k] = toupper(ServerList[i][k]);
7685 int ReadDomainList()
7692 unsigned char c[11];
7693 unsigned char stuff[256];
7698 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
7700 if ((fptr = fopen(temp, "r")) != NULL)
7702 while (fgets(temp, sizeof(temp), fptr) != 0)
7704 for (i = 0; i < (int)strlen(temp); i++)
7705 temp[i] = toupper(temp[i]);
7707 if (temp[strlen(temp) - 1] == '\n')
7708 temp[strlen(temp) - 1] = '\0';
7712 if (strlen(temp) == 0)
7715 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7717 if (strlen(temp) > (strlen(DOMAIN)))
7719 strcpy(temp1, &temp[strlen(DOMAIN)]);
7721 strcpy(temp, temp1);
7725 strcpy(DomainNames[Count], temp);
7726 StringTrim(DomainNames[Count]);
7735 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7736 "configuration error in winad.cfg");
7743 int email_isvalid(const char *address) {
7745 const char *c, *domain;
7746 static char *rfc822_specials = "()<>@,;:\\\"[]";
7748 if(address[strlen(address) - 1] == '.')
7751 /* first we validate the name portion (name@domain) */
7752 for (c = address; *c; c++) {
7753 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7758 if (*c == '\\' && (*++c == ' '))
7760 if (*c <= ' ' || *c >= 127)
7775 if (*c <= ' ' || *c >= 127)
7777 if (strchr(rfc822_specials, *c))
7781 if (c == address || *(c - 1) == '.')
7784 /* next we validate the domain portion (name@domain) */
7785 if (!*(domain = ++c)) return 0;
7788 if (c == domain || *(c - 1) == '.')
7792 if (*c <= ' ' || *c >= 127)
7794 if (strchr(rfc822_specials, *c))
7798 return (count >= 1);
7801 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7802 char **homeServerName)
7804 LK_ENTRY *group_base;
7805 LK_ENTRY *sub_group_base;
7809 int sub_group_count;
7811 char sub_filter[1024];
7812 char search_path[1024];
7814 char *attr_array[3];
7816 int homeMDB_count = -1;
7820 int rangeStep = 1500;
7822 int rangeHigh = rangeLow + (rangeStep - 1);
7825 /* Grumble..... microsoft not making it searchable from the root *grr* */
7827 memset(filter, '\0', sizeof(filter));
7828 memset(search_path, '\0', sizeof(search_path));
7830 sprintf(filter, "(objectClass=msExchMDB)");
7831 sprintf(search_path, "CN=Configuration,%s", dn_path);
7832 attr_array[0] = "distinguishedName";
7833 attr_array[1] = NULL;
7838 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7839 &group_base, &group_count,
7840 LDAP_SCOPE_SUBTREE)) != 0)
7842 com_err(whoami, 0, "Unable to find msExchMDB %s",
7843 ldap_err2string(rc));
7852 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
7853 ((s = strstr(gPtr->dn, "Recovery")) != (char *) NULL))
7860 * Due to limits in active directory we need to use the LDAP
7861 * range semantics to query and return all the values in
7862 * large lists, we will stop increasing the range when
7863 * the result count is 0.
7871 memset(sub_filter, '\0', sizeof(sub_filter));
7872 memset(range, '\0', sizeof(range));
7873 sprintf(sub_filter, "(objectClass=msExchMDB)");
7876 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
7878 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
7880 attr_array[0] = range;
7881 attr_array[1] = NULL;
7883 sub_group_base = NULL;
7884 sub_group_count = 0;
7886 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
7887 attr_array, &sub_group_base,
7889 LDAP_SCOPE_SUBTREE)) != 0)
7891 com_err(whoami, 0, "Unable to find homeMDBBL %s",
7892 ldap_err2string(rc));
7896 if(!sub_group_count)
7902 rangeHigh = rangeLow + (rangeStep - 1);
7909 mdbbl_count += sub_group_count;
7910 rangeLow = rangeHigh + 1;
7911 rangeHigh = rangeLow + (rangeStep - 1);
7914 /* First time through, need to initialize or update the least used */
7916 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
7919 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
7921 homeMDB_count = mdbbl_count;
7922 *homeMDB = strdup(gPtr->dn);
7926 linklist_free(sub_group_base);
7930 linklist_free(group_base);
7933 * Ok found the server least allocated need to now query to get its
7934 * msExchHomeServerName so we can set it as a user attribute
7937 attr_array[0] = "legacyExchangeDN";
7938 attr_array[1] = NULL;
7943 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
7944 attr_array, &group_base,
7946 LDAP_SCOPE_SUBTREE)) != 0)
7948 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
7949 ldap_err2string(rc));
7955 *homeServerName = strdup(group_base->value);
7956 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
7962 linklist_free(group_base);
7967 char *lowercase(char *s)
7971 for (p = s; *p; p++)
7979 char *uppercase(char *s)
7983 for (p = s; *p; p++)
7991 int save_query_info(int argc, char **argv, void *hint)
7994 char **nargv = hint;
7996 for(i = 0; i < argc; i++)
7997 nargv[i] = strdup(argv[i]);