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 *reportToOriginator_v[] = {NULL, NULL};
2344 char *address_book_v[] = {NULL, NULL};
2345 char *legacy_exchange_dn_v[] = {NULL, NULL};
2346 u_int groupTypeControl;
2347 char groupTypeControlStr[80];
2348 char contact_mail[256];
2352 LK_ENTRY *group_base;
2354 int MailDisabled = 0;
2356 if(UseGroupUniversal)
2357 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2359 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2361 if (!check_string(before_group_name))
2364 "Unable to process invalid LDAP list name %s",
2366 return(AD_INVALID_NAME);
2369 if (!check_string(after_group_name))
2372 "Unable to process invalid LDAP list name %s", after_group_name);
2373 return(AD_INVALID_NAME);
2383 sprintf(filter, "(&(objectClass=user)(cn=%s))", after_group_name);
2384 attr_array[0] = "cn";
2385 attr_array[1] = NULL;
2387 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2388 &group_base, &group_count,
2389 LDAP_SCOPE_SUBTREE)) != 0)
2391 com_err(whoami, 0, "Unable to process group %s : %s",
2392 after_group_name, ldap_err2string(rc));
2398 com_err(whoami, 0, "Object already exists with name %s",
2403 linklist_free(group_base);
2412 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
2413 before_group_membership,
2414 MoiraId, "distinguishedName", &group_base,
2415 &group_count, filter))
2418 if (group_count == 0)
2420 return(AD_NO_GROUPS_FOUND);
2423 if (group_count != 1)
2425 com_err(whoami, 0, "Unable to process multiple groups with "
2426 "MoiraId = %s exist in the AD", MoiraId);
2427 return(AD_MULTIPLE_GROUPS_FOUND);
2430 strcpy(old_dn, group_base->value);
2432 linklist_free(group_base);
2435 attr_array[0] = "sAMAccountName";
2436 attr_array[1] = NULL;
2438 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2439 &group_base, &group_count,
2440 LDAP_SCOPE_SUBTREE)) != 0)
2442 com_err(whoami, 0, "Unable to get list %s dn : %s",
2443 after_group_name, ldap_err2string(rc));
2447 if (group_count != 1)
2450 "Unable to get sAMAccountName for group %s",
2452 return(AD_LDAP_FAILURE);
2455 strcpy(sam_name, group_base->value);
2456 linklist_free(group_base);
2460 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2461 sprintf(new_dn, "cn=%s", after_group_name);
2462 sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain));
2463 sprintf(contact_mail, "%s@mit.edu", after_group_name);
2464 sprintf(proxy_address, "SMTP:%s@%s", after_group_name,
2465 lowercase(ldap_domain));
2466 sprintf(mail_nickname, "%s", after_group_name);
2468 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
2469 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2471 com_err(whoami, 0, "Unable to rename list from %s to %s : %s",
2472 before_group_name, after_group_name, ldap_err2string(rc));
2476 name_v[0] = after_group_name;
2478 if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)],
2479 group_suffix, strlen(group_suffix)))
2481 sprintf(sam_name, "%s%s", after_group_name, group_suffix);
2486 "Unable to rename list from %s to %s : sAMAccountName not found",
2487 before_group_name, after_group_name);
2491 samAccountName_v[0] = sam_name;
2493 if (after_security_flag)
2494 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2496 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2497 groupTypeControl_v[0] = groupTypeControlStr;
2498 mitMoiraId_v[0] = MoiraId;
2500 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
2501 rc = attribute_update(ldap_handle, new_dn, after_desc, "description",
2504 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
2505 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
2506 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2507 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
2511 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2513 mail_nickname_v[0] = mail_nickname;
2514 proxy_address_v[0] = proxy_address;
2516 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2517 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2518 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2522 mail_nickname_v[0] = NULL;
2523 proxy_address_v[0] = NULL;
2525 legacy_exchange_dn_v[0] = NULL;
2526 address_book_v[0] = NULL;
2528 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2529 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2530 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2531 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2532 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2537 if(atoi(maillist) && email_isvalid(contact_mail))
2539 mail_v[0] = contact_mail;
2540 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2546 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2549 "Unable to modify list data for %s after renaming: %s",
2550 after_group_name, ldap_err2string(rc));
2553 for (i = 0; i < n; i++)
2559 int group_create(int ac, char **av, void *ptr)
2564 char new_group_name[256];
2565 char sam_group_name[256];
2566 char cn_group_name[256];
2568 char contact_mail[256];
2569 char mail_nickname[256];
2570 char proxy_address[256];
2571 char address_book[256];
2572 char *cn_v[] = {NULL, NULL};
2573 char *objectClass_v[] = {"top", "group", NULL};
2575 char *samAccountName_v[] = {NULL, NULL};
2576 char *altSecurityIdentities_v[] = {NULL, NULL};
2577 char *member_v[] = {NULL, NULL};
2578 char *name_v[] = {NULL, NULL};
2579 char *desc_v[] = {NULL, NULL};
2580 char *info_v[] = {NULL, NULL};
2581 char *mitMoiraId_v[] = {NULL, NULL};
2582 char *groupTypeControl_v[] = {NULL, NULL};
2583 char *mail_v[] = {NULL, NULL};
2584 char *proxy_address_v[] = {NULL, NULL};
2585 char *mail_nickname_v[] = {NULL, NULL};
2586 char *reportToOriginator_v[] = {NULL, NULL};
2587 char *address_book_v[] = {NULL, NULL};
2588 char *legacy_exchange_dn_v[] = {NULL, NULL};
2589 char groupTypeControlStr[80];
2590 char group_membership[1];
2593 u_int groupTypeControl;
2597 int MailDisabled = 0;
2599 LK_ENTRY *group_base;
2602 char *attr_array[3];
2606 if(UseGroupUniversal)
2607 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2609 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2611 if (!check_string(av[L_NAME]))
2613 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2615 return(AD_INVALID_NAME);
2618 updateGroup = (int)call_args[4];
2619 memset(group_ou, 0, sizeof(group_ou));
2620 memset(group_membership, 0, sizeof(group_membership));
2623 get_group_membership(group_membership, group_ou, &security_flag, av);
2625 strcpy(new_group_name, av[L_NAME]);
2626 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2627 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2628 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2629 sprintf(mail_nickname, "%s", av[L_NAME]);
2632 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2634 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2638 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2639 groupTypeControl_v[0] = groupTypeControlStr;
2641 strcpy(cn_group_name, av[L_NAME]);
2643 samAccountName_v[0] = sam_group_name;
2644 name_v[0] = new_group_name;
2645 cn_v[0] = new_group_name;
2648 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2649 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2650 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2651 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2652 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2656 if(atoi(av[L_MAILLIST]))
2661 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2662 attr_array[0] = "cn";
2663 attr_array[1] = NULL;
2665 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2666 filter, attr_array, &group_base,
2668 LDAP_SCOPE_SUBTREE)) != 0)
2670 com_err(whoami, 0, "Unable to process group %s : %s",
2671 av[L_NAME], ldap_err2string(rc));
2677 com_err(whoami, 0, "Object already exists with name %s",
2682 linklist_free(group_base);
2687 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2689 mail_nickname_v[0] = mail_nickname;
2690 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2695 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2697 mail_v[0] = contact_mail;
2698 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2702 if (strlen(av[L_DESC]) != 0)
2704 desc_v[0] = av[L_DESC];
2705 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2708 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2710 if (strlen(av[L_ACE_NAME]) != 0)
2712 sprintf(info, "The Administrator of this list is: %s",
2715 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2718 if (strlen(call_args[5]) != 0)
2720 mitMoiraId_v[0] = call_args[5];
2721 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2726 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2728 for (i = 0; i < n; i++)
2731 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2733 com_err(whoami, 0, "Unable to create list %s in AD : %s",
2734 av[L_NAME], ldap_err2string(rc));
2740 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2742 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2743 "description", av[L_NAME]);
2744 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2745 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2749 if (strlen(call_args[5]) != 0)
2751 mitMoiraId_v[0] = call_args[5];
2752 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2755 if (!(atoi(av[L_ACTIVE])))
2758 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2763 if(atoi(av[L_MAILLIST]))
2768 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2769 attr_array[0] = "cn";
2770 attr_array[1] = NULL;
2772 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2773 filter, attr_array, &group_base,
2775 LDAP_SCOPE_SUBTREE)) != 0)
2777 com_err(whoami, 0, "Unable to process group %s : %s",
2778 av[L_NAME], ldap_err2string(rc));
2784 com_err(whoami, 0, "Object already exists with name %s",
2789 linklist_free(group_base);
2794 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2796 mail_nickname_v[0] = mail_nickname;
2797 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2802 mail_nickname_v[0] = NULL;
2803 proxy_address_v[0] = NULL;
2804 legacy_exchange_dn_v[0] = NULL;
2805 address_book_v[0] = NULL;
2807 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2808 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2809 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2810 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2812 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2817 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2819 mail_v[0] = contact_mail;
2820 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2825 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2834 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2836 for (i = 0; i < n; i++)
2839 if (rc != LDAP_SUCCESS)
2841 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2842 av[L_NAME], ldap_err2string(rc));
2849 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2850 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2852 return(LDAP_SUCCESS);
2855 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2856 char *TargetGroupName, int HiddenGroup,
2857 char *AceType, char *AceName)
2859 char filter_exp[1024];
2860 char *attr_array[5];
2861 char search_path[512];
2863 char TemplateDn[512];
2864 char TemplateSamName[128];
2866 char TargetSamName[128];
2867 char AceSamAccountName[128];
2869 unsigned char AceSid[128];
2870 unsigned char UserTemplateSid[128];
2871 char acBERBuf[N_SD_BER_BYTES];
2872 char GroupSecurityTemplate[256];
2873 char hide_addres_lists[256];
2874 char address_book[256];
2875 char *hide_address_lists_v[] = {NULL, NULL};
2876 char *address_book_v[] = {NULL, NULL};
2878 int UserTemplateSidCount;
2885 int array_count = 0;
2887 LK_ENTRY *group_base;
2888 LDAP_BERVAL **ppsValues;
2889 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2890 { N_SD_BER_BYTES, acBERBuf },
2893 LDAPControl *apsServerControls[] = {&sControl, NULL};
2896 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
2897 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
2898 BEREncodeSecurityBits(dwInfo, acBERBuf);
2900 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
2901 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
2902 attr_array[0] = "sAMAccountName";
2903 attr_array[1] = NULL;
2907 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2908 &group_base, &group_count,
2909 LDAP_SCOPE_SUBTREE) != 0))
2912 if (group_count != 1)
2914 linklist_free(group_base);
2918 strcpy(TargetDn, group_base->dn);
2919 strcpy(TargetSamName, group_base->value);
2920 linklist_free(group_base);
2924 UserTemplateSidCount = 0;
2925 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2926 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2927 memset(AceSid, '\0', sizeof(AceSid));
2932 if (strlen(AceName) != 0)
2934 if (!strcmp(AceType, "LIST"))
2936 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
2937 strcpy(root_ou, group_ou_root);
2939 else if (!strcmp(AceType, "USER"))
2941 sprintf(AceSamAccountName, "%s", AceName);
2942 strcpy(root_ou, user_ou);
2945 if (strlen(AceSamAccountName) != 0)
2947 sprintf(search_path, "%s", dn_path);
2948 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2949 attr_array[0] = "objectSid";
2950 attr_array[1] = NULL;
2954 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2955 attr_array, &group_base, &group_count,
2956 LDAP_SCOPE_SUBTREE) != 0))
2958 if (group_count == 1)
2960 strcpy(AceDn, group_base->dn);
2961 AceSidCount = group_base->length;
2962 memcpy(AceSid, group_base->value, AceSidCount);
2964 linklist_free(group_base);
2970 if (AceSidCount == 0)
2972 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
2973 "have an AD SID.", TargetGroupName, AceName, AceType);
2974 com_err(whoami, 0, " Non-admin security group template will be used.");
2978 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2979 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
2980 attr_array[0] = "objectSid";
2981 attr_array[1] = NULL;
2986 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2987 attr_array, &group_base, &group_count,
2988 LDAP_SCOPE_SUBTREE) != 0))
2991 if ((rc != 0) || (group_count != 1))
2993 com_err(whoami, 0, "Unable to process user security template: %s",
2999 UserTemplateSidCount = group_base->length;
3000 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3002 linklist_free(group_base);
3009 if (AceSidCount == 0)
3011 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3012 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3016 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3017 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3022 if (AceSidCount == 0)
3024 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3025 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3029 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
3030 sprintf(filter_exp, "(sAMAccountName=%s)",
3031 NOT_HIDDEN_GROUP_WITH_ADMIN);
3035 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3036 attr_array[0] = "sAMAccountName";
3037 attr_array[1] = NULL;
3041 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
3042 &group_base, &group_count,
3043 LDAP_SCOPE_SUBTREE) != 0))
3046 if (group_count != 1)
3048 linklist_free(group_base);
3049 com_err(whoami, 0, "Unable to process group security template: %s - "
3050 "security not set", GroupSecurityTemplate);
3054 strcpy(TemplateDn, group_base->dn);
3055 strcpy(TemplateSamName, group_base->value);
3056 linklist_free(group_base);
3060 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3061 rc = ldap_search_ext_s(ldap_handle,
3073 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3075 com_err(whoami, 0, "Unable to find group security template: %s - "
3076 "security not set", GroupSecurityTemplate);
3080 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3082 if (ppsValues == NULL)
3084 com_err(whoami, 0, "Unable to find group security descriptor for group "
3085 "%s - security not set", GroupSecurityTemplate);
3089 if (AceSidCount != 0)
3091 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3094 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3096 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3097 UserTemplateSidCount))
3099 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3107 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3108 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3114 hide_address_lists_v[0] = "TRUE";
3115 address_book_v[0] = NULL;
3116 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3118 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3120 hide_address_lists_v[0] = NULL;
3121 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3128 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3130 for (i = 0; i < n; i++)
3133 ldap_value_free_len(ppsValues);
3134 ldap_msgfree(psMsg);
3136 if (rc != LDAP_SUCCESS)
3138 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3139 TargetGroupName, ldap_err2string(rc));
3141 if (AceSidCount != 0)
3144 "Trying to set security for group %s without admin.",
3147 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3148 HiddenGroup, "", ""))
3150 com_err(whoami, 0, "Unable to set security for group %s.",
3161 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3162 char *group_membership, char *MoiraId)
3164 LK_ENTRY *group_base;
3170 if (!check_string(group_name))
3173 "Unable to process invalid LDAP list name %s", group_name);
3174 return(AD_INVALID_NAME);
3177 memset(filter, '\0', sizeof(filter));
3180 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3182 if (rc = ad_get_group(ldap_handle, temp, group_name,
3183 group_membership, MoiraId,
3184 "distinguishedName", &group_base,
3185 &group_count, filter))
3188 if (group_count == 1)
3190 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
3192 linklist_free(group_base);
3193 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3194 group_name, ldap_err2string(rc));
3197 linklist_free(group_base);
3201 linklist_free(group_base);
3202 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
3203 return(AD_NO_GROUPS_FOUND);
3209 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3215 return(N_SD_BER_BYTES);
3218 int process_lists(int ac, char **av, void *ptr)
3223 char group_membership[2];
3229 memset(group_ou, '\0', sizeof(group_ou));
3230 memset(group_membership, '\0', sizeof(group_membership));
3231 get_group_membership(group_membership, group_ou, &security_flag, av);
3232 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
3233 group_ou, group_membership, call_args[2],
3234 (char *)call_args[3], "");
3238 int member_list_build(int ac, char **av, void *ptr)
3246 strcpy(temp, av[ACE_NAME]);
3248 if (!check_string(temp))
3251 if (!strcmp(av[ACE_TYPE], "USER"))
3253 if (!((int)call_args[3] & MOIRA_USERS))
3256 else if (!strcmp(av[ACE_TYPE], "STRING"))
3260 if((s = strchr(temp, '@')) == (char *) NULL)
3262 strcat(temp, "@mit.edu");
3265 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3267 s = strrchr(temp, '.');
3269 strcat(s, ".mit.edu");
3273 if (!((int)call_args[3] & MOIRA_STRINGS))
3276 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3280 else if (!strcmp(av[ACE_TYPE], "LIST"))
3282 if (!((int)call_args[3] & MOIRA_LISTS))
3285 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3287 if (!((int)call_args[3] & MOIRA_KERBEROS))
3290 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3298 linklist = member_base;
3302 if (!strcasecmp(temp, linklist->member))
3305 linklist = linklist->next;
3308 linklist = calloc(1, sizeof(LK_ENTRY));
3310 linklist->dn = NULL;
3311 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3312 strcpy(linklist->list, call_args[2]);
3313 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3314 strcpy(linklist->type, av[ACE_TYPE]);
3315 linklist->member = calloc(1, strlen(temp) + 1);
3316 strcpy(linklist->member, temp);
3317 linklist->next = member_base;
3318 member_base = linklist;
3323 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3324 char *group_ou, char *group_membership, char *user_name,
3325 char *UserOu, char *MoiraId)
3327 char distinguished_name[1024];
3331 char *attr_array[3];
3336 LK_ENTRY *group_base;
3340 if (!check_string(group_name))
3341 return(AD_INVALID_NAME);
3343 memset(filter, '\0', sizeof(filter));
3347 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3348 group_membership, MoiraId,
3349 "distinguishedName", &group_base,
3350 &group_count, filter))
3353 if (group_count != 1)
3355 com_err(whoami, 0, "Unable to find list %s in AD",
3357 linklist_free(group_base);
3363 strcpy(distinguished_name, group_base->value);
3364 linklist_free(group_base);
3368 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3370 modvalues[0] = temp;
3371 modvalues[1] = NULL;
3374 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3376 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3378 for (i = 0; i < n; i++)
3381 if (rc == LDAP_UNWILLING_TO_PERFORM)
3384 if (rc != LDAP_SUCCESS)
3386 com_err(whoami, 0, "Unable to modify list %s members : %s",
3387 group_name, ldap_err2string(rc));
3391 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3395 if(!strcmp(UserOu, contact_ou) &&
3396 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3398 memset(temp, '\0', sizeof(temp));
3399 strcpy(temp, user_name);
3400 s = strchr(temp, '@');
3403 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3405 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3406 &group_base, &group_count,
3407 LDAP_SCOPE_SUBTREE) != 0))
3413 linklist_free(group_base);
3418 sprintf(filter, "(distinguishedName=%s)", temp);
3419 attr_array[0] = "memberOf";
3420 attr_array[1] = NULL;
3422 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3423 &group_base, &group_count,
3424 LDAP_SCOPE_SUBTREE) != 0))
3430 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3432 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3442 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3443 char *group_ou, char *group_membership, char *user_name,
3444 char *UserOu, char *MoiraId)
3446 char distinguished_name[1024];
3454 LK_ENTRY *group_base;
3457 if (!check_string(group_name))
3458 return(AD_INVALID_NAME);
3461 memset(filter, '\0', sizeof(filter));
3465 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3466 group_membership, MoiraId,
3467 "distinguishedName", &group_base,
3468 &group_count, filter))
3471 if (group_count != 1)
3473 linklist_free(group_base);
3476 com_err(whoami, 0, "Unable to find list %s in AD",
3478 return(AD_MULTIPLE_GROUPS_FOUND);
3481 strcpy(distinguished_name, group_base->value);
3482 linklist_free(group_base);
3486 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3487 modvalues[0] = temp;
3488 modvalues[1] = NULL;
3491 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3493 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3495 if (rc == LDAP_ALREADY_EXISTS)
3498 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3500 if (rc == LDAP_UNWILLING_TO_PERFORM)
3504 for (i = 0; i < n; i++)
3507 if (rc != LDAP_SUCCESS)
3509 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3510 user_name, group_name, ldap_err2string(rc));
3516 int contact_remove_email(LDAP *ld, char *bind_path,
3517 LK_ENTRY **linklist_base, int linklist_current)
3521 char *mail_v[] = {NULL, NULL};
3529 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3530 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3531 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3532 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3535 gPtr = (*linklist_base);
3538 rc = ldap_modify_s(ld, gPtr->dn, mods);
3540 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3542 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3543 gPtr->dn, ldap_err2string(rc));
3550 for (i = 0; i < n; i++)
3556 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3559 LK_ENTRY *group_base;
3562 char cn_user_name[256];
3563 char contact_name[256];
3564 char mail_nickname[256];
3565 char proxy_address_internal[256];
3566 char proxy_address_external[256];
3567 char target_address[256];
3568 char internal_contact_name[256];
3571 char mit_address_book[256];
3572 char default_address_book[256];
3573 char contact_address_book[256];
3574 char *email_v[] = {NULL, NULL};
3575 char *cn_v[] = {NULL, NULL};
3576 char *contact_v[] = {NULL, NULL};
3577 char *mail_nickname_v[] = {NULL, NULL};
3578 char *proxy_address_internal_v[] = {NULL, NULL};
3579 char *proxy_address_external_v[] = {NULL, NULL};
3580 char *target_address_v[] = {NULL, NULL};
3581 char *mit_address_book_v[] = {NULL, NULL};
3582 char *default_address_book_v[] = {NULL, NULL};
3583 char *contact_address_book_v[] = {NULL, NULL};
3584 char *hide_address_lists_v[] = {NULL, NULL};
3585 char *attr_array[3];
3587 char *objectClass_v[] = {"top", "person",
3588 "organizationalPerson",
3590 char *name_v[] = {NULL, NULL};
3591 char *desc_v[] = {NULL, NULL};
3597 if (!check_string(user))
3599 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3600 return(AD_INVALID_NAME);
3604 strcpy(contact_name, mail);
3605 strcpy(internal_contact_name, mail);
3607 if((s = strchr(internal_contact_name, '@')) != NULL) {
3611 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
3612 sprintf(target_address, "SMTP:%s", contact_name);
3613 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3614 sprintf(mail_nickname, "%s", internal_contact_name);
3616 cn_v[0] = cn_user_name;
3617 contact_v[0] = contact_name;
3619 desc_v[0] = "Auto account created by Moira";
3621 proxy_address_internal_v[0] = proxy_address_internal;
3622 proxy_address_external_v[0] = proxy_address_external;
3623 mail_nickname_v[0] = mail_nickname;
3624 target_address_v[0] = target_address;
3625 mit_address_book_v[0] = mit_address_book;
3626 default_address_book_v[0] = default_address_book;
3627 contact_address_book_v[0] = contact_address_book;
3628 strcpy(new_dn, cn_user_name);
3631 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3632 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3633 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3634 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3635 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3639 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3644 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3645 attr_array[0] = "cn";
3646 attr_array[1] = NULL;
3648 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3649 &group_base, &group_count,
3650 LDAP_SCOPE_SUBTREE)) != 0)
3652 com_err(whoami, 0, "Unable to process contact %s : %s",
3653 user, ldap_err2string(rc));
3659 com_err(whoami, 0, "Object already exists with name %s",
3664 linklist_free(group_base);
3668 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3669 attr_array[0] = "cn";
3670 attr_array[1] = NULL;
3672 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3673 &group_base, &group_count,
3674 LDAP_SCOPE_SUBTREE)) != 0)
3676 com_err(whoami, 0, "Unable to process contact %s : %s",
3677 user, ldap_err2string(rc));
3683 com_err(whoami, 0, "Object already exists with name %s",
3688 linklist_free(group_base);
3692 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3693 attr_array[0] = "cn";
3694 attr_array[1] = NULL;
3696 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3697 &group_base, &group_count,
3698 LDAP_SCOPE_SUBTREE)) != 0)
3700 com_err(whoami, 0, "Unable to process contact %s : %s",
3701 user, ldap_err2string(rc));
3707 com_err(whoami, 0, "Object already exists with name %s",
3712 linklist_free(group_base);
3716 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3717 attr_array[0] = "cn";
3718 attr_array[1] = NULL;
3720 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3721 &group_base, &group_count,
3722 LDAP_SCOPE_SUBTREE)) != 0)
3724 com_err(whoami, 0, "Unable to process contact %s : %s",
3725 user, ldap_err2string(rc));
3731 com_err(whoami, 0, "Object already exists with name %s",
3736 linklist_free(group_base);
3740 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3741 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3742 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3743 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3745 hide_address_lists_v[0] = "TRUE";
3746 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3753 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3755 for (i = 0; i < n; i++)
3760 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS))
3764 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
3765 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
3766 ADD_ATTR("proxyAddresses", proxy_address_external_v,
3768 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
3770 hide_address_lists_v[0] = "TRUE";
3771 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3775 rc = ldap_modify_s(ld, new_dn, mods);
3779 com_err(whoami, 0, "Unable to update contact %s", mail);
3782 for (i = 0; i < n; i++)
3787 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3790 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3791 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3792 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3793 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3794 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3796 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3798 for (i = 0; i < n; i++)
3802 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3804 com_err(whoami, 0, "Unable to create contact %s : %s",
3805 user, ldap_err2string(rc));
3812 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3813 char *Uid, char *MitId, char *MoiraId, int State,
3814 char *WinHomeDir, char *WinProfileDir, char *first,
3815 char *middle, char *last)
3818 LK_ENTRY *group_base;
3820 char distinguished_name[512];
3821 char displayName[256];
3822 char *mitMoiraId_v[] = {NULL, NULL};
3823 char *uid_v[] = {NULL, NULL};
3824 char *mitid_v[] = {NULL, NULL};
3825 char *homedir_v[] = {NULL, NULL};
3826 char *winProfile_v[] = {NULL, NULL};
3827 char *drives_v[] = {NULL, NULL};
3828 char *userAccountControl_v[] = {NULL, NULL};
3829 char *alt_recipient_v[] = {NULL, NULL};
3830 char *hide_address_lists_v[] = {NULL, NULL};
3831 char *mail_v[] = {NULL, NULL};
3832 char userAccountControlStr[80];
3837 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
3838 UF_PASSWD_CANT_CHANGE;
3840 char *attr_array[3];
3843 char contact_mail[256];
3844 char filter_exp[1024];
3845 char search_path[512];
3846 char TemplateDn[512];
3847 char TemplateSamName[128];
3848 char alt_recipient[256];
3849 char acBERBuf[N_SD_BER_BYTES];
3850 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3851 { N_SD_BER_BYTES, acBERBuf },
3853 LDAPControl *apsServerControls[] = {&sControl, NULL};
3855 LDAP_BERVAL **ppsValues;
3859 char *homeServerName;
3861 char search_string[256];
3863 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3864 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3865 BEREncodeSecurityBits(dwInfo, acBERBuf);
3867 if (!check_string(user_name))
3869 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
3871 return(AD_INVALID_NAME);
3874 memset(contact_mail, '\0', sizeof(contact_mail));
3875 sprintf(contact_mail, "%s@mit.edu", user_name);
3876 memset(mail, '\0', sizeof(mail));
3877 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
3878 memset(alt_recipient, '\0', sizeof(alt_recipient));
3879 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
3881 sprintf(search_string, "@%s", uppercase(ldap_domain));
3885 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
3887 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
3894 memset(displayName, '\0', sizeof(displayName));
3896 if (strlen(MoiraId) != 0)
3898 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
3899 attr_array[0] = "cn";
3900 attr_array[1] = NULL;
3901 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3902 &group_base, &group_count,
3903 LDAP_SCOPE_SUBTREE)) != 0)
3905 com_err(whoami, 0, "Unable to process user %s : %s",
3906 user_name, ldap_err2string(rc));
3911 if (group_count != 1)
3913 linklist_free(group_base);
3916 sprintf(filter, "(sAMAccountName=%s)", user_name);
3917 attr_array[0] = "cn";
3918 attr_array[1] = NULL;
3919 sprintf(temp, "%s,%s", user_ou, dn_path);
3920 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
3921 &group_base, &group_count,
3922 LDAP_SCOPE_SUBTREE)) != 0)
3924 com_err(whoami, 0, "Unable to process user %s : %s",
3925 user_name, ldap_err2string(rc));
3930 if (group_count != 1)
3932 com_err(whoami, 0, "Unable to find user %s in AD",
3934 linklist_free(group_base);
3935 return(AD_NO_USER_FOUND);
3938 strcpy(distinguished_name, group_base->dn);
3940 linklist_free(group_base);
3943 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
3944 rc = attribute_update(ldap_handle, distinguished_name, MitId,
3945 "employeeID", user_name);
3947 rc = attribute_update(ldap_handle, distinguished_name, "none",
3948 "employeeID", user_name);
3951 strcat(displayName, first);
3954 if(strlen(middle)) {
3956 strcat(displayName, " ");
3958 strcat(displayName, middle);
3962 if(strlen(middle) || strlen(first))
3963 strcat(displayName, " ");
3965 strcat(displayName, last);
3968 if(strlen(displayName))
3969 rc = attribute_update(ldap_handle, distinguished_name, displayName,
3970 "displayName", user_name);
3972 rc = attribute_update(ldap_handle, distinguished_name, user_name,
3973 "displayName", user_name);
3976 rc = attribute_update(ldap_handle, distinguished_name, first,
3977 "givenName", user_name);
3979 rc = attribute_update(ldap_handle, distinguished_name, "",
3980 "givenName", user_name);
3982 if(strlen(middle) == 1)
3983 rc = attribute_update(ldap_handle, distinguished_name, middle,
3984 "initials", user_name);
3986 rc = attribute_update(ldap_handle, distinguished_name, "",
3987 "initials", user_name);
3990 rc = attribute_update(ldap_handle, distinguished_name, last,
3993 rc = attribute_update(ldap_handle, distinguished_name, "",
3996 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
3998 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
3999 "mitMoiraId", user_name);
4006 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4010 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4013 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4015 userAccountControl |= UF_ACCOUNTDISABLE;
4019 hide_address_lists_v[0] = "TRUE";
4020 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4028 hide_address_lists_v[0] = NULL;
4029 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4034 sprintf(userAccountControlStr, "%ld", userAccountControl);
4035 userAccountControl_v[0] = userAccountControlStr;
4036 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4040 if (rc = moira_connect())
4042 critical_alert("AD incremental",
4043 "Error contacting Moira server : %s",
4048 argv[0] = user_name;
4050 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4052 if(!strcmp(save_argv[1], "EXCHANGE") ||
4053 (strstr(save_argv[3], search_string) != NULL))
4055 alt_recipient_v[0] = NULL;
4056 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4058 argv[0] = exchange_acl;
4060 argv[2] = user_name;
4062 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4064 if ((rc) && (rc != MR_EXISTS))
4066 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4067 user_name, exchange_acl, error_message(rc));
4072 alt_recipient_v[0] = alt_recipient;
4073 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4075 argv[0] = exchange_acl;
4077 argv[2] = user_name;
4079 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4081 if ((rc) && (rc != MR_NO_MATCH))
4084 "Unable to remove user %s from %s: %s, %d",
4085 user_name, exchange_acl, error_message(rc), rc);
4091 alt_recipient_v[0] = alt_recipient;
4092 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4094 argv[0] = exchange_acl;
4096 argv[2] = user_name;
4098 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4100 if ((rc) && (rc != MR_NO_MATCH))
4103 "Unable to remove user %s from %s: %s, %d",
4104 user_name, exchange_acl, error_message(rc), rc);
4112 mail_v[0] = contact_mail;
4113 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4116 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4117 WinProfileDir, homedir_v, winProfile_v,
4118 drives_v, mods, LDAP_MOD_REPLACE, n);
4120 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4121 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4122 attr_array[0] = "sAMAccountName";
4123 attr_array[1] = NULL;
4127 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
4128 &group_base, &group_count,
4129 LDAP_SCOPE_SUBTREE) != 0))
4132 if (group_count != 1)
4134 com_err(whoami, 0, "Unable to process user security template: %s - "
4135 "security not set", "UserTemplate.u");
4139 strcpy(TemplateDn, group_base->dn);
4140 strcpy(TemplateSamName, group_base->value);
4141 linklist_free(group_base);
4145 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4146 filter_exp, NULL, 0, apsServerControls, NULL,
4149 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4151 com_err(whoami, 0, "Unable to find user security template: %s - "
4152 "security not set", "UserTemplate.u");
4156 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
4158 if (ppsValues == NULL)
4160 com_err(whoami, 0, "Unable to find user security template: %s - "
4161 "security not set", "UserTemplate.u");
4165 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4166 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4170 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4171 mods)) != LDAP_SUCCESS)
4173 OldUseSFU30 = UseSFU30;
4174 SwitchSFU(mods, &UseSFU30, n);
4175 if (OldUseSFU30 != UseSFU30)
4176 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4179 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4180 user_name, ldap_err2string(rc));
4184 for (i = 0; i < n; i++)
4190 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4198 char contact_mail[256];
4199 char proxy_address[256];
4200 char query_base_dn[256];
4202 char *userPrincipalName_v[] = {NULL, NULL};
4203 char *altSecurityIdentities_v[] = {NULL, NULL};
4204 char *name_v[] = {NULL, NULL};
4205 char *samAccountName_v[] = {NULL, NULL};
4206 char *mail_v[] = {NULL, NULL};
4207 char *mail_nickname_v[] = {NULL, NULL};
4208 char *proxy_address_v[] = {NULL, NULL};
4209 char *query_base_dn_v[] = {NULL, NULL};
4214 if (!check_string(before_user_name))
4217 "Unable to process invalid LDAP user name %s", before_user_name);
4218 return(AD_INVALID_NAME);
4221 if (!check_string(user_name))
4224 "Unable to process invalid LDAP user name %s", user_name);
4225 return(AD_INVALID_NAME);
4228 strcpy(user_name, user_name);
4229 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4230 sprintf(new_dn, "cn=%s", user_name);
4231 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4232 sprintf(contact_mail, "%s@mit.edu", user_name);
4233 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4235 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4236 NULL, NULL)) != LDAP_SUCCESS)
4238 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4239 before_user_name, user_name, ldap_err2string(rc));
4245 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4248 if(rc = ldap_delete_s(ldap_handle, temp))
4250 com_err(whoami, 0, "Unable to delete user contact for %s",
4254 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4256 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4260 name_v[0] = user_name;
4261 sprintf(upn, "%s@%s", user_name, ldap_domain);
4262 userPrincipalName_v[0] = upn;
4263 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4264 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4265 altSecurityIdentities_v[0] = temp;
4266 samAccountName_v[0] = user_name;
4268 mail_nickname_v[0] = user_name;
4269 proxy_address_v[0] = proxy_address;
4270 query_base_dn_v[0] = query_base_dn;
4273 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4274 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4275 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4276 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4280 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4281 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4282 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4283 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4287 mail_v[0] = contact_mail;
4288 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4293 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4295 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4298 "Unable to modify user data for %s after renaming : %s",
4299 user_name, ldap_err2string(rc));
4302 for (i = 0; i < n; i++)
4308 int user_create(int ac, char **av, void *ptr)
4312 char user_name[256];
4316 char contact_mail[256];
4317 char proxy_address[256];
4318 char mail_nickname[256];
4319 char query_base_dn[256];
4320 char displayName[256];
4321 char address_book[256];
4322 char alt_recipient[256];
4323 char *cn_v[] = {NULL, NULL};
4324 char *objectClass_v[] = {"top", "person",
4325 "organizationalPerson",
4328 char *samAccountName_v[] = {NULL, NULL};
4329 char *altSecurityIdentities_v[] = {NULL, NULL};
4330 char *mitMoiraId_v[] = {NULL, NULL};
4331 char *name_v[] = {NULL, NULL};
4332 char *desc_v[] = {NULL, NULL};
4333 char *userPrincipalName_v[] = {NULL, NULL};
4334 char *userAccountControl_v[] = {NULL, NULL};
4335 char *uid_v[] = {NULL, NULL};
4336 char *mitid_v[] = {NULL, NULL};
4337 char *homedir_v[] = {NULL, NULL};
4338 char *winProfile_v[] = {NULL, NULL};
4339 char *drives_v[] = {NULL, NULL};
4340 char *mail_v[] = {NULL, NULL};
4341 char *givenName_v[] = {NULL, NULL};
4342 char *sn_v[] = {NULL, NULL};
4343 char *initials_v[] = {NULL, NULL};
4344 char *displayName_v[] = {NULL, NULL};
4345 char *proxy_address_v[] = {NULL, NULL};
4346 char *mail_nickname_v[] = {NULL, NULL};
4347 char *query_base_dn_v[] = {NULL, NULL};
4348 char *address_book_v[] = {NULL, NULL};
4349 char *homeMDB_v[] = {NULL, NULL};
4350 char *homeServerName_v[] = {NULL, NULL};
4351 char *mdbUseDefaults_v[] = {NULL, NULL};
4352 char *mailbox_guid_v[] = {NULL, NULL};
4353 char *user_culture_v[] = {NULL, NULL};
4354 char *user_account_control_v[] = {NULL, NULL};
4355 char *msexch_version_v[] = {NULL, NULL};
4356 char *alt_recipient_v[] = {NULL, NULL};
4357 char *hide_address_lists_v[] = {NULL, NULL};
4358 char userAccountControlStr[80];
4360 char filter_exp[1024];
4361 char search_path[512];
4362 char *attr_array[3];
4363 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4364 UF_PASSWD_CANT_CHANGE;
4370 char WinHomeDir[1024];
4371 char WinProfileDir[1024];
4373 char *homeServerName;
4375 char acBERBuf[N_SD_BER_BYTES];
4376 LK_ENTRY *group_base;
4378 char TemplateDn[512];
4379 char TemplateSamName[128];
4380 LDAP_BERVAL **ppsValues;
4381 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4382 { N_SD_BER_BYTES, acBERBuf },
4384 LDAPControl *apsServerControls[] = {&sControl, NULL};
4388 char search_string[256];
4392 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4393 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4394 BEREncodeSecurityBits(dwInfo, acBERBuf);
4396 if (!check_string(av[U_NAME]))
4398 callback_rc = AD_INVALID_NAME;
4399 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4401 return(AD_INVALID_NAME);
4404 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4405 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4406 memset(displayName, '\0', sizeof(displayName));
4407 memset(query_base_dn, '\0', sizeof(query_base_dn));
4408 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4409 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4410 strcpy(user_name, av[U_NAME]);
4411 sprintf(upn, "%s@%s", user_name, ldap_domain);
4412 sprintf(sam_name, "%s", av[U_NAME]);
4414 if(strlen(av[U_FIRST])) {
4415 strcat(displayName, av[U_FIRST]);
4418 if(strlen(av[U_MIDDLE])) {
4419 if(strlen(av[U_FIRST]))
4420 strcat(displayName, " ");
4422 strcat(displayName, av[U_MIDDLE]);
4425 if(strlen(av[U_LAST])) {
4426 if(strlen(av[U_FIRST]) || strlen(av[U_LAST]))
4427 strcat(displayName, " ");
4429 strcat(displayName, av[U_LAST]);
4432 samAccountName_v[0] = sam_name;
4433 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4434 (atoi(av[U_STATE]) != US_REGISTERED))
4436 userAccountControl |= UF_ACCOUNTDISABLE;
4440 hide_address_lists_v[0] = "TRUE";
4441 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4446 sprintf(userAccountControlStr, "%ld", userAccountControl);
4447 userAccountControl_v[0] = userAccountControlStr;
4448 userPrincipalName_v[0] = upn;
4449 cn_v[0] = user_name;
4450 name_v[0] = user_name;
4451 desc_v[0] = "Auto account created by Moira";
4453 givenName_v[0] = av[U_FIRST];
4454 sn_v[0] = av[U_LAST];
4455 displayName_v[0] = displayName;
4456 mail_nickname_v[0] = user_name;
4458 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4459 altSecurityIdentities_v[0] = temp;
4460 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4461 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4462 sprintf(contact_mail, "%s@mit.edu", user_name);
4463 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4464 query_base_dn_v[0] = query_base_dn;
4465 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4467 sprintf(search_string, "@%s", uppercase(ldap_domain));
4472 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4475 com_err(whoami, 0, "Unable to create user contact %s",
4479 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4482 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4486 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4487 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4489 homeMDB_v[0] = homeMDB;
4490 homeServerName_v[0] = homeServerName;
4494 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4495 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4496 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
4497 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
4498 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
4499 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
4500 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
4504 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
4505 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4506 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
4507 mdbUseDefaults_v[0] = "TRUE";
4508 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
4509 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
4511 argv[0] = user_name;
4513 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4515 if(!strcmp(save_argv[1], "EXCHANGE") ||
4516 (strstr(save_argv[3], search_string) != NULL))
4518 argv[0] = exchange_acl;
4520 argv[2] = user_name;
4522 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4524 if ((rc) && (rc != MR_EXISTS))
4526 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4527 user_name, exchange_acl, error_message(rc));
4532 alt_recipient_v[0] = alt_recipient;
4533 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4538 alt_recipient_v[0] = alt_recipient;
4539 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4541 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
4546 mail_v[0] = contact_mail;
4547 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
4550 if(strlen(av[U_FIRST])) {
4551 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
4554 if(strlen(av[U_LAST])) {
4555 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
4558 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
4559 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
4561 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4564 if (strlen(av[U_MIDDLE]) == 1) {
4565 initials_v[0] = av[U_MIDDLE];
4566 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
4569 if (strlen(call_args[2]) != 0)
4571 mitMoiraId_v[0] = call_args[2];
4572 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
4575 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
4577 if (strlen(av[U_UID]) != 0)
4579 uid_v[0] = av[U_UID];
4580 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
4584 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
4588 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
4592 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
4593 mitid_v[0] = av[U_MITID];
4595 mitid_v[0] = "none";
4597 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
4599 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
4600 WinProfileDir, homedir_v, winProfile_v,
4601 drives_v, mods, LDAP_MOD_ADD, n);
4603 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4604 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
4605 attr_array[0] = "sAMAccountName";
4606 attr_array[1] = NULL;
4610 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
4611 attr_array, &group_base, &group_count,
4612 LDAP_SCOPE_SUBTREE) != 0))
4615 if (group_count != 1)
4617 com_err(whoami, 0, "Unable to process user security template: %s - "
4618 "security not set", "UserTemplate.u");
4622 strcpy(TemplateDn, group_base->dn);
4623 strcpy(TemplateSamName, group_base->value);
4624 linklist_free(group_base);
4628 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE,
4629 filter_exp, NULL, 0, apsServerControls, NULL,
4632 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
4634 com_err(whoami, 0, "Unable to find user security template: %s - "
4635 "security not set", "UserTemplate.u");
4639 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
4640 "ntSecurityDescriptor");
4641 if (ppsValues == NULL)
4643 com_err(whoami, 0, "Unable to find user security template: %s - "
4644 "security not set", "UserTemplate.u");
4648 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4649 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4653 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4655 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4657 OldUseSFU30 = UseSFU30;
4658 SwitchSFU(mods, &UseSFU30, n);
4659 if (OldUseSFU30 != UseSFU30)
4660 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4663 for (i = 0; i < n; i++)
4666 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4668 com_err(whoami, 0, "Unable to create user %s : %s",
4669 user_name, ldap_err2string(rc));
4674 if ((rc == LDAP_SUCCESS) && (SetPassword))
4676 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4678 ad_kdc_disconnect();
4679 if (!ad_server_connect(default_server, ldap_domain))
4681 com_err(whoami, 0, "Unable to set password for user %s : %s",
4683 "cannot get changepw ticket from windows domain");
4687 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4689 com_err(whoami, 0, "Unable to set password for user %s "
4690 ": %ld", user_name, rc);
4699 int user_change_status(LDAP *ldap_handle, char *dn_path,
4700 char *user_name, char *MoiraId,
4704 char *attr_array[3];
4706 char distinguished_name[1024];
4708 char *mitMoiraId_v[] = {NULL, NULL};
4710 LK_ENTRY *group_base;
4717 if (!check_string(user_name))
4719 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4721 return(AD_INVALID_NAME);
4727 if (strlen(MoiraId) != 0)
4729 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4730 attr_array[0] = "UserAccountControl";
4731 attr_array[1] = NULL;
4732 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4733 &group_base, &group_count,
4734 LDAP_SCOPE_SUBTREE)) != 0)
4736 com_err(whoami, 0, "Unable to process user %s : %s",
4737 user_name, ldap_err2string(rc));
4742 if (group_count != 1)
4744 linklist_free(group_base);
4747 sprintf(filter, "(sAMAccountName=%s)", user_name);
4748 attr_array[0] = "UserAccountControl";
4749 attr_array[1] = NULL;
4750 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4751 &group_base, &group_count,
4752 LDAP_SCOPE_SUBTREE)) != 0)
4754 com_err(whoami, 0, "Unable to process user %s : %s",
4755 user_name, ldap_err2string(rc));
4760 if (group_count != 1)
4762 linklist_free(group_base);
4763 com_err(whoami, 0, "Unable to find user %s in AD",
4765 return(LDAP_NO_SUCH_OBJECT);
4768 strcpy(distinguished_name, group_base->dn);
4769 ulongValue = atoi((*group_base).value);
4771 if (operation == MEMBER_DEACTIVATE)
4772 ulongValue |= UF_ACCOUNTDISABLE;
4774 ulongValue &= ~UF_ACCOUNTDISABLE;
4776 sprintf(temp, "%ld", ulongValue);
4778 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
4779 temp, &modvalues, REPLACE)) == 1)
4782 linklist_free(group_base);
4786 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
4788 if (strlen(MoiraId) != 0)
4790 mitMoiraId_v[0] = MoiraId;
4791 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
4795 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4797 for (i = 0; i < n; i++)
4800 free_values(modvalues);
4802 if (rc != LDAP_SUCCESS)
4804 com_err(whoami, 0, "Unable to change status of user %s : %s",
4805 user_name, ldap_err2string(rc));
4812 int user_delete(LDAP *ldap_handle, char *dn_path,
4813 char *u_name, char *MoiraId)
4816 char *attr_array[3];
4817 char distinguished_name[1024];
4818 char user_name[512];
4819 LK_ENTRY *group_base;
4824 if (!check_string(u_name))
4825 return(AD_INVALID_NAME);
4827 strcpy(user_name, u_name);
4831 if (strlen(MoiraId) != 0)
4833 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4834 attr_array[0] = "name";
4835 attr_array[1] = NULL;
4836 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4837 &group_base, &group_count,
4838 LDAP_SCOPE_SUBTREE)) != 0)
4840 com_err(whoami, 0, "Unable to process user %s : %s",
4841 user_name, ldap_err2string(rc));
4846 if (group_count != 1)
4848 linklist_free(group_base);
4851 sprintf(filter, "(sAMAccountName=%s)", user_name);
4852 attr_array[0] = "name";
4853 attr_array[1] = NULL;
4854 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4855 &group_base, &group_count,
4856 LDAP_SCOPE_SUBTREE)) != 0)
4858 com_err(whoami, 0, "Unable to process user %s : %s",
4859 user_name, ldap_err2string(rc));
4864 if (group_count != 1)
4866 com_err(whoami, 0, "Unable to find user %s in AD",
4871 strcpy(distinguished_name, group_base->dn);
4873 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
4875 com_err(whoami, 0, "Unable to process user %s : %s",
4876 user_name, ldap_err2string(rc));
4879 /* Need to add code to delete mit.edu contact */
4883 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
4885 if(rc = ldap_delete_s(ldap_handle, temp))
4887 com_err(whoami, 0, "Unable to delete user contact for %s",
4893 linklist_free(group_base);
4898 void linklist_free(LK_ENTRY *linklist_base)
4900 LK_ENTRY *linklist_previous;
4902 while (linklist_base != NULL)
4904 if (linklist_base->dn != NULL)
4905 free(linklist_base->dn);
4907 if (linklist_base->attribute != NULL)
4908 free(linklist_base->attribute);
4910 if (linklist_base->value != NULL)
4911 free(linklist_base->value);
4913 if (linklist_base->member != NULL)
4914 free(linklist_base->member);
4916 if (linklist_base->type != NULL)
4917 free(linklist_base->type);
4919 if (linklist_base->list != NULL)
4920 free(linklist_base->list);
4922 linklist_previous = linklist_base;
4923 linklist_base = linklist_previous->next;
4924 free(linklist_previous);
4928 void free_values(char **modvalues)
4934 if (modvalues != NULL)
4936 while (modvalues[i] != NULL)
4939 modvalues[i] = NULL;
4946 static int illegalchars[] = {
4947 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
4948 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
4949 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
4950 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
4951 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
4952 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
4953 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
4954 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
4955 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4956 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4957 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4958 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4959 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4960 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4961 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4962 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4965 int check_string(char *s)
4973 if (isupper(character))
4974 character = tolower(character);
4976 if (illegalchars[(unsigned) character])
4983 int check_container_name(char *s)
4991 if (isupper(character))
4992 character = tolower(character);
4994 if (character == ' ')
4997 if (illegalchars[(unsigned) character])
5004 int mr_connect_cl(char *server, char *client, int version, int auth)
5010 status = mr_connect(server);
5014 com_err(whoami, status, "while connecting to Moira");
5018 status = mr_motd(&motd);
5023 com_err(whoami, status, "while checking server status");
5029 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5030 com_err(whoami, status, temp);
5035 status = mr_version(version);
5039 if (status == MR_UNKNOWN_PROC)
5042 status = MR_VERSION_HIGH;
5044 status = MR_SUCCESS;
5047 if (status == MR_VERSION_HIGH)
5049 com_err(whoami, 0, "Warning: This client is running newer code "
5050 "than the server.");
5051 com_err(whoami, 0, "Some operations may not work.");
5053 else if (status && status != MR_VERSION_LOW)
5055 com_err(whoami, status, "while setting query version number.");
5063 status = mr_krb5_auth(client);
5066 com_err(whoami, status, "while authenticating to Moira.");
5075 void AfsToWinAfs(char* path, char* winPath)
5079 strcpy(winPath, WINAFS);
5080 pathPtr = path + strlen(AFS);
5081 winPathPtr = winPath + strlen(WINAFS);
5085 if (*pathPtr == '/')
5088 *winPathPtr = *pathPtr;
5095 int GetAceInfo(int ac, char **av, void *ptr)
5102 strcpy(call_args[0], av[L_ACE_TYPE]);
5103 strcpy(call_args[1], av[L_ACE_NAME]);
5105 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5106 return(LDAP_SUCCESS);
5109 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5112 char *attr_array[3];
5115 LK_ENTRY *group_base;
5120 sprintf(filter, "(sAMAccountName=%s)", Name);
5121 attr_array[0] = "sAMAccountName";
5122 attr_array[1] = NULL;
5124 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5125 &group_base, &group_count,
5126 LDAP_SCOPE_SUBTREE)) != 0)
5128 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5129 Name, ldap_err2string(rc));
5133 linklist_free(group_base);
5136 if (group_count == 0)
5144 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5145 int UpdateGroup, int *ProcessGroup, char *maillist)
5148 char GroupName[256];
5154 char AceMembership[2];
5157 char *save_argv[U_END];
5161 com_err(whoami, 0, "ProcessAce disabled, skipping");
5165 strcpy(GroupName, Name);
5167 if (strcasecmp(Type, "LIST"))
5173 AceInfo[0] = AceType;
5174 AceInfo[1] = AceName;
5175 AceInfo[2] = AceMembership;
5177 memset(AceType, '\0', sizeof(AceType));
5178 memset(AceName, '\0', sizeof(AceName));
5179 memset(AceMembership, '\0', sizeof(AceMembership));
5180 memset(AceOu, '\0', sizeof(AceOu));
5183 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5185 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5186 GroupName, error_message(rc));
5192 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5196 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5199 strcpy(temp, AceName);
5201 if (!strcasecmp(AceType, "LIST"))
5202 sprintf(temp, "%s%s", AceName, group_suffix);
5206 if (checkADname(ldap_handle, dn_path, temp))
5208 (*ProcessGroup) = 1;
5211 if (!strcasecmp(AceInfo[0], "LIST"))
5213 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5214 AceMembership, 0, UpdateGroup, maillist))
5217 else if (!strcasecmp(AceInfo[0], "USER"))
5220 call_args[0] = (char *)ldap_handle;
5221 call_args[1] = dn_path;
5223 call_args[3] = NULL;
5226 if (rc = mr_query("get_user_account_by_login", 1, av,
5227 save_query_info, save_argv))
5229 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5234 if (rc = user_create(U_END, save_argv, call_args))
5236 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5243 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5253 if (!strcasecmp(AceType, "LIST"))
5255 if (!strcasecmp(GroupName, AceName))
5259 strcpy(GroupName, AceName);
5265 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5266 char *group_name, char *group_ou, char *group_membership,
5267 int group_security_flag, int updateGroup, char *maillist)
5272 LK_ENTRY *group_base;
5275 char *attr_array[3];
5278 call_args[0] = (char *)ldap_handle;
5279 call_args[1] = dn_path;
5280 call_args[2] = group_name;
5281 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5282 call_args[4] = (char *)updateGroup;
5283 call_args[5] = MoiraId;
5285 call_args[7] = NULL;
5291 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5294 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5302 com_err(whoami, 0, "Unable to create list %s", group_name);
5303 return(callback_rc);
5309 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
5310 char *group_ou, char *group_membership,
5311 int group_security_flag, char *MoiraId)
5321 com_err(whoami, 0, "Populating group %s", group_name);
5323 call_args[0] = (char *)ldap_handle;
5324 call_args[1] = dn_path;
5325 call_args[2] = group_name;
5326 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5327 call_args[4] = NULL;
5330 if (rc = mr_query("get_end_members_of_list", 1, av,
5331 member_list_build, call_args))
5333 com_err(whoami, 0, "Unable to populate list %s : %s",
5334 group_name, error_message(rc));
5338 if (member_base != NULL)
5344 if (!strcasecmp(ptr->type, "LIST"))
5352 if (!strcasecmp(ptr->type, "STRING"))
5354 if (contact_create(ldap_handle, dn_path, ptr->member,
5358 pUserOu = contact_ou;
5360 else if (!strcasecmp(ptr->type, "KERBEROS"))
5362 if (contact_create(ldap_handle, dn_path, ptr->member,
5366 pUserOu = kerberos_ou;
5369 rc = member_add(ldap_handle, dn_path, group_name,
5370 group_ou, group_membership, ptr->member,
5375 linklist_free(member_base);
5382 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5383 char *group_name, char *group_ou, char *group_membership,
5384 int group_security_flag, int type, char *maillist)
5386 char before_desc[512];
5387 char before_name[256];
5388 char before_group_ou[256];
5389 char before_group_membership[2];
5390 char distinguishedName[256];
5391 char ad_distinguishedName[256];
5393 char *attr_array[3];
5394 int before_security_flag;
5397 LK_ENTRY *group_base;
5400 char ou_security[512];
5401 char ou_distribution[512];
5402 char ou_neither[512];
5404 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
5405 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
5407 memset(filter, '\0', sizeof(filter));
5411 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5413 "distinguishedName", &group_base,
5414 &group_count, filter))
5417 if (type == CHECK_GROUPS)
5419 if (group_count == 1)
5421 if (!strcasecmp(group_base->value, distinguishedName))
5423 linklist_free(group_base);
5428 linklist_free(group_base);
5430 if (group_count == 0)
5431 return(AD_NO_GROUPS_FOUND);
5433 if (group_count == 1)
5434 return(AD_WRONG_GROUP_DN_FOUND);
5436 return(AD_MULTIPLE_GROUPS_FOUND);
5439 if (group_count == 0)
5441 return(AD_NO_GROUPS_FOUND);
5444 if (group_count > 1)
5450 if (!strcasecmp(distinguishedName, ptr->value))
5458 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
5464 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
5468 linklist_free(group_base);
5469 return(AD_MULTIPLE_GROUPS_FOUND);
5476 if (strcasecmp(distinguishedName, ptr->value))
5477 rc = ldap_delete_s(ldap_handle, ptr->value);
5482 linklist_free(group_base);
5483 memset(filter, '\0', sizeof(filter));
5487 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5489 "distinguishedName", &group_base,
5490 &group_count, filter))
5493 if (group_count == 0)
5494 return(AD_NO_GROUPS_FOUND);
5496 if (group_count > 1)
5497 return(AD_MULTIPLE_GROUPS_FOUND);
5500 strcpy(ad_distinguishedName, group_base->value);
5501 linklist_free(group_base);
5505 attr_array[0] = "sAMAccountName";
5506 attr_array[1] = NULL;
5508 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5509 &group_base, &group_count,
5510 LDAP_SCOPE_SUBTREE)) != 0)
5512 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5513 MoiraId, ldap_err2string(rc));
5517 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
5519 if (!strcasecmp(ad_distinguishedName, distinguishedName))
5521 linklist_free(group_base);
5527 linklist_free(group_base);
5530 memset(ou_both, '\0', sizeof(ou_both));
5531 memset(ou_security, '\0', sizeof(ou_security));
5532 memset(ou_distribution, '\0', sizeof(ou_distribution));
5533 memset(ou_neither, '\0', sizeof(ou_neither));
5534 memset(before_name, '\0', sizeof(before_name));
5535 memset(before_desc, '\0', sizeof(before_desc));
5536 memset(before_group_membership, '\0', sizeof(before_group_membership));
5537 attr_array[0] = "name";
5538 attr_array[1] = NULL;
5540 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5541 &group_base, &group_count,
5542 LDAP_SCOPE_SUBTREE)) != 0)
5544 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
5545 MoiraId, ldap_err2string(rc));
5549 strcpy(before_name, group_base->value);
5550 linklist_free(group_base);
5553 attr_array[0] = "description";
5554 attr_array[1] = NULL;
5556 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5557 &group_base, &group_count,
5558 LDAP_SCOPE_SUBTREE)) != 0)
5561 "Unable to get list description with MoiraId = %s: %s",
5562 MoiraId, ldap_err2string(rc));
5566 if (group_count != 0)
5568 strcpy(before_desc, group_base->value);
5569 linklist_free(group_base);
5574 change_to_lower_case(ad_distinguishedName);
5575 strcpy(ou_both, group_ou_both);
5576 change_to_lower_case(ou_both);
5577 strcpy(ou_security, group_ou_security);
5578 change_to_lower_case(ou_security);
5579 strcpy(ou_distribution, group_ou_distribution);
5580 change_to_lower_case(ou_distribution);
5581 strcpy(ou_neither, group_ou_neither);
5582 change_to_lower_case(ou_neither);
5584 if (strstr(ad_distinguishedName, ou_both))
5586 strcpy(before_group_ou, group_ou_both);
5587 before_group_membership[0] = 'B';
5588 before_security_flag = 1;
5590 else if (strstr(ad_distinguishedName, ou_security))
5592 strcpy(before_group_ou, group_ou_security);
5593 before_group_membership[0] = 'S';
5594 before_security_flag = 1;
5596 else if (strstr(ad_distinguishedName, ou_distribution))
5598 strcpy(before_group_ou, group_ou_distribution);
5599 before_group_membership[0] = 'D';
5600 before_security_flag = 0;
5602 else if (strstr(ad_distinguishedName, ou_neither))
5604 strcpy(before_group_ou, group_ou_neither);
5605 before_group_membership[0] = 'N';
5606 before_security_flag = 0;
5609 return(AD_NO_OU_FOUND);
5611 rc = group_rename(ldap_handle, dn_path, before_name,
5612 before_group_membership,
5613 before_group_ou, before_security_flag, before_desc,
5614 group_name, group_membership, group_ou,
5615 group_security_flag,
5616 before_desc, MoiraId, filter, maillist);
5621 void change_to_lower_case(char *ptr)
5625 for (i = 0; i < (int)strlen(ptr); i++)
5627 ptr[i] = tolower(ptr[i]);
5631 int ad_get_group(LDAP *ldap_handle, char *dn_path,
5632 char *group_name, char *group_membership,
5633 char *MoiraId, char *attribute,
5634 LK_ENTRY **linklist_base, int *linklist_count,
5639 char *attr_array[3];
5642 (*linklist_base) = NULL;
5643 (*linklist_count) = 0;
5645 if (strlen(rFilter) != 0)
5647 strcpy(filter, rFilter);
5648 attr_array[0] = attribute;
5649 attr_array[1] = NULL;
5651 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5652 linklist_base, linklist_count,
5653 LDAP_SCOPE_SUBTREE)) != 0)
5655 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5656 MoiraId, ldap_err2string(rc));
5660 if ((*linklist_count) == 1)
5662 strcpy(rFilter, filter);
5667 linklist_free((*linklist_base));
5668 (*linklist_base) = NULL;
5669 (*linklist_count) = 0;
5671 if (strlen(MoiraId) != 0)
5673 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
5674 attr_array[0] = attribute;
5675 attr_array[1] = NULL;
5677 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5678 linklist_base, linklist_count,
5679 LDAP_SCOPE_SUBTREE)) != 0)
5681 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5682 MoiraId, ldap_err2string(rc));
5687 if ((*linklist_count) > 1)
5689 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
5690 pPtr = (*linklist_base);
5694 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
5699 linklist_free((*linklist_base));
5700 (*linklist_base) = NULL;
5701 (*linklist_count) = 0;
5704 if ((*linklist_count) == 1)
5706 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
5708 strcpy(rFilter, filter);
5713 linklist_free((*linklist_base));
5714 (*linklist_base) = NULL;
5715 (*linklist_count) = 0;
5716 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
5717 attr_array[0] = attribute;
5718 attr_array[1] = NULL;
5720 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5721 linklist_base, linklist_count,
5722 LDAP_SCOPE_SUBTREE)) != 0)
5724 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5725 MoiraId, ldap_err2string(rc));
5729 if ((*linklist_count) == 1)
5731 strcpy(rFilter, filter);
5738 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5741 char *attr_array[3];
5742 char SamAccountName[64];
5745 LK_ENTRY *group_base;
5751 if (strlen(MoiraId) != 0)
5753 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5754 attr_array[0] = "sAMAccountName";
5755 attr_array[1] = NULL;
5756 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5757 &group_base, &group_count,
5758 LDAP_SCOPE_SUBTREE)) != 0)
5760 com_err(whoami, 0, "Unable to process user %s : %s",
5761 UserName, ldap_err2string(rc));
5765 if (group_count > 1)
5767 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5773 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5774 gPtr->value, MoiraId);
5780 if (group_count != 1)
5782 linklist_free(group_base);
5785 sprintf(filter, "(sAMAccountName=%s)", UserName);
5786 attr_array[0] = "sAMAccountName";
5787 attr_array[1] = NULL;
5789 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5790 &group_base, &group_count,
5791 LDAP_SCOPE_SUBTREE)) != 0)
5793 com_err(whoami, 0, "Unable to process user %s : %s",
5794 UserName, ldap_err2string(rc));
5799 if (group_count != 1)
5801 linklist_free(group_base);
5802 return(AD_NO_USER_FOUND);
5805 strcpy(SamAccountName, group_base->value);
5806 linklist_free(group_base);
5810 if (strcmp(SamAccountName, UserName))
5812 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5819 void container_get_dn(char *src, char *dest)
5826 memset(array, '\0', 20 * sizeof(array[0]));
5828 if (strlen(src) == 0)
5850 strcpy(dest, "OU=");
5854 strcat(dest, array[n-1]);
5858 strcat(dest, ",OU=");
5865 void container_get_name(char *src, char *dest)
5870 if (strlen(src) == 0)
5890 void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5897 strcpy(cName, name);
5899 for (i = 0; i < (int)strlen(cName); i++)
5901 if (cName[i] == '/')
5904 av[CONTAINER_NAME] = cName;
5905 av[CONTAINER_DESC] = "";
5906 av[CONTAINER_LOCATION] = "";
5907 av[CONTAINER_CONTACT] = "";
5908 av[CONTAINER_TYPE] = "";
5909 av[CONTAINER_ID] = "";
5910 av[CONTAINER_ROWID] = "";
5911 rc = container_create(ldap_handle, dn_path, 7, av);
5913 if (rc == LDAP_SUCCESS)
5915 com_err(whoami, 0, "container %s created without a mitMoiraId",
5924 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5925 char **before, int afterc, char **after)
5930 char new_dn_path[256];
5932 char distinguishedName[256];
5937 memset(cName, '\0', sizeof(cName));
5938 container_get_name(after[CONTAINER_NAME], cName);
5940 if (!check_container_name(cName))
5942 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5944 return(AD_INVALID_NAME);
5947 memset(distinguishedName, '\0', sizeof(distinguishedName));
5949 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5950 distinguishedName, beforec, before))
5953 if (strlen(distinguishedName) == 0)
5955 rc = container_create(ldap_handle, dn_path, afterc, after);
5959 strcpy(temp, after[CONTAINER_NAME]);
5962 for (i = 0; i < (int)strlen(temp); i++)
5972 container_get_dn(temp, dName);
5974 if (strlen(temp) != 0)
5975 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5977 sprintf(new_dn_path, "%s", dn_path);
5979 sprintf(new_cn, "OU=%s", cName);
5981 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
5983 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
5984 TRUE, NULL, NULL)) != LDAP_SUCCESS)
5986 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
5987 before[CONTAINER_NAME], after[CONTAINER_NAME],
5988 ldap_err2string(rc));
5992 memset(dName, '\0', sizeof(dName));
5993 container_get_dn(after[CONTAINER_NAME], dName);
5994 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
5999 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6001 char distinguishedName[256];
6004 memset(distinguishedName, '\0', sizeof(distinguishedName));
6006 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6007 distinguishedName, count, av))
6010 if (strlen(distinguishedName) == 0)
6013 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6015 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6016 container_move_objects(ldap_handle, dn_path, distinguishedName);
6018 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6019 av[CONTAINER_NAME], ldap_err2string(rc));
6025 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6027 char *attr_array[3];
6028 LK_ENTRY *group_base;
6031 char *objectClass_v[] = {"top",
6032 "organizationalUnit",
6035 char *ou_v[] = {NULL, NULL};
6036 char *name_v[] = {NULL, NULL};
6037 char *moiraId_v[] = {NULL, NULL};
6038 char *desc_v[] = {NULL, NULL};
6039 char *managedBy_v[] = {NULL, NULL};
6042 char managedByDN[256];
6049 memset(filter, '\0', sizeof(filter));
6050 memset(dName, '\0', sizeof(dName));
6051 memset(cName, '\0', sizeof(cName));
6052 memset(managedByDN, '\0', sizeof(managedByDN));
6053 container_get_dn(av[CONTAINER_NAME], dName);
6054 container_get_name(av[CONTAINER_NAME], cName);
6056 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6058 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6060 return(AD_INVALID_NAME);
6063 if (!check_container_name(cName))
6065 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6067 return(AD_INVALID_NAME);
6071 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6073 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6075 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6077 if (strlen(av[CONTAINER_ROWID]) != 0)
6079 moiraId_v[0] = av[CONTAINER_ROWID];
6080 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6083 if (strlen(av[CONTAINER_DESC]) != 0)
6085 desc_v[0] = av[CONTAINER_DESC];
6086 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6089 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6091 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6093 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6096 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6097 kerberos_ou, dn_path);
6098 managedBy_v[0] = managedByDN;
6099 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6104 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6106 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6107 "(objectClass=user)))", av[CONTAINER_ID]);
6110 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6112 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6116 if (strlen(filter) != 0)
6118 attr_array[0] = "distinguishedName";
6119 attr_array[1] = NULL;
6122 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6124 &group_base, &group_count,
6125 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6127 if (group_count == 1)
6129 strcpy(managedByDN, group_base->value);
6130 managedBy_v[0] = managedByDN;
6131 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6133 linklist_free(group_base);
6143 sprintf(temp, "%s,%s", dName, dn_path);
6144 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
6146 for (i = 0; i < n; i++)
6149 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6151 com_err(whoami, 0, "Unable to create container %s : %s",
6152 cName, ldap_err2string(rc));
6156 if (rc == LDAP_ALREADY_EXISTS)
6158 if (strlen(av[CONTAINER_ROWID]) != 0)
6159 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6165 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6166 char **before, int afterc, char **after)
6168 char distinguishedName[256];
6171 memset(distinguishedName, '\0', sizeof(distinguishedName));
6173 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6174 distinguishedName, afterc, after))
6177 if (strlen(distinguishedName) == 0)
6179 rc = container_create(ldap_handle, dn_path, afterc, after);
6183 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6184 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6190 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6191 char *distinguishedName, int count,
6194 char *attr_array[3];
6195 LK_ENTRY *group_base;
6202 memset(filter, '\0', sizeof(filter));
6203 memset(dName, '\0', sizeof(dName));
6204 memset(cName, '\0', sizeof(cName));
6205 container_get_dn(av[CONTAINER_NAME], dName);
6206 container_get_name(av[CONTAINER_NAME], cName);
6208 if (strlen(dName) == 0)
6210 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6211 av[CONTAINER_NAME]);
6212 return(AD_INVALID_NAME);
6215 if (!check_container_name(cName))
6217 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6219 return(AD_INVALID_NAME);
6222 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6223 av[CONTAINER_ROWID]);
6224 attr_array[0] = "distinguishedName";
6225 attr_array[1] = NULL;
6229 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6230 &group_base, &group_count,
6231 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6233 if (group_count == 1)
6235 strcpy(distinguishedName, group_base->value);
6238 linklist_free(group_base);
6243 if (strlen(distinguishedName) == 0)
6245 sprintf(filter, "(&(objectClass=organizationalUnit)"
6246 "(distinguishedName=%s,%s))", dName, dn_path);
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);
6270 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6271 char *distinguishedName, int count, char **av)
6273 char *attr_array[5];
6274 LK_ENTRY *group_base;
6279 char *moiraId_v[] = {NULL, NULL};
6280 char *desc_v[] = {NULL, NULL};
6281 char *managedBy_v[] = {NULL, NULL};
6282 char managedByDN[256];
6291 strcpy(ad_path, distinguishedName);
6293 if (strlen(dName) != 0)
6294 sprintf(ad_path, "%s,%s", dName, dn_path);
6296 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6299 if (strlen(av[CONTAINER_ID]) != 0)
6300 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6301 av[CONTAINER_ROWID]);
6303 attr_array[0] = "mitMoiraId";
6304 attr_array[1] = "description";
6305 attr_array[2] = "managedBy";
6306 attr_array[3] = NULL;
6310 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6311 &group_base, &group_count,
6312 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6314 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6315 av[CONTAINER_NAME], ldap_err2string(rc));
6319 memset(managedByDN, '\0', sizeof(managedByDN));
6320 memset(moiraId, '\0', sizeof(moiraId));
6321 memset(desc, '\0', sizeof(desc));
6326 if (!strcasecmp(pPtr->attribute, "description"))
6327 strcpy(desc, pPtr->value);
6328 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6329 strcpy(managedByDN, pPtr->value);
6330 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6331 strcpy(moiraId, pPtr->value);
6335 linklist_free(group_base);
6340 if (strlen(av[CONTAINER_ROWID]) != 0)
6342 moiraId_v[0] = av[CONTAINER_ROWID];
6343 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6346 if (strlen(av[CONTAINER_DESC]) != 0)
6348 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6353 if (strlen(desc) != 0)
6355 attribute_update(ldap_handle, ad_path, "", "description", dName);
6359 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6361 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6363 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6366 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6367 kerberos_ou, dn_path);
6368 managedBy_v[0] = managedByDN;
6369 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6373 if (strlen(managedByDN) != 0)
6375 attribute_update(ldap_handle, ad_path, "", "managedBy",
6382 memset(filter, '\0', sizeof(filter));
6384 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6386 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6387 "(objectClass=user)))", av[CONTAINER_ID]);
6390 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6392 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6396 if (strlen(filter) != 0)
6398 attr_array[0] = "distinguishedName";
6399 attr_array[1] = NULL;
6402 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6403 attr_array, &group_base, &group_count,
6404 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6406 if (group_count == 1)
6408 strcpy(managedByDN, group_base->value);
6409 managedBy_v[0] = managedByDN;
6410 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6414 if (strlen(managedByDN) != 0)
6416 attribute_update(ldap_handle, ad_path, "",
6417 "managedBy", dName);
6421 linklist_free(group_base);
6428 if (strlen(managedByDN) != 0)
6430 attribute_update(ldap_handle, ad_path, "", "managedBy",
6440 return(LDAP_SUCCESS);
6442 rc = ldap_modify_s(ldap_handle, ad_path, mods);
6444 for (i = 0; i < n; i++)
6447 if (rc != LDAP_SUCCESS)
6449 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6450 av[CONTAINER_NAME], ldap_err2string(rc));
6457 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6459 char *attr_array[3];
6460 LK_ENTRY *group_base;
6467 int NumberOfEntries = 10;
6471 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6473 for (i = 0; i < 3; i++)
6475 memset(filter, '\0', sizeof(filter));
6479 strcpy(filter, "(!(|(objectClass=computer)"
6480 "(objectClass=organizationalUnit)))");
6481 attr_array[0] = "cn";
6482 attr_array[1] = NULL;
6486 strcpy(filter, "(objectClass=computer)");
6487 attr_array[0] = "cn";
6488 attr_array[1] = NULL;
6492 strcpy(filter, "(objectClass=organizationalUnit)");
6493 attr_array[0] = "ou";
6494 attr_array[1] = NULL;
6499 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
6500 &group_base, &group_count,
6501 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6506 if (group_count == 0)
6513 if (!strcasecmp(pPtr->attribute, "cn"))
6515 sprintf(new_cn, "cn=%s", pPtr->value);
6517 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6519 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6524 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6526 if (rc == LDAP_ALREADY_EXISTS)
6528 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6535 else if (!strcasecmp(pPtr->attribute, "ou"))
6537 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6543 linklist_free(group_base);
6552 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6553 char *machine_ou, char *NewMachineName)
6555 LK_ENTRY *group_base;
6559 char *attr_array[3];
6566 strcpy(NewMachineName, member);
6567 rc = moira_connect();
6568 rc = GetMachineName(NewMachineName);
6571 if (strlen(NewMachineName) == 0)
6573 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6579 pPtr = strchr(NewMachineName, '.');
6586 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
6587 attr_array[0] = "cn";
6588 attr_array[1] = NULL;
6589 sprintf(temp, "%s", dn_path);
6591 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
6592 &group_base, &group_count,
6593 LDAP_SCOPE_SUBTREE)) != 0)
6595 com_err(whoami, 0, "Unable to process machine %s : %s",
6596 member, ldap_err2string(rc));
6600 if (group_count != 1)
6603 "Unable to process machine %s : machine not found in AD",
6608 strcpy(dn, group_base->dn);
6609 strcpy(cn, group_base->value);
6611 for (i = 0; i < (int)strlen(dn); i++)
6612 dn[i] = tolower(dn[i]);
6614 for (i = 0; i < (int)strlen(cn); i++)
6615 cn[i] = tolower(cn[i]);
6617 linklist_free(group_base);
6619 pPtr = strstr(dn, cn);
6623 com_err(whoami, 0, "Unable to process machine %s",
6628 pPtr += strlen(cn) + 1;
6629 strcpy(machine_ou, pPtr);
6631 pPtr = strstr(machine_ou, "dc=");
6635 com_err(whoami, 0, "Unable to process machine %s",
6646 int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6647 char *MoiraMachineName, char *DestinationOu)
6651 char MachineName[128];
6653 char *attr_array[3];
6658 LK_ENTRY *group_base;
6663 strcpy(MachineName, MoiraMachineName);
6664 rc = GetMachineName(MachineName);
6666 if (strlen(MachineName) == 0)
6668 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6673 cPtr = strchr(MachineName, '.');
6678 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6679 attr_array[0] = "sAMAccountName";
6680 attr_array[1] = NULL;
6682 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6684 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
6686 com_err(whoami, 0, "Unable to process machine %s : %s",
6687 MoiraMachineName, ldap_err2string(rc));
6691 if (group_count == 1)
6692 strcpy(OldDn, group_base->dn);
6694 linklist_free(group_base);
6697 if (group_count != 1)
6699 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6704 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6705 cPtr = strchr(OldDn, ',');
6710 if (!strcasecmp(cPtr, NewOu))
6714 sprintf(NewCn, "CN=%s", MachineName);
6715 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6720 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6726 memset(Name, '\0', sizeof(Name));
6727 strcpy(Name, machine_name);
6729 pPtr = strchr(Name, '.');
6735 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
6738 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6739 char *machine_name, char *container_name)
6745 av[0] = machine_name;
6746 call_args[0] = (char *)container_name;
6747 rc = mr_query("get_machine_to_container_map", 1, av,
6748 machine_GetMoiraContainer, call_args);
6752 int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6757 strcpy(call_args[0], av[1]);
6761 int Moira_container_group_create(char **after)
6767 memset(GroupName, '\0', sizeof(GroupName));
6768 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6769 after[CONTAINER_ROWID]);
6773 argv[L_NAME] = GroupName;
6774 argv[L_ACTIVE] = "1";
6775 argv[L_PUBLIC] = "0";
6776 argv[L_HIDDEN] = "0";
6777 argv[L_MAILLIST] = "0";
6778 argv[L_GROUP] = "1";
6779 argv[L_GID] = UNIQUE_GID;
6780 argv[L_NFSGROUP] = "0";
6781 argv[L_MAILMAN] = "0";
6782 argv[L_MAILMAN_SERVER] = "[NONE]";
6783 argv[L_DESC] = "auto created container group";
6784 argv[L_ACE_TYPE] = "USER";
6785 argv[L_MEMACE_TYPE] = "USER";
6786 argv[L_ACE_NAME] = "sms";
6787 argv[L_MEMACE_NAME] = "sms";
6789 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
6792 "Unable to create container group %s for container %s: %s",
6793 GroupName, after[CONTAINER_NAME], error_message(rc));
6796 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6797 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6802 int Moira_container_group_update(char **before, char **after)
6805 char BeforeGroupName[64];
6806 char AfterGroupName[64];
6809 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6812 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6813 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6814 if (strlen(BeforeGroupName) == 0)
6817 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6818 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6819 after[CONTAINER_ROWID]);
6823 if (strcasecmp(BeforeGroupName, AfterGroupName))
6825 argv[L_NAME] = BeforeGroupName;
6826 argv[L_NAME + 1] = AfterGroupName;
6827 argv[L_ACTIVE + 1] = "1";
6828 argv[L_PUBLIC + 1] = "0";
6829 argv[L_HIDDEN + 1] = "0";
6830 argv[L_MAILLIST + 1] = "0";
6831 argv[L_GROUP + 1] = "1";
6832 argv[L_GID + 1] = UNIQUE_GID;
6833 argv[L_NFSGROUP + 1] = "0";
6834 argv[L_MAILMAN + 1] = "0";
6835 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
6836 argv[L_DESC + 1] = "auto created container group";
6837 argv[L_ACE_TYPE + 1] = "USER";
6838 argv[L_MEMACE_TYPE + 1] = "USER";
6839 argv[L_ACE_NAME + 1] = "sms";
6840 argv[L_MEMACE_NAME + 1] = "sms";
6842 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
6845 "Unable to rename container group from %s to %s: %s",
6846 BeforeGroupName, AfterGroupName, error_message(rc));
6853 int Moira_container_group_delete(char **before)
6858 char ParentGroupName[64];
6860 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6861 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6863 memset(GroupName, '\0', sizeof(GroupName));
6865 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6866 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6868 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6870 argv[0] = ParentGroupName;
6872 argv[2] = GroupName;
6874 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6877 "Unable to delete container group %s from list: %s",
6878 GroupName, ParentGroupName, error_message(rc));
6882 if (strlen(GroupName) != 0)
6884 argv[0] = GroupName;
6886 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6888 com_err(whoami, 0, "Unable to delete container group %s : %s",
6889 GroupName, error_message(rc));
6896 int Moira_groupname_create(char *GroupName, char *ContainerName,
6897 char *ContainerRowID)
6902 char newGroupName[64];
6903 char tempGroupName[64];
6909 strcpy(temp, ContainerName);
6911 ptr1 = strrchr(temp, '/');
6917 ptr1 = strrchr(temp, '/');
6921 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6924 strcpy(tempgname, ptr);
6927 strcpy(tempgname, temp);
6929 if (strlen(tempgname) > 25)
6930 tempgname[25] ='\0';
6932 sprintf(newGroupName, "cnt-%s", tempgname);
6934 /* change everything to lower case */
6940 *ptr = tolower(*ptr);
6948 strcpy(tempGroupName, newGroupName);
6951 /* append 0-9 then a-z if a duplicate is found */
6954 argv[0] = newGroupName;
6956 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6958 if (rc == MR_NO_MATCH)
6960 com_err(whoami, 0, "Moira error while creating group name for "
6961 "container %s : %s", ContainerName, error_message(rc));
6965 sprintf(newGroupName, "%s-%c", tempGroupName, i);
6969 com_err(whoami, 0, "Unable to find a unique group name for "
6970 "container %s: too many duplicate container names",
6981 strcpy(GroupName, newGroupName);
6985 int Moira_setContainerGroup(char *origContainerName, char *GroupName)
6990 argv[0] = origContainerName;
6991 argv[1] = GroupName;
6993 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
6996 "Unable to set container group %s in container %s: %s",
6997 GroupName, origContainerName, error_message(rc));
7003 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7005 char ContainerName[64];
7006 char ParentGroupName[64];
7010 strcpy(ContainerName, origContainerName);
7012 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7014 /* top-level container */
7015 if (strlen(ParentGroupName) == 0)
7018 argv[0] = ParentGroupName;
7020 argv[2] = GroupName;
7022 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7025 "Unable to add container group %s to parent group %s: %s",
7026 GroupName, ParentGroupName, error_message(rc));
7032 int Moira_getContainerGroup(int ac, char **av, void *ptr)
7037 strcpy(call_args[0], av[1]);
7042 int Moira_getGroupName(char *origContainerName, char *GroupName,
7045 char ContainerName[64];
7051 strcpy(ContainerName, origContainerName);
7055 ptr = strrchr(ContainerName, '/');
7063 argv[0] = ContainerName;
7065 call_args[0] = GroupName;
7066 call_args[1] = NULL;
7068 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7071 if (strlen(GroupName) != 0)
7076 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7077 ContainerName, error_message(rc));
7079 com_err(whoami, 0, "Unable to get container group from container %s",
7085 int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7091 if (strcmp(GroupName, "[none]") == 0)
7094 argv[0] = GroupName;
7095 argv[1] = "MACHINE";
7096 argv[2] = MachineName;
7099 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7101 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7105 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7106 MachineName, GroupName, error_message(rc));
7112 int GetMachineName(char *MachineName)
7115 char NewMachineName[1024];
7122 // If the address happens to be in the top-level MIT domain, great!
7123 strcpy(NewMachineName, MachineName);
7125 for (i = 0; i < (int)strlen(NewMachineName); i++)
7126 NewMachineName[i] = toupper(NewMachineName[i]);
7128 szDot = strchr(NewMachineName,'.');
7130 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7135 // If not, see if it has a Moira alias in the top-level MIT domain.
7136 memset(NewMachineName, '\0', sizeof(NewMachineName));
7138 args[1] = MachineName;
7139 call_args[0] = NewMachineName;
7140 call_args[1] = NULL;
7142 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7144 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7145 MachineName, error_message(rc));
7146 strcpy(MachineName, "");
7150 if (strlen(NewMachineName) != 0)
7151 strcpy(MachineName, NewMachineName);
7153 strcpy(MachineName, "");
7158 int ProcessMachineName(int ac, char **av, void *ptr)
7161 char MachineName[1024];
7167 if (strlen(call_args[0]) == 0)
7169 strcpy(MachineName, av[0]);
7171 for (i = 0; i < (int)strlen(MachineName); i++)
7172 MachineName[i] = toupper(MachineName[i]);
7174 szDot = strchr(MachineName,'.');
7176 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
7178 strcpy(call_args[0], MachineName);
7185 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7191 for (i = 0; i < n; i++)
7193 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7194 mods[i]->mod_type = "uidNumber";
7201 for (i = 0; i < n; i++)
7203 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7204 mods[i]->mod_type = "msSFU30UidNumber";
7211 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7212 char *DistinguishedName,
7213 char *WinHomeDir, char *WinProfileDir,
7214 char **homedir_v, char **winProfile_v,
7215 char **drives_v, LDAPMod **mods,
7223 char winProfile[1024];
7228 LDAPMod *DelMods[20];
7230 memset(homeDrive, '\0', sizeof(homeDrive));
7231 memset(path, '\0', sizeof(path));
7232 memset(winPath, '\0', sizeof(winPath));
7233 memset(winProfile, '\0', sizeof(winProfile));
7236 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7237 (!strcasecmp(WinProfileDir, "[afs]")))
7239 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
7241 memset(cWeight, 0, sizeof(cWeight));
7242 memset(cPath, 0, sizeof(cPath));
7246 while (hp[i] != NULL)
7248 if (sscanf(hp[i], "%*s %s", cPath))
7250 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
7252 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
7254 if (atoi(cWeight) < last_weight)
7256 strcpy(path, cPath);
7257 last_weight = (int)atoi(cWeight);
7261 strcpy(path, cPath);
7269 if (!strnicmp(path, AFS, strlen(AFS)))
7271 AfsToWinAfs(path, winPath);
7272 strcpy(winProfile, winPath);
7273 strcat(winProfile, "\\.winprofile");
7281 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7282 (!strcasecmp(WinProfileDir, "[dfs]")))
7284 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7285 user_name[0], user_name);
7287 if (!strcasecmp(WinProfileDir, "[dfs]"))
7289 strcpy(winProfile, path);
7290 strcat(winProfile, "\\.winprofile");
7293 if (!strcasecmp(WinHomeDir, "[dfs]"))
7294 strcpy(winPath, path);
7307 if (!strcasecmp(WinHomeDir, "[local]"))
7308 memset(winPath, '\0', sizeof(winPath));
7309 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7310 !strcasecmp(WinHomeDir, "[dfs]"))
7312 strcpy(homeDrive, "H:");
7316 strcpy(winPath, WinHomeDir);
7317 if (!strncmp(WinHomeDir, "\\\\", 2))
7319 strcpy(homeDrive, "H:");
7323 // nothing needs to be done if WinProfileDir is [afs].
7324 if (!strcasecmp(WinProfileDir, "[local]"))
7325 memset(winProfile, '\0', sizeof(winProfile));
7326 else if (strcasecmp(WinProfileDir, "[afs]") &&
7327 strcasecmp(WinProfileDir, "[dfs]"))
7329 strcpy(winProfile, WinProfileDir);
7332 if (strlen(winProfile) != 0)
7334 if (winProfile[strlen(winProfile) - 1] == '\\')
7335 winProfile[strlen(winProfile) - 1] = '\0';
7338 if (strlen(winPath) != 0)
7340 if (winPath[strlen(winPath) - 1] == '\\')
7341 winPath[strlen(winPath) - 1] = '\0';
7344 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
7345 strcat(winProfile, "\\");
7347 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7348 strcat(winPath, "\\");
7350 if (strlen(winPath) == 0)
7352 if (OpType == LDAP_MOD_REPLACE)
7355 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7357 //unset homeDirectory attribute for user.
7358 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7364 homedir_v[0] = strdup(winPath);
7365 ADD_ATTR("homeDirectory", homedir_v, OpType);
7368 if (strlen(winProfile) == 0)
7370 if (OpType == LDAP_MOD_REPLACE)
7373 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7375 //unset profilePate attribute for user.
7376 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7382 winProfile_v[0] = strdup(winProfile);
7383 ADD_ATTR("profilePath", winProfile_v, OpType);
7386 if (strlen(homeDrive) == 0)
7388 if (OpType == LDAP_MOD_REPLACE)
7391 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7393 //unset homeDrive attribute for user
7394 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7400 drives_v[0] = strdup(homeDrive);
7401 ADD_ATTR("homeDrive", drives_v, OpType);
7407 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
7408 char *attribute_value, char *attribute, char *user_name)
7410 char *mod_v[] = {NULL, NULL};
7411 LDAPMod *DelMods[20];
7417 if (strlen(attribute_value) == 0)
7420 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7422 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7428 mod_v[0] = attribute_value;
7429 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7432 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7433 mods)) != LDAP_SUCCESS)
7437 mod_v[0] = attribute_value;
7438 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7441 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7442 mods)) != LDAP_SUCCESS)
7444 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7446 attribute, user_name, ldap_err2string(rc));
7456 void StringTrim(char *StringToTrim)
7461 save = strdup(StringToTrim);
7468 /* skip to end of string */
7473 strcpy(StringToTrim, save);
7477 for (t = s; *t; t++)
7493 strcpy(StringToTrim, s);
7497 int ReadConfigFile(char *DomainName)
7508 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
7510 if ((fptr = fopen(temp, "r")) != NULL)
7512 while (fgets(temp, sizeof(temp), fptr) != 0)
7514 for (i = 0; i < (int)strlen(temp); i++)
7515 temp[i] = toupper(temp[i]);
7517 if (temp[strlen(temp) - 1] == '\n')
7518 temp[strlen(temp) - 1] = '\0';
7522 if (strlen(temp) == 0)
7525 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7527 if (strlen(temp) > (strlen(DOMAIN)))
7529 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7530 StringTrim(ldap_domain);
7533 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
7535 if (strlen(temp) > (strlen(PRINCIPALNAME)))
7537 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7538 StringTrim(PrincipalName);
7541 else if (!strncmp(temp, SERVER, strlen(SERVER)))
7543 if (strlen(temp) > (strlen(SERVER)))
7545 ServerList[Count] = calloc(1, 256);
7546 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7547 StringTrim(ServerList[Count]);
7551 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
7553 if (strlen(temp) > (strlen(MSSFU)))
7555 strcpy(temp1, &temp[strlen(MSSFU)]);
7557 if (!strcmp(temp1, SFUTYPE))
7561 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7563 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7565 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7567 if (!strcasecmp(temp1, "NO"))
7570 memset(group_suffix, '\0', sizeof(group_suffix));
7574 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7576 if (strlen(temp) > (strlen(GROUP_TYPE)))
7578 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7580 if (!strcasecmp(temp1, "UNIVERSAL"))
7581 UseGroupUniversal = 1;
7584 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7586 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7588 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7590 if (!strcasecmp(temp1, "NO"))
7594 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7596 if (strlen(temp) > (strlen(SET_PASSWORD)))
7598 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7600 if (!strcasecmp(temp1, "NO"))
7604 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7606 if (strlen(temp) > (strlen(EXCHANGE)))
7608 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7610 if (!strcasecmp(temp1, "YES"))
7614 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7615 strlen(PROCESS_MACHINE_CONTAINER)))
7617 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7619 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7621 if (!strcasecmp(temp1, "NO"))
7622 ProcessMachineContainer = 0;
7627 if (strlen(ldap_domain) != 0)
7629 memset(ldap_domain, '\0', sizeof(ldap_domain));
7633 if (strlen(temp) != 0)
7634 strcpy(ldap_domain, temp);
7640 if (strlen(ldap_domain) == 0)
7642 strcpy(ldap_domain, DomainName);
7648 for (i = 0; i < Count; i++)
7650 if (ServerList[i] != 0)
7652 strcat(ServerList[i], ".");
7653 strcat(ServerList[i], ldap_domain);
7654 for (k = 0; k < (int)strlen(ServerList[i]); k++)
7655 ServerList[i][k] = toupper(ServerList[i][k]);
7662 int ReadDomainList()
7669 unsigned char c[11];
7670 unsigned char stuff[256];
7675 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
7677 if ((fptr = fopen(temp, "r")) != NULL)
7679 while (fgets(temp, sizeof(temp), fptr) != 0)
7681 for (i = 0; i < (int)strlen(temp); i++)
7682 temp[i] = toupper(temp[i]);
7684 if (temp[strlen(temp) - 1] == '\n')
7685 temp[strlen(temp) - 1] = '\0';
7689 if (strlen(temp) == 0)
7692 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7694 if (strlen(temp) > (strlen(DOMAIN)))
7696 strcpy(temp1, &temp[strlen(DOMAIN)]);
7698 strcpy(temp, temp1);
7702 strcpy(DomainNames[Count], temp);
7703 StringTrim(DomainNames[Count]);
7712 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7713 "configuration error in winad.cfg");
7720 int email_isvalid(const char *address) {
7722 const char *c, *domain;
7723 static char *rfc822_specials = "()<>@,;:\\\"[]";
7725 if(address[strlen(address) - 1] == '.')
7728 /* first we validate the name portion (name@domain) */
7729 for (c = address; *c; c++) {
7730 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7735 if (*c == '\\' && (*++c == ' '))
7737 if (*c <= ' ' || *c >= 127)
7752 if (*c <= ' ' || *c >= 127)
7754 if (strchr(rfc822_specials, *c))
7758 if (c == address || *(c - 1) == '.')
7761 /* next we validate the domain portion (name@domain) */
7762 if (!*(domain = ++c)) return 0;
7765 if (c == domain || *(c - 1) == '.')
7769 if (*c <= ' ' || *c >= 127)
7771 if (strchr(rfc822_specials, *c))
7775 return (count >= 1);
7778 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7779 char **homeServerName)
7781 LK_ENTRY *group_base;
7782 LK_ENTRY *sub_group_base;
7786 int sub_group_count;
7788 char sub_filter[1024];
7789 char search_path[1024];
7791 char *attr_array[3];
7793 int homeMDB_count = -1;
7797 int rangeStep = 1500;
7799 int rangeHigh = rangeLow + (rangeStep - 1);
7802 /* Grumble..... microsoft not making it searchable from the root *grr* */
7804 memset(filter, '\0', sizeof(filter));
7805 memset(search_path, '\0', sizeof(search_path));
7807 sprintf(filter, "(objectClass=msExchMDB)");
7808 sprintf(search_path, "CN=Configuration,%s", dn_path);
7809 attr_array[0] = "distinguishedName";
7810 attr_array[1] = NULL;
7815 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7816 &group_base, &group_count,
7817 LDAP_SCOPE_SUBTREE)) != 0)
7819 com_err(whoami, 0, "Unable to find msExchMDB %s",
7820 ldap_err2string(rc));
7829 if ((s = strstr(gPtr->dn, "Public")) != (char *) NULL)
7835 if ((s = strstr(gPtr->dn, "msExchRestore=True")) != (char *) NULL)
7842 * Due to limits in active directory we need to use the LDAP
7843 * range semantics to query and return all the values in
7844 * large lists, we will stop increasing the range when
7845 * the result count is 0.
7853 memset(sub_filter, '\0', sizeof(sub_filter));
7854 memset(range, '\0', sizeof(range));
7855 sprintf(sub_filter, "(objectClass=msExchMDB)");
7858 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
7860 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
7862 attr_array[0] = range;
7863 attr_array[1] = NULL;
7865 sub_group_base = NULL;
7866 sub_group_count = 0;
7868 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
7869 attr_array, &sub_group_base,
7871 LDAP_SCOPE_SUBTREE)) != 0)
7873 com_err(whoami, 0, "Unable to find homeMDBBL %s",
7874 ldap_err2string(rc));
7878 if(!sub_group_count)
7884 rangeHigh = rangeLow + (rangeStep - 1);
7891 mdbbl_count += sub_group_count;
7892 rangeLow = rangeHigh + 1;
7893 rangeHigh = rangeLow + (rangeStep - 1);
7896 /* First time through, need to initialize or update the least used */
7898 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
7901 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
7903 homeMDB_count = mdbbl_count;
7904 *homeMDB = strdup(gPtr->dn);
7908 linklist_free(sub_group_base);
7912 linklist_free(group_base);
7915 * Ok found the server least allocated need to now query to get its
7916 * msExchHomeServerName so we can set it as a user attribute
7919 attr_array[0] = "legacyExchangeDN";
7920 attr_array[1] = NULL;
7925 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
7926 attr_array, &group_base,
7928 LDAP_SCOPE_SUBTREE)) != 0)
7930 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
7931 ldap_err2string(rc));
7937 *homeServerName = strdup(group_base->value);
7938 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
7944 linklist_free(group_base);
7949 char *lowercase(char *s)
7953 for (p = s; *p; p++)
7961 char *uppercase(char *s)
7965 for (p = s; *p; p++)
7973 int save_query_info(int argc, char **argv, void *hint)
7976 char **nargv = hint;
7978 for(i = 0; i < argc; i++)
7979 nargv[i] = strdup(argv[i]);