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] = mail;
2526 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2527 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2528 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2529 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2530 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2535 if(atoi(maillist) && email_isvalid(contact_mail))
2537 mail_v[0] = contact_mail;
2538 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2544 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
2547 "Unable to modify list data for %s after renaming: %s",
2548 after_group_name, ldap_err2string(rc));
2551 for (i = 0; i < n; i++)
2557 int group_create(int ac, char **av, void *ptr)
2562 char new_group_name[256];
2563 char sam_group_name[256];
2564 char cn_group_name[256];
2566 char contact_mail[256];
2567 char mail_nickname[256];
2568 char proxy_address[256];
2569 char address_book[256];
2570 char *cn_v[] = {NULL, NULL};
2571 char *objectClass_v[] = {"top", "group", NULL};
2573 char *samAccountName_v[] = {NULL, NULL};
2574 char *altSecurityIdentities_v[] = {NULL, NULL};
2575 char *member_v[] = {NULL, NULL};
2576 char *name_v[] = {NULL, NULL};
2577 char *desc_v[] = {NULL, NULL};
2578 char *info_v[] = {NULL, NULL};
2579 char *mitMoiraId_v[] = {NULL, NULL};
2580 char *groupTypeControl_v[] = {NULL, NULL};
2581 char *mail_v[] = {NULL, NULL};
2582 char *proxy_address_v[] = {NULL, NULL};
2583 char *mail_nickname_v[] = {NULL, NULL};
2584 char *reportToOriginator_v[] = {NULL, NULL};
2585 char *address_book_v[] = {NULL, NULL};
2586 char *legacy_exchange_dn_v[] = {NULL, NULL};
2587 char groupTypeControlStr[80];
2588 char group_membership[1];
2591 u_int groupTypeControl;
2600 if(UseGroupUniversal)
2601 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2603 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2605 if (!check_string(av[L_NAME]))
2607 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2609 return(AD_INVALID_NAME);
2612 updateGroup = (int)call_args[4];
2613 MailDisabled = atoi(call_args[6]);
2614 memset(group_ou, 0, sizeof(group_ou));
2615 memset(group_membership, 0, sizeof(group_membership));
2618 get_group_membership(group_membership, group_ou, &security_flag, av);
2620 strcpy(new_group_name, av[L_NAME]);
2621 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
2622 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2623 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2624 sprintf(mail_nickname, "%s", av[L_NAME]);
2627 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
2629 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
2633 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2634 groupTypeControl_v[0] = groupTypeControlStr;
2636 strcpy(cn_group_name, av[L_NAME]);
2638 samAccountName_v[0] = sam_group_name;
2639 name_v[0] = new_group_name;
2640 cn_v[0] = new_group_name;
2643 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2644 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2645 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2646 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2647 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
2651 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2653 mail_nickname_v[0] = mail_nickname;
2654 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2659 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2661 mail_v[0] = contact_mail;
2662 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2666 if (strlen(av[L_DESC]) != 0)
2668 desc_v[0] = av[L_DESC];
2669 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2672 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
2674 if (strlen(av[L_ACE_NAME]) != 0)
2676 sprintf(info, "The Administrator of this list is: %s",
2679 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2682 if (strlen(call_args[5]) != 0)
2684 mitMoiraId_v[0] = call_args[5];
2685 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2690 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
2692 for (i = 0; i < n; i++)
2695 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2697 com_err(whoami, 0, "Unable to create list %s in AD : %s",
2698 av[L_NAME], ldap_err2string(rc));
2704 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
2706 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2707 "description", av[L_NAME]);
2708 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
2709 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2713 if (strlen(call_args[5]) != 0)
2715 mitMoiraId_v[0] = call_args[5];
2716 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2719 if (!(atoi(av[L_ACTIVE])))
2722 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2727 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2729 mail_nickname_v[0] = mail_nickname;
2730 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2735 mail_nickname_v[0] = NULL;
2736 proxy_address_v[0] = NULL;
2737 legacy_exchange_dn_v[0] = NULL;
2738 address_book_v[0] = NULL;
2740 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2741 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2742 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2743 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2745 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2750 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2752 mail_v[0] = contact_mail;
2753 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2758 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2767 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
2769 for (i = 0; i < n; i++)
2772 if (rc != LDAP_SUCCESS)
2774 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2775 av[L_NAME], ldap_err2string(rc));
2782 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2783 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2785 return(LDAP_SUCCESS);
2788 int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2789 char *TargetGroupName, int HiddenGroup,
2790 char *AceType, char *AceName)
2792 char filter_exp[1024];
2793 char *attr_array[5];
2794 char search_path[512];
2796 char TemplateDn[512];
2797 char TemplateSamName[128];
2799 char TargetSamName[128];
2800 char AceSamAccountName[128];
2802 unsigned char AceSid[128];
2803 unsigned char UserTemplateSid[128];
2804 char acBERBuf[N_SD_BER_BYTES];
2805 char GroupSecurityTemplate[256];
2806 char hide_addres_lists[256];
2807 char address_book[256];
2808 char *hide_address_lists_v[] = {NULL, NULL};
2809 char *address_book_v[] = {NULL, NULL};
2811 int UserTemplateSidCount;
2818 int array_count = 0;
2820 LK_ENTRY *group_base;
2821 LDAP_BERVAL **ppsValues;
2822 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2823 { N_SD_BER_BYTES, acBERBuf },
2826 LDAPControl *apsServerControls[] = {&sControl, NULL};
2829 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
2830 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
2831 BEREncodeSecurityBits(dwInfo, acBERBuf);
2833 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
2834 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
2835 attr_array[0] = "sAMAccountName";
2836 attr_array[1] = NULL;
2840 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2841 &group_base, &group_count,
2842 LDAP_SCOPE_SUBTREE) != 0))
2845 if (group_count != 1)
2847 linklist_free(group_base);
2851 strcpy(TargetDn, group_base->dn);
2852 strcpy(TargetSamName, group_base->value);
2853 linklist_free(group_base);
2857 UserTemplateSidCount = 0;
2858 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2859 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2860 memset(AceSid, '\0', sizeof(AceSid));
2865 if (strlen(AceName) != 0)
2867 if (!strcmp(AceType, "LIST"))
2869 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
2870 strcpy(root_ou, group_ou_root);
2872 else if (!strcmp(AceType, "USER"))
2874 sprintf(AceSamAccountName, "%s", AceName);
2875 strcpy(root_ou, user_ou);
2878 if (strlen(AceSamAccountName) != 0)
2880 sprintf(search_path, "%s", dn_path);
2881 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2882 attr_array[0] = "objectSid";
2883 attr_array[1] = NULL;
2887 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2888 attr_array, &group_base, &group_count,
2889 LDAP_SCOPE_SUBTREE) != 0))
2891 if (group_count == 1)
2893 strcpy(AceDn, group_base->dn);
2894 AceSidCount = group_base->length;
2895 memcpy(AceSid, group_base->value, AceSidCount);
2897 linklist_free(group_base);
2903 if (AceSidCount == 0)
2905 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
2906 "have an AD SID.", TargetGroupName, AceName, AceType);
2907 com_err(whoami, 0, " Non-admin security group template will be used.");
2911 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2912 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
2913 attr_array[0] = "objectSid";
2914 attr_array[1] = NULL;
2919 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2920 attr_array, &group_base, &group_count,
2921 LDAP_SCOPE_SUBTREE) != 0))
2924 if ((rc != 0) || (group_count != 1))
2926 com_err(whoami, 0, "Unable to process user security template: %s",
2932 UserTemplateSidCount = group_base->length;
2933 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
2935 linklist_free(group_base);
2942 if (AceSidCount == 0)
2944 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
2945 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
2949 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
2950 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
2955 if (AceSidCount == 0)
2957 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
2958 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
2962 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
2963 sprintf(filter_exp, "(sAMAccountName=%s)",
2964 NOT_HIDDEN_GROUP_WITH_ADMIN);
2968 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2969 attr_array[0] = "sAMAccountName";
2970 attr_array[1] = NULL;
2974 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
2975 &group_base, &group_count,
2976 LDAP_SCOPE_SUBTREE) != 0))
2979 if (group_count != 1)
2981 linklist_free(group_base);
2982 com_err(whoami, 0, "Unable to process group security template: %s - "
2983 "security not set", GroupSecurityTemplate);
2987 strcpy(TemplateDn, group_base->dn);
2988 strcpy(TemplateSamName, group_base->value);
2989 linklist_free(group_base);
2993 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
2994 rc = ldap_search_ext_s(ldap_handle,
3006 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3008 com_err(whoami, 0, "Unable to find group security template: %s - "
3009 "security not set", GroupSecurityTemplate);
3013 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
3015 if (ppsValues == NULL)
3017 com_err(whoami, 0, "Unable to find group security descriptor for group "
3018 "%s - security not set", GroupSecurityTemplate);
3022 if (AceSidCount != 0)
3024 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3027 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
3029 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3030 UserTemplateSidCount))
3032 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3040 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3041 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3047 hide_address_lists_v[0] = "TRUE";
3048 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3050 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3052 hide_address_lists_v[0] = NULL;
3053 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3060 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
3062 for (i = 0; i < n; i++)
3065 ldap_value_free_len(ppsValues);
3066 ldap_msgfree(psMsg);
3068 if (rc != LDAP_SUCCESS)
3070 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
3071 TargetGroupName, ldap_err2string(rc));
3073 if (AceSidCount != 0)
3076 "Trying to set security for group %s without admin.",
3079 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3080 HiddenGroup, "", ""))
3082 com_err(whoami, 0, "Unable to set security for group %s.",
3093 int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3094 char *group_membership, char *MoiraId)
3096 LK_ENTRY *group_base;
3102 if (!check_string(group_name))
3105 "Unable to process invalid LDAP list name %s", group_name);
3106 return(AD_INVALID_NAME);
3109 memset(filter, '\0', sizeof(filter));
3112 sprintf(temp, "%s,%s", group_ou_root, dn_path);
3114 if (rc = ad_get_group(ldap_handle, temp, group_name,
3115 group_membership, MoiraId,
3116 "distinguishedName", &group_base,
3117 &group_count, filter))
3120 if (group_count == 1)
3122 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
3124 linklist_free(group_base);
3125 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3126 group_name, ldap_err2string(rc));
3129 linklist_free(group_base);
3133 linklist_free(group_base);
3134 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
3135 return(AD_NO_GROUPS_FOUND);
3141 int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3147 return(N_SD_BER_BYTES);
3150 int process_lists(int ac, char **av, void *ptr)
3155 char group_membership[2];
3161 memset(group_ou, '\0', sizeof(group_ou));
3162 memset(group_membership, '\0', sizeof(group_membership));
3163 get_group_membership(group_membership, group_ou, &security_flag, av);
3164 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
3165 group_ou, group_membership, call_args[2],
3166 (char *)call_args[3], "");
3170 int member_list_build(int ac, char **av, void *ptr)
3178 strcpy(temp, av[ACE_NAME]);
3180 if (!check_string(temp))
3183 if (!strcmp(av[ACE_TYPE], "USER"))
3185 if (!((int)call_args[3] & MOIRA_USERS))
3188 else if (!strcmp(av[ACE_TYPE], "STRING"))
3192 if((s = strchr(temp, '@')) == (char *) NULL)
3194 strcat(temp, "@mit.edu");
3197 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3199 s = strrchr(temp, '.');
3201 strcat(s, ".mit.edu");
3205 if (!((int)call_args[3] & MOIRA_STRINGS))
3208 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3212 else if (!strcmp(av[ACE_TYPE], "LIST"))
3214 if (!((int)call_args[3] & MOIRA_LISTS))
3217 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
3219 if (!((int)call_args[3] & MOIRA_KERBEROS))
3222 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3230 linklist = member_base;
3234 if (!strcasecmp(temp, linklist->member))
3237 linklist = linklist->next;
3240 linklist = calloc(1, sizeof(LK_ENTRY));
3242 linklist->dn = NULL;
3243 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3244 strcpy(linklist->list, call_args[2]);
3245 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3246 strcpy(linklist->type, av[ACE_TYPE]);
3247 linklist->member = calloc(1, strlen(temp) + 1);
3248 strcpy(linklist->member, temp);
3249 linklist->next = member_base;
3250 member_base = linklist;
3255 int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
3256 char *group_ou, char *group_membership, char *user_name,
3257 char *UserOu, char *MoiraId)
3259 char distinguished_name[1024];
3263 char *attr_array[3];
3268 LK_ENTRY *group_base;
3272 if (!check_string(group_name))
3273 return(AD_INVALID_NAME);
3275 memset(filter, '\0', sizeof(filter));
3279 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3280 group_membership, MoiraId,
3281 "distinguishedName", &group_base,
3282 &group_count, filter))
3285 if (group_count != 1)
3287 com_err(whoami, 0, "Unable to find list %s in AD",
3289 linklist_free(group_base);
3295 strcpy(distinguished_name, group_base->value);
3296 linklist_free(group_base);
3300 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3302 modvalues[0] = temp;
3303 modvalues[1] = NULL;
3306 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3308 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3310 for (i = 0; i < n; i++)
3313 if (rc == LDAP_UNWILLING_TO_PERFORM)
3316 if (rc != LDAP_SUCCESS)
3318 com_err(whoami, 0, "Unable to modify list %s members : %s",
3319 group_name, ldap_err2string(rc));
3323 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3327 if(!strcmp(UserOu, contact_ou) &&
3328 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3330 memset(temp, '\0', sizeof(temp));
3331 strcpy(temp, user_name);
3332 s = strchr(temp, '@');
3335 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3337 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3338 &group_base, &group_count,
3339 LDAP_SCOPE_SUBTREE) != 0))
3345 linklist_free(group_base);
3350 sprintf(filter, "(distinguishedName=%s)", temp);
3351 attr_array[0] = "memberOf";
3352 attr_array[1] = NULL;
3354 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3355 &group_base, &group_count,
3356 LDAP_SCOPE_SUBTREE) != 0))
3362 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3364 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3374 int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
3375 char *group_ou, char *group_membership, char *user_name,
3376 char *UserOu, char *MoiraId)
3378 char distinguished_name[1024];
3386 LK_ENTRY *group_base;
3389 if (!check_string(group_name))
3390 return(AD_INVALID_NAME);
3393 memset(filter, '\0', sizeof(filter));
3397 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3398 group_membership, MoiraId,
3399 "distinguishedName", &group_base,
3400 &group_count, filter))
3403 if (group_count != 1)
3405 linklist_free(group_base);
3408 com_err(whoami, 0, "Unable to find list %s in AD",
3410 return(AD_MULTIPLE_GROUPS_FOUND);
3413 strcpy(distinguished_name, group_base->value);
3414 linklist_free(group_base);
3418 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3419 modvalues[0] = temp;
3420 modvalues[1] = NULL;
3423 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3425 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
3427 if (rc == LDAP_ALREADY_EXISTS)
3430 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3432 if (rc == LDAP_UNWILLING_TO_PERFORM)
3436 for (i = 0; i < n; i++)
3439 if (rc != LDAP_SUCCESS)
3441 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
3442 user_name, group_name, ldap_err2string(rc));
3448 int contact_remove_email(LDAP *ld, char *bind_path,
3449 LK_ENTRY **linklist_base, int linklist_current)
3453 char *mail_v[] = {NULL, NULL};
3461 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3462 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3463 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3464 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3467 gPtr = (*linklist_base);
3470 rc = ldap_modify_s(ld, gPtr->dn, mods);
3472 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3474 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3475 gPtr->dn, ldap_err2string(rc));
3482 for (i = 0; i < n; i++)
3488 int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3491 LK_ENTRY *group_base;
3494 char cn_user_name[256];
3495 char contact_name[256];
3496 char mail_nickname[256];
3497 char proxy_address_internal[256];
3498 char proxy_address_external[256];
3499 char target_address[256];
3500 char internal_contact_name[256];
3503 char mit_address_book[256];
3504 char default_address_book[256];
3505 char contact_address_book[256];
3506 char *email_v[] = {NULL, NULL};
3507 char *cn_v[] = {NULL, NULL};
3508 char *contact_v[] = {NULL, NULL};
3509 char *mail_nickname_v[] = {NULL, NULL};
3510 char *proxy_address_internal_v[] = {NULL, NULL};
3511 char *proxy_address_external_v[] = {NULL, NULL};
3512 char *target_address_v[] = {NULL, NULL};
3513 char *mit_address_book_v[] = {NULL, NULL};
3514 char *default_address_book_v[] = {NULL, NULL};
3515 char *contact_address_book_v[] = {NULL, NULL};
3516 char *hide_address_lists_v[] = {NULL, NULL};
3517 char *attr_array[3];
3519 char *objectClass_v[] = {"top", "person",
3520 "organizationalPerson",
3522 char *name_v[] = {NULL, NULL};
3523 char *desc_v[] = {NULL, NULL};
3529 if (!check_string(user))
3531 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
3532 return(AD_INVALID_NAME);
3536 strcpy(contact_name, mail);
3537 strcpy(internal_contact_name, mail);
3539 if((s = strchr(internal_contact_name, '@')) != NULL) {
3543 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
3544 sprintf(target_address, "SMTP:%s", contact_name);
3545 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3546 sprintf(mail_nickname, "%s", internal_contact_name);
3548 cn_v[0] = cn_user_name;
3549 contact_v[0] = contact_name;
3551 desc_v[0] = "Auto account created by Moira";
3553 proxy_address_internal_v[0] = proxy_address_internal;
3554 proxy_address_external_v[0] = proxy_address_external;
3555 mail_nickname_v[0] = mail_nickname;
3556 target_address_v[0] = target_address;
3557 mit_address_book_v[0] = mit_address_book;
3558 default_address_book_v[0] = default_address_book;
3559 contact_address_book_v[0] = contact_address_book;
3560 strcpy(new_dn, cn_user_name);
3563 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3564 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3565 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3566 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3567 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3571 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3576 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3577 attr_array[0] = "cn";
3578 attr_array[1] = NULL;
3580 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3581 &group_base, &group_count,
3582 LDAP_SCOPE_SUBTREE)) != 0)
3584 com_err(whoami, 0, "Unable to process contact %s : %s",
3585 user, ldap_err2string(rc));
3591 com_err(whoami, 0, "Object already exists with name %s",
3596 linklist_free(group_base);
3600 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3601 attr_array[0] = "cn";
3602 attr_array[1] = NULL;
3604 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3605 &group_base, &group_count,
3606 LDAP_SCOPE_SUBTREE)) != 0)
3608 com_err(whoami, 0, "Unable to process contact %s : %s",
3609 user, ldap_err2string(rc));
3615 com_err(whoami, 0, "Object already exists with name %s",
3620 linklist_free(group_base);
3624 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3625 attr_array[0] = "cn";
3626 attr_array[1] = NULL;
3628 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3629 &group_base, &group_count,
3630 LDAP_SCOPE_SUBTREE)) != 0)
3632 com_err(whoami, 0, "Unable to process contact %s : %s",
3633 user, ldap_err2string(rc));
3639 com_err(whoami, 0, "Object already exists with name %s",
3644 linklist_free(group_base);
3648 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3649 attr_array[0] = "cn";
3650 attr_array[1] = NULL;
3652 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3653 &group_base, &group_count,
3654 LDAP_SCOPE_SUBTREE)) != 0)
3656 com_err(whoami, 0, "Unable to process contact %s : %s",
3657 user, ldap_err2string(rc));
3663 com_err(whoami, 0, "Object already exists with name %s",
3668 linklist_free(group_base);
3672 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3673 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3674 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3675 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3677 hide_address_lists_v[0] = "TRUE";
3678 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3685 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3687 for (i = 0; i < n; i++)
3692 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS))
3696 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
3697 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
3698 ADD_ATTR("proxyAddresses", proxy_address_external_v,
3700 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
3702 hide_address_lists_v[0] = "TRUE";
3703 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3707 rc = ldap_modify_s(ld, new_dn, mods);
3711 com_err(whoami, 0, "Unable to update contact %s", mail);
3714 for (i = 0; i < n; i++)
3719 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3722 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3723 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3724 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3725 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3726 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3728 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
3730 for (i = 0; i < n; i++)
3734 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3736 com_err(whoami, 0, "Unable to create contact %s : %s",
3737 user, ldap_err2string(rc));
3744 int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3745 char *Uid, char *MitId, char *MoiraId, int State,
3746 char *WinHomeDir, char *WinProfileDir, char *first,
3747 char *middle, char *last)
3750 LK_ENTRY *group_base;
3752 char distinguished_name[512];
3753 char displayName[256];
3754 char *mitMoiraId_v[] = {NULL, NULL};
3755 char *uid_v[] = {NULL, NULL};
3756 char *mitid_v[] = {NULL, NULL};
3757 char *homedir_v[] = {NULL, NULL};
3758 char *winProfile_v[] = {NULL, NULL};
3759 char *drives_v[] = {NULL, NULL};
3760 char *userAccountControl_v[] = {NULL, NULL};
3761 char *alt_recipient_v[] = {NULL, NULL};
3762 char *hide_address_lists_v[] = {NULL, NULL};
3763 char *mail_v[] = {NULL, NULL};
3764 char userAccountControlStr[80];
3769 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
3770 UF_PASSWD_CANT_CHANGE;
3772 char *attr_array[3];
3775 char contact_mail[256];
3776 char filter_exp[1024];
3777 char search_path[512];
3778 char TemplateDn[512];
3779 char TemplateSamName[128];
3780 char alt_recipient[256];
3781 char acBERBuf[N_SD_BER_BYTES];
3782 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3783 { N_SD_BER_BYTES, acBERBuf },
3785 LDAPControl *apsServerControls[] = {&sControl, NULL};
3787 LDAP_BERVAL **ppsValues;
3791 char *homeServerName;
3793 char search_string[256];
3795 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3796 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3797 BEREncodeSecurityBits(dwInfo, acBERBuf);
3799 if (!check_string(user_name))
3801 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
3803 return(AD_INVALID_NAME);
3806 memset(contact_mail, '\0', sizeof(contact_mail));
3807 sprintf(contact_mail, "%s@mit.edu", user_name);
3808 memset(mail, '\0', sizeof(mail));
3809 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
3810 memset(alt_recipient, '\0', sizeof(alt_recipient));
3811 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
3813 sprintf(search_string, "@%s", uppercase(ldap_domain));
3817 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
3819 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
3826 memset(displayName, '\0', sizeof(displayName));
3828 if (strlen(MoiraId) != 0)
3830 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
3831 attr_array[0] = "cn";
3832 attr_array[1] = NULL;
3833 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3834 &group_base, &group_count,
3835 LDAP_SCOPE_SUBTREE)) != 0)
3837 com_err(whoami, 0, "Unable to process user %s : %s",
3838 user_name, ldap_err2string(rc));
3843 if (group_count != 1)
3845 linklist_free(group_base);
3848 sprintf(filter, "(sAMAccountName=%s)", user_name);
3849 attr_array[0] = "cn";
3850 attr_array[1] = NULL;
3851 sprintf(temp, "%s,%s", user_ou, dn_path);
3852 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
3853 &group_base, &group_count,
3854 LDAP_SCOPE_SUBTREE)) != 0)
3856 com_err(whoami, 0, "Unable to process user %s : %s",
3857 user_name, ldap_err2string(rc));
3862 if (group_count != 1)
3864 com_err(whoami, 0, "Unable to find user %s in AD",
3866 linklist_free(group_base);
3867 return(AD_NO_USER_FOUND);
3870 strcpy(distinguished_name, group_base->dn);
3872 linklist_free(group_base);
3875 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
3876 rc = attribute_update(ldap_handle, distinguished_name, MitId,
3877 "employeeID", user_name);
3879 rc = attribute_update(ldap_handle, distinguished_name, "none",
3880 "employeeID", user_name);
3883 strcat(displayName, first);
3886 if(strlen(middle)) {
3888 strcat(displayName, " ");
3890 strcat(displayName, middle);
3894 if(strlen(middle) || strlen(first))
3895 strcat(displayName, " ");
3897 strcat(displayName, last);
3900 if(strlen(displayName))
3901 rc = attribute_update(ldap_handle, distinguished_name, displayName,
3902 "displayName", user_name);
3904 rc = attribute_update(ldap_handle, distinguished_name, user_name,
3905 "displayName", user_name);
3908 rc = attribute_update(ldap_handle, distinguished_name, first,
3909 "givenName", user_name);
3911 rc = attribute_update(ldap_handle, distinguished_name, "",
3912 "givenName", user_name);
3914 if(strlen(middle) == 1)
3915 rc = attribute_update(ldap_handle, distinguished_name, middle,
3916 "initials", user_name);
3918 rc = attribute_update(ldap_handle, distinguished_name, "",
3919 "initials", user_name);
3922 rc = attribute_update(ldap_handle, distinguished_name, last,
3925 rc = attribute_update(ldap_handle, distinguished_name, "",
3928 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
3930 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
3931 "mitMoiraId", user_name);
3938 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
3942 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
3945 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
3947 userAccountControl |= UF_ACCOUNTDISABLE;
3951 hide_address_lists_v[0] = "TRUE";
3952 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3960 hide_address_lists_v[0] = NULL;
3961 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3966 sprintf(userAccountControlStr, "%ld", userAccountControl);
3967 userAccountControl_v[0] = userAccountControlStr;
3968 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
3972 if (rc = moira_connect())
3974 critical_alert("AD incremental",
3975 "Error contacting Moira server : %s",
3980 argv[0] = user_name;
3982 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
3984 if(!strcmp(save_argv[1], "EXCHANGE") ||
3985 (strstr(save_argv[3], search_string) != NULL))
3987 alt_recipient_v[0] = NULL;
3988 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
3990 argv[0] = exchange_acl;
3992 argv[2] = user_name;
3994 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
3996 if ((rc) && (rc != MR_EXISTS))
3998 com_err(whoami, 0, "Unable to add user %s to %s: %s",
3999 user_name, exchange_acl, error_message(rc));
4004 alt_recipient_v[0] = alt_recipient;
4005 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4007 argv[0] = exchange_acl;
4009 argv[2] = user_name;
4011 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4013 if ((rc) && (rc != MR_NO_MATCH))
4016 "Unable to remove user %s from %s: %s, %d",
4017 user_name, exchange_acl, error_message(rc), rc);
4023 alt_recipient_v[0] = alt_recipient;
4024 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4026 argv[0] = exchange_acl;
4028 argv[2] = user_name;
4030 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4032 if ((rc) && (rc != MR_NO_MATCH))
4035 "Unable to remove user %s from %s: %s, %d",
4036 user_name, exchange_acl, error_message(rc), rc);
4044 mail_v[0] = contact_mail;
4045 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4048 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4049 WinProfileDir, homedir_v, winProfile_v,
4050 drives_v, mods, LDAP_MOD_REPLACE, n);
4052 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4053 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4054 attr_array[0] = "sAMAccountName";
4055 attr_array[1] = NULL;
4059 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
4060 &group_base, &group_count,
4061 LDAP_SCOPE_SUBTREE) != 0))
4064 if (group_count != 1)
4066 com_err(whoami, 0, "Unable to process user security template: %s - "
4067 "security not set", "UserTemplate.u");
4071 strcpy(TemplateDn, group_base->dn);
4072 strcpy(TemplateSamName, group_base->value);
4073 linklist_free(group_base);
4077 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4078 filter_exp, NULL, 0, apsServerControls, NULL,
4081 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4083 com_err(whoami, 0, "Unable to find user security template: %s - "
4084 "security not set", "UserTemplate.u");
4088 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
4090 if (ppsValues == NULL)
4092 com_err(whoami, 0, "Unable to find user security template: %s - "
4093 "security not set", "UserTemplate.u");
4097 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4098 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4102 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4103 mods)) != LDAP_SUCCESS)
4105 OldUseSFU30 = UseSFU30;
4106 SwitchSFU(mods, &UseSFU30, n);
4107 if (OldUseSFU30 != UseSFU30)
4108 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4111 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4112 user_name, ldap_err2string(rc));
4116 for (i = 0; i < n; i++)
4122 int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4130 char contact_mail[256];
4131 char proxy_address[256];
4132 char query_base_dn[256];
4134 char *userPrincipalName_v[] = {NULL, NULL};
4135 char *altSecurityIdentities_v[] = {NULL, NULL};
4136 char *name_v[] = {NULL, NULL};
4137 char *samAccountName_v[] = {NULL, NULL};
4138 char *mail_v[] = {NULL, NULL};
4139 char *mail_nickname_v[] = {NULL, NULL};
4140 char *proxy_address_v[] = {NULL, NULL};
4141 char *query_base_dn_v[] = {NULL, NULL};
4146 if (!check_string(before_user_name))
4149 "Unable to process invalid LDAP user name %s", before_user_name);
4150 return(AD_INVALID_NAME);
4153 if (!check_string(user_name))
4156 "Unable to process invalid LDAP user name %s", user_name);
4157 return(AD_INVALID_NAME);
4160 strcpy(user_name, user_name);
4161 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4162 sprintf(new_dn, "cn=%s", user_name);
4163 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4164 sprintf(contact_mail, "%s@mit.edu", user_name);
4165 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4167 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4168 NULL, NULL)) != LDAP_SUCCESS)
4170 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4171 before_user_name, user_name, ldap_err2string(rc));
4177 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4180 if(rc = ldap_delete_s(ldap_handle, temp))
4182 com_err(whoami, 0, "Unable to delete user contact for %s",
4186 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4188 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4192 name_v[0] = user_name;
4193 sprintf(upn, "%s@%s", user_name, ldap_domain);
4194 userPrincipalName_v[0] = upn;
4195 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4196 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4197 altSecurityIdentities_v[0] = temp;
4198 samAccountName_v[0] = user_name;
4200 mail_nickname_v[0] = user_name;
4201 proxy_address_v[0] = proxy_address;
4202 query_base_dn_v[0] = query_base_dn;
4205 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4206 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4207 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4208 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4212 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4213 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4214 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4215 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4219 mail_v[0] = contact_mail;
4220 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4225 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4227 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4230 "Unable to modify user data for %s after renaming : %s",
4231 user_name, ldap_err2string(rc));
4234 for (i = 0; i < n; i++)
4240 int user_create(int ac, char **av, void *ptr)
4244 char user_name[256];
4248 char contact_mail[256];
4249 char proxy_address[256];
4250 char mail_nickname[256];
4251 char query_base_dn[256];
4252 char displayName[256];
4253 char address_book[256];
4254 char alt_recipient[256];
4255 char *cn_v[] = {NULL, NULL};
4256 char *objectClass_v[] = {"top", "person",
4257 "organizationalPerson",
4260 char *samAccountName_v[] = {NULL, NULL};
4261 char *altSecurityIdentities_v[] = {NULL, NULL};
4262 char *mitMoiraId_v[] = {NULL, NULL};
4263 char *name_v[] = {NULL, NULL};
4264 char *desc_v[] = {NULL, NULL};
4265 char *userPrincipalName_v[] = {NULL, NULL};
4266 char *userAccountControl_v[] = {NULL, NULL};
4267 char *uid_v[] = {NULL, NULL};
4268 char *mitid_v[] = {NULL, NULL};
4269 char *homedir_v[] = {NULL, NULL};
4270 char *winProfile_v[] = {NULL, NULL};
4271 char *drives_v[] = {NULL, NULL};
4272 char *mail_v[] = {NULL, NULL};
4273 char *givenName_v[] = {NULL, NULL};
4274 char *sn_v[] = {NULL, NULL};
4275 char *initials_v[] = {NULL, NULL};
4276 char *displayName_v[] = {NULL, NULL};
4277 char *proxy_address_v[] = {NULL, NULL};
4278 char *mail_nickname_v[] = {NULL, NULL};
4279 char *query_base_dn_v[] = {NULL, NULL};
4280 char *address_book_v[] = {NULL, NULL};
4281 char *homeMDB_v[] = {NULL, NULL};
4282 char *homeServerName_v[] = {NULL, NULL};
4283 char *mdbUseDefaults_v[] = {NULL, NULL};
4284 char *mailbox_guid_v[] = {NULL, NULL};
4285 char *user_culture_v[] = {NULL, NULL};
4286 char *user_account_control_v[] = {NULL, NULL};
4287 char *msexch_version_v[] = {NULL, NULL};
4288 char *alt_recipient_v[] = {NULL, NULL};
4289 char *hide_address_lists_v[] = {NULL, NULL};
4290 char userAccountControlStr[80];
4292 char filter_exp[1024];
4293 char search_path[512];
4294 char *attr_array[3];
4295 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4296 UF_PASSWD_CANT_CHANGE;
4302 char WinHomeDir[1024];
4303 char WinProfileDir[1024];
4305 char *homeServerName;
4307 char acBERBuf[N_SD_BER_BYTES];
4308 LK_ENTRY *group_base;
4310 char TemplateDn[512];
4311 char TemplateSamName[128];
4312 LDAP_BERVAL **ppsValues;
4313 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4314 { N_SD_BER_BYTES, acBERBuf },
4316 LDAPControl *apsServerControls[] = {&sControl, NULL};
4320 char search_string[256];
4324 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4325 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4326 BEREncodeSecurityBits(dwInfo, acBERBuf);
4328 if (!check_string(av[U_NAME]))
4330 callback_rc = AD_INVALID_NAME;
4331 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4333 return(AD_INVALID_NAME);
4336 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4337 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4338 memset(displayName, '\0', sizeof(displayName));
4339 memset(query_base_dn, '\0', sizeof(query_base_dn));
4340 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4341 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4342 strcpy(user_name, av[U_NAME]);
4343 sprintf(upn, "%s@%s", user_name, ldap_domain);
4344 sprintf(sam_name, "%s", av[U_NAME]);
4346 if(strlen(av[U_FIRST])) {
4347 strcat(displayName, av[U_FIRST]);
4350 if(strlen(av[U_MIDDLE])) {
4351 if(strlen(av[U_FIRST]))
4352 strcat(displayName, " ");
4354 strcat(displayName, av[U_MIDDLE]);
4357 if(strlen(av[U_LAST])) {
4358 if(strlen(av[U_FIRST]) || strlen(av[U_LAST]))
4359 strcat(displayName, " ");
4361 strcat(displayName, av[U_LAST]);
4364 samAccountName_v[0] = sam_name;
4365 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4366 (atoi(av[U_STATE]) != US_REGISTERED))
4368 userAccountControl |= UF_ACCOUNTDISABLE;
4372 hide_address_lists_v[0] = "TRUE";
4373 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4378 sprintf(userAccountControlStr, "%ld", userAccountControl);
4379 userAccountControl_v[0] = userAccountControlStr;
4380 userPrincipalName_v[0] = upn;
4381 cn_v[0] = user_name;
4382 name_v[0] = user_name;
4383 desc_v[0] = "Auto account created by Moira";
4385 givenName_v[0] = av[U_FIRST];
4386 sn_v[0] = av[U_LAST];
4387 displayName_v[0] = displayName;
4388 mail_nickname_v[0] = user_name;
4390 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4391 altSecurityIdentities_v[0] = temp;
4392 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
4393 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4394 sprintf(contact_mail, "%s@mit.edu", user_name);
4395 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4396 query_base_dn_v[0] = query_base_dn;
4397 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4399 sprintf(search_string, "@%s", uppercase(ldap_domain));
4404 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4407 com_err(whoami, 0, "Unable to create user contact %s",
4411 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4414 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4418 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4419 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4421 homeMDB_v[0] = homeMDB;
4422 homeServerName_v[0] = homeServerName;
4426 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4427 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4428 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
4429 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
4430 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
4431 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
4432 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
4436 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
4437 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4438 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
4439 mdbUseDefaults_v[0] = "TRUE";
4440 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
4441 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
4443 argv[0] = user_name;
4445 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4447 if(!strcmp(save_argv[1], "EXCHANGE") ||
4448 (strstr(save_argv[3], search_string) != NULL))
4450 argv[0] = exchange_acl;
4452 argv[2] = user_name;
4454 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4456 if ((rc) && (rc != MR_EXISTS))
4458 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4459 user_name, exchange_acl, error_message(rc));
4464 alt_recipient_v[0] = alt_recipient;
4465 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4470 alt_recipient_v[0] = alt_recipient;
4471 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4473 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
4478 mail_v[0] = contact_mail;
4479 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
4482 if(strlen(av[U_FIRST])) {
4483 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
4486 if(strlen(av[U_LAST])) {
4487 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
4490 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
4491 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
4493 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4496 if (strlen(av[U_MIDDLE]) == 1) {
4497 initials_v[0] = av[U_MIDDLE];
4498 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
4501 if (strlen(call_args[2]) != 0)
4503 mitMoiraId_v[0] = call_args[2];
4504 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
4507 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
4509 if (strlen(av[U_UID]) != 0)
4511 uid_v[0] = av[U_UID];
4512 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
4516 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
4520 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
4524 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
4525 mitid_v[0] = av[U_MITID];
4527 mitid_v[0] = "none";
4529 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
4531 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
4532 WinProfileDir, homedir_v, winProfile_v,
4533 drives_v, mods, LDAP_MOD_ADD, n);
4535 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4536 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
4537 attr_array[0] = "sAMAccountName";
4538 attr_array[1] = NULL;
4542 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
4543 attr_array, &group_base, &group_count,
4544 LDAP_SCOPE_SUBTREE) != 0))
4547 if (group_count != 1)
4549 com_err(whoami, 0, "Unable to process user security template: %s - "
4550 "security not set", "UserTemplate.u");
4554 strcpy(TemplateDn, group_base->dn);
4555 strcpy(TemplateSamName, group_base->value);
4556 linklist_free(group_base);
4560 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE,
4561 filter_exp, NULL, 0, apsServerControls, NULL,
4564 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
4566 com_err(whoami, 0, "Unable to find user security template: %s - "
4567 "security not set", "UserTemplate.u");
4571 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
4572 "ntSecurityDescriptor");
4573 if (ppsValues == NULL)
4575 com_err(whoami, 0, "Unable to find user security template: %s - "
4576 "security not set", "UserTemplate.u");
4580 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4581 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4585 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4587 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4589 OldUseSFU30 = UseSFU30;
4590 SwitchSFU(mods, &UseSFU30, n);
4591 if (OldUseSFU30 != UseSFU30)
4592 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4595 for (i = 0; i < n; i++)
4598 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4600 com_err(whoami, 0, "Unable to create user %s : %s",
4601 user_name, ldap_err2string(rc));
4606 if ((rc == LDAP_SUCCESS) && (SetPassword))
4608 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4610 ad_kdc_disconnect();
4611 if (!ad_server_connect(default_server, ldap_domain))
4613 com_err(whoami, 0, "Unable to set password for user %s : %s",
4615 "cannot get changepw ticket from windows domain");
4619 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4621 com_err(whoami, 0, "Unable to set password for user %s "
4622 ": %ld", user_name, rc);
4631 int user_change_status(LDAP *ldap_handle, char *dn_path,
4632 char *user_name, char *MoiraId,
4636 char *attr_array[3];
4638 char distinguished_name[1024];
4640 char *mitMoiraId_v[] = {NULL, NULL};
4642 LK_ENTRY *group_base;
4649 if (!check_string(user_name))
4651 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4653 return(AD_INVALID_NAME);
4659 if (strlen(MoiraId) != 0)
4661 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4662 attr_array[0] = "UserAccountControl";
4663 attr_array[1] = NULL;
4664 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4665 &group_base, &group_count,
4666 LDAP_SCOPE_SUBTREE)) != 0)
4668 com_err(whoami, 0, "Unable to process user %s : %s",
4669 user_name, ldap_err2string(rc));
4674 if (group_count != 1)
4676 linklist_free(group_base);
4679 sprintf(filter, "(sAMAccountName=%s)", user_name);
4680 attr_array[0] = "UserAccountControl";
4681 attr_array[1] = NULL;
4682 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4683 &group_base, &group_count,
4684 LDAP_SCOPE_SUBTREE)) != 0)
4686 com_err(whoami, 0, "Unable to process user %s : %s",
4687 user_name, ldap_err2string(rc));
4692 if (group_count != 1)
4694 linklist_free(group_base);
4695 com_err(whoami, 0, "Unable to find user %s in AD",
4697 return(LDAP_NO_SUCH_OBJECT);
4700 strcpy(distinguished_name, group_base->dn);
4701 ulongValue = atoi((*group_base).value);
4703 if (operation == MEMBER_DEACTIVATE)
4704 ulongValue |= UF_ACCOUNTDISABLE;
4706 ulongValue &= ~UF_ACCOUNTDISABLE;
4708 sprintf(temp, "%ld", ulongValue);
4710 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
4711 temp, &modvalues, REPLACE)) == 1)
4714 linklist_free(group_base);
4718 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
4720 if (strlen(MoiraId) != 0)
4722 mitMoiraId_v[0] = MoiraId;
4723 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
4727 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4729 for (i = 0; i < n; i++)
4732 free_values(modvalues);
4734 if (rc != LDAP_SUCCESS)
4736 com_err(whoami, 0, "Unable to change status of user %s : %s",
4737 user_name, ldap_err2string(rc));
4744 int user_delete(LDAP *ldap_handle, char *dn_path,
4745 char *u_name, char *MoiraId)
4748 char *attr_array[3];
4749 char distinguished_name[1024];
4750 char user_name[512];
4751 LK_ENTRY *group_base;
4756 if (!check_string(u_name))
4757 return(AD_INVALID_NAME);
4759 strcpy(user_name, u_name);
4763 if (strlen(MoiraId) != 0)
4765 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
4766 attr_array[0] = "name";
4767 attr_array[1] = NULL;
4768 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4769 &group_base, &group_count,
4770 LDAP_SCOPE_SUBTREE)) != 0)
4772 com_err(whoami, 0, "Unable to process user %s : %s",
4773 user_name, ldap_err2string(rc));
4778 if (group_count != 1)
4780 linklist_free(group_base);
4783 sprintf(filter, "(sAMAccountName=%s)", user_name);
4784 attr_array[0] = "name";
4785 attr_array[1] = NULL;
4786 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
4787 &group_base, &group_count,
4788 LDAP_SCOPE_SUBTREE)) != 0)
4790 com_err(whoami, 0, "Unable to process user %s : %s",
4791 user_name, ldap_err2string(rc));
4796 if (group_count != 1)
4798 com_err(whoami, 0, "Unable to find user %s in AD",
4803 strcpy(distinguished_name, group_base->dn);
4805 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
4807 com_err(whoami, 0, "Unable to process user %s : %s",
4808 user_name, ldap_err2string(rc));
4811 /* Need to add code to delete mit.edu contact */
4815 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
4817 if(rc = ldap_delete_s(ldap_handle, temp))
4819 com_err(whoami, 0, "Unable to delete user contact for %s",
4825 linklist_free(group_base);
4830 void linklist_free(LK_ENTRY *linklist_base)
4832 LK_ENTRY *linklist_previous;
4834 while (linklist_base != NULL)
4836 if (linklist_base->dn != NULL)
4837 free(linklist_base->dn);
4839 if (linklist_base->attribute != NULL)
4840 free(linklist_base->attribute);
4842 if (linklist_base->value != NULL)
4843 free(linklist_base->value);
4845 if (linklist_base->member != NULL)
4846 free(linklist_base->member);
4848 if (linklist_base->type != NULL)
4849 free(linklist_base->type);
4851 if (linklist_base->list != NULL)
4852 free(linklist_base->list);
4854 linklist_previous = linklist_base;
4855 linklist_base = linklist_previous->next;
4856 free(linklist_previous);
4860 void free_values(char **modvalues)
4866 if (modvalues != NULL)
4868 while (modvalues[i] != NULL)
4871 modvalues[i] = NULL;
4878 static int illegalchars[] = {
4879 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
4880 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
4881 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
4882 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
4883 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
4884 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
4885 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
4886 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
4887 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4888 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4889 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4890 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4891 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4892 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4893 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4894 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4897 int check_string(char *s)
4905 if (isupper(character))
4906 character = tolower(character);
4908 if (illegalchars[(unsigned) character])
4915 int check_container_name(char *s)
4923 if (isupper(character))
4924 character = tolower(character);
4926 if (character == ' ')
4929 if (illegalchars[(unsigned) character])
4936 int mr_connect_cl(char *server, char *client, int version, int auth)
4942 status = mr_connect(server);
4946 com_err(whoami, status, "while connecting to Moira");
4950 status = mr_motd(&motd);
4955 com_err(whoami, status, "while checking server status");
4961 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
4962 com_err(whoami, status, temp);
4967 status = mr_version(version);
4971 if (status == MR_UNKNOWN_PROC)
4974 status = MR_VERSION_HIGH;
4976 status = MR_SUCCESS;
4979 if (status == MR_VERSION_HIGH)
4981 com_err(whoami, 0, "Warning: This client is running newer code "
4982 "than the server.");
4983 com_err(whoami, 0, "Some operations may not work.");
4985 else if (status && status != MR_VERSION_LOW)
4987 com_err(whoami, status, "while setting query version number.");
4995 status = mr_krb5_auth(client);
4998 com_err(whoami, status, "while authenticating to Moira.");
5007 void AfsToWinAfs(char* path, char* winPath)
5011 strcpy(winPath, WINAFS);
5012 pathPtr = path + strlen(AFS);
5013 winPathPtr = winPath + strlen(WINAFS);
5017 if (*pathPtr == '/')
5020 *winPathPtr = *pathPtr;
5027 int GetAceInfo(int ac, char **av, void *ptr)
5034 strcpy(call_args[0], av[L_ACE_TYPE]);
5035 strcpy(call_args[1], av[L_ACE_NAME]);
5037 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5038 return(LDAP_SUCCESS);
5041 int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5044 char *attr_array[3];
5047 LK_ENTRY *group_base;
5052 sprintf(filter, "(sAMAccountName=%s)", Name);
5053 attr_array[0] = "sAMAccountName";
5054 attr_array[1] = NULL;
5056 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5057 &group_base, &group_count,
5058 LDAP_SCOPE_SUBTREE)) != 0)
5060 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5061 Name, ldap_err2string(rc));
5065 linklist_free(group_base);
5068 if (group_count == 0)
5076 int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5077 int UpdateGroup, int *ProcessGroup, char *maillist)
5080 char GroupName[256];
5086 char AceMembership[2];
5089 char *save_argv[U_END];
5093 com_err(whoami, 0, "ProcessAce disabled, skipping");
5097 strcpy(GroupName, Name);
5099 if (strcasecmp(Type, "LIST"))
5105 AceInfo[0] = AceType;
5106 AceInfo[1] = AceName;
5107 AceInfo[2] = AceMembership;
5109 memset(AceType, '\0', sizeof(AceType));
5110 memset(AceName, '\0', sizeof(AceName));
5111 memset(AceMembership, '\0', sizeof(AceMembership));
5112 memset(AceOu, '\0', sizeof(AceOu));
5115 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5117 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5118 GroupName, error_message(rc));
5124 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5128 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5131 strcpy(temp, AceName);
5133 if (!strcasecmp(AceType, "LIST"))
5134 sprintf(temp, "%s%s", AceName, group_suffix);
5138 if (checkADname(ldap_handle, dn_path, temp))
5140 (*ProcessGroup) = 1;
5143 if (!strcasecmp(AceInfo[0], "LIST"))
5145 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5146 AceMembership, 0, UpdateGroup, maillist))
5149 else if (!strcasecmp(AceInfo[0], "USER"))
5152 call_args[0] = (char *)ldap_handle;
5153 call_args[1] = dn_path;
5155 call_args[3] = NULL;
5158 if (rc = mr_query("get_user_account_by_login", 1, av,
5159 save_query_info, save_argv))
5161 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5166 if (rc = user_create(U_END, save_argv, call_args))
5168 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5175 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5185 if (!strcasecmp(AceType, "LIST"))
5187 if (!strcasecmp(GroupName, AceName))
5191 strcpy(GroupName, AceName);
5197 int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5198 char *group_name, char *group_ou, char *group_membership,
5199 int group_security_flag, int updateGroup, char *maillist)
5204 LK_ENTRY *group_base;
5207 char *attr_array[3];
5210 call_args[0] = (char *)ldap_handle;
5211 call_args[1] = dn_path;
5212 call_args[2] = group_name;
5213 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5214 call_args[4] = (char *)updateGroup;
5215 call_args[5] = MoiraId;
5217 call_args[7] = NULL;
5223 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5226 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5234 com_err(whoami, 0, "Unable to create list %s", group_name);
5235 return(callback_rc);
5241 int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
5242 char *group_ou, char *group_membership,
5243 int group_security_flag, char *MoiraId)
5253 com_err(whoami, 0, "Populating group %s", group_name);
5255 call_args[0] = (char *)ldap_handle;
5256 call_args[1] = dn_path;
5257 call_args[2] = group_name;
5258 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5259 call_args[4] = NULL;
5262 if (rc = mr_query("get_end_members_of_list", 1, av,
5263 member_list_build, call_args))
5265 com_err(whoami, 0, "Unable to populate list %s : %s",
5266 group_name, error_message(rc));
5270 if (member_base != NULL)
5276 if (!strcasecmp(ptr->type, "LIST"))
5284 if (!strcasecmp(ptr->type, "STRING"))
5286 if (contact_create(ldap_handle, dn_path, ptr->member,
5290 pUserOu = contact_ou;
5292 else if (!strcasecmp(ptr->type, "KERBEROS"))
5294 if (contact_create(ldap_handle, dn_path, ptr->member,
5298 pUserOu = kerberos_ou;
5301 rc = member_add(ldap_handle, dn_path, group_name,
5302 group_ou, group_membership, ptr->member,
5307 linklist_free(member_base);
5314 int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5315 char *group_name, char *group_ou, char *group_membership,
5316 int group_security_flag, int type, char *maillist)
5318 char before_desc[512];
5319 char before_name[256];
5320 char before_group_ou[256];
5321 char before_group_membership[2];
5322 char distinguishedName[256];
5323 char ad_distinguishedName[256];
5325 char *attr_array[3];
5326 int before_security_flag;
5329 LK_ENTRY *group_base;
5332 char ou_security[512];
5333 char ou_distribution[512];
5334 char ou_neither[512];
5336 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
5337 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
5339 memset(filter, '\0', sizeof(filter));
5343 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5345 "distinguishedName", &group_base,
5346 &group_count, filter))
5349 if (type == CHECK_GROUPS)
5351 if (group_count == 1)
5353 if (!strcasecmp(group_base->value, distinguishedName))
5355 linklist_free(group_base);
5360 linklist_free(group_base);
5362 if (group_count == 0)
5363 return(AD_NO_GROUPS_FOUND);
5365 if (group_count == 1)
5366 return(AD_WRONG_GROUP_DN_FOUND);
5368 return(AD_MULTIPLE_GROUPS_FOUND);
5371 if (group_count == 0)
5373 return(AD_NO_GROUPS_FOUND);
5376 if (group_count > 1)
5382 if (!strcasecmp(distinguishedName, ptr->value))
5390 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
5396 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
5400 linklist_free(group_base);
5401 return(AD_MULTIPLE_GROUPS_FOUND);
5408 if (strcasecmp(distinguishedName, ptr->value))
5409 rc = ldap_delete_s(ldap_handle, ptr->value);
5414 linklist_free(group_base);
5415 memset(filter, '\0', sizeof(filter));
5419 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5421 "distinguishedName", &group_base,
5422 &group_count, filter))
5425 if (group_count == 0)
5426 return(AD_NO_GROUPS_FOUND);
5428 if (group_count > 1)
5429 return(AD_MULTIPLE_GROUPS_FOUND);
5432 strcpy(ad_distinguishedName, group_base->value);
5433 linklist_free(group_base);
5437 attr_array[0] = "sAMAccountName";
5438 attr_array[1] = NULL;
5440 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5441 &group_base, &group_count,
5442 LDAP_SCOPE_SUBTREE)) != 0)
5444 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5445 MoiraId, ldap_err2string(rc));
5449 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
5451 if (!strcasecmp(ad_distinguishedName, distinguishedName))
5453 linklist_free(group_base);
5459 linklist_free(group_base);
5462 memset(ou_both, '\0', sizeof(ou_both));
5463 memset(ou_security, '\0', sizeof(ou_security));
5464 memset(ou_distribution, '\0', sizeof(ou_distribution));
5465 memset(ou_neither, '\0', sizeof(ou_neither));
5466 memset(before_name, '\0', sizeof(before_name));
5467 memset(before_desc, '\0', sizeof(before_desc));
5468 memset(before_group_membership, '\0', sizeof(before_group_membership));
5469 attr_array[0] = "name";
5470 attr_array[1] = NULL;
5472 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5473 &group_base, &group_count,
5474 LDAP_SCOPE_SUBTREE)) != 0)
5476 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
5477 MoiraId, ldap_err2string(rc));
5481 strcpy(before_name, group_base->value);
5482 linklist_free(group_base);
5485 attr_array[0] = "description";
5486 attr_array[1] = NULL;
5488 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5489 &group_base, &group_count,
5490 LDAP_SCOPE_SUBTREE)) != 0)
5493 "Unable to get list description with MoiraId = %s: %s",
5494 MoiraId, ldap_err2string(rc));
5498 if (group_count != 0)
5500 strcpy(before_desc, group_base->value);
5501 linklist_free(group_base);
5506 change_to_lower_case(ad_distinguishedName);
5507 strcpy(ou_both, group_ou_both);
5508 change_to_lower_case(ou_both);
5509 strcpy(ou_security, group_ou_security);
5510 change_to_lower_case(ou_security);
5511 strcpy(ou_distribution, group_ou_distribution);
5512 change_to_lower_case(ou_distribution);
5513 strcpy(ou_neither, group_ou_neither);
5514 change_to_lower_case(ou_neither);
5516 if (strstr(ad_distinguishedName, ou_both))
5518 strcpy(before_group_ou, group_ou_both);
5519 before_group_membership[0] = 'B';
5520 before_security_flag = 1;
5522 else if (strstr(ad_distinguishedName, ou_security))
5524 strcpy(before_group_ou, group_ou_security);
5525 before_group_membership[0] = 'S';
5526 before_security_flag = 1;
5528 else if (strstr(ad_distinguishedName, ou_distribution))
5530 strcpy(before_group_ou, group_ou_distribution);
5531 before_group_membership[0] = 'D';
5532 before_security_flag = 0;
5534 else if (strstr(ad_distinguishedName, ou_neither))
5536 strcpy(before_group_ou, group_ou_neither);
5537 before_group_membership[0] = 'N';
5538 before_security_flag = 0;
5541 return(AD_NO_OU_FOUND);
5543 rc = group_rename(ldap_handle, dn_path, before_name,
5544 before_group_membership,
5545 before_group_ou, before_security_flag, before_desc,
5546 group_name, group_membership, group_ou,
5547 group_security_flag,
5548 before_desc, MoiraId, filter, maillist);
5553 void change_to_lower_case(char *ptr)
5557 for (i = 0; i < (int)strlen(ptr); i++)
5559 ptr[i] = tolower(ptr[i]);
5563 int ad_get_group(LDAP *ldap_handle, char *dn_path,
5564 char *group_name, char *group_membership,
5565 char *MoiraId, char *attribute,
5566 LK_ENTRY **linklist_base, int *linklist_count,
5571 char *attr_array[3];
5574 (*linklist_base) = NULL;
5575 (*linklist_count) = 0;
5577 if (strlen(rFilter) != 0)
5579 strcpy(filter, rFilter);
5580 attr_array[0] = attribute;
5581 attr_array[1] = NULL;
5583 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5584 linklist_base, linklist_count,
5585 LDAP_SCOPE_SUBTREE)) != 0)
5587 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5588 MoiraId, ldap_err2string(rc));
5592 if ((*linklist_count) == 1)
5594 strcpy(rFilter, filter);
5599 linklist_free((*linklist_base));
5600 (*linklist_base) = NULL;
5601 (*linklist_count) = 0;
5603 if (strlen(MoiraId) != 0)
5605 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
5606 attr_array[0] = attribute;
5607 attr_array[1] = NULL;
5609 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5610 linklist_base, linklist_count,
5611 LDAP_SCOPE_SUBTREE)) != 0)
5613 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5614 MoiraId, ldap_err2string(rc));
5619 if ((*linklist_count) > 1)
5621 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
5622 pPtr = (*linklist_base);
5626 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
5631 linklist_free((*linklist_base));
5632 (*linklist_base) = NULL;
5633 (*linklist_count) = 0;
5636 if ((*linklist_count) == 1)
5638 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
5640 strcpy(rFilter, filter);
5645 linklist_free((*linklist_base));
5646 (*linklist_base) = NULL;
5647 (*linklist_count) = 0;
5648 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
5649 attr_array[0] = attribute;
5650 attr_array[1] = NULL;
5652 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5653 linklist_base, linklist_count,
5654 LDAP_SCOPE_SUBTREE)) != 0)
5656 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
5657 MoiraId, ldap_err2string(rc));
5661 if ((*linklist_count) == 1)
5663 strcpy(rFilter, filter);
5670 int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5673 char *attr_array[3];
5674 char SamAccountName[64];
5677 LK_ENTRY *group_base;
5683 if (strlen(MoiraId) != 0)
5685 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5686 attr_array[0] = "sAMAccountName";
5687 attr_array[1] = NULL;
5688 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5689 &group_base, &group_count,
5690 LDAP_SCOPE_SUBTREE)) != 0)
5692 com_err(whoami, 0, "Unable to process user %s : %s",
5693 UserName, ldap_err2string(rc));
5697 if (group_count > 1)
5699 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5705 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5706 gPtr->value, MoiraId);
5712 if (group_count != 1)
5714 linklist_free(group_base);
5717 sprintf(filter, "(sAMAccountName=%s)", UserName);
5718 attr_array[0] = "sAMAccountName";
5719 attr_array[1] = NULL;
5721 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5722 &group_base, &group_count,
5723 LDAP_SCOPE_SUBTREE)) != 0)
5725 com_err(whoami, 0, "Unable to process user %s : %s",
5726 UserName, ldap_err2string(rc));
5731 if (group_count != 1)
5733 linklist_free(group_base);
5734 return(AD_NO_USER_FOUND);
5737 strcpy(SamAccountName, group_base->value);
5738 linklist_free(group_base);
5742 if (strcmp(SamAccountName, UserName))
5744 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5751 void container_get_dn(char *src, char *dest)
5758 memset(array, '\0', 20 * sizeof(array[0]));
5760 if (strlen(src) == 0)
5782 strcpy(dest, "OU=");
5786 strcat(dest, array[n-1]);
5790 strcat(dest, ",OU=");
5797 void container_get_name(char *src, char *dest)
5802 if (strlen(src) == 0)
5822 void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5829 strcpy(cName, name);
5831 for (i = 0; i < (int)strlen(cName); i++)
5833 if (cName[i] == '/')
5836 av[CONTAINER_NAME] = cName;
5837 av[CONTAINER_DESC] = "";
5838 av[CONTAINER_LOCATION] = "";
5839 av[CONTAINER_CONTACT] = "";
5840 av[CONTAINER_TYPE] = "";
5841 av[CONTAINER_ID] = "";
5842 av[CONTAINER_ROWID] = "";
5843 rc = container_create(ldap_handle, dn_path, 7, av);
5845 if (rc == LDAP_SUCCESS)
5847 com_err(whoami, 0, "container %s created without a mitMoiraId",
5856 int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5857 char **before, int afterc, char **after)
5862 char new_dn_path[256];
5864 char distinguishedName[256];
5869 memset(cName, '\0', sizeof(cName));
5870 container_get_name(after[CONTAINER_NAME], cName);
5872 if (!check_container_name(cName))
5874 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5876 return(AD_INVALID_NAME);
5879 memset(distinguishedName, '\0', sizeof(distinguishedName));
5881 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5882 distinguishedName, beforec, before))
5885 if (strlen(distinguishedName) == 0)
5887 rc = container_create(ldap_handle, dn_path, afterc, after);
5891 strcpy(temp, after[CONTAINER_NAME]);
5894 for (i = 0; i < (int)strlen(temp); i++)
5904 container_get_dn(temp, dName);
5906 if (strlen(temp) != 0)
5907 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5909 sprintf(new_dn_path, "%s", dn_path);
5911 sprintf(new_cn, "OU=%s", cName);
5913 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
5915 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
5916 TRUE, NULL, NULL)) != LDAP_SUCCESS)
5918 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
5919 before[CONTAINER_NAME], after[CONTAINER_NAME],
5920 ldap_err2string(rc));
5924 memset(dName, '\0', sizeof(dName));
5925 container_get_dn(after[CONTAINER_NAME], dName);
5926 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
5931 int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
5933 char distinguishedName[256];
5936 memset(distinguishedName, '\0', sizeof(distinguishedName));
5938 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5939 distinguishedName, count, av))
5942 if (strlen(distinguishedName) == 0)
5945 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
5947 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
5948 container_move_objects(ldap_handle, dn_path, distinguishedName);
5950 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
5951 av[CONTAINER_NAME], ldap_err2string(rc));
5957 int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
5959 char *attr_array[3];
5960 LK_ENTRY *group_base;
5963 char *objectClass_v[] = {"top",
5964 "organizationalUnit",
5967 char *ou_v[] = {NULL, NULL};
5968 char *name_v[] = {NULL, NULL};
5969 char *moiraId_v[] = {NULL, NULL};
5970 char *desc_v[] = {NULL, NULL};
5971 char *managedBy_v[] = {NULL, NULL};
5974 char managedByDN[256];
5981 memset(filter, '\0', sizeof(filter));
5982 memset(dName, '\0', sizeof(dName));
5983 memset(cName, '\0', sizeof(cName));
5984 memset(managedByDN, '\0', sizeof(managedByDN));
5985 container_get_dn(av[CONTAINER_NAME], dName);
5986 container_get_name(av[CONTAINER_NAME], cName);
5988 if ((strlen(cName) == 0) || (strlen(dName) == 0))
5990 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5992 return(AD_INVALID_NAME);
5995 if (!check_container_name(cName))
5997 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5999 return(AD_INVALID_NAME);
6003 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6005 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6007 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
6009 if (strlen(av[CONTAINER_ROWID]) != 0)
6011 moiraId_v[0] = av[CONTAINER_ROWID];
6012 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6015 if (strlen(av[CONTAINER_DESC]) != 0)
6017 desc_v[0] = av[CONTAINER_DESC];
6018 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6021 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6023 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6025 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6028 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6029 kerberos_ou, dn_path);
6030 managedBy_v[0] = managedByDN;
6031 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6036 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6038 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6039 "(objectClass=user)))", av[CONTAINER_ID]);
6042 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6044 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6048 if (strlen(filter) != 0)
6050 attr_array[0] = "distinguishedName";
6051 attr_array[1] = NULL;
6054 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6056 &group_base, &group_count,
6057 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6059 if (group_count == 1)
6061 strcpy(managedByDN, group_base->value);
6062 managedBy_v[0] = managedByDN;
6063 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6065 linklist_free(group_base);
6075 sprintf(temp, "%s,%s", dName, dn_path);
6076 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
6078 for (i = 0; i < n; i++)
6081 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6083 com_err(whoami, 0, "Unable to create container %s : %s",
6084 cName, ldap_err2string(rc));
6088 if (rc == LDAP_ALREADY_EXISTS)
6090 if (strlen(av[CONTAINER_ROWID]) != 0)
6091 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6097 int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6098 char **before, int afterc, char **after)
6100 char distinguishedName[256];
6103 memset(distinguishedName, '\0', sizeof(distinguishedName));
6105 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6106 distinguishedName, afterc, after))
6109 if (strlen(distinguishedName) == 0)
6111 rc = container_create(ldap_handle, dn_path, afterc, after);
6115 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6116 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6122 int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6123 char *distinguishedName, int count,
6126 char *attr_array[3];
6127 LK_ENTRY *group_base;
6134 memset(filter, '\0', sizeof(filter));
6135 memset(dName, '\0', sizeof(dName));
6136 memset(cName, '\0', sizeof(cName));
6137 container_get_dn(av[CONTAINER_NAME], dName);
6138 container_get_name(av[CONTAINER_NAME], cName);
6140 if (strlen(dName) == 0)
6142 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6143 av[CONTAINER_NAME]);
6144 return(AD_INVALID_NAME);
6147 if (!check_container_name(cName))
6149 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6151 return(AD_INVALID_NAME);
6154 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6155 av[CONTAINER_ROWID]);
6156 attr_array[0] = "distinguishedName";
6157 attr_array[1] = NULL;
6161 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6162 &group_base, &group_count,
6163 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6165 if (group_count == 1)
6167 strcpy(distinguishedName, group_base->value);
6170 linklist_free(group_base);
6175 if (strlen(distinguishedName) == 0)
6177 sprintf(filter, "(&(objectClass=organizationalUnit)"
6178 "(distinguishedName=%s,%s))", dName, dn_path);
6179 attr_array[0] = "distinguishedName";
6180 attr_array[1] = NULL;
6184 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6185 &group_base, &group_count,
6186 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6188 if (group_count == 1)
6190 strcpy(distinguishedName, group_base->value);
6193 linklist_free(group_base);
6202 int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6203 char *distinguishedName, int count, char **av)
6205 char *attr_array[5];
6206 LK_ENTRY *group_base;
6211 char *moiraId_v[] = {NULL, NULL};
6212 char *desc_v[] = {NULL, NULL};
6213 char *managedBy_v[] = {NULL, NULL};
6214 char managedByDN[256];
6223 strcpy(ad_path, distinguishedName);
6225 if (strlen(dName) != 0)
6226 sprintf(ad_path, "%s,%s", dName, dn_path);
6228 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6231 if (strlen(av[CONTAINER_ID]) != 0)
6232 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6233 av[CONTAINER_ROWID]);
6235 attr_array[0] = "mitMoiraId";
6236 attr_array[1] = "description";
6237 attr_array[2] = "managedBy";
6238 attr_array[3] = NULL;
6242 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6243 &group_base, &group_count,
6244 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6246 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6247 av[CONTAINER_NAME], ldap_err2string(rc));
6251 memset(managedByDN, '\0', sizeof(managedByDN));
6252 memset(moiraId, '\0', sizeof(moiraId));
6253 memset(desc, '\0', sizeof(desc));
6258 if (!strcasecmp(pPtr->attribute, "description"))
6259 strcpy(desc, pPtr->value);
6260 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6261 strcpy(managedByDN, pPtr->value);
6262 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6263 strcpy(moiraId, pPtr->value);
6267 linklist_free(group_base);
6272 if (strlen(av[CONTAINER_ROWID]) != 0)
6274 moiraId_v[0] = av[CONTAINER_ROWID];
6275 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6278 if (strlen(av[CONTAINER_DESC]) != 0)
6280 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6285 if (strlen(desc) != 0)
6287 attribute_update(ldap_handle, ad_path, "", "description", dName);
6291 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6293 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6295 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6298 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6299 kerberos_ou, dn_path);
6300 managedBy_v[0] = managedByDN;
6301 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6305 if (strlen(managedByDN) != 0)
6307 attribute_update(ldap_handle, ad_path, "", "managedBy",
6314 memset(filter, '\0', sizeof(filter));
6316 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6318 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6319 "(objectClass=user)))", av[CONTAINER_ID]);
6322 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6324 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6328 if (strlen(filter) != 0)
6330 attr_array[0] = "distinguishedName";
6331 attr_array[1] = NULL;
6334 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6335 attr_array, &group_base, &group_count,
6336 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6338 if (group_count == 1)
6340 strcpy(managedByDN, group_base->value);
6341 managedBy_v[0] = managedByDN;
6342 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6346 if (strlen(managedByDN) != 0)
6348 attribute_update(ldap_handle, ad_path, "",
6349 "managedBy", dName);
6353 linklist_free(group_base);
6360 if (strlen(managedByDN) != 0)
6362 attribute_update(ldap_handle, ad_path, "", "managedBy",
6372 return(LDAP_SUCCESS);
6374 rc = ldap_modify_s(ldap_handle, ad_path, mods);
6376 for (i = 0; i < n; i++)
6379 if (rc != LDAP_SUCCESS)
6381 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6382 av[CONTAINER_NAME], ldap_err2string(rc));
6389 int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6391 char *attr_array[3];
6392 LK_ENTRY *group_base;
6399 int NumberOfEntries = 10;
6403 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6405 for (i = 0; i < 3; i++)
6407 memset(filter, '\0', sizeof(filter));
6411 strcpy(filter, "(!(|(objectClass=computer)"
6412 "(objectClass=organizationalUnit)))");
6413 attr_array[0] = "cn";
6414 attr_array[1] = NULL;
6418 strcpy(filter, "(objectClass=computer)");
6419 attr_array[0] = "cn";
6420 attr_array[1] = NULL;
6424 strcpy(filter, "(objectClass=organizationalUnit)");
6425 attr_array[0] = "ou";
6426 attr_array[1] = NULL;
6431 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
6432 &group_base, &group_count,
6433 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6438 if (group_count == 0)
6445 if (!strcasecmp(pPtr->attribute, "cn"))
6447 sprintf(new_cn, "cn=%s", pPtr->value);
6449 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6451 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6456 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6458 if (rc == LDAP_ALREADY_EXISTS)
6460 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6467 else if (!strcasecmp(pPtr->attribute, "ou"))
6469 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6475 linklist_free(group_base);
6484 int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6485 char *machine_ou, char *NewMachineName)
6487 LK_ENTRY *group_base;
6491 char *attr_array[3];
6498 strcpy(NewMachineName, member);
6499 rc = moira_connect();
6500 rc = GetMachineName(NewMachineName);
6503 if (strlen(NewMachineName) == 0)
6505 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6511 pPtr = strchr(NewMachineName, '.');
6518 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
6519 attr_array[0] = "cn";
6520 attr_array[1] = NULL;
6521 sprintf(temp, "%s", dn_path);
6523 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
6524 &group_base, &group_count,
6525 LDAP_SCOPE_SUBTREE)) != 0)
6527 com_err(whoami, 0, "Unable to process machine %s : %s",
6528 member, ldap_err2string(rc));
6532 if (group_count != 1)
6535 "Unable to process machine %s : machine not found in AD",
6540 strcpy(dn, group_base->dn);
6541 strcpy(cn, group_base->value);
6543 for (i = 0; i < (int)strlen(dn); i++)
6544 dn[i] = tolower(dn[i]);
6546 for (i = 0; i < (int)strlen(cn); i++)
6547 cn[i] = tolower(cn[i]);
6549 linklist_free(group_base);
6551 pPtr = strstr(dn, cn);
6555 com_err(whoami, 0, "Unable to process machine %s",
6560 pPtr += strlen(cn) + 1;
6561 strcpy(machine_ou, pPtr);
6563 pPtr = strstr(machine_ou, "dc=");
6567 com_err(whoami, 0, "Unable to process machine %s",
6578 int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6579 char *MoiraMachineName, char *DestinationOu)
6583 char MachineName[128];
6585 char *attr_array[3];
6590 LK_ENTRY *group_base;
6595 strcpy(MachineName, MoiraMachineName);
6596 rc = GetMachineName(MachineName);
6598 if (strlen(MachineName) == 0)
6600 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6605 cPtr = strchr(MachineName, '.');
6610 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6611 attr_array[0] = "sAMAccountName";
6612 attr_array[1] = NULL;
6614 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6616 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
6618 com_err(whoami, 0, "Unable to process machine %s : %s",
6619 MoiraMachineName, ldap_err2string(rc));
6623 if (group_count == 1)
6624 strcpy(OldDn, group_base->dn);
6626 linklist_free(group_base);
6629 if (group_count != 1)
6631 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6636 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6637 cPtr = strchr(OldDn, ',');
6642 if (!strcasecmp(cPtr, NewOu))
6646 sprintf(NewCn, "CN=%s", MachineName);
6647 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6652 int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6658 memset(Name, '\0', sizeof(Name));
6659 strcpy(Name, machine_name);
6661 pPtr = strchr(Name, '.');
6667 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
6670 int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6671 char *machine_name, char *container_name)
6677 av[0] = machine_name;
6678 call_args[0] = (char *)container_name;
6679 rc = mr_query("get_machine_to_container_map", 1, av,
6680 machine_GetMoiraContainer, call_args);
6684 int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6689 strcpy(call_args[0], av[1]);
6693 int Moira_container_group_create(char **after)
6699 memset(GroupName, '\0', sizeof(GroupName));
6700 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6701 after[CONTAINER_ROWID]);
6705 argv[L_NAME] = GroupName;
6706 argv[L_ACTIVE] = "1";
6707 argv[L_PUBLIC] = "0";
6708 argv[L_HIDDEN] = "0";
6709 argv[L_MAILLIST] = "0";
6710 argv[L_GROUP] = "1";
6711 argv[L_GID] = UNIQUE_GID;
6712 argv[L_NFSGROUP] = "0";
6713 argv[L_MAILMAN] = "0";
6714 argv[L_MAILMAN_SERVER] = "[NONE]";
6715 argv[L_DESC] = "auto created container group";
6716 argv[L_ACE_TYPE] = "USER";
6717 argv[L_MEMACE_TYPE] = "USER";
6718 argv[L_ACE_NAME] = "sms";
6719 argv[L_MEMACE_NAME] = "sms";
6721 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
6724 "Unable to create container group %s for container %s: %s",
6725 GroupName, after[CONTAINER_NAME], error_message(rc));
6728 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6729 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6734 int Moira_container_group_update(char **before, char **after)
6737 char BeforeGroupName[64];
6738 char AfterGroupName[64];
6741 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6744 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6745 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6746 if (strlen(BeforeGroupName) == 0)
6749 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6750 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6751 after[CONTAINER_ROWID]);
6755 if (strcasecmp(BeforeGroupName, AfterGroupName))
6757 argv[L_NAME] = BeforeGroupName;
6758 argv[L_NAME + 1] = AfterGroupName;
6759 argv[L_ACTIVE + 1] = "1";
6760 argv[L_PUBLIC + 1] = "0";
6761 argv[L_HIDDEN + 1] = "0";
6762 argv[L_MAILLIST + 1] = "0";
6763 argv[L_GROUP + 1] = "1";
6764 argv[L_GID + 1] = UNIQUE_GID;
6765 argv[L_NFSGROUP + 1] = "0";
6766 argv[L_MAILMAN + 1] = "0";
6767 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
6768 argv[L_DESC + 1] = "auto created container group";
6769 argv[L_ACE_TYPE + 1] = "USER";
6770 argv[L_MEMACE_TYPE + 1] = "USER";
6771 argv[L_ACE_NAME + 1] = "sms";
6772 argv[L_MEMACE_NAME + 1] = "sms";
6774 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
6777 "Unable to rename container group from %s to %s: %s",
6778 BeforeGroupName, AfterGroupName, error_message(rc));
6785 int Moira_container_group_delete(char **before)
6790 char ParentGroupName[64];
6792 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6793 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6795 memset(GroupName, '\0', sizeof(GroupName));
6797 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6798 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6800 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6802 argv[0] = ParentGroupName;
6804 argv[2] = GroupName;
6806 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6809 "Unable to delete container group %s from list: %s",
6810 GroupName, ParentGroupName, error_message(rc));
6814 if (strlen(GroupName) != 0)
6816 argv[0] = GroupName;
6818 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6820 com_err(whoami, 0, "Unable to delete container group %s : %s",
6821 GroupName, error_message(rc));
6828 int Moira_groupname_create(char *GroupName, char *ContainerName,
6829 char *ContainerRowID)
6834 char newGroupName[64];
6835 char tempGroupName[64];
6841 strcpy(temp, ContainerName);
6843 ptr1 = strrchr(temp, '/');
6849 ptr1 = strrchr(temp, '/');
6853 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6856 strcpy(tempgname, ptr);
6859 strcpy(tempgname, temp);
6861 if (strlen(tempgname) > 25)
6862 tempgname[25] ='\0';
6864 sprintf(newGroupName, "cnt-%s", tempgname);
6866 /* change everything to lower case */
6872 *ptr = tolower(*ptr);
6880 strcpy(tempGroupName, newGroupName);
6883 /* append 0-9 then a-z if a duplicate is found */
6886 argv[0] = newGroupName;
6888 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6890 if (rc == MR_NO_MATCH)
6892 com_err(whoami, 0, "Moira error while creating group name for "
6893 "container %s : %s", ContainerName, error_message(rc));
6897 sprintf(newGroupName, "%s-%c", tempGroupName, i);
6901 com_err(whoami, 0, "Unable to find a unique group name for "
6902 "container %s: too many duplicate container names",
6913 strcpy(GroupName, newGroupName);
6917 int Moira_setContainerGroup(char *origContainerName, char *GroupName)
6922 argv[0] = origContainerName;
6923 argv[1] = GroupName;
6925 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
6928 "Unable to set container group %s in container %s: %s",
6929 GroupName, origContainerName, error_message(rc));
6935 int Moira_addGroupToParent(char *origContainerName, char *GroupName)
6937 char ContainerName[64];
6938 char ParentGroupName[64];
6942 strcpy(ContainerName, origContainerName);
6944 Moira_getGroupName(ContainerName, ParentGroupName, 1);
6946 /* top-level container */
6947 if (strlen(ParentGroupName) == 0)
6950 argv[0] = ParentGroupName;
6952 argv[2] = GroupName;
6954 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
6957 "Unable to add container group %s to parent group %s: %s",
6958 GroupName, ParentGroupName, error_message(rc));
6964 int Moira_getContainerGroup(int ac, char **av, void *ptr)
6969 strcpy(call_args[0], av[1]);
6974 int Moira_getGroupName(char *origContainerName, char *GroupName,
6977 char ContainerName[64];
6983 strcpy(ContainerName, origContainerName);
6987 ptr = strrchr(ContainerName, '/');
6995 argv[0] = ContainerName;
6997 call_args[0] = GroupName;
6998 call_args[1] = NULL;
7000 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7003 if (strlen(GroupName) != 0)
7008 com_err(whoami, 0, "Unable to get container group from container %s: %s",
7009 ContainerName, error_message(rc));
7011 com_err(whoami, 0, "Unable to get container group from container %s",
7017 int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7023 if (strcmp(GroupName, "[none]") == 0)
7026 argv[0] = GroupName;
7027 argv[1] = "MACHINE";
7028 argv[2] = MachineName;
7031 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7033 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
7037 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
7038 MachineName, GroupName, error_message(rc));
7044 int GetMachineName(char *MachineName)
7047 char NewMachineName[1024];
7054 // If the address happens to be in the top-level MIT domain, great!
7055 strcpy(NewMachineName, MachineName);
7057 for (i = 0; i < (int)strlen(NewMachineName); i++)
7058 NewMachineName[i] = toupper(NewMachineName[i]);
7060 szDot = strchr(NewMachineName,'.');
7062 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
7067 // If not, see if it has a Moira alias in the top-level MIT domain.
7068 memset(NewMachineName, '\0', sizeof(NewMachineName));
7070 args[1] = MachineName;
7071 call_args[0] = NewMachineName;
7072 call_args[1] = NULL;
7074 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7076 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7077 MachineName, error_message(rc));
7078 strcpy(MachineName, "");
7082 if (strlen(NewMachineName) != 0)
7083 strcpy(MachineName, NewMachineName);
7085 strcpy(MachineName, "");
7090 int ProcessMachineName(int ac, char **av, void *ptr)
7093 char MachineName[1024];
7099 if (strlen(call_args[0]) == 0)
7101 strcpy(MachineName, av[0]);
7103 for (i = 0; i < (int)strlen(MachineName); i++)
7104 MachineName[i] = toupper(MachineName[i]);
7106 szDot = strchr(MachineName,'.');
7108 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
7110 strcpy(call_args[0], MachineName);
7117 void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7123 for (i = 0; i < n; i++)
7125 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7126 mods[i]->mod_type = "uidNumber";
7133 for (i = 0; i < n; i++)
7135 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7136 mods[i]->mod_type = "msSFU30UidNumber";
7143 int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7144 char *DistinguishedName,
7145 char *WinHomeDir, char *WinProfileDir,
7146 char **homedir_v, char **winProfile_v,
7147 char **drives_v, LDAPMod **mods,
7155 char winProfile[1024];
7160 LDAPMod *DelMods[20];
7162 memset(homeDrive, '\0', sizeof(homeDrive));
7163 memset(path, '\0', sizeof(path));
7164 memset(winPath, '\0', sizeof(winPath));
7165 memset(winProfile, '\0', sizeof(winProfile));
7168 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7169 (!strcasecmp(WinProfileDir, "[afs]")))
7171 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
7173 memset(cWeight, 0, sizeof(cWeight));
7174 memset(cPath, 0, sizeof(cPath));
7178 while (hp[i] != NULL)
7180 if (sscanf(hp[i], "%*s %s", cPath))
7182 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
7184 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
7186 if (atoi(cWeight) < last_weight)
7188 strcpy(path, cPath);
7189 last_weight = (int)atoi(cWeight);
7193 strcpy(path, cPath);
7201 if (!strnicmp(path, AFS, strlen(AFS)))
7203 AfsToWinAfs(path, winPath);
7204 strcpy(winProfile, winPath);
7205 strcat(winProfile, "\\.winprofile");
7213 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7214 (!strcasecmp(WinProfileDir, "[dfs]")))
7216 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7217 user_name[0], user_name);
7219 if (!strcasecmp(WinProfileDir, "[dfs]"))
7221 strcpy(winProfile, path);
7222 strcat(winProfile, "\\.winprofile");
7225 if (!strcasecmp(WinHomeDir, "[dfs]"))
7226 strcpy(winPath, path);
7239 if (!strcasecmp(WinHomeDir, "[local]"))
7240 memset(winPath, '\0', sizeof(winPath));
7241 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7242 !strcasecmp(WinHomeDir, "[dfs]"))
7244 strcpy(homeDrive, "H:");
7248 strcpy(winPath, WinHomeDir);
7249 if (!strncmp(WinHomeDir, "\\\\", 2))
7251 strcpy(homeDrive, "H:");
7255 // nothing needs to be done if WinProfileDir is [afs].
7256 if (!strcasecmp(WinProfileDir, "[local]"))
7257 memset(winProfile, '\0', sizeof(winProfile));
7258 else if (strcasecmp(WinProfileDir, "[afs]") &&
7259 strcasecmp(WinProfileDir, "[dfs]"))
7261 strcpy(winProfile, WinProfileDir);
7264 if (strlen(winProfile) != 0)
7266 if (winProfile[strlen(winProfile) - 1] == '\\')
7267 winProfile[strlen(winProfile) - 1] = '\0';
7270 if (strlen(winPath) != 0)
7272 if (winPath[strlen(winPath) - 1] == '\\')
7273 winPath[strlen(winPath) - 1] = '\0';
7276 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
7277 strcat(winProfile, "\\");
7279 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7280 strcat(winPath, "\\");
7282 if (strlen(winPath) == 0)
7284 if (OpType == LDAP_MOD_REPLACE)
7287 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7289 //unset homeDirectory attribute for user.
7290 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7296 homedir_v[0] = strdup(winPath);
7297 ADD_ATTR("homeDirectory", homedir_v, OpType);
7300 if (strlen(winProfile) == 0)
7302 if (OpType == LDAP_MOD_REPLACE)
7305 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7307 //unset profilePate attribute for user.
7308 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7314 winProfile_v[0] = strdup(winProfile);
7315 ADD_ATTR("profilePath", winProfile_v, OpType);
7318 if (strlen(homeDrive) == 0)
7320 if (OpType == LDAP_MOD_REPLACE)
7323 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7325 //unset homeDrive attribute for user
7326 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7332 drives_v[0] = strdup(homeDrive);
7333 ADD_ATTR("homeDrive", drives_v, OpType);
7339 int attribute_update(LDAP *ldap_handle, char *distinguished_name,
7340 char *attribute_value, char *attribute, char *user_name)
7342 char *mod_v[] = {NULL, NULL};
7343 LDAPMod *DelMods[20];
7349 if (strlen(attribute_value) == 0)
7352 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7354 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7360 mod_v[0] = attribute_value;
7361 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7364 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7365 mods)) != LDAP_SUCCESS)
7369 mod_v[0] = attribute_value;
7370 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7373 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7374 mods)) != LDAP_SUCCESS)
7376 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7378 attribute, user_name, ldap_err2string(rc));
7388 void StringTrim(char *StringToTrim)
7393 save = strdup(StringToTrim);
7400 /* skip to end of string */
7405 strcpy(StringToTrim, save);
7409 for (t = s; *t; t++)
7425 strcpy(StringToTrim, s);
7429 int ReadConfigFile(char *DomainName)
7440 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
7442 if ((fptr = fopen(temp, "r")) != NULL)
7444 while (fgets(temp, sizeof(temp), fptr) != 0)
7446 for (i = 0; i < (int)strlen(temp); i++)
7447 temp[i] = toupper(temp[i]);
7449 if (temp[strlen(temp) - 1] == '\n')
7450 temp[strlen(temp) - 1] = '\0';
7454 if (strlen(temp) == 0)
7457 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7459 if (strlen(temp) > (strlen(DOMAIN)))
7461 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7462 StringTrim(ldap_domain);
7465 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
7467 if (strlen(temp) > (strlen(PRINCIPALNAME)))
7469 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7470 StringTrim(PrincipalName);
7473 else if (!strncmp(temp, SERVER, strlen(SERVER)))
7475 if (strlen(temp) > (strlen(SERVER)))
7477 ServerList[Count] = calloc(1, 256);
7478 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7479 StringTrim(ServerList[Count]);
7483 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
7485 if (strlen(temp) > (strlen(MSSFU)))
7487 strcpy(temp1, &temp[strlen(MSSFU)]);
7489 if (!strcmp(temp1, SFUTYPE))
7493 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7495 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7497 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7499 if (!strcasecmp(temp1, "NO"))
7502 memset(group_suffix, '\0', sizeof(group_suffix));
7506 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7508 if (strlen(temp) > (strlen(GROUP_TYPE)))
7510 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7512 if (!strcasecmp(temp1, "UNIVERSAL"))
7513 UseGroupUniversal = 1;
7516 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7518 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7520 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7522 if (!strcasecmp(temp1, "NO"))
7526 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7528 if (strlen(temp) > (strlen(SET_PASSWORD)))
7530 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7532 if (!strcasecmp(temp1, "NO"))
7536 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7538 if (strlen(temp) > (strlen(EXCHANGE)))
7540 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7542 if (!strcasecmp(temp1, "YES"))
7546 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7547 strlen(PROCESS_MACHINE_CONTAINER)))
7549 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7551 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7553 if (!strcasecmp(temp1, "NO"))
7554 ProcessMachineContainer = 0;
7559 if (strlen(ldap_domain) != 0)
7561 memset(ldap_domain, '\0', sizeof(ldap_domain));
7565 if (strlen(temp) != 0)
7566 strcpy(ldap_domain, temp);
7572 if (strlen(ldap_domain) == 0)
7574 strcpy(ldap_domain, DomainName);
7580 for (i = 0; i < Count; i++)
7582 if (ServerList[i] != 0)
7584 strcat(ServerList[i], ".");
7585 strcat(ServerList[i], ldap_domain);
7586 for (k = 0; k < (int)strlen(ServerList[i]); k++)
7587 ServerList[i][k] = toupper(ServerList[i][k]);
7594 int ReadDomainList()
7601 unsigned char c[11];
7602 unsigned char stuff[256];
7607 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
7609 if ((fptr = fopen(temp, "r")) != NULL)
7611 while (fgets(temp, sizeof(temp), fptr) != 0)
7613 for (i = 0; i < (int)strlen(temp); i++)
7614 temp[i] = toupper(temp[i]);
7616 if (temp[strlen(temp) - 1] == '\n')
7617 temp[strlen(temp) - 1] = '\0';
7621 if (strlen(temp) == 0)
7624 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7626 if (strlen(temp) > (strlen(DOMAIN)))
7628 strcpy(temp1, &temp[strlen(DOMAIN)]);
7630 strcpy(temp, temp1);
7634 strcpy(DomainNames[Count], temp);
7635 StringTrim(DomainNames[Count]);
7644 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7645 "configuration error in winad.cfg");
7652 int email_isvalid(const char *address) {
7654 const char *c, *domain;
7655 static char *rfc822_specials = "()<>@,;:\\\"[]";
7657 if(address[strlen(address) - 1] == '.')
7660 /* first we validate the name portion (name@domain) */
7661 for (c = address; *c; c++) {
7662 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7667 if (*c == '\\' && (*++c == ' '))
7669 if (*c <= ' ' || *c >= 127)
7684 if (*c <= ' ' || *c >= 127)
7686 if (strchr(rfc822_specials, *c))
7690 if (c == address || *(c - 1) == '.')
7693 /* next we validate the domain portion (name@domain) */
7694 if (!*(domain = ++c)) return 0;
7697 if (c == domain || *(c - 1) == '.')
7701 if (*c <= ' ' || *c >= 127)
7703 if (strchr(rfc822_specials, *c))
7707 return (count >= 1);
7710 int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7711 char **homeServerName)
7713 LK_ENTRY *group_base;
7714 LK_ENTRY *sub_group_base;
7718 int sub_group_count;
7720 char sub_filter[1024];
7721 char search_path[1024];
7723 char *attr_array[3];
7725 int homeMDB_count = -1;
7729 int rangeStep = 1500;
7731 int rangeHigh = rangeLow + (rangeStep - 1);
7734 /* Grumble..... microsoft not making it searchable from the root *grr* */
7736 memset(filter, '\0', sizeof(filter));
7737 memset(search_path, '\0', sizeof(search_path));
7739 sprintf(filter, "(objectClass=msExchMDB)");
7740 sprintf(search_path, "CN=Configuration,%s", dn_path);
7741 attr_array[0] = "distinguishedName";
7742 attr_array[1] = NULL;
7747 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7748 &group_base, &group_count,
7749 LDAP_SCOPE_SUBTREE)) != 0)
7751 com_err(whoami, 0, "Unable to find msExchMDB %s",
7752 ldap_err2string(rc));
7761 if ((s = strstr(gPtr->dn, "Public")) != (char *) NULL)
7768 * Due to limits in active directory we need to use the LDAP
7769 * range semantics to query and return all the values in
7770 * large lists, we will stop increasing the range when
7771 * the result count is 0.
7779 memset(sub_filter, '\0', sizeof(sub_filter));
7780 memset(range, '\0', sizeof(range));
7781 sprintf(sub_filter, "(objectClass=msExchMDB)");
7784 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
7786 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
7788 attr_array[0] = range;
7789 attr_array[1] = NULL;
7791 sub_group_base = NULL;
7792 sub_group_count = 0;
7794 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
7795 attr_array, &sub_group_base,
7797 LDAP_SCOPE_SUBTREE)) != 0)
7799 com_err(whoami, 0, "Unable to find homeMDBBL %s",
7800 ldap_err2string(rc));
7804 if(!sub_group_count)
7810 rangeHigh = rangeLow + (rangeStep - 1);
7817 mdbbl_count += sub_group_count;
7818 rangeLow = rangeHigh + 1;
7819 rangeHigh = rangeLow + (rangeStep - 1);
7822 /* First time through, need to initialize or update the least used */
7824 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
7827 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
7829 homeMDB_count = mdbbl_count;
7830 *homeMDB = strdup(gPtr->dn);
7834 linklist_free(sub_group_base);
7838 linklist_free(group_base);
7841 * Ok found the server least allocated need to now query to get its
7842 * msExchHomeServerName so we can set it as a user attribute
7845 attr_array[0] = "legacyExchangeDN";
7846 attr_array[1] = NULL;
7851 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
7852 attr_array, &group_base,
7854 LDAP_SCOPE_SUBTREE)) != 0)
7856 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
7857 ldap_err2string(rc));
7863 *homeServerName = strdup(group_base->value);
7864 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
7870 linklist_free(group_base);
7875 char *lowercase(char *s)
7879 for (p = s; *p; p++)
7887 char *uppercase(char *s)
7891 for (p = s; *p; p++)
7899 int save_query_info(int argc, char **argv, void *hint)
7902 char **nargv = hint;
7904 for(i = 0; i < argc; i++)
7905 nargv[i] = strdup(argv[i]);