]> andersk Git - moira.git/blame - incremental/winad/winad.c
From mark: Exchange changes.
[moira.git] / incremental / winad / winad.c
CommitLineData
5d0a7127 1/* $Header$
df2a74ce 2/* winad.incr arguments example
cd9e6b16 3 *
df2a74ce 4 * arguments when moira creates the account - ignored by winad.incr since the
5 * account is unusable. users 0 11 #45198 45198 /bin/cmd cmd Last First Middle
6 * 0 950000001 2000 121049
7 *
8 * login, unix_uid, shell, winconsoleshell, last,
9 * first, middle, status, mitid, type, moiraid
cd9e6b16 10 *
89db421e 11 * arguments for creating or updating a user account
df2a74ce 12 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
13 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
14 * First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
15 * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF
16 * 121058 PathToHomeDir PathToProfileDir newuser 45206 /bin/cmd cmd Last
17 * First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
18 *
19 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
20 * mitid, type, moiraid
78af4e6e 21 *
89db421e 22 * arguments for deactivating/deleting a user account
df2a74ce 23 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
24 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
25 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
26 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
27 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
28 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
29 *
30 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
31 * mitid, type, moiraid
cd9e6b16 32 *
89db421e 33 * arguments for reactivating a user account
df2a74ce 34 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
35 * 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
36 * 121058
37 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
38 * 121058 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 12105
39 *
40 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
41 * mitid, type, moiraid
cd9e6b16 42 *
89db421e 43 * arguments for changing user name
df2a74ce 44 * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001
45 * STAFF 121058 PathToHomeDir PathToProfileDir newusername 45206 /bin/cmd cmd
46 * Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
47 *
48 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
49 * mitid, type, moiraid
cd9e6b16 50 *
89db421e 51 * arguments for expunging a user
df2a74ce 52 * users 11 0 username 45198 /bin/cmd cmd Last First Middle 0 950000001 2000
53 * 121049
54 *
55 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
56 * mitid, type, moiraid
89db421e 57 *
58 * arguments for creating a "special" group/list
59 * list 0 11 listname 1 1 0 0 0 -1 NONE 0 description 92616
df2a74ce 60 *
61 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
62 * acl_id, description, moiraid
9db0b148 63 *
89db421e 64 * arguments for creating a "mail" group/list
65 * list 0 11 listname 1 1 0 1 0 -1 NONE 0 description 92616
df2a74ce 66 *
67 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
68 * acl_id, description, moiraid
89db421e 69 *
70 * arguments for creating a "group" group/list
71 * list 0 11 listname 1 1 0 0 1 -1 NONE 0 description 92616
df2a74ce 72 *
73 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
74 * acl_id, description, moiraid
89db421e 75 *
76 * arguments for creating a "group/mail" group/list
77 * list 0 11 listname 1 1 0 1 1 -1 NONE 0 description 92616
df2a74ce 78 *
79 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
80 * acl_id, description, moiraid
89db421e 81 *
82 * arguments to add a USER member to group/list
83 * imembers 0 12 listname USER userName 1 1 0 0 0 -1 1 92616 121047
df2a74ce 84 *
85 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
86 * gid, userStatus, moiraListId, moiraUserId
89db421e 87 *
88 * arguments to add a STRING or KERBEROS member to group/list
89 * imembers 0 10 listname STRING stringName 1 1 0 0 0 -1 92616
90 * imembers 0 10 listlistnameName KERBEROS kerberosName 1 1 0 0 0 -1 92616
df2a74ce 91 *
92 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
93 * gid, moiraListId
89db421e 94 *
95 * NOTE: group members of type LIST are ignored.
96 *
97 * arguments to remove a USER member to group/list
98 * imembers 12 0 listname USER userName 1 1 0 0 0 -1 1 92616 121047
df2a74ce 99 *
100 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
101 * gid, userStatus, moiraListId, moiraUserId
89db421e 102 *
103 * arguments to remove a STRING or KERBEROS member to group/list
104 * imembers 10 0 listname STRING stringName 1 1 0 0 0 -1 92616
105 * imembers 10 0 listname KERBEROS kerberosName 1 1 0 0 0 -1 92616
df2a74ce 106 *
107 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
108 * gid, moiraListId
9db0b148 109 *
89db421e 110 * NOTE: group members of type LIST are ignored.
f75f605a 111 *
89db421e 112 * arguments for renaming a group/list
df2a74ce 113 * list 11 11 oldlistname 1 1 0 0 0 -1 NONE 0 description 92616 newlistname 1
114 * 1 0 0 0 -1 description 0 92616
115 *
116 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
117 * acl_id, description, moiraListId
f75f605a 118 *
89db421e 119 * arguments for deleting a group/list
120 * list 11 0 listname 1 1 0 0 0 -1 NONE 0 description 92616
df2a74ce 121 *
122 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
123 * acl_id, description, moiraListId
6c8f12af 124 *
89db421e 125 * arguments for adding a file system
df2a74ce 126 * filesys 0 12 username AFS ATHENA.MIT.EDU
127 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
128 * wheel 1 HOMEDIR 101727
89db421e 129 *
130 * arguments for deleting a file system
df2a74ce 131 * filesys 12 0 username AFS ATHENA.MIT.EDU
132 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
133 * wheel 1 HOMEDIR 101727
6c8f12af 134 *
135 * arguments when moira creates a container (OU).
df2a74ce 136 * containers 0 8 machines/test/bottom description location contact USER
137 * 105316 2222 [none]
6c8f12af 138 *
139 * arguments when moira deletes a container (OU).
df2a74ce 140 * containers 8 0 machines/test/bottom description location contact USER
141 * 105316 2222 groupname
9cfe334f 142 *
6c8f12af 143 * arguments when moira modifies a container information (OU).
df2a74ce 144 * containers 8 8 machines/test/bottom description location contact USER
145 * 105316 2222 groupname machines/test/bottom description1 location contact
146 * USER 105316 2222 groupname
bbef4f93 147 *
148 * arguments when moira adds a machine from an OU
149 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
209367bd 150 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
bbef4f93 151 *
152 * arguments when moira removes a machine from an OU
153 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
209367bd 154 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
bbef4f93 155 *
cd9e6b16 156*/
df2a74ce 157
5d0a7127 158#include <mit-copyright.h>
df2a74ce 159
5d0a7127 160#ifdef _WIN32
4a6e2ee4 161#include <winsock2.h>
5d0a7127 162#include <windows.h>
163#include <stdlib.h>
164#include <malloc.h>
165#include <lmaccess.h>
166#endif
df2a74ce 167
f78c7eaf 168#include <hesiod.h>
cd9e6b16 169#include <string.h>
5d0a7127 170#include <ldap.h>
171#include <stdio.h>
172#include <moira.h>
173#include <moira_site.h>
cd9e6b16 174#include <mrclient.h>
5d0a7127 175#include <krb5.h>
5d0a7127 176#include <gsssasl.h>
df2a74ce 177#include <gssldap.h>
cd9e6b16 178#include "kpasswd.h"
179
180#ifdef _WIN32
181#ifndef ECONNABORTED
182#define ECONNABORTED WSAECONNABORTED
183#endif
184#ifndef ECONNREFUSED
185#define ECONNREFUSED WSAECONNREFUSED
186#endif
187#ifndef EHOSTUNREACH
188#define EHOSTUNREACH WSAEHOSTUNREACH
189#endif
190#define krb5_xfree free
0d958b3c 191#define F_OK 0
192#define sleep(A) Sleep(A * 1000);
cd9e6b16 193#endif /* _WIN32 */
5d0a7127 194
195#ifndef _WIN32
f78c7eaf 196#include <sys/types.h>
197#include <netinet/in.h>
198#include <arpa/nameser.h>
199#include <resolv.h>
5d0a7127 200#include <sys/utsname.h>
0d958b3c 201#include <unistd.h>
5d0a7127 202
6a4366ac 203#define CFG_PATH "/moira/winad/"
204#define WINADCFG "winad.cfg"
f78c7eaf 205#define strnicmp(A,B,C) strncasecmp(A,B,C)
cd9e6b16 206#define UCHAR unsigned char
207
5d0a7127 208#define UF_SCRIPT 0x0001
209#define UF_ACCOUNTDISABLE 0x0002
210#define UF_HOMEDIR_REQUIRED 0x0008
211#define UF_LOCKOUT 0x0010
212#define UF_PASSWD_NOTREQD 0x0020
213#define UF_PASSWD_CANT_CHANGE 0x0040
cd9e6b16 214#define UF_DONT_EXPIRE_PASSWD 0x10000
5d0a7127 215
216#define UF_TEMP_DUPLICATE_ACCOUNT 0x0100
217#define UF_NORMAL_ACCOUNT 0x0200
218#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800
219#define UF_WORKSTATION_TRUST_ACCOUNT 0x1000
220#define UF_SERVER_TRUST_ACCOUNT 0x2000
221
909e0dc3 222#define OWNER_SECURITY_INFORMATION (0x00000001L)
223#define GROUP_SECURITY_INFORMATION (0x00000002L)
224#define DACL_SECURITY_INFORMATION (0x00000004L)
225#define SACL_SECURITY_INFORMATION (0x00000008L)
226
5d0a7127 227#ifndef BYTE
228#define BYTE unsigned char
229#endif
230typedef unsigned int DWORD;
231typedef unsigned long ULONG;
232
233typedef struct _GUID
234{
235 unsigned long Data1;
236 unsigned short Data2;
237 unsigned short Data3;
238 unsigned char Data4[8];
239} GUID;
240
241typedef struct _SID_IDENTIFIER_AUTHORITY {
242 BYTE Value[6];
243} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
244
245typedef struct _SID {
246 BYTE Revision;
247 BYTE SubAuthorityCount;
248 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
249 DWORD SubAuthority[512];
250} SID;
251#endif/*!WIN32*/
252
f75f605a 253#ifndef WINADCFG
254#define WINADCFG "winad.cfg"
255#endif
256
6a4366ac 257#ifndef CFG_PATH
258#define CFG_PATH ""
259#endif
260
f78c7eaf 261#define AFS "/afs/"
262#define WINAFS "\\\\afs\\all\\"
263
cd9e6b16 264#define ADS_GROUP_TYPE_GLOBAL_GROUP 0x00000002
f78c7eaf 265#define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP 0x00000004
266#define ADS_GROUP_TYPE_LOCAL_GROUP 0x00000004
267#define ADS_GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
268#define ADS_GROUP_TYPE_SECURITY_ENABLED 0x80000000
cd9e6b16 269
26503e15 270#define QUERY_VERSION -1
271#define PRIMARY_REALM "ATHENA.MIT.EDU"
272#define PRIMARY_DOMAIN "win.mit.edu"
273#define PRODUCTION_PRINCIPAL "sms"
274#define TEST_PRINCIPAL "smstest"
cd9e6b16 275
5d0a7127 276#define SUBSTITUTE 1
277#define REPLACE 2
278
cd9e6b16 279#define USERS 0
280#define GROUPS 1
281
5d0a7127 282#define MEMBER_ADD 1
283#define MEMBER_REMOVE 2
284#define MEMBER_CHANGE_NAME 3
285#define MEMBER_ACTIVATE 4
286#define MEMBER_DEACTIVATE 5
cd9e6b16 287#define MEMBER_CREATE 6
5d0a7127 288
f78c7eaf 289#define MOIRA_ALL 0x0
290#define MOIRA_USERS 0x1
291#define MOIRA_KERBEROS 0x2
292#define MOIRA_STRINGS 0x4
293#define MOIRA_LISTS 0x8
294
89db421e 295#define CHECK_GROUPS 1
296#define CLEANUP_GROUPS 2
297
298#define AD_NO_GROUPS_FOUND -1
299#define AD_WRONG_GROUP_DN_FOUND -2
300#define AD_MULTIPLE_GROUPS_FOUND -3
301#define AD_INVALID_NAME -4
302#define AD_LDAP_FAILURE -5
303#define AD_INVALID_FILESYS -6
304#define AD_NO_ATTRIBUTE_FOUND -7
305#define AD_NO_OU_FOUND -8
306#define AD_NO_USER_FOUND -9
307
6c8f12af 308/* container arguments */
209367bd 309#define CONTAINER_NAME 0
310#define CONTAINER_DESC 1
311#define CONTAINER_LOCATION 2
312#define CONTAINER_CONTACT 3
313#define CONTAINER_TYPE 4
314#define CONTAINER_ID 5
315#define CONTAINER_ROWID 6
316#define CONTAINER_GROUP_NAME 7
6c8f12af 317
bbef4f93 318/*mcntmap arguments*/
319#define OU_MACHINE_NAME 0
320#define OU_CONTAINER_NAME 1
321#define OU_MACHINE_ID 2
322#define OU_CONTAINER_ID 3
209367bd 323#define OU_CONTAINER_GROUP 4
bbef4f93 324
5d0a7127 325typedef struct lk_entry {
326 int op;
327 int length;
328 int ber_value;
329 char *dn;
330 char *attribute;
331 char *value;
332 char *member;
333 char *type;
334 char *list;
335 struct lk_entry *next;
336} LK_ENTRY;
337
0d958b3c 338#define STOP_FILE "/moira/winad/nowinad"
339#define file_exists(file) (access((file), F_OK) == 0)
340
909e0dc3 341#define N_SD_BER_BYTES 5
5d0a7127 342#define LDAP_BERVAL struct berval
cd9e6b16 343#define MAX_SERVER_NAMES 32
344
909e0dc3 345#define HIDDEN_GROUP "HiddenGroup.g"
346#define HIDDEN_GROUP_WITH_ADMIN "HiddenGroupWithAdmin.g"
347#define NOT_HIDDEN_GROUP "NotHiddenGroup.g"
348#define NOT_HIDDEN_GROUP_WITH_ADMIN "NotHiddenGroupWithAdmin.g"
349
df2a74ce 350#define ADDRESS_LIST_PREFIX "CN=MIT Directory,CN=All Address Lists,\
351CN=Address Lists Container,CN=Massachusetts Institute of Technology,\
352CN=Microsoft Exchange,CN=Services,CN=Configuration,"
353
cd9e6b16 354#define ADD_ATTR(t, v, o) \
355 mods[n] = malloc(sizeof(LDAPMod)); \
df2a74ce 356 mods[n]->mod_op = o; \
cd9e6b16 357 mods[n]->mod_type = t; \
358 mods[n++]->mod_values = v
5d0a7127 359
df2a74ce 360#define DEL_ATTR(t, o) \
3abb4456 361 DelMods[i] = malloc(sizeof(LDAPMod)); \
df2a74ce 362 DelMods[i]->mod_op = o; \
3abb4456 363 DelMods[i]->mod_type = t; \
364 DelMods[i++]->mod_values = NULL
365
366#define DOMAIN_SUFFIX "MIT.EDU"
26503e15 367#define DOMAIN "DOMAIN:"
368#define PRINCIPALNAME "PRINCIPAL:"
369#define SERVER "SERVER:"
370#define MSSFU "SFU:"
d7051053 371#define SFUTYPE "30"
df2a74ce 372#define GROUP_SUFFIX "GROUP_SUFFIX:"
373#define GROUP_TYPE "GROUP_TYPE:"
374#define SET_GROUP_ACE "SET_GROUP_ACE:"
375#define SET_PASSWORD "SET_PASSWORD:"
376#define EXCHANGE "EXCHANGE:"
377#define PROCESS_MACHINE_CONTAINER "PROCESS_MACHINE_CONTAINER:"
6a4366ac 378#define MAX_DOMAINS 10
379char DomainNames[MAX_DOMAINS][128];
3abb4456 380
5d0a7127 381LK_ENTRY *member_base = NULL;
df2a74ce 382
383char PrincipalName[128];
0d958b3c 384static char tbl_buf[1024];
89db421e 385char kerberos_ou[] = "OU=kerberos,OU=moira";
386char contact_ou[] = "OU=strings,OU=moira";
387char user_ou[] = "OU=users,OU=moira";
388char group_ou_distribution[] = "OU=mail,OU=lists,OU=moira";
389char group_ou_root[] = "OU=lists,OU=moira";
390char group_ou_security[] = "OU=group,OU=lists,OU=moira";
391char group_ou_neither[] = "OU=special,OU=lists,OU=moira";
392char group_ou_both[] = "OU=mail,OU=group,OU=lists,OU=moira";
6c8f12af 393char orphans_machines_ou[] = "OU=Machines,OU=Orphans";
394char orphans_other_ou[] = "OU=Other,OU=Orphans";
909e0dc3 395char security_template_ou[] = "OU=security_templates";
5d0a7127 396char *whoami;
cd9e6b16 397char ldap_domain[256];
d7051053 398char *ServerList[MAX_SERVER_NAMES];
f78c7eaf 399char default_server[256];
bfb6f0ad 400static char tbl_buf[1024];
df2a74ce 401char group_suffix[256];
402char exchange_acl[256];
403int mr_connections = 0;
404int callback_rc;
3abb4456 405int UseSFU30 = 0;
df2a74ce 406int UseGroupSuffix = 1;
407int UseGroupUniversal = 0;
408int SetGroupAce = 1;
409int SetPassword = 1;
410int Exchange = 0;
411int ProcessMachineContainer = 1;
6a4366ac 412int UpdateDomainList;
cd9e6b16 413
f78c7eaf 414extern int set_password(char *user, char *password, char *domain);
cd9e6b16 415
89db421e 416int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name,
df2a74ce 417 char *group_membership, char *MoiraId, char *attribute,
418 LK_ENTRY **linklist_base, int *linklist_count,
419 char *rFilter);
f78c7eaf 420void AfsToWinAfs(char* path, char* winPath);
421int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
422 char *Win2kPassword, char *Win2kUser, char *default_server,
26503e15 423 int connect_to_kdc, char **ServerList);
f78c7eaf 424void ad_kdc_disconnect();
26503e15 425int ad_server_connect(char *connectedServer, char *domain);
4a6e2ee4 426int attribute_update(LDAP *ldap_handle, char *distinguished_name,
df2a74ce 427 char *attribute_value, char *attribute, char *user_name);
909e0dc3 428int BEREncodeSecurityBits(ULONG uBits, char *pBuffer);
bbef4f93 429int checkADname(LDAP *ldap_handle, char *dn_path, char *Name);
6a4366ac 430int check_winad(void);
df2a74ce 431int check_user(LDAP *ldap_handle, char *dn_path, char *UserName,
432 char *MoiraId);
6c8f12af 433/* containers */
434int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
435 char *distinguishedName, int count, char **av);
436void container_check(LDAP *ldap_handle, char *dn_path, char *name);
437int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av);
438int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av);
439int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
df2a74ce 440 char *distinguishedName, int count,
441 char **av);
6c8f12af 442void container_get_dn(char *src, char *dest);
443void container_get_name(char *src, char *dest);
444int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName);
df2a74ce 445int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
446 char **before, int afterc, char **after);
447int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
448 char **before, int afterc, char **after);
6c8f12af 449
909e0dc3 450int GetAceInfo(int ac, char **av, void *ptr);
f75f605a 451int get_group_membership(char *group_membership, char *group_ou,
452 int *security_flag, char **av);
df2a74ce 453int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
454 char *machine_ou, char *pPtr);
209367bd 455int Moira_container_group_create(char **after);
456int Moira_container_group_delete(char **before);
457int Moira_groupname_create(char *GroupName, char *ContainerName,
458 char *ContainerRowID);
459int Moira_container_group_update(char **before, char **after);
460int Moira_process_machine_container_group(char *MachineName, char* groupName,
461 int DeleteMachine);
462int Moira_addGroupToParent(char *origContainerName, char *GroupName);
463int Moira_getContainerGroup(int ac, char **av, void *ptr);
464int Moira_getGroupName(char *origContainerName, char *GroupName,
465 int ParentFlag);
466int Moira_setContainerGroup(char *ContainerName, char *GroupName);
909e0dc3 467int ProcessAce(LDAP *ldap_handle, char *dn_path, char *group_name, char *Type,
df2a74ce 468 int UpdateGroup, int *ProcessGroup, char *maillist);
89db421e 469int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
470 char *group_name, char *group_ou, char *group_membership,
df2a74ce 471 int group_security_flag, int type, char *maillist);
f75f605a 472int process_lists(int ac, char **av, void *ptr);
df2a74ce 473int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
474 char *TargetGroupName, int HiddenGroup,
475 char *AceType, char *AceName);
3abb4456 476int ProcessMachineName(int ac, char **av, void *ptr);
6a4366ac 477int ReadConfigFile(char *DomainName);
478int ReadDomainList();
26503e15 479void StringTrim(char *StringToTrim);
df2a74ce 480int save_query_info(int argc, char **argv, void *hint);
cd9e6b16 481int user_create(int ac, char **av, void *ptr);
89db421e 482int user_change_status(LDAP *ldap_handle, char *dn_path,
483 char *user_name, char *MoiraId, int operation);
484int user_delete(LDAP *ldap_handle, char *dn_path,
485 char *u_name, char *MoiraId);
f75f605a 486int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
89db421e 487 char *user_name);
f75f605a 488int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3abb4456 489 char *uid, char *MitId, char *MoiraId, int State,
df2a74ce 490 char *WinHomeDir, char *WinProfileDir, char *first,
491 char *middle, char *last);
89db421e 492void change_to_lower_case(char *ptr);
cd9e6b16 493int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
df2a74ce 494int contact_remove_email(LDAP *ld, char *bind_path,
495 LK_ENTRY **linklist_entry, int linklist_current);
cd9e6b16 496int group_create(int ac, char **av, void *ptr);
f75f605a 497int group_delete(LDAP *ldap_handle, char *dn_path,
89db421e 498 char *group_name, char *group_membership, char *MoiraId);
f75f605a 499int group_rename(LDAP *ldap_handle, char *dn_path,
500 char *before_group_name, char *before_group_membership,
df2a74ce 501 char *before_group_ou, int before_security_flag,
502 char *before_desc, char *after_group_name,
503 char *after_group_membership, char *after_group_ou,
504 int after_security_flag, char *after_desc,
505 char *MoiraId, char *filter, char *maillist);
bbef4f93 506int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name);
507int machine_GetMoiraContainer(int ac, char **av, void *ptr);
df2a74ce 508int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
509 char *machine_name, char *container_name);
510int machine_move_to_ou(LDAP *ldap_handle, char *dn_path,
511 char *MoiraMachineName, char *DestinationOu);
89db421e 512int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
513 char *group_name, char *group_ou, char *group_membership,
df2a74ce 514 int group_security_flag, int updateGroup, char *maillist);
cd9e6b16 515int member_list_build(int ac, char **av, void *ptr);
f75f605a 516int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
df2a74ce 517 char *group_ou, char *group_membership,
518 char *user_name, char *pUserOu, char *MoiraId);
78af4e6e 519int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
f75f605a 520 char *group_ou, char *group_membership, char *user_name,
89db421e 521 char *pUserOu, char *MoiraId);
522int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
523 char *group_ou, char *group_membership,
524 int group_security_flag, char *MoiraId);
df2a74ce 525int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
526 char *DistinguishedName,
3abb4456 527 char *WinHomeDir, char *WinProfileDir,
528 char **homedir_v, char **winProfile_v,
529 char **drives_v, LDAPMod **mods,
530 int OpType, int n);
6a4366ac 531int sid_update(LDAP *ldap_handle, char *dn_path);
3abb4456 532void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n);
cd9e6b16 533int check_string(char *s);
bb52f279 534int check_container_name(char* s);
91d83263 535
cd9e6b16 536int mr_connect_cl(char *server, char *client, int version, int auth);
6c8f12af 537void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
df2a74ce 538 char **before, int beforec, char **after, int afterc);
6a4366ac 539void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
540 char **before, int beforec, char **after, int afterc);
f78c7eaf 541void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
542 char **before, int beforec, char **after, int afterc);
543void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 544 char **before, int beforec, char **after, int afterc);
5d0a7127 545void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 546 char **before, int beforec, char **after, int afterc);
bbef4f93 547void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
548 char **before, int beforec, char **after, int afterc);
cd9e6b16 549int linklist_create_entry(char *attribute, char *value,
550 LK_ENTRY **linklist_entry);
5d0a7127 551int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
cd9e6b16 552 char **attr_array, LK_ENTRY **linklist_base,
d7051053 553 int *linklist_count, unsigned long ScopeType);
5d0a7127 554void linklist_free(LK_ENTRY *linklist_base);
cd9e6b16 555
556int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
557 char *distinguished_name, LK_ENTRY **linklist_current);
558int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
559 LK_ENTRY **linklist_base, int *linklist_count);
560int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
561 char *Attribute, char *distinguished_name,
562 LK_ENTRY **linklist_current);
563
564int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
565 char *oldValue, char *newValue,
566 char ***modvalues, int type);
567void free_values(char **modvalues);
568
569int convert_domain_to_dn(char *domain, char **bind_path);
5d0a7127 570void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 571 char *distinguished_name);
5d0a7127 572int moira_disconnect(void);
573int moira_connect(void);
574void print_to_screen(const char *fmt, ...);
3abb4456 575int GetMachineName(char *MachineName);
26503e15 576int tickets_get_k5();
26503e15 577int destroy_cache(void);
578int dest_tkt(void);
5d0a7127 579
df2a74ce 580int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
581 char **homeServerName);
582
5d0a7127 583int main(int argc, char **argv)
584{
cd9e6b16 585 unsigned long rc;
586 int beforec;
587 int afterc;
cd9e6b16 588 int i;
d7051053 589 int j;
6a4366ac 590 int k;
d7051053 591 int OldUseSFU30;
cd9e6b16 592 char *table;
593 char **before;
594 char **after;
cd9e6b16 595 LDAP *ldap_handle;
f78c7eaf 596 char dn_path[256];
6a4366ac 597 char *orig_argv[64];
df2a74ce 598
5d0a7127 599 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
df2a74ce 600
cd9e6b16 601 if (argc < 4)
602 {
4a6e2ee4 603 com_err(whoami, 0, "Unable to process %s", "argc < 4");
cd9e6b16 604 exit(1);
605 }
df2a74ce 606
6a4366ac 607 if (argc < (4 + atoi(argv[2]) + atoi(argv[3])))
cd9e6b16 608 {
df2a74ce 609 com_err(whoami, 0, "Unable to process %s",
610 "argc < (4 + beforec + afterc)");
cd9e6b16 611 exit(1);
612 }
613
6a4366ac 614 if (!strcmp(argv[1], "filesys"))
74647f91 615 exit(0);
616
bfb6f0ad 617 for (i = 1; i < argc; i++)
0d958b3c 618 {
bfb6f0ad 619 strcat(tbl_buf, argv[i]);
620 strcat(tbl_buf, " ");
0d958b3c 621 }
df2a74ce 622
bfb6f0ad 623 com_err(whoami, 0, "%s", tbl_buf);
624
6a4366ac 625 if (check_winad())
626 {
627 com_err(whoami, 0, "%s failed", "check_winad()");
628 exit(1);
629 }
d7051053 630
5d0a7127 631 initialize_sms_error_table();
632 initialize_krb_error_table();
cd9e6b16 633
6a4366ac 634 UpdateDomainList = 0;
635 memset(DomainNames, '\0', sizeof(DomainNames[0]) * MAX_DOMAINS);
df2a74ce 636
6a4366ac 637 if (ReadDomainList())
cd9e6b16 638 {
6a4366ac 639 com_err(whoami, 0, "%s failed", "ReadDomainList()");
cd9e6b16 640 exit(1);
641 }
cd9e6b16 642
6a4366ac 643 for (i = 0; i < argc; i++)
644 orig_argv[i] = NULL;
645
646 for (k = 0; k < MAX_DOMAINS; k++)
d7051053 647 {
6a4366ac 648 if (strlen(DomainNames[k]) == 0)
649 continue;
650 for (i = 0; i < argc; i++)
651 {
652 if (orig_argv[i] != NULL)
653 free(orig_argv[i]);
654 orig_argv[i] = strdup(argv[i]);
655 }
656
657 memset(PrincipalName, '\0', sizeof(PrincipalName));
658 memset(ldap_domain, '\0', sizeof(ldap_domain));
659 memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES);
660 memset(default_server, '\0', sizeof(default_server));
661 memset(dn_path, '\0', sizeof(dn_path));
df2a74ce 662 memset(group_suffix, '\0', sizeof(group_suffix));
663 memset(exchange_acl, '\0', sizeof(exchange_acl));
664
6a4366ac 665 UseSFU30 = 0;
df2a74ce 666 UseGroupSuffix = 1;
667 UseGroupUniversal = 0;
668 SetGroupAce = 1;
669 SetPassword = 1;
670 Exchange = 0;
671 ProcessMachineContainer = 1;
672
673 sprintf(group_suffix, "%s", "_group");
674 sprintf(exchange_acl, "%s", "exchange-acl");
675
6a4366ac 676 beforec = atoi(orig_argv[2]);
677 afterc = atoi(orig_argv[3]);
678 table = orig_argv[1];
679 before = &orig_argv[4];
680 after = &orig_argv[4 + beforec];
681
682 if (afterc == 0)
683 after = NULL;
684
685 if (beforec == 0)
686 before = NULL;
687
688 if (ReadConfigFile(DomainNames[k]))
df2a74ce 689 continue;
6a4366ac 690
691 OldUseSFU30 = UseSFU30;
692
693 for (i = 0; i < 5; i++)
694 {
695 ldap_handle = (LDAP *)NULL;
696 if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "",
697 default_server, 1, ServerList)))
698 {
699 com_err(whoami, 0, "connected to domain %s", DomainNames[k]);
700 break;
701 }
6a4366ac 702 }
703
704 if ((rc) || (ldap_handle == NULL))
705 {
706 critical_alert("incremental",
df2a74ce 707 "winad.incr cannot connect to any server in "
708 "domain %s", DomainNames[k]);
6a4366ac 709 continue;
710 }
711
712 for (i = 0; i < (int)strlen(table); i++)
713 table[i] = tolower(table[i]);
714
715 if (!strcmp(table, "users"))
716 do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
717 afterc);
718 else if (!strcmp(table, "list"))
719 do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
720 afterc);
721 else if (!strcmp(table, "imembers"))
722 do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
723 afterc);
724 else if (!strcmp(table, "containers"))
725 do_container(ldap_handle, dn_path, ldap_domain, before, beforec, after,
726 afterc);
727 else if (!strcmp(table, "mcntmap"))
728 do_mcntmap(ldap_handle, dn_path, ldap_domain, before, beforec, after,
729 afterc);
df2a74ce 730
6a4366ac 731 ad_kdc_disconnect();
732
733 for (i = 0; i < MAX_SERVER_NAMES; i++)
734 {
735 if (ServerList[i] != NULL)
736 {
737 free(ServerList[i]);
738 ServerList[i] = NULL;
739 }
740 }
df2a74ce 741
6a4366ac 742 rc = ldap_unbind_s(ldap_handle);
d7051053 743 }
df2a74ce 744
5d0a7127 745 exit(0);
746}
747
bbef4f93 748void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
749 char **before, int beforec, char **after, int afterc)
750{
df2a74ce 751 char MoiraContainerName[128];
752 char ADContainerName[128];
753 char MachineName[1024];
754 char OriginalMachineName[1024];
755 long rc;
756 int DeleteMachine;
757 char MoiraContainerGroup[64];
bbef4f93 758
df2a74ce 759 if (!ProcessMachineContainer)
bbef4f93 760 {
df2a74ce 761 com_err(whoami, 0, "Process machines and containers disabled, skipping");
762 return;
bbef4f93 763 }
df2a74ce 764
765 DeleteMachine = 0;
766 memset(ADContainerName, '\0', sizeof(ADContainerName));
767 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
768
769 if ((beforec == 0) && (afterc == 0))
770 return;
771
772 if (rc = moira_connect())
773 {
774 critical_alert("AD incremental",
775 "Error contacting Moira server : %s",
776 error_message(rc));
777 return;
778 }
779
780 if ((beforec != 0) && (afterc == 0)) /*remove a machine*/
bbef4f93 781 {
df2a74ce 782 strcpy(OriginalMachineName, before[OU_MACHINE_NAME]);
783 strcpy(MachineName, before[OU_MACHINE_NAME]);
784 strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]);
785 DeleteMachine = 1;
786 com_err(whoami, 0, "removing machine %s from %s",
787 OriginalMachineName, before[OU_CONTAINER_NAME]);
bbef4f93 788 }
df2a74ce 789 else if ((beforec == 0) && (afterc != 0)) /*add a machine*/
bbef4f93 790 {
df2a74ce 791 strcpy(OriginalMachineName, after[OU_MACHINE_NAME]);
792 strcpy(MachineName, after[OU_MACHINE_NAME]);
793 strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]);
794 com_err(whoami, 0, "adding machine %s to container %s",
795 OriginalMachineName, after[OU_CONTAINER_NAME]);
bbef4f93 796 }
df2a74ce 797 else
798 {
799 moira_disconnect();
800 return;
801 }
802
803 rc = GetMachineName(MachineName);
bbef4f93 804
df2a74ce 805 if (strlen(MachineName) == 0)
3abb4456 806 {
df2a74ce 807 moira_disconnect();
808 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
809 OriginalMachineName);
810 return;
3abb4456 811 }
df2a74ce 812
813 Moira_process_machine_container_group(MachineName, MoiraContainerGroup,
814 DeleteMachine);
815
816 if (machine_check(ldap_handle, dn_path, MachineName))
bbef4f93 817 {
df2a74ce 818 com_err(whoami, 0, "Unable to find machine %s (alias %s) in AD.",
819 OriginalMachineName, MachineName);
820 moira_disconnect();
821 return;
bbef4f93 822 }
df2a74ce 823
824 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
825 machine_get_moira_container(ldap_handle, dn_path, MachineName,
826 MoiraContainerName);
827
828 if (strlen(MoiraContainerName) == 0)
bbef4f93 829 {
df2a74ce 830 com_err(whoami, 0, "Unable to fine machine %s (alias %s) container "
831 "in Moira - moving to orphans OU.",
832 OriginalMachineName, MachineName);
833 machine_move_to_ou(ldap_handle, dn_path, MachineName,
834 orphans_machines_ou);
835 moira_disconnect();
836 return;
bbef4f93 837 }
df2a74ce 838
839 container_get_dn(MoiraContainerName, ADContainerName);
840
841 if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/')
842 strcat(MoiraContainerName, "/");
843
844 container_check(ldap_handle, dn_path, MoiraContainerName);
845 machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName);
846 moira_disconnect();
847 return;
bbef4f93 848}
849
6c8f12af 850void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
df2a74ce 851 char **before, int beforec, char **after, int afterc)
6c8f12af 852{
209367bd 853 long rc;
6c8f12af 854
df2a74ce 855 if (!ProcessMachineContainer)
856 {
857 com_err(whoami, 0, "Process machines and containers disabled, skipping");
858 return;
859 }
860
6c8f12af 861 if ((beforec == 0) && (afterc == 0))
862 return;
863
209367bd 864 if (rc = moira_connect())
865 {
866 critical_alert("AD incremental", "Error contacting Moira server : %s",
867 error_message(rc));
868 return;
869 }
870
6c8f12af 871 if ((beforec != 0) && (afterc == 0)) /*delete a new container*/
872 {
873 com_err(whoami, 0, "deleting container %s", before[CONTAINER_NAME]);
874 container_delete(ldap_handle, dn_path, beforec, before);
209367bd 875 Moira_container_group_delete(before);
876 moira_disconnect();
6c8f12af 877 return;
878 }
df2a74ce 879
6c8f12af 880 if ((beforec == 0) && (afterc != 0)) /*create a container*/
881 {
9cfe334f 882 com_err(whoami, 0, "creating container %s", after[CONTAINER_NAME]);
6c8f12af 883 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
884 container_create(ldap_handle, dn_path, afterc, after);
209367bd 885 Moira_container_group_create(after);
886 moira_disconnect();
6c8f12af 887 return;
888 }
889
890 if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME]))
891 {
df2a74ce 892 com_err(whoami, 0, "renaming container %s to %s",
893 before[CONTAINER_NAME], after[CONTAINER_NAME]);
6c8f12af 894 container_rename(ldap_handle, dn_path, beforec, before, afterc, after);
209367bd 895 Moira_container_group_update(before, after);
896 moira_disconnect();
6c8f12af 897 return;
898 }
df2a74ce 899
900 com_err(whoami, 0, "updating container %s information",
901 after[CONTAINER_NAME]);
6c8f12af 902 container_update(ldap_handle, dn_path, beforec, before, afterc, after);
209367bd 903 Moira_container_group_update(before, after);
904 moira_disconnect();
6c8f12af 905 return;
906}
907
89db421e 908#define L_LIST_DESC 9
909#define L_LIST_ID 10
910
cd9e6b16 911void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
912 char **before, int beforec, char **after, int afterc)
5d0a7127 913{
89db421e 914 int updateGroup;
909e0dc3 915 int ProcessGroup;
f75f605a 916 long rc;
89db421e 917 char group_membership[6];
918 char list_id[32];
f75f605a 919 int security_flag;
89db421e 920 char filter[128];
f75f605a 921 char group_ou[256];
89db421e 922 char before_list_id[32];
f75f605a 923 char before_group_membership[1];
924 int before_security_flag;
925 char before_group_ou[256];
f75f605a 926 LK_ENTRY *ptr = NULL;
9db0b148 927
928 if (beforec == 0 && afterc == 0)
929 return;
930
89db421e 931 memset(list_id, '\0', sizeof(list_id));
932 memset(before_list_id, '\0', sizeof(before_list_id));
933 memset(before_group_ou, '\0', sizeof(before_group_ou));
934 memset(before_group_membership, '\0', sizeof(before_group_membership));
935 memset(group_ou, '\0', sizeof(group_ou));
936 memset(group_membership, '\0', sizeof(group_membership));
937 updateGroup = 0;
938
939 if (beforec > L_GID)
940 {
941 if (beforec < L_LIST_ID)
942 return;
943 if (beforec > L_LIST_DESC)
944 {
945 strcpy(before_list_id, before[L_LIST_ID]);
946 }
f75f605a 947 before_security_flag = 0;
df2a74ce 948 get_group_membership(before_group_membership, before_group_ou,
949 &before_security_flag, before);
f75f605a 950 }
df2a74ce 951
89db421e 952 if (afterc > L_GID)
f75f605a 953 {
89db421e 954 if (afterc < L_LIST_ID)
955 return;
956 if (afterc > L_LIST_DESC)
957 {
0a5e96ec 958 strcpy(list_id, after[L_LIST_ID]);
89db421e 959 }
f75f605a 960 security_flag = 0;
f75f605a 961 get_group_membership(group_membership, group_ou, &security_flag, after);
962 }
df2a74ce 963
89db421e 964 if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/
f75f605a 965 return;
cd9e6b16 966
89db421e 967 updateGroup = 0;
df2a74ce 968
89db421e 969 if (beforec)
cd9e6b16 970 {
89db421e 971 updateGroup = 1;
df2a74ce 972
973 if ((rc = process_group(ldap_handle, dn_path, before_list_id,
974 before[L_NAME], before_group_ou,
975 before_group_membership,
976 before_security_flag, CHECK_GROUPS,
977 before[L_MAILLIST])))
89db421e 978 {
979 if (rc == AD_NO_GROUPS_FOUND)
980 updateGroup = 0;
981 else
f75f605a 982 {
df2a74ce 983 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
984 (rc == AD_MULTIPLE_GROUPS_FOUND))
89db421e 985 {
df2a74ce 986 rc = process_group(ldap_handle, dn_path, before_list_id,
987 before[L_NAME], before_group_ou,
988 before_group_membership,
989 before_security_flag, CLEANUP_GROUPS,
990 before[L_MAILLIST]);
89db421e 991 }
992 if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0))
f75f605a 993 {
68ba2617 994 com_err(whoami, 0, "Unable to process list %s",
995 before[L_NAME]);
f75f605a 996 return;
997 }
89db421e 998 if (rc == AD_NO_GROUPS_FOUND)
999 updateGroup = 0;
1000 }
1001 }
1002 }
1003
1004 if ((beforec != 0) && (afterc != 0))
1005 {
1006 if (((strcmp(after[L_NAME], before[L_NAME])) ||
df2a74ce 1007 ((!strcmp(after[L_NAME], before[L_NAME])) &&
1008 (strcmp(before_group_ou, group_ou)))) &&
89db421e 1009 (updateGroup == 1))
1010 {
1011 com_err(whoami, 0, "Changing list name from %s to %s",
1012 before[L_NAME], after[L_NAME]);
df2a74ce 1013
1014 if ((strlen(before_group_ou) == 0) ||
1015 (strlen(before_group_membership) == 0) ||
89db421e 1016 (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
1017 {
4a6e2ee4 1018 com_err(whoami, 0, "%s", "Unable to find the group OU's");
89db421e 1019 return;
1020 }
df2a74ce 1021
89db421e 1022 memset(filter, '\0', sizeof(filter));
df2a74ce 1023
89db421e 1024 if ((rc = group_rename(ldap_handle, dn_path,
1025 before[L_NAME], before_group_membership,
df2a74ce 1026 before_group_ou, before_security_flag,
1027 before[L_LIST_DESC], after[L_NAME],
1028 group_membership, group_ou, security_flag,
1029 after[L_LIST_DESC],
1030 list_id, filter, after[L_MAILLIST])))
89db421e 1031 {
1032 if (rc != AD_NO_GROUPS_FOUND)
f75f605a 1033 {
df2a74ce 1034 com_err(whoami, 0,
1035 "Unable to change list name from %s to %s",
89db421e 1036 before[L_NAME], after[L_NAME]);
f75f605a 1037 return;
1038 }
89db421e 1039 updateGroup = 0;
f75f605a 1040 }
89db421e 1041 beforec = 0;
f75f605a 1042 }
1043 else
89db421e 1044 beforec = 0;
cd9e6b16 1045 }
df2a74ce 1046
89db421e 1047 if (beforec)
984c91b7 1048 {
df2a74ce 1049 if ((strlen(before_group_ou) == 0) ||
1050 (strlen(before_group_membership) == 0))
984c91b7 1051 {
df2a74ce 1052 com_err(whoami, 0,
1053 "Unable to find the group OU for group %s", before[L_NAME]);
f75f605a 1054 return;
1055 }
df2a74ce 1056
984c91b7 1057 com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
89db421e 1058 rc = group_delete(ldap_handle, dn_path, before[L_NAME],
1059 before_group_membership, before_list_id);
f75f605a 1060 return;
5d0a7127 1061 }
df2a74ce 1062
89db421e 1063 if (afterc)
5d0a7127 1064 {
89db421e 1065 if (!updateGroup)
1066 {
1067 com_err(whoami, 0, "Creating group %s", after[L_NAME]);
df2a74ce 1068
89db421e 1069 if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME],
1070 group_ou, group_membership,
df2a74ce 1071 security_flag, CHECK_GROUPS,
1072 after[L_MAILLIST]))
89db421e 1073 {
1074 if (rc != AD_NO_GROUPS_FOUND)
1075 {
df2a74ce 1076 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
1077 (rc == AD_MULTIPLE_GROUPS_FOUND))
89db421e 1078 {
df2a74ce 1079 rc = process_group(ldap_handle, dn_path, list_id,
1080 after[L_NAME],
89db421e 1081 group_ou, group_membership,
df2a74ce 1082 security_flag, CLEANUP_GROUPS,
1083 after[L_MAILLIST]);
89db421e 1084 }
df2a74ce 1085
89db421e 1086 if (rc)
1087 {
df2a74ce 1088 com_err(whoami, 0,
1089 "Unable to create list %s", after[L_NAME]);
89db421e 1090 return;
1091 }
1092 }
1093 }
1094 }
1095 else
1096 com_err(whoami, 0, "Updating group %s information", after[L_NAME]);
cd9e6b16 1097
f75f605a 1098 if (rc = moira_connect())
1099 {
1100 critical_alert("AD incremental",
1101 "Error contacting Moira server : %s",
1102 error_message(rc));
1103 return;
1104 }
1105
909e0dc3 1106 ProcessGroup = 0;
df2a74ce 1107
1108 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0,
1109 &ProcessGroup, after[L_MAILLIST]))
909e0dc3 1110 return;
df2a74ce 1111
909e0dc3 1112 if (ProcessGroup)
1113 {
df2a74ce 1114 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1,
1115 &ProcessGroup, after[L_MAILLIST]))
909e0dc3 1116 return;
1117 }
df2a74ce 1118
89db421e 1119 if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME],
df2a74ce 1120 group_ou, group_membership, security_flag,
1121 updateGroup, after[L_MAILLIST]))
cd9e6b16 1122 {
f75f605a 1123 moira_disconnect();
f75f605a 1124 return;
cd9e6b16 1125 }
df2a74ce 1126
89db421e 1127 if (atoi(after[L_ACTIVE]))
cd9e6b16 1128 {
89db421e 1129 populate_group(ldap_handle, dn_path, after[L_NAME], group_ou,
1130 group_membership, security_flag, list_id);
cd9e6b16 1131 }
df2a74ce 1132
f75f605a 1133 moira_disconnect();
5d0a7127 1134 }
f75f605a 1135 return;
5d0a7127 1136}
1137
f75f605a 1138#define LM_EXTRA_ACTIVE (LM_END)
1139#define LM_EXTRA_PUBLIC (LM_END+1)
1140#define LM_EXTRA_HIDDEN (LM_END+2)
1141#define LM_EXTRA_MAILLIST (LM_END+3)
1142#define LM_EXTRA_GROUP (LM_END+4)
1143#define LM_EXTRA_GID (LM_END+5)
89db421e 1144#define LMN_LIST_ID (LM_END+6)
1145#define LM_LIST_ID (LM_END+7)
1146#define LM_USER_ID (LM_END+8)
1147#define LM_EXTRA_END (LM_END+9)
984c91b7 1148
5d0a7127 1149void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 1150 char **before, int beforec, char **after, int afterc)
5d0a7127 1151{
df2a74ce 1152 LK_ENTRY *group_base;
1153 int group_count;
1154 char filter[128];
1155 char *attr_array[3];
cd9e6b16 1156 char group_name[128];
1157 char user_name[128];
9db0b148 1158 char user_type[128];
89db421e 1159 char moira_list_id[32];
1160 char moira_user_id[32];
f75f605a 1161 char group_membership[1];
f75f605a 1162 char group_ou[256];
5f7b0741 1163 char machine_ou[256];
df2a74ce 1164 char member[256];
f75f605a 1165 char *args[16];
1166 char **ptr;
89db421e 1167 char *av[7];
1168 char *call_args[7];
f75f605a 1169 char *pUserOu;
df2a74ce 1170 char *s;
cc1e4a1d 1171 char NewMachineName[1024];
89db421e 1172 int security_flag;
1173 int rc;
909e0dc3 1174 int ProcessGroup;
df2a74ce 1175 char *save_argv[U_END];
f75f605a 1176
1177 pUserOu = NULL;
1178 ptr = NULL;
89db421e 1179 memset(moira_list_id, '\0', sizeof(moira_list_id));
1180 memset(moira_user_id, '\0', sizeof(moira_user_id));
df2a74ce 1181
5d0a7127 1182 if (afterc)
1183 {
89db421e 1184 if (afterc < LM_EXTRA_GID)
f75f605a 1185 return;
df2a74ce 1186
984c91b7 1187 if (!atoi(after[LM_EXTRA_ACTIVE]))
4a6e2ee4 1188 {
df2a74ce 1189 com_err(whoami, 0,
1190 "Unable to add %s to group %s : group not active",
1191 after[2], after[0]);
1192 return;
4a6e2ee4 1193 }
df2a74ce 1194
f75f605a 1195 ptr = after;
df2a74ce 1196
89db421e 1197 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
2f62d71a 1198 return;
df2a74ce 1199
984c91b7 1200 strcpy(user_name, after[LM_MEMBER]);
1201 strcpy(group_name, after[LM_LIST]);
1202 strcpy(user_type, after[LM_TYPE]);
df2a74ce 1203
5f7b0741 1204 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1205 {
1206 if (afterc > LM_EXTRA_GROUP)
1207 {
f7c496a6 1208 strcpy(moira_list_id, after[LMN_LIST_ID]);
1209 strcpy(moira_user_id, after[LM_LIST_ID]);
5f7b0741 1210 }
1211 }
1212 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
89db421e 1213 {
1214 if (afterc > LMN_LIST_ID)
1215 {
1216 strcpy(moira_list_id, after[LM_LIST_ID]);
1217 strcpy(moira_user_id, after[LM_USER_ID]);
1218 }
1219 }
1220 else
1221 {
1222 if (afterc > LM_EXTRA_GID)
1223 strcpy(moira_list_id, after[LMN_LIST_ID]);
1224 }
5d0a7127 1225 }
1226 else if (beforec)
1227 {
89db421e 1228 if (beforec < LM_EXTRA_GID)
f75f605a 1229 return;
984c91b7 1230 if (!atoi(before[LM_EXTRA_ACTIVE]))
4a6e2ee4 1231 {
df2a74ce 1232 com_err(whoami, 0,
1233 "Unable to add %s to group %s : group not active",
1234 before[2], before[0]);
9db0b148 1235 return;
4a6e2ee4 1236 }
df2a74ce 1237
f75f605a 1238 ptr = before;
df2a74ce 1239
89db421e 1240 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
2f62d71a 1241 return;
df2a74ce 1242
984c91b7 1243 strcpy(user_name, before[LM_MEMBER]);
1244 strcpy(group_name, before[LM_LIST]);
1245 strcpy(user_type, before[LM_TYPE]);
df2a74ce 1246
5f7b0741 1247 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1248 {
1249 if (beforec > LM_EXTRA_GROUP)
1250 {
f7c496a6 1251 strcpy(moira_list_id, before[LMN_LIST_ID]);
1252 strcpy(moira_user_id, before[LM_LIST_ID]);
5f7b0741 1253 }
1254 }
1255 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
89db421e 1256 {
1257 if (beforec > LMN_LIST_ID)
1258 {
1259 strcpy(moira_list_id, before[LM_LIST_ID]);
1260 strcpy(moira_user_id, before[LM_USER_ID]);
1261 }
1262 }
1263 else
1264 {
1265 if (beforec > LM_EXTRA_GID)
1266 strcpy(moira_list_id, before[LMN_LIST_ID]);
1267 }
5d0a7127 1268 }
cd9e6b16 1269
f75f605a 1270 if (ptr == NULL)
4a6e2ee4 1271 {
df2a74ce 1272 com_err(whoami, 0,
1273 "Unable to process group : beforec = %d, afterc = %d",
1274 beforec, afterc);
4a6e2ee4 1275 return;
1276 }
f75f605a 1277
1278 args[L_NAME] = ptr[LM_LIST];
1279 args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
1280 args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
1281 args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
1282 args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
1283 args[L_GROUP] = ptr[LM_EXTRA_GROUP];
1284 args[L_GID] = ptr[LM_EXTRA_GID];
1285
1286 security_flag = 0;
1287 memset(group_ou, '\0', sizeof(group_ou));
1288 get_group_membership(group_membership, group_ou, &security_flag, args);
df2a74ce 1289
f75f605a 1290 if (strlen(group_ou) == 0)
cd9e6b16 1291 {
df2a74ce 1292 com_err(whoami, 0, "Unable to find the group OU for group %s",
1293 group_name);
cd9e6b16 1294 return;
1295 }
df2a74ce 1296
1297 if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name,
1298 group_ou, group_membership, security_flag,
1299 CHECK_GROUPS, args[L_MAILLIST]))
89db421e 1300 {
1301 if (rc != AD_NO_GROUPS_FOUND)
1302 {
df2a74ce 1303 if (rc = process_group(ldap_handle, dn_path, moira_list_id,
1304 group_name, group_ou, group_membership,
1305 security_flag, CLEANUP_GROUPS,
1306 args[L_MAILLIST]))
89db421e 1307 {
1308 if (rc != AD_NO_GROUPS_FOUND)
1309 {
1310 if (afterc)
df2a74ce 1311 com_err(whoami, 0, "Unable to add %s to group %s - "
1312 "unable to process group", user_name, group_name);
89db421e 1313 else
df2a74ce 1314 com_err(whoami, 0, "Unable to remove %s from group %s - "
1315 "unable to process group", user_name, group_name);
89db421e 1316 return;
1317 }
1318 }
1319 }
1320 }
df2a74ce 1321
89db421e 1322 if (rc == AD_NO_GROUPS_FOUND)
1323 {
1324 if (rc = moira_connect())
1325 {
1326 critical_alert("AD incremental",
1327 "Error contacting Moira server : %s",
1328 error_message(rc));
1329 return;
1330 }
df2a74ce 1331
89db421e 1332 com_err(whoami, 0, "creating group %s", group_name);
909e0dc3 1333 ProcessGroup = 0;
df2a74ce 1334
1335 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0,
1336 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
909e0dc3 1337 return;
df2a74ce 1338
909e0dc3 1339 if (ProcessGroup)
1340 {
df2a74ce 1341 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1,
1342 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
909e0dc3 1343 return;
1344 }
df2a74ce 1345
89db421e 1346 if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST],
df2a74ce 1347 group_ou, group_membership, security_flag, 0,
1348 ptr[LM_EXTRA_MAILLIST]))
89db421e 1349 {
1350 moira_disconnect();
1351 return;
1352 }
df2a74ce 1353
89db421e 1354 if (atoi(ptr[LM_EXTRA_ACTIVE]))
1355 {
1356 populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou,
1357 group_membership, security_flag, moira_list_id);
1358 }
df2a74ce 1359
89db421e 1360 moira_disconnect();
1361 }
df2a74ce 1362
f75f605a 1363 rc = 0;
df2a74ce 1364
f75f605a 1365 if (beforec)
1366 {
df2a74ce 1367 com_err(whoami, 0, "removing user %s from list %s", user_name,
1368 group_name);
f75f605a 1369 pUserOu = user_ou;
df2a74ce 1370
5f7b0741 1371 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1372 {
1373 memset(machine_ou, '\0', sizeof(machine_ou));
cc1e4a1d 1374 memset(NewMachineName, '\0', sizeof(NewMachineName));
df2a74ce 1375 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER],
1376 machine_ou, NewMachineName))
5f7b0741 1377 return;
6a4366ac 1378 if (ptr[LM_MEMBER] != NULL)
1379 free(ptr[LM_MEMBER]);
1380 ptr[LM_MEMBER] = strdup(NewMachineName);
5f7b0741 1381 pUserOu = machine_ou;
1382 }
df2a74ce 1383
f75f605a 1384 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
cd9e6b16 1385 {
df2a74ce 1386 strcpy(member, ptr[LM_MEMBER]);
1387
1388 if (Exchange)
1389 {
1390 if((s = strchr(member, '@')) == (char *) NULL)
1391 {
1392 strcat(member, "@mit.edu");
1393
1394 if (ptr[LM_MEMBER] != NULL)
1395 free(ptr[LM_MEMBER]);
1396 ptr[LM_MEMBER] = strdup(member);
1397 }
1398
1399 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1400 {
1401 s = strrchr(member, '.');
1402 *s = '\0';
1403 strcat(s, ".mit.edu");
1404
1405 if (ptr[LM_MEMBER] != NULL)
1406 free(ptr[LM_MEMBER]);
1407 ptr[LM_MEMBER] = strdup(member);
1408 }
1409 }
1410
f75f605a 1411 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1412 return;
df2a74ce 1413
f75f605a 1414 pUserOu = contact_ou;
1415 }
1416 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
df2a74ce 1417 {
1418 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1419 kerberos_ou))
1420 return;
1421
1422 pUserOu = kerberos_ou;
1423 }
89db421e 1424 if (rc = member_remove(ldap_handle, dn_path, group_name,
df2a74ce 1425 group_ou, group_membership, ptr[LM_MEMBER],
1426 pUserOu, moira_list_id))
1427 com_err(whoami, 0, "Unable to remove %s from group %s", user_name,
1428 group_name);
1429
1430 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1431 {
1432 if (rc = moira_connect())
1433 {
1434 critical_alert("AD incremental",
1435 "Error contacting Moira server : %s",
1436 error_message(rc));
1437 return;
1438 }
1439
1440 if (rc = populate_group(ldap_handle, dn_path, group_name,
1441 group_ou, group_membership, security_flag,
1442 moira_list_id))
1443 com_err(whoami, 0, "Unable to remove %s from group %s",
1444 user_name, group_name);
1445 moira_disconnect();
1446 }
89db421e 1447 return;
f75f605a 1448 }
df2a74ce 1449
89db421e 1450 com_err(whoami, 0, "Adding %s to list %s", user_name, group_name);
1451 pUserOu = user_ou;
df2a74ce 1452
5f7b0741 1453 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1454 {
1455 memset(machine_ou, '\0', sizeof(machine_ou));
cc1e4a1d 1456 memset(NewMachineName, '\0', sizeof(NewMachineName));
df2a74ce 1457
1458 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou,
1459 NewMachineName))
5f7b0741 1460 return;
df2a74ce 1461
6a4366ac 1462 if (ptr[LM_MEMBER] != NULL)
1463 free(ptr[LM_MEMBER]);
df2a74ce 1464
6a4366ac 1465 ptr[LM_MEMBER] = strdup(NewMachineName);
5f7b0741 1466 pUserOu = machine_ou;
1467 }
1468 else if (!strcasecmp(ptr[LM_TYPE], "STRING"))
f75f605a 1469 {
df2a74ce 1470 strcpy(member, ptr[LM_MEMBER]);
1471
1472 if (Exchange)
1473 {
1474 if((s = strchr(member, '@')) == (char *) NULL)
1475 {
1476 strcat(member, "@mit.edu");
1477
1478 if (ptr[LM_MEMBER] != NULL)
1479 free(ptr[LM_MEMBER]);
1480 ptr[LM_MEMBER] = strdup(member);
1481 }
1482
1483 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1484 {
1485 s = strrchr(member, '.');
1486 *s = '\0';
1487 strcat(s, ".mit.edu");
1488
1489 if (ptr[LM_MEMBER] != NULL)
1490 free(ptr[LM_MEMBER]);
1491 ptr[LM_MEMBER] = strdup(member);
1492 }
1493 }
1494
89db421e 1495 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
f75f605a 1496 return;
df2a74ce 1497
89db421e 1498 pUserOu = contact_ou;
1499 }
1500 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1501 {
1502 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
1503 return;
df2a74ce 1504
89db421e 1505 pUserOu = kerberos_ou;
1506 }
1507 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1508 {
1509 if ((rc = check_user(ldap_handle, dn_path, ptr[LM_MEMBER],
1510 moira_user_id)) == AD_NO_USER_FOUND)
f75f605a 1511 {
89db421e 1512 if (rc = moira_connect())
1513 {
1514 critical_alert("AD incremental",
1515 "Error connection to Moira : %s",
1516 error_message(rc));
1517 return;
1518 }
df2a74ce 1519
1520 com_err(whoami, 0, "creating user %s", ptr[LM_MEMBER]);
89db421e 1521 av[0] = ptr[LM_MEMBER];
1522 call_args[0] = (char *)ldap_handle;
1523 call_args[1] = dn_path;
1524 call_args[2] = moira_user_id;
1525 call_args[3] = NULL;
df2a74ce 1526
89db421e 1527 callback_rc = 0;
df2a74ce 1528
1529 if (Exchange)
1530 {
1531 group_count = 0;
1532 group_base = NULL;
1533
1534 sprintf(filter, "(&(objectClass=group)(cn=%s))", ptr[LM_MEMBER]);
1535 attr_array[0] = "cn";
1536 attr_array[1] = NULL;
1537 if ((rc = linklist_build(ldap_handle, dn_path, filter,
1538 attr_array, &group_base, &group_count,
1539 LDAP_SCOPE_SUBTREE)) != 0)
1540 {
1541 com_err(whoami, 0, "Unable to process user %s : %s",
1542 ptr[LM_MEMBER], ldap_err2string(rc));
1543 return;
1544 }
1545
1546 if (group_count)
1547 {
1548 com_err(whoami, 0, "Object already exists with name %s",
1549 ptr[LM_MEMBER]);
1550 return;
1551 }
1552
1553 linklist_free(group_base);
1554 group_count = 0;
1555 group_base = NULL;
1556 }
1557
1558 if (rc = mr_query("get_user_account_by_login", 1, av,
1559 save_query_info, save_argv))
89db421e 1560 {
1561 moira_disconnect();
4a6e2ee4 1562 com_err(whoami, 0, "Unable to create user %s : %s",
89db421e 1563 ptr[LM_MEMBER], error_message(rc));
1564 return;
1565 }
df2a74ce 1566
1567 if (rc = user_create(U_END, save_argv, call_args))
1568 {
1569 moira_disconnect();
1570 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1571 return;
1572 }
1573
89db421e 1574 if (callback_rc)
1575 {
1576 moira_disconnect();
4a6e2ee4 1577 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
89db421e 1578 return;
1579 }
f75f605a 1580 }
89db421e 1581 else
f75f605a 1582 {
89db421e 1583 if (rc != 0)
f75f605a 1584 return;
cd9e6b16 1585 }
89db421e 1586 pUserOu = user_ou;
cd9e6b16 1587 }
df2a74ce 1588
89db421e 1589 if (rc = member_add(ldap_handle, dn_path, group_name,
df2a74ce 1590 group_ou, group_membership, ptr[LM_MEMBER],
1591 pUserOu, moira_list_id))
1592 com_err(whoami, 0, "Unable to add %s to group %s", user_name, group_name);
1593
1594 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
cd9e6b16 1595 {
df2a74ce 1596 if (rc = moira_connect())
1597 {
1598 critical_alert("AD incremental",
1599 "Error contacting Moira server : %s",
1600 error_message(rc));
1601 return;
1602 }
1603
1604 if (rc = populate_group(ldap_handle, dn_path, group_name,
1605 group_ou, group_membership, security_flag,
1606 moira_list_id))
1607 com_err(whoami, 0, "Unable to add %s to group %s",
1608 user_name, group_name);
1609
1610 moira_disconnect();
f75f605a 1611 }
df2a74ce 1612
f75f605a 1613 return;
5d0a7127 1614}
1615
cd9e6b16 1616
3abb4456 1617#define U_USER_ID 10
1618#define U_HOMEDIR 11
1619#define U_PROFILEDIR 12
89db421e 1620
f78c7eaf 1621void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1622 char **before, int beforec, char **after,
cd9e6b16 1623 int afterc)
5d0a7127 1624{
df2a74ce 1625 LK_ENTRY *group_base;
1626 int group_count;
1627 char filter[128];
1628 char *attr_array[3];
984c91b7 1629 int rc;
89db421e 1630 char *av[7];
1631 char after_user_id[32];
1632 char before_user_id[32];
1633 char *call_args[7];
df2a74ce 1634 char *save_argv[U_END];
984c91b7 1635
5b8457c5 1636 if ((beforec == 0) && (afterc == 0))
984c91b7 1637 return;
1638
89db421e 1639 memset(after_user_id, '\0', sizeof(after_user_id));
1640 memset(before_user_id, '\0', sizeof(before_user_id));
df2a74ce 1641
89db421e 1642 if (beforec > U_USER_ID)
1643 strcpy(before_user_id, before[U_USER_ID]);
df2a74ce 1644
89db421e 1645 if (afterc > U_USER_ID)
1646 strcpy(after_user_id, after[U_USER_ID]);
984c91b7 1647
89db421e 1648 if ((beforec == 0) && (afterc == 0)) /*this case should never happen */
984c91b7 1649 return;
cd9e6b16 1650
4a6e2ee4 1651 if ((beforec == 0) && (afterc != 0))
1652 {
1653 /*this case only happens when the account*/
1654 /*account is first created but not usable*/
df2a74ce 1655
1656 com_err(whoami, 0, "Unable to process user %s because the user account "
1657 "is not yet usable", after[U_NAME]);
4a6e2ee4 1658 return;
1659 }
df2a74ce 1660
1661 /*this case only happens when the account is expunged */
1662
1663 if ((beforec != 0) && (afterc == 0))
1664 {
89db421e 1665 if (atoi(before[U_STATE]) == 0)
cd9e6b16 1666 {
89db421e 1667 com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]);
1668 user_delete(ldap_handle, dn_path, before[U_NAME], before_user_id);
cd9e6b16 1669 }
4a6e2ee4 1670 else
1671 {
df2a74ce 1672 com_err(whoami, 0, "Unable to process because user %s has been "
1673 "previously expungeded", before[U_NAME]);
4a6e2ee4 1674 }
f75f605a 1675 return;
5d0a7127 1676 }
f75f605a 1677
89db421e 1678 /*process anything that gets here*/
df2a74ce 1679
c0bd7667 1680 if ((rc = check_user(ldap_handle, dn_path, before[U_NAME],
1681 before_user_id)) == AD_NO_USER_FOUND)
5d0a7127 1682 {
6c8f12af 1683 if (!check_string(after[U_NAME]))
1684 return;
df2a74ce 1685
f75f605a 1686 if (rc = moira_connect())
1687 {
1688 critical_alert("AD incremental",
1689 "Error connection to Moira : %s",
1690 error_message(rc));
1691 return;
1692 }
5d0a7127 1693
df2a74ce 1694 com_err(whoami, 0, "creating user %s", after[U_NAME]);
1695
984c91b7 1696 av[0] = after[U_NAME];
cd9e6b16 1697 call_args[0] = (char *)ldap_handle;
1698 call_args[1] = dn_path;
89db421e 1699 call_args[2] = after_user_id;
9db0b148 1700 call_args[3] = NULL;
5b8457c5 1701 callback_rc = 0;
df2a74ce 1702
1703 if (Exchange)
1704 {
1705 group_count = 0;
1706 group_base = NULL;
1707
1708 sprintf(filter, "(&(objectClass=group)(cn=%s))", after[U_NAME]);
1709 attr_array[0] = "cn";
1710 attr_array[1] = NULL;
1711
1712 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
1713 &group_base, &group_count,
1714 LDAP_SCOPE_SUBTREE)) != 0)
1715 {
1716 com_err(whoami, 0, "Unable to process user %s : %s",
1717 after[U_NAME], ldap_err2string(rc));
1718 return;
1719 }
1720
1721 if (group_count >= 1)
1722 {
1723 com_err(whoami, 0, "Object already exists with name %s",
1724 after[U_NAME]);
1725 return;
1726 }
1727
1728 linklist_free(group_base);
1729 group_count = 0;
1730 group_base = NULL;
1731 }
1732
1733 if (rc = mr_query("get_user_account_by_login", 1, av,
1734 save_query_info, save_argv))
cd9e6b16 1735 {
f75f605a 1736 moira_disconnect();
4a6e2ee4 1737 com_err(whoami, 0, "Unable to create user %s : %s",
f75f605a 1738 after[U_NAME], error_message(rc));
1739 return;
cd9e6b16 1740 }
df2a74ce 1741
1742 if (rc = user_create(U_END, save_argv, call_args))
1743 {
1744 com_err(whoami, 0, "Unable to create user %s : %s",
1745 after[U_NAME], error_message(rc));
1746 return;
1747 }
1748
1749 if (callback_rc)
1750 {
1751 moira_disconnect();
1752 com_err(whoami, 0, "Unable to create user %s", after[U_NAME]);
5b8457c5 1753 return;
1754 }
df2a74ce 1755
89db421e 1756 return;
1757 }
1758 else
1759 {
1760 if (rc != 0)
1761 return;
1762 }
df2a74ce 1763
89db421e 1764 if (strcmp(before[U_NAME], after[U_NAME]))
1765 {
1766 if ((check_string(before[U_NAME])) && (check_string(after[U_NAME])))
f75f605a 1767 {
89db421e 1768 com_err(whoami, 0, "changing user %s to %s",
1769 before[U_NAME], after[U_NAME]);
df2a74ce 1770
89db421e 1771 if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME],
1772 after[U_NAME])) != LDAP_SUCCESS)
f75f605a 1773 {
89db421e 1774 return;
f75f605a 1775 }
1776 }
cd9e6b16 1777 }
df2a74ce 1778
89db421e 1779 com_err(whoami, 0, "updating user %s information", after[U_NAME]);
1780 rc = user_update(ldap_handle, dn_path, after[U_NAME],
1781 after[U_UID], after[U_MITID],
df2a74ce 1782 after_user_id, atoi(after[U_STATE]),
1783 after[U_HOMEDIR], after[U_PROFILEDIR],
1784 after[U_FIRST], after[U_MIDDLE], after[U_LAST]);
1785
f75f605a 1786 return;
5d0a7127 1787}
1788
1789int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
cd9e6b16 1790 char *oldValue, char *newValue,
1791 char ***modvalues, int type)
5d0a7127 1792{
cd9e6b16 1793 LK_ENTRY *linklist_ptr;
1794 int i;
1795 char *cPtr;
df2a74ce 1796
1797 if (((*modvalues) = calloc(1,
1798 (modvalue_count + 1) * sizeof(char *))) == NULL)
cd9e6b16 1799 {
1800 return(1);
1801 }
df2a74ce 1802
5d0a7127 1803 for (i = 0; i < (modvalue_count + 1); i++)
cd9e6b16 1804 (*modvalues)[i] = NULL;
df2a74ce 1805
5d0a7127 1806 if (modvalue_count != 0)
1807 {
1808 linklist_ptr = linklist_base;
1809 for (i = 0; i < modvalue_count; i++)
cd9e6b16 1810 {
1811 if ((oldValue != NULL) && (newValue != NULL))
1812 {
1813 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
df2a74ce 1814 != (char *)NULL)
cd9e6b16 1815 {
1816 if (type == REPLACE)
1817 {
1818 if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1819 == NULL)
1820 return(1);
1821 memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1822 strcpy((*modvalues)[i], newValue);
1823 }
1824 else
1825 {
1826 if (((*modvalues)[i] = calloc(1,
1827 (int)(cPtr - linklist_ptr->value) +
df2a74ce 1828 (linklist_ptr->length -
1829 strlen(oldValue)) +
1830 strlen(newValue) + 1)) == NULL)
cd9e6b16 1831 return(1);
1832 memset((*modvalues)[i], '\0',
1833 (int)(cPtr - linklist_ptr->value) +
1834 (linklist_ptr->length - strlen(oldValue)) +
1835 strlen(newValue) + 1);
1836 memcpy((*modvalues)[i], linklist_ptr->value,
1837 (int)(cPtr - linklist_ptr->value));
1838 strcat((*modvalues)[i], newValue);
1839 strcat((*modvalues)[i],
df2a74ce 1840 &linklist_ptr->value[(int)(cPtr -
1841 linklist_ptr->value) + strlen(oldValue)]);
cd9e6b16 1842 }
1843 }
1844 else
1845 {
1846 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1847 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1848 memcpy((*modvalues)[i], linklist_ptr->value,
1849 linklist_ptr->length);
1850 }
1851 }
1852 else
1853 {
1854 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1855 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1856 memcpy((*modvalues)[i], linklist_ptr->value,
1857 linklist_ptr->length);
1858 }
1859 linklist_ptr = linklist_ptr->next;
1860 }
1861 (*modvalues)[i] = NULL;
5d0a7127 1862 }
1863 return(0);
1864}
1865
cd9e6b16 1866
5d0a7127 1867int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
cd9e6b16 1868 char **attr_array, LK_ENTRY **linklist_base,
d7051053 1869 int *linklist_count, unsigned long ScopeType)
5d0a7127 1870{
cd9e6b16 1871 ULONG rc;
5d0a7127 1872 LDAPMessage *ldap_entry;
cd9e6b16 1873
1874 rc = 0;
5d0a7127 1875 ldap_entry = NULL;
1876 (*linklist_base) = NULL;
1877 (*linklist_count) = 0;
df2a74ce 1878
d7051053 1879 if ((rc = ldap_search_s(ldap_handle, dn_path, ScopeType,
df2a74ce 1880 search_exp, attr_array, 0,
1881 &ldap_entry)) != LDAP_SUCCESS)
6c8f12af 1882 {
1883 if (rc != LDAP_SIZELIMIT_EXCEEDED)
1884 return(0);
1885 }
1886
df2a74ce 1887 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base,
1888 linklist_count);
cd9e6b16 1889
5d0a7127 1890 ldap_msgfree(ldap_entry);
1891 return(rc);
1892}
1893
1894int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 1895 LK_ENTRY **linklist_base, int *linklist_count)
5d0a7127 1896{
cd9e6b16 1897 char distinguished_name[1024];
1898 LK_ENTRY *linklist_ptr;
1899 int rc;
1900
5d0a7127 1901 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1902 return(0);
df2a74ce 1903
cd9e6b16 1904 memset(distinguished_name, '\0', sizeof(distinguished_name));
1905 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1906
1907 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1908 linklist_base)) != 0)
5d0a7127 1909 return(rc);
cd9e6b16 1910
5d0a7127 1911 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1912 {
cd9e6b16 1913 memset(distinguished_name, '\0', sizeof(distinguished_name));
1914 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
df2a74ce 1915
1916 if ((rc = retrieve_attributes(ldap_handle, ldap_entry,
1917 distinguished_name, linklist_base)) != 0)
cd9e6b16 1918 return(rc);
5d0a7127 1919 }
cd9e6b16 1920
5d0a7127 1921 linklist_ptr = (*linklist_base);
1922 (*linklist_count) = 0;
df2a74ce 1923
5d0a7127 1924 while (linklist_ptr != NULL)
1925 {
1926 ++(*linklist_count);
1927 linklist_ptr = linklist_ptr->next;
1928 }
df2a74ce 1929
5d0a7127 1930 return(0);
1931}
1932
1933int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 1934 char *distinguished_name, LK_ENTRY **linklist_current)
5d0a7127 1935{
cd9e6b16 1936 char *Attribute;
1937 BerElement *ptr;
1938
5d0a7127 1939 ptr = NULL;
df2a74ce 1940
1941 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry,
1942 &ptr)) != NULL)
5d0a7127 1943 {
cd9e6b16 1944 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1945 linklist_current);
5d0a7127 1946 ldap_memfree(Attribute);
cd9e6b16 1947 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
1948 ptr)) != NULL)
1949 {
1950 retrieve_values(ldap_handle, ldap_entry, Attribute,
1951 distinguished_name, linklist_current);
1952 ldap_memfree(Attribute);
1953 }
5d0a7127 1954 }
df2a74ce 1955
cd9e6b16 1956 ldap_ber_free(ptr, 0);
df2a74ce 1957
5d0a7127 1958 return(0);
1959}
1960
cd9e6b16 1961int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1962 char *Attribute, char *distinguished_name,
1963 LK_ENTRY **linklist_current)
5d0a7127 1964{
cd9e6b16 1965 char **str_value;
1966 char temp[256];
1967 void **Ptr;
1968 int use_bervalue;
1969 LK_ENTRY *linklist_previous;
5d0a7127 1970 LDAP_BERVAL **ber_value;
cd9e6b16 1971 DWORD ber_length;
df2a74ce 1972
5d0a7127 1973#ifdef LDAP_DEBUG
cd9e6b16 1974 SID *sid;
1975 GUID *guid;
1976 int i;
1977 int intValue;
1978 DWORD *subauth;
1979 SID_IDENTIFIER_AUTHORITY *sid_auth;
1980 unsigned char *subauth_count;
1981#endif /*LDAP_BEGUG*/
5d0a7127 1982
1983 use_bervalue = 0;
1984 memset(temp, '\0', sizeof(temp));
df2a74ce 1985
5d0a7127 1986 if ((!strcmp(Attribute, "objectSid")) ||
1987 (!strcmp(Attribute, "objectGUID")))
1988 use_bervalue = 1;
df2a74ce 1989
5d0a7127 1990 if (use_bervalue)
1991 {
1992 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1993 Ptr = (void **)ber_value;
1994 str_value = NULL;
df2a74ce 1995 }
5d0a7127 1996 else
1997 {
1998 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1999 Ptr = (void **)str_value;
2000 ber_value = NULL;
2001 }
df2a74ce 2002
5d0a7127 2003 if (Ptr != NULL)
2004 {
2005 for (; *Ptr; Ptr++)
cd9e6b16 2006 {
2007 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
2008 return(1);
df2a74ce 2009
cd9e6b16 2010 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
2011 linklist_previous->next = (*linklist_current);
2012 (*linklist_current) = linklist_previous;
df2a74ce 2013
cd9e6b16 2014 if (((*linklist_current)->attribute = calloc(1,
df2a74ce 2015 strlen(Attribute) + 1)) == NULL)
cd9e6b16 2016 return(1);
df2a74ce 2017
cd9e6b16 2018 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
2019 strcpy((*linklist_current)->attribute, Attribute);
df2a74ce 2020
cd9e6b16 2021 if (use_bervalue)
2022 {
2023 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
df2a74ce 2024
cd9e6b16 2025 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
2026 return(1);
df2a74ce 2027
cd9e6b16 2028 memset((*linklist_current)->value, '\0', ber_length);
df2a74ce 2029 memcpy((*linklist_current)->value,
2030 (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length);
cd9e6b16 2031 (*linklist_current)->length = ber_length;
2032 }
2033 else
2034 {
2035 if (((*linklist_current)->value = calloc(1,
df2a74ce 2036 strlen(*Ptr) + 1)) == NULL)
cd9e6b16 2037 return(1);
df2a74ce 2038
cd9e6b16 2039 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
2040 (*linklist_current)->length = strlen(*Ptr);
2041 strcpy((*linklist_current)->value, *Ptr);
2042 }
df2a74ce 2043
cd9e6b16 2044 (*linklist_current)->ber_value = use_bervalue;
df2a74ce 2045
cd9e6b16 2046 if (((*linklist_current)->dn = calloc(1,
df2a74ce 2047 strlen(distinguished_name) + 1)) == NULL)
cd9e6b16 2048 return(1);
df2a74ce 2049
2050 memset((*linklist_current)->dn, '\0',
2051 strlen(distinguished_name) + 1);
cd9e6b16 2052 strcpy((*linklist_current)->dn, distinguished_name);
2053
5d0a7127 2054#ifdef LDAP_DEBUG
cd9e6b16 2055 if (!strcmp(Attribute, "objectGUID"))
2056 {
2057 guid = (GUID *)((*linklist_current)->value);
df2a74ce 2058 sprintf(temp,
2059 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
cd9e6b16 2060 guid->Data1, guid->Data2, guid->Data3,
2061 guid->Data4[0], guid->Data4[1], guid->Data4[2],
2062 guid->Data4[3], guid->Data4[4], guid->Data4[5],
2063 guid->Data4[6], guid->Data4[7]);
2064 print_to_screen(" %20s : {%s}\n", Attribute, temp);
2065 }
2066 else if (!strcmp(Attribute, "objectSid"))
2067 {
2068 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
df2a74ce 2069
5d0a7127 2070#ifdef _WIN32
cd9e6b16 2071 print_to_screen(" Revision = %d\n", sid->Revision);
2072 print_to_screen(" SID Identifier Authority:\n");
2073 sid_auth = &sid->IdentifierAuthority;
2074 if (sid_auth->Value[0])
2075 print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
2076 else if (sid_auth->Value[1])
2077 print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
2078 else if (sid_auth->Value[2])
2079 print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
2080 else if (sid_auth->Value[3])
df2a74ce 2081 print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
cd9e6b16 2082 else if (sid_auth->Value[5])
2083 print_to_screen(" SECURITY_NT_AUTHORITY\n");
2084 else
2085 print_to_screen(" UNKNOWN SID AUTHORITY\n");
2086 subauth_count = GetSidSubAuthorityCount(sid);
2087 print_to_screen(" SidSubAuthorityCount = %d\n",
2088 *subauth_count);
2089 print_to_screen(" SidSubAuthority:\n");
2090 for (i = 0; i < *subauth_count; i++)
2091 {
2092 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
2093 print_to_screen(" %u\n", *subauth);
2094 }
5d0a7127 2095#endif
cd9e6b16 2096 }
2097 else if ((!memcmp(Attribute, "userAccountControl",
2098 strlen("userAccountControl"))) ||
2099 (!memcmp(Attribute, "sAMAccountType",
2100 strlen("sAmAccountType"))))
2101 {
2102 intValue = atoi(*Ptr);
2103 print_to_screen(" %20s : %ld\n",Attribute, intValue);
df2a74ce 2104
cd9e6b16 2105 if (!memcmp(Attribute, "userAccountControl",
2106 strlen("userAccountControl")))
2107 {
2108 if (intValue & UF_ACCOUNTDISABLE)
2109 print_to_screen(" %20s : %s\n",
2110 "", "Account disabled");
2111 else
2112 print_to_screen(" %20s : %s\n",
2113 "", "Account active");
2114 if (intValue & UF_HOMEDIR_REQUIRED)
2115 print_to_screen(" %20s : %s\n",
2116 "", "Home directory required");
2117 if (intValue & UF_LOCKOUT)
2118 print_to_screen(" %20s : %s\n",
2119 "", "Account locked out");
2120 if (intValue & UF_PASSWD_NOTREQD)
2121 print_to_screen(" %20s : %s\n",
2122 "", "No password required");
2123 if (intValue & UF_PASSWD_CANT_CHANGE)
2124 print_to_screen(" %20s : %s\n",
2125 "", "Cannot change password");
2126 if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
2127 print_to_screen(" %20s : %s\n",
2128 "", "Temp duplicate account");
2129 if (intValue & UF_NORMAL_ACCOUNT)
2130 print_to_screen(" %20s : %s\n",
2131 "", "Normal account");
2132 if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
2133 print_to_screen(" %20s : %s\n",
2134 "", "Interdomain trust account");
2135 if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
2136 print_to_screen(" %20s : %s\n",
2137 "", "Workstation trust account");
2138 if (intValue & UF_SERVER_TRUST_ACCOUNT)
2139 print_to_screen(" %20s : %s\n",
2140 "", "Server trust account");
2141 }
2142 }
2143 else
2144 {
2145 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
2146 }
5d0a7127 2147#endif /*LDAP_DEBUG*/
cd9e6b16 2148 }
df2a74ce 2149
5d0a7127 2150 if (str_value != NULL)
cd9e6b16 2151 ldap_value_free(str_value);
df2a74ce 2152
5d0a7127 2153 if (ber_value != NULL)
cd9e6b16 2154 ldap_value_free_len(ber_value);
5d0a7127 2155 }
df2a74ce 2156
5d0a7127 2157 (*linklist_current) = linklist_previous;
df2a74ce 2158
5d0a7127 2159 return(0);
2160}
2161
5d0a7127 2162int moira_connect(void)
2163{
cd9e6b16 2164 long rc;
2165 char HostName[64];
2166
5d0a7127 2167 if (!mr_connections++)
2168 {
df2a74ce 2169
5d0a7127 2170#ifdef _WIN32
2171 memset(HostName, '\0', sizeof(HostName));
2172 strcpy(HostName, "ttsp");
cd9e6b16 2173 rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
5d0a7127 2174#else
2175 struct utsname uts;
2176 uname(&uts);
cd9e6b16 2177 rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
5d0a7127 2178#endif /*WIN32*/
df2a74ce 2179
5d0a7127 2180 return rc;
2181 }
df2a74ce 2182
5d0a7127 2183 return 0;
2184}
2185
6a4366ac 2186int check_winad(void)
0d958b3c 2187{
2188 int i;
2189
2190 for (i = 0; file_exists(STOP_FILE); i++)
2191 {
2192 if (i > 30)
2193 {
f75f605a 2194 critical_alert("AD incremental",
f78c7eaf 2195 "WINAD incremental failed (%s exists): %s",
2196 STOP_FILE, tbl_buf);
6a4366ac 2197 return(1);
f78c7eaf 2198 }
df2a74ce 2199
0d958b3c 2200 sleep(60);
2201 }
df2a74ce 2202
6a4366ac 2203 return(0);
0d958b3c 2204}
2205
5d0a7127 2206int moira_disconnect(void)
2207{
5d0a7127 2208
cd9e6b16 2209 if (!--mr_connections)
5d0a7127 2210 {
cd9e6b16 2211 mr_disconnect();
5d0a7127 2212 }
df2a74ce 2213
cd9e6b16 2214 return 0;
5d0a7127 2215}
2216
5d0a7127 2217void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 2218 char *distinguished_name)
5d0a7127 2219{
cd9e6b16 2220 char *CName;
df2a74ce 2221
5d0a7127 2222 CName = ldap_get_dn(ldap_handle, ldap_entry);
df2a74ce 2223
5d0a7127 2224 if (CName == NULL)
2225 return;
df2a74ce 2226
5d0a7127 2227 strcpy(distinguished_name, CName);
2228 ldap_memfree(CName);
2229}
2230
2231int linklist_create_entry(char *attribute, char *value,
cd9e6b16 2232 LK_ENTRY **linklist_entry)
5d0a7127 2233{
2234 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
df2a74ce 2235
5d0a7127 2236 if (!(*linklist_entry))
2237 {
2238 return(1);
2239 }
df2a74ce 2240
5d0a7127 2241 memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
2242 (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
2243 memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
2244 strcpy((*linklist_entry)->attribute, attribute);
2245 (*linklist_entry)->value = calloc(1, strlen(value) + 1);
2246 memset((*linklist_entry)->value, '\0', strlen(value) + 1);
2247 strcpy((*linklist_entry)->value, value);
2248 (*linklist_entry)->length = strlen(value);
2249 (*linklist_entry)->next = NULL;
df2a74ce 2250
5d0a7127 2251 return(0);
2252}
2253
2254void print_to_screen(const char *fmt, ...)
2255{
2256 va_list pvar;
cd9e6b16 2257
5d0a7127 2258 va_start(pvar, fmt);
2259 vfprintf(stderr, fmt, pvar);
2260 fflush(stderr);
2261 va_end(pvar);
2262}
cd9e6b16 2263
2264int get_group_membership(char *group_membership, char *group_ou,
2265 int *security_flag, char **av)
2266{
2267 int maillist_flag;
2268 int group_flag;
df2a74ce 2269
cd9e6b16 2270 maillist_flag = atoi(av[L_MAILLIST]);
2271 group_flag = atoi(av[L_GROUP]);
df2a74ce 2272
cd9e6b16 2273 if (security_flag != NULL)
2274 (*security_flag) = 0;
df2a74ce 2275
cd9e6b16 2276 if ((maillist_flag) && (group_flag))
2277 {
2278 if (group_membership != NULL)
2279 group_membership[0] = 'B';
df2a74ce 2280
cd9e6b16 2281 if (security_flag != NULL)
2282 (*security_flag) = 1;
df2a74ce 2283
cd9e6b16 2284 if (group_ou != NULL)
2285 strcpy(group_ou, group_ou_both);
2286 }
2287 else if ((!maillist_flag) && (group_flag))
2288 {
2289 if (group_membership != NULL)
2290 group_membership[0] = 'S';
df2a74ce 2291
cd9e6b16 2292 if (security_flag != NULL)
2293 (*security_flag) = 1;
df2a74ce 2294
cd9e6b16 2295 if (group_ou != NULL)
2296 strcpy(group_ou, group_ou_security);
2297 }
2298 else if ((maillist_flag) && (!group_flag))
2299 {
2300 if (group_membership != NULL)
2301 group_membership[0] = 'D';
df2a74ce 2302
cd9e6b16 2303 if (group_ou != NULL)
2304 strcpy(group_ou, group_ou_distribution);
2305 }
2306 else
2307 {
2308 if (group_membership != NULL)
2309 group_membership[0] = 'N';
df2a74ce 2310
cd9e6b16 2311 if (group_ou != NULL)
2312 strcpy(group_ou, group_ou_neither);
2313 }
df2a74ce 2314
cd9e6b16 2315 return(0);
2316}
2317
f75f605a 2318int group_rename(LDAP *ldap_handle, char *dn_path,
2319 char *before_group_name, char *before_group_membership,
df2a74ce 2320 char *before_group_ou, int before_security_flag,
2321 char *before_desc, char *after_group_name,
2322 char *after_group_membership, char *after_group_ou,
2323 int after_security_flag, char *after_desc,
2324 char *MoiraId, char *filter, char *maillist)
9db0b148 2325{
2326 LDAPMod *mods[20];
2327 char old_dn[512];
2328 char new_dn[512];
78af4e6e 2329 char new_dn_path[512];
78af4e6e 2330 char sam_name[256];
df2a74ce 2331 char mail[256];
2332 char mail_nickname[256];
2333 char proxy_address[256];
2334 char address_book[256];
9db0b148 2335 char *attr_array[3];
89db421e 2336 char *mitMoiraId_v[] = {NULL, NULL};
9db0b148 2337 char *name_v[] = {NULL, NULL};
78af4e6e 2338 char *samAccountName_v[] = {NULL, NULL};
c76c595a 2339 char *groupTypeControl_v[] = {NULL, NULL};
df2a74ce 2340 char *mail_v[] = {NULL, NULL};
2341 char *proxy_address_v[] = {NULL, NULL};
2342 char *mail_nickname_v[] = {NULL, NULL};
2343 char *reportToOriginator_v[] = {NULL, NULL};
2344 char *address_book_v[] = {NULL, NULL};
2345 char *legacy_exchange_dn_v[] = {NULL, NULL};
2346 u_int groupTypeControl;
c76c595a 2347 char groupTypeControlStr[80];
df2a74ce 2348 char contact_mail[256];
9db0b148 2349 int n;
2350 int i;
2351 int rc;
9db0b148 2352 LK_ENTRY *group_base;
2353 int group_count;
df2a74ce 2354 int MailDisabled = 0;
9db0b148 2355
df2a74ce 2356 if(UseGroupUniversal)
2357 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2358 else
2359 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2360
f75f605a 2361 if (!check_string(before_group_name))
78af4e6e 2362 {
df2a74ce 2363 com_err(whoami, 0,
2364 "Unable to process invalid LDAP list name %s",
2365 before_group_name);
89db421e 2366 return(AD_INVALID_NAME);
78af4e6e 2367 }
df2a74ce 2368
f75f605a 2369 if (!check_string(after_group_name))
78af4e6e 2370 {
df2a74ce 2371 com_err(whoami, 0,
2372 "Unable to process invalid LDAP list name %s", after_group_name);
89db421e 2373 return(AD_INVALID_NAME);
2374 }
2375
df2a74ce 2376 if (Exchange)
2377 {
2378 if(atoi(maillist))
2379 {
2380 group_count = 0;
2381 group_base = NULL;
2382
2383 sprintf(filter, "(&(objectClass=user)(cn=%s))", after_group_name);
2384 attr_array[0] = "cn";
2385 attr_array[1] = NULL;
2386
2387 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
2388 &group_base, &group_count,
2389 LDAP_SCOPE_SUBTREE)) != 0)
2390 {
2391 com_err(whoami, 0, "Unable to process group %s : %s",
2392 after_group_name, ldap_err2string(rc));
2393 return(rc);
2394 }
2395
2396 if (group_count)
2397 {
2398 com_err(whoami, 0, "Object already exists with name %s",
2399 after_group_name);
2400 MailDisabled++;
2401 }
2402
2403 linklist_free(group_base);
2404 group_base = NULL;
2405 group_count = 0;
2406 }
2407 }
2408
89db421e 2409 group_count = 0;
2410 group_base = NULL;
df2a74ce 2411
89db421e 2412 if (rc = ad_get_group(ldap_handle, dn_path, before_group_name,
2413 before_group_membership,
2414 MoiraId, "distinguishedName", &group_base,
2415 &group_count, filter))
2416 return(rc);
2417
2418 if (group_count == 0)
2419 {
2420 return(AD_NO_GROUPS_FOUND);
2421 }
df2a74ce 2422
89db421e 2423 if (group_count != 1)
2424 {
df2a74ce 2425 com_err(whoami, 0, "Unable to process multiple groups with "
2426 "MoiraId = %s exist in the AD", MoiraId);
89db421e 2427 return(AD_MULTIPLE_GROUPS_FOUND);
78af4e6e 2428 }
df2a74ce 2429
89db421e 2430 strcpy(old_dn, group_base->value);
78af4e6e 2431
89db421e 2432 linklist_free(group_base);
2433 group_base = NULL;
2434 group_count = 0;
2435 attr_array[0] = "sAMAccountName";
9db0b148 2436 attr_array[1] = NULL;
df2a74ce 2437
89db421e 2438 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 2439 &group_base, &group_count,
2440 LDAP_SCOPE_SUBTREE)) != 0)
9db0b148 2441 {
4a6e2ee4 2442 com_err(whoami, 0, "Unable to get list %s dn : %s",
f75f605a 2443 after_group_name, ldap_err2string(rc));
2444 return(rc);
9db0b148 2445 }
df2a74ce 2446
9db0b148 2447 if (group_count != 1)
2448 {
89db421e 2449 com_err(whoami, 0,
2450 "Unable to get sAMAccountName for group %s",
2451 before_group_name);
2452 return(AD_LDAP_FAILURE);
9db0b148 2453 }
df2a74ce 2454
89db421e 2455 strcpy(sam_name, group_base->value);
9db0b148 2456 linklist_free(group_base);
2457 group_base = NULL;
2458 group_count = 0;
df2a74ce 2459
f75f605a 2460 sprintf(new_dn_path, "%s,%s", after_group_ou, dn_path);
2461 sprintf(new_dn, "cn=%s", after_group_name);
df2a74ce 2462 sprintf(mail, "%s@%s", after_group_name, lowercase(ldap_domain));
2463 sprintf(contact_mail, "%s@mit.edu", after_group_name);
2464 sprintf(proxy_address, "SMTP:%s@%s", after_group_name,
2465 lowercase(ldap_domain));
2466 sprintf(mail_nickname, "%s", after_group_name);
2467
f75f605a 2468 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, new_dn_path,
78af4e6e 2469 TRUE, NULL, NULL)) != LDAP_SUCCESS)
2470 {
4a6e2ee4 2471 com_err(whoami, 0, "Unable to rename list from %s to %s : %s",
89db421e 2472 before_group_name, after_group_name, ldap_err2string(rc));
f75f605a 2473 return(rc);
78af4e6e 2474 }
9db0b148 2475
f75f605a 2476 name_v[0] = after_group_name;
df2a74ce 2477
2478 if (!strncmp(&sam_name[strlen(sam_name) - strlen(group_suffix)],
2479 group_suffix, strlen(group_suffix)))
89db421e 2480 {
df2a74ce 2481 sprintf(sam_name, "%s%s", after_group_name, group_suffix);
89db421e 2482 }
2483 else
2484 {
df2a74ce 2485 com_err(whoami, 0,
2486 "Unable to rename list from %s to %s : sAMAccountName not found",
89db421e 2487 before_group_name, after_group_name);
2488 return(rc);
2489 }
df2a74ce 2490
78af4e6e 2491 samAccountName_v[0] = sam_name;
df2a74ce 2492
c76c595a 2493 if (after_security_flag)
2494 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
df2a74ce 2495
c76c595a 2496 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2497 groupTypeControl_v[0] = groupTypeControlStr;
4a6e2ee4 2498 mitMoiraId_v[0] = MoiraId;
2499
2500 sprintf(new_dn, "cn=%s,%s,%s", after_group_name, after_group_ou, dn_path);
df2a74ce 2501 rc = attribute_update(ldap_handle, new_dn, after_desc, "description",
2502 after_group_name);
9db0b148 2503 n = 0;
5a775f54 2504 ADD_ATTR("samAccountName", samAccountName_v, LDAP_MOD_REPLACE);
9db0b148 2505 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
89db421e 2506 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
c76c595a 2507 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_REPLACE);
df2a74ce 2508
2509 if (Exchange)
2510 {
2511 if(atoi(maillist) && !MailDisabled && email_isvalid(mail))
2512 {
2513 mail_nickname_v[0] = mail_nickname;
2514 proxy_address_v[0] = proxy_address;
2515 mail_v[0] = mail;
2516 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2517 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2518 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2519 }
2520 else
2521 {
2522 mail_nickname_v[0] = NULL;
2523 proxy_address_v[0] = NULL;
2524 mail_v[0] = NULL;
2525 legacy_exchange_dn_v[0] = mail;
2526 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2527 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2528 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2529 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2530 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2531 }
2532 }
2533 else
2534 {
2535 if(atoi(maillist) && email_isvalid(contact_mail))
2536 {
2537 mail_v[0] = contact_mail;
2538 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2539 }
2540 }
2541
9db0b148 2542 mods[n] = NULL;
df2a74ce 2543
f75f605a 2544 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
78af4e6e 2545 {
df2a74ce 2546 com_err(whoami, 0,
2547 "Unable to modify list data for %s after renaming: %s",
f75f605a 2548 after_group_name, ldap_err2string(rc));
78af4e6e 2549 }
df2a74ce 2550
9db0b148 2551 for (i = 0; i < n; i++)
2552 free(mods[i]);
df2a74ce 2553
f75f605a 2554 return(rc);
9db0b148 2555}
2556
cd9e6b16 2557int group_create(int ac, char **av, void *ptr)
2558{
2559 LDAPMod *mods[20];
2560 char new_dn[256];
2561 char group_ou[256];
2562 char new_group_name[256];
2563 char sam_group_name[256];
2564 char cn_group_name[256];
df2a74ce 2565 char mail[256];
2566 char contact_mail[256];
2567 char mail_nickname[256];
2568 char proxy_address[256];
2569 char address_book[256];
cd9e6b16 2570 char *cn_v[] = {NULL, NULL};
2571 char *objectClass_v[] = {"top", "group", NULL};
2572 char info[256];
2573 char *samAccountName_v[] = {NULL, NULL};
cd9e6b16 2574 char *altSecurityIdentities_v[] = {NULL, NULL};
89db421e 2575 char *member_v[] = {NULL, NULL};
cd9e6b16 2576 char *name_v[] = {NULL, NULL};
2577 char *desc_v[] = {NULL, NULL};
2578 char *info_v[] = {NULL, NULL};
89db421e 2579 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 2580 char *groupTypeControl_v[] = {NULL, NULL};
df2a74ce 2581 char *mail_v[] = {NULL, NULL};
2582 char *proxy_address_v[] = {NULL, NULL};
2583 char *mail_nickname_v[] = {NULL, NULL};
2584 char *reportToOriginator_v[] = {NULL, NULL};
2585 char *address_book_v[] = {NULL, NULL};
2586 char *legacy_exchange_dn_v[] = {NULL, NULL};
cd9e6b16 2587 char groupTypeControlStr[80];
2588 char group_membership[1];
2589 int i;
2590 int security_flag;
df2a74ce 2591 u_int groupTypeControl;
cd9e6b16 2592 int n;
2593 int rc;
89db421e 2594 int updateGroup;
df2a74ce 2595 int MailDisabled;
cd9e6b16 2596 char **call_args;
2597
2598 call_args = ptr;
2599
df2a74ce 2600 if(UseGroupUniversal)
2601 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2602 else
2603 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2604
cd9e6b16 2605 if (!check_string(av[L_NAME]))
78af4e6e 2606 {
df2a74ce 2607 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2608 av[L_NAME]);
89db421e 2609 return(AD_INVALID_NAME);
78af4e6e 2610 }
f75f605a 2611
89db421e 2612 updateGroup = (int)call_args[4];
df2a74ce 2613 MailDisabled = atoi(call_args[6]);
cd9e6b16 2614 memset(group_ou, 0, sizeof(group_ou));
2615 memset(group_membership, 0, sizeof(group_membership));
2616 security_flag = 0;
df2a74ce 2617
cd9e6b16 2618 get_group_membership(group_membership, group_ou, &security_flag, av);
df2a74ce 2619
89db421e 2620 strcpy(new_group_name, av[L_NAME]);
2621 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
df2a74ce 2622 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2623 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2624 sprintf(mail_nickname, "%s", av[L_NAME]);
2625
cd9e6b16 2626 if (security_flag)
2627 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
89db421e 2628
df2a74ce 2629 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
cd9e6b16 2630
89db421e 2631 if (!updateGroup)
2632 {
89db421e 2633 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2634 groupTypeControl_v[0] = groupTypeControlStr;
cd9e6b16 2635
89db421e 2636 strcpy(cn_group_name, av[L_NAME]);
df2a74ce 2637
89db421e 2638 samAccountName_v[0] = sam_group_name;
2639 name_v[0] = new_group_name;
2640 cn_v[0] = new_group_name;
cd9e6b16 2641
89db421e 2642 n = 0;
2643 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2644 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2645 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2646 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2647 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
df2a74ce 2648
2649 if (Exchange)
2650 {
2651 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2652 {
2653 mail_nickname_v[0] = mail_nickname;
2654 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
2655 }
2656 }
2657 else
2658 {
2659 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2660 {
2661 mail_v[0] = contact_mail;
2662 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2663 }
2664 }
2665
89db421e 2666 if (strlen(av[L_DESC]) != 0)
2667 {
2668 desc_v[0] = av[L_DESC];
2669 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2670 }
df2a74ce 2671
89db421e 2672 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
df2a74ce 2673
89db421e 2674 if (strlen(av[L_ACE_NAME]) != 0)
2675 {
df2a74ce 2676 sprintf(info, "The Administrator of this list is: %s",
2677 av[L_ACE_NAME]);
89db421e 2678 info_v[0] = info;
2679 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2680 }
df2a74ce 2681
89db421e 2682 if (strlen(call_args[5]) != 0)
2683 {
2684 mitMoiraId_v[0] = call_args[5];
2685 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2686 }
89db421e 2687
df2a74ce 2688 mods[n] = NULL;
2689
89db421e 2690 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
df2a74ce 2691
89db421e 2692 for (i = 0; i < n; i++)
2693 free(mods[i]);
df2a74ce 2694
89db421e 2695 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2696 {
909e0dc3 2697 com_err(whoami, 0, "Unable to create list %s in AD : %s",
89db421e 2698 av[L_NAME], ldap_err2string(rc));
2699 callback_rc = rc;
2700 return(rc);
2701 }
78af4e6e 2702 }
df2a74ce 2703
89db421e 2704 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
5a775f54 2705 {
df2a74ce 2706 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2707 "description", av[L_NAME]);
4a6e2ee4 2708 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
df2a74ce 2709 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2710 av[L_NAME]);
5a775f54 2711 n = 0;
df2a74ce 2712
89db421e 2713 if (strlen(call_args[5]) != 0)
2714 {
2715 mitMoiraId_v[0] = call_args[5];
2716 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2717 }
df2a74ce 2718
89db421e 2719 if (!(atoi(av[L_ACTIVE])))
2720 {
2721 member_v[0] = NULL;
2722 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2723 }
df2a74ce 2724
2725 if (Exchange)
2726 {
2727 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2728 {
2729 mail_nickname_v[0] = mail_nickname;
2730 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2731 }
2732 else
2733 {
2734 mail_v[0] = NULL;
2735 mail_nickname_v[0] = NULL;
2736 proxy_address_v[0] = NULL;
2737 legacy_exchange_dn_v[0] = NULL;
2738 address_book_v[0] = NULL;
2739
2740 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2741 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2742 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2743 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2744 LDAP_MOD_REPLACE);
2745 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
2746 }
2747 }
2748 else
2749 {
2750 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2751 {
2752 mail_v[0] = contact_mail;
2753 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2754 }
2755 else
2756 {
2757 mail_v[0] = NULL;
2758 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2759 }
2760 }
2761
5a775f54 2762 mods[n] = NULL;
4a6e2ee4 2763 rc = LDAP_SUCCESS;
df2a74ce 2764
4a6e2ee4 2765 if (n != 0)
909e0dc3 2766 {
4a6e2ee4 2767 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
df2a74ce 2768
4a6e2ee4 2769 for (i = 0; i < n; i++)
2770 free(mods[i]);
df2a74ce 2771
4a6e2ee4 2772 if (rc != LDAP_SUCCESS)
2773 {
2774 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2775 av[L_NAME], ldap_err2string(rc));
2776 callback_rc = rc;
2777 return(rc);
2778 }
909e0dc3 2779 }
5a775f54 2780 }
89db421e 2781
909e0dc3 2782 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2783 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2784
5b8457c5 2785 return(LDAP_SUCCESS);
cd9e6b16 2786}
2787
df2a74ce 2788int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2789 char *TargetGroupName, int HiddenGroup,
2790 char *AceType, char *AceName)
909e0dc3 2791{
2792 char filter_exp[1024];
2793 char *attr_array[5];
2794 char search_path[512];
2795 char root_ou[128];
2796 char TemplateDn[512];
2797 char TemplateSamName[128];
2798 char TargetDn[512];
2799 char TargetSamName[128];
2800 char AceSamAccountName[128];
2801 char AceDn[256];
2802 unsigned char AceSid[128];
2803 unsigned char UserTemplateSid[128];
2804 char acBERBuf[N_SD_BER_BYTES];
2805 char GroupSecurityTemplate[256];
df2a74ce 2806 char hide_addres_lists[256];
2807 char address_book[256];
2808 char *hide_address_lists_v[] = {NULL, NULL};
2809 char *address_book_v[] = {NULL, NULL};
909e0dc3 2810 int AceSidCount;
2811 int UserTemplateSidCount;
2812 int group_count;
2813 int n;
2814 int i;
2815 int rc;
2816 int nVal;
2817 ULONG dwInfo;
2818 int array_count = 0;
2819 LDAPMod *mods[20];
2820 LK_ENTRY *group_base;
2821 LDAP_BERVAL **ppsValues;
2822 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2823 { N_SD_BER_BYTES, acBERBuf },
2824 TRUE
2825 };
2826 LDAPControl *apsServerControls[] = {&sControl, NULL};
2827 LDAPMessage *psMsg;
2828
df2a74ce 2829 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
2830 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
909e0dc3 2831 BEREncodeSecurityBits(dwInfo, acBERBuf);
2832
2833 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
df2a74ce 2834 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
909e0dc3 2835 attr_array[0] = "sAMAccountName";
2836 attr_array[1] = NULL;
2837 group_count = 0;
2838 group_base = NULL;
df2a74ce 2839
909e0dc3 2840 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
df2a74ce 2841 &group_base, &group_count,
2842 LDAP_SCOPE_SUBTREE) != 0))
909e0dc3 2843 return(1);
df2a74ce 2844
909e0dc3 2845 if (group_count != 1)
2846 {
2847 linklist_free(group_base);
2848 return(1);
2849 }
df2a74ce 2850
909e0dc3 2851 strcpy(TargetDn, group_base->dn);
2852 strcpy(TargetSamName, group_base->value);
2853 linklist_free(group_base);
2854 group_base = NULL;
2855 group_count = 0;
2856
2857 UserTemplateSidCount = 0;
2858 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2859 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2860 memset(AceSid, '\0', sizeof(AceSid));
2861 AceSidCount = 0;
2862 group_base = NULL;
2863 group_count = 0;
df2a74ce 2864
909e0dc3 2865 if (strlen(AceName) != 0)
2866 {
2867 if (!strcmp(AceType, "LIST"))
2868 {
df2a74ce 2869 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
909e0dc3 2870 strcpy(root_ou, group_ou_root);
2871 }
2872 else if (!strcmp(AceType, "USER"))
2873 {
2874 sprintf(AceSamAccountName, "%s", AceName);
2875 strcpy(root_ou, user_ou);
2876 }
df2a74ce 2877
909e0dc3 2878 if (strlen(AceSamAccountName) != 0)
2879 {
bbef4f93 2880 sprintf(search_path, "%s", dn_path);
909e0dc3 2881 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2882 attr_array[0] = "objectSid";
2883 attr_array[1] = NULL;
2884 group_count = 0;
2885 group_base = NULL;
df2a74ce 2886
2887 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2888 attr_array, &group_base, &group_count,
2889 LDAP_SCOPE_SUBTREE) != 0))
909e0dc3 2890 return(1);
2891 if (group_count == 1)
2892 {
2893 strcpy(AceDn, group_base->dn);
2894 AceSidCount = group_base->length;
2895 memcpy(AceSid, group_base->value, AceSidCount);
2896 }
2897 linklist_free(group_base);
2898 group_base = NULL;
2899 group_count = 0;
2900 }
2901 }
df2a74ce 2902
909e0dc3 2903 if (AceSidCount == 0)
2904 {
df2a74ce 2905 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
2906 "have an AD SID.", TargetGroupName, AceName, AceType);
909e0dc3 2907 com_err(whoami, 0, " Non-admin security group template will be used.");
2908 }
2909 else
2910 {
2911 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2912 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
2913 attr_array[0] = "objectSid";
2914 attr_array[1] = NULL;
2915
2916 group_count = 0;
2917 group_base = NULL;
df2a74ce 2918
2919 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2920 attr_array, &group_base, &group_count,
2921 LDAP_SCOPE_SUBTREE) != 0))
909e0dc3 2922 return(1);
df2a74ce 2923
909e0dc3 2924 if ((rc != 0) || (group_count != 1))
2925 {
df2a74ce 2926 com_err(whoami, 0, "Unable to process user security template: %s",
2927 "UserTemplate");
909e0dc3 2928 AceSidCount = 0;
2929 }
2930 else
2931 {
2932 UserTemplateSidCount = group_base->length;
2933 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
2934 }
2935 linklist_free(group_base);
2936 group_base = NULL;
2937 group_count = 0;
2938 }
2939
2940 if (HiddenGroup)
2941 {
2942 if (AceSidCount == 0)
2943 {
2944 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
2945 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
2946 }
2947 else
2948 {
2949 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
2950 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
2951 }
2952 }
2953 else
2954 {
2955 if (AceSidCount == 0)
2956 {
2957 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
2958 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
2959 }
2960 else
2961 {
2962 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
df2a74ce 2963 sprintf(filter_exp, "(sAMAccountName=%s)",
2964 NOT_HIDDEN_GROUP_WITH_ADMIN);
909e0dc3 2965 }
2966 }
2967
2968 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2969 attr_array[0] = "sAMAccountName";
2970 attr_array[1] = NULL;
2971 group_count = 0;
2972 group_base = NULL;
df2a74ce 2973
909e0dc3 2974 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
df2a74ce 2975 &group_base, &group_count,
2976 LDAP_SCOPE_SUBTREE) != 0))
909e0dc3 2977 return(1);
df2a74ce 2978
909e0dc3 2979 if (group_count != 1)
2980 {
2981 linklist_free(group_base);
df2a74ce 2982 com_err(whoami, 0, "Unable to process group security template: %s - "
2983 "security not set", GroupSecurityTemplate);
909e0dc3 2984 return(1);
2985 }
df2a74ce 2986
909e0dc3 2987 strcpy(TemplateDn, group_base->dn);
2988 strcpy(TemplateSamName, group_base->value);
2989 linklist_free(group_base);
2990 group_base = NULL;
2991 group_count = 0;
df2a74ce 2992
909e0dc3 2993 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
2994 rc = ldap_search_ext_s(ldap_handle,
2995 TemplateDn,
2996 LDAP_SCOPE_SUBTREE,
2997 filter_exp,
2998 NULL,
2999 0,
3000 apsServerControls,
3001 NULL,
3002 NULL,
3003 0,
3004 &psMsg);
3005
3006 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3007 {
df2a74ce 3008 com_err(whoami, 0, "Unable to find group security template: %s - "
3009 "security not set", GroupSecurityTemplate);
909e0dc3 3010 return(1);
3011 }
df2a74ce 3012
909e0dc3 3013 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
df2a74ce 3014
909e0dc3 3015 if (ppsValues == NULL)
3016 {
df2a74ce 3017 com_err(whoami, 0, "Unable to find group security descriptor for group "
3018 "%s - security not set", GroupSecurityTemplate);
909e0dc3 3019 return(1);
3020 }
df2a74ce 3021
909e0dc3 3022 if (AceSidCount != 0)
3023 {
3024 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3025 {
df2a74ce 3026 for (i = 0;
3027 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
909e0dc3 3028 {
df2a74ce 3029 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3030 UserTemplateSidCount))
909e0dc3 3031 {
3032 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3033 break;
3034 }
3035 }
3036 }
3037 }
3038
3039 n = 0;
df2a74ce 3040 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3041 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3042
3043 if (Exchange)
3044 {
3045 if(HiddenGroup)
3046 {
3047 hide_address_lists_v[0] = "TRUE";
3048 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3049 LDAP_MOD_REPLACE);
3050 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3051 } else {
3052 hide_address_lists_v[0] = NULL;
3053 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3054 LDAP_MOD_REPLACE);
3055 }
3056 }
3057
909e0dc3 3058 mods[n] = NULL;
3059
3060 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
df2a74ce 3061
909e0dc3 3062 for (i = 0; i < n; i++)
3063 free(mods[i]);
df2a74ce 3064
909e0dc3 3065 ldap_value_free_len(ppsValues);
3066 ldap_msgfree(psMsg);
df2a74ce 3067
909e0dc3 3068 if (rc != LDAP_SUCCESS)
3069 {
4a6e2ee4 3070 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
909e0dc3 3071 TargetGroupName, ldap_err2string(rc));
df2a74ce 3072
909e0dc3 3073 if (AceSidCount != 0)
3074 {
df2a74ce 3075 com_err(whoami, 0,
3076 "Trying to set security for group %s without admin.",
909e0dc3 3077 TargetGroupName);
df2a74ce 3078
909e0dc3 3079 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3080 HiddenGroup, "", ""))
3081 {
3082 com_err(whoami, 0, "Unable to set security for group %s.",
3083 TargetGroupName);
3084 return(rc);
3085 }
3086 }
3087 return(rc);
3088 }
df2a74ce 3089
909e0dc3 3090 return(rc);
3091}
3092
89db421e 3093int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3094 char *group_membership, char *MoiraId)
cd9e6b16 3095{
3096 LK_ENTRY *group_base;
f75f605a 3097 char temp[512];
89db421e 3098 char filter[128];
cd9e6b16 3099 int group_count;
3100 int rc;
3101
f75f605a 3102 if (!check_string(group_name))
78af4e6e 3103 {
df2a74ce 3104 com_err(whoami, 0,
3105 "Unable to process invalid LDAP list name %s", group_name);
89db421e 3106 return(AD_INVALID_NAME);
78af4e6e 3107 }
89db421e 3108
3109 memset(filter, '\0', sizeof(filter));
cd9e6b16 3110 group_count = 0;
3111 group_base = NULL;
cd9e6b16 3112 sprintf(temp, "%s,%s", group_ou_root, dn_path);
df2a74ce 3113
89db421e 3114 if (rc = ad_get_group(ldap_handle, temp, group_name,
3115 group_membership, MoiraId,
3116 "distinguishedName", &group_base,
3117 &group_count, filter))
3118 return(rc);
3119
cd9e6b16 3120 if (group_count == 1)
78af4e6e 3121 {
3122 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
3123 {
f75f605a 3124 linklist_free(group_base);
3125 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3126 group_name, ldap_err2string(rc));
89db421e 3127 return(rc);
78af4e6e 3128 }
f75f605a 3129 linklist_free(group_base);
78af4e6e 3130 }
3131 else
3132 {
f75f605a 3133 linklist_free(group_base);
3134 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
89db421e 3135 return(AD_NO_GROUPS_FOUND);
78af4e6e 3136 }
df2a74ce 3137
78af4e6e 3138 return(0);
cd9e6b16 3139}
3140
909e0dc3 3141int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3142{
3143 *pBuffer++ = 0x30;
3144 *pBuffer++ = 0x03;
3145 *pBuffer++ = 0x02;
3146 *pBuffer++ = 0x00;
3147 return(N_SD_BER_BYTES);
3148}
3149
f75f605a 3150int process_lists(int ac, char **av, void *ptr)
cd9e6b16 3151{
f75f605a 3152 int rc;
3153 int security_flag;
3154 char group_ou[256];
3155 char group_membership[2];
3156 char **call_args;
cd9e6b16 3157
3158 call_args = ptr;
3159
f75f605a 3160 security_flag = 0;
3161 memset(group_ou, '\0', sizeof(group_ou));
3162 memset(group_membership, '\0', sizeof(group_membership));
3163 get_group_membership(group_membership, group_ou, &security_flag, av);
3164 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
89db421e 3165 group_ou, group_membership, call_args[2],
3166 (char *)call_args[3], "");
cd9e6b16 3167 return(0);
3168}
3169
3170int member_list_build(int ac, char **av, void *ptr)
3171{
3172 LK_ENTRY *linklist;
78af4e6e 3173 char temp[1024];
cd9e6b16 3174 char **call_args;
df2a74ce 3175 char *s;
cd9e6b16 3176 call_args = ptr;
df2a74ce 3177
cd9e6b16 3178 strcpy(temp, av[ACE_NAME]);
df2a74ce 3179
cd9e6b16 3180 if (!check_string(temp))
3181 return(0);
df2a74ce 3182
f78c7eaf 3183 if (!strcmp(av[ACE_TYPE], "USER"))
cd9e6b16 3184 {
f75f605a 3185 if (!((int)call_args[3] & MOIRA_USERS))
f78c7eaf 3186 return(0);
3187 }
3188 else if (!strcmp(av[ACE_TYPE], "STRING"))
3189 {
df2a74ce 3190 if (Exchange)
3191 {
3192 if((s = strchr(temp, '@')) == (char *) NULL)
3193 {
3194 strcat(temp, "@mit.edu");
3195 }
3196
3197 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3198 {
3199 s = strrchr(temp, '.');
3200 *s = '\0';
3201 strcat(s, ".mit.edu");
3202 }
3203 }
3204
f75f605a 3205 if (!((int)call_args[3] & MOIRA_STRINGS))
f78c7eaf 3206 return(0);
df2a74ce 3207
f78c7eaf 3208 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3209 return(0);
df2a74ce 3210
cd9e6b16 3211 }
3212 else if (!strcmp(av[ACE_TYPE], "LIST"))
3213 {
f75f605a 3214 if (!((int)call_args[3] & MOIRA_LISTS))
f78c7eaf 3215 return(0);
cd9e6b16 3216 }
f78c7eaf 3217 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
cd9e6b16 3218 {
f75f605a 3219 if (!((int)call_args[3] & MOIRA_KERBEROS))
f78c7eaf 3220 return(0);
df2a74ce 3221
3222 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3223 kerberos_ou))
f78c7eaf 3224 return(0);
df2a74ce 3225
cd9e6b16 3226 }
f78c7eaf 3227 else
3228 return(0);
3229
cd9e6b16 3230 linklist = member_base;
df2a74ce 3231
cd9e6b16 3232 while (linklist)
3233 {
3234 if (!strcasecmp(temp, linklist->member))
3235 return(0);
df2a74ce 3236
cd9e6b16 3237 linklist = linklist->next;
3238 }
df2a74ce 3239
cd9e6b16 3240 linklist = calloc(1, sizeof(LK_ENTRY));
3241 linklist->op = 1;
3242 linklist->dn = NULL;
3243 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3244 strcpy(linklist->list, call_args[2]);
3245 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3246 strcpy(linklist->type, av[ACE_TYPE]);
3247 linklist->member = calloc(1, strlen(temp) + 1);
3248 strcpy(linklist->member, temp);
3249 linklist->next = member_base;
3250 member_base = linklist;
df2a74ce 3251
cd9e6b16 3252 return(0);
3253}
3254
78af4e6e 3255int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
f75f605a 3256 char *group_ou, char *group_membership, char *user_name,
89db421e 3257 char *UserOu, char *MoiraId)
78af4e6e 3258{
3259 char distinguished_name[1024];
f75f605a 3260 char *modvalues[2];
78af4e6e 3261 char temp[256];
89db421e 3262 char filter[128];
df2a74ce 3263 char *attr_array[3];
78af4e6e 3264 int group_count;
3265 int i;
3266 int n;
3267 LDAPMod *mods[20];
3268 LK_ENTRY *group_base;
3269 ULONG rc;
df2a74ce 3270 char *s;
78af4e6e 3271
3272 if (!check_string(group_name))
89db421e 3273 return(AD_INVALID_NAME);
3274
3275 memset(filter, '\0', sizeof(filter));
3276 group_base = NULL;
3277 group_count = 0;
df2a74ce 3278
89db421e 3279 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3280 group_membership, MoiraId,
3281 "distinguishedName", &group_base,
3282 &group_count, filter))
3283 return(rc);
3284
78af4e6e 3285 if (group_count != 1)
3286 {
4a6e2ee4 3287 com_err(whoami, 0, "Unable to find list %s in AD",
f75f605a 3288 group_name);
3289 linklist_free(group_base);
3290 group_base = NULL;
3291 group_count = 0;
78af4e6e 3292 goto cleanup;
3293 }
df2a74ce 3294
78af4e6e 3295 strcpy(distinguished_name, group_base->value);
3296 linklist_free(group_base);
3297 group_base = NULL;
3298 group_count = 0;
78af4e6e 3299
f75f605a 3300 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
df2a74ce 3301
f75f605a 3302 modvalues[0] = temp;
3303 modvalues[1] = NULL;
3304
3305 n = 0;
3306 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3307 mods[n] = NULL;
3308 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
df2a74ce 3309
f75f605a 3310 for (i = 0; i < n; i++)
3311 free(mods[i]);
df2a74ce 3312
6c8f12af 3313 if (rc == LDAP_UNWILLING_TO_PERFORM)
3314 rc = LDAP_SUCCESS;
df2a74ce 3315
f75f605a 3316 if (rc != LDAP_SUCCESS)
78af4e6e 3317 {
4a6e2ee4 3318 com_err(whoami, 0, "Unable to modify list %s members : %s",
f75f605a 3319 group_name, ldap_err2string(rc));
3320 goto cleanup;
78af4e6e 3321 }
3322
df2a74ce 3323 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3324 {
3325 if (Exchange)
3326 {
3327 if(!strcmp(UserOu, contact_ou) &&
3328 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3329 {
3330 memset(temp, '\0', sizeof(temp));
3331 strcpy(temp, user_name);
3332 s = strchr(temp, '@');
3333 *s = '\0';
3334
3335 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3336
3337 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3338 &group_base, &group_count,
3339 LDAP_SCOPE_SUBTREE) != 0))
3340 return(rc);
3341
3342 if(group_count)
3343 goto cleanup;
3344
3345 linklist_free(group_base);
3346 group_base = NULL;
3347 group_count = 0;
3348 }
3349
3350 sprintf(filter, "(distinguishedName=%s)", temp);
3351 attr_array[0] = "memberOf";
3352 attr_array[1] = NULL;
3353
3354 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3355 &group_base, &group_count,
3356 LDAP_SCOPE_SUBTREE) != 0))
3357 return(rc);
3358
3359
3360 if(!group_count)
3361 {
3362 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3363
3364 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3365 return(rc);
3366 }
3367 }
3368 }
3369
3370 cleanup:
78af4e6e 3371 return(rc);
3372}
3373
f75f605a 3374int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
89db421e 3375 char *group_ou, char *group_membership, char *user_name,
3376 char *UserOu, char *MoiraId)
cd9e6b16 3377{
3378 char distinguished_name[1024];
f75f605a 3379 char *modvalues[2];
cd9e6b16 3380 char temp[256];
89db421e 3381 char filter[128];
cd9e6b16 3382 int group_count;
cd9e6b16 3383 int n;
f75f605a 3384 int i;
cd9e6b16 3385 LDAPMod *mods[20];
3386 LK_ENTRY *group_base;
cd9e6b16 3387 ULONG rc;
3388
89db421e 3389 if (!check_string(group_name))
3390 return(AD_INVALID_NAME);
3391
cd9e6b16 3392 rc = 0;
89db421e 3393 memset(filter, '\0', sizeof(filter));
cd9e6b16 3394 group_base = NULL;
3395 group_count = 0;
df2a74ce 3396
89db421e 3397 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3398 group_membership, MoiraId,
3399 "distinguishedName", &group_base,
3400 &group_count, filter))
3401 return(rc);
cd9e6b16 3402
cd9e6b16 3403 if (group_count != 1)
3404 {
f75f605a 3405 linklist_free(group_base);
3406 group_base = NULL;
3407 group_count = 0;
4a6e2ee4 3408 com_err(whoami, 0, "Unable to find list %s in AD",
f75f605a 3409 group_name);
89db421e 3410 return(AD_MULTIPLE_GROUPS_FOUND);
cd9e6b16 3411 }
f75f605a 3412
cd9e6b16 3413 strcpy(distinguished_name, group_base->value);
3414 linklist_free(group_base);
3415 group_base = NULL;
3416 group_count = 0;
3417
f75f605a 3418 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3419 modvalues[0] = temp;
3420 modvalues[1] = NULL;
cd9e6b16 3421
f75f605a 3422 n = 0;
3423 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3424 mods[n] = NULL;
3425 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
df2a74ce 3426
f75f605a 3427 if (rc == LDAP_ALREADY_EXISTS)
3428 rc = LDAP_SUCCESS;
df2a74ce 3429
89db421e 3430 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3431 {
3432 if (rc == LDAP_UNWILLING_TO_PERFORM)
3433 rc = LDAP_SUCCESS;
3434 }
df2a74ce 3435
f75f605a 3436 for (i = 0; i < n; i++)
3437 free(mods[i]);
df2a74ce 3438
f75f605a 3439 if (rc != LDAP_SUCCESS)
cd9e6b16 3440 {
4a6e2ee4 3441 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
89db421e 3442 user_name, group_name, ldap_err2string(rc));
cd9e6b16 3443 }
df2a74ce 3444
f75f605a 3445 return(rc);
cd9e6b16 3446}
3447
df2a74ce 3448int contact_remove_email(LDAP *ld, char *bind_path,
3449 LK_ENTRY **linklist_base, int linklist_current)
cd9e6b16 3450{
df2a74ce 3451 LK_ENTRY *gPtr;
3452 int rc;
3453 char *mail_v[] = {NULL, NULL};
3454 LDAPMod *mods[20];
3455 int n;
3456 int i;
3457
3458 mail_v[0] = NULL;
3459
3460 n = 0;
3461 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3462 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3463 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3464 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3465 mods[n] = NULL;
3466
3467 gPtr = (*linklist_base);
3468
3469 while(gPtr) {
3470 rc = ldap_modify_s(ld, gPtr->dn, mods);
3471
3472 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3473 {
3474 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3475 gPtr->dn, ldap_err2string(rc));
3476 return(rc);
3477 }
3478
3479 gPtr = gPtr->next;
3480 }
3481
3482 for (i = 0; i < n; i++)
3483 free(mods[i]);
3484
3485 return(rc);
3486}
3487
3488int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3489{
3490 LDAPMod *mods[20];
3491 LK_ENTRY *group_base;
3492 int group_count;
3493 char new_dn[256];
3494 char cn_user_name[256];
3495 char contact_name[256];
3496 char mail_nickname[256];
3497 char proxy_address_internal[256];
3498 char proxy_address_external[256];
3499 char target_address[256];
3500 char internal_contact_name[256];
3501 char filter[128];
3502 char mail[256];
3503 char mit_address_book[256];
3504 char default_address_book[256];
3505 char contact_address_book[256];
f78c7eaf 3506 char *email_v[] = {NULL, NULL};
cd9e6b16 3507 char *cn_v[] = {NULL, NULL};
3508 char *contact_v[] = {NULL, NULL};
df2a74ce 3509 char *mail_nickname_v[] = {NULL, NULL};
3510 char *proxy_address_internal_v[] = {NULL, NULL};
3511 char *proxy_address_external_v[] = {NULL, NULL};
3512 char *target_address_v[] = {NULL, NULL};
3513 char *mit_address_book_v[] = {NULL, NULL};
3514 char *default_address_book_v[] = {NULL, NULL};
3515 char *contact_address_book_v[] = {NULL, NULL};
3516 char *hide_address_lists_v[] = {NULL, NULL};
3517 char *attr_array[3];
3518
cd9e6b16 3519 char *objectClass_v[] = {"top", "person",
3520 "organizationalPerson",
3521 "contact", NULL};
3522 char *name_v[] = {NULL, NULL};
3523 char *desc_v[] = {NULL, NULL};
df2a74ce 3524 char *s;
cd9e6b16 3525 int n;
3526 int rc;
3527 int i;
3528
3529 if (!check_string(user))
78af4e6e 3530 {
4a6e2ee4 3531 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
89db421e 3532 return(AD_INVALID_NAME);
78af4e6e 3533 }
df2a74ce 3534
3535 strcpy(mail, user);
3536 strcpy(contact_name, mail);
3537 strcpy(internal_contact_name, mail);
3538
3539 if((s = strchr(internal_contact_name, '@')) != NULL) {
3540 *s = '?';
3541 }
3542
cd9e6b16 3543 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
df2a74ce 3544 sprintf(target_address, "SMTP:%s", contact_name);
3545 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3546 sprintf(mail_nickname, "%s", internal_contact_name);
3547
cd9e6b16 3548 cn_v[0] = cn_user_name;
3549 contact_v[0] = contact_name;
3550 name_v[0] = user;
3551 desc_v[0] = "Auto account created by Moira";
df2a74ce 3552 email_v[0] = mail;
3553 proxy_address_internal_v[0] = proxy_address_internal;
3554 proxy_address_external_v[0] = proxy_address_external;
3555 mail_nickname_v[0] = mail_nickname;
3556 target_address_v[0] = target_address;
3557 mit_address_book_v[0] = mit_address_book;
3558 default_address_book_v[0] = default_address_book;
3559 contact_address_book_v[0] = contact_address_book;
cd9e6b16 3560 strcpy(new_dn, cn_user_name);
3561 n = 0;
df2a74ce 3562
cd9e6b16 3563 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3564 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3565 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3566 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3567 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
df2a74ce 3568
3569 if (Exchange)
f78c7eaf 3570 {
df2a74ce 3571 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3572 {
3573 group_count = 0;
3574 group_base = NULL;
3575
3576 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3577 attr_array[0] = "cn";
3578 attr_array[1] = NULL;
3579
3580 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3581 &group_base, &group_count,
3582 LDAP_SCOPE_SUBTREE)) != 0)
3583 {
3584 com_err(whoami, 0, "Unable to process contact %s : %s",
3585 user, ldap_err2string(rc));
3586 return(rc);
3587 }
3588
3589 if (group_count)
3590 {
3591 com_err(whoami, 0, "Object already exists with name %s",
3592 user);
3593 return(1);
3594 }
3595
3596 linklist_free(group_base);
3597 group_base = NULL;
3598 group_count = 0;
3599
3600 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3601 attr_array[0] = "cn";
3602 attr_array[1] = NULL;
3603
3604 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3605 &group_base, &group_count,
3606 LDAP_SCOPE_SUBTREE)) != 0)
3607 {
3608 com_err(whoami, 0, "Unable to process contact %s : %s",
3609 user, ldap_err2string(rc));
3610 return(rc);
3611 }
3612
3613 if (group_count)
3614 {
3615 com_err(whoami, 0, "Object already exists with name %s",
3616 user);
3617 return(1);
3618 }
3619
3620 linklist_free(group_base);
3621 group_count = 0;
3622 group_base = NULL;
3623
3624 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3625 attr_array[0] = "cn";
3626 attr_array[1] = NULL;
3627
3628 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3629 &group_base, &group_count,
3630 LDAP_SCOPE_SUBTREE)) != 0)
3631 {
3632 com_err(whoami, 0, "Unable to process contact %s : %s",
3633 user, ldap_err2string(rc));
3634 return(rc);
3635 }
3636
3637 if (group_count)
3638 {
3639 com_err(whoami, 0, "Object already exists with name %s",
3640 user);
3641 return(1);
3642 }
3643
3644 linklist_free(group_base);
3645 group_base = NULL;
3646 group_count = 0;
3647
3648 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3649 attr_array[0] = "cn";
3650 attr_array[1] = NULL;
3651
3652 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3653 &group_base, &group_count,
3654 LDAP_SCOPE_SUBTREE)) != 0)
3655 {
3656 com_err(whoami, 0, "Unable to process contact %s : %s",
3657 user, ldap_err2string(rc));
3658 return(rc);
3659 }
3660
3661 if (group_count)
3662 {
3663 com_err(whoami, 0, "Object already exists with name %s",
3664 user);
3665 return(1);
3666 }
3667
3668 linklist_free(group_base);
3669 group_base = NULL;
3670 group_count = 0;
3671
3672 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3673 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3674 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3675 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3676
3677 hide_address_lists_v[0] = "TRUE";
3678 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3679 LDAP_MOD_ADD);
3680 }
f78c7eaf 3681 }
df2a74ce 3682
cd9e6b16 3683 mods[n] = NULL;
3684
3685 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
df2a74ce 3686
cd9e6b16 3687 for (i = 0; i < n; i++)
3688 free(mods[i]);
df2a74ce 3689
3690 if (Exchange)
3691 {
3692 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS))
3693 {
3694 n = 0;
3695
3696 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
3697 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
3698 ADD_ATTR("proxyAddresses", proxy_address_external_v,
3699 LDAP_MOD_REPLACE);
3700 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
3701
3702 hide_address_lists_v[0] = "TRUE";
3703 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3704 LDAP_MOD_REPLACE);
3705
3706 mods[n] = NULL;
3707 rc = ldap_modify_s(ld, new_dn, mods);
3708
3709 if (rc)
3710 {
3711 com_err(whoami, 0, "Unable to update contact %s", mail);
3712 }
3713
3714 for (i = 0; i < n; i++)
3715 free(mods[i]);
3716 }
3717 }
3718
f78c7eaf 3719 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3720 {
3721 n = 0;
3722 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3723 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3724 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3725 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3726 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3727 mods[n] = NULL;
3728 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
df2a74ce 3729
f78c7eaf 3730 for (i = 0; i < n; i++)
3731 free(mods[i]);
3732 }
df2a74ce 3733
cd9e6b16 3734 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
78af4e6e 3735 {
4a6e2ee4 3736 com_err(whoami, 0, "Unable to create contact %s : %s",
f75f605a 3737 user, ldap_err2string(rc));
89db421e 3738 return(rc);
78af4e6e 3739 }
df2a74ce 3740
78af4e6e 3741 return(0);
3742}
3743
f75f605a 3744int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3abb4456 3745 char *Uid, char *MitId, char *MoiraId, int State,
df2a74ce 3746 char *WinHomeDir, char *WinProfileDir, char *first,
3747 char *middle, char *last)
78af4e6e 3748{
3749 LDAPMod *mods[20];
3750 LK_ENTRY *group_base;
3751 int group_count;
3abb4456 3752 char distinguished_name[512];
df2a74ce 3753 char displayName[256];
89db421e 3754 char *mitMoiraId_v[] = {NULL, NULL};
78af4e6e 3755 char *uid_v[] = {NULL, NULL};
3756 char *mitid_v[] = {NULL, NULL};
f78c7eaf 3757 char *homedir_v[] = {NULL, NULL};
3758 char *winProfile_v[] = {NULL, NULL};
3759 char *drives_v[] = {NULL, NULL};
89db421e 3760 char *userAccountControl_v[] = {NULL, NULL};
df2a74ce 3761 char *alt_recipient_v[] = {NULL, NULL};
3762 char *hide_address_lists_v[] = {NULL, NULL};
3763 char *mail_v[] = {NULL, NULL};
89db421e 3764 char userAccountControlStr[80];
78af4e6e 3765 int n;
3766 int rc;
3767 int i;
3abb4456 3768 int OldUseSFU30;
df2a74ce 3769 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
3770 UF_PASSWD_CANT_CHANGE;
89db421e 3771 char filter[128];
78af4e6e 3772 char *attr_array[3];
c0bd7667 3773 char temp[256];
df2a74ce 3774 char mail[256];
3775 char contact_mail[256];
3776 char filter_exp[1024];
3777 char search_path[512];
3778 char TemplateDn[512];
3779 char TemplateSamName[128];
3780 char alt_recipient[256];
3781 char acBERBuf[N_SD_BER_BYTES];
3782 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3783 { N_SD_BER_BYTES, acBERBuf },
3784 TRUE};
3785 LDAPControl *apsServerControls[] = {&sControl, NULL};
3786 LDAPMessage *psMsg;
3787 LDAP_BERVAL **ppsValues;
3788 ULONG dwInfo;
3789 char *argv[3];
3790 char *homeMDB;
3791 char *homeServerName;
3792 char *save_argv[7];
3793 char search_string[256];
3794
3795 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3796 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3797 BEREncodeSecurityBits(dwInfo, acBERBuf);
78af4e6e 3798
f75f605a 3799 if (!check_string(user_name))
78af4e6e 3800 {
df2a74ce 3801 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
3802 user_name);
89db421e 3803 return(AD_INVALID_NAME);
78af4e6e 3804 }
df2a74ce 3805
3806 memset(contact_mail, '\0', sizeof(contact_mail));
3807 sprintf(contact_mail, "%s@mit.edu", user_name);
3808 memset(mail, '\0', sizeof(mail));
3809 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
3810 memset(alt_recipient, '\0', sizeof(alt_recipient));
3811 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
3812 dn_path);
3813 sprintf(search_string, "@%s", uppercase(ldap_domain));
3814
3815 if (Exchange)
3816 {
3817 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
3818 {
3819 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
3820 }
3821 }
78af4e6e 3822
78af4e6e 3823 group_count = 0;
3824 group_base = NULL;
89db421e 3825
df2a74ce 3826 memset(displayName, '\0', sizeof(displayName));
3827
89db421e 3828 if (strlen(MoiraId) != 0)
78af4e6e 3829 {
c0bd7667 3830 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 3831 attr_array[0] = "cn";
3832 attr_array[1] = NULL;
3833 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 3834 &group_base, &group_count,
3835 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 3836 {
4a6e2ee4 3837 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 3838 user_name, ldap_err2string(rc));
3839 return(rc);
3840 }
3841 }
df2a74ce 3842
c0bd7667 3843 if (group_count != 1)
89db421e 3844 {
c0bd7667 3845 linklist_free(group_base);
3846 group_base = NULL;
3847 group_count = 0;
89db421e 3848 sprintf(filter, "(sAMAccountName=%s)", user_name);
3849 attr_array[0] = "cn";
3850 attr_array[1] = NULL;
c0bd7667 3851 sprintf(temp, "%s,%s", user_ou, dn_path);
3852 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
df2a74ce 3853 &group_base, &group_count,
3854 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 3855 {
4a6e2ee4 3856 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 3857 user_name, ldap_err2string(rc));
3858 return(rc);
3859 }
78af4e6e 3860 }
3861
3862 if (group_count != 1)
3863 {
4a6e2ee4 3864 com_err(whoami, 0, "Unable to find user %s in AD",
f75f605a 3865 user_name);
3866 linklist_free(group_base);
89db421e 3867 return(AD_NO_USER_FOUND);
78af4e6e 3868 }
df2a74ce 3869
78af4e6e 3870 strcpy(distinguished_name, group_base->dn);
3871
f75f605a 3872 linklist_free(group_base);
3873 group_count = 0;
4a6e2ee4 3874
7dc865bd 3875 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
df2a74ce 3876 rc = attribute_update(ldap_handle, distinguished_name, MitId,
3877 "employeeID", user_name);
3878 else
3879 rc = attribute_update(ldap_handle, distinguished_name, "none",
3880 "employeeID", user_name);
3881
3882 if(strlen(first)) {
3883 strcat(displayName, first);
3884 }
3885
3886 if(strlen(middle)) {
3887 if(strlen(first))
3888 strcat(displayName, " ");
3889
3890 strcat(displayName, middle);
3891 }
3892
3893 if(strlen(last)) {
3894 if(strlen(middle) || strlen(first))
3895 strcat(displayName, " ");
3896
3897 strcat(displayName, last);
3898 }
3899
3900 if(strlen(displayName))
3901 rc = attribute_update(ldap_handle, distinguished_name, displayName,
3902 "displayName", user_name);
3903 else
3904 rc = attribute_update(ldap_handle, distinguished_name, user_name,
3905 "displayName", user_name);
3906
3907 if(strlen(first))
3908 rc = attribute_update(ldap_handle, distinguished_name, first,
3909 "givenName", user_name);
7dc865bd 3910 else
df2a74ce 3911 rc = attribute_update(ldap_handle, distinguished_name, "",
3912 "givenName", user_name);
3913
3914 if(strlen(middle) == 1)
3915 rc = attribute_update(ldap_handle, distinguished_name, middle,
3916 "initials", user_name);
3917 else
3918 rc = attribute_update(ldap_handle, distinguished_name, "",
3919 "initials", user_name);
3920
3921 if(strlen(last))
3922 rc = attribute_update(ldap_handle, distinguished_name, last,
3923 "sn", user_name);
3924 else
3925 rc = attribute_update(ldap_handle, distinguished_name, "",
3926 "sn", user_name);
3927
3928 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
3929 user_name);
3930 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
3931 "mitMoiraId", user_name);
4a6e2ee4 3932
78af4e6e 3933 n = 0;
50b4a32b 3934 uid_v[0] = Uid;
df2a74ce 3935
3abb4456 3936 if (!UseSFU30)
3937 {
3938 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
3939 }
3940 else
3941 {
3942 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
3943 }
4a6e2ee4 3944
89db421e 3945 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
df2a74ce 3946 {
3947 userAccountControl |= UF_ACCOUNTDISABLE;
3948
3949 if (Exchange)
3950 {
3951 hide_address_lists_v[0] = "TRUE";
3952 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3953 LDAP_MOD_REPLACE);
3954 }
3955 }
3956 else
3957 {
3958 if (Exchange)
3959 {
3960 hide_address_lists_v[0] = NULL;
3961 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3962 LDAP_MOD_REPLACE);
3963 }
3964 }
3965
89db421e 3966 sprintf(userAccountControlStr, "%ld", userAccountControl);
3967 userAccountControl_v[0] = userAccountControlStr;
3968 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
3abb4456 3969
df2a74ce 3970 if (Exchange)
3971 {
3972 if (rc = moira_connect())
3973 {
3974 critical_alert("AD incremental",
3975 "Error contacting Moira server : %s",
3976 error_message(rc));
3977 return;
3978 }
3979
3980 argv[0] = user_name;
3981
3982 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
3983 {
3984 if(!strcmp(save_argv[1], "EXCHANGE") ||
3985 (strstr(save_argv[3], search_string) != NULL))
3986 {
3987 alt_recipient_v[0] = NULL;
3988 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
3989
3990 argv[0] = exchange_acl;
3991 argv[1] = "USER";
3992 argv[2] = user_name;
3993
3994 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
3995
3996 if ((rc) && (rc != MR_EXISTS))
3997 {
3998 com_err(whoami, 0, "Unable to add user %s to %s: %s",
3999 user_name, exchange_acl, error_message(rc));
4000 }
4001 }
4002 else
4003 {
4004 alt_recipient_v[0] = alt_recipient;
4005 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4006
4007 argv[0] = exchange_acl;
4008 argv[1] = "USER";
4009 argv[2] = user_name;
4010
4011 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4012
4013 if ((rc) && (rc != MR_NO_MATCH))
4014 {
4015 com_err(whoami, 0,
4016 "Unable to remove user %s from %s: %s, %d",
4017 user_name, exchange_acl, error_message(rc), rc);
4018 }
4019 }
4020 }
4021 else
4022 {
4023 alt_recipient_v[0] = alt_recipient;
4024 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4025
4026 argv[0] = exchange_acl;
4027 argv[1] = "USER";
4028 argv[2] = user_name;
4029
4030 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4031
4032 if ((rc) && (rc != MR_NO_MATCH))
4033 {
4034 com_err(whoami, 0,
4035 "Unable to remove user %s from %s: %s, %d",
4036 user_name, exchange_acl, error_message(rc), rc);
4037 }
4038 }
4039
4040 moira_disconnect();
4041 }
4042 else
4043 {
4044 mail_v[0] = contact_mail;
4045 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4046 }
4047
3abb4456 4048 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4049 WinProfileDir, homedir_v, winProfile_v,
4050 drives_v, mods, LDAP_MOD_REPLACE, n);
4051
df2a74ce 4052 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4053 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4054 attr_array[0] = "sAMAccountName";
4055 attr_array[1] = NULL;
4056 group_count = 0;
4057 group_base = NULL;
4058
4059 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
4060 &group_base, &group_count,
4061 LDAP_SCOPE_SUBTREE) != 0))
4062 return(1);
4063
4064 if (group_count != 1)
4065 {
4066 com_err(whoami, 0, "Unable to process user security template: %s - "
4067 "security not set", "UserTemplate.u");
4068 return(1);
4069 }
4070
4071 strcpy(TemplateDn, group_base->dn);
4072 strcpy(TemplateSamName, group_base->value);
4073 linklist_free(group_base);
4074 group_base = NULL;
4075 group_count = 0;
4076
4077 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4078 filter_exp, NULL, 0, apsServerControls, NULL,
4079 NULL, 0, &psMsg);
4080
4081 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4082 {
4083 com_err(whoami, 0, "Unable to find user security template: %s - "
4084 "security not set", "UserTemplate.u");
4085 return(1);
4086 }
4087
4088 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
4089
4090 if (ppsValues == NULL)
4091 {
4092 com_err(whoami, 0, "Unable to find user security template: %s - "
4093 "security not set", "UserTemplate.u");
4094 return(1);
4095 }
4096
4097 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4098 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4099
78af4e6e 4100 mods[n] = NULL;
df2a74ce 4101
4102 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4103 mods)) != LDAP_SUCCESS)
78af4e6e 4104 {
df2a74ce 4105 OldUseSFU30 = UseSFU30;
4106 SwitchSFU(mods, &UseSFU30, n);
4107 if (OldUseSFU30 != UseSFU30)
4108 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4109 if (rc)
f78c7eaf 4110 {
df2a74ce 4111 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4112 user_name, ldap_err2string(rc));
f78c7eaf 4113 }
4114 }
df2a74ce 4115
3abb4456 4116 for (i = 0; i < n; i++)
4117 free(mods[i]);
df2a74ce 4118
f75f605a 4119 return(rc);
cd9e6b16 4120}
4121
f75f605a 4122int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
89db421e 4123 char *user_name)
9db0b148 4124{
4125 LDAPMod *mods[20];
4126 char new_dn[256];
4127 char old_dn[256];
9db0b148 4128 char upn[256];
df2a74ce 4129 char mail[256];
4130 char contact_mail[256];
4131 char proxy_address[256];
4132 char query_base_dn[256];
4133 char temp[256];
9db0b148 4134 char *userPrincipalName_v[] = {NULL, NULL};
4135 char *altSecurityIdentities_v[] = {NULL, NULL};
4136 char *name_v[] = {NULL, NULL};
78af4e6e 4137 char *samAccountName_v[] = {NULL, NULL};
df2a74ce 4138 char *mail_v[] = {NULL, NULL};
4139 char *mail_nickname_v[] = {NULL, NULL};
4140 char *proxy_address_v[] = {NULL, NULL};
4141 char *query_base_dn_v[] = {NULL, NULL};
9db0b148 4142 int n;
4143 int rc;
4144 int i;
9db0b148 4145
f75f605a 4146 if (!check_string(before_user_name))
78af4e6e 4147 {
df2a74ce 4148 com_err(whoami, 0,
4149 "Unable to process invalid LDAP user name %s", before_user_name);
89db421e 4150 return(AD_INVALID_NAME);
78af4e6e 4151 }
df2a74ce 4152
f75f605a 4153 if (!check_string(user_name))
78af4e6e 4154 {
df2a74ce 4155 com_err(whoami, 0,
4156 "Unable to process invalid LDAP user name %s", user_name);
89db421e 4157 return(AD_INVALID_NAME);
78af4e6e 4158 }
9db0b148 4159
f75f605a 4160 strcpy(user_name, user_name);
4161 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
9db0b148 4162 sprintf(new_dn, "cn=%s", user_name);
df2a74ce 4163 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4164 sprintf(contact_mail, "%s@mit.edu", user_name);
4165 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4166
f75f605a 4167 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
9db0b148 4168 NULL, NULL)) != LDAP_SUCCESS)
4169 {
4a6e2ee4 4170 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
89db421e 4171 before_user_name, user_name, ldap_err2string(rc));
f75f605a 4172 return(rc);
9db0b148 4173 }
4174
df2a74ce 4175 if (Exchange)
4176 {
4177 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4178 dn_path);
4179
4180 if(rc = ldap_delete_s(ldap_handle, temp))
4181 {
4182 com_err(whoami, 0, "Unable to delete user contact for %s",
4183 user_name);
4184 }
4185
4186 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4187 {
4188 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4189 }
4190 }
4191
9db0b148 4192 name_v[0] = user_name;
4193 sprintf(upn, "%s@%s", user_name, ldap_domain);
4194 userPrincipalName_v[0] = upn;
4195 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
df2a74ce 4196 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
9db0b148 4197 altSecurityIdentities_v[0] = temp;
78af4e6e 4198 samAccountName_v[0] = user_name;
df2a74ce 4199 mail_v[0] = mail;
4200 mail_nickname_v[0] = user_name;
4201 proxy_address_v[0] = proxy_address;
4202 query_base_dn_v[0] = query_base_dn;
9db0b148 4203
4204 n = 0;
4205 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4206 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4207 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
78af4e6e 4208 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
df2a74ce 4209
4210 if (Exchange)
4211 {
4212 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4213 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4214 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4215 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4216 }
4217 else
4218 {
4219 mail_v[0] = contact_mail;
4220 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4221 }
4222
9db0b148 4223 mods[n] = NULL;
df2a74ce 4224
f75f605a 4225 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
df2a74ce 4226
f75f605a 4227 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
9db0b148 4228 {
df2a74ce 4229 com_err(whoami, 0,
4230 "Unable to modify user data for %s after renaming : %s",
f75f605a 4231 user_name, ldap_err2string(rc));
9db0b148 4232 }
df2a74ce 4233
9db0b148 4234 for (i = 0; i < n; i++)
4235 free(mods[i]);
df2a74ce 4236
f75f605a 4237 return(rc);
9db0b148 4238}
4239
cd9e6b16 4240int user_create(int ac, char **av, void *ptr)
4241{
4242 LDAPMod *mods[20];
4243 char new_dn[256];
4244 char user_name[256];
9db0b148 4245 char sam_name[256];
5b8457c5 4246 char upn[256];
df2a74ce 4247 char mail[256];
4248 char contact_mail[256];
4249 char proxy_address[256];
4250 char mail_nickname[256];
4251 char query_base_dn[256];
4252 char displayName[256];
4253 char address_book[256];
4254 char alt_recipient[256];
cd9e6b16 4255 char *cn_v[] = {NULL, NULL};
4256 char *objectClass_v[] = {"top", "person",
4257 "organizationalPerson",
4258 "user", NULL};
4259
4260 char *samAccountName_v[] = {NULL, NULL};
4261 char *altSecurityIdentities_v[] = {NULL, NULL};
89db421e 4262 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 4263 char *name_v[] = {NULL, NULL};
4264 char *desc_v[] = {NULL, NULL};
cd9e6b16 4265 char *userPrincipalName_v[] = {NULL, NULL};
4266 char *userAccountControl_v[] = {NULL, NULL};
78af4e6e 4267 char *uid_v[] = {NULL, NULL};
4268 char *mitid_v[] = {NULL, NULL};
3abb4456 4269 char *homedir_v[] = {NULL, NULL};
4270 char *winProfile_v[] = {NULL, NULL};
4271 char *drives_v[] = {NULL, NULL};
df2a74ce 4272 char *mail_v[] = {NULL, NULL};
4273 char *givenName_v[] = {NULL, NULL};
4274 char *sn_v[] = {NULL, NULL};
4275 char *initials_v[] = {NULL, NULL};
4276 char *displayName_v[] = {NULL, NULL};
4277 char *proxy_address_v[] = {NULL, NULL};
4278 char *mail_nickname_v[] = {NULL, NULL};
4279 char *query_base_dn_v[] = {NULL, NULL};
4280 char *address_book_v[] = {NULL, NULL};
4281 char *homeMDB_v[] = {NULL, NULL};
4282 char *homeServerName_v[] = {NULL, NULL};
4283 char *mdbUseDefaults_v[] = {NULL, NULL};
4284 char *mailbox_guid_v[] = {NULL, NULL};
4285 char *user_culture_v[] = {NULL, NULL};
4286 char *user_account_control_v[] = {NULL, NULL};
4287 char *msexch_version_v[] = {NULL, NULL};
4288 char *alt_recipient_v[] = {NULL, NULL};
4289 char *hide_address_lists_v[] = {NULL, NULL};
cd9e6b16 4290 char userAccountControlStr[80];
4291 char temp[128];
df2a74ce 4292 char filter_exp[1024];
4293 char search_path[512];
4294 char *attr_array[3];
4295 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4296 UF_PASSWD_CANT_CHANGE;
cd9e6b16 4297 int n;
4298 int rc;
4299 int i;
3abb4456 4300 int OldUseSFU30;
cd9e6b16 4301 char **call_args;
3abb4456 4302 char WinHomeDir[1024];
4303 char WinProfileDir[1024];
df2a74ce 4304 char *homeMDB;
4305 char *homeServerName;
4306 ULONG dwInfo;
4307 char acBERBuf[N_SD_BER_BYTES];
4308 LK_ENTRY *group_base;
4309 int group_count;
4310 char TemplateDn[512];
4311 char TemplateSamName[128];
4312 LDAP_BERVAL **ppsValues;
4313 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4314 { N_SD_BER_BYTES, acBERBuf },
4315 TRUE};
4316 LDAPControl *apsServerControls[] = {&sControl, NULL};
4317 LDAPMessage *psMsg;
4318 char *argv[3];
4319 char *save_argv[7];
4320 char search_string[256];
cd9e6b16 4321
4322 call_args = ptr;
4323
df2a74ce 4324 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4325 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4326 BEREncodeSecurityBits(dwInfo, acBERBuf);
4327
78af4e6e 4328 if (!check_string(av[U_NAME]))
4329 {
89db421e 4330 callback_rc = AD_INVALID_NAME;
df2a74ce 4331 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4332 av[U_NAME]);
89db421e 4333 return(AD_INVALID_NAME);
78af4e6e 4334 }
9db0b148 4335
3abb4456 4336 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4337 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
df2a74ce 4338 memset(displayName, '\0', sizeof(displayName));
4339 memset(query_base_dn, '\0', sizeof(query_base_dn));
3abb4456 4340 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4341 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
cd9e6b16 4342 strcpy(user_name, av[U_NAME]);
4343 sprintf(upn, "%s@%s", user_name, ldap_domain);
78af4e6e 4344 sprintf(sam_name, "%s", av[U_NAME]);
df2a74ce 4345
4346 if(strlen(av[U_FIRST])) {
4347 strcat(displayName, av[U_FIRST]);
4348 }
4349
4350 if(strlen(av[U_MIDDLE])) {
4351 if(strlen(av[U_FIRST]))
4352 strcat(displayName, " ");
4353
4354 strcat(displayName, av[U_MIDDLE]);
4355 }
4356
4357 if(strlen(av[U_LAST])) {
4358 if(strlen(av[U_FIRST]) || strlen(av[U_LAST]))
4359 strcat(displayName, " ");
4360
4361 strcat(displayName, av[U_LAST]);
4362 }
4363
9db0b148 4364 samAccountName_v[0] = sam_name;
df2a74ce 4365 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4366 (atoi(av[U_STATE]) != US_REGISTERED))
4367 {
4368 userAccountControl |= UF_ACCOUNTDISABLE;
4369
4370 if (Exchange)
4371 {
4372 hide_address_lists_v[0] = "TRUE";
4373 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4374 LDAP_MOD_ADD);
4375 }
4376 }
4377
cd9e6b16 4378 sprintf(userAccountControlStr, "%ld", userAccountControl);
4379 userAccountControl_v[0] = userAccountControlStr;
4380 userPrincipalName_v[0] = upn;
cd9e6b16 4381 cn_v[0] = user_name;
4382 name_v[0] = user_name;
4383 desc_v[0] = "Auto account created by Moira";
df2a74ce 4384 mail_v[0] = mail;
4385 givenName_v[0] = av[U_FIRST];
4386 sn_v[0] = av[U_LAST];
4387 displayName_v[0] = displayName;
4388 mail_nickname_v[0] = user_name;
4389
cd9e6b16 4390 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4391 altSecurityIdentities_v[0] = temp;
4392 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
df2a74ce 4393 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4394 sprintf(contact_mail, "%s@mit.edu", user_name);
4395 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4396 query_base_dn_v[0] = query_base_dn;
4397 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4398 call_args[1]);
4399 sprintf(search_string, "@%s", uppercase(ldap_domain));
4400
4401
4402 if (Exchange)
4403 {
4404 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4405 contact_ou))
4406 {
4407 com_err(whoami, 0, "Unable to create user contact %s",
4408 contact_mail);
4409 }
4410
4411 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4412 &homeServerName))
4413 {
4414 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4415 return(1);
4416 }
4417
4418 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4419 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4420
4421 homeMDB_v[0] = homeMDB;
4422 homeServerName_v[0] = homeServerName;
4423 }
cd9e6b16 4424
4425 n = 0;
4426 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4427 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4428 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
4429 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
4430 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
4431 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
cd9e6b16 4432 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
df2a74ce 4433
4434 if (Exchange)
4435 {
4436 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
4437 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4438 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
4439 mdbUseDefaults_v[0] = "TRUE";
4440 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
4441 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
4442
4443 argv[0] = user_name;
4444
4445 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4446 {
4447 if(!strcmp(save_argv[1], "EXCHANGE") ||
4448 (strstr(save_argv[3], search_string) != NULL))
4449 {
4450 argv[0] = exchange_acl;
4451 argv[1] = "USER";
4452 argv[2] = user_name;
4453
4454 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4455
4456 if ((rc) && (rc != MR_EXISTS))
4457 {
4458 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4459 user_name, exchange_acl, error_message(rc));
4460 }
4461 }
4462 else
4463 {
4464 alt_recipient_v[0] = alt_recipient;
4465 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4466 }
4467 }
4468 else
4469 {
4470 alt_recipient_v[0] = alt_recipient;
4471 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4472
4473 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
4474 }
4475 }
4476 else
4477 {
4478 mail_v[0] = contact_mail;
4479 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
4480 }
4481
4482 if(strlen(av[U_FIRST])) {
4483 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
4484 }
4485
4486 if(strlen(av[U_LAST])) {
4487 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
4488 }
4489
4490 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
4491 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
4492 } else {
4493 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4494 }
4495
4496 if (strlen(av[U_MIDDLE]) == 1) {
4497 initials_v[0] = av[U_MIDDLE];
4498 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
4499 }
4500
4501 if (strlen(call_args[2]) != 0)
89db421e 4502 {
4503 mitMoiraId_v[0] = call_args[2];
df2a74ce 4504 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
89db421e 4505 }
df2a74ce 4506
4507 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
4508
78af4e6e 4509 if (strlen(av[U_UID]) != 0)
4510 {
4511 uid_v[0] = av[U_UID];
4512 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
df2a74ce 4513
3abb4456 4514 if (!UseSFU30)
4515 {
4516 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
4517 }
4518 else
4519 {
4520 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
4521 }
78af4e6e 4522 }
df2a74ce 4523
7dc865bd 4524 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
78af4e6e 4525 mitid_v[0] = av[U_MITID];
4526 else
4527 mitid_v[0] = "none";
df2a74ce 4528
78af4e6e 4529 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
3abb4456 4530
4531 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
4532 WinProfileDir, homedir_v, winProfile_v,
4533 drives_v, mods, LDAP_MOD_ADD, n);
4534
df2a74ce 4535 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4536 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
4537 attr_array[0] = "sAMAccountName";
4538 attr_array[1] = NULL;
4539 group_count = 0;
4540 group_base = NULL;
4541
4542 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
4543 attr_array, &group_base, &group_count,
4544 LDAP_SCOPE_SUBTREE) != 0))
4545 return(1);
4546
4547 if (group_count != 1)
4548 {
4549 com_err(whoami, 0, "Unable to process user security template: %s - "
4550 "security not set", "UserTemplate.u");
4551 return(1);
4552 }
4553
4554 strcpy(TemplateDn, group_base->dn);
4555 strcpy(TemplateSamName, group_base->value);
4556 linklist_free(group_base);
4557 group_base = NULL;
4558 group_count = 0;
4559
4560 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE,
4561 filter_exp, NULL, 0, apsServerControls, NULL,
4562 NULL, 0, &psMsg);
4563
4564 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
4565 {
4566 com_err(whoami, 0, "Unable to find user security template: %s - "
4567 "security not set", "UserTemplate.u");
4568 return(1);
4569 }
4570
4571 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
4572 "ntSecurityDescriptor");
4573 if (ppsValues == NULL)
4574 {
4575 com_err(whoami, 0, "Unable to find user security template: %s - "
4576 "security not set", "UserTemplate.u");
4577 return(1);
4578 }
4579
4580 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4581 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4582
cd9e6b16 4583 mods[n] = NULL;
4584
4585 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
df2a74ce 4586
3abb4456 4587 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
df2a74ce 4588 {
3abb4456 4589 OldUseSFU30 = UseSFU30;
4590 SwitchSFU(mods, &UseSFU30, n);
4591 if (OldUseSFU30 != UseSFU30)
df2a74ce 4592 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4593 }
3abb4456 4594
78af4e6e 4595 for (i = 0; i < n; i++)
4596 free(mods[i]);
df2a74ce 4597
5b8457c5 4598 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4599 {
4a6e2ee4 4600 com_err(whoami, 0, "Unable to create user %s : %s",
5b8457c5 4601 user_name, ldap_err2string(rc));
4602 callback_rc = rc;
4603 return(rc);
4604 }
df2a74ce 4605
4606 if ((rc == LDAP_SUCCESS) && (SetPassword))
cd9e6b16 4607 {
f78c7eaf 4608 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
cd9e6b16 4609 {
26503e15 4610 ad_kdc_disconnect();
26503e15 4611 if (!ad_server_connect(default_server, ldap_domain))
4612 {
4613 com_err(whoami, 0, "Unable to set password for user %s : %s",
df2a74ce 4614 user_name,
4615 "cannot get changepw ticket from windows domain");
26503e15 4616 }
4617 else
4618 {
4619 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4620 {
df2a74ce 4621 com_err(whoami, 0, "Unable to set password for user %s "
4622 ": %ld", user_name, rc);
26503e15 4623 }
4624 }
cd9e6b16 4625 }
4626 }
df2a74ce 4627
78af4e6e 4628 return(0);
cd9e6b16 4629}
4630
89db421e 4631int user_change_status(LDAP *ldap_handle, char *dn_path,
4632 char *user_name, char *MoiraId,
4633 int operation)
cd9e6b16 4634{
89db421e 4635 char filter[128];
cd9e6b16 4636 char *attr_array[3];
4637 char temp[256];
4638 char distinguished_name[1024];
cd9e6b16 4639 char **modvalues;
89db421e 4640 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 4641 LDAPMod *mods[20];
4642 LK_ENTRY *group_base;
4643 int group_count;
4644 int rc;
4645 int i;
4646 int n;
4647 ULONG ulongValue;
4648
f75f605a 4649 if (!check_string(user_name))
78af4e6e 4650 {
df2a74ce 4651 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4652 user_name);
89db421e 4653 return(AD_INVALID_NAME);
78af4e6e 4654 }
f75f605a 4655
cd9e6b16 4656 group_count = 0;
4657 group_base = NULL;
89db421e 4658
4659 if (strlen(MoiraId) != 0)
cd9e6b16 4660 {
c0bd7667 4661 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 4662 attr_array[0] = "UserAccountControl";
4663 attr_array[1] = NULL;
4664 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 4665 &group_base, &group_count,
4666 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 4667 {
4a6e2ee4 4668 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 4669 user_name, ldap_err2string(rc));
4670 return(rc);
4671 }
4672 }
df2a74ce 4673
c0bd7667 4674 if (group_count != 1)
89db421e 4675 {
c0bd7667 4676 linklist_free(group_base);
4677 group_count = 0;
4678 group_base = NULL;
89db421e 4679 sprintf(filter, "(sAMAccountName=%s)", user_name);
4680 attr_array[0] = "UserAccountControl";
4681 attr_array[1] = NULL;
4682 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 4683 &group_base, &group_count,
4684 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 4685 {
4a6e2ee4 4686 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 4687 user_name, ldap_err2string(rc));
4688 return(rc);
4689 }
cd9e6b16 4690 }
df2a74ce 4691
78af4e6e 4692 if (group_count != 1)
cd9e6b16 4693 {
f75f605a 4694 linklist_free(group_base);
4a6e2ee4 4695 com_err(whoami, 0, "Unable to find user %s in AD",
f75f605a 4696 user_name);
4697 return(LDAP_NO_SUCH_OBJECT);
cd9e6b16 4698 }
4699
4700 strcpy(distinguished_name, group_base->dn);
4701 ulongValue = atoi((*group_base).value);
df2a74ce 4702
cd9e6b16 4703 if (operation == MEMBER_DEACTIVATE)
4704 ulongValue |= UF_ACCOUNTDISABLE;
4705 else
4706 ulongValue &= ~UF_ACCOUNTDISABLE;
df2a74ce 4707
cd9e6b16 4708 sprintf(temp, "%ld", ulongValue);
df2a74ce 4709
cd9e6b16 4710 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
4711 temp, &modvalues, REPLACE)) == 1)
f75f605a 4712 goto cleanup;
df2a74ce 4713
cd9e6b16 4714 linklist_free(group_base);
4715 group_base = NULL;
4716 group_count = 0;
4717 n = 0;
4718 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
df2a74ce 4719
89db421e 4720 if (strlen(MoiraId) != 0)
4721 {
4722 mitMoiraId_v[0] = MoiraId;
4723 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
4724 }
df2a74ce 4725
cd9e6b16 4726 mods[n] = NULL;
f75f605a 4727 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
df2a74ce 4728
cd9e6b16 4729 for (i = 0; i < n; i++)
4730 free(mods[i]);
df2a74ce 4731
cd9e6b16 4732 free_values(modvalues);
df2a74ce 4733
cd9e6b16 4734 if (rc != LDAP_SUCCESS)
4735 {
4a6e2ee4 4736 com_err(whoami, 0, "Unable to change status of user %s : %s",
f75f605a 4737 user_name, ldap_err2string(rc));
cd9e6b16 4738 }
df2a74ce 4739
4740 cleanup:
f75f605a 4741 return(rc);
cd9e6b16 4742}
4743
89db421e 4744int user_delete(LDAP *ldap_handle, char *dn_path,
4745 char *u_name, char *MoiraId)
cd9e6b16 4746{
89db421e 4747 char filter[128];
cd9e6b16 4748 char *attr_array[3];
4749 char distinguished_name[1024];
4750 char user_name[512];
4751 LK_ENTRY *group_base;
4752 int group_count;
4753 int rc;
df2a74ce 4754 char temp[256];
cd9e6b16 4755
4756 if (!check_string(u_name))
89db421e 4757 return(AD_INVALID_NAME);
4758
cd9e6b16 4759 strcpy(user_name, u_name);
4760 group_count = 0;
4761 group_base = NULL;
89db421e 4762
4763 if (strlen(MoiraId) != 0)
cd9e6b16 4764 {
c0bd7667 4765 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 4766 attr_array[0] = "name";
4767 attr_array[1] = NULL;
4768 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 4769 &group_base, &group_count,
4770 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 4771 {
4a6e2ee4 4772 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 4773 user_name, ldap_err2string(rc));
4774 goto cleanup;
4775 }
4776 }
df2a74ce 4777
c0bd7667 4778 if (group_count != 1)
89db421e 4779 {
c0bd7667 4780 linklist_free(group_base);
4781 group_count = 0;
4782 group_base = NULL;
89db421e 4783 sprintf(filter, "(sAMAccountName=%s)", user_name);
4784 attr_array[0] = "name";
4785 attr_array[1] = NULL;
4786 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 4787 &group_base, &group_count,
4788 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 4789 {
4a6e2ee4 4790 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 4791 user_name, ldap_err2string(rc));
4792 goto cleanup;
4793 }
cd9e6b16 4794 }
4795
78af4e6e 4796 if (group_count != 1)
cd9e6b16 4797 {
4a6e2ee4 4798 com_err(whoami, 0, "Unable to find user %s in AD",
f75f605a 4799 user_name);
cd9e6b16 4800 goto cleanup;
4801 }
df2a74ce 4802
cd9e6b16 4803 strcpy(distinguished_name, group_base->dn);
df2a74ce 4804
cd9e6b16 4805 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
4806 {
4a6e2ee4 4807 com_err(whoami, 0, "Unable to process user %s : %s",
f75f605a 4808 user_name, ldap_err2string(rc));
cd9e6b16 4809 }
4810
df2a74ce 4811 /* Need to add code to delete mit.edu contact */
4812
4813 if (Exchange)
4814 {
4815 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
4816
4817 if(rc = ldap_delete_s(ldap_handle, temp))
4818 {
4819 com_err(whoami, 0, "Unable to delete user contact for %s",
4820 user_name);
4821 }
4822 }
4823
4824 cleanup:
cd9e6b16 4825 linklist_free(group_base);
df2a74ce 4826
78af4e6e 4827 return(0);
cd9e6b16 4828}
4829
4830void linklist_free(LK_ENTRY *linklist_base)
4831{
4832 LK_ENTRY *linklist_previous;
4833
4834 while (linklist_base != NULL)
4835 {
4836 if (linklist_base->dn != NULL)
4837 free(linklist_base->dn);
df2a74ce 4838
cd9e6b16 4839 if (linklist_base->attribute != NULL)
4840 free(linklist_base->attribute);
df2a74ce 4841
cd9e6b16 4842 if (linklist_base->value != NULL)
4843 free(linklist_base->value);
df2a74ce 4844
cd9e6b16 4845 if (linklist_base->member != NULL)
4846 free(linklist_base->member);
df2a74ce 4847
cd9e6b16 4848 if (linklist_base->type != NULL)
4849 free(linklist_base->type);
df2a74ce 4850
cd9e6b16 4851 if (linklist_base->list != NULL)
4852 free(linklist_base->list);
df2a74ce 4853
cd9e6b16 4854 linklist_previous = linklist_base;
4855 linklist_base = linklist_previous->next;
4856 free(linklist_previous);
4857 }
4858}
4859
4860void free_values(char **modvalues)
4861{
4862 int i;
4863
4864 i = 0;
df2a74ce 4865
cd9e6b16 4866 if (modvalues != NULL)
4867 {
4868 while (modvalues[i] != NULL)
4869 {
4870 free(modvalues[i]);
4871 modvalues[i] = NULL;
4872 ++i;
4873 }
4874 free(modvalues);
4875 }
4876}
4877
cd9e6b16 4878static int illegalchars[] = {
4879 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
4880 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
4881 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
4882 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
f75f605a 4883 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
cd9e6b16 4884 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
4885 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
4886 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
4887 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4888 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4889 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4890 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4891 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4892 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4893 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4894 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4895};
4896
4897int check_string(char *s)
4898{
78af4e6e 4899 char character;
4900
cd9e6b16 4901 for (; *s; s++)
4902 {
78af4e6e 4903 character = *s;
df2a74ce 4904
78af4e6e 4905 if (isupper(character))
4906 character = tolower(character);
df2a74ce 4907
78af4e6e 4908 if (illegalchars[(unsigned) character])
cd9e6b16 4909 return 0;
4910 }
df2a74ce 4911
4912 return(1);
cd9e6b16 4913}
4914
bb52f279 4915int check_container_name(char *s)
4916{
4917 char character;
4918
4919 for (; *s; s++)
4920 {
4921 character = *s;
df2a74ce 4922
bb52f279 4923 if (isupper(character))
4924 character = tolower(character);
4925
df2a74ce 4926 if (character == ' ')
4927 continue;
4928
bb52f279 4929 if (illegalchars[(unsigned) character])
4930 return 0;
4931 }
df2a74ce 4932
4933 return(1);
bb52f279 4934}
4935
cd9e6b16 4936int mr_connect_cl(char *server, char *client, int version, int auth)
4937{
984c91b7 4938 int status;
4939 char *motd;
4940 char temp[128];
cd9e6b16 4941
4942 status = mr_connect(server);
df2a74ce 4943
cd9e6b16 4944 if (status)
4945 {
4946 com_err(whoami, status, "while connecting to Moira");
aea5154c 4947 return status;
cd9e6b16 4948 }
4949
4950 status = mr_motd(&motd);
df2a74ce 4951
cd9e6b16 4952 if (status)
4953 {
4954 mr_disconnect();
4955 com_err(whoami, status, "while checking server status");
aea5154c 4956 return status;
cd9e6b16 4957 }
df2a74ce 4958
cd9e6b16 4959 if (motd)
4960 {
984c91b7 4961 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
4962 com_err(whoami, status, temp);
cd9e6b16 4963 mr_disconnect();
aea5154c 4964 return status;
cd9e6b16 4965 }
4966
4967 status = mr_version(version);
df2a74ce 4968
cd9e6b16 4969 if (status)
4970 {
4971 if (status == MR_UNKNOWN_PROC)
f78c7eaf 4972 {
4973 if (version > 2)
4974 status = MR_VERSION_HIGH;
4975 else
4976 status = MR_SUCCESS;
4977 }
cd9e6b16 4978
4979 if (status == MR_VERSION_HIGH)
f78c7eaf 4980 {
df2a74ce 4981 com_err(whoami, 0, "Warning: This client is running newer code "
4982 "than the server.");
f78c7eaf 4983 com_err(whoami, 0, "Some operations may not work.");
4984 }
cd9e6b16 4985 else if (status && status != MR_VERSION_LOW)
f78c7eaf 4986 {
4987 com_err(whoami, status, "while setting query version number.");
4988 mr_disconnect();
aea5154c 4989 return status;
f78c7eaf 4990 }
cd9e6b16 4991 }
4992
4993 if (auth)
4994 {
991417e4 4995 status = mr_krb5_auth(client);
cd9e6b16 4996 if (status)
f78c7eaf 4997 {
4998 com_err(whoami, status, "while authenticating to Moira.");
4999 mr_disconnect();
aea5154c 5000 return status;
f78c7eaf 5001 }
cd9e6b16 5002 }
df2a74ce 5003
aea5154c 5004 return MR_SUCCESS;
cd9e6b16 5005}
5006
f78c7eaf 5007void AfsToWinAfs(char* path, char* winPath)
5008{
df2a74ce 5009 char* pathPtr;
5010 char* winPathPtr;
5011 strcpy(winPath, WINAFS);
5012 pathPtr = path + strlen(AFS);
5013 winPathPtr = winPath + strlen(WINAFS);
5014
5015 while (*pathPtr)
f78c7eaf 5016 {
df2a74ce 5017 if (*pathPtr == '/')
5018 *winPathPtr = '\\';
5019 else
5020 *winPathPtr = *pathPtr;
5021
5022 pathPtr++;
5023 winPathPtr++;
f78c7eaf 5024 }
5025}
89db421e 5026
909e0dc3 5027int GetAceInfo(int ac, char **av, void *ptr)
5028{
5029 char **call_args;
5030 int security_flag;
5031
5032 call_args = ptr;
df2a74ce 5033
909e0dc3 5034 strcpy(call_args[0], av[L_ACE_TYPE]);
5035 strcpy(call_args[1], av[L_ACE_NAME]);
5036 security_flag = 0;
5037 get_group_membership(call_args[2], call_args[3], &security_flag, av);
df2a74ce 5038 return(LDAP_SUCCESS);
909e0dc3 5039}
5040
bbef4f93 5041int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
909e0dc3 5042{
5043 char filter[128];
5044 char *attr_array[3];
5045 int group_count;
5046 int rc;
5047 LK_ENTRY *group_base;
df2a74ce 5048
909e0dc3 5049 group_count = 0;
5050 group_base = NULL;
df2a74ce 5051
909e0dc3 5052 sprintf(filter, "(sAMAccountName=%s)", Name);
5053 attr_array[0] = "sAMAccountName";
5054 attr_array[1] = NULL;
df2a74ce 5055
909e0dc3 5056 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5057 &group_base, &group_count,
5058 LDAP_SCOPE_SUBTREE)) != 0)
909e0dc3 5059 {
4a6e2ee4 5060 com_err(whoami, 0, "Unable to process ACE name %s : %s",
909e0dc3 5061 Name, ldap_err2string(rc));
5062 return(1);
5063 }
5064
5065 linklist_free(group_base);
5066 group_base = NULL;
df2a74ce 5067
909e0dc3 5068 if (group_count == 0)
5069 return(0);
df2a74ce 5070
909e0dc3 5071 return(1);
5072}
5073
5074#define MAX_ACE 7
5075
df2a74ce 5076int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5077 int UpdateGroup, int *ProcessGroup, char *maillist)
909e0dc3 5078{
5079 char *av[2];
5080 char GroupName[256];
5081 char *call_args[7];
5082 int rc;
5083 char *AceInfo[4];
5084 char AceType[32];
5085 char AceName[128];
5086 char AceMembership[2];
5087 char AceOu[256];
5088 char temp[128];
df2a74ce 5089 char *save_argv[U_END];
909e0dc3 5090
df2a74ce 5091 if (!SetGroupAce)
5092 {
5093 com_err(whoami, 0, "ProcessAce disabled, skipping");
5094 return(0);
5095 }
909e0dc3 5096
df2a74ce 5097 strcpy(GroupName, Name);
5098
909e0dc3 5099 if (strcasecmp(Type, "LIST"))
5100 return(1);
df2a74ce 5101
909e0dc3 5102 while (1)
5103 {
5104 av[0] = GroupName;
5105 AceInfo[0] = AceType;
5106 AceInfo[1] = AceName;
5107 AceInfo[2] = AceMembership;
5108 AceInfo[3] = AceOu;
5109 memset(AceType, '\0', sizeof(AceType));
5110 memset(AceName, '\0', sizeof(AceName));
5111 memset(AceMembership, '\0', sizeof(AceMembership));
5112 memset(AceOu, '\0', sizeof(AceOu));
5113 callback_rc = 0;
df2a74ce 5114
909e0dc3 5115 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
df2a74ce 5116 {
5117 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5118 GroupName, error_message(rc));
909e0dc3 5119 return(1);
5120 }
df2a74ce 5121
909e0dc3 5122 if (callback_rc)
5123 {
4a6e2ee4 5124 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
909e0dc3 5125 return(1);
5126 }
df2a74ce 5127
909e0dc3 5128 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5129 return(0);
df2a74ce 5130
909e0dc3 5131 strcpy(temp, AceName);
df2a74ce 5132
909e0dc3 5133 if (!strcasecmp(AceType, "LIST"))
df2a74ce 5134 sprintf(temp, "%s%s", AceName, group_suffix);
5135
909e0dc3 5136 if (!UpdateGroup)
5137 {
bbef4f93 5138 if (checkADname(ldap_handle, dn_path, temp))
909e0dc3 5139 return(0);
5140 (*ProcessGroup) = 1;
5141 }
df2a74ce 5142
909e0dc3 5143 if (!strcasecmp(AceInfo[0], "LIST"))
5144 {
df2a74ce 5145 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5146 AceMembership, 0, UpdateGroup, maillist))
909e0dc3 5147 return(1);
5148 }
5149 else if (!strcasecmp(AceInfo[0], "USER"))
5150 {
5151 av[0] = AceName;
5152 call_args[0] = (char *)ldap_handle;
5153 call_args[1] = dn_path;
5154 call_args[2] = "";
5155 call_args[3] = NULL;
909e0dc3 5156 callback_rc = 0;
df2a74ce 5157
5158 if (rc = mr_query("get_user_account_by_login", 1, av,
5159 save_query_info, save_argv))
909e0dc3 5160 {
df2a74ce 5161 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5162 AceName, Name);
909e0dc3 5163 return(1);
5164 }
df2a74ce 5165
5166 if (rc = user_create(U_END, save_argv, call_args))
5167 {
5168 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5169 AceName, Name);
5170 return(1);
5171 }
5172
909e0dc3 5173 if (callback_rc)
5174 {
df2a74ce 5175 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5176 AceName, Name);
909e0dc3 5177 return(1);
5178 }
df2a74ce 5179
909e0dc3 5180 return(0);
5181 }
5182 else
5183 return(1);
df2a74ce 5184
909e0dc3 5185 if (!strcasecmp(AceType, "LIST"))
5186 {
5187 if (!strcasecmp(GroupName, AceName))
5188 return(0);
5189 }
df2a74ce 5190
909e0dc3 5191 strcpy(GroupName, AceName);
5192 }
df2a74ce 5193
909e0dc3 5194 return(1);
5195}
5196
89db421e 5197int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5198 char *group_name, char *group_ou, char *group_membership,
df2a74ce 5199 int group_security_flag, int updateGroup, char *maillist)
89db421e 5200{
5201 char *av[3];
df2a74ce 5202 char *call_args[8];
89db421e 5203 int rc;
df2a74ce 5204 LK_ENTRY *group_base;
5205 int group_count;
5206 char filter[128];
5207 char *attr_array[3];
89db421e 5208
5209 av[0] = group_name;
5210 call_args[0] = (char *)ldap_handle;
5211 call_args[1] = dn_path;
5212 call_args[2] = group_name;
5213 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5214 call_args[4] = (char *)updateGroup;
5215 call_args[5] = MoiraId;
df2a74ce 5216 call_args[6] = "0";
5217 call_args[7] = NULL;
89db421e 5218 callback_rc = 0;
df2a74ce 5219
5220 group_count = 0;
5221 group_base = NULL;
5222
89db421e 5223 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5224 {
5225 moira_disconnect();
df2a74ce 5226 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5227 error_message(rc));
89db421e 5228 return(rc);
5229 }
df2a74ce 5230
89db421e 5231 if (callback_rc)
5232 {
5233 moira_disconnect();
4a6e2ee4 5234 com_err(whoami, 0, "Unable to create list %s", group_name);
89db421e 5235 return(callback_rc);
5236 }
5237
89db421e 5238 return(0);
5239}
5240
5241int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
5242 char *group_ou, char *group_membership,
5243 int group_security_flag, char *MoiraId)
5244{
5245 char *av[3];
5246 char *call_args[7];
5247 char *pUserOu;
5248 LK_ENTRY *ptr;
5249 int rc;
df2a74ce 5250 char member[256];
5251 char *s;
89db421e 5252
5253 com_err(whoami, 0, "Populating group %s", group_name);
5254 av[0] = group_name;
5255 call_args[0] = (char *)ldap_handle;
5256 call_args[1] = dn_path;
5257 call_args[2] = group_name;
5258 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5259 call_args[4] = NULL;
5260 member_base = NULL;
df2a74ce 5261
89db421e 5262 if (rc = mr_query("get_end_members_of_list", 1, av,
5263 member_list_build, call_args))
5264 {
4a6e2ee4 5265 com_err(whoami, 0, "Unable to populate list %s : %s",
89db421e 5266 group_name, error_message(rc));
5267 return(3);
5268 }
df2a74ce 5269
89db421e 5270 if (member_base != NULL)
5271 {
5272 ptr = member_base;
df2a74ce 5273
89db421e 5274 while (ptr != NULL)
5275 {
5276 if (!strcasecmp(ptr->type, "LIST"))
5277 {
5278 ptr = ptr->next;
5279 continue;
5280 }
df2a74ce 5281
89db421e 5282 pUserOu = user_ou;
df2a74ce 5283
89db421e 5284 if (!strcasecmp(ptr->type, "STRING"))
5285 {
df2a74ce 5286 if (contact_create(ldap_handle, dn_path, ptr->member,
5287 contact_ou))
89db421e 5288 return(3);
df2a74ce 5289
89db421e 5290 pUserOu = contact_ou;
5291 }
5292 else if (!strcasecmp(ptr->type, "KERBEROS"))
5293 {
df2a74ce 5294 if (contact_create(ldap_handle, dn_path, ptr->member,
5295 kerberos_ou))
89db421e 5296 return(3);
df2a74ce 5297
89db421e 5298 pUserOu = kerberos_ou;
5299 }
df2a74ce 5300
89db421e 5301 rc = member_add(ldap_handle, dn_path, group_name,
5302 group_ou, group_membership, ptr->member,
5303 pUserOu, MoiraId);
5304 ptr = ptr->next;
5305 }
df2a74ce 5306
89db421e 5307 linklist_free(member_base);
5308 member_base = NULL;
5309 }
df2a74ce 5310
89db421e 5311 return(0);
5312}
5313
5314int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5315 char *group_name, char *group_ou, char *group_membership,
df2a74ce 5316 int group_security_flag, int type, char *maillist)
89db421e 5317{
5318 char before_desc[512];
5319 char before_name[256];
5320 char before_group_ou[256];
5321 char before_group_membership[2];
5322 char distinguishedName[256];
5323 char ad_distinguishedName[256];
5324 char filter[128];
5325 char *attr_array[3];
5326 int before_security_flag;
5327 int group_count;
5328 int rc;
5329 LK_ENTRY *group_base;
5330 LK_ENTRY *ptr;
5331 char ou_both[512];
5332 char ou_security[512];
5333 char ou_distribution[512];
5334 char ou_neither[512];
5335
5336 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
5337 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
5338
89db421e 5339 memset(filter, '\0', sizeof(filter));
5340 group_base = NULL;
5341 group_count = 0;
df2a74ce 5342
89db421e 5343 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5344 "*", MoiraId,
5345 "distinguishedName", &group_base,
5346 &group_count, filter))
5347 return(rc);
5348
5349 if (type == CHECK_GROUPS)
5350 {
5351 if (group_count == 1)
5352 {
5353 if (!strcasecmp(group_base->value, distinguishedName))
5354 {
5355 linklist_free(group_base);
5356 return(0);
5357 }
5358 }
df2a74ce 5359
89db421e 5360 linklist_free(group_base);
df2a74ce 5361
89db421e 5362 if (group_count == 0)
5363 return(AD_NO_GROUPS_FOUND);
df2a74ce 5364
89db421e 5365 if (group_count == 1)
5366 return(AD_WRONG_GROUP_DN_FOUND);
df2a74ce 5367
89db421e 5368 return(AD_MULTIPLE_GROUPS_FOUND);
5369 }
df2a74ce 5370
89db421e 5371 if (group_count == 0)
5372 {
5373 return(AD_NO_GROUPS_FOUND);
5374 }
df2a74ce 5375
89db421e 5376 if (group_count > 1)
5377 {
5378 ptr = group_base;
df2a74ce 5379
89db421e 5380 while (ptr != NULL)
5381 {
5382 if (!strcasecmp(distinguishedName, ptr->value))
5383 break;
df2a74ce 5384
89db421e 5385 ptr = ptr->next;
5386 }
df2a74ce 5387
89db421e 5388 if (ptr == NULL)
5389 {
df2a74ce 5390 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
5391 MoiraId);
89db421e 5392 ptr = group_base;
df2a74ce 5393
89db421e 5394 while (ptr != NULL)
5395 {
5396 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
5397 ptr = ptr->next;
5398 }
df2a74ce 5399
89db421e 5400 linklist_free(group_base);
5401 return(AD_MULTIPLE_GROUPS_FOUND);
6c8f12af 5402 }
df2a74ce 5403
89db421e 5404 ptr = group_base;
df2a74ce 5405
89db421e 5406 while (ptr != NULL)
5407 {
5408 if (strcasecmp(distinguishedName, ptr->value))
5409 rc = ldap_delete_s(ldap_handle, ptr->value);
df2a74ce 5410
89db421e 5411 ptr = ptr->next;
5412 }
df2a74ce 5413
89db421e 5414 linklist_free(group_base);
5415 memset(filter, '\0', sizeof(filter));
5416 group_base = NULL;
5417 group_count = 0;
df2a74ce 5418
89db421e 5419 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5420 "*", MoiraId,
5421 "distinguishedName", &group_base,
5422 &group_count, filter))
5423 return(rc);
df2a74ce 5424
89db421e 5425 if (group_count == 0)
5426 return(AD_NO_GROUPS_FOUND);
df2a74ce 5427
89db421e 5428 if (group_count > 1)
5429 return(AD_MULTIPLE_GROUPS_FOUND);
5430 }
df2a74ce 5431
89db421e 5432 strcpy(ad_distinguishedName, group_base->value);
5433 linklist_free(group_base);
5434 group_base = NULL;
5435 group_count = 0;
5436
5437 attr_array[0] = "sAMAccountName";
5438 attr_array[1] = NULL;
df2a74ce 5439
89db421e 5440 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5441 &group_base, &group_count,
5442 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5443 {
4a6e2ee4 5444 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5445 MoiraId, ldap_err2string(rc));
5446 return(rc);
5447 }
89db421e 5448
df2a74ce 5449 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
5450
89db421e 5451 if (!strcasecmp(ad_distinguishedName, distinguishedName))
5452 {
5453 linklist_free(group_base);
5454 group_base = NULL;
5455 group_count = 0;
5456 return(0);
5457 }
df2a74ce 5458
89db421e 5459 linklist_free(group_base);
5460 group_base = NULL;
5461 group_count = 0;
5462 memset(ou_both, '\0', sizeof(ou_both));
5463 memset(ou_security, '\0', sizeof(ou_security));
5464 memset(ou_distribution, '\0', sizeof(ou_distribution));
5465 memset(ou_neither, '\0', sizeof(ou_neither));
5466 memset(before_name, '\0', sizeof(before_name));
5467 memset(before_desc, '\0', sizeof(before_desc));
5468 memset(before_group_membership, '\0', sizeof(before_group_membership));
5469 attr_array[0] = "name";
5470 attr_array[1] = NULL;
df2a74ce 5471
89db421e 5472 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5473 &group_base, &group_count,
5474 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5475 {
4a6e2ee4 5476 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
89db421e 5477 MoiraId, ldap_err2string(rc));
5478 return(rc);
5479 }
df2a74ce 5480
89db421e 5481 strcpy(before_name, group_base->value);
5482 linklist_free(group_base);
5483 group_base = NULL;
5484 group_count = 0;
5485 attr_array[0] = "description";
5486 attr_array[1] = NULL;
df2a74ce 5487
89db421e 5488 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5489 &group_base, &group_count,
5490 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5491 {
5492 com_err(whoami, 0,
4a6e2ee4 5493 "Unable to get list description with MoiraId = %s: %s",
89db421e 5494 MoiraId, ldap_err2string(rc));
5495 return(rc);
5496 }
df2a74ce 5497
c0bd7667 5498 if (group_count != 0)
5499 {
5500 strcpy(before_desc, group_base->value);
5501 linklist_free(group_base);
5502 group_base = NULL;
5503 group_count = 0;
5504 }
df2a74ce 5505
89db421e 5506 change_to_lower_case(ad_distinguishedName);
5507 strcpy(ou_both, group_ou_both);
5508 change_to_lower_case(ou_both);
5509 strcpy(ou_security, group_ou_security);
5510 change_to_lower_case(ou_security);
5511 strcpy(ou_distribution, group_ou_distribution);
5512 change_to_lower_case(ou_distribution);
5513 strcpy(ou_neither, group_ou_neither);
5514 change_to_lower_case(ou_neither);
df2a74ce 5515
89db421e 5516 if (strstr(ad_distinguishedName, ou_both))
5517 {
5518 strcpy(before_group_ou, group_ou_both);
5519 before_group_membership[0] = 'B';
5520 before_security_flag = 1;
5521 }
5522 else if (strstr(ad_distinguishedName, ou_security))
5523 {
5524 strcpy(before_group_ou, group_ou_security);
5525 before_group_membership[0] = 'S';
5526 before_security_flag = 1;
5527 }
5528 else if (strstr(ad_distinguishedName, ou_distribution))
5529 {
5530 strcpy(before_group_ou, group_ou_distribution);
5531 before_group_membership[0] = 'D';
5532 before_security_flag = 0;
5533 }
5534 else if (strstr(ad_distinguishedName, ou_neither))
5535 {
5536 strcpy(before_group_ou, group_ou_neither);
5537 before_group_membership[0] = 'N';
5538 before_security_flag = 0;
5539 }
5540 else
5541 return(AD_NO_OU_FOUND);
df2a74ce 5542
5543 rc = group_rename(ldap_handle, dn_path, before_name,
5544 before_group_membership,
89db421e 5545 before_group_ou, before_security_flag, before_desc,
df2a74ce 5546 group_name, group_membership, group_ou,
5547 group_security_flag,
5548 before_desc, MoiraId, filter, maillist);
5549
89db421e 5550 return(rc);
5551}
5552
5553void change_to_lower_case(char *ptr)
5554{
5555 int i;
5556
5557 for (i = 0; i < (int)strlen(ptr); i++)
5558 {
5559 ptr[i] = tolower(ptr[i]);
5560 }
5561}
5562
5563int ad_get_group(LDAP *ldap_handle, char *dn_path,
5564 char *group_name, char *group_membership,
5565 char *MoiraId, char *attribute,
5566 LK_ENTRY **linklist_base, int *linklist_count,
5567 char *rFilter)
5568{
3e586ecf 5569 LK_ENTRY *pPtr;
c0bd7667 5570 char filter[128];
5571 char *attr_array[3];
89db421e 5572 int rc;
5573
5574 (*linklist_base) = NULL;
5575 (*linklist_count) = 0;
df2a74ce 5576
89db421e 5577 if (strlen(rFilter) != 0)
5578 {
5579 strcpy(filter, rFilter);
5580 attr_array[0] = attribute;
5581 attr_array[1] = NULL;
df2a74ce 5582
89db421e 5583 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5584 linklist_base, linklist_count,
5585 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5586 {
4a6e2ee4 5587 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5588 MoiraId, ldap_err2string(rc));
5589 return(rc);
5590 }
df2a74ce 5591
89db421e 5592 if ((*linklist_count) == 1)
5593 {
5594 strcpy(rFilter, filter);
5595 return(0);
5596 }
5597 }
5598
5599 linklist_free((*linklist_base));
5600 (*linklist_base) = NULL;
5601 (*linklist_count) = 0;
df2a74ce 5602
89db421e 5603 if (strlen(MoiraId) != 0)
5604 {
c0bd7667 5605 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
89db421e 5606 attr_array[0] = attribute;
5607 attr_array[1] = NULL;
df2a74ce 5608
89db421e 5609 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5610 linklist_base, linklist_count,
5611 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5612 {
4a6e2ee4 5613 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5614 MoiraId, ldap_err2string(rc));
5615 return(rc);
5616 }
5617 }
df2a74ce 5618
3e586ecf 5619 if ((*linklist_count) > 1)
5620 {
5621 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
5622 pPtr = (*linklist_base);
df2a74ce 5623
3e586ecf 5624 while (pPtr)
5625 {
df2a74ce 5626 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
5627 MoiraId);
3e586ecf 5628 pPtr = pPtr->next;
5629 }
df2a74ce 5630
3e586ecf 5631 linklist_free((*linklist_base));
5632 (*linklist_base) = NULL;
5633 (*linklist_count) = 0;
5634 }
df2a74ce 5635
89db421e 5636 if ((*linklist_count) == 1)
5637 {
909e0dc3 5638 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
5639 {
5640 strcpy(rFilter, filter);
5641 return(0);
5642 }
89db421e 5643 }
5644
5645 linklist_free((*linklist_base));
5646 (*linklist_base) = NULL;
5647 (*linklist_count) = 0;
df2a74ce 5648 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
89db421e 5649 attr_array[0] = attribute;
5650 attr_array[1] = NULL;
df2a74ce 5651
89db421e 5652 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5653 linklist_base, linklist_count,
5654 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5655 {
4a6e2ee4 5656 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5657 MoiraId, ldap_err2string(rc));
5658 return(rc);
5659 }
df2a74ce 5660
89db421e 5661 if ((*linklist_count) == 1)
5662 {
5663 strcpy(rFilter, filter);
5664 return(0);
5665 }
5666
89db421e 5667 return(0);
5668}
5669
5670int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5671{
5672 char filter[128];
5673 char *attr_array[3];
5674 char SamAccountName[64];
5675 int group_count;
5676 int rc;
5677 LK_ENTRY *group_base;
c0bd7667 5678 LK_ENTRY *gPtr;
89db421e 5679
5680 group_count = 0;
5681 group_base = NULL;
5682
5683 if (strlen(MoiraId) != 0)
5684 {
c0bd7667 5685 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 5686 attr_array[0] = "sAMAccountName";
5687 attr_array[1] = NULL;
5688 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5689 &group_base, &group_count,
5690 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5691 {
4a6e2ee4 5692 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 5693 UserName, ldap_err2string(rc));
5694 return(rc);
5695 }
df2a74ce 5696
c0bd7667 5697 if (group_count > 1)
5698 {
5699 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5700 MoiraId);
5701 gPtr = group_base;
df2a74ce 5702
c0bd7667 5703 while (gPtr)
5704 {
5705 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5706 gPtr->value, MoiraId);
5707 gPtr = gPtr->next;
5708 }
5709 }
89db421e 5710 }
df2a74ce 5711
c0bd7667 5712 if (group_count != 1)
89db421e 5713 {
c0bd7667 5714 linklist_free(group_base);
5715 group_count = 0;
5716 group_base = NULL;
89db421e 5717 sprintf(filter, "(sAMAccountName=%s)", UserName);
5718 attr_array[0] = "sAMAccountName";
5719 attr_array[1] = NULL;
df2a74ce 5720
89db421e 5721 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5722 &group_base, &group_count,
5723 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5724 {
4a6e2ee4 5725 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 5726 UserName, ldap_err2string(rc));
5727 return(rc);
5728 }
5729 }
5730
5731 if (group_count != 1)
5732 {
5733 linklist_free(group_base);
5734 return(AD_NO_USER_FOUND);
5735 }
df2a74ce 5736
89db421e 5737 strcpy(SamAccountName, group_base->value);
5738 linklist_free(group_base);
5739 group_count = 0;
5740 rc = 0;
df2a74ce 5741
89db421e 5742 if (strcmp(SamAccountName, UserName))
5743 {
5744 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5745 UserName);
5746 }
df2a74ce 5747
89db421e 5748 return(0);
5749}
6c8f12af 5750
5751void container_get_dn(char *src, char *dest)
5752{
5753 char *sPtr;
5754 char *array[20];
5755 char name[256];
5756 int n;
5757
5758 memset(array, '\0', 20 * sizeof(array[0]));
5759
5760 if (strlen(src) == 0)
5761 return;
df2a74ce 5762
6c8f12af 5763 strcpy(name, src);
5764 sPtr = name;
5765 n = 0;
5766 array[n] = name;
5767 ++n;
df2a74ce 5768
6c8f12af 5769 while (*sPtr)
5770 {
5771 if ((*sPtr) == '/')
5772 {
5773 (*sPtr) = '\0';
5774 ++sPtr;
5775 array[n] = sPtr;
5776 ++n;
5777 }
5778 else
5779 ++sPtr;
5780 }
df2a74ce 5781
6c8f12af 5782 strcpy(dest, "OU=");
df2a74ce 5783
6c8f12af 5784 while (n != 0)
5785 {
5786 strcat(dest, array[n-1]);
5787 --n;
5788 if (n > 0)
5789 {
5790 strcat(dest, ",OU=");
5791 }
5792 }
df2a74ce 5793
6c8f12af 5794 return;
5795}
5796
5797void container_get_name(char *src, char *dest)
5798{
5799 char *sPtr;
5800 char *dPtr;
5801
5802 if (strlen(src) == 0)
5803 return;
df2a74ce 5804
6c8f12af 5805 sPtr = src;
5806 dPtr = src;
df2a74ce 5807
6c8f12af 5808 while (*sPtr)
5809 {
5810 if ((*sPtr) == '/')
5811 {
5812 dPtr = sPtr;
5813 ++dPtr;
5814 }
5815 ++sPtr;
5816 }
df2a74ce 5817
6c8f12af 5818 strcpy(dest, dPtr);
5819 return;
5820}
5821
5822void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5823{
5824 char cName[256];
5825 char *av[7];
5826 int i;
5827 int rc;
5828
5829 strcpy(cName, name);
df2a74ce 5830
6c8f12af 5831 for (i = 0; i < (int)strlen(cName); i++)
5832 {
5833 if (cName[i] == '/')
5834 {
5835 cName[i] = '\0';
5836 av[CONTAINER_NAME] = cName;
5837 av[CONTAINER_DESC] = "";
5838 av[CONTAINER_LOCATION] = "";
5839 av[CONTAINER_CONTACT] = "";
5840 av[CONTAINER_TYPE] = "";
5841 av[CONTAINER_ID] = "";
5842 av[CONTAINER_ROWID] = "";
5843 rc = container_create(ldap_handle, dn_path, 7, av);
df2a74ce 5844
6c8f12af 5845 if (rc == LDAP_SUCCESS)
5846 {
df2a74ce 5847 com_err(whoami, 0, "container %s created without a mitMoiraId",
5848 cName);
6c8f12af 5849 }
df2a74ce 5850
6c8f12af 5851 cName[i] = '/';
5852 }
5853 }
6c8f12af 5854}
5855
df2a74ce 5856int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5857 char **before, int afterc, char **after)
6c8f12af 5858{
5859 char dName[256];
5860 char cName[256];
5861 char new_cn[128];
5862 char new_dn_path[256];
5863 char temp[256];
5864 char distinguishedName[256];
5865 char *pPtr;
5866 int rc;
5867 int i;
5868
5869 memset(cName, '\0', sizeof(cName));
5870 container_get_name(after[CONTAINER_NAME], cName);
df2a74ce 5871
bb52f279 5872 if (!check_container_name(cName))
6c8f12af 5873 {
df2a74ce 5874 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5875 cName);
6c8f12af 5876 return(AD_INVALID_NAME);
5877 }
5878
5879 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 5880
5881 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5882 distinguishedName, beforec, before))
6c8f12af 5883 return(rc);
df2a74ce 5884
6c8f12af 5885 if (strlen(distinguishedName) == 0)
5886 {
5887 rc = container_create(ldap_handle, dn_path, afterc, after);
5888 return(rc);
5889 }
5890
5891 strcpy(temp, after[CONTAINER_NAME]);
9cfe334f 5892 pPtr = temp;
df2a74ce 5893
6c8f12af 5894 for (i = 0; i < (int)strlen(temp); i++)
5895 {
5896 if (temp[i] == '/')
5897 {
5898 pPtr = &temp[i];
5899 }
5900 }
df2a74ce 5901
9cfe334f 5902 (*pPtr) = '\0';
6c8f12af 5903
5904 container_get_dn(temp, dName);
df2a74ce 5905
9cfe334f 5906 if (strlen(temp) != 0)
5907 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5908 else
5909 sprintf(new_dn_path, "%s", dn_path);
df2a74ce 5910
6c8f12af 5911 sprintf(new_cn, "OU=%s", cName);
5912
5913 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
5914
5915 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
5916 TRUE, NULL, NULL)) != LDAP_SUCCESS)
5917 {
4a6e2ee4 5918 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
df2a74ce 5919 before[CONTAINER_NAME], after[CONTAINER_NAME],
5920 ldap_err2string(rc));
6c8f12af 5921 return(rc);
5922 }
5923
5924 memset(dName, '\0', sizeof(dName));
5925 container_get_dn(after[CONTAINER_NAME], dName);
5926 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
df2a74ce 5927
6c8f12af 5928 return(rc);
5929}
5930
5931int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
5932{
5933 char distinguishedName[256];
5934 int rc;
5935
5936 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 5937
5938 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5939 distinguishedName, count, av))
6c8f12af 5940 return(rc);
df2a74ce 5941
6c8f12af 5942 if (strlen(distinguishedName) == 0)
5943 return(0);
df2a74ce 5944
6c8f12af 5945 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
5946 {
5947 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
5948 container_move_objects(ldap_handle, dn_path, distinguishedName);
5949 else
4a6e2ee4 5950 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6c8f12af 5951 av[CONTAINER_NAME], ldap_err2string(rc));
5952 }
df2a74ce 5953
6c8f12af 5954 return(rc);
5955}
bbef4f93 5956
6c8f12af 5957int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
5958{
5959 char *attr_array[3];
5960 LK_ENTRY *group_base;
5961 int group_count;
5962 LDAPMod *mods[20];
5963 char *objectClass_v[] = {"top",
5964 "organizationalUnit",
5965 NULL};
5966
5967 char *ou_v[] = {NULL, NULL};
5968 char *name_v[] = {NULL, NULL};
5969 char *moiraId_v[] = {NULL, NULL};
5970 char *desc_v[] = {NULL, NULL};
5971 char *managedBy_v[] = {NULL, NULL};
5972 char dName[256];
5973 char cName[256];
5974 char managedByDN[256];
5975 char filter[256];
5976 char temp[256];
5977 int n;
5978 int i;
5979 int rc;
5980
5981 memset(filter, '\0', sizeof(filter));
5982 memset(dName, '\0', sizeof(dName));
5983 memset(cName, '\0', sizeof(cName));
5984 memset(managedByDN, '\0', sizeof(managedByDN));
5985 container_get_dn(av[CONTAINER_NAME], dName);
5986 container_get_name(av[CONTAINER_NAME], cName);
5987
5988 if ((strlen(cName) == 0) || (strlen(dName) == 0))
5989 {
df2a74ce 5990 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5991 cName);
6c8f12af 5992 return(AD_INVALID_NAME);
5993 }
5994
bb52f279 5995 if (!check_container_name(cName))
6c8f12af 5996 {
df2a74ce 5997 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5998 cName);
6c8f12af 5999 return(AD_INVALID_NAME);
6000 }
6001
6002 n = 0;
6003 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6004 name_v[0] = cName;
6005 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6006 ou_v[0] = cName;
6007 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
df2a74ce 6008
6c8f12af 6009 if (strlen(av[CONTAINER_ROWID]) != 0)
6010 {
6011 moiraId_v[0] = av[CONTAINER_ROWID];
6012 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6013 }
df2a74ce 6014
6c8f12af 6015 if (strlen(av[CONTAINER_DESC]) != 0)
6016 {
6017 desc_v[0] = av[CONTAINER_DESC];
6018 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6019 }
df2a74ce 6020
6c8f12af 6021 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6022 {
df2a74ce 6023 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6024 {
6025 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6026 kerberos_ou))
6027 {
6028 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6029 kerberos_ou, dn_path);
6030 managedBy_v[0] = managedByDN;
6031 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6032 }
6033 }
6034 else
6035 {
6036 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6037 {
6038 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6039 "(objectClass=user)))", av[CONTAINER_ID]);
6040 }
6041
6042 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6043 {
6044 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6045 av[CONTAINER_ID]);
6046 }
6047
6048 if (strlen(filter) != 0)
6049 {
6050 attr_array[0] = "distinguishedName";
6051 attr_array[1] = NULL;
6052 group_count = 0;
6053 group_base = NULL;
6054 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6055 attr_array,
6056 &group_base, &group_count,
6057 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6058 {
6059 if (group_count == 1)
6060 {
6061 strcpy(managedByDN, group_base->value);
6062 managedBy_v[0] = managedByDN;
6063 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6064 }
6065 linklist_free(group_base);
6066 group_base = NULL;
6067 group_count = 0;
6068 }
6069 }
6070 }
6c8f12af 6071 }
df2a74ce 6072
6c8f12af 6073 mods[n] = NULL;
6074
6075 sprintf(temp, "%s,%s", dName, dn_path);
6076 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
df2a74ce 6077
6c8f12af 6078 for (i = 0; i < n; i++)
6079 free(mods[i]);
df2a74ce 6080
6c8f12af 6081 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6082 {
4a6e2ee4 6083 com_err(whoami, 0, "Unable to create container %s : %s",
6c8f12af 6084 cName, ldap_err2string(rc));
6085 return(rc);
6086 }
df2a74ce 6087
6c8f12af 6088 if (rc == LDAP_ALREADY_EXISTS)
6089 {
6090 if (strlen(av[CONTAINER_ROWID]) != 0)
6091 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6092 }
df2a74ce 6093
6c8f12af 6094 return(rc);
6095}
6096
df2a74ce 6097int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6098 char **before, int afterc, char **after)
6c8f12af 6099{
6100 char distinguishedName[256];
6101 int rc;
6102
6103 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 6104
6105 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6106 distinguishedName, afterc, after))
6c8f12af 6107 return(rc);
df2a74ce 6108
6c8f12af 6109 if (strlen(distinguishedName) == 0)
6110 {
6111 rc = container_create(ldap_handle, dn_path, afterc, after);
6112 return(rc);
6113 }
df2a74ce 6114
6c8f12af 6115 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
df2a74ce 6116 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6117 after);
6c8f12af 6118
6119 return(rc);
6120}
6121
df2a74ce 6122int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6123 char *distinguishedName, int count,
6124 char **av)
6c8f12af 6125{
6126 char *attr_array[3];
6127 LK_ENTRY *group_base;
6128 int group_count;
6129 char dName[256];
6130 char cName[256];
6131 char filter[512];
6132 int rc;
6133
6134 memset(filter, '\0', sizeof(filter));
6135 memset(dName, '\0', sizeof(dName));
6136 memset(cName, '\0', sizeof(cName));
6137 container_get_dn(av[CONTAINER_NAME], dName);
6138 container_get_name(av[CONTAINER_NAME], cName);
6139
6140 if (strlen(dName) == 0)
6141 {
df2a74ce 6142 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6143 av[CONTAINER_NAME]);
6c8f12af 6144 return(AD_INVALID_NAME);
6145 }
6146
bb52f279 6147 if (!check_container_name(cName))
6c8f12af 6148 {
df2a74ce 6149 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6150 cName);
6c8f12af 6151 return(AD_INVALID_NAME);
6152 }
df2a74ce 6153
6154 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6155 av[CONTAINER_ROWID]);
6c8f12af 6156 attr_array[0] = "distinguishedName";
6157 attr_array[1] = NULL;
6158 group_count = 0;
6159 group_base = NULL;
df2a74ce 6160
6c8f12af 6161 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6162 &group_base, &group_count,
6163 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6c8f12af 6164 {
6165 if (group_count == 1)
6166 {
6167 strcpy(distinguishedName, group_base->value);
6168 }
df2a74ce 6169
6c8f12af 6170 linklist_free(group_base);
6171 group_base = NULL;
6172 group_count = 0;
6173 }
df2a74ce 6174
6c8f12af 6175 if (strlen(distinguishedName) == 0)
6176 {
df2a74ce 6177 sprintf(filter, "(&(objectClass=organizationalUnit)"
6178 "(distinguishedName=%s,%s))", dName, dn_path);
6c8f12af 6179 attr_array[0] = "distinguishedName";
6180 attr_array[1] = NULL;
6181 group_count = 0;
6182 group_base = NULL;
df2a74ce 6183
6c8f12af 6184 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6185 &group_base, &group_count,
6186 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6c8f12af 6187 {
6188 if (group_count == 1)
6189 {
6190 strcpy(distinguishedName, group_base->value);
6191 }
df2a74ce 6192
6c8f12af 6193 linklist_free(group_base);
6194 group_base = NULL;
6195 group_count = 0;
6196 }
6197 }
df2a74ce 6198
6c8f12af 6199 return(0);
6200}
6201
6202int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6203 char *distinguishedName, int count, char **av)
6204{
6205 char *attr_array[5];
6206 LK_ENTRY *group_base;
6207 LK_ENTRY *pPtr;
6208 LDAPMod *mods[20];
6209 int group_count;
6210 char filter[512];
6c8f12af 6211 char *moiraId_v[] = {NULL, NULL};
6212 char *desc_v[] = {NULL, NULL};
6213 char *managedBy_v[] = {NULL, NULL};
6214 char managedByDN[256];
6215 char moiraId[64];
6216 char desc[256];
4a6e2ee4 6217 char ad_path[512];
6c8f12af 6218 int rc;
6219 int i;
6220 int n;
6221
6222
4a6e2ee4 6223 strcpy(ad_path, distinguishedName);
df2a74ce 6224
6c8f12af 6225 if (strlen(dName) != 0)
4a6e2ee4 6226 sprintf(ad_path, "%s,%s", dName, dn_path);
6c8f12af 6227
df2a74ce 6228 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6229 ad_path);
6230
6c8f12af 6231 if (strlen(av[CONTAINER_ID]) != 0)
df2a74ce 6232 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6233 av[CONTAINER_ROWID]);
6234
6c8f12af 6235 attr_array[0] = "mitMoiraId";
6236 attr_array[1] = "description";
6237 attr_array[2] = "managedBy";
6238 attr_array[3] = NULL;
6239 group_count = 0;
6240 group_base = NULL;
df2a74ce 6241
6c8f12af 6242 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6243 &group_base, &group_count,
6244 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6c8f12af 6245 {
4a6e2ee4 6246 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6c8f12af 6247 av[CONTAINER_NAME], ldap_err2string(rc));
6248 return(rc);
6249 }
df2a74ce 6250
6c8f12af 6251 memset(managedByDN, '\0', sizeof(managedByDN));
6252 memset(moiraId, '\0', sizeof(moiraId));
6253 memset(desc, '\0', sizeof(desc));
6254 pPtr = group_base;
df2a74ce 6255
6c8f12af 6256 while (pPtr)
6257 {
6258 if (!strcasecmp(pPtr->attribute, "description"))
6259 strcpy(desc, pPtr->value);
9cfe334f 6260 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6c8f12af 6261 strcpy(managedByDN, pPtr->value);
9cfe334f 6262 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6c8f12af 6263 strcpy(moiraId, pPtr->value);
6264 pPtr = pPtr->next;
6265 }
df2a74ce 6266
6c8f12af 6267 linklist_free(group_base);
6268 group_base = NULL;
6269 group_count = 0;
6270
6271 n = 0;
6272 if (strlen(av[CONTAINER_ROWID]) != 0)
6273 {
6274 moiraId_v[0] = av[CONTAINER_ROWID];
6275 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6276 }
df2a74ce 6277
6c8f12af 6278 if (strlen(av[CONTAINER_DESC]) != 0)
6279 {
df2a74ce 6280 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6281 dName);
6c8f12af 6282 }
6283 else
6284 {
6285 if (strlen(desc) != 0)
6286 {
4a6e2ee4 6287 attribute_update(ldap_handle, ad_path, "", "description", dName);
6c8f12af 6288 }
6289 }
df2a74ce 6290
6c8f12af 6291 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6292 {
df2a74ce 6293 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6294 {
6295 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6296 kerberos_ou))
6297 {
6298 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6299 kerberos_ou, dn_path);
6300 managedBy_v[0] = managedByDN;
6301 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6302 }
6303 else
6304 {
6305 if (strlen(managedByDN) != 0)
6306 {
6307 attribute_update(ldap_handle, ad_path, "", "managedBy",
6308 dName);
6309 }
6310 }
6311 }
6312 else
6313 {
6314 memset(filter, '\0', sizeof(filter));
6315
6316 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6317 {
6318 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6319 "(objectClass=user)))", av[CONTAINER_ID]);
6320 }
6321
6322 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6323 {
6324 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6325 av[CONTAINER_ID]);
6326 }
6327
6328 if (strlen(filter) != 0)
6329 {
6330 attr_array[0] = "distinguishedName";
6331 attr_array[1] = NULL;
6332 group_count = 0;
6333 group_base = NULL;
6334 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6335 attr_array, &group_base, &group_count,
6336 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6337 {
6338 if (group_count == 1)
6339 {
6340 strcpy(managedByDN, group_base->value);
6341 managedBy_v[0] = managedByDN;
6342 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6343 }
0eae7c9b 6344 else
df2a74ce 6345 {
6346 if (strlen(managedByDN) != 0)
0eae7c9b 6347 {
df2a74ce 6348 attribute_update(ldap_handle, ad_path, "",
6349 "managedBy", dName);
0eae7c9b 6350 }
df2a74ce 6351 }
6352
6353 linklist_free(group_base);
6354 group_base = NULL;
6355 group_count = 0;
6356 }
6357 }
0eae7c9b 6358 else
df2a74ce 6359 {
6360 if (strlen(managedByDN) != 0)
6361 {
6362 attribute_update(ldap_handle, ad_path, "", "managedBy",
6363 dName);
6364 }
6365 }
6366 }
6c8f12af 6367 }
df2a74ce 6368
6c8f12af 6369 mods[n] = NULL;
df2a74ce 6370
6c8f12af 6371 if (n == 0)
6372 return(LDAP_SUCCESS);
6373
4a6e2ee4 6374 rc = ldap_modify_s(ldap_handle, ad_path, mods);
df2a74ce 6375
6c8f12af 6376 for (i = 0; i < n; i++)
6377 free(mods[i]);
df2a74ce 6378
6c8f12af 6379 if (rc != LDAP_SUCCESS)
6380 {
df2a74ce 6381 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6382 av[CONTAINER_NAME], ldap_err2string(rc));
6383 return(rc);
6c8f12af 6384 }
df2a74ce 6385
6c8f12af 6386 return(rc);
6387}
6388
6389int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6390{
6391 char *attr_array[3];
6392 LK_ENTRY *group_base;
6393 LK_ENTRY *pPtr;
6394 int group_count;
6395 char filter[512];
6396 char new_cn[128];
6397 char temp[256];
6398 int rc;
6399 int NumberOfEntries = 10;
6400 int i;
6401 int count;
6402
6403 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6404
6405 for (i = 0; i < 3; i++)
6406 {
6407 memset(filter, '\0', sizeof(filter));
df2a74ce 6408
6c8f12af 6409 if (i == 0)
6410 {
df2a74ce 6411 strcpy(filter, "(!(|(objectClass=computer)"
6412 "(objectClass=organizationalUnit)))");
6c8f12af 6413 attr_array[0] = "cn";
6414 attr_array[1] = NULL;
6415 }
6416 else if (i == 1)
6417 {
6418 strcpy(filter, "(objectClass=computer)");
6419 attr_array[0] = "cn";
6420 attr_array[1] = NULL;
6421 }
6422 else
6423 {
6424 strcpy(filter, "(objectClass=organizationalUnit)");
6425 attr_array[0] = "ou";
6426 attr_array[1] = NULL;
6427 }
6428
6429 while (1)
6430 {
6431 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
df2a74ce 6432 &group_base, &group_count,
6433 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6c8f12af 6434 {
6435 break;
6436 }
df2a74ce 6437
6c8f12af 6438 if (group_count == 0)
6439 break;
df2a74ce 6440
6c8f12af 6441 pPtr = group_base;
df2a74ce 6442
6c8f12af 6443 while(pPtr)
6444 {
6445 if (!strcasecmp(pPtr->attribute, "cn"))
6446 {
6447 sprintf(new_cn, "cn=%s", pPtr->value);
6448 if (i == 0)
6449 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6450 if (i == 1)
6451 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6452 count = 1;
df2a74ce 6453
6c8f12af 6454 while (1)
6455 {
6456 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6457 TRUE, NULL, NULL);
6458 if (rc == LDAP_ALREADY_EXISTS)
6459 {
6460 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6461 ++count;
6462 }
6463 else
6464 break;
6465 }
6466 }
6467 else if (!strcasecmp(pPtr->attribute, "ou"))
6468 {
6469 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6470 }
df2a74ce 6471
6c8f12af 6472 pPtr = pPtr->next;
6473 }
df2a74ce 6474
6c8f12af 6475 linklist_free(group_base);
6476 group_base = NULL;
6477 group_count = 0;
6478 }
6479 }
df2a74ce 6480
6c8f12af 6481 return(0);
6482}
5f7b0741 6483
df2a74ce 6484int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6485 char *machine_ou, char *NewMachineName)
5f7b0741 6486{
6487 LK_ENTRY *group_base;
6488 int group_count;
6489 int i;
6490 char filter[128];
6491 char *attr_array[3];
6492 char cn[256];
6493 char dn[256];
6494 char temp[256];
6495 char *pPtr;
6496 int rc;
6497
3abb4456 6498 strcpy(NewMachineName, member);
cc1e4a1d 6499 rc = moira_connect();
3abb4456 6500 rc = GetMachineName(NewMachineName);
cc1e4a1d 6501 moira_disconnect();
df2a74ce 6502
3abb4456 6503 if (strlen(NewMachineName) == 0)
6504 {
df2a74ce 6505 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6506 member);
3abb4456 6507 return(1);
6508 }
6509
5f7b0741 6510 pPtr = NULL;
3abb4456 6511 pPtr = strchr(NewMachineName, '.');
df2a74ce 6512
5f7b0741 6513 if (pPtr != NULL)
6514 (*pPtr) = '\0';
6515
6516 group_base = NULL;
6517 group_count = 0;
3abb4456 6518 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
5f7b0741 6519 attr_array[0] = "cn";
6520 attr_array[1] = NULL;
6521 sprintf(temp, "%s", dn_path);
df2a74ce 6522
5f7b0741 6523 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
df2a74ce 6524 &group_base, &group_count,
6525 LDAP_SCOPE_SUBTREE)) != 0)
5f7b0741 6526 {
4a6e2ee4 6527 com_err(whoami, 0, "Unable to process machine %s : %s",
5f7b0741 6528 member, ldap_err2string(rc));
6529 return(1);
6530 }
df2a74ce 6531
5f7b0741 6532 if (group_count != 1)
6533 {
df2a74ce 6534 com_err(whoami, 0,
6535 "Unable to process machine %s : machine not found in AD",
3abb4456 6536 NewMachineName);
5f7b0741 6537 return(1);
6538 }
df2a74ce 6539
5f7b0741 6540 strcpy(dn, group_base->dn);
6541 strcpy(cn, group_base->value);
df2a74ce 6542
5f7b0741 6543 for (i = 0; i < (int)strlen(dn); i++)
6544 dn[i] = tolower(dn[i]);
df2a74ce 6545
5f7b0741 6546 for (i = 0; i < (int)strlen(cn); i++)
6547 cn[i] = tolower(cn[i]);
df2a74ce 6548
5f7b0741 6549 linklist_free(group_base);
6550 pPtr = NULL;
6551 pPtr = strstr(dn, cn);
df2a74ce 6552
5f7b0741 6553 if (pPtr == NULL)
6554 {
4a6e2ee4 6555 com_err(whoami, 0, "Unable to process machine %s",
5f7b0741 6556 member);
6557 return(1);
6558 }
df2a74ce 6559
5f7b0741 6560 pPtr += strlen(cn) + 1;
6561 strcpy(machine_ou, pPtr);
6562 pPtr = NULL;
6563 pPtr = strstr(machine_ou, "dc=");
df2a74ce 6564
5f7b0741 6565 if (pPtr == NULL)
6566 {
4a6e2ee4 6567 com_err(whoami, 0, "Unable to process machine %s",
5f7b0741 6568 member);
6569 return(1);
6570 }
df2a74ce 6571
5f7b0741 6572 --pPtr;
6573 (*pPtr) = '\0';
df2a74ce 6574
5f7b0741 6575 return(0);
6576}
bbef4f93 6577
df2a74ce 6578int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6579 char *MoiraMachineName, char *DestinationOu)
bbef4f93 6580{
df2a74ce 6581 char NewCn[128];
6582 char OldDn[512];
6583 char MachineName[128];
6584 char filter[128];
6585 char *attr_array[3];
6586 char NewOu[256];
6587 char *cPtr = NULL;
6588 int group_count;
6589 long rc;
6590 LK_ENTRY *group_base;
bbef4f93 6591
df2a74ce 6592 group_count = 0;
6593 group_base = NULL;
6594
6595 strcpy(MachineName, MoiraMachineName);
6596 rc = GetMachineName(MachineName);
6597
6598 if (strlen(MachineName) == 0)
6599 {
6600 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6601 MoiraMachineName);
6602 return(1);
3abb4456 6603 }
df2a74ce 6604
6605 cPtr = strchr(MachineName, '.');
6606
6607 if (cPtr != NULL)
6608 (*cPtr) = '\0';
3abb4456 6609
df2a74ce 6610 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6611 attr_array[0] = "sAMAccountName";
6612 attr_array[1] = NULL;
6613
6614 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6615 &group_base,
6616 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
bbef4f93 6617 {
df2a74ce 6618 com_err(whoami, 0, "Unable to process machine %s : %s",
6619 MoiraMachineName, ldap_err2string(rc));
6620 return(1);
bbef4f93 6621 }
df2a74ce 6622
6623 if (group_count == 1)
6624 strcpy(OldDn, group_base->dn);
6625
6626 linklist_free(group_base);
6627 group_base = NULL;
bbef4f93 6628
df2a74ce 6629 if (group_count != 1)
bbef4f93 6630 {
df2a74ce 6631 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6632 MoiraMachineName);
6633 return(1);
bbef4f93 6634 }
df2a74ce 6635
6636 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6637 cPtr = strchr(OldDn, ',');
6638
6639 if (cPtr != NULL)
bbef4f93 6640 {
df2a74ce 6641 ++cPtr;
6642 if (!strcasecmp(cPtr, NewOu))
6643 return(0);
bbef4f93 6644 }
df2a74ce 6645
6646 sprintf(NewCn, "CN=%s", MachineName);
6647 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6648
6649 return(rc);
bbef4f93 6650}
6651
6652int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6653{
df2a74ce 6654 char Name[128];
6655 char *pPtr;
6656 int rc;
6657
6658 memset(Name, '\0', sizeof(Name));
6659 strcpy(Name, machine_name);
6660 pPtr = NULL;
6661 pPtr = strchr(Name, '.');
6662
6663 if (pPtr != NULL)
6664 (*pPtr) = '\0';
6665
6666 strcat(Name, "$");
6667 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
bbef4f93 6668}
6669
df2a74ce 6670int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6671 char *machine_name, char *container_name)
bbef4f93 6672{
df2a74ce 6673 int rc;
6674 char *av[2];
6675 char *call_args[2];
6676
6677 av[0] = machine_name;
6678 call_args[0] = (char *)container_name;
6679 rc = mr_query("get_machine_to_container_map", 1, av,
6680 machine_GetMoiraContainer, call_args);
6681 return(rc);
bbef4f93 6682}
6683
6684int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6685{
df2a74ce 6686 char **call_args;
6687
6688 call_args = ptr;
6689 strcpy(call_args[0], av[1]);
6690 return(0);
bbef4f93 6691}
6692
209367bd 6693int Moira_container_group_create(char **after)
6694{
6695 long rc;
6696 char GroupName[64];
c7fec834 6697 char *argv[20];
209367bd 6698
6699 memset(GroupName, '\0', sizeof(GroupName));
6700 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6701 after[CONTAINER_ROWID]);
6702 if (rc)
6703 return rc;
6704
6705 argv[L_NAME] = GroupName;
6706 argv[L_ACTIVE] = "1";
6707 argv[L_PUBLIC] = "0";
6708 argv[L_HIDDEN] = "0";
6709 argv[L_MAILLIST] = "0";
6710 argv[L_GROUP] = "1";
6711 argv[L_GID] = UNIQUE_GID;
6712 argv[L_NFSGROUP] = "0";
3fe96507 6713 argv[L_MAILMAN] = "0";
6714 argv[L_MAILMAN_SERVER] = "[NONE]";
209367bd 6715 argv[L_DESC] = "auto created container group";
6716 argv[L_ACE_TYPE] = "USER";
6717 argv[L_MEMACE_TYPE] = "USER";
6718 argv[L_ACE_NAME] = "sms";
6719 argv[L_MEMACE_NAME] = "sms";
6720
3fe96507 6721 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
209367bd 6722 {
df2a74ce 6723 com_err(whoami, 0,
6724 "Unable to create container group %s for container %s: %s",
209367bd 6725 GroupName, after[CONTAINER_NAME], error_message(rc));
6726 }
6727
6728 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6729 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6730
6731 return(rc);
6732}
6733
6734int Moira_container_group_update(char **before, char **after)
6735{
6736 long rc;
6737 char BeforeGroupName[64];
6738 char AfterGroupName[64];
c7fec834 6739 char *argv[20];
209367bd 6740
6741 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6742 return(0);
6743
6744 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6745 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6746 if (strlen(BeforeGroupName) == 0)
6747 return(0);
6748
6749 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6750 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6751 after[CONTAINER_ROWID]);
6752 if (rc)
6753 return rc;
6754
6755 if (strcasecmp(BeforeGroupName, AfterGroupName))
6756 {
6757 argv[L_NAME] = BeforeGroupName;
6758 argv[L_NAME + 1] = AfterGroupName;
6759 argv[L_ACTIVE + 1] = "1";
6760 argv[L_PUBLIC + 1] = "0";
50b4a32b 6761 argv[L_HIDDEN + 1] = "0";
209367bd 6762 argv[L_MAILLIST + 1] = "0";
6763 argv[L_GROUP + 1] = "1";
6764 argv[L_GID + 1] = UNIQUE_GID;
6765 argv[L_NFSGROUP + 1] = "0";
3fe96507 6766 argv[L_MAILMAN + 1] = "0";
6767 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
209367bd 6768 argv[L_DESC + 1] = "auto created container group";
6769 argv[L_ACE_TYPE + 1] = "USER";
6770 argv[L_MEMACE_TYPE + 1] = "USER";
6771 argv[L_ACE_NAME + 1] = "sms";
6772 argv[L_MEMACE_NAME + 1] = "sms";
6773
3fe96507 6774 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
209367bd 6775 {
df2a74ce 6776 com_err(whoami, 0,
6777 "Unable to rename container group from %s to %s: %s",
209367bd 6778 BeforeGroupName, AfterGroupName, error_message(rc));
6779 }
6780 }
6781
6782 return(rc);
6783}
6784
6785int Moira_container_group_delete(char **before)
6786{
6787 long rc = 0;
6788 char *argv[13];
6789 char GroupName[64];
6790 char ParentGroupName[64];
6791
6792 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6793 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6794
6795 memset(GroupName, '\0', sizeof(GroupName));
df2a74ce 6796
209367bd 6797 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6798 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6799
6800 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6801 {
6802 argv[0] = ParentGroupName;
6803 argv[1] = "LIST";
6804 argv[2] = GroupName;
df2a74ce 6805
209367bd 6806 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6807 {
df2a74ce 6808 com_err(whoami, 0,
6809 "Unable to delete container group %s from list: %s",
209367bd 6810 GroupName, ParentGroupName, error_message(rc));
6811 }
6812 }
6813
6814 if (strlen(GroupName) != 0)
6815 {
6816 argv[0] = GroupName;
df2a74ce 6817
209367bd 6818 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6819 {
4a6e2ee4 6820 com_err(whoami, 0, "Unable to delete container group %s : %s",
209367bd 6821 GroupName, error_message(rc));
6822 }
df2a74ce 6823 }
209367bd 6824
6825 return(rc);
6826}
6827
6828int Moira_groupname_create(char *GroupName, char *ContainerName,
6829 char *ContainerRowID)
6830{
6831 char *ptr;
6832 char *ptr1;
6833 char temp[64];
6834 char newGroupName[64];
6835 char tempGroupName[64];
e0e094af 6836 char tempgname[64];
209367bd 6837 char *argv[1];
6838 int i;
6839 long rc;
6840
6841 strcpy(temp, ContainerName);
6842
6843 ptr1 = strrchr(temp, '/');
df2a74ce 6844
209367bd 6845 if (ptr1 != NULL)
e0e094af 6846 {
6847 *ptr1 = '\0';
209367bd 6848 ptr = ++ptr1;
e0e094af 6849 ptr1 = strrchr(temp, '/');
df2a74ce 6850
e0e094af 6851 if (ptr1 != NULL)
6852 {
6853 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6854 }
6855 else
6856 strcpy(tempgname, ptr);
6857 }
209367bd 6858 else
e0e094af 6859 strcpy(tempgname, temp);
209367bd 6860
e0e094af 6861 if (strlen(tempgname) > 25)
6862 tempgname[25] ='\0';
209367bd 6863
e0e094af 6864 sprintf(newGroupName, "cnt-%s", tempgname);
209367bd 6865
6866 /* change everything to lower case */
6867 ptr = newGroupName;
df2a74ce 6868
209367bd 6869 while (*ptr)
6870 {
6871 if (isupper(*ptr))
6872 *ptr = tolower(*ptr);
df2a74ce 6873
209367bd 6874 if (*ptr == ' ')
6875 *ptr = '-';
df2a74ce 6876
209367bd 6877 ptr++;
6878 }
6879
6880 strcpy(tempGroupName, newGroupName);
6881 i = (int)'0';
df2a74ce 6882
209367bd 6883 /* append 0-9 then a-z if a duplicate is found */
6884 while(1)
6885 {
6886 argv[0] = newGroupName;
df2a74ce 6887
209367bd 6888 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6889 {
6890 if (rc == MR_NO_MATCH)
6891 break;
df2a74ce 6892 com_err(whoami, 0, "Moira error while creating group name for "
6893 "container %s : %s", ContainerName, error_message(rc));
209367bd 6894 return rc;
6895 }
df2a74ce 6896
209367bd 6897 sprintf(newGroupName, "%s-%c", tempGroupName, i);
df2a74ce 6898
209367bd 6899 if (i == (int)'z')
6900 {
df2a74ce 6901 com_err(whoami, 0, "Unable to find a unique group name for "
6902 "container %s: too many duplicate container names",
209367bd 6903 ContainerName);
6904 return 1;
6905 }
df2a74ce 6906
209367bd 6907 if (i == '9')
6908 i = 'a';
6909 else
6910 i++;
6911 }
6912
6913 strcpy(GroupName, newGroupName);
6914 return(0);
6915}
6916
6917int Moira_setContainerGroup(char *origContainerName, char *GroupName)
6918{
6919 long rc;
6920 char *argv[3];
6921
6922 argv[0] = origContainerName;
6923 argv[1] = GroupName;
df2a74ce 6924
209367bd 6925 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
6926 {
df2a74ce 6927 com_err(whoami, 0,
6928 "Unable to set container group %s in container %s: %s",
6929 GroupName, origContainerName, error_message(rc));
209367bd 6930 }
df2a74ce 6931
209367bd 6932 return(0);
6933}
6934
df2a74ce 6935int Moira_addGroupToParent(char *origContainerName, char *GroupName)
209367bd 6936 {
6937 char ContainerName[64];
6938 char ParentGroupName[64];
6939 char *argv[3];
6940 long rc;
6941
6942 strcpy(ContainerName, origContainerName);
df2a74ce 6943
209367bd 6944 Moira_getGroupName(ContainerName, ParentGroupName, 1);
df2a74ce 6945
209367bd 6946 /* top-level container */
6947 if (strlen(ParentGroupName) == 0)
6948 return(0);
6949
6950 argv[0] = ParentGroupName;
6951 argv[1] = "LIST";
6952 argv[2] = GroupName;
df2a74ce 6953
209367bd 6954 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
6955 {
df2a74ce 6956 com_err(whoami, 0,
6957 "Unable to add container group %s to parent group %s: %s",
209367bd 6958 GroupName, ParentGroupName, error_message(rc));
6959 }
df2a74ce 6960
209367bd 6961 return(0);
6962 }
6963
6964int Moira_getContainerGroup(int ac, char **av, void *ptr)
6965{
6966 char **call_args;
6967
6968 call_args = ptr;
6969 strcpy(call_args[0], av[1]);
df2a74ce 6970
209367bd 6971 return(0);
6972}
6973
6974int Moira_getGroupName(char *origContainerName, char *GroupName,
6975 int ParentFlag)
6976{
209367bd 6977 char ContainerName[64];
6978 char *argv[3];
6979 char *call_args[3];
6980 char *ptr;
6981 long rc;
6982
6983 strcpy(ContainerName, origContainerName);
6984
6985 if (ParentFlag)
6986 {
6987 ptr = strrchr(ContainerName, '/');
df2a74ce 6988
209367bd 6989 if (ptr != NULL)
6990 (*ptr) = '\0';
6991 else
6992 return(0);
6993 }
6994
6995 argv[0] = ContainerName;
6996 argv[1] = NULL;
6997 call_args[0] = GroupName;
6998 call_args[1] = NULL;
6999
7000 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7001 call_args)))
7002 {
7003 if (strlen(GroupName) != 0)
7004 return(0);
7005 }
7006
7007 if (rc)
4a6e2ee4 7008 com_err(whoami, 0, "Unable to get container group from container %s: %s",
209367bd 7009 ContainerName, error_message(rc));
7010 else
4a6e2ee4 7011 com_err(whoami, 0, "Unable to get container group from container %s",
209367bd 7012 ContainerName);
df2a74ce 7013
7014 return(0);
209367bd 7015}
7016
7017int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7018 int DeleteMachine)
7019{
7020 char *argv[3];
7021 long rc;
df2a74ce 7022
209367bd 7023 if (strcmp(GroupName, "[none]") == 0)
7024 return 0;
7025
7026 argv[0] = GroupName;
7027 argv[1] = "MACHINE";
7028 argv[2] = MachineName;
df2a74ce 7029
209367bd 7030 if (!DeleteMachine)
7031 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7032 else
7033 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
df2a74ce 7034
209367bd 7035 if (rc)
7036 {
4a6e2ee4 7037 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
209367bd 7038 MachineName, GroupName, error_message(rc));
7039 }
df2a74ce 7040
209367bd 7041 return(0);
7042}
3abb4456 7043
7044int GetMachineName(char *MachineName)
7045{
df2a74ce 7046 char *args[2];
7047 char NewMachineName[1024];
7048 char *szDot;
7049 int rc = 0;
7050 int i;
7051 DWORD dwLen = 0;
7052 char *call_args[2];
7053
7054 // If the address happens to be in the top-level MIT domain, great!
7055 strcpy(NewMachineName, MachineName);
3abb4456 7056
df2a74ce 7057 for (i = 0; i < (int)strlen(NewMachineName); i++)
7058 NewMachineName[i] = toupper(NewMachineName[i]);
7059
7060 szDot = strchr(NewMachineName,'.');
7061
7062 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
3abb4456 7063 {
df2a74ce 7064 return(0);
3abb4456 7065 }
df2a74ce 7066
7067 // If not, see if it has a Moira alias in the top-level MIT domain.
7068 memset(NewMachineName, '\0', sizeof(NewMachineName));
7069 args[0] = "*";
7070 args[1] = MachineName;
7071 call_args[0] = NewMachineName;
7072 call_args[1] = NULL;
3abb4456 7073
df2a74ce 7074 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7075 {
7076 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7077 MachineName, error_message(rc));
7078 strcpy(MachineName, "");
7079 return(0);
7080 }
7081
7082 if (strlen(NewMachineName) != 0)
7083 strcpy(MachineName, NewMachineName);
7084 else
7085 strcpy(MachineName, "");
3abb4456 7086
df2a74ce 7087 return(0);
3abb4456 7088}
7089
7090int ProcessMachineName(int ac, char **av, void *ptr)
7091{
df2a74ce 7092 char **call_args;
7093 char MachineName[1024];
7094 char *szDot;
7095 int i;
7096
7097 call_args = ptr;
3abb4456 7098
df2a74ce 7099 if (strlen(call_args[0]) == 0)
3abb4456 7100 {
df2a74ce 7101 strcpy(MachineName, av[0]);
7102
7103 for (i = 0; i < (int)strlen(MachineName); i++)
7104 MachineName[i] = toupper(MachineName[i]);
7105
7106 szDot = strchr(MachineName,'.');
7107
3abb4456 7108 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
df2a74ce 7109 {
3abb4456 7110 strcpy(call_args[0], MachineName);
df2a74ce 7111 }
3abb4456 7112 }
df2a74ce 7113
7114 return(0);
3abb4456 7115}
7116
7117void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7118{
df2a74ce 7119 int i;
7120
7121 if (*UseSFU30)
3abb4456 7122 {
df2a74ce 7123 for (i = 0; i < n; i++)
3abb4456 7124 {
df2a74ce 7125 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7126 mods[i]->mod_type = "uidNumber";
3abb4456 7127 }
df2a74ce 7128
7129 (*UseSFU30) = 0;
3abb4456 7130 }
df2a74ce 7131 else
3abb4456 7132 {
df2a74ce 7133 for (i = 0; i < n; i++)
3abb4456 7134 {
df2a74ce 7135 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7136 mods[i]->mod_type = "msSFU30UidNumber";
3abb4456 7137 }
df2a74ce 7138
7139 (*UseSFU30) = 1;
3abb4456 7140 }
7141}
7142
df2a74ce 7143int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7144 char *DistinguishedName,
3abb4456 7145 char *WinHomeDir, char *WinProfileDir,
7146 char **homedir_v, char **winProfile_v,
7147 char **drives_v, LDAPMod **mods,
7148 int OpType, int n)
7149{
df2a74ce 7150 char **hp;
7151 char cWeight[3];
7152 char cPath[1024];
7153 char path[1024];
7154 char winPath[1024];
7155 char winProfile[1024];
7156 char homeDrive[8];
7157 int last_weight;
7158 int i;
7159 int rc;
7160 LDAPMod *DelMods[20];
7161
7162 memset(homeDrive, '\0', sizeof(homeDrive));
7163 memset(path, '\0', sizeof(path));
7164 memset(winPath, '\0', sizeof(winPath));
7165 memset(winProfile, '\0', sizeof(winProfile));
7166 hp = NULL;
7167
7168 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7169 (!strcasecmp(WinProfileDir, "[afs]")))
7170 {
7171 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
3abb4456 7172 {
df2a74ce 7173 memset(cWeight, 0, sizeof(cWeight));
7174 memset(cPath, 0, sizeof(cPath));
7175 last_weight = 1000;
7176 i = 0;
7177
7178 while (hp[i] != NULL)
3abb4456 7179 {
df2a74ce 7180 if (sscanf(hp[i], "%*s %s", cPath))
3abb4456 7181 {
df2a74ce 7182 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
3abb4456 7183 {
df2a74ce 7184 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
3abb4456 7185 {
df2a74ce 7186 if (atoi(cWeight) < last_weight)
3abb4456 7187 {
df2a74ce 7188 strcpy(path, cPath);
7189 last_weight = (int)atoi(cWeight);
3abb4456 7190 }
7191 }
df2a74ce 7192 else
7193 strcpy(path, cPath);
3abb4456 7194 }
7195 }
7196 ++i;
7197 }
df2a74ce 7198
7199 if (strlen(path))
3abb4456 7200 {
df2a74ce 7201 if (!strnicmp(path, AFS, strlen(AFS)))
3abb4456 7202 {
df2a74ce 7203 AfsToWinAfs(path, winPath);
7204 strcpy(winProfile, winPath);
7205 strcat(winProfile, "\\.winprofile");
3abb4456 7206 }
7207 }
7208 }
df2a74ce 7209 else
7210 return(n);
3abb4456 7211 }
7212
df2a74ce 7213 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7214 (!strcasecmp(WinProfileDir, "[dfs]")))
e0e094af 7215 {
df2a74ce 7216 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7217 user_name[0], user_name);
e0e094af 7218
df2a74ce 7219 if (!strcasecmp(WinProfileDir, "[dfs]"))
7220 {
7221 strcpy(winProfile, path);
7222 strcat(winProfile, "\\.winprofile");
7223 }
7224
7225 if (!strcasecmp(WinHomeDir, "[dfs]"))
7226 strcpy(winPath, path);
7227 }
7228
3abb4456 7229 if (hp != NULL)
df2a74ce 7230 {
3abb4456 7231 i = 0;
7232 while (hp[i])
df2a74ce 7233 {
3abb4456 7234 free(hp[i]);
7235 i++;
df2a74ce 7236 }
7237 }
7238
3abb4456 7239 if (!strcasecmp(WinHomeDir, "[local]"))
df2a74ce 7240 memset(winPath, '\0', sizeof(winPath));
7241 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7242 !strcasecmp(WinHomeDir, "[dfs]"))
7243 {
3abb4456 7244 strcpy(homeDrive, "H:");
df2a74ce 7245 }
3abb4456 7246 else
df2a74ce 7247 {
3abb4456 7248 strcpy(winPath, WinHomeDir);
7249 if (!strncmp(WinHomeDir, "\\\\", 2))
df2a74ce 7250 {
3abb4456 7251 strcpy(homeDrive, "H:");
df2a74ce 7252 }
7253 }
7254
3abb4456 7255 // nothing needs to be done if WinProfileDir is [afs].
7256 if (!strcasecmp(WinProfileDir, "[local]"))
df2a74ce 7257 memset(winProfile, '\0', sizeof(winProfile));
7258 else if (strcasecmp(WinProfileDir, "[afs]") &&
7259 strcasecmp(WinProfileDir, "[dfs]"))
7260 {
3abb4456 7261 strcpy(winProfile, WinProfileDir);
df2a74ce 7262 }
7263
3abb4456 7264 if (strlen(winProfile) != 0)
df2a74ce 7265 {
3abb4456 7266 if (winProfile[strlen(winProfile) - 1] == '\\')
df2a74ce 7267 winProfile[strlen(winProfile) - 1] = '\0';
7268 }
7269
3abb4456 7270 if (strlen(winPath) != 0)
df2a74ce 7271 {
3abb4456 7272 if (winPath[strlen(winPath) - 1] == '\\')
df2a74ce 7273 winPath[strlen(winPath) - 1] = '\0';
7274 }
7275
3abb4456 7276 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
df2a74ce 7277 strcat(winProfile, "\\");
3abb4456 7278
df2a74ce 7279 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7280 strcat(winPath, "\\");
7281
3abb4456 7282 if (strlen(winPath) == 0)
df2a74ce 7283 {
3abb4456 7284 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7285 {
3abb4456 7286 i = 0;
7287 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7288 DelMods[i] = NULL;
7289 //unset homeDirectory attribute for user.
7290 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7291 free(DelMods[0]);
df2a74ce 7292 }
7293 }
3abb4456 7294 else
df2a74ce 7295 {
3abb4456 7296 homedir_v[0] = strdup(winPath);
7297 ADD_ATTR("homeDirectory", homedir_v, OpType);
df2a74ce 7298 }
7299
3abb4456 7300 if (strlen(winProfile) == 0)
df2a74ce 7301 {
3abb4456 7302 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7303 {
3abb4456 7304 i = 0;
7305 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7306 DelMods[i] = NULL;
7307 //unset profilePate attribute for user.
7308 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7309 free(DelMods[0]);
df2a74ce 7310 }
7311 }
3abb4456 7312 else
df2a74ce 7313 {
3abb4456 7314 winProfile_v[0] = strdup(winProfile);
7315 ADD_ATTR("profilePath", winProfile_v, OpType);
df2a74ce 7316 }
7317
3abb4456 7318 if (strlen(homeDrive) == 0)
df2a74ce 7319 {
3abb4456 7320 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7321 {
3abb4456 7322 i = 0;
7323 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7324 DelMods[i] = NULL;
7325 //unset homeDrive attribute for user
7326 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7327 free(DelMods[0]);
df2a74ce 7328 }
7329 }
3abb4456 7330 else
df2a74ce 7331 {
3abb4456 7332 drives_v[0] = strdup(homeDrive);
7333 ADD_ATTR("homeDrive", drives_v, OpType);
df2a74ce 7334 }
3abb4456 7335
7336 return(n);
7337}
d7051053 7338
4a6e2ee4 7339int attribute_update(LDAP *ldap_handle, char *distinguished_name,
df2a74ce 7340 char *attribute_value, char *attribute, char *user_name)
4a6e2ee4 7341{
7342 char *mod_v[] = {NULL, NULL};
7343 LDAPMod *DelMods[20];
7344 LDAPMod *mods[20];
7345 int n;
7346 int i;
7347 int rc;
df2a74ce 7348
4a6e2ee4 7349 if (strlen(attribute_value) == 0)
7350 {
7351 i = 0;
7352 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7353 DelMods[i] = NULL;
7354 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7355 free(DelMods[0]);
7356 }
df2a74ce 7357 else
4a6e2ee4 7358 {
7359 n = 0;
7360 mod_v[0] = attribute_value;
7361 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7362 mods[n] = NULL;
df2a74ce 7363
7364 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7365 mods)) != LDAP_SUCCESS)
4a6e2ee4 7366 {
7367 free(mods[0]);
7368 n = 0;
7369 mod_v[0] = attribute_value;
7370 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7371 mods[n] = NULL;
df2a74ce 7372
7373 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7374 mods)) != LDAP_SUCCESS)
4a6e2ee4 7375 {
df2a74ce 7376 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7377 "in the AD : %s",
4a6e2ee4 7378 attribute, user_name, ldap_err2string(rc));
7379 }
7380 }
df2a74ce 7381
4a6e2ee4 7382 free(mods[0]);
7383 }
df2a74ce 7384
4a6e2ee4 7385 return(rc);
7386}
26503e15 7387
df2a74ce 7388void StringTrim(char *StringToTrim)
26503e15 7389{
df2a74ce 7390 char *t, *s;
7391 char *save;
26503e15 7392
df2a74ce 7393 save = strdup(StringToTrim);
26503e15 7394
df2a74ce 7395 s = save;
26503e15 7396
df2a74ce 7397 while (isspace(*s))
7398 s++;
26503e15 7399
df2a74ce 7400 /* skip to end of string */
7401 if (*s == '\0')
26503e15 7402 {
df2a74ce 7403 if (*save)
7404 *save = '\0';
7405 strcpy(StringToTrim, save);
7406 return;
26503e15 7407 }
df2a74ce 7408
7409 for (t = s; *t; t++)
7410 continue;
26503e15 7411
df2a74ce 7412 while (t > s)
26503e15 7413 {
df2a74ce 7414 --t;
7415 if (!isspace(*t))
7416 {
7417 t++;
7418 break;
7419 }
26503e15 7420 }
7421
df2a74ce 7422 if (*t)
7423 *t = '\0';
7424
7425 strcpy(StringToTrim, s);
7426 return;
26503e15 7427}
7428
6a4366ac 7429int ReadConfigFile(char *DomainName)
26503e15 7430{
7431 int Count;
7432 int i;
7433 int k;
7434 char temp[256];
7435 char temp1[256];
7436 FILE *fptr;
7437
7438 Count = 0;
7439
6a4366ac 7440 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
df2a74ce 7441
6a4366ac 7442 if ((fptr = fopen(temp, "r")) != NULL)
df2a74ce 7443 {
26503e15 7444 while (fgets(temp, sizeof(temp), fptr) != 0)
df2a74ce 7445 {
26503e15 7446 for (i = 0; i < (int)strlen(temp); i++)
df2a74ce 7447 temp[i] = toupper(temp[i]);
7448
26503e15 7449 if (temp[strlen(temp) - 1] == '\n')
df2a74ce 7450 temp[strlen(temp) - 1] = '\0';
7451
26503e15 7452 StringTrim(temp);
df2a74ce 7453
26503e15 7454 if (strlen(temp) == 0)
df2a74ce 7455 continue;
7456
26503e15 7457 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
df2a74ce 7458 {
26503e15 7459 if (strlen(temp) > (strlen(DOMAIN)))
df2a74ce 7460 {
26503e15 7461 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7462 StringTrim(ldap_domain);
df2a74ce 7463 }
7464 }
26503e15 7465 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
df2a74ce 7466 {
26503e15 7467 if (strlen(temp) > (strlen(PRINCIPALNAME)))
df2a74ce 7468 {
26503e15 7469 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7470 StringTrim(PrincipalName);
df2a74ce 7471 }
7472 }
26503e15 7473 else if (!strncmp(temp, SERVER, strlen(SERVER)))
df2a74ce 7474 {
26503e15 7475 if (strlen(temp) > (strlen(SERVER)))
df2a74ce 7476 {
26503e15 7477 ServerList[Count] = calloc(1, 256);
7478 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7479 StringTrim(ServerList[Count]);
7480 ++Count;
df2a74ce 7481 }
7482 }
26503e15 7483 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
df2a74ce 7484 {
26503e15 7485 if (strlen(temp) > (strlen(MSSFU)))
df2a74ce 7486 {
26503e15 7487 strcpy(temp1, &temp[strlen(MSSFU)]);
7488 StringTrim(temp1);
7489 if (!strcmp(temp1, SFUTYPE))
df2a74ce 7490 UseSFU30 = 1;
7491 }
7492 }
7493 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7494 {
7495 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7496 {
7497 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7498 StringTrim(temp1);
7499 if (!strcasecmp(temp1, "NO"))
7500 {
7501 UseGroupSuffix = 0;
7502 memset(group_suffix, '\0', sizeof(group_suffix));
7503 }
7504 }
7505 }
7506 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7507 {
7508 if (strlen(temp) > (strlen(GROUP_TYPE)))
7509 {
7510 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7511 StringTrim(temp1);
7512 if (!strcasecmp(temp1, "UNIVERSAL"))
7513 UseGroupUniversal = 1;
7514 }
7515 }
7516 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7517 {
7518 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7519 {
7520 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7521 StringTrim(temp1);
7522 if (!strcasecmp(temp1, "NO"))
7523 SetGroupAce = 0;
7524 }
7525 }
7526 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7527 {
7528 if (strlen(temp) > (strlen(SET_PASSWORD)))
7529 {
7530 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7531 StringTrim(temp1);
7532 if (!strcasecmp(temp1, "NO"))
7533 SetPassword = 0;
7534 }
7535 }
7536 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7537 {
7538 if (strlen(temp) > (strlen(EXCHANGE)))
7539 {
7540 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7541 StringTrim(temp1);
7542 if (!strcasecmp(temp1, "YES"))
7543 Exchange = 1;
7544 }
7545 }
7546 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7547 strlen(PROCESS_MACHINE_CONTAINER)))
7548 {
7549 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7550 {
7551 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7552 StringTrim(temp1);
7553 if (!strcasecmp(temp1, "NO"))
7554 ProcessMachineContainer = 0;
7555 }
7556 }
26503e15 7557 else
df2a74ce 7558 {
26503e15 7559 if (strlen(ldap_domain) != 0)
df2a74ce 7560 {
26503e15 7561 memset(ldap_domain, '\0', sizeof(ldap_domain));
7562 break;
df2a74ce 7563 }
7564
26503e15 7565 if (strlen(temp) != 0)
df2a74ce 7566 strcpy(ldap_domain, temp);
7567 }
7568 }
26503e15 7569 fclose(fptr);
df2a74ce 7570 }
7571
26503e15 7572 if (strlen(ldap_domain) == 0)
df2a74ce 7573 {
6a4366ac 7574 strcpy(ldap_domain, DomainName);
df2a74ce 7575 }
7576
26503e15 7577 if (Count == 0)
6a4366ac 7578 return(0);
df2a74ce 7579
26503e15 7580 for (i = 0; i < Count; i++)
df2a74ce 7581 {
26503e15 7582 if (ServerList[i] != 0)
df2a74ce 7583 {
26503e15 7584 strcat(ServerList[i], ".");
7585 strcat(ServerList[i], ldap_domain);
7586 for (k = 0; k < (int)strlen(ServerList[i]); k++)
df2a74ce 7587 ServerList[i][k] = toupper(ServerList[i][k]);
7588 }
7589 }
7590
6a4366ac 7591 return(0);
7592}
7593
7594int ReadDomainList()
7595{
7596 int Count;
7597 int i;
7598 char temp[128];
7599 char temp1[128];
7600 FILE *fptr;
7601 unsigned char c[11];
7602 unsigned char stuff[256];
7603 int rc;
7604 int ok;
7605
7606 Count = 0;
7607 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
df2a74ce 7608
6a4366ac 7609 if ((fptr = fopen(temp, "r")) != NULL)
7610 {
7611 while (fgets(temp, sizeof(temp), fptr) != 0)
7612 {
7613 for (i = 0; i < (int)strlen(temp); i++)
7614 temp[i] = toupper(temp[i]);
df2a74ce 7615
6a4366ac 7616 if (temp[strlen(temp) - 1] == '\n')
7617 temp[strlen(temp) - 1] = '\0';
df2a74ce 7618
6a4366ac 7619 StringTrim(temp);
df2a74ce 7620
6a4366ac 7621 if (strlen(temp) == 0)
7622 continue;
df2a74ce 7623
6a4366ac 7624 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7625 {
7626 if (strlen(temp) > (strlen(DOMAIN)))
7627 {
7628 strcpy(temp1, &temp[strlen(DOMAIN)]);
7629 StringTrim(temp1);
7630 strcpy(temp, temp1);
7631 }
7632 }
df2a74ce 7633
7634 strcpy(DomainNames[Count], temp);
7635 StringTrim(DomainNames[Count]);
7636 ++Count;
6a4366ac 7637 }
df2a74ce 7638
6a4366ac 7639 fclose(fptr);
7640 }
df2a74ce 7641
6a4366ac 7642 if (Count == 0)
7643 {
df2a74ce 7644 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7645 "configuration error in winad.cfg");
6a4366ac 7646 return(1);
7647 }
df2a74ce 7648
6a4366ac 7649 return(0);
7650}
26503e15 7651
df2a74ce 7652int email_isvalid(const char *address) {
7653 int count = 0;
7654 const char *c, *domain;
7655 static char *rfc822_specials = "()<>@,;:\\\"[]";
7656
7657 if(address[strlen(address) - 1] == '.')
7658 return 0;
7659
7660 /* first we validate the name portion (name@domain) */
7661 for (c = address; *c; c++) {
7662 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7663 '\"')) {
7664 while (*++c) {
7665 if (*c == '\"')
7666 break;
7667 if (*c == '\\' && (*++c == ' '))
7668 continue;
7669 if (*c <= ' ' || *c >= 127)
7670 return 0;
7671 }
7672
7673 if (!*c++)
7674 return 0;
7675 if (*c == '@')
7676 break;
7677 if (*c != '.')
7678 return 0;
7679 continue;
7680 }
7681
7682 if (*c == '@')
7683 break;
7684 if (*c <= ' ' || *c >= 127)
7685 return 0;
7686 if (strchr(rfc822_specials, *c))
7687 return 0;
7688 }
7689
7690 if (c == address || *(c - 1) == '.')
7691 return 0;
7692
7693 /* next we validate the domain portion (name@domain) */
7694 if (!*(domain = ++c)) return 0;
7695 do {
7696 if (*c == '.') {
7697 if (c == domain || *(c - 1) == '.')
7698 return 0;
7699 count++;
7700 }
7701 if (*c <= ' ' || *c >= 127)
7702 return 0;
7703 if (strchr(rfc822_specials, *c))
7704 return 0;
7705 } while (*++c);
7706
7707 return (count >= 1);
7708}
7709
7710int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7711 char **homeServerName)
6a4366ac 7712{
df2a74ce 7713 LK_ENTRY *group_base;
7714 LK_ENTRY *sub_group_base;
7715 LK_ENTRY *gPtr;
7716 LK_ENTRY *sub_gPtr;
7717 int group_count;
7718 int sub_group_count;
7719 char filter[1024];
7720 char sub_filter[1024];
7721 char search_path[1024];
7722 char range[1024];
7723 char *attr_array[3];
7724 char *s;
7725 int homeMDB_count = -1;
7726 int rc;
7727 int i;
7728 int mdbbl_count;
7729 int rangeStep = 1500;
7730 int rangeLow = 0;
7731 int rangeHigh = rangeLow + (rangeStep - 1);
7732 int isLast = 0;
7733
7734 /* Grumble..... microsoft not making it searchable from the root *grr* */
7735
7736 memset(filter, '\0', sizeof(filter));
7737 memset(search_path, '\0', sizeof(search_path));
6a4366ac 7738
df2a74ce 7739 sprintf(filter, "(objectClass=msExchMDB)");
7740 sprintf(search_path, "CN=Configuration,%s", dn_path);
7741 attr_array[0] = "distinguishedName";
7742 attr_array[1] = NULL;
7743
7744 group_base = NULL;
7745 group_count = 0;
7746
7747 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7748 &group_base, &group_count,
7749 LDAP_SCOPE_SUBTREE)) != 0)
6a4366ac 7750 {
df2a74ce 7751 com_err(whoami, 0, "Unable to find msExchMDB %s",
7752 ldap_err2string(rc));
7753 return(rc);
7754 }
7755
7756 if (group_count)
7757 {
7758 gPtr = group_base;
7759
7760 while(gPtr) {
7761 if ((s = strstr(gPtr->dn, "Public")) != (char *) NULL)
7762 {
7763 gPtr = gPtr->next;
7764 continue;
7765 }
7766
7767 /*
7768 * Due to limits in active directory we need to use the LDAP
7769 * range semantics to query and return all the values in
7770 * large lists, we will stop increasing the range when
7771 * the result count is 0.
7772 */
7773
7774 i = 0;
7775 mdbbl_count = 0;
7776
7777 for(;;)
7778 {
7779 memset(sub_filter, '\0', sizeof(sub_filter));
7780 memset(range, '\0', sizeof(range));
7781 sprintf(sub_filter, "(objectClass=msExchMDB)");
7782
7783 if(isLast)
7784 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
7785 else
7786 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
7787
7788 attr_array[0] = range;
7789 attr_array[1] = NULL;
7790
7791 sub_group_base = NULL;
7792 sub_group_count = 0;
7793
7794 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
7795 attr_array, &sub_group_base,
7796 &sub_group_count,
7797 LDAP_SCOPE_SUBTREE)) != 0)
7798 {
7799 com_err(whoami, 0, "Unable to find homeMDBBL %s",
7800 ldap_err2string(rc));
7801 return(rc);
7802 }
7803
7804 if(!sub_group_count)
7805 {
7806 if(isLast)
7807 {
7808 isLast = 0;
7809 rangeLow = 0;
7810 rangeHigh = rangeLow + (rangeStep - 1);
7811 break;
7812 }
7813 else
7814 isLast++;
7815 }
7816
7817 mdbbl_count += sub_group_count;
7818 rangeLow = rangeHigh + 1;
7819 rangeHigh = rangeLow + (rangeStep - 1);
7820 }
7821
7822 /* First time through, need to initialize or update the least used */
7823
7824 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
7825 mdbbl_count);
7826
7827 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
7828 {
7829 homeMDB_count = mdbbl_count;
7830 *homeMDB = strdup(gPtr->dn);
7831 }
7832
7833 gPtr = gPtr->next;
7834 linklist_free(sub_group_base);
7835 }
7836 }
7837
7838 linklist_free(group_base);
7839
7840 /*
7841 * Ok found the server least allocated need to now query to get its
7842 * msExchHomeServerName so we can set it as a user attribute
7843 */
7844
7845 attr_array[0] = "legacyExchangeDN";
7846 attr_array[1] = NULL;
7847
7848 group_count = 0;
7849 group_base = NULL;
7850
7851 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
7852 attr_array, &group_base,
7853 &group_count,
7854 LDAP_SCOPE_SUBTREE)) != 0)
7855 {
7856 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
7857 ldap_err2string(rc));
7858 return(rc);
7859 }
7860
7861 if(group_count)
7862 {
7863 *homeServerName = strdup(group_base->value);
7864 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
6a4366ac 7865 {
df2a74ce 7866 *s = '\0';
6a4366ac 7867 }
df2a74ce 7868 }
7869
7870 linklist_free(group_base);
7871
7872 return(rc);
7873}
7874
7875char *lowercase(char *s)
7876{
7877 char *p;
7878
7879 for (p = s; *p; p++)
7880 {
7881 if (isupper(*p))
7882 *p = tolower(*p);
7883 }
7884 return s;
7885}
7886
7887char *uppercase(char *s)
7888{
7889 char *p;
7890
7891 for (p = s; *p; p++)
7892 {
7893 if (islower(*p))
7894 *p = toupper(*p);
6a4366ac 7895 }
df2a74ce 7896 return s;
7897}
7898
7899int save_query_info(int argc, char **argv, void *hint)
7900{
7901 int i;
7902 char **nargv = hint;
7903
7904 for(i = 0; i < argc; i++)
7905 nargv[i] = strdup(argv[i]);
7906
7907 return MR_CONT;
26503e15 7908}
This page took 1.614894 seconds and 5 git commands to generate.