From: zacheiss Date: Mon, 25 Aug 2008 16:52:53 +0000 (+0000) Subject: From mark: Exchange changes. X-Git-Url: http://andersk.mit.edu/gitweb/moira.git/commitdiff_plain/df2a74ce83ebb860ebad703ecb062a845cd0d6de From mark: Exchange changes. --- diff --git a/incremental/winad/ldap-int.h b/incremental/winad/ldap-int.h index e7ffb403..f3439282 100755 --- a/incremental/winad/ldap-int.h +++ b/incremental/winad/ldap-int.h @@ -471,10 +471,10 @@ extern int nsldapi_initialized; * following macros. This is so we can plug-in alternative memory * allocators, etc. as the need arises. */ -#define NSLDAPI_MALLOC( size ) nsldapi_malloc( size ) +#define NSLDAPI_MALLOC( size ) ldap_x_malloc( size ) #define NSLDAPI_CALLOC( nelem, elsize ) nsldapi_calloc( nelem, elsize ) #define NSLDAPI_REALLOC( ptr, size ) nsldapi_realloc( ptr, size ) -#define NSLDAPI_FREE( ptr ) nsldapi_free( ptr ) +#define NSLDAPI_FREE( ptr ) ldap_x_free( ptr ) /* diff --git a/incremental/winad/setpw.c b/incremental/winad/setpw.c index c3a6e5f2..9908a1f3 100644 --- a/incremental/winad/setpw.c +++ b/incremental/winad/setpw.c @@ -698,7 +698,7 @@ int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, static char temp[128]; ULONG version = LDAP_VERSION3; ULONG rc; - int Max_wait_time = 500; + int Max_wait_time = 1000; int Max_size_limit = LDAP_NO_LIMIT; if (strlen(ldap_domain) == 0) @@ -764,7 +764,7 @@ int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, rc = ldap_set_option((*ldap_handle), LDAP_OPT_SIZELIMIT, (void *)&Max_size_limit); rc = ldap_set_option((*ldap_handle), LDAP_OPT_REFERRALS, LDAP_OPT_OFF); - rc = ldap_adgssapi_bind((*ldap_handle), dn_path, GSSSASL_PRIVACY_PROTECTION); + rc = ldap_adgssapi_bind((*ldap_handle), dn_path, 0); if (rc == LDAP_SUCCESS) { if (connect_to_kdc) diff --git a/incremental/winad/winad.c b/incremental/winad/winad.c index c42a93a1..1d71e3b3 100755 --- a/incremental/winad/winad.c +++ b/incremental/winad/winad.c @@ -1,93 +1,149 @@ /* $Header$ -/* winad.incr arguments examples +/* winad.incr arguments example * - * arguments when moira creates the account - ignored by winad.incr since the account is unusable. - * users 0 11 #45198 45198 /bin/cmd cmd Last First Middle 0 950000001 2000 121049 - * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid + * arguments when moira creates the account - ignored by winad.incr since the + * account is unusable. users 0 11 #45198 45198 /bin/cmd cmd Last First Middle + * 0 950000001 2000 121049 + * + * login, unix_uid, shell, winconsoleshell, last, + * first, middle, status, mitid, type, moiraid * * arguments for creating or updating a user account - * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir - * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF 121058 PathToHomeDir PathToProfileDir newuser 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir - * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid + * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF + * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last + * First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir + * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF + * 121058 PathToHomeDir PathToProfileDir newuser 45206 /bin/cmd cmd Last + * First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir + * + * login, unix_uid, shell, winconsoleshell, last, first, middle, status, + * mitid, type, moiraid * * arguments for deactivating/deleting a user account - * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir - * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir - * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid + * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF + * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last + * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir + * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF + * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last + * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir + * + * login, unix_uid, shell, winconsoleshell, last, first, middle, status, + * mitid, type, moiraid * * arguments for reactivating a user account - * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 - * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF 121058 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 121058 - * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid + * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF + * 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF + * 121058 + * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF + * 121058 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 12105 + * + * login, unix_uid, shell, winconsoleshell, last, first, middle, status, + * mitid, type, moiraid * * arguments for changing user name - * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir newusername 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir - * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid + * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001 + * STAFF 121058 PathToHomeDir PathToProfileDir newusername 45206 /bin/cmd cmd + * Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir + * + * login, unix_uid, shell, winconsoleshell, last, first, middle, status, + * mitid, type, moiraid * * arguments for expunging a user - * users 11 0 username 45198 /bin/cmd cmd Last First Middle 0 950000001 2000 121049 - * login, unix_uid, shell, winconsoleshell, last, first, middle, status, mitid, type, moiraid + * users 11 0 username 45198 /bin/cmd cmd Last First Middle 0 950000001 2000 + * 121049 + * + * login, unix_uid, shell, winconsoleshell, last, first, middle, status, + * mitid, type, moiraid * * arguments for creating a "special" group/list * list 0 11 listname 1 1 0 0 0 -1 NONE 0 description 92616 - * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraid + * + * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, + * acl_id, description, moiraid * * arguments for creating a "mail" group/list * list 0 11 listname 1 1 0 1 0 -1 NONE 0 description 92616 - * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraid + * + * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, + * acl_id, description, moiraid * * arguments for creating a "group" group/list * list 0 11 listname 1 1 0 0 1 -1 NONE 0 description 92616 - * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraid + * + * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, + * acl_id, description, moiraid * * arguments for creating a "group/mail" group/list * list 0 11 listname 1 1 0 1 1 -1 NONE 0 description 92616 - * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraid + * + * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type, + * acl_id, description, moiraid * * arguments to add a USER member to group/list * imembers 0 12 listname USER userName 1 1 0 0 0 -1 1 92616 121047 - * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid, userStatus, moiraListId, moiraUserId + * + * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, + * gid, userStatus, moiraListId, moiraUserId * * arguments to add a STRING or KERBEROS member to group/list * imembers 0 10 listname STRING stringName 1 1 0 0 0 -1 92616 * imembers 0 10 listlistnameName KERBEROS kerberosName 1 1 0 0 0 -1 92616 - * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid, moiraListId + * + * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, + * gid, moiraListId * * NOTE: group members of type LIST are ignored. * * arguments to remove a USER member to group/list * imembers 12 0 listname USER userName 1 1 0 0 0 -1 1 92616 121047 - * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid, userStatus, moiraListId, moiraUserId + * + * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, + * gid, userStatus, moiraListId, moiraUserId * * arguments to remove a STRING or KERBEROS member to group/list * imembers 10 0 listname STRING stringName 1 1 0 0 0 -1 92616 * imembers 10 0 listname KERBEROS kerberosName 1 1 0 0 0 -1 92616 - * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, gid, moiraListId + * + * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist, + * gid, moiraListId * * NOTE: group members of type LIST are ignored. * * arguments for renaming a group/list - * list 11 11 oldlistname 1 1 0 0 0 -1 NONE 0 description 92616 newlistname 1 1 0 0 0 -1 description 0 92616 - * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraListId + * list 11 11 oldlistname 1 1 0 0 0 -1 NONE 0 description 92616 newlistname 1 + * 1 0 0 0 -1 description 0 92616 + * + * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, + * acl_id, description, moiraListId * * arguments for deleting a group/list * list 11 0 listname 1 1 0 0 0 -1 NONE 0 description 92616 - * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, acl_id, description, moiraListId + * + * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type, + * acl_id, description, moiraListId * * arguments for adding a file system - * filesys 0 12 username AFS ATHENA.MIT.EDU /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username wheel 1 HOMEDIR 101727 + * filesys 0 12 username AFS ATHENA.MIT.EDU + * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username + * wheel 1 HOMEDIR 101727 * * arguments for deleting a file system - * filesys 12 0 username AFS ATHENA.MIT.EDU /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username wheel 1 HOMEDIR 101727 + * filesys 12 0 username AFS ATHENA.MIT.EDU + * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username + * wheel 1 HOMEDIR 101727 * * arguments when moira creates a container (OU). - * containers 0 8 machines/test/bottom description location contact USER 105316 2222 [none] + * containers 0 8 machines/test/bottom description location contact USER + * 105316 2222 [none] * * arguments when moira deletes a container (OU). - * containers 8 0 machines/test/bottom description location contact USER 105316 2222 groupname + * containers 8 0 machines/test/bottom description location contact USER + * 105316 2222 groupname * * arguments when moira modifies a container information (OU). - * containers 8 8 machines/test/bottom description location contact USER 105316 2222 groupname machines/test/bottom description1 location contact USER 105316 2222 groupname + * containers 8 8 machines/test/bottom description location contact USER + * 105316 2222 groupname machines/test/bottom description1 location contact + * USER 105316 2222 groupname * * arguments when moira adds a machine from an OU * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id @@ -98,7 +154,9 @@ * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname * */ + #include + #ifdef _WIN32 #include #include @@ -106,6 +164,7 @@ #include #include #endif + #include #include #include @@ -115,7 +174,7 @@ #include #include #include -#include +#include #include "kpasswd.h" #ifdef _WIN32 @@ -288,15 +347,19 @@ typedef struct lk_entry { #define NOT_HIDDEN_GROUP "NotHiddenGroup.g" #define NOT_HIDDEN_GROUP_WITH_ADMIN "NotHiddenGroupWithAdmin.g" +#define ADDRESS_LIST_PREFIX "CN=MIT Directory,CN=All Address Lists,\ +CN=Address Lists Container,CN=Massachusetts Institute of Technology,\ +CN=Microsoft Exchange,CN=Services,CN=Configuration," + #define ADD_ATTR(t, v, o) \ mods[n] = malloc(sizeof(LDAPMod)); \ - mods[n]->mod_op = o; \ + mods[n]->mod_op = o; \ mods[n]->mod_type = t; \ mods[n++]->mod_values = v -#define DEL_ATTR(t, o) \ +#define DEL_ATTR(t, o) \ DelMods[i] = malloc(sizeof(LDAPMod)); \ - DelMods[i]->mod_op = o; \ + DelMods[i]->mod_op = o; \ DelMods[i]->mod_type = t; \ DelMods[i++]->mod_values = NULL @@ -306,21 +369,18 @@ typedef struct lk_entry { #define SERVER "SERVER:" #define MSSFU "SFU:" #define SFUTYPE "30" +#define GROUP_SUFFIX "GROUP_SUFFIX:" +#define GROUP_TYPE "GROUP_TYPE:" +#define SET_GROUP_ACE "SET_GROUP_ACE:" +#define SET_PASSWORD "SET_PASSWORD:" +#define EXCHANGE "EXCHANGE:" +#define PROCESS_MACHINE_CONTAINER "PROCESS_MACHINE_CONTAINER:" #define MAX_DOMAINS 10 char DomainNames[MAX_DOMAINS][128]; -char PrincipalName[128]; -#ifndef _WIN32 -#define KRB5CCNAME "KRB5CCNAME=/tmp/krb5cc_winad.incr" -#define KRBTKFILE "KRBTKFILE=/tmp/tkt_winad.incr" -#define KEYTABFILE "/etc/krb5.keytab" -#else -#define KRB5CCNAME "KRB5CCNAME=\\tmp\\krb5cc_winad.incr" -#define KRBTKFILE "KRBTKFILE=\\tmp\\tkt_winad.incr" -#define KEYTABFILE "\\keytabs\\krb5.keytab" -#endif - LK_ENTRY *member_base = NULL; + +char PrincipalName[128]; static char tbl_buf[1024]; char kerberos_ou[] = "OU=kerberos,OU=moira"; char contact_ou[] = "OU=strings,OU=moira"; @@ -336,20 +396,27 @@ char security_template_ou[] = "OU=security_templates"; char *whoami; char ldap_domain[256]; char *ServerList[MAX_SERVER_NAMES]; -int mr_connections = 0; -int callback_rc; char default_server[256]; static char tbl_buf[1024]; +char group_suffix[256]; +char exchange_acl[256]; +int mr_connections = 0; +int callback_rc; int UseSFU30 = 0; -int NoChangeConfigFile; +int UseGroupSuffix = 1; +int UseGroupUniversal = 0; +int SetGroupAce = 1; +int SetPassword = 1; +int Exchange = 0; +int ProcessMachineContainer = 1; int UpdateDomainList; extern int set_password(char *user, char *password, char *domain); int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name, - char *group_membership, char *MoiraId, char *attribute, - LK_ENTRY **linklist_base, int *linklist_count, - char *rFilter); + char *group_membership, char *MoiraId, char *attribute, + LK_ENTRY **linklist_base, int *linklist_count, + char *rFilter); void AfsToWinAfs(char* path, char* winPath); int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, char *Win2kPassword, char *Win2kUser, char *default_server, @@ -357,11 +424,12 @@ int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path, void ad_kdc_disconnect(); int ad_server_connect(char *connectedServer, char *domain); int attribute_update(LDAP *ldap_handle, char *distinguished_name, - char *attribute_value, char *attribute, char *user_name); + char *attribute_value, char *attribute, char *user_name); int BEREncodeSecurityBits(ULONG uBits, char *pBuffer); int checkADname(LDAP *ldap_handle, char *dn_path, char *Name); int check_winad(void); -int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId); +int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, + char *MoiraId); /* containers */ int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName, char *distinguishedName, int count, char **av); @@ -369,20 +437,21 @@ void container_check(LDAP *ldap_handle, char *dn_path, char *name); int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av); int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av); int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path, - char *distinguishedName, int count, char **av); + char *distinguishedName, int count, + char **av); void container_get_dn(char *src, char *dest); void container_get_name(char *src, char *dest); int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName); -int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **before, - int afterc, char **after); -int container_update(LDAP *ldap_handle, char *dn_path, int beforec, char **before, - int afterc, char **after); +int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, + char **before, int afterc, char **after); +int container_update(LDAP *ldap_handle, char *dn_path, int beforec, + char **before, int afterc, char **after); int GetAceInfo(int ac, char **av, void *ptr); -int GetServerList(char *ldap_domain, char **MasterServe); int get_group_membership(char *group_membership, char *group_ou, int *security_flag, char **av); -int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, char *machine_ou, char *pPtr); +int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, + char *machine_ou, char *pPtr); int Moira_container_group_create(char **after); int Moira_container_group_delete(char **before); int Moira_groupname_create(char *GroupName, char *ContainerName, @@ -396,17 +465,19 @@ int Moira_getGroupName(char *origContainerName, char *GroupName, int ParentFlag); int Moira_setContainerGroup(char *ContainerName, char *GroupName); int ProcessAce(LDAP *ldap_handle, char *dn_path, char *group_name, char *Type, - int UpdateGroup, int *ProcessGroup); + int UpdateGroup, int *ProcessGroup, char *maillist); int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, char *group_name, char *group_ou, char *group_membership, - int group_security_flag, int type); + int group_security_flag, int type, char *maillist); int process_lists(int ac, char **av, void *ptr); -int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName, - int HiddenGroup, char *AceType, char *AceName); +int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, + char *TargetGroupName, int HiddenGroup, + char *AceType, char *AceName); int ProcessMachineName(int ac, char **av, void *ptr); int ReadConfigFile(char *DomainName); int ReadDomainList(); void StringTrim(char *StringToTrim); +int save_query_info(int argc, char **argv, void *hint); int user_create(int ac, char **av, void *ptr); int user_change_status(LDAP *ldap_handle, char *dn_path, char *user_name, char *MoiraId, int operation); @@ -416,36 +487,43 @@ int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, char *user_name); int user_update(LDAP *ldap_handle, char *dn_path, char *user_name, char *uid, char *MitId, char *MoiraId, int State, - char *WinHomeDir, char *WinProfileDir); + char *WinHomeDir, char *WinProfileDir, char *first, + char *middle, char *last); void change_to_lower_case(char *ptr); int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou); +int contact_remove_email(LDAP *ld, char *bind_path, + LK_ENTRY **linklist_entry, int linklist_current); int group_create(int ac, char **av, void *ptr); int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name, char *group_membership, char *MoiraId); int group_rename(LDAP *ldap_handle, char *dn_path, char *before_group_name, char *before_group_membership, - char *before_group_ou, int before_security_flag, char *before_desc, - char *after_group_name, char *after_group_membership, - char *after_group_ou, int after_security_flag, char *after_desc, - char *MoiraId, char *filter); + char *before_group_ou, int before_security_flag, + char *before_desc, char *after_group_name, + char *after_group_membership, char *after_group_ou, + int after_security_flag, char *after_desc, + char *MoiraId, char *filter, char *maillist); int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name); int machine_GetMoiraContainer(int ac, char **av, void *ptr); -int machine_get_moira_container(LDAP *ldap_handle, char *dn_path, char *machine_name, char *container_name); -int machine_move_to_ou(LDAP *ldap_handle, char *dn_path, char *MoiraMachineName, char *DestinationOu); +int machine_get_moira_container(LDAP *ldap_handle, char *dn_path, + char *machine_name, char *container_name); +int machine_move_to_ou(LDAP *ldap_handle, char *dn_path, + char *MoiraMachineName, char *DestinationOu); int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, char *group_name, char *group_ou, char *group_membership, - int group_security_flag, int updateGroup); + int group_security_flag, int updateGroup, char *maillist); int member_list_build(int ac, char **av, void *ptr); int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, - char *group_ou, char *group_membership, - char *user_name, char *pUserOu, char *MoiraId); + char *group_ou, char *group_membership, + char *user_name, char *pUserOu, char *MoiraId); int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, char *group_ou, char *group_membership, char *user_name, char *pUserOu, char *MoiraId); int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name, char *group_ou, char *group_membership, int group_security_flag, char *MoiraId); -int SetHomeDirectory(LDAP *ldap_handle, char *user_name, char *DistinguishedName, +int SetHomeDirectory(LDAP *ldap_handle, char *user_name, + char *DistinguishedName, char *WinHomeDir, char *WinProfileDir, char **homedir_v, char **winProfile_v, char **drives_v, LDAPMod **mods, @@ -456,9 +534,8 @@ int check_string(char *s); int check_container_name(char* s); int mr_connect_cl(char *server, char *client, int version, int auth); -void WriteDomainList(); void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, - char **before, int beforec, char **after, int afterc); + char **before, int beforec, char **after, int afterc); void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, char **before, int beforec, char **after, int afterc); void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, @@ -497,10 +574,12 @@ int moira_connect(void); void print_to_screen(const char *fmt, ...); int GetMachineName(char *MachineName); int tickets_get_k5(); -int get_tickets(); int destroy_cache(void); int dest_tkt(void); +int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB, + char **homeServerName); + int main(int argc, char **argv) { unsigned long rc; @@ -516,18 +595,19 @@ int main(int argc, char **argv) LDAP *ldap_handle; char dn_path[256]; char *orig_argv[64]; - + whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]); - + if (argc < 4) { com_err(whoami, 0, "Unable to process %s", "argc < 4"); exit(1); } - + if (argc < (4 + atoi(argv[2]) + atoi(argv[3]))) { - com_err(whoami, 0, "Unable to process %s", "argc < (4 + beforec + afterc)"); + com_err(whoami, 0, "Unable to process %s", + "argc < (4 + beforec + afterc)"); exit(1); } @@ -539,6 +619,7 @@ int main(int argc, char **argv) strcat(tbl_buf, argv[i]); strcat(tbl_buf, " "); } + com_err(whoami, 0, "%s", tbl_buf); if (check_winad()) @@ -547,17 +628,12 @@ int main(int argc, char **argv) exit(1); } - if (get_tickets()) - { - com_err(whoami, 0, "%s failed", "get_tickets()"); - exit(1); - } - initialize_sms_error_table(); initialize_krb_error_table(); UpdateDomainList = 0; memset(DomainNames, '\0', sizeof(DomainNames[0]) * MAX_DOMAINS); + if (ReadDomainList()) { com_err(whoami, 0, "%s failed", "ReadDomainList()"); @@ -583,8 +659,20 @@ int main(int argc, char **argv) memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES); memset(default_server, '\0', sizeof(default_server)); memset(dn_path, '\0', sizeof(dn_path)); + memset(group_suffix, '\0', sizeof(group_suffix)); + memset(exchange_acl, '\0', sizeof(exchange_acl)); + UseSFU30 = 0; - NoChangeConfigFile = 0; + UseGroupSuffix = 1; + UseGroupUniversal = 0; + SetGroupAce = 1; + SetPassword = 1; + Exchange = 0; + ProcessMachineContainer = 1; + + sprintf(group_suffix, "%s", "_group"); + sprintf(exchange_acl, "%s", "exchange-acl"); + beforec = atoi(orig_argv[2]); afterc = atoi(orig_argv[3]); table = orig_argv[1]; @@ -598,9 +686,7 @@ int main(int argc, char **argv) before = NULL; if (ReadConfigFile(DomainNames[k])) - { - continue; - } + continue; OldUseSFU30 = UseSFU30; @@ -613,35 +699,13 @@ int main(int argc, char **argv) com_err(whoami, 0, "connected to domain %s", DomainNames[k]); break; } - - if (ldap_handle == NULL) - { - if (!NoChangeConfigFile) - { - for (j = 0; j < MAX_SERVER_NAMES; j++) - { - if (ServerList[j] != NULL) - { - free(ServerList[j]); - ServerList[j] = NULL; - } - } - if (rc = GetServerList(ldap_domain, ServerList)) - { - com_err("incremental", 0, - "winad.incr cannot bind to any server in domain %s", - DomainNames[k]); - continue; - } - } - } } if ((rc) || (ldap_handle == NULL)) { critical_alert("incremental", - "winad.incr cannot connect to any server in domain %s", - DomainNames[k]); + "winad.incr cannot connect to any server in " + "domain %s", DomainNames[k]); continue; } @@ -663,9 +727,7 @@ int main(int argc, char **argv) else if (!strcmp(table, "mcntmap")) do_mcntmap(ldap_handle, dn_path, ldap_domain, before, beforec, after, afterc); - if (!NoChangeConfigFile) - GetServerList(ldap_domain, ServerList); - + ad_kdc_disconnect(); for (i = 0; i < MAX_SERVER_NAMES; i++) @@ -676,103 +738,126 @@ int main(int argc, char **argv) ServerList[i] = NULL; } } - + rc = ldap_unbind_s(ldap_handle); } - - if (UpdateDomainList == 1) - WriteDomainList(); - - destroy_cache(); + exit(0); } void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, char **before, int beforec, char **after, int afterc) { - char MoiraContainerName[128]; - char ADContainerName[128]; - char MachineName[1024]; - char OriginalMachineName[1024]; - long rc; - int DeleteMachine; - char MoiraContainerGroup[64]; - - DeleteMachine = 0; - memset(ADContainerName, '\0', sizeof(ADContainerName)); - memset(MoiraContainerName, '\0', sizeof(MoiraContainerName)); - - if ((beforec == 0) && (afterc == 0)) - return; + char MoiraContainerName[128]; + char ADContainerName[128]; + char MachineName[1024]; + char OriginalMachineName[1024]; + long rc; + int DeleteMachine; + char MoiraContainerGroup[64]; - if (rc = moira_connect()) + if (!ProcessMachineContainer) { - critical_alert("AD incremental", - "Error contacting Moira server : %s", - error_message(rc)); - return; + com_err(whoami, 0, "Process machines and containers disabled, skipping"); + return; } - - if ((beforec != 0) && (afterc == 0)) /*remove a machine*/ + + DeleteMachine = 0; + memset(ADContainerName, '\0', sizeof(ADContainerName)); + memset(MoiraContainerName, '\0', sizeof(MoiraContainerName)); + + if ((beforec == 0) && (afterc == 0)) + return; + + if (rc = moira_connect()) + { + critical_alert("AD incremental", + "Error contacting Moira server : %s", + error_message(rc)); + return; + } + + if ((beforec != 0) && (afterc == 0)) /*remove a machine*/ { - strcpy(OriginalMachineName, before[OU_MACHINE_NAME]); - strcpy(MachineName, before[OU_MACHINE_NAME]); - strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]); - DeleteMachine = 1; - com_err(whoami, 0, "removing machine %s from %s", OriginalMachineName, before[OU_CONTAINER_NAME]); + strcpy(OriginalMachineName, before[OU_MACHINE_NAME]); + strcpy(MachineName, before[OU_MACHINE_NAME]); + strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]); + DeleteMachine = 1; + com_err(whoami, 0, "removing machine %s from %s", + OriginalMachineName, before[OU_CONTAINER_NAME]); } - else if ((beforec == 0) && (afterc != 0)) /*add a machine*/ + else if ((beforec == 0) && (afterc != 0)) /*add a machine*/ { - strcpy(OriginalMachineName, after[OU_MACHINE_NAME]); - strcpy(MachineName, after[OU_MACHINE_NAME]); - strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]); - com_err(whoami, 0, "adding machine %s to container %s", OriginalMachineName, after[OU_CONTAINER_NAME]); + strcpy(OriginalMachineName, after[OU_MACHINE_NAME]); + strcpy(MachineName, after[OU_MACHINE_NAME]); + strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]); + com_err(whoami, 0, "adding machine %s to container %s", + OriginalMachineName, after[OU_CONTAINER_NAME]); } - else - { - moira_disconnect(); - return; - } + else + { + moira_disconnect(); + return; + } + + rc = GetMachineName(MachineName); - rc = GetMachineName(MachineName); - if (strlen(MachineName) == 0) + if (strlen(MachineName) == 0) { - moira_disconnect(); - com_err(whoami, 0, "Unable to find alais for machine %s in Moira", OriginalMachineName); - return; + moira_disconnect(); + com_err(whoami, 0, "Unable to find alais for machine %s in Moira", + OriginalMachineName); + return; } - Moira_process_machine_container_group(MachineName, MoiraContainerGroup, - DeleteMachine); - if (machine_check(ldap_handle, dn_path, MachineName)) + + Moira_process_machine_container_group(MachineName, MoiraContainerGroup, + DeleteMachine); + + if (machine_check(ldap_handle, dn_path, MachineName)) { - com_err(whoami, 0, "Unable to find machine %s (alias %s) in AD.", OriginalMachineName, MachineName); - moira_disconnect(); - return; + com_err(whoami, 0, "Unable to find machine %s (alias %s) in AD.", + OriginalMachineName, MachineName); + moira_disconnect(); + return; } - memset(MoiraContainerName, '\0', sizeof(MoiraContainerName)); - machine_get_moira_container(ldap_handle, dn_path, MachineName, MoiraContainerName); - if (strlen(MoiraContainerName) == 0) + + memset(MoiraContainerName, '\0', sizeof(MoiraContainerName)); + machine_get_moira_container(ldap_handle, dn_path, MachineName, + MoiraContainerName); + + if (strlen(MoiraContainerName) == 0) { - com_err(whoami, 0, "Unable to fine machine %s (alias %s) container in Moira - moving to orphans OU.", - OriginalMachineName, MachineName); - machine_move_to_ou(ldap_handle, dn_path, MachineName, orphans_machines_ou); - moira_disconnect(); - return; + com_err(whoami, 0, "Unable to fine machine %s (alias %s) container " + "in Moira - moving to orphans OU.", + OriginalMachineName, MachineName); + machine_move_to_ou(ldap_handle, dn_path, MachineName, + orphans_machines_ou); + moira_disconnect(); + return; } - container_get_dn(MoiraContainerName, ADContainerName); - if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/') - strcat(MoiraContainerName, "/"); - container_check(ldap_handle, dn_path, MoiraContainerName); - machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName); - moira_disconnect(); - return; + + container_get_dn(MoiraContainerName, ADContainerName); + + if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/') + strcat(MoiraContainerName, "/"); + + container_check(ldap_handle, dn_path, MoiraContainerName); + machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName); + moira_disconnect(); + return; } void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, - char **before, int beforec, char **after, int afterc) + char **before, int beforec, char **after, int afterc) { long rc; + if (!ProcessMachineContainer) + { + com_err(whoami, 0, "Process machines and containers disabled, skipping"); + return; + } + if ((beforec == 0) && (afterc == 0)) return; @@ -791,6 +876,7 @@ void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, moira_disconnect(); return; } + if ((beforec == 0) && (afterc != 0)) /*create a container*/ { com_err(whoami, 0, "creating container %s", after[CONTAINER_NAME]); @@ -803,20 +889,22 @@ void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME])) { - com_err(whoami, 0, "renaming container %s to %s", before[CONTAINER_NAME], after[CONTAINER_NAME]); + com_err(whoami, 0, "renaming container %s to %s", + before[CONTAINER_NAME], after[CONTAINER_NAME]); container_rename(ldap_handle, dn_path, beforec, before, afterc, after); Moira_container_group_update(before, after); moira_disconnect(); return; } - com_err(whoami, 0, "updating container %s information", after[CONTAINER_NAME]); + + com_err(whoami, 0, "updating container %s information", + after[CONTAINER_NAME]); container_update(ldap_handle, dn_path, beforec, before, afterc, after); Moira_container_group_update(before, after); moira_disconnect(); return; } - #define L_LIST_DESC 9 #define L_LIST_ID 10 @@ -857,8 +945,10 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, strcpy(before_list_id, before[L_LIST_ID]); } before_security_flag = 0; - get_group_membership(before_group_membership, before_group_ou, &before_security_flag, before); + get_group_membership(before_group_membership, before_group_ou, + &before_security_flag, before); } + if (afterc > L_GID) { if (afterc < L_LIST_ID) @@ -870,27 +960,34 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, security_flag = 0; get_group_membership(group_membership, group_ou, &security_flag, after); } - + if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/ return; updateGroup = 0; + if (beforec) { updateGroup = 1; - if ((rc = process_group(ldap_handle, dn_path, before_list_id, before[L_NAME], - before_group_ou, before_group_membership, - before_security_flag, CHECK_GROUPS))) + + if ((rc = process_group(ldap_handle, dn_path, before_list_id, + before[L_NAME], before_group_ou, + before_group_membership, + before_security_flag, CHECK_GROUPS, + before[L_MAILLIST]))) { if (rc == AD_NO_GROUPS_FOUND) updateGroup = 0; else { - if ((rc == AD_WRONG_GROUP_DN_FOUND) || (rc == AD_MULTIPLE_GROUPS_FOUND)) + if ((rc == AD_WRONG_GROUP_DN_FOUND) || + (rc == AD_MULTIPLE_GROUPS_FOUND)) { - rc = process_group(ldap_handle, dn_path, before_list_id, before[L_NAME], - before_group_ou, before_group_membership, - before_security_flag, CLEANUP_GROUPS); + rc = process_group(ldap_handle, dn_path, before_list_id, + before[L_NAME], before_group_ou, + before_group_membership, + before_security_flag, CLEANUP_GROUPS, + before[L_MAILLIST]); } if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0)) { @@ -907,29 +1004,35 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, if ((beforec != 0) && (afterc != 0)) { if (((strcmp(after[L_NAME], before[L_NAME])) || - ((!strcmp(after[L_NAME], before[L_NAME])) && - (strcmp(before_group_ou, group_ou)))) && + ((!strcmp(after[L_NAME], before[L_NAME])) && + (strcmp(before_group_ou, group_ou)))) && (updateGroup == 1)) { com_err(whoami, 0, "Changing list name from %s to %s", before[L_NAME], after[L_NAME]); - if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0) || + + if ((strlen(before_group_ou) == 0) || + (strlen(before_group_membership) == 0) || (strlen(group_ou) == 0) || (strlen(group_membership) == 0)) { com_err(whoami, 0, "%s", "Unable to find the group OU's"); return; } + memset(filter, '\0', sizeof(filter)); + if ((rc = group_rename(ldap_handle, dn_path, before[L_NAME], before_group_membership, - before_group_ou, before_security_flag, before[L_LIST_DESC], - after[L_NAME], group_membership, - group_ou, security_flag, after[L_LIST_DESC], - list_id, filter))) + before_group_ou, before_security_flag, + before[L_LIST_DESC], after[L_NAME], + group_membership, group_ou, security_flag, + after[L_LIST_DESC], + list_id, filter, after[L_MAILLIST]))) { if (rc != AD_NO_GROUPS_FOUND) { - com_err(whoami, 0, "Unable to change list name from %s to %s", + com_err(whoami, 0, + "Unable to change list name from %s to %s", before[L_NAME], after[L_NAME]); return; } @@ -940,39 +1043,50 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, else beforec = 0; } - + if (beforec) { - if ((strlen(before_group_ou) == 0) || (strlen(before_group_membership) == 0)) + if ((strlen(before_group_ou) == 0) || + (strlen(before_group_membership) == 0)) { - com_err(whoami, 0, "Unable to find the group OU for group %s", before[L_NAME]); + com_err(whoami, 0, + "Unable to find the group OU for group %s", before[L_NAME]); return; } + com_err(whoami, 0, "Deleting group %s", before[L_NAME]); rc = group_delete(ldap_handle, dn_path, before[L_NAME], before_group_membership, before_list_id); return; } + if (afterc) { if (!updateGroup) { com_err(whoami, 0, "Creating group %s", after[L_NAME]); + if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME], group_ou, group_membership, - security_flag, CHECK_GROUPS)) + security_flag, CHECK_GROUPS, + after[L_MAILLIST])) { if (rc != AD_NO_GROUPS_FOUND) { - if ((rc == AD_WRONG_GROUP_DN_FOUND) || (rc == AD_MULTIPLE_GROUPS_FOUND)) + if ((rc == AD_WRONG_GROUP_DN_FOUND) || + (rc == AD_MULTIPLE_GROUPS_FOUND)) { - rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME], + rc = process_group(ldap_handle, dn_path, list_id, + after[L_NAME], group_ou, group_membership, - security_flag, CLEANUP_GROUPS); + security_flag, CLEANUP_GROUPS, + after[L_MAILLIST]); } + if (rc) { - com_err(whoami, 0, "Unable to create list %s", after[L_NAME]); + com_err(whoami, 0, + "Unable to create list %s", after[L_NAME]); return; } } @@ -990,24 +1104,32 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, } ProcessGroup = 0; - if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0, &ProcessGroup)) + + if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0, + &ProcessGroup, after[L_MAILLIST])) return; + if (ProcessGroup) { - if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1, &ProcessGroup)) + if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1, + &ProcessGroup, after[L_MAILLIST])) return; } + if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME], - group_ou, group_membership, security_flag, updateGroup)) + group_ou, group_membership, security_flag, + updateGroup, after[L_MAILLIST])) { moira_disconnect(); return; } + if (atoi(after[L_ACTIVE])) { populate_group(ldap_handle, dn_path, after[L_NAME], group_ou, group_membership, security_flag, list_id); } + moira_disconnect(); } return; @@ -1027,6 +1149,10 @@ void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, char **before, int beforec, char **after, int afterc) { + LK_ENTRY *group_base; + int group_count; + char filter[128]; + char *attr_array[3]; char group_name[128]; char user_name[128]; char user_type[128]; @@ -1035,35 +1161,46 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, char group_membership[1]; char group_ou[256]; char machine_ou[256]; + char member[256]; char *args[16]; char **ptr; char *av[7]; char *call_args[7]; char *pUserOu; + char *s; char NewMachineName[1024]; int security_flag; int rc; int ProcessGroup; + char *save_argv[U_END]; pUserOu = NULL; ptr = NULL; memset(moira_list_id, '\0', sizeof(moira_list_id)); memset(moira_user_id, '\0', sizeof(moira_user_id)); + if (afterc) { if (afterc < LM_EXTRA_GID) return; + if (!atoi(after[LM_EXTRA_ACTIVE])) { - com_err(whoami, 0, "Unable to add %s to group %s : group not active", after[2], after[0]); - return; + com_err(whoami, 0, + "Unable to add %s to group %s : group not active", + after[2], after[0]); + return; } + ptr = after; + if (!strcasecmp(ptr[LM_TYPE], "LIST")) return; + strcpy(user_name, after[LM_MEMBER]); strcpy(group_name, after[LM_LIST]); strcpy(user_type, after[LM_TYPE]); + if (!strcasecmp(ptr[LM_TYPE], "MACHINE")) { if (afterc > LM_EXTRA_GROUP) @@ -1092,15 +1229,21 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, return; if (!atoi(before[LM_EXTRA_ACTIVE])) { - com_err(whoami, 0, "Unable to add %s to group %s : group not active", before[2], before[0]); + com_err(whoami, 0, + "Unable to add %s to group %s : group not active", + before[2], before[0]); return; } + ptr = before; + if (!strcasecmp(ptr[LM_TYPE], "LIST")) return; + strcpy(user_name, before[LM_MEMBER]); strcpy(group_name, before[LM_LIST]); strcpy(user_type, before[LM_TYPE]); + if (!strcasecmp(ptr[LM_TYPE], "MACHINE")) { if (beforec > LM_EXTRA_GROUP) @@ -1126,7 +1269,9 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, if (ptr == NULL) { - com_err(whoami, 0, "Unable to process group : beforec = %d, afterc = %d", beforec, afterc); + com_err(whoami, 0, + "Unable to process group : beforec = %d, afterc = %d", + beforec, afterc); return; } @@ -1141,28 +1286,39 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, security_flag = 0; memset(group_ou, '\0', sizeof(group_ou)); get_group_membership(group_membership, group_ou, &security_flag, args); + if (strlen(group_ou) == 0) { - com_err(whoami, 0, "Unable to find the group OU for group %s", group_name); + com_err(whoami, 0, "Unable to find the group OU for group %s", + group_name); return; } - if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name, group_ou, group_membership, security_flag, CHECK_GROUPS)) + + if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name, + group_ou, group_membership, security_flag, + CHECK_GROUPS, args[L_MAILLIST])) { if (rc != AD_NO_GROUPS_FOUND) { - if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name, group_ou, group_membership, security_flag, CLEANUP_GROUPS)) + if (rc = process_group(ldap_handle, dn_path, moira_list_id, + group_name, group_ou, group_membership, + security_flag, CLEANUP_GROUPS, + args[L_MAILLIST])) { if (rc != AD_NO_GROUPS_FOUND) { if (afterc) - com_err(whoami, 0, "Unable to add %s to group %s - unable to process group", user_name, group_name); + com_err(whoami, 0, "Unable to add %s to group %s - " + "unable to process group", user_name, group_name); else - com_err(whoami, 0, "Unable to remove %s from group %s - unable to process group", user_name, group_name); + com_err(whoami, 0, "Unable to remove %s from group %s - " + "unable to process group", user_name, group_name); return; } } } } + if (rc == AD_NO_GROUPS_FOUND) { if (rc = moira_connect()) @@ -1172,88 +1328,180 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, error_message(rc)); return; } - + com_err(whoami, 0, "creating group %s", group_name); ProcessGroup = 0; - if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0, &ProcessGroup)) + + if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0, + &ProcessGroup, ptr[LM_EXTRA_MAILLIST])) return; + if (ProcessGroup) { - if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1, &ProcessGroup)) + if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1, + &ProcessGroup, ptr[LM_EXTRA_MAILLIST])) return; } + if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST], - group_ou, group_membership, security_flag, 0)) + group_ou, group_membership, security_flag, 0, + ptr[LM_EXTRA_MAILLIST])) { moira_disconnect(); return; } + if (atoi(ptr[LM_EXTRA_ACTIVE])) { populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou, group_membership, security_flag, moira_list_id); } + moira_disconnect(); } + rc = 0; + if (beforec) { - com_err(whoami, 0, "removing user %s from list %s", user_name, group_name); + com_err(whoami, 0, "removing user %s from list %s", user_name, + group_name); pUserOu = user_ou; + if (!strcasecmp(ptr[LM_TYPE], "MACHINE")) { memset(machine_ou, '\0', sizeof(machine_ou)); memset(NewMachineName, '\0', sizeof(NewMachineName)); - if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou, NewMachineName)) + if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], + machine_ou, NewMachineName)) return; if (ptr[LM_MEMBER] != NULL) free(ptr[LM_MEMBER]); ptr[LM_MEMBER] = strdup(NewMachineName); pUserOu = machine_ou; } + if (!strcasecmp(ptr[LM_TYPE], "STRING")) { + strcpy(member, ptr[LM_MEMBER]); + + if (Exchange) + { + if((s = strchr(member, '@')) == (char *) NULL) + { + strcat(member, "@mit.edu"); + + if (ptr[LM_MEMBER] != NULL) + free(ptr[LM_MEMBER]); + ptr[LM_MEMBER] = strdup(member); + } + + if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6)) + { + s = strrchr(member, '.'); + *s = '\0'; + strcat(s, ".mit.edu"); + + if (ptr[LM_MEMBER] != NULL) + free(ptr[LM_MEMBER]); + ptr[LM_MEMBER] = strdup(member); + } + } + if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou)) return; + pUserOu = contact_ou; } else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS")) - { - if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou)) - return; - pUserOu = kerberos_ou; - } + { + if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], + kerberos_ou)) + return; + + pUserOu = kerberos_ou; + } if (rc = member_remove(ldap_handle, dn_path, group_name, - group_ou, group_membership, ptr[LM_MEMBER], - pUserOu, moira_list_id)) - com_err(whoami, 0, "Unable to remove %s from group %s", user_name, group_name); + group_ou, group_membership, ptr[LM_MEMBER], + pUserOu, moira_list_id)) + com_err(whoami, 0, "Unable to remove %s from group %s", user_name, + group_name); + + if (!strcasecmp(ptr[LM_TYPE], "STRING")) + { + if (rc = moira_connect()) + { + critical_alert("AD incremental", + "Error contacting Moira server : %s", + error_message(rc)); + return; + } + + if (rc = populate_group(ldap_handle, dn_path, group_name, + group_ou, group_membership, security_flag, + moira_list_id)) + com_err(whoami, 0, "Unable to remove %s from group %s", + user_name, group_name); + moira_disconnect(); + } return; } - + com_err(whoami, 0, "Adding %s to list %s", user_name, group_name); pUserOu = user_ou; - + if (!strcasecmp(ptr[LM_TYPE], "MACHINE")) { memset(machine_ou, '\0', sizeof(machine_ou)); memset(NewMachineName, '\0', sizeof(NewMachineName)); - if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou, NewMachineName)) + + if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou, + NewMachineName)) return; + if (ptr[LM_MEMBER] != NULL) free(ptr[LM_MEMBER]); + ptr[LM_MEMBER] = strdup(NewMachineName); pUserOu = machine_ou; } else if (!strcasecmp(ptr[LM_TYPE], "STRING")) { + strcpy(member, ptr[LM_MEMBER]); + + if (Exchange) + { + if((s = strchr(member, '@')) == (char *) NULL) + { + strcat(member, "@mit.edu"); + + if (ptr[LM_MEMBER] != NULL) + free(ptr[LM_MEMBER]); + ptr[LM_MEMBER] = strdup(member); + } + + if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6)) + { + s = strrchr(member, '.'); + *s = '\0'; + strcat(s, ".mit.edu"); + + if (ptr[LM_MEMBER] != NULL) + free(ptr[LM_MEMBER]); + ptr[LM_MEMBER] = strdup(member); + } + } + if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou)) return; + pUserOu = contact_ou; } else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS")) { if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou)) return; + pUserOu = kerberos_ou; } else if (!strcasecmp(ptr[LM_TYPE], "USER")) @@ -1268,22 +1516,61 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, error_message(rc)); return; } - com_err(whoami, 0, "creating user %s", after[U_NAME]); + + com_err(whoami, 0, "creating user %s", ptr[LM_MEMBER]); av[0] = ptr[LM_MEMBER]; call_args[0] = (char *)ldap_handle; call_args[1] = dn_path; call_args[2] = moira_user_id; call_args[3] = NULL; - + callback_rc = 0; - if (rc = mr_query("get_user_account_by_login", 1, av, user_create, - call_args)) + + if (Exchange) + { + group_count = 0; + group_base = NULL; + + sprintf(filter, "(&(objectClass=group)(cn=%s))", ptr[LM_MEMBER]); + attr_array[0] = "cn"; + attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, + attr_array, &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to process user %s : %s", + ptr[LM_MEMBER], ldap_err2string(rc)); + return; + } + + if (group_count) + { + com_err(whoami, 0, "Object already exists with name %s", + ptr[LM_MEMBER]); + return; + } + + linklist_free(group_base); + group_count = 0; + group_base = NULL; + } + + if (rc = mr_query("get_user_account_by_login", 1, av, + save_query_info, save_argv)) { moira_disconnect(); com_err(whoami, 0, "Unable to create user %s : %s", ptr[LM_MEMBER], error_message(rc)); return; } + + if (rc = user_create(U_END, save_argv, call_args)) + { + moira_disconnect(); + com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]); + return; + } + if (callback_rc) { moira_disconnect(); @@ -1298,13 +1585,31 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, } pUserOu = user_ou; } - + if (rc = member_add(ldap_handle, dn_path, group_name, - group_ou, group_membership, ptr[LM_MEMBER], - pUserOu, moira_list_id)) + group_ou, group_membership, ptr[LM_MEMBER], + pUserOu, moira_list_id)) + com_err(whoami, 0, "Unable to add %s to group %s", user_name, group_name); + + if (!strcasecmp(ptr[LM_TYPE], "STRING")) { - com_err(whoami, 0, "Unable to add %s to group %s", user_name, group_name); + if (rc = moira_connect()) + { + critical_alert("AD incremental", + "Error contacting Moira server : %s", + error_message(rc)); + return; + } + + if (rc = populate_group(ldap_handle, dn_path, group_name, + group_ou, group_membership, security_flag, + moira_list_id)) + com_err(whoami, 0, "Unable to add %s to group %s", + user_name, group_name); + + moira_disconnect(); } + return; } @@ -1312,25 +1617,31 @@ void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, #define U_USER_ID 10 #define U_HOMEDIR 11 #define U_PROFILEDIR 12 -#define U_POTYPE 13 void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, char **before, int beforec, char **after, int afterc) { + LK_ENTRY *group_base; + int group_count; + char filter[128]; + char *attr_array[3]; int rc; char *av[7]; char after_user_id[32]; char before_user_id[32]; char *call_args[7]; + char *save_argv[U_END]; if ((beforec == 0) && (afterc == 0)) return; memset(after_user_id, '\0', sizeof(after_user_id)); memset(before_user_id, '\0', sizeof(before_user_id)); + if (beforec > U_USER_ID) strcpy(before_user_id, before[U_USER_ID]); + if (afterc > U_USER_ID) strcpy(after_user_id, after[U_USER_ID]); @@ -1341,11 +1652,16 @@ void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, { /*this case only happens when the account*/ /*account is first created but not usable*/ - com_err(whoami, 0, "Unable to process user %s because the user account is not yet usable", after[U_NAME]); + + com_err(whoami, 0, "Unable to process user %s because the user account " + "is not yet usable", after[U_NAME]); return; } - if ((beforec != 0) && (afterc == 0)) /*this case only happens when the account*/ - { /*is expunged*/ + + /*this case only happens when the account is expunged */ + + if ((beforec != 0) && (afterc == 0)) + { if (atoi(before[U_STATE]) == 0) { com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]); @@ -1353,17 +1669,20 @@ void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, } else { - com_err(whoami, 0, "Unable to process because user %s has been previously expungeded", before[U_NAME]); + com_err(whoami, 0, "Unable to process because user %s has been " + "previously expungeded", before[U_NAME]); } return; } /*process anything that gets here*/ + if ((rc = check_user(ldap_handle, dn_path, before[U_NAME], before_user_id)) == AD_NO_USER_FOUND) { if (!check_string(after[U_NAME])) return; + if (rc = moira_connect()) { critical_alert("AD incremental", @@ -1371,28 +1690,69 @@ void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, error_message(rc)); return; } - com_err(whoami, 0, "creating user %s", after[U_NAME]); + com_err(whoami, 0, "creating user %s", after[U_NAME]); + av[0] = after[U_NAME]; call_args[0] = (char *)ldap_handle; call_args[1] = dn_path; call_args[2] = after_user_id; call_args[3] = NULL; callback_rc = 0; - if (rc = mr_query("get_user_account_by_login", 1, av, user_create, - call_args)) + + if (Exchange) + { + group_count = 0; + group_base = NULL; + + sprintf(filter, "(&(objectClass=group)(cn=%s))", after[U_NAME]); + attr_array[0] = "cn"; + attr_array[1] = NULL; + + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to process user %s : %s", + after[U_NAME], ldap_err2string(rc)); + return; + } + + if (group_count >= 1) + { + com_err(whoami, 0, "Object already exists with name %s", + after[U_NAME]); + return; + } + + linklist_free(group_base); + group_count = 0; + group_base = NULL; + } + + if (rc = mr_query("get_user_account_by_login", 1, av, + save_query_info, save_argv)) { moira_disconnect(); com_err(whoami, 0, "Unable to create user %s : %s", after[U_NAME], error_message(rc)); return; } - if (callback_rc) - { - moira_disconnect(); - com_err(whoami, 0, "Unable to create user %s", after[U_NAME]); + + if (rc = user_create(U_END, save_argv, call_args)) + { + com_err(whoami, 0, "Unable to create user %s : %s", + after[U_NAME], error_message(rc)); + return; + } + + if (callback_rc) + { + moira_disconnect(); + com_err(whoami, 0, "Unable to create user %s", after[U_NAME]); return; } + return; } else @@ -1400,12 +1760,14 @@ void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, if (rc != 0) return; } + if (strcmp(before[U_NAME], after[U_NAME])) { if ((check_string(before[U_NAME])) && (check_string(after[U_NAME]))) { com_err(whoami, 0, "changing user %s to %s", before[U_NAME], after[U_NAME]); + if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME], after[U_NAME])) != LDAP_SUCCESS) { @@ -1413,11 +1775,14 @@ void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname, } } } + com_err(whoami, 0, "updating user %s information", after[U_NAME]); rc = user_update(ldap_handle, dn_path, after[U_NAME], after[U_UID], after[U_MITID], - after_user_id, atoi(after[U_STATE]), - after[U_HOMEDIR], after[U_PROFILEDIR]); + after_user_id, atoi(after[U_STATE]), + after[U_HOMEDIR], after[U_PROFILEDIR], + after[U_FIRST], after[U_MIDDLE], after[U_LAST]); + return; } @@ -1428,14 +1793,16 @@ int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, LK_ENTRY *linklist_ptr; int i; char *cPtr; - - if (((*modvalues) = calloc(1, (modvalue_count + 1) * sizeof(char *))) - == NULL) + + if (((*modvalues) = calloc(1, + (modvalue_count + 1) * sizeof(char *))) == NULL) { return(1); } + for (i = 0; i < (modvalue_count + 1); i++) (*modvalues)[i] = NULL; + if (modvalue_count != 0) { linklist_ptr = linklist_base; @@ -1444,7 +1811,7 @@ int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, if ((oldValue != NULL) && (newValue != NULL)) { if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue)) - != (char *)NULL) + != (char *)NULL) { if (type == REPLACE) { @@ -1458,8 +1825,9 @@ int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, { if (((*modvalues)[i] = calloc(1, (int)(cPtr - linklist_ptr->value) + - (linklist_ptr->length - strlen(oldValue)) + - strlen(newValue) + 1)) == NULL) + (linklist_ptr->length - + strlen(oldValue)) + + strlen(newValue) + 1)) == NULL) return(1); memset((*modvalues)[i], '\0', (int)(cPtr - linklist_ptr->value) + @@ -1469,7 +1837,8 @@ int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count, (int)(cPtr - linklist_ptr->value)); strcat((*modvalues)[i], newValue); strcat((*modvalues)[i], - &linklist_ptr->value[(int)(cPtr - linklist_ptr->value) + strlen(oldValue)]); + &linklist_ptr->value[(int)(cPtr - + linklist_ptr->value) + strlen(oldValue)]); } } else @@ -1506,21 +1875,22 @@ int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp, ldap_entry = NULL; (*linklist_base) = NULL; (*linklist_count) = 0; + if ((rc = ldap_search_s(ldap_handle, dn_path, ScopeType, - search_exp, attr_array, 0, &ldap_entry)) - != LDAP_SUCCESS) + search_exp, attr_array, 0, + &ldap_entry)) != LDAP_SUCCESS) { if (rc != LDAP_SIZELIMIT_EXCEEDED) return(0); } - rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, linklist_count); + rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base, + linklist_count); ldap_msgfree(ldap_entry); return(rc); } - int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, LK_ENTRY **linklist_base, int *linklist_count) { @@ -1530,7 +1900,7 @@ int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL) return(0); - + memset(distinguished_name, '\0', sizeof(distinguished_name)); get_distinguished_name(ldap_handle, ldap_entry, distinguished_name); @@ -1542,19 +1912,21 @@ int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry, { memset(distinguished_name, '\0', sizeof(distinguished_name)); get_distinguished_name(ldap_handle, ldap_entry, distinguished_name); - - if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name, - linklist_base)) != 0) + + if ((rc = retrieve_attributes(ldap_handle, ldap_entry, + distinguished_name, linklist_base)) != 0) return(rc); } linklist_ptr = (*linklist_base); (*linklist_count) = 0; + while (linklist_ptr != NULL) { ++(*linklist_count); linklist_ptr = linklist_ptr->next; } + return(0); } @@ -1565,7 +1937,9 @@ int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, BerElement *ptr; ptr = NULL; - if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, &ptr)) != NULL) + + if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry, + &ptr)) != NULL) { retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name, linklist_current); @@ -1578,7 +1952,9 @@ int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry, ldap_memfree(Attribute); } } + ldap_ber_free(ptr, 0); + return(0); } @@ -1593,6 +1969,7 @@ int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, LK_ENTRY *linklist_previous; LDAP_BERVAL **ber_value; DWORD ber_length; + #ifdef LDAP_DEBUG SID *sid; GUID *guid; @@ -1605,68 +1982,81 @@ int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, use_bervalue = 0; memset(temp, '\0', sizeof(temp)); + if ((!strcmp(Attribute, "objectSid")) || (!strcmp(Attribute, "objectGUID"))) use_bervalue = 1; - + if (use_bervalue) { ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute); Ptr = (void **)ber_value; str_value = NULL; - } + } else { str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute); Ptr = (void **)str_value; ber_value = NULL; } + if (Ptr != NULL) { for (; *Ptr; Ptr++) { if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL) return(1); + memset(linklist_previous, '\0', sizeof(LK_ENTRY)); linklist_previous->next = (*linklist_current); (*linklist_current) = linklist_previous; - + if (((*linklist_current)->attribute = calloc(1, - strlen(Attribute) + 1)) == NULL) + strlen(Attribute) + 1)) == NULL) return(1); + memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1); strcpy((*linklist_current)->attribute, Attribute); + if (use_bervalue) { ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len; + if (((*linklist_current)->value = calloc(1, ber_length)) == NULL) return(1); + memset((*linklist_current)->value, '\0', ber_length); - memcpy((*linklist_current)->value, (*(LDAP_BERVAL **)Ptr)->bv_val, - ber_length); + memcpy((*linklist_current)->value, + (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length); (*linklist_current)->length = ber_length; } else { if (((*linklist_current)->value = calloc(1, - strlen(*Ptr) + 1)) == NULL) + strlen(*Ptr) + 1)) == NULL) return(1); + memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1); (*linklist_current)->length = strlen(*Ptr); strcpy((*linklist_current)->value, *Ptr); } + (*linklist_current)->ber_value = use_bervalue; + if (((*linklist_current)->dn = calloc(1, - strlen(distinguished_name) + 1)) == NULL) + strlen(distinguished_name) + 1)) == NULL) return(1); - memset((*linklist_current)->dn, '\0', strlen(distinguished_name) + 1); + + memset((*linklist_current)->dn, '\0', + strlen(distinguished_name) + 1); strcpy((*linklist_current)->dn, distinguished_name); #ifdef LDAP_DEBUG if (!strcmp(Attribute, "objectGUID")) { guid = (GUID *)((*linklist_current)->value); - sprintf(temp, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + sprintf(temp, + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", guid->Data1, guid->Data2, guid->Data3, guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3], guid->Data4[4], guid->Data4[5], @@ -1676,6 +2066,7 @@ int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, else if (!strcmp(Attribute, "objectSid")) { sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val); + #ifdef _WIN32 print_to_screen(" Revision = %d\n", sid->Revision); print_to_screen(" SID Identifier Authority:\n"); @@ -1687,7 +2078,7 @@ int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, else if (sid_auth->Value[2]) print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n"); else if (sid_auth->Value[3]) - print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n"); + print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n"); else if (sid_auth->Value[5]) print_to_screen(" SECURITY_NT_AUTHORITY\n"); else @@ -1710,6 +2101,7 @@ int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, { intValue = atoi(*Ptr); print_to_screen(" %20s : %ld\n",Attribute, intValue); + if (!memcmp(Attribute, "userAccountControl", strlen("userAccountControl"))) { @@ -1754,12 +2146,16 @@ int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry, } #endif /*LDAP_DEBUG*/ } + if (str_value != NULL) ldap_value_free(str_value); + if (ber_value != NULL) ldap_value_free_len(ber_value); } + (*linklist_current) = linklist_previous; + return(0); } @@ -1770,27 +2166,20 @@ int moira_connect(void) if (!mr_connections++) { + #ifdef _WIN32 memset(HostName, '\0', sizeof(HostName)); strcpy(HostName, "ttsp"); rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1); -/*det - rc = mr_connect(HostName); -*/ #else struct utsname uts; uname(&uts); rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1); -/* - rc = mr_connect(uts.nodename); -*/ #endif /*WIN32*/ -/*det - if (!rc) - rc = mr_krb5_auth("winad.incr"); -*/ + return rc; } + return 0; } @@ -1807,8 +2196,10 @@ int check_winad(void) STOP_FILE, tbl_buf); return(1); } + sleep(60); } + return(0); } @@ -1819,6 +2210,7 @@ int moira_disconnect(void) { mr_disconnect(); } + return 0; } @@ -1826,10 +2218,12 @@ void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry, char *distinguished_name) { char *CName; - + CName = ldap_get_dn(ldap_handle, ldap_entry); + if (CName == NULL) return; + strcpy(distinguished_name, CName); ldap_memfree(CName); } @@ -1838,10 +2232,12 @@ int linklist_create_entry(char *attribute, char *value, LK_ENTRY **linklist_entry) { (*linklist_entry) = calloc(1, sizeof(LK_ENTRY)); + if (!(*linklist_entry)) { return(1); } + memset((*linklist_entry), '\0', sizeof(LK_ENTRY)); (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1); memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1); @@ -1851,6 +2247,7 @@ int linklist_create_entry(char *attribute, char *value, strcpy((*linklist_entry)->value, value); (*linklist_entry)->length = strlen(value); (*linklist_entry)->next = NULL; + return(0); } @@ -1869,18 +2266,21 @@ int get_group_membership(char *group_membership, char *group_ou, { int maillist_flag; int group_flag; - + maillist_flag = atoi(av[L_MAILLIST]); group_flag = atoi(av[L_GROUP]); + if (security_flag != NULL) (*security_flag) = 0; - + if ((maillist_flag) && (group_flag)) { if (group_membership != NULL) group_membership[0] = 'B'; + if (security_flag != NULL) (*security_flag) = 1; + if (group_ou != NULL) strcpy(group_ou, group_ou_both); } @@ -1888,8 +2288,10 @@ int get_group_membership(char *group_membership, char *group_ou, { if (group_membership != NULL) group_membership[0] = 'S'; + if (security_flag != NULL) (*security_flag) = 1; + if (group_ou != NULL) strcpy(group_ou, group_ou_security); } @@ -1897,6 +2299,7 @@ int get_group_membership(char *group_membership, char *group_ou, { if (group_membership != NULL) group_membership[0] = 'D'; + if (group_ou != NULL) strcpy(group_ou, group_ou_distribution); } @@ -1904,50 +2307,108 @@ int get_group_membership(char *group_membership, char *group_ou, { if (group_membership != NULL) group_membership[0] = 'N'; + if (group_ou != NULL) strcpy(group_ou, group_ou_neither); } + return(0); } int group_rename(LDAP *ldap_handle, char *dn_path, char *before_group_name, char *before_group_membership, - char *before_group_ou, int before_security_flag, char *before_desc, - char *after_group_name, char *after_group_membership, - char *after_group_ou, int after_security_flag, char *after_desc, - char *MoiraId, char *filter) + char *before_group_ou, int before_security_flag, + char *before_desc, char *after_group_name, + char *after_group_membership, char *after_group_ou, + int after_security_flag, char *after_desc, + char *MoiraId, char *filter, char *maillist) { LDAPMod *mods[20]; char old_dn[512]; char new_dn[512]; char new_dn_path[512]; char sam_name[256]; + char mail[256]; + char mail_nickname[256]; + char proxy_address[256]; + char address_book[256]; char *attr_array[3]; char *mitMoiraId_v[] = {NULL, NULL}; char *name_v[] = {NULL, NULL}; char *samAccountName_v[] = {NULL, NULL}; char *groupTypeControl_v[] = {NULL, NULL}; - u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP; + char *mail_v[] = {NULL, NULL}; + char *proxy_address_v[] = {NULL, NULL}; + char *mail_nickname_v[] = {NULL, NULL}; + char *reportToOriginator_v[] = {NULL, NULL}; + char *address_book_v[] = {NULL, NULL}; + char *legacy_exchange_dn_v[] = {NULL, NULL}; + u_int groupTypeControl; char groupTypeControlStr[80]; + char contact_mail[256]; int n; int i; int rc; LK_ENTRY *group_base; int group_count; + int MailDisabled = 0; + if(UseGroupUniversal) + groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP; + else + groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP; + if (!check_string(before_group_name)) { - com_err(whoami, 0, "Unable to process invalid LDAP list name %s", before_group_name); + com_err(whoami, 0, + "Unable to process invalid LDAP list name %s", + before_group_name); return(AD_INVALID_NAME); } + if (!check_string(after_group_name)) { - com_err(whoami, 0, "Unable to process invalid LDAP list name %s", after_group_name); + com_err(whoami, 0, + "Unable to process invalid LDAP list name %s", after_group_name); return(AD_INVALID_NAME); } + if (Exchange) + { + if(atoi(maillist)) + { + group_count = 0; + group_base = NULL; + + sprintf(filter, "(&(objectClass=user)(cn=%s))", after_group_name); + attr_array[0] = "cn"; + attr_array[1] = NULL; + + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to process group %s : %s", + after_group_name, ldap_err2string(rc)); + return(rc); + } + + if (group_count) + { + com_err(whoami, 0, "Object already exists with name %s", + after_group_name); + MailDisabled++; + } + + linklist_free(group_base); + group_base = NULL; + group_count = 0; + } + } + group_count = 0; group_base = NULL; + if (rc = ad_get_group(ldap_handle, dn_path, before_group_name, before_group_membership, MoiraId, "distinguishedName", &group_base, @@ -1958,13 +2419,14 @@ int group_rename(LDAP *ldap_handle, char *dn_path, { return(AD_NO_GROUPS_FOUND); } + if (group_count != 1) { - com_err(whoami, 0, - "Unable to process multiple groups with MoiraId = %s exist in the AD", - MoiraId); + com_err(whoami, 0, "Unable to process multiple groups with " + "MoiraId = %s exist in the AD", MoiraId); return(AD_MULTIPLE_GROUPS_FOUND); } + strcpy(old_dn, group_base->value); linklist_free(group_base); @@ -1972,13 +2434,16 @@ int group_rename(LDAP *ldap_handle, char *dn_path, group_count = 0; attr_array[0] = "sAMAccountName"; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to get list %s dn : %s", after_group_name, ldap_err2string(rc)); return(rc); } + if (group_count != 1) { com_err(whoami, 0, @@ -1986,14 +2451,20 @@ int group_rename(LDAP *ldap_handle, char *dn_path, before_group_name); return(AD_LDAP_FAILURE); } - + strcpy(sam_name, group_base->value); linklist_free(group_base); group_base = NULL; group_count = 0; - + sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path); sprintf(new_dn, "cn=%s", after_group_name); + sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain)); + sprintf(contact_mail, "%s@mit.edu", after_group_name); + sprintf(proxy_address, "SMTP:%s@%s", after_group_name, + lowercase(ldap_domain)); + sprintf(mail_nickname, "%s", after_group_name); + if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path, TRUE, NULL, NULL)) != LDAP_SUCCESS) { @@ -2003,38 +2474,83 @@ int group_rename(LDAP *ldap_handle, char *dn_path, } name_v[0] = after_group_name; - if (!strncmp(&sam_name[strlen(sam_name) - strlen("_group")], "_group", strlen("_group"))) + + if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)], + group_suffix, strlen(group_suffix))) { - sprintf(sam_name, "%s_group", after_group_name); + sprintf(sam_name, "%s%s", after_group_name, group_suffix); } else { - com_err(whoami, 0, "Unable to rename list from %s to %s : sAMAccountName not found", + com_err(whoami, 0, + "Unable to rename list from %s to %s : sAMAccountName not found", before_group_name, after_group_name); return(rc); } + samAccountName_v[0] = sam_name; + if (after_security_flag) groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED; + sprintf(groupTypeControlStr, "%ld", groupTypeControl); groupTypeControl_v[0] = groupTypeControlStr; mitMoiraId_v[0] = MoiraId; sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path); - rc = attribute_update(ldap_handle, new_dn, after_desc, "description", after_group_name); + rc = attribute_update(ldap_handle, new_dn, after_desc, "description", + after_group_name); n = 0; ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE); ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE); ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE); ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE); + + if (Exchange) + { + if(atoi(maillist) && !MailDisabled && email_isvalid(mail)) + { + mail_nickname_v[0] = mail_nickname; + proxy_address_v[0] = proxy_address; + mail_v[0] = mail; + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE); + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE); + } + else + { + mail_nickname_v[0] = NULL; + proxy_address_v[0] = NULL; + mail_v[0] = NULL; + legacy_exchange_dn_v[0] = mail; + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE); + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE); + ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE); + ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE); + } + } + else + { + if(atoi(maillist) && email_isvalid(contact_mail)) + { + mail_v[0] = contact_mail; + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + } + } + mods[n] = NULL; + if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS) { - com_err(whoami, 0, "Unable to modify list data for %s after renaming: %s", + com_err(whoami, 0, + "Unable to modify list data for %s after renaming: %s", after_group_name, ldap_err2string(rc)); } + for (i = 0; i < n; i++) free(mods[i]); + return(rc); } @@ -2046,6 +2562,11 @@ int group_create(int ac, char **av, void *ptr) char new_group_name[256]; char sam_group_name[256]; char cn_group_name[256]; + char mail[256]; + char contact_mail[256]; + char mail_nickname[256]; + char proxy_address[256]; + char address_book[256]; char *cn_v[] = {NULL, NULL}; char *objectClass_v[] = {"top", "group", NULL}; char info[256]; @@ -2057,44 +2578,63 @@ int group_create(int ac, char **av, void *ptr) char *info_v[] = {NULL, NULL}; char *mitMoiraId_v[] = {NULL, NULL}; char *groupTypeControl_v[] = {NULL, NULL}; + char *mail_v[] = {NULL, NULL}; + char *proxy_address_v[] = {NULL, NULL}; + char *mail_nickname_v[] = {NULL, NULL}; + char *reportToOriginator_v[] = {NULL, NULL}; + char *address_book_v[] = {NULL, NULL}; + char *legacy_exchange_dn_v[] = {NULL, NULL}; char groupTypeControlStr[80]; char group_membership[1]; int i; int security_flag; - u_int groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP; + u_int groupTypeControl; int n; int rc; int updateGroup; + int MailDisabled; char **call_args; call_args = ptr; + if(UseGroupUniversal) + groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP; + else + groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP; + if (!check_string(av[L_NAME])) { - com_err(whoami, 0, "Unable to process invalid LDAP list name %s", av[L_NAME]); + com_err(whoami, 0, "Unable to process invalid LDAP list name %s", + av[L_NAME]); return(AD_INVALID_NAME); } updateGroup = (int)call_args[4]; + MailDisabled = atoi(call_args[6]); memset(group_ou, 0, sizeof(group_ou)); memset(group_membership, 0, sizeof(group_membership)); security_flag = 0; + get_group_membership(group_membership, group_ou, &security_flag, av); + strcpy(new_group_name, av[L_NAME]); sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]); + sprintf(contact_mail, "%s@mit.edu", av[L_NAME]); + sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain)); + sprintf(mail_nickname, "%s", av[L_NAME]); + if (security_flag) groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED; - sprintf(sam_group_name, "%s_group", av[L_NAME]); + sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix); if (!updateGroup) { - sprintf(groupTypeControlStr, "%ld", groupTypeControl); groupTypeControl_v[0] = groupTypeControlStr; strcpy(cn_group_name, av[L_NAME]); - + samAccountName_v[0] = sam_group_name; name_v[0] = new_group_name; cn_v[0] = new_group_name; @@ -2105,29 +2645,53 @@ int group_create(int ac, char **av, void *ptr) ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD); ADD_ATTR("displayName", name_v, LDAP_MOD_ADD); ADD_ATTR("name", name_v, LDAP_MOD_ADD); + + if (Exchange) + { + if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail)) + { + mail_nickname_v[0] = mail_nickname; + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD); + } + } + else + { + if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail)) + { + mail_v[0] = contact_mail; + ADD_ATTR("mail", mail_v, LDAP_MOD_ADD); + } + } + if (strlen(av[L_DESC]) != 0) { desc_v[0] = av[L_DESC]; ADD_ATTR("description", desc_v, LDAP_MOD_ADD); } + ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD); + if (strlen(av[L_ACE_NAME]) != 0) { - sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]); + sprintf(info, "The Administrator of this list is: %s", + av[L_ACE_NAME]); info_v[0] = info; ADD_ATTR("info", info_v, LDAP_MOD_ADD); } + if (strlen(call_args[5]) != 0) { mitMoiraId_v[0] = call_args[5]; ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD); } - mods[n] = NULL; + mods[n] = NULL; + rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL); - + for (i = 0; i < n; i++) free(mods[i]); + if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) { com_err(whoami, 0, "Unable to create list %s in AD : %s", @@ -2136,29 +2700,75 @@ int group_create(int ac, char **av, void *ptr) return(rc); } } + if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup)) { - rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC], "description", av[L_NAME]); + rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC], + "description", av[L_NAME]); sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]); - rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info", av[L_NAME]); + rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info", + av[L_NAME]); n = 0; + if (strlen(call_args[5]) != 0) { mitMoiraId_v[0] = call_args[5]; ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE); } + if (!(atoi(av[L_ACTIVE]))) { member_v[0] = NULL; ADD_ATTR("member", member_v, LDAP_MOD_REPLACE); } + + if (Exchange) + { + if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail)) + { + mail_nickname_v[0] = mail_nickname; + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE); + } + else + { + mail_v[0] = NULL; + mail_nickname_v[0] = NULL; + proxy_address_v[0] = NULL; + legacy_exchange_dn_v[0] = NULL; + address_book_v[0] = NULL; + + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE); + ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE); + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, + LDAP_MOD_REPLACE); + ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE); + } + } + else + { + if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail)) + { + mail_v[0] = contact_mail; + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + } + else + { + mail_v[0] = NULL; + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + } + } + mods[n] = NULL; rc = LDAP_SUCCESS; + if (n != 0) { rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods); + for (i = 0; i < n; i++) free(mods[i]); + if (rc != LDAP_SUCCESS) { com_err(whoami, 0, "Unable to update list %s in AD : %s", @@ -2175,8 +2785,9 @@ int group_create(int ac, char **av, void *ptr) return(LDAP_SUCCESS); } -int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName, - int HiddenGroup, char *AceType, char *AceName) +int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, + char *TargetGroupName, int HiddenGroup, + char *AceType, char *AceName) { char filter_exp[1024]; char *attr_array[5]; @@ -2192,6 +2803,10 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName unsigned char UserTemplateSid[128]; char acBERBuf[N_SD_BER_BYTES]; char GroupSecurityTemplate[256]; + char hide_addres_lists[256]; + char address_book[256]; + char *hide_address_lists_v[] = {NULL, NULL}; + char *address_book_v[] = {NULL, NULL}; int AceSidCount; int UserTemplateSidCount; int group_count; @@ -2211,23 +2826,28 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName LDAPControl *apsServerControls[] = {&sControl, NULL}; LDAPMessage *psMsg; - dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION; + dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION; BEREncodeSecurityBits(dwInfo, acBERBuf); sprintf(search_path, "%s,%s", group_ou_root, dn_path); - sprintf(filter_exp, "(sAMAccountName=%s_group)", TargetGroupName); + sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix); attr_array[0] = "sAMAccountName"; attr_array[1] = NULL; group_count = 0; group_base = NULL; + if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE) != 0)) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE) != 0)) return(1); + if (group_count != 1) { linklist_free(group_base); return(1); } + strcpy(TargetDn, group_base->dn); strcpy(TargetSamName, group_base->value); linklist_free(group_base); @@ -2241,11 +2861,12 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName AceSidCount = 0; group_base = NULL; group_count = 0; + if (strlen(AceName) != 0) { if (!strcmp(AceType, "LIST")) { - sprintf(AceSamAccountName, "%s_group", AceName); + sprintf(AceSamAccountName, "%s%s", AceName, group_suffix); strcpy(root_ou, group_ou_root); } else if (!strcmp(AceType, "USER")) @@ -2253,6 +2874,7 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName sprintf(AceSamAccountName, "%s", AceName); strcpy(root_ou, user_ou); } + if (strlen(AceSamAccountName) != 0) { sprintf(search_path, "%s", dn_path); @@ -2261,8 +2883,10 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName attr_array[1] = NULL; group_count = 0; group_base = NULL; - if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE) != 0)) + + if ((rc = linklist_build(ldap_handle, search_path, filter_exp, + attr_array, &group_base, &group_count, + LDAP_SCOPE_SUBTREE) != 0)) return(1); if (group_count == 1) { @@ -2275,9 +2899,11 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName group_count = 0; } } + if (AceSidCount == 0) { - com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not have an AD SID.", TargetGroupName, AceName, AceType); + com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not " + "have an AD SID.", TargetGroupName, AceName, AceType); com_err(whoami, 0, " Non-admin security group template will be used."); } else @@ -2289,12 +2915,16 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName group_count = 0; group_base = NULL; - if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE) != 0)) + + if ((rc = linklist_build(ldap_handle, search_path, filter_exp, + attr_array, &group_base, &group_count, + LDAP_SCOPE_SUBTREE) != 0)) return(1); + if ((rc != 0) || (group_count != 1)) { - com_err(whoami, 0, "Unable to process user security template: %s", "UserTemplate"); + com_err(whoami, 0, "Unable to process user security template: %s", + "UserTemplate"); AceSidCount = 0; } else @@ -2330,7 +2960,8 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName else { strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN); - sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP_WITH_ADMIN); + sprintf(filter_exp, "(sAMAccountName=%s)", + NOT_HIDDEN_GROUP_WITH_ADMIN); } } @@ -2339,21 +2970,26 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName attr_array[1] = NULL; group_count = 0; group_base = NULL; + if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE) != 0)) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE) != 0)) return(1); + if (group_count != 1) { linklist_free(group_base); - com_err(whoami, 0, "Unable to process group security template: %s - security not set", GroupSecurityTemplate); + com_err(whoami, 0, "Unable to process group security template: %s - " + "security not set", GroupSecurityTemplate); return(1); } + strcpy(TemplateDn, group_base->dn); strcpy(TemplateSamName, group_base->value); linklist_free(group_base); group_base = NULL; group_count = 0; - + sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName); rc = ldap_search_ext_s(ldap_handle, TemplateDn, @@ -2369,23 +3005,29 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL) { - com_err(whoami, 0, "Unable to find group security template: %s - security not set", GroupSecurityTemplate); + com_err(whoami, 0, "Unable to find group security template: %s - " + "security not set", GroupSecurityTemplate); return(1); } + ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor"); + if (ppsValues == NULL) { - com_err(whoami, 0, "Unable to find group security descriptor for group %s - security not set", GroupSecurityTemplate); + com_err(whoami, 0, "Unable to find group security descriptor for group " + "%s - security not set", GroupSecurityTemplate); return(1); } - + if (AceSidCount != 0) { for (nVal = 0; ppsValues[nVal] != NULL; nVal++) { - for (i = 0; i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++) + for (i = 0; + i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++) { - if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid, UserTemplateSidCount)) + if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid, + UserTemplateSidCount)) { memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount); break; @@ -2395,22 +3037,45 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName } n = 0; - ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES); + ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues, + LDAP_MOD_REPLACE | LDAP_MOD_BVALUES); + + if (Exchange) + { + if(HiddenGroup) + { + hide_address_lists_v[0] = "TRUE"; + ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v, + LDAP_MOD_REPLACE); + ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE); + } else { + hide_address_lists_v[0] = NULL; + ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v, + LDAP_MOD_REPLACE); + } + } + mods[n] = NULL; rc = ldap_modify_s(ldap_handle, TargetDn, mods); + for (i = 0; i < n; i++) free(mods[i]); + ldap_value_free_len(ppsValues); ldap_msgfree(psMsg); + if (rc != LDAP_SUCCESS) { com_err(whoami, 0, "Unable to set security settings for group %s : %s", TargetGroupName, ldap_err2string(rc)); + if (AceSidCount != 0) { - com_err(whoami, 0, "Trying to set security for group %s without admin.", + com_err(whoami, 0, + "Trying to set security for group %s without admin.", TargetGroupName); + if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName, HiddenGroup, "", "")) { @@ -2421,6 +3086,7 @@ int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path, char *TargetGroupName } return(rc); } + return(rc); } @@ -2435,7 +3101,8 @@ int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name, if (!check_string(group_name)) { - com_err(whoami, 0, "Unable to process invalid LDAP list name %s", group_name); + com_err(whoami, 0, + "Unable to process invalid LDAP list name %s", group_name); return(AD_INVALID_NAME); } @@ -2443,6 +3110,7 @@ int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name, group_count = 0; group_base = NULL; sprintf(temp, "%s,%s", group_ou_root, dn_path); + if (rc = ad_get_group(ldap_handle, temp, group_name, group_membership, MoiraId, "distinguishedName", &group_base, @@ -2466,7 +3134,7 @@ int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name, com_err(whoami, 0, "Unable to find list %s in AD.", group_name); return(AD_NO_GROUPS_FOUND); } - + return(0); } @@ -2504,12 +3172,14 @@ int member_list_build(int ac, char **av, void *ptr) LK_ENTRY *linklist; char temp[1024]; char **call_args; - + char *s; call_args = ptr; - + strcpy(temp, av[ACE_NAME]); + if (!check_string(temp)) return(0); + if (!strcmp(av[ACE_TYPE], "USER")) { if (!((int)call_args[3] & MOIRA_USERS)) @@ -2517,10 +3187,27 @@ int member_list_build(int ac, char **av, void *ptr) } else if (!strcmp(av[ACE_TYPE], "STRING")) { + if (Exchange) + { + if((s = strchr(temp, '@')) == (char *) NULL) + { + strcat(temp, "@mit.edu"); + } + + if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6)) + { + s = strrchr(temp, '.'); + *s = '\0'; + strcat(s, ".mit.edu"); + } + } + if (!((int)call_args[3] & MOIRA_STRINGS)) return(0); + if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou)) return(0); + } else if (!strcmp(av[ACE_TYPE], "LIST")) { @@ -2531,19 +3218,25 @@ int member_list_build(int ac, char **av, void *ptr) { if (!((int)call_args[3] & MOIRA_KERBEROS)) return(0); - if (contact_create((LDAP *)call_args[0], call_args[1], temp, kerberos_ou)) + + if (contact_create((LDAP *)call_args[0], call_args[1], temp, + kerberos_ou)) return(0); + } else return(0); linklist = member_base; + while (linklist) { if (!strcasecmp(temp, linklist->member)) return(0); + linklist = linklist->next; } + linklist = calloc(1, sizeof(LK_ENTRY)); linklist->op = 1; linklist->dn = NULL; @@ -2555,6 +3248,7 @@ int member_list_build(int ac, char **av, void *ptr) strcpy(linklist->member, temp); linklist->next = member_base; member_base = linklist; + return(0); } @@ -2566,12 +3260,14 @@ int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, char *modvalues[2]; char temp[256]; char filter[128]; + char *attr_array[3]; int group_count; int i; int n; LDAPMod *mods[20]; LK_ENTRY *group_base; ULONG rc; + char *s; if (!check_string(group_name)) return(AD_INVALID_NAME); @@ -2579,6 +3275,7 @@ int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, memset(filter, '\0', sizeof(filter)); group_base = NULL; group_count = 0; + if (rc = ad_get_group(ldap_handle, dn_path, group_name, group_membership, MoiraId, "distinguishedName", &group_base, @@ -2594,12 +3291,14 @@ int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, group_count = 0; goto cleanup; } + strcpy(distinguished_name, group_base->value); linklist_free(group_base); group_base = NULL; group_count = 0; sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path); + modvalues[0] = temp; modvalues[1] = NULL; @@ -2607,10 +3306,13 @@ int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, ADD_ATTR("member", modvalues, LDAP_MOD_DELETE); mods[n] = NULL; rc = ldap_modify_s(ldap_handle, distinguished_name, mods); + for (i = 0; i < n; i++) free(mods[i]); + if (rc == LDAP_UNWILLING_TO_PERFORM) rc = LDAP_SUCCESS; + if (rc != LDAP_SUCCESS) { com_err(whoami, 0, "Unable to modify list %s members : %s", @@ -2618,7 +3320,54 @@ int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name, goto cleanup; } -cleanup: + if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou))) + { + if (Exchange) + { + if(!strcmp(UserOu, contact_ou) && + ((s = strstr(user_name, "@mit.edu")) != (char *) NULL)) + { + memset(temp, '\0', sizeof(temp)); + strcpy(temp, user_name); + s = strchr(temp, '@'); + *s = '\0'; + + sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp); + + if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE) != 0)) + return(rc); + + if(group_count) + goto cleanup; + + linklist_free(group_base); + group_base = NULL; + group_count = 0; + } + + sprintf(filter, "(distinguishedName=%s)", temp); + attr_array[0] = "memberOf"; + attr_array[1] = NULL; + + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE) != 0)) + return(rc); + + + if(!group_count) + { + com_err(whoami, 0, "Removing unreferenced object %s", temp); + + if ((rc = ldap_delete_s(ldap_handle, temp)) != 0) + return(rc); + } + } + } + + cleanup: return(rc); } @@ -2644,6 +3393,7 @@ int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, memset(filter, '\0', sizeof(filter)); group_base = NULL; group_count = 0; + if (rc = ad_get_group(ldap_handle, dn_path, group_name, group_membership, MoiraId, "distinguishedName", &group_base, @@ -2673,38 +3423,105 @@ int member_add(LDAP *ldap_handle, char *dn_path, char *group_name, ADD_ATTR("member", modvalues, LDAP_MOD_ADD); mods[n] = NULL; rc = ldap_modify_s(ldap_handle, distinguished_name, mods); + if (rc == LDAP_ALREADY_EXISTS) rc = LDAP_SUCCESS; + if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou))) { if (rc == LDAP_UNWILLING_TO_PERFORM) rc = LDAP_SUCCESS; } + for (i = 0; i < n; i++) free(mods[i]); + if (rc != LDAP_SUCCESS) { com_err(whoami, 0, "Unable to add %s to list %s as a member : %s", user_name, group_name, ldap_err2string(rc)); } - + return(rc); } -int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou) +int contact_remove_email(LDAP *ld, char *bind_path, + LK_ENTRY **linklist_base, int linklist_current) { - LDAPMod *mods[20]; - char new_dn[256]; - char cn_user_name[256]; - char contact_name[256]; + LK_ENTRY *gPtr; + int rc; + char *mail_v[] = {NULL, NULL}; + LDAPMod *mods[20]; + int n; + int i; + + mail_v[0] = NULL; + + n = 0; + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE); + ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE); + ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE); + mods[n] = NULL; + + gPtr = (*linklist_base); + + while(gPtr) { + rc = ldap_modify_s(ld, gPtr->dn, mods); + + if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) + { + com_err(whoami, 0, "Unable to modify contact %s in AD : %s", + gPtr->dn, ldap_err2string(rc)); + return(rc); + } + + gPtr = gPtr->next; + } + + for (i = 0; i < n; i++) + free(mods[i]); + + return(rc); +} + +int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou) +{ + LDAPMod *mods[20]; + LK_ENTRY *group_base; + int group_count; + char new_dn[256]; + char cn_user_name[256]; + char contact_name[256]; + char mail_nickname[256]; + char proxy_address_internal[256]; + char proxy_address_external[256]; + char target_address[256]; + char internal_contact_name[256]; + char filter[128]; + char mail[256]; + char mit_address_book[256]; + char default_address_book[256]; + char contact_address_book[256]; char *email_v[] = {NULL, NULL}; char *cn_v[] = {NULL, NULL}; char *contact_v[] = {NULL, NULL}; + char *mail_nickname_v[] = {NULL, NULL}; + char *proxy_address_internal_v[] = {NULL, NULL}; + char *proxy_address_external_v[] = {NULL, NULL}; + char *target_address_v[] = {NULL, NULL}; + char *mit_address_book_v[] = {NULL, NULL}; + char *default_address_book_v[] = {NULL, NULL}; + char *contact_address_book_v[] = {NULL, NULL}; + char *hide_address_lists_v[] = {NULL, NULL}; + char *attr_array[3]; + char *objectClass_v[] = {"top", "person", "organizationalPerson", "contact", NULL}; char *name_v[] = {NULL, NULL}; char *desc_v[] = {NULL, NULL}; + char *s; int n; int rc; int i; @@ -2714,30 +3531,191 @@ int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou) com_err(whoami, 0, "Unable to process invalid LDAP name %s", user); return(AD_INVALID_NAME); } - strcpy(contact_name, user); + + strcpy(mail, user); + strcpy(contact_name, mail); + strcpy(internal_contact_name, mail); + + if((s = strchr(internal_contact_name, '@')) != NULL) { + *s = '?'; + } + sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path); + sprintf(target_address, "SMTP:%s", contact_name); + sprintf(proxy_address_external, "SMTP:%s", contact_name); + sprintf(mail_nickname, "%s", internal_contact_name); + cn_v[0] = cn_user_name; contact_v[0] = contact_name; name_v[0] = user; desc_v[0] = "Auto account created by Moira"; - email_v[0] = user; - + email_v[0] = mail; + proxy_address_internal_v[0] = proxy_address_internal; + proxy_address_external_v[0] = proxy_address_external; + mail_nickname_v[0] = mail_nickname; + target_address_v[0] = target_address; + mit_address_book_v[0] = mit_address_book; + default_address_book_v[0] = default_address_book; + contact_address_book_v[0] = contact_address_book; strcpy(new_dn, cn_user_name); n = 0; + ADD_ATTR("cn", contact_v, LDAP_MOD_ADD); ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD); ADD_ATTR("name", name_v, LDAP_MOD_ADD); ADD_ATTR("displayName", name_v, LDAP_MOD_ADD); ADD_ATTR("description", desc_v, LDAP_MOD_ADD); - if (!strcmp(group_ou, contact_ou)) + + if (Exchange) { - ADD_ATTR("mail", email_v, LDAP_MOD_ADD); + if (!strcmp(group_ou, contact_ou) && email_isvalid(mail)) + { + group_count = 0; + group_base = NULL; + + sprintf(filter, "(&(objectClass=user)(cn=%s))", mail); + attr_array[0] = "cn"; + attr_array[1] = NULL; + + if ((rc = linklist_build(ld, bind_path, filter, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to process contact %s : %s", + user, ldap_err2string(rc)); + return(rc); + } + + if (group_count) + { + com_err(whoami, 0, "Object already exists with name %s", + user); + return(1); + } + + linklist_free(group_base); + group_base = NULL; + group_count = 0; + + sprintf(filter, "(&(objectClass=group)(cn=%s))", mail); + attr_array[0] = "cn"; + attr_array[1] = NULL; + + if ((rc = linklist_build(ld, bind_path, filter, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to process contact %s : %s", + user, ldap_err2string(rc)); + return(rc); + } + + if (group_count) + { + com_err(whoami, 0, "Object already exists with name %s", + user); + return(1); + } + + linklist_free(group_base); + group_count = 0; + group_base = NULL; + + sprintf(filter, "(&(objectClass=user)(mail=%s))", mail); + attr_array[0] = "cn"; + attr_array[1] = NULL; + + if ((rc = linklist_build(ld, bind_path, filter, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to process contact %s : %s", + user, ldap_err2string(rc)); + return(rc); + } + + if (group_count) + { + com_err(whoami, 0, "Object already exists with name %s", + user); + return(1); + } + + linklist_free(group_base); + group_base = NULL; + group_count = 0; + + sprintf(filter, "(&(objectClass=group)(mail=%s))", mail); + attr_array[0] = "cn"; + attr_array[1] = NULL; + + if ((rc = linklist_build(ld, bind_path, filter, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to process contact %s : %s", + user, ldap_err2string(rc)); + return(rc); + } + + if (group_count) + { + com_err(whoami, 0, "Object already exists with name %s", + user); + return(1); + } + + linklist_free(group_base); + group_base = NULL; + group_count = 0; + + ADD_ATTR("mail", email_v, LDAP_MOD_ADD); + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD); + ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD); + ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD); + + hide_address_lists_v[0] = "TRUE"; + ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v, + LDAP_MOD_ADD); + } } + mods[n] = NULL; rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL); + for (i = 0; i < n; i++) free(mods[i]); + + if (Exchange) + { + if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS)) + { + n = 0; + + ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE); + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE); + ADD_ATTR("proxyAddresses", proxy_address_external_v, + LDAP_MOD_REPLACE); + ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE); + + hide_address_lists_v[0] = "TRUE"; + ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v, + LDAP_MOD_REPLACE); + + mods[n] = NULL; + rc = ldap_modify_s(ld, new_dn, mods); + + if (rc) + { + com_err(whoami, 0, "Unable to update contact %s", mail); + } + + for (i = 0; i < n; i++) + free(mods[i]); + } + } + if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) { n = 0; @@ -2748,26 +3726,31 @@ int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou) ADD_ATTR("description", desc_v, LDAP_MOD_ADD); mods[n] = NULL; rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL); + for (i = 0; i < n; i++) free(mods[i]); } + if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) { com_err(whoami, 0, "Unable to create contact %s : %s", user, ldap_err2string(rc)); return(rc); } + return(0); } int user_update(LDAP *ldap_handle, char *dn_path, char *user_name, char *Uid, char *MitId, char *MoiraId, int State, - char *WinHomeDir, char *WinProfileDir) + char *WinHomeDir, char *WinProfileDir, char *first, + char *middle, char *last) { LDAPMod *mods[20]; LK_ENTRY *group_base; int group_count; char distinguished_name[512]; + char displayName[256]; char *mitMoiraId_v[] = {NULL, NULL}; char *uid_v[] = {NULL, NULL}; char *mitid_v[] = {NULL, NULL}; @@ -2775,38 +3758,88 @@ int user_update(LDAP *ldap_handle, char *dn_path, char *user_name, char *winProfile_v[] = {NULL, NULL}; char *drives_v[] = {NULL, NULL}; char *userAccountControl_v[] = {NULL, NULL}; + char *alt_recipient_v[] = {NULL, NULL}; + char *hide_address_lists_v[] = {NULL, NULL}; + char *mail_v[] = {NULL, NULL}; char userAccountControlStr[80]; int n; int rc; int i; int OldUseSFU30; - u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE; + u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | + UF_PASSWD_CANT_CHANGE; char filter[128]; char *attr_array[3]; char temp[256]; + char mail[256]; + char contact_mail[256]; + char filter_exp[1024]; + char search_path[512]; + char TemplateDn[512]; + char TemplateSamName[128]; + char alt_recipient[256]; + char acBERBuf[N_SD_BER_BYTES]; + LDAPControl sControl = {"1.2.840.113556.1.4.801", + { N_SD_BER_BYTES, acBERBuf }, + TRUE}; + LDAPControl *apsServerControls[] = {&sControl, NULL}; + LDAPMessage *psMsg; + LDAP_BERVAL **ppsValues; + ULONG dwInfo; + char *argv[3]; + char *homeMDB; + char *homeServerName; + char *save_argv[7]; + char search_string[256]; + + dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION; + BEREncodeSecurityBits(dwInfo, acBERBuf); if (!check_string(user_name)) { - com_err(whoami, 0, "Unable to process invalid LDAP user name %s", user_name); + com_err(whoami, 0, "Unable to process invalid LDAP user name %s", + user_name); return(AD_INVALID_NAME); } + + memset(contact_mail, '\0', sizeof(contact_mail)); + sprintf(contact_mail, "%s@mit.edu", user_name); + memset(mail, '\0', sizeof(mail)); + sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain)); + memset(alt_recipient, '\0', sizeof(alt_recipient)); + sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, + dn_path); + sprintf(search_string, "@%s", uppercase(ldap_domain)); + + if (Exchange) + { + if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou)) + { + com_err(whoami, 0, "Unable to create user contact %s", contact_mail); + } + } group_count = 0; group_base = NULL; + memset(displayName, '\0', sizeof(displayName)); + if (strlen(MoiraId) != 0) { sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId); attr_array[0] = "cn"; attr_array[1] = NULL; if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process user %s : %s", user_name, ldap_err2string(rc)); return(rc); } } + if (group_count != 1) { linklist_free(group_base); @@ -2817,7 +3850,8 @@ int user_update(LDAP *ldap_handle, char *dn_path, char *user_name, attr_array[1] = NULL; sprintf(temp, "%s,%s", user_ou, dn_path); if ((rc = linklist_build(ldap_handle, temp, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process user %s : %s", user_name, ldap_err2string(rc)); @@ -2832,20 +3866,73 @@ int user_update(LDAP *ldap_handle, char *dn_path, char *user_name, linklist_free(group_base); return(AD_NO_USER_FOUND); } + strcpy(distinguished_name, group_base->dn); linklist_free(group_base); group_count = 0; if ((strlen(MitId) != 0) && (MitId[0] == '9')) - rc = attribute_update(ldap_handle, distinguished_name, MitId, "employeeID", user_name); + rc = attribute_update(ldap_handle, distinguished_name, MitId, + "employeeID", user_name); + else + rc = attribute_update(ldap_handle, distinguished_name, "none", + "employeeID", user_name); + + if(strlen(first)) { + strcat(displayName, first); + } + + if(strlen(middle)) { + if(strlen(first)) + strcat(displayName, " "); + + strcat(displayName, middle); + } + + if(strlen(last)) { + if(strlen(middle) || strlen(first)) + strcat(displayName, " "); + + strcat(displayName, last); + } + + if(strlen(displayName)) + rc = attribute_update(ldap_handle, distinguished_name, displayName, + "displayName", user_name); + else + rc = attribute_update(ldap_handle, distinguished_name, user_name, + "displayName", user_name); + + if(strlen(first)) + rc = attribute_update(ldap_handle, distinguished_name, first, + "givenName", user_name); else - rc = attribute_update(ldap_handle, distinguished_name, "none", "employeeID", user_name); - rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid", user_name); - rc = attribute_update(ldap_handle, distinguished_name, MoiraId, "mitMoiraId", user_name); + rc = attribute_update(ldap_handle, distinguished_name, "", + "givenName", user_name); + + if(strlen(middle) == 1) + rc = attribute_update(ldap_handle, distinguished_name, middle, + "initials", user_name); + else + rc = attribute_update(ldap_handle, distinguished_name, "", + "initials", user_name); + + if(strlen(last)) + rc = attribute_update(ldap_handle, distinguished_name, last, + "sn", user_name); + else + rc = attribute_update(ldap_handle, distinguished_name, "", + "sn", user_name); + + rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid", + user_name); + rc = attribute_update(ldap_handle, distinguished_name, MoiraId, + "mitMoiraId", user_name); n = 0; uid_v[0] = Uid; + if (!UseSFU30) { ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE); @@ -2855,32 +3942,180 @@ int user_update(LDAP *ldap_handle, char *dn_path, char *user_name, ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE); } - if ((State != US_NO_PASSWD) && (State != US_REGISTERED)) - userAccountControl |= UF_ACCOUNTDISABLE; + { + userAccountControl |= UF_ACCOUNTDISABLE; + + if (Exchange) + { + hide_address_lists_v[0] = "TRUE"; + ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v, + LDAP_MOD_REPLACE); + } + } + else + { + if (Exchange) + { + hide_address_lists_v[0] = NULL; + ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v, + LDAP_MOD_REPLACE); + } + } + sprintf(userAccountControlStr, "%ld", userAccountControl); userAccountControl_v[0] = userAccountControlStr; ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE); + if (Exchange) + { + if (rc = moira_connect()) + { + critical_alert("AD incremental", + "Error contacting Moira server : %s", + error_message(rc)); + return; + } + + argv[0] = user_name; + + if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv))) + { + if(!strcmp(save_argv[1], "EXCHANGE") || + (strstr(save_argv[3], search_string) != NULL)) + { + alt_recipient_v[0] = NULL; + ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE); + + argv[0] = exchange_acl; + argv[1] = "USER"; + argv[2] = user_name; + + rc = mr_query("add_member_to_list", 3, argv, NULL, NULL); + + if ((rc) && (rc != MR_EXISTS)) + { + com_err(whoami, 0, "Unable to add user %s to %s: %s", + user_name, exchange_acl, error_message(rc)); + } + } + else + { + alt_recipient_v[0] = alt_recipient; + ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE); + + argv[0] = exchange_acl; + argv[1] = "USER"; + argv[2] = user_name; + + rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL); + + if ((rc) && (rc != MR_NO_MATCH)) + { + com_err(whoami, 0, + "Unable to remove user %s from %s: %s, %d", + user_name, exchange_acl, error_message(rc), rc); + } + } + } + else + { + alt_recipient_v[0] = alt_recipient; + ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE); + + argv[0] = exchange_acl; + argv[1] = "USER"; + argv[2] = user_name; + + rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL); + + if ((rc) && (rc != MR_NO_MATCH)) + { + com_err(whoami, 0, + "Unable to remove user %s from %s: %s, %d", + user_name, exchange_acl, error_message(rc), rc); + } + } + + moira_disconnect(); + } + else + { + mail_v[0] = contact_mail; + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + } + n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir, WinProfileDir, homedir_v, winProfile_v, drives_v, mods, LDAP_MOD_REPLACE, n); + sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u"); + sprintf(search_path, "%s,%s", security_template_ou, dn_path); + attr_array[0] = "sAMAccountName"; + attr_array[1] = NULL; + group_count = 0; + group_base = NULL; + + if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE) != 0)) + return(1); + + if (group_count != 1) + { + com_err(whoami, 0, "Unable to process user security template: %s - " + "security not set", "UserTemplate.u"); + return(1); + } + + strcpy(TemplateDn, group_base->dn); + strcpy(TemplateSamName, group_base->value); + linklist_free(group_base); + group_base = NULL; + group_count = 0; + + rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE, + filter_exp, NULL, 0, apsServerControls, NULL, + NULL, 0, &psMsg); + + if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL) + { + com_err(whoami, 0, "Unable to find user security template: %s - " + "security not set", "UserTemplate.u"); + return(1); + } + + ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor"); + + if (ppsValues == NULL) + { + com_err(whoami, 0, "Unable to find user security template: %s - " + "security not set", "UserTemplate.u"); + return(1); + } + + ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues, + LDAP_MOD_REPLACE | LDAP_MOD_BVALUES); + mods[n] = NULL; - if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) != LDAP_SUCCESS) + + if ((rc = ldap_modify_s(ldap_handle, distinguished_name, + mods)) != LDAP_SUCCESS) { - OldUseSFU30 = UseSFU30; - SwitchSFU(mods, &UseSFU30, n); - if (OldUseSFU30 != UseSFU30) - rc = ldap_modify_s(ldap_handle, distinguished_name, mods); - if (rc) + OldUseSFU30 = UseSFU30; + SwitchSFU(mods, &UseSFU30, n); + if (OldUseSFU30 != UseSFU30) + rc = ldap_modify_s(ldap_handle, distinguished_name, mods); + if (rc) { - com_err(whoami, 0, "Unable to modify user data for %s : %s", - user_name, ldap_err2string(rc)); + com_err(whoami, 0, "Unable to modify user data for %s : %s", + user_name, ldap_err2string(rc)); } } + for (i = 0; i < n; i++) free(mods[i]); + return(rc); } @@ -2891,29 +4126,44 @@ int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, char new_dn[256]; char old_dn[256]; char upn[256]; - char temp[128]; + char mail[256]; + char contact_mail[256]; + char proxy_address[256]; + char query_base_dn[256]; + char temp[256]; char *userPrincipalName_v[] = {NULL, NULL}; char *altSecurityIdentities_v[] = {NULL, NULL}; char *name_v[] = {NULL, NULL}; char *samAccountName_v[] = {NULL, NULL}; + char *mail_v[] = {NULL, NULL}; + char *mail_nickname_v[] = {NULL, NULL}; + char *proxy_address_v[] = {NULL, NULL}; + char *query_base_dn_v[] = {NULL, NULL}; int n; int rc; int i; if (!check_string(before_user_name)) { - com_err(whoami, 0, "Unable to process invalid LDAP user name %s", before_user_name); + com_err(whoami, 0, + "Unable to process invalid LDAP user name %s", before_user_name); return(AD_INVALID_NAME); } + if (!check_string(user_name)) { - com_err(whoami, 0, "Unable to process invalid LDAP user name %s", user_name); + com_err(whoami, 0, + "Unable to process invalid LDAP user name %s", user_name); return(AD_INVALID_NAME); } strcpy(user_name, user_name); sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path); sprintf(new_dn, "cn=%s", user_name); + sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain)); + sprintf(contact_mail, "%s@mit.edu", user_name); + sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain)); + if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE, NULL, NULL)) != LDAP_SUCCESS) { @@ -2922,31 +4172,71 @@ int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name, return(rc); } + if (Exchange) + { + sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou, + dn_path); + + if(rc = ldap_delete_s(ldap_handle, temp)) + { + com_err(whoami, 0, "Unable to delete user contact for %s", + user_name); + } + + if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou)) + { + com_err(whoami, 0, "Unable to create user contact %s", contact_mail); + } + } + name_v[0] = user_name; sprintf(upn, "%s@%s", user_name, ldap_domain); userPrincipalName_v[0] = upn; sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM); + sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path); altSecurityIdentities_v[0] = temp; samAccountName_v[0] = user_name; + mail_v[0] = mail; + mail_nickname_v[0] = user_name; + proxy_address_v[0] = proxy_address; + query_base_dn_v[0] = query_base_dn; n = 0; ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE); ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE); ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE); ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE); + + if (Exchange) + { + ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE); + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE); + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE); + } + else + { + mail_v[0] = contact_mail; + ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE); + } + mods[n] = NULL; + sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path); + if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS) { - com_err(whoami, 0, "Unable to modify user data for %s after renaming : %s", + com_err(whoami, 0, + "Unable to modify user data for %s after renaming : %s", user_name, ldap_err2string(rc)); } + for (i = 0; i < n; i++) free(mods[i]); + return(rc); } - int user_create(int ac, char **av, void *ptr) { LDAPMod *mods[20]; @@ -2954,6 +4244,14 @@ int user_create(int ac, char **av, void *ptr) char user_name[256]; char sam_name[256]; char upn[256]; + char mail[256]; + char contact_mail[256]; + char proxy_address[256]; + char mail_nickname[256]; + char query_base_dn[256]; + char displayName[256]; + char address_book[256]; + char alt_recipient[256]; char *cn_v[] = {NULL, NULL}; char *objectClass_v[] = {"top", "person", "organizationalPerson", @@ -2971,9 +4269,31 @@ int user_create(int ac, char **av, void *ptr) char *homedir_v[] = {NULL, NULL}; char *winProfile_v[] = {NULL, NULL}; char *drives_v[] = {NULL, NULL}; + char *mail_v[] = {NULL, NULL}; + char *givenName_v[] = {NULL, NULL}; + char *sn_v[] = {NULL, NULL}; + char *initials_v[] = {NULL, NULL}; + char *displayName_v[] = {NULL, NULL}; + char *proxy_address_v[] = {NULL, NULL}; + char *mail_nickname_v[] = {NULL, NULL}; + char *query_base_dn_v[] = {NULL, NULL}; + char *address_book_v[] = {NULL, NULL}; + char *homeMDB_v[] = {NULL, NULL}; + char *homeServerName_v[] = {NULL, NULL}; + char *mdbUseDefaults_v[] = {NULL, NULL}; + char *mailbox_guid_v[] = {NULL, NULL}; + char *user_culture_v[] = {NULL, NULL}; + char *user_account_control_v[] = {NULL, NULL}; + char *msexch_version_v[] = {NULL, NULL}; + char *alt_recipient_v[] = {NULL, NULL}; + char *hide_address_lists_v[] = {NULL, NULL}; char userAccountControlStr[80]; char temp[128]; - u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | UF_PASSWD_CANT_CHANGE; + char filter_exp[1024]; + char search_path[512]; + char *attr_array[3]; + u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD | + UF_PASSWD_CANT_CHANGE; int n; int rc; int i; @@ -2981,36 +4301,126 @@ int user_create(int ac, char **av, void *ptr) char **call_args; char WinHomeDir[1024]; char WinProfileDir[1024]; + char *homeMDB; + char *homeServerName; + ULONG dwInfo; + char acBERBuf[N_SD_BER_BYTES]; + LK_ENTRY *group_base; + int group_count; + char TemplateDn[512]; + char TemplateSamName[128]; + LDAP_BERVAL **ppsValues; + LDAPControl sControl = {"1.2.840.113556.1.4.801", + { N_SD_BER_BYTES, acBERBuf }, + TRUE}; + LDAPControl *apsServerControls[] = {&sControl, NULL}; + LDAPMessage *psMsg; + char *argv[3]; + char *save_argv[7]; + char search_string[256]; call_args = ptr; + dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION; + BEREncodeSecurityBits(dwInfo, acBERBuf); + if (!check_string(av[U_NAME])) { callback_rc = AD_INVALID_NAME; - com_err(whoami, 0, "Unable to process invalid LDAP user name %s", av[U_NAME]); + com_err(whoami, 0, "Unable to process invalid LDAP user name %s", + av[U_NAME]); return(AD_INVALID_NAME); } memset(WinHomeDir, '\0', sizeof(WinHomeDir)); memset(WinProfileDir, '\0', sizeof(WinProfileDir)); + memset(displayName, '\0', sizeof(displayName)); + memset(query_base_dn, '\0', sizeof(query_base_dn)); strcpy(WinHomeDir, av[U_WINHOMEDIR]); strcpy(WinProfileDir, av[U_WINPROFILEDIR]); strcpy(user_name, av[U_NAME]); sprintf(upn, "%s@%s", user_name, ldap_domain); sprintf(sam_name, "%s", av[U_NAME]); + + if(strlen(av[U_FIRST])) { + strcat(displayName, av[U_FIRST]); + } + + if(strlen(av[U_MIDDLE])) { + if(strlen(av[U_FIRST])) + strcat(displayName, " "); + + strcat(displayName, av[U_MIDDLE]); + } + + if(strlen(av[U_LAST])) { + if(strlen(av[U_FIRST]) || strlen(av[U_LAST])) + strcat(displayName, " "); + + strcat(displayName, av[U_LAST]); + } + samAccountName_v[0] = sam_name; - if ((atoi(av[U_STATE]) != US_NO_PASSWD) && (atoi(av[U_STATE]) != US_REGISTERED)) - userAccountControl |= UF_ACCOUNTDISABLE; + if ((atoi(av[U_STATE]) != US_NO_PASSWD) && + (atoi(av[U_STATE]) != US_REGISTERED)) + { + userAccountControl |= UF_ACCOUNTDISABLE; + + if (Exchange) + { + hide_address_lists_v[0] = "TRUE"; + ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v, + LDAP_MOD_ADD); + } + } + sprintf(userAccountControlStr, "%ld", userAccountControl); userAccountControl_v[0] = userAccountControlStr; userPrincipalName_v[0] = upn; - cn_v[0] = user_name; name_v[0] = user_name; desc_v[0] = "Auto account created by Moira"; + mail_v[0] = mail; + givenName_v[0] = av[U_FIRST]; + sn_v[0] = av[U_LAST]; + displayName_v[0] = displayName; + mail_nickname_v[0] = user_name; + sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM); altSecurityIdentities_v[0] = temp; sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]); + sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain)); + sprintf(contact_mail, "%s@mit.edu", user_name); + sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]); + query_base_dn_v[0] = query_base_dn; + sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, + call_args[1]); + sprintf(search_string, "@%s", uppercase(ldap_domain)); + + + if (Exchange) + { + if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail, + contact_ou)) + { + com_err(whoami, 0, "Unable to create user contact %s", + contact_mail); + } + + if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB, + &homeServerName)) + { + com_err(whoami, 0, "Unable to locate homeMB and homeServerName"); + return(1); + } + + com_err(whoami, 0, "homeMDB:%s", homeMDB); + com_err(whoami, 0, "homeServerName:%s", homeServerName); + + homeMDB_v[0] = homeMDB; + homeServerName_v[0] = homeServerName; + } n = 0; ADD_ATTR("cn", cn_v, LDAP_MOD_ADD); @@ -3019,18 +4429,88 @@ int user_create(int ac, char **av, void *ptr) ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD); ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD); ADD_ATTR("name", name_v, LDAP_MOD_ADD); - ADD_ATTR("displayName", name_v, LDAP_MOD_ADD); ADD_ATTR("description", desc_v, LDAP_MOD_ADD); - if (strlen(call_args[2]) != 0) + + if (Exchange) + { + ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD); + ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD); + ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD); + mdbUseDefaults_v[0] = "TRUE"; + ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD); + ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD); + + argv[0] = user_name; + + if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv))) + { + if(!strcmp(save_argv[1], "EXCHANGE") || + (strstr(save_argv[3], search_string) != NULL)) + { + argv[0] = exchange_acl; + argv[1] = "USER"; + argv[2] = user_name; + + rc = mr_query("add_member_to_list", 3, argv, NULL, NULL); + + if ((rc) && (rc != MR_EXISTS)) + { + com_err(whoami, 0, "Unable to add user %s to %s: %s", + user_name, exchange_acl, error_message(rc)); + } + } + else + { + alt_recipient_v[0] = alt_recipient; + ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD); + } + } + else + { + alt_recipient_v[0] = alt_recipient; + ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD); + + com_err(whoami, 0, "Unable to fetch pobox for %s", user_name); + } + } + else + { + mail_v[0] = contact_mail; + ADD_ATTR("mail", mail_v, LDAP_MOD_ADD); + } + + if(strlen(av[U_FIRST])) { + ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD); + } + + if(strlen(av[U_LAST])) { + ADD_ATTR("sn", sn_v, LDAP_MOD_ADD); + } + + if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) { + ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD); + } else { + ADD_ATTR("displayName", name_v, LDAP_MOD_ADD); + } + + if (strlen(av[U_MIDDLE]) == 1) { + initials_v[0] = av[U_MIDDLE]; + ADD_ATTR("initials", initials_v, LDAP_MOD_ADD); + } + + if (strlen(call_args[2]) != 0) { mitMoiraId_v[0] = call_args[2]; - ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD); + ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD); } - ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD); + + ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD); + if (strlen(av[U_UID]) != 0) { uid_v[0] = av[U_UID]; ADD_ATTR("uid", uid_v, LDAP_MOD_ADD); + if (!UseSFU30) { ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD); @@ -3040,29 +4520,81 @@ int user_create(int ac, char **av, void *ptr) ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD); } } + if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9')) mitid_v[0] = av[U_MITID]; else mitid_v[0] = "none"; + ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD); n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir, WinProfileDir, homedir_v, winProfile_v, drives_v, mods, LDAP_MOD_ADD, n); + sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u"); + sprintf(search_path, "%s,%s", security_template_ou, call_args[1]); + attr_array[0] = "sAMAccountName"; + attr_array[1] = NULL; + group_count = 0; + group_base = NULL; + + if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp, + attr_array, &group_base, &group_count, + LDAP_SCOPE_SUBTREE) != 0)) + return(1); + + if (group_count != 1) + { + com_err(whoami, 0, "Unable to process user security template: %s - " + "security not set", "UserTemplate.u"); + return(1); + } + + strcpy(TemplateDn, group_base->dn); + strcpy(TemplateSamName, group_base->value); + linklist_free(group_base); + group_base = NULL; + group_count = 0; + + rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE, + filter_exp, NULL, 0, apsServerControls, NULL, + NULL, 0, &psMsg); + + if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL) + { + com_err(whoami, 0, "Unable to find user security template: %s - " + "security not set", "UserTemplate.u"); + return(1); + } + + ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg, + "ntSecurityDescriptor"); + if (ppsValues == NULL) + { + com_err(whoami, 0, "Unable to find user security template: %s - " + "security not set", "UserTemplate.u"); + return(1); + } + + ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues, + LDAP_MOD_REPLACE | LDAP_MOD_BVALUES); + mods[n] = NULL; rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL); + if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) - { + { OldUseSFU30 = UseSFU30; SwitchSFU(mods, &UseSFU30, n); if (OldUseSFU30 != UseSFU30) - rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL); - } + rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL); + } for (i = 0; i < n; i++) free(mods[i]); + if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) { com_err(whoami, 0, "Unable to create user %s : %s", @@ -3070,27 +4602,29 @@ int user_create(int ac, char **av, void *ptr) callback_rc = rc; return(rc); } - if (rc == LDAP_SUCCESS) + + if ((rc == LDAP_SUCCESS) && (SetPassword)) { if ((rc = set_password(sam_name, "", ldap_domain)) != 0) { ad_kdc_disconnect(); - tickets_get_k5(); if (!ad_server_connect(default_server, ldap_domain)) { com_err(whoami, 0, "Unable to set password for user %s : %s", - user_name, "cannot get changepw ticket from windows domain"); + user_name, + "cannot get changepw ticket from windows domain"); } else { if ((rc = set_password(sam_name, "", ldap_domain)) != 0) { - com_err(whoami, 0, "Unable to set password for user %s : %ld", - user_name, rc); + com_err(whoami, 0, "Unable to set password for user %s " + ": %ld", user_name, rc); } } } } + return(0); } @@ -3114,7 +4648,8 @@ int user_change_status(LDAP *ldap_handle, char *dn_path, if (!check_string(user_name)) { - com_err(whoami, 0, "Unable to process invalid LDAP user name %s", user_name); + com_err(whoami, 0, "Unable to process invalid LDAP user name %s", + user_name); return(AD_INVALID_NAME); } @@ -3127,13 +4662,15 @@ int user_change_status(LDAP *ldap_handle, char *dn_path, attr_array[0] = "UserAccountControl"; attr_array[1] = NULL; if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process user %s : %s", user_name, ldap_err2string(rc)); return(rc); } } + if (group_count != 1) { linklist_free(group_base); @@ -3143,14 +4680,15 @@ int user_change_status(LDAP *ldap_handle, char *dn_path, attr_array[0] = "UserAccountControl"; attr_array[1] = NULL; if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process user %s : %s", user_name, ldap_err2string(rc)); return(rc); } } - + if (group_count != 1) { linklist_free(group_base); @@ -3161,35 +4699,45 @@ int user_change_status(LDAP *ldap_handle, char *dn_path, strcpy(distinguished_name, group_base->dn); ulongValue = atoi((*group_base).value); + if (operation == MEMBER_DEACTIVATE) ulongValue |= UF_ACCOUNTDISABLE; else ulongValue &= ~UF_ACCOUNTDISABLE; + sprintf(temp, "%ld", ulongValue); + if ((rc = construct_newvalues(group_base, group_count, (*group_base).value, temp, &modvalues, REPLACE)) == 1) goto cleanup; + linklist_free(group_base); group_base = NULL; group_count = 0; n = 0; ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE); + if (strlen(MoiraId) != 0) { mitMoiraId_v[0] = MoiraId; ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE); } + mods[n] = NULL; rc = ldap_modify_s(ldap_handle, distinguished_name, mods); + for (i = 0; i < n; i++) free(mods[i]); + free_values(modvalues); + if (rc != LDAP_SUCCESS) { com_err(whoami, 0, "Unable to change status of user %s : %s", user_name, ldap_err2string(rc)); } -cleanup: + + cleanup: return(rc); } @@ -3203,6 +4751,7 @@ int user_delete(LDAP *ldap_handle, char *dn_path, LK_ENTRY *group_base; int group_count; int rc; + char temp[256]; if (!check_string(u_name)) return(AD_INVALID_NAME); @@ -3217,13 +4766,15 @@ int user_delete(LDAP *ldap_handle, char *dn_path, attr_array[0] = "name"; attr_array[1] = NULL; if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process user %s : %s", user_name, ldap_err2string(rc)); goto cleanup; } } + if (group_count != 1) { linklist_free(group_base); @@ -3233,7 +4784,8 @@ int user_delete(LDAP *ldap_handle, char *dn_path, attr_array[0] = "name"; attr_array[1] = NULL; if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process user %s : %s", user_name, ldap_err2string(rc)); @@ -3247,16 +4799,31 @@ int user_delete(LDAP *ldap_handle, char *dn_path, user_name); goto cleanup; } - + strcpy(distinguished_name, group_base->dn); + if (rc = ldap_delete_s(ldap_handle, distinguished_name)) { com_err(whoami, 0, "Unable to process user %s : %s", user_name, ldap_err2string(rc)); } -cleanup: + /* Need to add code to delete mit.edu contact */ + + if (Exchange) + { + sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path); + + if(rc = ldap_delete_s(ldap_handle, temp)) + { + com_err(whoami, 0, "Unable to delete user contact for %s", + user_name); + } + } + + cleanup: linklist_free(group_base); + return(0); } @@ -3268,16 +4835,22 @@ void linklist_free(LK_ENTRY *linklist_base) { if (linklist_base->dn != NULL) free(linklist_base->dn); + if (linklist_base->attribute != NULL) free(linklist_base->attribute); + if (linklist_base->value != NULL) free(linklist_base->value); + if (linklist_base->member != NULL) free(linklist_base->member); + if (linklist_base->type != NULL) free(linklist_base->type); + if (linklist_base->list != NULL) free(linklist_base->list); + linklist_previous = linklist_base; linklist_base = linklist_previous->next; free(linklist_previous); @@ -3289,6 +4862,7 @@ void free_values(char **modvalues) int i; i = 0; + if (modvalues != NULL) { while (modvalues[i] != NULL) @@ -3327,12 +4901,15 @@ int check_string(char *s) for (; *s; s++) { character = *s; + if (isupper(character)) character = tolower(character); + if (illegalchars[(unsigned) character]) return 0; } - return 1; + + return(1); } int check_container_name(char *s) @@ -3342,15 +4919,18 @@ int check_container_name(char *s) for (; *s; s++) { character = *s; + if (isupper(character)) character = tolower(character); - if (character == ' ') - continue; + if (character == ' ') + continue; + if (illegalchars[(unsigned) character]) return 0; } - return 1; + + return(1); } int mr_connect_cl(char *server, char *client, int version, int auth) @@ -3360,6 +4940,7 @@ int mr_connect_cl(char *server, char *client, int version, int auth) char temp[128]; status = mr_connect(server); + if (status) { com_err(whoami, status, "while connecting to Moira"); @@ -3367,12 +4948,14 @@ int mr_connect_cl(char *server, char *client, int version, int auth) } status = mr_motd(&motd); + if (status) { mr_disconnect(); com_err(whoami, status, "while checking server status"); return status; } + if (motd) { sprintf(temp, "The Moira server is currently unavailable: %s", motd); @@ -3382,6 +4965,7 @@ int mr_connect_cl(char *server, char *client, int version, int auth) } status = mr_version(version); + if (status) { if (status == MR_UNKNOWN_PROC) @@ -3394,7 +4978,8 @@ int mr_connect_cl(char *server, char *client, int version, int auth) if (status == MR_VERSION_HIGH) { - com_err(whoami, 0, "Warning: This client is running newer code than the server."); + com_err(whoami, 0, "Warning: This client is running newer code " + "than the server."); com_err(whoami, 0, "Some operations may not work."); } else if (status && status != MR_VERSION_LOW) @@ -3415,27 +5000,27 @@ int mr_connect_cl(char *server, char *client, int version, int auth) return status; } } - + return MR_SUCCESS; } void AfsToWinAfs(char* path, char* winPath) { - char* pathPtr; - char* winPathPtr; - strcpy(winPath, WINAFS); - pathPtr = path + strlen(AFS); - winPathPtr = winPath + strlen(WINAFS); - - while (*pathPtr) + char* pathPtr; + char* winPathPtr; + strcpy(winPath, WINAFS); + pathPtr = path + strlen(AFS); + winPathPtr = winPath + strlen(WINAFS); + + while (*pathPtr) { - if (*pathPtr == '/') - *winPathPtr = '\\'; - else - *winPathPtr = *pathPtr; - - pathPtr++; - winPathPtr++; + if (*pathPtr == '/') + *winPathPtr = '\\'; + else + *winPathPtr = *pathPtr; + + pathPtr++; + winPathPtr++; } } @@ -3445,13 +5030,12 @@ int GetAceInfo(int ac, char **av, void *ptr) int security_flag; call_args = ptr; - + strcpy(call_args[0], av[L_ACE_TYPE]); strcpy(call_args[1], av[L_ACE_NAME]); security_flag = 0; get_group_membership(call_args[2], call_args[3], &security_flag, av); - return(LDAP_SUCCESS); - + return(LDAP_SUCCESS); } int checkADname(LDAP *ldap_handle, char *dn_path, char *Name) @@ -3461,15 +5045,17 @@ int checkADname(LDAP *ldap_handle, char *dn_path, char *Name) int group_count; int rc; LK_ENTRY *group_base; - + group_count = 0; group_base = NULL; - + sprintf(filter, "(sAMAccountName=%s)", Name); attr_array[0] = "sAMAccountName"; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process ACE name %s : %s", Name, ldap_err2string(rc)); @@ -3478,14 +5064,17 @@ int checkADname(LDAP *ldap_handle, char *dn_path, char *Name) linklist_free(group_base); group_base = NULL; + if (group_count == 0) return(0); + return(1); } #define MAX_ACE 7 -int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type, int UpdateGroup, int *ProcessGroup) +int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type, + int UpdateGroup, int *ProcessGroup, char *maillist) { char *av[2]; char GroupName[256]; @@ -3497,11 +5086,19 @@ int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type, int Upd char AceMembership[2]; char AceOu[256]; char temp[128]; + char *save_argv[U_END]; - strcpy(GroupName, Name); + if (!SetGroupAce) + { + com_err(whoami, 0, "ProcessAce disabled, skipping"); + return(0); + } + strcpy(GroupName, Name); + if (strcasecmp(Type, "LIST")) return(1); + while (1) { av[0] = GroupName; @@ -3514,30 +5111,39 @@ int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type, int Upd memset(AceMembership, '\0', sizeof(AceMembership)); memset(AceOu, '\0', sizeof(AceOu)); callback_rc = 0; + if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo)) - { - com_err(whoami, 0, "Unable to get ACE info for list %s : %s", GroupName, error_message(rc)); + { + com_err(whoami, 0, "Unable to get ACE info for list %s : %s", + GroupName, error_message(rc)); return(1); } + if (callback_rc) { com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName); return(1); } + if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST"))) return(0); + strcpy(temp, AceName); + if (!strcasecmp(AceType, "LIST")) - sprintf(temp, "%s_group", AceName); + sprintf(temp, "%s%s", AceName, group_suffix); + if (!UpdateGroup) { if (checkADname(ldap_handle, dn_path, temp)) return(0); (*ProcessGroup) = 1; } + if (!strcasecmp(AceInfo[0], "LIST")) { - if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu, AceMembership, 0, UpdateGroup)) + if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu, + AceMembership, 0, UpdateGroup, maillist)) return(1); } else if (!strcasecmp(AceInfo[0], "USER")) @@ -3548,37 +5154,57 @@ int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type, int Upd call_args[2] = ""; call_args[3] = NULL; callback_rc = 0; - if (rc = mr_query("get_user_account_by_login", 1, av, user_create, call_args)) + + if (rc = mr_query("get_user_account_by_login", 1, av, + save_query_info, save_argv)) { - com_err(whoami, 0, "Unable to process user ACE %s for group %s.", AceName, Name); + com_err(whoami, 0, "Unable to process user ACE %s for group %s.", + AceName, Name); return(1); } + + if (rc = user_create(U_END, save_argv, call_args)) + { + com_err(whoami, 0, "Unable to process user ACE %s for group %s.", + AceName, Name); + return(1); + } + if (callback_rc) { - com_err(whoami, 0, "Unable to process user Ace %s for group %s", AceName, Name); + com_err(whoami, 0, "Unable to process user Ace %s for group %s", + AceName, Name); return(1); } + return(0); } else return(1); + if (!strcasecmp(AceType, "LIST")) { if (!strcasecmp(GroupName, AceName)) return(0); } + strcpy(GroupName, AceName); } + return(1); } int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, char *group_name, char *group_ou, char *group_membership, - int group_security_flag, int updateGroup) + int group_security_flag, int updateGroup, char *maillist) { char *av[3]; - char *call_args[7]; + char *call_args[8]; int rc; + LK_ENTRY *group_base; + int group_count; + char filter[128]; + char *attr_array[3]; av[0] = group_name; call_args[0] = (char *)ldap_handle; @@ -3587,14 +5213,21 @@ int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS); call_args[4] = (char *)updateGroup; call_args[5] = MoiraId; - call_args[6] = NULL; + call_args[6] = "0"; + call_args[7] = NULL; callback_rc = 0; + + group_count = 0; + group_base = NULL; + if (rc = mr_query("get_list_info", 1, av, group_create, call_args)) { moira_disconnect(); - com_err(whoami, 0, "Unable to create list %s : %s", group_name, error_message(rc)); + com_err(whoami, 0, "Unable to create list %s : %s", group_name, + error_message(rc)); return(rc); } + if (callback_rc) { moira_disconnect(); @@ -3614,6 +5247,8 @@ int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name, char *pUserOu; LK_ENTRY *ptr; int rc; + char member[256]; + char *s; com_err(whoami, 0, "Populating group %s", group_name); av[0] = group_name; @@ -3623,6 +5258,7 @@ int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name, call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS); call_args[4] = NULL; member_base = NULL; + if (rc = mr_query("get_end_members_of_list", 1, av, member_list_build, call_args)) { @@ -3630,9 +5266,11 @@ int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name, group_name, error_message(rc)); return(3); } + if (member_base != NULL) { ptr = member_base; + while (ptr != NULL) { if (!strcasecmp(ptr->type, "LIST")) @@ -3640,33 +5278,42 @@ int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name, ptr = ptr->next; continue; } + pUserOu = user_ou; + if (!strcasecmp(ptr->type, "STRING")) { - if (contact_create(ldap_handle, dn_path, ptr->member, contact_ou)) + if (contact_create(ldap_handle, dn_path, ptr->member, + contact_ou)) return(3); + pUserOu = contact_ou; } else if (!strcasecmp(ptr->type, "KERBEROS")) { - if (contact_create(ldap_handle, dn_path, ptr->member, kerberos_ou)) + if (contact_create(ldap_handle, dn_path, ptr->member, + kerberos_ou)) return(3); + pUserOu = kerberos_ou; } + rc = member_add(ldap_handle, dn_path, group_name, group_ou, group_membership, ptr->member, pUserOu, MoiraId); ptr = ptr->next; } + linklist_free(member_base); member_base = NULL; } + return(0); } int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, char *group_name, char *group_ou, char *group_membership, - int group_security_flag, int type) + int group_security_flag, int type, char *maillist) { char before_desc[512]; char before_name[256]; @@ -3689,10 +5336,10 @@ int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName)); sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path); - memset(filter, '\0', sizeof(filter)); group_base = NULL; group_count = 0; + if (rc = ad_get_group(ldap_handle, dn_path, group_name, "*", MoiraId, "distinguishedName", &group_base, @@ -3709,60 +5356,79 @@ int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, return(0); } } + linklist_free(group_base); + if (group_count == 0) return(AD_NO_GROUPS_FOUND); + if (group_count == 1) return(AD_WRONG_GROUP_DN_FOUND); + return(AD_MULTIPLE_GROUPS_FOUND); } + if (group_count == 0) { return(AD_NO_GROUPS_FOUND); } + if (group_count > 1) { ptr = group_base; + while (ptr != NULL) { if (!strcasecmp(distinguishedName, ptr->value)) break; + ptr = ptr->next; } + if (ptr == NULL) { - com_err(whoami, 0, "%d groups with moira id = %s", group_count, MoiraId); + com_err(whoami, 0, "%d groups with moira id = %s", group_count, + MoiraId); ptr = group_base; + while (ptr != NULL) { com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId); ptr = ptr->next; } + linklist_free(group_base); return(AD_MULTIPLE_GROUPS_FOUND); } + ptr = group_base; + while (ptr != NULL) { if (strcasecmp(distinguishedName, ptr->value)) rc = ldap_delete_s(ldap_handle, ptr->value); + ptr = ptr->next; } + linklist_free(group_base); memset(filter, '\0', sizeof(filter)); group_base = NULL; group_count = 0; + if (rc = ad_get_group(ldap_handle, dn_path, group_name, "*", MoiraId, "distinguishedName", &group_base, &group_count, filter)) return(rc); + if (group_count == 0) return(AD_NO_GROUPS_FOUND); + if (group_count > 1) return(AD_MULTIPLE_GROUPS_FOUND); } - + strcpy(ad_distinguishedName, group_base->value); linklist_free(group_base); group_base = NULL; @@ -3770,15 +5436,18 @@ int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, attr_array[0] = "sAMAccountName"; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s", MoiraId, ldap_err2string(rc)); return(rc); } - sprintf(filter, "(sAMAccountName=%s)", group_base->value); + sprintf(filter, "(sAMAccountName=%s)", group_base->value); + if (!strcasecmp(ad_distinguishedName, distinguishedName)) { linklist_free(group_base); @@ -3786,6 +5455,7 @@ int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, group_count = 0; return(0); } + linklist_free(group_base); group_base = NULL; group_count = 0; @@ -3798,27 +5468,33 @@ int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, memset(before_group_membership, '\0', sizeof(before_group_membership)); attr_array[0] = "name"; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s", MoiraId, ldap_err2string(rc)); return(rc); } + strcpy(before_name, group_base->value); linklist_free(group_base); group_base = NULL; group_count = 0; attr_array[0] = "description"; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to get list description with MoiraId = %s: %s", MoiraId, ldap_err2string(rc)); return(rc); } + if (group_count != 0) { strcpy(before_desc, group_base->value); @@ -3826,6 +5502,7 @@ int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, group_base = NULL; group_count = 0; } + change_to_lower_case(ad_distinguishedName); strcpy(ou_both, group_ou_both); change_to_lower_case(ou_both); @@ -3835,6 +5512,7 @@ int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, change_to_lower_case(ou_distribution); strcpy(ou_neither, group_ou_neither); change_to_lower_case(ou_neither); + if (strstr(ad_distinguishedName, ou_both)) { strcpy(before_group_ou, group_ou_both); @@ -3861,10 +5539,14 @@ int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId, } else return(AD_NO_OU_FOUND); - rc = group_rename(ldap_handle, dn_path, before_name, before_group_membership, + + rc = group_rename(ldap_handle, dn_path, before_name, + before_group_membership, before_group_ou, before_security_flag, before_desc, - group_name, group_membership, group_ou, group_security_flag, - before_desc, MoiraId, filter); + group_name, group_membership, group_ou, + group_security_flag, + before_desc, MoiraId, filter, maillist); + return(rc); } @@ -3891,18 +5573,22 @@ int ad_get_group(LDAP *ldap_handle, char *dn_path, (*linklist_base) = NULL; (*linklist_count) = 0; + if (strlen(rFilter) != 0) { strcpy(filter, rFilter); attr_array[0] = attribute; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - linklist_base, linklist_count, LDAP_SCOPE_SUBTREE)) != 0) + linklist_base, linklist_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s", MoiraId, ldap_err2string(rc)); return(rc); } + if ((*linklist_count) == 1) { strcpy(rFilter, filter); @@ -3913,32 +5599,40 @@ int ad_get_group(LDAP *ldap_handle, char *dn_path, linklist_free((*linklist_base)); (*linklist_base) = NULL; (*linklist_count) = 0; + if (strlen(MoiraId) != 0) { sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId); attr_array[0] = attribute; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - linklist_base, linklist_count, LDAP_SCOPE_SUBTREE)) != 0) + linklist_base, linklist_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s", MoiraId, ldap_err2string(rc)); return(rc); } } + if ((*linklist_count) > 1) { com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId); pPtr = (*linklist_base); + while (pPtr) { - com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value, MoiraId); + com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value, + MoiraId); pPtr = pPtr->next; } + linklist_free((*linklist_base)); (*linklist_base) = NULL; (*linklist_count) = 0; } + if ((*linklist_count) == 1) { if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name))) @@ -3951,16 +5645,19 @@ int ad_get_group(LDAP *ldap_handle, char *dn_path, linklist_free((*linklist_base)); (*linklist_base) = NULL; (*linklist_count) = 0; - sprintf(filter, "(sAMAccountName=%s_group)", group_name); + sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix); attr_array[0] = attribute; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - linklist_base, linklist_count, LDAP_SCOPE_SUBTREE)) != 0) + linklist_base, linklist_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s", MoiraId, ldap_err2string(rc)); return(rc); } + if ((*linklist_count) == 1) { strcpy(rFilter, filter); @@ -3989,17 +5686,20 @@ int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId) attr_array[0] = "sAMAccountName"; attr_array[1] = NULL; if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process user %s : %s", UserName, ldap_err2string(rc)); return(rc); } + if (group_count > 1) { com_err(whoami, 0, "multiple users exist with MoiraId = %s", MoiraId); gPtr = group_base; + while (gPtr) { com_err(whoami, 0, "user %s exist with MoiraId = %s", @@ -4008,6 +5708,7 @@ int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId) } } } + if (group_count != 1) { linklist_free(group_base); @@ -4016,8 +5717,10 @@ int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId) sprintf(filter, "(sAMAccountName=%s)", UserName); attr_array[0] = "sAMAccountName"; attr_array[1] = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process user %s : %s", UserName, ldap_err2string(rc)); @@ -4030,15 +5733,18 @@ int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId) linklist_free(group_base); return(AD_NO_USER_FOUND); } + strcpy(SamAccountName, group_base->value); linklist_free(group_base); group_count = 0; rc = 0; + if (strcmp(SamAccountName, UserName)) { rc = user_rename(ldap_handle, dn_path, SamAccountName, UserName); } + return(0); } @@ -4053,11 +5759,13 @@ void container_get_dn(char *src, char *dest) if (strlen(src) == 0) return; + strcpy(name, src); sPtr = name; n = 0; array[n] = name; ++n; + while (*sPtr) { if ((*sPtr) == '/') @@ -4070,7 +5778,9 @@ void container_get_dn(char *src, char *dest) else ++sPtr; } + strcpy(dest, "OU="); + while (n != 0) { strcat(dest, array[n-1]); @@ -4080,6 +5790,7 @@ void container_get_dn(char *src, char *dest) strcat(dest, ",OU="); } } + return; } @@ -4090,8 +5801,10 @@ void container_get_name(char *src, char *dest) if (strlen(src) == 0) return; + sPtr = src; dPtr = src; + while (*sPtr) { if ((*sPtr) == '/') @@ -4101,6 +5814,7 @@ void container_get_name(char *src, char *dest) } ++sPtr; } + strcpy(dest, dPtr); return; } @@ -4113,6 +5827,7 @@ void container_check(LDAP *ldap_handle, char *dn_path, char *name) int rc; strcpy(cName, name); + for (i = 0; i < (int)strlen(cName); i++) { if (cName[i] == '/') @@ -4126,18 +5841,20 @@ void container_check(LDAP *ldap_handle, char *dn_path, char *name) av[CONTAINER_ID] = ""; av[CONTAINER_ROWID] = ""; rc = container_create(ldap_handle, dn_path, 7, av); + if (rc == LDAP_SUCCESS) { - com_err(whoami, 0, "container %s created without a mitMoiraId", cName); + com_err(whoami, 0, "container %s created without a mitMoiraId", + cName); } + cName[i] = '/'; } } - } -int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **before, - int afterc, char **after) +int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, + char **before, int afterc, char **after) { char dName[256]; char cName[256]; @@ -4151,15 +5868,20 @@ int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **befor memset(cName, '\0', sizeof(cName)); container_get_name(after[CONTAINER_NAME], cName); + if (!check_container_name(cName)) { - com_err(whoami, 0, "Unable to process invalid LDAP container name %s", cName); + com_err(whoami, 0, "Unable to process invalid LDAP container name %s", + cName); return(AD_INVALID_NAME); } memset(distinguishedName, '\0', sizeof(distinguishedName)); - if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, beforec, before)) + + if (rc = container_get_distinguishedName(ldap_handle, dn_path, + distinguishedName, beforec, before)) return(rc); + if (strlen(distinguishedName) == 0) { rc = container_create(ldap_handle, dn_path, afterc, after); @@ -4168,6 +5890,7 @@ int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **befor strcpy(temp, after[CONTAINER_NAME]); pPtr = temp; + for (i = 0; i < (int)strlen(temp); i++) { if (temp[i] == '/') @@ -4175,13 +5898,16 @@ int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **befor pPtr = &temp[i]; } } + (*pPtr) = '\0'; container_get_dn(temp, dName); + if (strlen(temp) != 0) sprintf(new_dn_path, "%s,%s", dName, dn_path); else sprintf(new_dn_path, "%s", dn_path); + sprintf(new_cn, "OU=%s", cName); container_check(ldap_handle, dn_path, after[CONTAINER_NAME]); @@ -4190,13 +5916,15 @@ int container_rename(LDAP *ldap_handle, char *dn_path, int beforec, char **befor TRUE, NULL, NULL)) != LDAP_SUCCESS) { com_err(whoami, 0, "Unable to rename container from %s to %s : %s", - before[CONTAINER_NAME], after[CONTAINER_NAME], ldap_err2string(rc)); + before[CONTAINER_NAME], after[CONTAINER_NAME], + ldap_err2string(rc)); return(rc); } memset(dName, '\0', sizeof(dName)); container_get_dn(after[CONTAINER_NAME], dName); rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after); + return(rc); } @@ -4206,10 +5934,14 @@ int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av) int rc; memset(distinguishedName, '\0', sizeof(distinguishedName)); - if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, count, av)) + + if (rc = container_get_distinguishedName(ldap_handle, dn_path, + distinguishedName, count, av)) return(rc); + if (strlen(distinguishedName) == 0) return(0); + if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS) { if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF) @@ -4218,6 +5950,7 @@ int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av) com_err(whoami, 0, "Unable to delete container %s from AD : %s", av[CONTAINER_NAME], ldap_err2string(rc)); } + return(rc); } @@ -4254,13 +5987,15 @@ int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av) if ((strlen(cName) == 0) || (strlen(dName) == 0)) { - com_err(whoami, 0, "Unable to process invalid LDAP container name %s", cName); + com_err(whoami, 0, "Unable to process invalid LDAP container name %s", + cName); return(AD_INVALID_NAME); } if (!check_container_name(cName)) { - com_err(whoami, 0, "Unable to process invalid LDAP container name %s", cName); + com_err(whoami, 0, "Unable to process invalid LDAP container name %s", + cName); return(AD_INVALID_NAME); } @@ -4270,101 +6005,123 @@ int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av) ADD_ATTR("name", name_v, LDAP_MOD_ADD); ou_v[0] = cName; ADD_ATTR("ou", ou_v, LDAP_MOD_ADD); + if (strlen(av[CONTAINER_ROWID]) != 0) { moiraId_v[0] = av[CONTAINER_ROWID]; ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD); } + if (strlen(av[CONTAINER_DESC]) != 0) { desc_v[0] = av[CONTAINER_DESC]; ADD_ATTR("description", desc_v, LDAP_MOD_ADD); } + if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0)) { - if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS")) - { - if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID], kerberos_ou)) - { - sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID], kerberos_ou,dn_path); - managedBy_v[0] = managedByDN; - ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD); - } - } - else - { - if (!strcasecmp(av[CONTAINER_TYPE], "USER")) - { - sprintf(filter, "(&(cn=%s)(&(objectCategory=person)(objectClass=user)))", av[CONTAINER_ID]); - } - if (!strcasecmp(av[CONTAINER_TYPE], "LIST")) - { - sprintf(filter, "(&(objectClass=group)(cn=%s))", av[CONTAINER_ID]); - } - if (strlen(filter) != 0) - { - attr_array[0] = "distinguishedName"; - attr_array[1] = NULL; - group_count = 0; - group_base = NULL; - if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS) - { - if (group_count == 1) - { - strcpy(managedByDN, group_base->value); - managedBy_v[0] = managedByDN; - ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD); - } - linklist_free(group_base); - group_base = NULL; - group_count = 0; - } - } + if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS")) + { + if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID], + kerberos_ou)) + { + sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID], + kerberos_ou, dn_path); + managedBy_v[0] = managedByDN; + ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD); + } + } + else + { + if (!strcasecmp(av[CONTAINER_TYPE], "USER")) + { + sprintf(filter, "(&(cn=%s)(&(objectCategory=person)" + "(objectClass=user)))", av[CONTAINER_ID]); + } + + if (!strcasecmp(av[CONTAINER_TYPE], "LIST")) + { + sprintf(filter, "(&(objectClass=group)(cn=%s))", + av[CONTAINER_ID]); + } + + if (strlen(filter) != 0) + { + attr_array[0] = "distinguishedName"; + attr_array[1] = NULL; + group_count = 0; + group_base = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, + attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS) + { + if (group_count == 1) + { + strcpy(managedByDN, group_base->value); + managedBy_v[0] = managedByDN; + ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD); + } + linklist_free(group_base); + group_base = NULL; + group_count = 0; + } + } + } } - } + mods[n] = NULL; sprintf(temp, "%s,%s", dName, dn_path); rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL); + for (i = 0; i < n; i++) free(mods[i]); + if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS)) { com_err(whoami, 0, "Unable to create container %s : %s", cName, ldap_err2string(rc)); return(rc); } + if (rc == LDAP_ALREADY_EXISTS) { if (strlen(av[CONTAINER_ROWID]) != 0) rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av); } + return(rc); } -int container_update(LDAP *ldap_handle, char *dn_path, int beforec, char **before, - int afterc, char **after) +int container_update(LDAP *ldap_handle, char *dn_path, int beforec, + char **before, int afterc, char **after) { char distinguishedName[256]; int rc; memset(distinguishedName, '\0', sizeof(distinguishedName)); - if (rc = container_get_distinguishedName(ldap_handle, dn_path, distinguishedName, afterc, after)) + + if (rc = container_get_distinguishedName(ldap_handle, dn_path, + distinguishedName, afterc, after)) return(rc); + if (strlen(distinguishedName) == 0) { rc = container_create(ldap_handle, dn_path, afterc, after); return(rc); } - + container_check(ldap_handle, dn_path, after[CONTAINER_NAME]); - rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc, after); + rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc, + after); return(rc); } -int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path, char *distinguishedName, int count, char **av) +int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path, + char *distinguishedName, int count, + char **av) { char *attr_array[3]; LK_ENTRY *group_base; @@ -4382,51 +6139,63 @@ int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path, char *dist if (strlen(dName) == 0) { - com_err(whoami, 0, "Unable to process invalid LDAP container name %s", av[CONTAINER_NAME]); + com_err(whoami, 0, "Unable to process invalid LDAP container name %s", + av[CONTAINER_NAME]); return(AD_INVALID_NAME); } if (!check_container_name(cName)) { - com_err(whoami, 0, "Unable to process invalid LDAP container name %s", cName); + com_err(whoami, 0, "Unable to process invalid LDAP container name %s", + cName); return(AD_INVALID_NAME); } - - sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))", av[CONTAINER_ROWID]); + + sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))", + av[CONTAINER_ROWID]); attr_array[0] = "distinguishedName"; attr_array[1] = NULL; group_count = 0; group_base = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS) { if (group_count == 1) { strcpy(distinguishedName, group_base->value); } + linklist_free(group_base); group_base = NULL; group_count = 0; } + if (strlen(distinguishedName) == 0) { - sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s,%s))", dName, dn_path); + sprintf(filter, "(&(objectClass=organizationalUnit)" + "(distinguishedName=%s,%s))", dName, dn_path); attr_array[0] = "distinguishedName"; attr_array[1] = NULL; group_count = 0; group_base = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS) { if (group_count == 1) { strcpy(distinguishedName, group_base->value); } + linklist_free(group_base); group_base = NULL; group_count = 0; } } + return(0); } @@ -4452,29 +6221,38 @@ int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName, strcpy(ad_path, distinguishedName); + if (strlen(dName) != 0) sprintf(ad_path, "%s,%s", dName, dn_path); - sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))", ad_path); + sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))", + ad_path); + if (strlen(av[CONTAINER_ID]) != 0) - sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))", av[CONTAINER_ROWID]); + sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))", + av[CONTAINER_ROWID]); + attr_array[0] = "mitMoiraId"; attr_array[1] = "description"; attr_array[2] = "managedBy"; attr_array[3] = NULL; group_count = 0; group_base = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS) { com_err(whoami, 0, "Unable to retreive container info for %s : %s", av[CONTAINER_NAME], ldap_err2string(rc)); return(rc); } + memset(managedByDN, '\0', sizeof(managedByDN)); memset(moiraId, '\0', sizeof(moiraId)); memset(desc, '\0', sizeof(desc)); pPtr = group_base; + while (pPtr) { if (!strcasecmp(pPtr->attribute, "description")) @@ -4485,6 +6263,7 @@ int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName, strcpy(moiraId, pPtr->value); pPtr = pPtr->next; } + linklist_free(group_base); group_base = NULL; group_count = 0; @@ -4495,9 +6274,11 @@ int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName, moiraId_v[0] = av[CONTAINER_ROWID]; ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE); } + if (strlen(av[CONTAINER_DESC]) != 0) { - attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description", dName); + attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description", + dName); } else { @@ -4506,84 +6287,102 @@ int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName, attribute_update(ldap_handle, ad_path, "", "description", dName); } } + if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0)) { - if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS")) - { - if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID], kerberos_ou)) - { - sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID], kerberos_ou, dn_path); - managedBy_v[0] = managedByDN; - ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE); - } + if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS")) + { + if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID], + kerberos_ou)) + { + sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID], + kerberos_ou, dn_path); + managedBy_v[0] = managedByDN; + ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE); + } + else + { + if (strlen(managedByDN) != 0) + { + attribute_update(ldap_handle, ad_path, "", "managedBy", + dName); + } + } + } + else + { + memset(filter, '\0', sizeof(filter)); + + if (!strcasecmp(av[CONTAINER_TYPE], "USER")) + { + sprintf(filter, "(&(cn=%s)(&(objectCategory=person)" + "(objectClass=user)))", av[CONTAINER_ID]); + } + + if (!strcasecmp(av[CONTAINER_TYPE], "LIST")) + { + sprintf(filter, "(&(objectClass=group)(cn=%s))", + av[CONTAINER_ID]); + } + + if (strlen(filter) != 0) + { + attr_array[0] = "distinguishedName"; + attr_array[1] = NULL; + group_count = 0; + group_base = NULL; + if ((rc = linklist_build(ldap_handle, dn_path, filter, + attr_array, &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS) + { + if (group_count == 1) + { + strcpy(managedByDN, group_base->value); + managedBy_v[0] = managedByDN; + ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE); + } else - { - if (strlen(managedByDN) != 0) + { + if (strlen(managedByDN) != 0) { - attribute_update(ldap_handle, ad_path, "", "managedBy", dName); + attribute_update(ldap_handle, ad_path, "", + "managedBy", dName); } - } - } + } + + linklist_free(group_base); + group_base = NULL; + group_count = 0; + } + } else - { - memset(filter, '\0', sizeof(filter)); - if (!strcasecmp(av[CONTAINER_TYPE], "USER")) - { - sprintf(filter, "(&(cn=%s)(&(objectCategory=person)(objectClass=user)))", av[CONTAINER_ID]); - } - if (!strcasecmp(av[CONTAINER_TYPE], "LIST")) - { - sprintf(filter, "(&(objectClass=group)(cn=%s))", av[CONTAINER_ID]); - } - if (strlen(filter) != 0) - { - attr_array[0] = "distinguishedName"; - attr_array[1] = NULL; - group_count = 0; - group_base = NULL; - if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS) - { - if (group_count == 1) - { - strcpy(managedByDN, group_base->value); - managedBy_v[0] = managedByDN; - ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE); - } - else - { - if (strlen(managedByDN) != 0) - { - attribute_update(ldap_handle, ad_path, "", "managedBy", dName); - } - } - linklist_free(group_base); - group_base = NULL; - group_count = 0; - } - } - else - { - if (strlen(managedByDN) != 0) - { - attribute_update(ldap_handle, ad_path, "", "managedBy", dName); - } - } - } + { + if (strlen(managedByDN) != 0) + { + attribute_update(ldap_handle, ad_path, "", "managedBy", + dName); + } + } + } } + mods[n] = NULL; + if (n == 0) return(LDAP_SUCCESS); rc = ldap_modify_s(ldap_handle, ad_path, mods); + for (i = 0; i < n; i++) free(mods[i]); + if (rc != LDAP_SUCCESS) { - com_err(whoami, 0, "Unable to modify container info for %s : %s", - av[CONTAINER_NAME], ldap_err2string(rc)); - return(rc); + com_err(whoami, 0, "Unable to modify container info for %s : %s", + av[CONTAINER_NAME], ldap_err2string(rc)); + return(rc); } + return(rc); } @@ -4606,9 +6405,11 @@ int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName) for (i = 0; i < 3; i++) { memset(filter, '\0', sizeof(filter)); + if (i == 0) { - strcpy(filter, "(!(|(objectClass=computer)(objectClass=organizationalUnit)))"); + strcpy(filter, "(!(|(objectClass=computer)" + "(objectClass=organizationalUnit)))"); attr_array[0] = "cn"; attr_array[1] = NULL; } @@ -4628,13 +6429,17 @@ int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName) while (1) { if ((rc = linklist_build(ldap_handle, dName, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS) { break; } + if (group_count == 0) break; + pPtr = group_base; + while(pPtr) { if (!strcasecmp(pPtr->attribute, "cn")) @@ -4645,6 +6450,7 @@ int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName) if (i == 1) sprintf(temp, "%s,%s", orphans_machines_ou, dn_path); count = 1; + while (1) { rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp, @@ -4662,17 +6468,21 @@ int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName) { rc = ldap_delete_s(ldap_handle, pPtr->dn); } + pPtr = pPtr->next; } + linklist_free(group_base); group_base = NULL; group_count = 0; } } + return(0); } -int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, char *machine_ou, char *NewMachineName) +int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, + char *machine_ou, char *NewMachineName) { LK_ENTRY *group_base; int group_count; @@ -4689,14 +6499,17 @@ int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, char *machine rc = moira_connect(); rc = GetMachineName(NewMachineName); moira_disconnect(); + if (strlen(NewMachineName) == 0) { - com_err(whoami, 0, "Unable to find alais for machine %s in Moira", member); + com_err(whoami, 0, "Unable to find alais for machine %s in Moira", + member); return(1); } pPtr = NULL; pPtr = strchr(NewMachineName, '.'); + if (pPtr != NULL) (*pPtr) = '\0'; @@ -4706,146 +6519,175 @@ int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member, char *machine attr_array[0] = "cn"; attr_array[1] = NULL; sprintf(temp, "%s", dn_path); + if ((rc = linklist_build(ldap_handle, temp, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { com_err(whoami, 0, "Unable to process machine %s : %s", member, ldap_err2string(rc)); return(1); } + if (group_count != 1) { - com_err(whoami, 0, "Unable to process machine %s : machine not found in AD", + com_err(whoami, 0, + "Unable to process machine %s : machine not found in AD", NewMachineName); return(1); } + strcpy(dn, group_base->dn); strcpy(cn, group_base->value); + for (i = 0; i < (int)strlen(dn); i++) dn[i] = tolower(dn[i]); + for (i = 0; i < (int)strlen(cn); i++) cn[i] = tolower(cn[i]); + linklist_free(group_base); pPtr = NULL; pPtr = strstr(dn, cn); + if (pPtr == NULL) { com_err(whoami, 0, "Unable to process machine %s", member); return(1); } + pPtr += strlen(cn) + 1; strcpy(machine_ou, pPtr); pPtr = NULL; pPtr = strstr(machine_ou, "dc="); + if (pPtr == NULL) { com_err(whoami, 0, "Unable to process machine %s", member); return(1); } + --pPtr; (*pPtr) = '\0'; + return(0); } -int machine_move_to_ou(LDAP *ldap_handle, char * dn_path, char *MoiraMachineName, char *DestinationOu) +int machine_move_to_ou(LDAP *ldap_handle, char * dn_path, + char *MoiraMachineName, char *DestinationOu) { + char NewCn[128]; + char OldDn[512]; + char MachineName[128]; + char filter[128]; + char *attr_array[3]; + char NewOu[256]; + char *cPtr = NULL; + int group_count; + long rc; + LK_ENTRY *group_base; - char NewCn[128]; - char OldDn[512]; - char MachineName[128]; - char filter[128]; - char *attr_array[3]; - char NewOu[256]; - char *cPtr = NULL; - int group_count; - long rc; - LK_ENTRY *group_base; - - group_count = 0; - group_base = NULL; - - strcpy(MachineName, MoiraMachineName); - rc = GetMachineName(MachineName); - if (strlen(MachineName) == 0) - { - com_err(whoami, 0, "Unable to find alais for machine %s in Moira", MoiraMachineName); - return(1); + group_count = 0; + group_base = NULL; + + strcpy(MachineName, MoiraMachineName); + rc = GetMachineName(MachineName); + + if (strlen(MachineName) == 0) + { + com_err(whoami, 0, "Unable to find alais for machine %s in Moira", + MoiraMachineName); + return(1); } + + cPtr = strchr(MachineName, '.'); + + if (cPtr != NULL) + (*cPtr) = '\0'; - cPtr = strchr(MachineName, '.'); - if (cPtr != NULL) - (*cPtr) = '\0'; - sprintf(filter, "(sAMAccountName=%s$)", MachineName); - attr_array[0] = "sAMAccountName"; - attr_array[1] = NULL; - if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, &group_base, - &group_count, LDAP_SCOPE_SUBTREE)) != 0) + sprintf(filter, "(sAMAccountName=%s$)", MachineName); + attr_array[0] = "sAMAccountName"; + attr_array[1] = NULL; + + if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array, + &group_base, + &group_count, LDAP_SCOPE_SUBTREE)) != 0) { - com_err(whoami, 0, "Unable to process machine %s : %s", - MoiraMachineName, ldap_err2string(rc)); - return(1); + com_err(whoami, 0, "Unable to process machine %s : %s", + MoiraMachineName, ldap_err2string(rc)); + return(1); } + + if (group_count == 1) + strcpy(OldDn, group_base->dn); + + linklist_free(group_base); + group_base = NULL; - if (group_count == 1) - strcpy(OldDn, group_base->dn); - linklist_free(group_base); - group_base = NULL; - if (group_count != 1) + if (group_count != 1) { - com_err(whoami, 0, "Unable to find machine %s in AD: %s", MoiraMachineName); - return(1); + com_err(whoami, 0, "Unable to find machine %s in AD: %s", + MoiraMachineName); + return(1); } - sprintf(NewOu, "%s,%s", DestinationOu, dn_path); - cPtr = strchr(OldDn, ','); - if (cPtr != NULL) + + sprintf(NewOu, "%s,%s", DestinationOu, dn_path); + cPtr = strchr(OldDn, ','); + + if (cPtr != NULL) { - ++cPtr; - if (!strcasecmp(cPtr, NewOu)) - return(0); + ++cPtr; + if (!strcasecmp(cPtr, NewOu)) + return(0); } - sprintf(NewCn, "CN=%s", MachineName); - rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL); - return(rc); + + sprintf(NewCn, "CN=%s", MachineName); + rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL); + + return(rc); } int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name) { - char Name[128]; - char *pPtr; - int rc; - - memset(Name, '\0', sizeof(Name)); - strcpy(Name, machine_name); - pPtr = NULL; - pPtr = strchr(Name, '.'); - if (pPtr != NULL) - (*pPtr) = '\0'; - strcat(Name, "$"); - return(!(rc = checkADname(ldap_handle, dn_path, Name))); + char Name[128]; + char *pPtr; + int rc; + + memset(Name, '\0', sizeof(Name)); + strcpy(Name, machine_name); + pPtr = NULL; + pPtr = strchr(Name, '.'); + + if (pPtr != NULL) + (*pPtr) = '\0'; + + strcat(Name, "$"); + return(!(rc = checkADname(ldap_handle, dn_path, Name))); } -int machine_get_moira_container(LDAP *ldap_handle, char *dn_path, char *machine_name, char *container_name) +int machine_get_moira_container(LDAP *ldap_handle, char *dn_path, + char *machine_name, char *container_name) { - int rc; - char *av[2]; - char *call_args[2]; - - av[0] = machine_name; - call_args[0] = (char *)container_name; - rc = mr_query("get_machine_to_container_map", 1, av, machine_GetMoiraContainer, - call_args); - return(rc); + int rc; + char *av[2]; + char *call_args[2]; + + av[0] = machine_name; + call_args[0] = (char *)container_name; + rc = mr_query("get_machine_to_container_map", 1, av, + machine_GetMoiraContainer, call_args); + return(rc); } int machine_GetMoiraContainer(int ac, char **av, void *ptr) { - char **call_args; - - call_args = ptr; - strcpy(call_args[0], av[1]); - return(0); + char **call_args; + + call_args = ptr; + strcpy(call_args[0], av[1]); + return(0); } int Moira_container_group_create(char **after) @@ -4878,7 +6720,8 @@ int Moira_container_group_create(char **after) if (rc = mr_query("add_list", 15, argv, NULL, NULL)) { - com_err(whoami, 0, "Unable to create container group %s for container %s: %s", + com_err(whoami, 0, + "Unable to create container group %s for container %s: %s", GroupName, after[CONTAINER_NAME], error_message(rc)); } @@ -4930,7 +6773,8 @@ int Moira_container_group_update(char **before, char **after) if (rc = mr_query("update_list", 16, argv, NULL, NULL)) { - com_err(whoami, 0, "Unable to rename container group from %s to %s: %s", + com_err(whoami, 0, + "Unable to rename container group from %s to %s: %s", BeforeGroupName, AfterGroupName, error_message(rc)); } } @@ -4949,6 +6793,7 @@ int Moira_container_group_delete(char **before) Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1); memset(GroupName, '\0', sizeof(GroupName)); + if (strcmp(before[CONTAINER_GROUP_NAME], "[none]")) strcpy(GroupName, before[CONTAINER_GROUP_NAME]); @@ -4957,9 +6802,11 @@ int Moira_container_group_delete(char **before) argv[0] = ParentGroupName; argv[1] = "LIST"; argv[2] = GroupName; + if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL)) { - com_err(whoami, 0, "Unable to delete container group %s from list: %s", + com_err(whoami, 0, + "Unable to delete container group %s from list: %s", GroupName, ParentGroupName, error_message(rc)); } } @@ -4967,12 +6814,13 @@ int Moira_container_group_delete(char **before) if (strlen(GroupName) != 0) { argv[0] = GroupName; + if (rc = mr_query("delete_list", 1, argv, NULL, NULL)) { com_err(whoami, 0, "Unable to delete container group %s : %s", GroupName, error_message(rc)); } - } + } return(rc); } @@ -4993,11 +6841,13 @@ int Moira_groupname_create(char *GroupName, char *ContainerName, strcpy(temp, ContainerName); ptr1 = strrchr(temp, '/'); + if (ptr1 != NULL) { *ptr1 = '\0'; ptr = ++ptr1; ptr1 = strrchr(temp, '/'); + if (ptr1 != NULL) { sprintf(tempgname, "%s-%s", ++ptr1, ptr); @@ -5015,36 +6865,45 @@ int Moira_groupname_create(char *GroupName, char *ContainerName, /* change everything to lower case */ ptr = newGroupName; + while (*ptr) { if (isupper(*ptr)) *ptr = tolower(*ptr); + if (*ptr == ' ') *ptr = '-'; + ptr++; } strcpy(tempGroupName, newGroupName); i = (int)'0'; + /* append 0-9 then a-z if a duplicate is found */ while(1) { argv[0] = newGroupName; + if (rc = mr_query("get_list_info", 1, argv, NULL, NULL)) { if (rc == MR_NO_MATCH) break; - com_err(whoami, 0, "Moira error while creating group name for container %s : %s", - ContainerName, error_message(rc)); + com_err(whoami, 0, "Moira error while creating group name for " + "container %s : %s", ContainerName, error_message(rc)); return rc; } + sprintf(newGroupName, "%s-%c", tempGroupName, i); + if (i == (int)'z') { - com_err(whoami, 0, "Unable to find a unique group name for container %s: too many duplicate container names", + com_err(whoami, 0, "Unable to find a unique group name for " + "container %s: too many duplicate container names", ContainerName); return 1; } + if (i == '9') i = 'a'; else @@ -5062,17 +6921,18 @@ int Moira_setContainerGroup(char *origContainerName, char *GroupName) argv[0] = origContainerName; argv[1] = GroupName; - + if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL))) { - com_err(whoami, 0, "Unable to set container group %s in container %s: %s", - GroupName, origContainerName, error_message(rc)); + com_err(whoami, 0, + "Unable to set container group %s in container %s: %s", + GroupName, origContainerName, error_message(rc)); } - + return(0); } - int Moira_addGroupToParent(char *origContainerName, char *GroupName) +int Moira_addGroupToParent(char *origContainerName, char *GroupName) { char ContainerName[64]; char ParentGroupName[64]; @@ -5080,8 +6940,9 @@ int Moira_setContainerGroup(char *origContainerName, char *GroupName) long rc; strcpy(ContainerName, origContainerName); - + Moira_getGroupName(ContainerName, ParentGroupName, 1); + /* top-level container */ if (strlen(ParentGroupName) == 0) return(0); @@ -5089,11 +6950,14 @@ int Moira_setContainerGroup(char *origContainerName, char *GroupName) argv[0] = ParentGroupName; argv[1] = "LIST"; argv[2] = GroupName; + if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL))) { - com_err(whoami, 0, "Unable to add container group %s to parent group %s: %s", + com_err(whoami, 0, + "Unable to add container group %s to parent group %s: %s", GroupName, ParentGroupName, error_message(rc)); } + return(0); } @@ -5103,6 +6967,7 @@ int Moira_getContainerGroup(int ac, char **av, void *ptr) call_args = ptr; strcpy(call_args[0], av[1]); + return(0); } @@ -5120,6 +6985,7 @@ int Moira_getGroupName(char *origContainerName, char *GroupName, if (ParentFlag) { ptr = strrchr(ContainerName, '/'); + if (ptr != NULL) (*ptr) = '\0'; else @@ -5144,7 +7010,8 @@ int Moira_getGroupName(char *origContainerName, char *GroupName, else com_err(whoami, 0, "Unable to get container group from container %s", ContainerName); - return(0); + + return(0); } int Moira_process_machine_container_group(char *MachineName, char* GroupName, @@ -5152,459 +7019,325 @@ int Moira_process_machine_container_group(char *MachineName, char* GroupName, { char *argv[3]; long rc; - + if (strcmp(GroupName, "[none]") == 0) return 0; argv[0] = GroupName; argv[1] = "MACHINE"; argv[2] = MachineName; + if (!DeleteMachine) rc = mr_query("add_member_to_list", 3, argv, NULL, NULL); else rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL); + if (rc) { com_err(whoami, 0, "Unable to add machine %s to container group%s: %s", MachineName, GroupName, error_message(rc)); } + return(0); } int GetMachineName(char *MachineName) { - char *args[2]; - char NewMachineName[1024]; - char *szDot; - int rc = 0; - int i; - DWORD dwLen = 0; - char *call_args[2]; + char *args[2]; + char NewMachineName[1024]; + char *szDot; + int rc = 0; + int i; + DWORD dwLen = 0; + char *call_args[2]; + + // If the address happens to be in the top-level MIT domain, great! + strcpy(NewMachineName, MachineName); - // If the address happens to be in the top-level MIT domain, great! - strcpy(NewMachineName, MachineName); - for (i = 0; i < (int)strlen(NewMachineName); i++) - NewMachineName[i] = toupper(NewMachineName[i]); - szDot = strchr(NewMachineName,'.'); - if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX))) + for (i = 0; i < (int)strlen(NewMachineName); i++) + NewMachineName[i] = toupper(NewMachineName[i]); + + szDot = strchr(NewMachineName,'.'); + + if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX))) { - return(0); - } - - // If not, see if it has a Moira alias in the top-level MIT domain. - memset(NewMachineName, '\0', sizeof(NewMachineName)); - args[0] = "*"; - args[1] = MachineName; - call_args[0] = NewMachineName; - call_args[1] = NULL; - if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args)) - { - com_err(whoami, 0, "Unable to resolve machine name %s : %s", - MachineName, error_message(rc)); - strcpy(MachineName, ""); - return(0); + return(0); } + + // If not, see if it has a Moira alias in the top-level MIT domain. + memset(NewMachineName, '\0', sizeof(NewMachineName)); + args[0] = "*"; + args[1] = MachineName; + call_args[0] = NewMachineName; + call_args[1] = NULL; - if (strlen(NewMachineName) != 0) - strcpy(MachineName, NewMachineName); - else - strcpy(MachineName, ""); - return(0); + if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args)) + { + com_err(whoami, 0, "Unable to resolve machine name %s : %s", + MachineName, error_message(rc)); + strcpy(MachineName, ""); + return(0); + } + + if (strlen(NewMachineName) != 0) + strcpy(MachineName, NewMachineName); + else + strcpy(MachineName, ""); + return(0); } int ProcessMachineName(int ac, char **av, void *ptr) { - char **call_args; - char MachineName[1024]; - char *szDot; - int i; + char **call_args; + char MachineName[1024]; + char *szDot; + int i; + + call_args = ptr; - call_args = ptr; - if (strlen(call_args[0]) == 0) + if (strlen(call_args[0]) == 0) { - strcpy(MachineName, av[0]); - for (i = 0; i < (int)strlen(MachineName); i++) - MachineName[i] = toupper(MachineName[i]); - szDot = strchr(MachineName,'.'); + strcpy(MachineName, av[0]); + + for (i = 0; i < (int)strlen(MachineName); i++) + MachineName[i] = toupper(MachineName[i]); + + szDot = strchr(MachineName,'.'); + if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX))) - { + { strcpy(call_args[0], MachineName); - } + } } - return(0); + + return(0); } void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n) { - int i; - - if (*UseSFU30) + int i; + + if (*UseSFU30) { - for (i = 0; i < n; i++) + for (i = 0; i < n; i++) { - if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber")) - mods[i]->mod_type = "uidNumber"; + if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber")) + mods[i]->mod_type = "uidNumber"; } - (*UseSFU30) = 0; + + (*UseSFU30) = 0; } - else + else { - for (i = 0; i < n; i++) + for (i = 0; i < n; i++) { - if (!strcmp(mods[i]->mod_type, "uidNumber")) - mods[i]->mod_type = "msSFU30UidNumber"; + if (!strcmp(mods[i]->mod_type, "uidNumber")) + mods[i]->mod_type = "msSFU30UidNumber"; } - (*UseSFU30) = 1; + + (*UseSFU30) = 1; } } -int SetHomeDirectory(LDAP *ldap_handle, char *user_name, char *DistinguishedName, +int SetHomeDirectory(LDAP *ldap_handle, char *user_name, + char *DistinguishedName, char *WinHomeDir, char *WinProfileDir, char **homedir_v, char **winProfile_v, char **drives_v, LDAPMod **mods, int OpType, int n) { - char **hp; - char cWeight[3]; - char cPath[1024]; - char path[1024]; - char winPath[1024]; - char winProfile[1024]; - char homeDrive[8]; - int last_weight; - int i; - int rc; - LDAPMod *DelMods[20]; - - memset(homeDrive, '\0', sizeof(homeDrive)); - memset(path, '\0', sizeof(path)); - memset(winPath, '\0', sizeof(winPath)); - memset(winProfile, '\0', sizeof(winProfile)); - hp = NULL; - if ((!strcasecmp(WinHomeDir, "[afs]")) || (!strcasecmp(WinProfileDir, "[afs]"))) - { - if ((hp = hes_resolve(user_name, "filsys")) != NULL) + char **hp; + char cWeight[3]; + char cPath[1024]; + char path[1024]; + char winPath[1024]; + char winProfile[1024]; + char homeDrive[8]; + int last_weight; + int i; + int rc; + LDAPMod *DelMods[20]; + + memset(homeDrive, '\0', sizeof(homeDrive)); + memset(path, '\0', sizeof(path)); + memset(winPath, '\0', sizeof(winPath)); + memset(winProfile, '\0', sizeof(winProfile)); + hp = NULL; + + if ((!strcasecmp(WinHomeDir, "[afs]")) || + (!strcasecmp(WinProfileDir, "[afs]"))) + { + if ((hp = hes_resolve(user_name, "filsys")) != NULL) { - memset(cWeight, 0, sizeof(cWeight)); - memset(cPath, 0, sizeof(cPath)); - last_weight = 1000; - i = 0; - while (hp[i] != NULL) + memset(cWeight, 0, sizeof(cWeight)); + memset(cPath, 0, sizeof(cPath)); + last_weight = 1000; + i = 0; + + while (hp[i] != NULL) { - if (sscanf(hp[i], "%*s %s", cPath)) + if (sscanf(hp[i], "%*s %s", cPath)) { - if (strnicmp(cPath, AFS, strlen(AFS)) == 0) + if (strnicmp(cPath, AFS, strlen(AFS)) == 0) { - if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight)) + if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight)) { - if (atoi(cWeight) < last_weight) + if (atoi(cWeight) < last_weight) { - strcpy(path, cPath); - last_weight = (int)atoi(cWeight); + strcpy(path, cPath); + last_weight = (int)atoi(cWeight); } } - else - strcpy(path, cPath); + else + strcpy(path, cPath); } } ++i; } - if (strlen(path)) + + if (strlen(path)) { - if (!strnicmp(path, AFS, strlen(AFS))) + if (!strnicmp(path, AFS, strlen(AFS))) { - AfsToWinAfs(path, winPath); - strcpy(winProfile, winPath); - strcat(winProfile, "\\.winprofile"); + AfsToWinAfs(path, winPath); + strcpy(winProfile, winPath); + strcat(winProfile, "\\.winprofile"); } } } - else - return(n); + else + return(n); } - if ((!strcasecmp(WinHomeDir, "[dfs]")) || (!strcasecmp(WinProfileDir, "[dfs]"))) + if ((!strcasecmp(WinHomeDir, "[dfs]")) || + (!strcasecmp(WinProfileDir, "[dfs]"))) { - sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain, user_name[0], user_name); - if (!strcasecmp(WinProfileDir, "[dfs]")) - { - strcpy(winProfile, path); - strcat(winProfile, "\\.winprofile"); - } - if (!strcasecmp(WinHomeDir, "[dfs]")) - strcpy(winPath, path); - } + sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain, + user_name[0], user_name); + if (!strcasecmp(WinProfileDir, "[dfs]")) + { + strcpy(winProfile, path); + strcat(winProfile, "\\.winprofile"); + } + + if (!strcasecmp(WinHomeDir, "[dfs]")) + strcpy(winPath, path); + } + if (hp != NULL) - { + { i = 0; while (hp[i]) - { + { free(hp[i]); i++; - } - } - + } + } + if (!strcasecmp(WinHomeDir, "[local]")) - memset(winPath, '\0', sizeof(winPath)); - else if (!strcasecmp(WinHomeDir, "[afs]") || !strcasecmp(WinHomeDir, "[dfs]")) - { + memset(winPath, '\0', sizeof(winPath)); + else if (!strcasecmp(WinHomeDir, "[afs]") || + !strcasecmp(WinHomeDir, "[dfs]")) + { strcpy(homeDrive, "H:"); - } + } else - { + { strcpy(winPath, WinHomeDir); if (!strncmp(WinHomeDir, "\\\\", 2)) - { + { strcpy(homeDrive, "H:"); - } - } - + } + } + // nothing needs to be done if WinProfileDir is [afs]. if (!strcasecmp(WinProfileDir, "[local]")) - memset(winProfile, '\0', sizeof(winProfile)); - else if (strcasecmp(WinProfileDir, "[afs]") && strcasecmp(WinProfileDir, "[dfs]")) - { + memset(winProfile, '\0', sizeof(winProfile)); + else if (strcasecmp(WinProfileDir, "[afs]") && + strcasecmp(WinProfileDir, "[dfs]")) + { strcpy(winProfile, WinProfileDir); - } - + } + if (strlen(winProfile) != 0) - { + { if (winProfile[strlen(winProfile) - 1] == '\\') - winProfile[strlen(winProfile) - 1] = '\0'; - } + winProfile[strlen(winProfile) - 1] = '\0'; + } + if (strlen(winPath) != 0) - { + { if (winPath[strlen(winPath) - 1] == '\\') - winPath[strlen(winPath) - 1] = '\0'; - } - + winPath[strlen(winPath) - 1] = '\0'; + } + if ((winProfile[1] == ':') && (strlen(winProfile) == 2)) - strcat(winProfile, "\\"); - if ((winPath[1] == ':') && (strlen(winPath) == 2)) - strcat(winPath, "\\"); + strcat(winProfile, "\\"); + if ((winPath[1] == ':') && (strlen(winPath) == 2)) + strcat(winPath, "\\"); + if (strlen(winPath) == 0) - { + { if (OpType == LDAP_MOD_REPLACE) - { + { i = 0; DEL_ATTR("homeDirectory", LDAP_MOD_DELETE); DelMods[i] = NULL; //unset homeDirectory attribute for user. rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods); free(DelMods[0]); - } - } + } + } else - { + { homedir_v[0] = strdup(winPath); ADD_ATTR("homeDirectory", homedir_v, OpType); - } - + } + if (strlen(winProfile) == 0) - { + { if (OpType == LDAP_MOD_REPLACE) - { + { i = 0; DEL_ATTR("profilePath", LDAP_MOD_DELETE); DelMods[i] = NULL; //unset profilePate attribute for user. rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods); free(DelMods[0]); - } - } + } + } else - { + { winProfile_v[0] = strdup(winProfile); ADD_ATTR("profilePath", winProfile_v, OpType); - } - + } + if (strlen(homeDrive) == 0) - { + { if (OpType == LDAP_MOD_REPLACE) - { + { i = 0; DEL_ATTR("homeDrive", LDAP_MOD_DELETE); DelMods[i] = NULL; //unset homeDrive attribute for user rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods); free(DelMods[0]); - } - } + } + } else - { + { drives_v[0] = strdup(homeDrive); ADD_ATTR("homeDrive", drives_v, OpType); - } + } return(n); } -int GetServerList(char *ldap_domain, char **ServerList) -{ - unsigned long rc; - int group_count; - int UseSFU30; - int Count; - int i; - int k; - int ServerListFound; - char default_server[256]; - char dn_path[256]; - char *attr_array[3]; - char *sPtr; - char base[128]; - char filter[128]; - char temp[128]; - LK_ENTRY *group_base; - LK_ENTRY *gPtr; - LDAP *ldap_handle; - FILE *fptr; - - memset(default_server, '\0', sizeof(default_server)); - memset(dn_path, '\0', sizeof(dn_path)); - for (i = 0; i < MAX_SERVER_NAMES; i++) - { - if (ServerList[i] != NULL) - { - free(ServerList[i]); - ServerList[i] = NULL; - } - } - if (rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "", default_server, 0, - ServerList)) - return(1); - - for (i = 0; i < MAX_SERVER_NAMES; i++) - { - ServerList[i] = NULL; - } - - memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES); - group_count = 0; - group_base = NULL; - Count = 0; - ServerListFound = 0; - - strcpy(filter, "(&(objectClass=rIDManager)(fSMORoleOwner=*))"); - attr_array[0] = "fSMORoleOwner"; - attr_array[1] = NULL; - if (!(rc = linklist_build(ldap_handle, dn_path, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) - { - if (group_count != 0) - { - sPtr = strstr(group_base->value, ",CN="); - if (sPtr != NULL) - { - sPtr += strlen(",CN="); - if (ServerList[0] == NULL) - ServerList[0] = calloc(1, 256); - strcpy(ServerList[0], sPtr); - sPtr = strstr(ServerList[0], ","); - if (sPtr != NULL) - (*sPtr) = '\0'; - ++Count; - ServerListFound = 1; - } - } - } - linklist_free(group_base); - - group_count = 0; - group_base = NULL; - attr_array[0] = "cn"; - attr_array[1] = NULL; - strcpy(filter, "(cn=*)"); - sprintf(base, "cn=Servers,cn=Default-First-Site-Name,cn=Sites,cn=Configuration,%s", dn_path); - - if (!(rc = linklist_build(ldap_handle, base, filter, attr_array, - &group_base, &group_count, LDAP_SCOPE_ONELEVEL)) != 0) - { - if (group_count != 0) - { - gPtr = group_base; - while (gPtr != NULL) - { - if (ServerListFound != 0) - { - if (!strcasecmp(ServerList[0], gPtr->value)) - { - gPtr = gPtr->next; - continue; - } - } - if (Count < MAX_SERVER_NAMES) - { - if (ServerList[Count] == NULL) - ServerList[Count] = calloc(1, 256); - strcpy(ServerList[Count], gPtr->value); - gPtr = gPtr->next; - ++Count; - } - } - } - } - linklist_free(group_base); - - UseSFU30 = 0; - group_count = 0; - group_base = NULL; - - strcpy(filter, "(cn=msSFU-30-Uid-Number)"); - sprintf(base, "cn=schema,cn=configuration,%s", dn_path); - - if (!(rc = linklist_build(ldap_handle, base, filter, NULL, - &group_base, &group_count, LDAP_SCOPE_SUBTREE)) != 0) - { - if (group_count != 0) - { - UseSFU30 = 1; - } - } - linklist_free(group_base); - group_count = 0; - group_base = NULL; - - sprintf(temp, "%s%s.cfg", CFG_PATH, ldap_domain); - if ((fptr = fopen(temp, "w+")) != NULL) - { - fprintf(fptr, "%s %s\n", DOMAIN, ldap_domain); - if (strlen(PrincipalName) != 0) - fprintf(fptr, "%s %s\n", PRINCIPALNAME, PrincipalName); - if (UseSFU30) - fprintf(fptr, "%s %s\n", MSSFU, SFUTYPE); - for (i = 0; i < MAX_SERVER_NAMES; i++) - { - if (ServerList[i] != NULL) - { - fprintf(fptr, "%s %s\n", SERVER, ServerList[i]); - } - } - fclose(fptr); - } - ldap_unbind_s(ldap_handle); - - for (i = 0; i < MAX_SERVER_NAMES; i++) - { - if (ServerList[i] != NULL) - { - if (ServerList[i][strlen(ServerList[i]) - 1] == '\n') - ServerList[i][strlen(ServerList[i]) - 1] = '\0'; - strcat(ServerList[i], "."); - strcat(ServerList[i], ldap_domain); - for (k = 0; k < (int)strlen(ServerList[i]); k++) - ServerList[i][k] = toupper(ServerList[i][k]); - } - } - - return(0); -} - int attribute_update(LDAP *ldap_handle, char *distinguished_name, - char *attribute_value, char *attribute, char *user_name) + char *attribute_value, char *attribute, char *user_name) { char *mod_v[] = {NULL, NULL}; LDAPMod *DelMods[20]; @@ -5612,7 +7345,7 @@ int attribute_update(LDAP *ldap_handle, char *distinguished_name, int n; int i; int rc; - + if (strlen(attribute_value) == 0) { i = 0; @@ -5621,143 +7354,76 @@ int attribute_update(LDAP *ldap_handle, char *distinguished_name, rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods); free(DelMods[0]); } - else + else { n = 0; mod_v[0] = attribute_value; ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE); mods[n] = NULL; - if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) != LDAP_SUCCESS) + + if ((rc = ldap_modify_s(ldap_handle, distinguished_name, + mods)) != LDAP_SUCCESS) { free(mods[0]); n = 0; mod_v[0] = attribute_value; ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD); mods[n] = NULL; - if ((rc = ldap_modify_s(ldap_handle, distinguished_name, mods)) != LDAP_SUCCESS) + + if ((rc = ldap_modify_s(ldap_handle, distinguished_name, + mods)) != LDAP_SUCCESS) { - com_err(whoami, 0, "Unable to change the %s attribute for %s in the AD : %s", + com_err(whoami, 0, "Unable to change the %s attribute for %s " + "in the AD : %s", attribute, user_name, ldap_err2string(rc)); } } + free(mods[0]); } + return(rc); } -int tickets_get_k5() +void StringTrim(char *StringToTrim) { - char temp[128]; - char KinitPath[128]; - int retval; - int i; - static char EnvVar[128]; - static char EnvVar1[128]; - - strcpy(EnvVar, KRB5CCNAME); - retval = putenv(EnvVar); - strcpy(EnvVar1, KRBTKFILE); - retval = putenv(EnvVar1); - - for (i = 0; i < (int)strlen(PrincipalName); i++) - PrincipalName[i] = tolower(PrincipalName[i]); - if (strlen(PrincipalName) == 0) - { - strcpy(PrincipalName, PRODUCTION_PRINCIPAL); - if (strcasecmp(ldap_domain, PRIMARY_DOMAIN)) - strcpy(PrincipalName, TEST_PRINCIPAL); - } - - memset(KinitPath, '\0',sizeof(KinitPath)); -#ifndef _WIN32 - strcpy(KinitPath, "/usr/athena/bin/"); -#endif - sprintf(temp, "%skinit -k -t %s %s", KinitPath, KEYTABFILE, PrincipalName); - retval = system(temp); - if (retval) - { - com_err(whoami, 0, "%s failed", temp); - sprintf(temp, "%skinit -5 -k -t %s %s", KinitPath, KEYTABFILE, PrincipalName); - retval = system(temp); - if (retval) - { - com_err(whoami, 0, "%s failed", temp); - return(-1); - } - } - return(0); -} + char *t, *s; + char *save; -int get_tickets() -{ + save = strdup(StringToTrim); - if (tickets_get_k5()) - { - sleep(1); - if (tickets_get_k5()) - { - com_err(whoami, 0, "%s", "Unable to get kerberos tickets"); - critical_alert("AD incremental", "%s", - "winad.incr incremental failed (unable to get kerberos tickets)"); - return(1); - } - } - return(0); -} + s = save; -int destroy_cache(void) -{ - krb5_context context; - krb5_ccache cache; - krb5_error_code rc; + while (isspace(*s)) + s++; - context = NULL; - cache = NULL; - if (!krb5_init_context(&context)) + /* skip to end of string */ + if (*s == '\0') { - if (!krb5_cc_default(context, &cache)) - rc = krb5_cc_destroy(context, cache); + if (*save) + *save = '\0'; + strcpy(StringToTrim, save); + return; } - if (context != NULL) - krb5_free_context(context); - dest_tkt(); - - return(rc); -} - - -void StringTrim(char *StringToTrim) -{ - char *cPtr; - char temp[256]; - int i; - - if (strlen(StringToTrim) == 0) - return; + + for (t = s; *t; t++) + continue; - cPtr = StringToTrim; - while (isspace(*cPtr)) - { - ++cPtr; - } - strcpy(temp, cPtr); - if (strlen(temp) == 0) - { - strcpy(StringToTrim, temp); - return; - } - while (1) + while (t > s) { - i = strlen(temp); - if (i == 0) - break; - if (!isspace(temp[i-1])) - break; - temp[i-1] = '\0'; + --t; + if (!isspace(*t)) + { + t++; + break; + } } - strcpy(StringToTrim, temp); - return; + if (*t) + *t = '\0'; + + strcpy(StringToTrim, s); + return; } int ReadConfigFile(char *DomainName) @@ -5772,87 +7438,156 @@ int ReadConfigFile(char *DomainName) Count = 0; sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName); + if ((fptr = fopen(temp, "r")) != NULL) - { + { while (fgets(temp, sizeof(temp), fptr) != 0) - { + { for (i = 0; i < (int)strlen(temp); i++) - temp[i] = toupper(temp[i]); + temp[i] = toupper(temp[i]); + if (temp[strlen(temp) - 1] == '\n') - temp[strlen(temp) - 1] = '\0'; + temp[strlen(temp) - 1] = '\0'; + StringTrim(temp); + if (strlen(temp) == 0) - continue; + continue; + if (!strncmp(temp, DOMAIN, strlen(DOMAIN))) - { + { if (strlen(temp) > (strlen(DOMAIN))) - { + { strcpy(ldap_domain, &temp[strlen(DOMAIN)]); StringTrim(ldap_domain); - } - } + } + } else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME))) - { + { if (strlen(temp) > (strlen(PRINCIPALNAME))) - { + { strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]); StringTrim(PrincipalName); - } - } + } + } else if (!strncmp(temp, SERVER, strlen(SERVER))) - { + { if (strlen(temp) > (strlen(SERVER))) - { + { ServerList[Count] = calloc(1, 256); strcpy(ServerList[Count], &temp[strlen(SERVER)]); StringTrim(ServerList[Count]); ++Count; - } - } + } + } else if (!strncmp(temp, MSSFU, strlen(MSSFU))) - { + { if (strlen(temp) > (strlen(MSSFU))) - { + { strcpy(temp1, &temp[strlen(MSSFU)]); StringTrim(temp1); if (!strcmp(temp1, SFUTYPE)) - UseSFU30 = 1; - } - } - else if (!strcasecmp(temp, "NOCHANGE")) - { - NoChangeConfigFile = 1; - } + UseSFU30 = 1; + } + } + else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX))) + { + if (strlen(temp) > (strlen(GROUP_SUFFIX))) + { + strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]); + StringTrim(temp1); + if (!strcasecmp(temp1, "NO")) + { + UseGroupSuffix = 0; + memset(group_suffix, '\0', sizeof(group_suffix)); + } + } + } + else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE))) + { + if (strlen(temp) > (strlen(GROUP_TYPE))) + { + strcpy(temp1, &temp[strlen(GROUP_TYPE)]); + StringTrim(temp1); + if (!strcasecmp(temp1, "UNIVERSAL")) + UseGroupUniversal = 1; + } + } + else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE))) + { + if (strlen(temp) > (strlen(SET_GROUP_ACE))) + { + strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]); + StringTrim(temp1); + if (!strcasecmp(temp1, "NO")) + SetGroupAce = 0; + } + } + else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD))) + { + if (strlen(temp) > (strlen(SET_PASSWORD))) + { + strcpy(temp1, &temp[strlen(SET_PASSWORD)]); + StringTrim(temp1); + if (!strcasecmp(temp1, "NO")) + SetPassword = 0; + } + } + else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE))) + { + if (strlen(temp) > (strlen(EXCHANGE))) + { + strcpy(temp1, &temp[strlen(EXCHANGE)]); + StringTrim(temp1); + if (!strcasecmp(temp1, "YES")) + Exchange = 1; + } + } + else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER, + strlen(PROCESS_MACHINE_CONTAINER))) + { + if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER))) + { + strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]); + StringTrim(temp1); + if (!strcasecmp(temp1, "NO")) + ProcessMachineContainer = 0; + } + } else - { + { if (strlen(ldap_domain) != 0) - { + { memset(ldap_domain, '\0', sizeof(ldap_domain)); break; - } + } + if (strlen(temp) != 0) - strcpy(ldap_domain, temp); - } - } + strcpy(ldap_domain, temp); + } + } fclose(fptr); - } - + } + if (strlen(ldap_domain) == 0) - { + { strcpy(ldap_domain, DomainName); - } + } + if (Count == 0) return(0); + for (i = 0; i < Count; i++) - { + { if (ServerList[i] != 0) - { + { strcat(ServerList[i], "."); strcat(ServerList[i], ldap_domain); for (k = 0; k < (int)strlen(ServerList[i]); k++) - ServerList[i][k] = toupper(ServerList[i][k]); - } - } + ServerList[i][k] = toupper(ServerList[i][k]); + } + } + return(0); } @@ -5870,17 +7605,22 @@ int ReadDomainList() Count = 0; sprintf(temp, "%s%s", CFG_PATH, WINADCFG); + if ((fptr = fopen(temp, "r")) != NULL) { while (fgets(temp, sizeof(temp), fptr) != 0) { for (i = 0; i < (int)strlen(temp); i++) temp[i] = toupper(temp[i]); + if (temp[strlen(temp) - 1] == '\n') temp[strlen(temp) - 1] = '\0'; + StringTrim(temp); + if (strlen(temp) == 0) continue; + if (!strncmp(temp, DOMAIN, strlen(DOMAIN))) { if (strlen(temp) > (strlen(DOMAIN))) @@ -5890,61 +7630,279 @@ int ReadDomainList() strcpy(temp, temp1); } } - ok = 1; - rc = sscanf(temp, "%c%c%c%c%c.%c%c%c.%c%c%c%s", &c[0], - &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], - &c[7], &c[8], &c[9], &c[10], stuff); - if (rc != 11) - { - rc = sscanf(temp, "%c%c%c%c.%c%c%c.%c%c%c%s", &c[0], - &c[1], &c[2], &c[3], &c[4], &c[5], &c[6], - &c[7], &c[8], &c[9], stuff); - if (rc != 10) - { - rc = sscanf(temp, "%c%c%%c.%c%c%c.%c%c%c%s", &c[0], - &c[1], &c[2], &c[3], &c[4], &c[5], - &c[6], &c[7], &c[8], stuff); - if (rc != 9) - { - UpdateDomainList = 1; - ok = 0; - } - } - } - if (ok) - { - strcpy(DomainNames[Count], temp); - StringTrim(DomainNames[Count]); - ++Count; - } + + strcpy(DomainNames[Count], temp); + StringTrim(DomainNames[Count]); + ++Count; } + fclose(fptr); } + if (Count == 0) { - critical_alert("incremental", "%s", - "winad.incr cannot run due to a configuration error in winad.cfg"); + critical_alert("incremental", "%s", "winad.incr cannot run due to a " + "configuration error in winad.cfg"); return(1); } + return(0); } -void WriteDomainList() +int email_isvalid(const char *address) { + int count = 0; + const char *c, *domain; + static char *rfc822_specials = "()<>@,;:\\\"[]"; + + if(address[strlen(address) - 1] == '.') + return 0; + + /* first we validate the name portion (name@domain) */ + for (c = address; *c; c++) { + if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) == + '\"')) { + while (*++c) { + if (*c == '\"') + break; + if (*c == '\\' && (*++c == ' ')) + continue; + if (*c <= ' ' || *c >= 127) + return 0; + } + + if (!*c++) + return 0; + if (*c == '@') + break; + if (*c != '.') + return 0; + continue; + } + + if (*c == '@') + break; + if (*c <= ' ' || *c >= 127) + return 0; + if (strchr(rfc822_specials, *c)) + return 0; + } + + if (c == address || *(c - 1) == '.') + return 0; + + /* next we validate the domain portion (name@domain) */ + if (!*(domain = ++c)) return 0; + do { + if (*c == '.') { + if (c == domain || *(c - 1) == '.') + return 0; + count++; + } + if (*c <= ' ' || *c >= 127) + return 0; + if (strchr(rfc822_specials, *c)) + return 0; + } while (*++c); + + return (count >= 1); +} + +int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB, + char **homeServerName) { - char temp[128]; - int i; - FILE *fptr; + LK_ENTRY *group_base; + LK_ENTRY *sub_group_base; + LK_ENTRY *gPtr; + LK_ENTRY *sub_gPtr; + int group_count; + int sub_group_count; + char filter[1024]; + char sub_filter[1024]; + char search_path[1024]; + char range[1024]; + char *attr_array[3]; + char *s; + int homeMDB_count = -1; + int rc; + int i; + int mdbbl_count; + int rangeStep = 1500; + int rangeLow = 0; + int rangeHigh = rangeLow + (rangeStep - 1); + int isLast = 0; + + /* Grumble..... microsoft not making it searchable from the root *grr* */ + + memset(filter, '\0', sizeof(filter)); + memset(search_path, '\0', sizeof(search_path)); - sprintf(temp, "%s%s", CFG_PATH, WINADCFG); - if ((fptr = fopen(temp, "w+")) != NULL) + sprintf(filter, "(objectClass=msExchMDB)"); + sprintf(search_path, "CN=Configuration,%s", dn_path); + attr_array[0] = "distinguishedName"; + attr_array[1] = NULL; + + group_base = NULL; + group_count = 0; + + if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array, + &group_base, &group_count, + LDAP_SCOPE_SUBTREE)) != 0) { - for (i = 0; i < MAX_DOMAINS; i++) + com_err(whoami, 0, "Unable to find msExchMDB %s", + ldap_err2string(rc)); + return(rc); + } + + if (group_count) + { + gPtr = group_base; + + while(gPtr) { + if ((s = strstr(gPtr->dn, "Public")) != (char *) NULL) + { + gPtr = gPtr->next; + continue; + } + + /* + * Due to limits in active directory we need to use the LDAP + * range semantics to query and return all the values in + * large lists, we will stop increasing the range when + * the result count is 0. + */ + + i = 0; + mdbbl_count = 0; + + for(;;) + { + memset(sub_filter, '\0', sizeof(sub_filter)); + memset(range, '\0', sizeof(range)); + sprintf(sub_filter, "(objectClass=msExchMDB)"); + + if(isLast) + sprintf(range, "homeMDBBL;Range=%d-*", rangeLow); + else + sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh); + + attr_array[0] = range; + attr_array[1] = NULL; + + sub_group_base = NULL; + sub_group_count = 0; + + if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter, + attr_array, &sub_group_base, + &sub_group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to find homeMDBBL %s", + ldap_err2string(rc)); + return(rc); + } + + if(!sub_group_count) + { + if(isLast) + { + isLast = 0; + rangeLow = 0; + rangeHigh = rangeLow + (rangeStep - 1); + break; + } + else + isLast++; + } + + mdbbl_count += sub_group_count; + rangeLow = rangeHigh + 1; + rangeHigh = rangeLow + (rangeStep - 1); + } + + /* First time through, need to initialize or update the least used */ + + com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn, + mdbbl_count); + + if(mdbbl_count < homeMDB_count || homeMDB_count == -1) + { + homeMDB_count = mdbbl_count; + *homeMDB = strdup(gPtr->dn); + } + + gPtr = gPtr->next; + linklist_free(sub_group_base); + } + } + + linklist_free(group_base); + + /* + * Ok found the server least allocated need to now query to get its + * msExchHomeServerName so we can set it as a user attribute + */ + + attr_array[0] = "legacyExchangeDN"; + attr_array[1] = NULL; + + group_count = 0; + group_base = NULL; + + if ((rc = linklist_build(ldap_handle, *homeMDB, filter, + attr_array, &group_base, + &group_count, + LDAP_SCOPE_SUBTREE)) != 0) + { + com_err(whoami, 0, "Unable to find msExchHomeServerName %s", + ldap_err2string(rc)); + return(rc); + } + + if(group_count) + { + *homeServerName = strdup(group_base->value); + if((s = strrchr(*homeServerName, '/')) != (char *) NULL) { - if (strlen(DomainNames[i]) != 0) - { - fprintf(fptr, "%s\n", DomainNames[i]); - } + *s = '\0'; } - fclose(fptr); + } + + linklist_free(group_base); + + return(rc); +} + +char *lowercase(char *s) +{ + char *p; + + for (p = s; *p; p++) + { + if (isupper(*p)) + *p = tolower(*p); + } + return s; +} + +char *uppercase(char *s) +{ + char *p; + + for (p = s; *p; p++) + { + if (islower(*p)) + *p = toupper(*p); } + return s; +} + +int save_query_info(int argc, char **argv, void *hint) +{ + int i; + char **nargv = hint; + + for(i = 0; i < argc; i++) + nargv[i] = strdup(argv[i]); + + return MR_CONT; }