]> andersk Git - moira.git/blame - incremental/winad/winad.c
From mark.
[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};
268bfb91 2343 char *report_to_originator_v[] = {NULL, NULL};
df2a74ce 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;
268bfb91 2516 report_to_originator_v[0] = "TRUE";
2517
df2a74ce 2518 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2519 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2520 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
268bfb91 2521 ADD_ATTR("reportToOriginator", report_to_originator_v,
2522 LDAP_MOD_REPLACE);
df2a74ce 2523 }
2524 else
2525 {
2526 mail_nickname_v[0] = NULL;
2527 proxy_address_v[0] = NULL;
2528 mail_v[0] = NULL;
ac4fbabf 2529 legacy_exchange_dn_v[0] = NULL;
2530 address_book_v[0] = NULL;
268bfb91 2531 report_to_originator_v[0] = NULL;
ac4fbabf 2532
df2a74ce 2533 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2534 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2535 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2536 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v, LDAP_MOD_REPLACE);
2537 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
268bfb91 2538 ADD_ATTR("reportToOriginator", report_to_originator_v,
2539 LDAP_MOD_REPLACE);
df2a74ce 2540 }
2541 }
2542 else
2543 {
2544 if(atoi(maillist) && email_isvalid(contact_mail))
2545 {
2546 mail_v[0] = contact_mail;
2547 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2548 }
2549 }
2550
9db0b148 2551 mods[n] = NULL;
df2a74ce 2552
f75f605a 2553 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
78af4e6e 2554 {
df2a74ce 2555 com_err(whoami, 0,
2556 "Unable to modify list data for %s after renaming: %s",
f75f605a 2557 after_group_name, ldap_err2string(rc));
78af4e6e 2558 }
df2a74ce 2559
9db0b148 2560 for (i = 0; i < n; i++)
2561 free(mods[i]);
df2a74ce 2562
f75f605a 2563 return(rc);
9db0b148 2564}
2565
cd9e6b16 2566int group_create(int ac, char **av, void *ptr)
2567{
2568 LDAPMod *mods[20];
2569 char new_dn[256];
2570 char group_ou[256];
2571 char new_group_name[256];
2572 char sam_group_name[256];
2573 char cn_group_name[256];
df2a74ce 2574 char mail[256];
2575 char contact_mail[256];
2576 char mail_nickname[256];
2577 char proxy_address[256];
2578 char address_book[256];
cd9e6b16 2579 char *cn_v[] = {NULL, NULL};
2580 char *objectClass_v[] = {"top", "group", NULL};
2581 char info[256];
2582 char *samAccountName_v[] = {NULL, NULL};
cd9e6b16 2583 char *altSecurityIdentities_v[] = {NULL, NULL};
89db421e 2584 char *member_v[] = {NULL, NULL};
cd9e6b16 2585 char *name_v[] = {NULL, NULL};
2586 char *desc_v[] = {NULL, NULL};
2587 char *info_v[] = {NULL, NULL};
89db421e 2588 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 2589 char *groupTypeControl_v[] = {NULL, NULL};
df2a74ce 2590 char *mail_v[] = {NULL, NULL};
2591 char *proxy_address_v[] = {NULL, NULL};
2592 char *mail_nickname_v[] = {NULL, NULL};
268bfb91 2593 char *report_to_originator_v[] = {NULL, NULL};
df2a74ce 2594 char *address_book_v[] = {NULL, NULL};
2595 char *legacy_exchange_dn_v[] = {NULL, NULL};
cd9e6b16 2596 char groupTypeControlStr[80];
2597 char group_membership[1];
2598 int i;
2599 int security_flag;
df2a74ce 2600 u_int groupTypeControl;
cd9e6b16 2601 int n;
2602 int rc;
89db421e 2603 int updateGroup;
ac4fbabf 2604 int MailDisabled = 0;
cd9e6b16 2605 char **call_args;
ac4fbabf 2606 LK_ENTRY *group_base;
2607 int group_count;
2608 char filter[1024];
2609 char *attr_array[3];
2610
cd9e6b16 2611 call_args = ptr;
2612
df2a74ce 2613 if(UseGroupUniversal)
2614 groupTypeControl = ADS_GROUP_TYPE_UNIVERSAL_GROUP;
2615 else
2616 groupTypeControl = ADS_GROUP_TYPE_GLOBAL_GROUP;
2617
cd9e6b16 2618 if (!check_string(av[L_NAME]))
78af4e6e 2619 {
df2a74ce 2620 com_err(whoami, 0, "Unable to process invalid LDAP list name %s",
2621 av[L_NAME]);
89db421e 2622 return(AD_INVALID_NAME);
78af4e6e 2623 }
f75f605a 2624
89db421e 2625 updateGroup = (int)call_args[4];
cd9e6b16 2626 memset(group_ou, 0, sizeof(group_ou));
2627 memset(group_membership, 0, sizeof(group_membership));
2628 security_flag = 0;
df2a74ce 2629
cd9e6b16 2630 get_group_membership(group_membership, group_ou, &security_flag, av);
df2a74ce 2631
89db421e 2632 strcpy(new_group_name, av[L_NAME]);
2633 sprintf(new_dn, "cn=%s,%s,%s", new_group_name, group_ou, call_args[1]);
df2a74ce 2634 sprintf(contact_mail, "%s@mit.edu", av[L_NAME]);
2635 sprintf(mail, "%s@%s", av[L_NAME], lowercase(ldap_domain));
2636 sprintf(mail_nickname, "%s", av[L_NAME]);
2637
cd9e6b16 2638 if (security_flag)
2639 groupTypeControl |= ADS_GROUP_TYPE_SECURITY_ENABLED;
89db421e 2640
df2a74ce 2641 sprintf(sam_group_name, "%s%s", av[L_NAME], group_suffix);
cd9e6b16 2642
89db421e 2643 if (!updateGroup)
2644 {
89db421e 2645 sprintf(groupTypeControlStr, "%ld", groupTypeControl);
2646 groupTypeControl_v[0] = groupTypeControlStr;
cd9e6b16 2647
89db421e 2648 strcpy(cn_group_name, av[L_NAME]);
df2a74ce 2649
89db421e 2650 samAccountName_v[0] = sam_group_name;
2651 name_v[0] = new_group_name;
2652 cn_v[0] = new_group_name;
cd9e6b16 2653
89db421e 2654 n = 0;
2655 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
2656 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
2657 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
2658 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
2659 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
ac4fbabf 2660
df2a74ce 2661 if (Exchange)
2662 {
ac4fbabf 2663 if(atoi(av[L_MAILLIST]))
2664 {
2665 group_count = 0;
2666 group_base = NULL;
2667
2668 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2669 attr_array[0] = "cn";
2670 attr_array[1] = NULL;
2671
2672 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2673 filter, attr_array, &group_base,
2674 &group_count,
2675 LDAP_SCOPE_SUBTREE)) != 0)
2676 {
2677 com_err(whoami, 0, "Unable to process group %s : %s",
2678 av[L_NAME], ldap_err2string(rc));
2679 return(rc);
2680 }
2681
2682 if (group_count)
2683 {
2684 com_err(whoami, 0, "Object already exists with name %s",
2685 av[L_NAME]);
2686 MailDisabled++;
2687 }
2688
2689 linklist_free(group_base);
2690 group_base = NULL;
2691 group_count = 0;
2692 }
2693
df2a74ce 2694 if(atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2695 {
2696 mail_nickname_v[0] = mail_nickname;
268bfb91 2697 report_to_originator_v[0] = "TRUE";
2698
df2a74ce 2699 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
268bfb91 2700 ADD_ATTR("reportToOriginator", report_to_originator_v,
2701 LDAP_MOD_ADD);
df2a74ce 2702 }
2703 }
2704 else
2705 {
2706 if(atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2707 {
2708 mail_v[0] = contact_mail;
2709 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
2710 }
2711 }
ac4fbabf 2712
89db421e 2713 if (strlen(av[L_DESC]) != 0)
ac4fbabf 2714 {
2715 desc_v[0] = av[L_DESC];
2716 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
2717 }
2718
89db421e 2719 ADD_ATTR("groupType", groupTypeControl_v, LDAP_MOD_ADD);
ac4fbabf 2720
89db421e 2721 if (strlen(av[L_ACE_NAME]) != 0)
2722 {
df2a74ce 2723 sprintf(info, "The Administrator of this list is: %s",
2724 av[L_ACE_NAME]);
89db421e 2725 info_v[0] = info;
2726 ADD_ATTR("info", info_v, LDAP_MOD_ADD);
2727 }
df2a74ce 2728
89db421e 2729 if (strlen(call_args[5]) != 0)
2730 {
2731 mitMoiraId_v[0] = call_args[5];
2732 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
2733 }
89db421e 2734
df2a74ce 2735 mods[n] = NULL;
2736
89db421e 2737 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
df2a74ce 2738
89db421e 2739 for (i = 0; i < n; i++)
2740 free(mods[i]);
df2a74ce 2741
89db421e 2742 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
2743 {
909e0dc3 2744 com_err(whoami, 0, "Unable to create list %s in AD : %s",
89db421e 2745 av[L_NAME], ldap_err2string(rc));
2746 callback_rc = rc;
2747 return(rc);
2748 }
78af4e6e 2749 }
df2a74ce 2750
89db421e 2751 if ((rc == LDAP_ALREADY_EXISTS) || (updateGroup))
5a775f54 2752 {
df2a74ce 2753 rc = attribute_update((LDAP *)call_args[0], new_dn, av[L_DESC],
2754 "description", av[L_NAME]);
4a6e2ee4 2755 sprintf(info, "The Administrator of this list is: %s", av[L_ACE_NAME]);
df2a74ce 2756 rc = attribute_update((LDAP *)call_args[0], new_dn, info, "info",
2757 av[L_NAME]);
5a775f54 2758 n = 0;
df2a74ce 2759
89db421e 2760 if (strlen(call_args[5]) != 0)
2761 {
2762 mitMoiraId_v[0] = call_args[5];
2763 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
2764 }
df2a74ce 2765
89db421e 2766 if (!(atoi(av[L_ACTIVE])))
2767 {
2768 member_v[0] = NULL;
2769 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
2770 }
df2a74ce 2771
2772 if (Exchange)
2773 {
ac4fbabf 2774 if(atoi(av[L_MAILLIST]))
2775 {
2776 group_count = 0;
2777 group_base = NULL;
2778
2779 sprintf(filter, "(&(objectClass=user)(cn=%s))", av[L_NAME]);
2780 attr_array[0] = "cn";
2781 attr_array[1] = NULL;
2782
2783 if ((rc = linklist_build((LDAP *)call_args[0], call_args[1],
2784 filter, attr_array, &group_base,
2785 &group_count,
2786 LDAP_SCOPE_SUBTREE)) != 0)
2787 {
2788 com_err(whoami, 0, "Unable to process group %s : %s",
2789 av[L_NAME], ldap_err2string(rc));
2790 return(rc);
2791 }
2792
2793 if (group_count)
2794 {
2795 com_err(whoami, 0, "Object already exists with name %s",
2796 av[L_NAME]);
2797 MailDisabled++;
2798 }
2799
2800 linklist_free(group_base);
2801 group_base = NULL;
2802 group_count = 0;
2803 }
2804
df2a74ce 2805 if (atoi(av[L_MAILLIST]) && !MailDisabled && email_isvalid(mail))
2806 {
2807 mail_nickname_v[0] = mail_nickname;
268bfb91 2808 report_to_originator_v[0] = "TRUE";
2809
df2a74ce 2810 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
268bfb91 2811 ADD_ATTR("reportToOriginator", report_to_originator_v,
2812 LDAP_MOD_REPLACE);
df2a74ce 2813 }
2814 else
2815 {
2816 mail_v[0] = NULL;
2817 mail_nickname_v[0] = NULL;
2818 proxy_address_v[0] = NULL;
2819 legacy_exchange_dn_v[0] = NULL;
2820 address_book_v[0] = NULL;
268bfb91 2821 report_to_originator_v[0] = NULL;
df2a74ce 2822
2823 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
2824 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
2825 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2826 ADD_ATTR("legacyExchangeDN", legacy_exchange_dn_v,
2827 LDAP_MOD_REPLACE);
2828 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
268bfb91 2829 ADD_ATTR("reportToOriginator", report_to_originator_v,
2830 LDAP_MOD_REPLACE);
df2a74ce 2831 }
2832 }
2833 else
2834 {
2835 if (atoi(av[L_MAILLIST]) && email_isvalid(contact_mail))
2836 {
2837 mail_v[0] = contact_mail;
2838 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2839 }
2840 else
2841 {
2842 mail_v[0] = NULL;
2843 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
2844 }
2845 }
2846
5a775f54 2847 mods[n] = NULL;
4a6e2ee4 2848 rc = LDAP_SUCCESS;
df2a74ce 2849
4a6e2ee4 2850 if (n != 0)
909e0dc3 2851 {
4a6e2ee4 2852 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
df2a74ce 2853
4a6e2ee4 2854 for (i = 0; i < n; i++)
2855 free(mods[i]);
df2a74ce 2856
4a6e2ee4 2857 if (rc != LDAP_SUCCESS)
2858 {
2859 com_err(whoami, 0, "Unable to update list %s in AD : %s",
2860 av[L_NAME], ldap_err2string(rc));
2861 callback_rc = rc;
2862 return(rc);
2863 }
909e0dc3 2864 }
5a775f54 2865 }
89db421e 2866
909e0dc3 2867 ProcessGroupSecurity((LDAP *)call_args[0], call_args[1], av[L_NAME],
2868 atoi(av[L_HIDDEN]), av[L_ACE_TYPE], av[L_ACE_NAME]);
2869
5b8457c5 2870 return(LDAP_SUCCESS);
cd9e6b16 2871}
2872
df2a74ce 2873int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
2874 char *TargetGroupName, int HiddenGroup,
2875 char *AceType, char *AceName)
909e0dc3 2876{
2877 char filter_exp[1024];
2878 char *attr_array[5];
2879 char search_path[512];
2880 char root_ou[128];
2881 char TemplateDn[512];
2882 char TemplateSamName[128];
2883 char TargetDn[512];
2884 char TargetSamName[128];
2885 char AceSamAccountName[128];
2886 char AceDn[256];
2887 unsigned char AceSid[128];
2888 unsigned char UserTemplateSid[128];
2889 char acBERBuf[N_SD_BER_BYTES];
2890 char GroupSecurityTemplate[256];
df2a74ce 2891 char hide_addres_lists[256];
2892 char address_book[256];
2893 char *hide_address_lists_v[] = {NULL, NULL};
2894 char *address_book_v[] = {NULL, NULL};
909e0dc3 2895 int AceSidCount;
2896 int UserTemplateSidCount;
2897 int group_count;
2898 int n;
2899 int i;
2900 int rc;
2901 int nVal;
2902 ULONG dwInfo;
2903 int array_count = 0;
2904 LDAPMod *mods[20];
2905 LK_ENTRY *group_base;
2906 LDAP_BERVAL **ppsValues;
2907 LDAPControl sControl = {"1.2.840.113556.1.4.801",
2908 { N_SD_BER_BYTES, acBERBuf },
2909 TRUE
2910 };
2911 LDAPControl *apsServerControls[] = {&sControl, NULL};
2912 LDAPMessage *psMsg;
2913
df2a74ce 2914 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
2915 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
909e0dc3 2916 BEREncodeSecurityBits(dwInfo, acBERBuf);
2917
2918 sprintf(search_path, "%s,%s", group_ou_root, dn_path);
df2a74ce 2919 sprintf(filter_exp, "(sAMAccountName=%s%s)", TargetGroupName, group_suffix);
909e0dc3 2920 attr_array[0] = "sAMAccountName";
2921 attr_array[1] = NULL;
2922 group_count = 0;
2923 group_base = NULL;
df2a74ce 2924
909e0dc3 2925 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
df2a74ce 2926 &group_base, &group_count,
2927 LDAP_SCOPE_SUBTREE) != 0))
909e0dc3 2928 return(1);
df2a74ce 2929
909e0dc3 2930 if (group_count != 1)
2931 {
2932 linklist_free(group_base);
2933 return(1);
2934 }
df2a74ce 2935
909e0dc3 2936 strcpy(TargetDn, group_base->dn);
2937 strcpy(TargetSamName, group_base->value);
2938 linklist_free(group_base);
2939 group_base = NULL;
2940 group_count = 0;
2941
2942 UserTemplateSidCount = 0;
2943 memset(UserTemplateSid, '\0', sizeof(UserTemplateSid));
2944 memset(AceSamAccountName, '\0', sizeof(AceSamAccountName));
2945 memset(AceSid, '\0', sizeof(AceSid));
2946 AceSidCount = 0;
2947 group_base = NULL;
2948 group_count = 0;
df2a74ce 2949
909e0dc3 2950 if (strlen(AceName) != 0)
2951 {
2952 if (!strcmp(AceType, "LIST"))
2953 {
df2a74ce 2954 sprintf(AceSamAccountName, "%s%s", AceName, group_suffix);
909e0dc3 2955 strcpy(root_ou, group_ou_root);
2956 }
2957 else if (!strcmp(AceType, "USER"))
2958 {
2959 sprintf(AceSamAccountName, "%s", AceName);
2960 strcpy(root_ou, user_ou);
2961 }
df2a74ce 2962
909e0dc3 2963 if (strlen(AceSamAccountName) != 0)
2964 {
bbef4f93 2965 sprintf(search_path, "%s", dn_path);
909e0dc3 2966 sprintf(filter_exp, "(sAMAccountName=%s)", AceSamAccountName);
2967 attr_array[0] = "objectSid";
2968 attr_array[1] = NULL;
2969 group_count = 0;
2970 group_base = NULL;
df2a74ce 2971
2972 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
2973 attr_array, &group_base, &group_count,
2974 LDAP_SCOPE_SUBTREE) != 0))
909e0dc3 2975 return(1);
2976 if (group_count == 1)
2977 {
2978 strcpy(AceDn, group_base->dn);
2979 AceSidCount = group_base->length;
2980 memcpy(AceSid, group_base->value, AceSidCount);
2981 }
2982 linklist_free(group_base);
2983 group_base = NULL;
2984 group_count = 0;
2985 }
2986 }
df2a74ce 2987
909e0dc3 2988 if (AceSidCount == 0)
2989 {
df2a74ce 2990 com_err(whoami, 0, "Group %s: Administrator: %s, Type: %s - does not "
2991 "have an AD SID.", TargetGroupName, AceName, AceType);
909e0dc3 2992 com_err(whoami, 0, " Non-admin security group template will be used.");
2993 }
2994 else
2995 {
2996 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
2997 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
2998 attr_array[0] = "objectSid";
2999 attr_array[1] = NULL;
3000
3001 group_count = 0;
3002 group_base = NULL;
df2a74ce 3003
3004 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
3005 attr_array, &group_base, &group_count,
3006 LDAP_SCOPE_SUBTREE) != 0))
909e0dc3 3007 return(1);
df2a74ce 3008
909e0dc3 3009 if ((rc != 0) || (group_count != 1))
3010 {
df2a74ce 3011 com_err(whoami, 0, "Unable to process user security template: %s",
3012 "UserTemplate");
909e0dc3 3013 AceSidCount = 0;
3014 }
3015 else
3016 {
3017 UserTemplateSidCount = group_base->length;
3018 memcpy(UserTemplateSid, group_base->value, UserTemplateSidCount);
3019 }
3020 linklist_free(group_base);
3021 group_base = NULL;
3022 group_count = 0;
3023 }
3024
3025 if (HiddenGroup)
3026 {
3027 if (AceSidCount == 0)
3028 {
3029 strcpy(GroupSecurityTemplate, HIDDEN_GROUP);
3030 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP);
3031 }
3032 else
3033 {
3034 strcpy(GroupSecurityTemplate, HIDDEN_GROUP_WITH_ADMIN);
3035 sprintf(filter_exp, "(sAMAccountName=%s)", HIDDEN_GROUP_WITH_ADMIN);
3036 }
3037 }
3038 else
3039 {
3040 if (AceSidCount == 0)
3041 {
3042 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP);
3043 sprintf(filter_exp, "(sAMAccountName=%s)", NOT_HIDDEN_GROUP);
3044 }
3045 else
3046 {
3047 strcpy(GroupSecurityTemplate, NOT_HIDDEN_GROUP_WITH_ADMIN);
df2a74ce 3048 sprintf(filter_exp, "(sAMAccountName=%s)",
3049 NOT_HIDDEN_GROUP_WITH_ADMIN);
909e0dc3 3050 }
3051 }
3052
3053 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
3054 attr_array[0] = "sAMAccountName";
3055 attr_array[1] = NULL;
3056 group_count = 0;
3057 group_base = NULL;
df2a74ce 3058
909e0dc3 3059 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
df2a74ce 3060 &group_base, &group_count,
3061 LDAP_SCOPE_SUBTREE) != 0))
909e0dc3 3062 return(1);
df2a74ce 3063
909e0dc3 3064 if (group_count != 1)
3065 {
3066 linklist_free(group_base);
df2a74ce 3067 com_err(whoami, 0, "Unable to process group security template: %s - "
3068 "security not set", GroupSecurityTemplate);
909e0dc3 3069 return(1);
3070 }
df2a74ce 3071
909e0dc3 3072 strcpy(TemplateDn, group_base->dn);
3073 strcpy(TemplateSamName, group_base->value);
3074 linklist_free(group_base);
3075 group_base = NULL;
3076 group_count = 0;
df2a74ce 3077
909e0dc3 3078 sprintf(filter_exp, "(sAMAccountName=%s)", TemplateSamName);
3079 rc = ldap_search_ext_s(ldap_handle,
3080 TemplateDn,
3081 LDAP_SCOPE_SUBTREE,
3082 filter_exp,
3083 NULL,
3084 0,
3085 apsServerControls,
3086 NULL,
3087 NULL,
3088 0,
3089 &psMsg);
3090
3091 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
3092 {
df2a74ce 3093 com_err(whoami, 0, "Unable to find group security template: %s - "
3094 "security not set", GroupSecurityTemplate);
909e0dc3 3095 return(1);
3096 }
df2a74ce 3097
909e0dc3 3098 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
df2a74ce 3099
909e0dc3 3100 if (ppsValues == NULL)
3101 {
df2a74ce 3102 com_err(whoami, 0, "Unable to find group security descriptor for group "
3103 "%s - security not set", GroupSecurityTemplate);
909e0dc3 3104 return(1);
3105 }
df2a74ce 3106
909e0dc3 3107 if (AceSidCount != 0)
3108 {
3109 for (nVal = 0; ppsValues[nVal] != NULL; nVal++)
3110 {
df2a74ce 3111 for (i = 0;
3112 i < (int)(ppsValues[nVal]->bv_len - UserTemplateSidCount); i++)
909e0dc3 3113 {
df2a74ce 3114 if (!memcmp(&ppsValues[nVal]->bv_val[i], UserTemplateSid,
3115 UserTemplateSidCount))
909e0dc3 3116 {
3117 memcpy(&ppsValues[nVal]->bv_val[i], AceSid, AceSidCount);
3118 break;
3119 }
3120 }
3121 }
3122 }
3123
3124 n = 0;
df2a74ce 3125 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
3126 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
3127
3128 if (Exchange)
3129 {
3130 if(HiddenGroup)
3131 {
3132 hide_address_lists_v[0] = "TRUE";
ac4fbabf 3133 address_book_v[0] = NULL;
df2a74ce 3134 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3135 LDAP_MOD_REPLACE);
3136 ADD_ATTR("showInAddressBook", address_book_v, LDAP_MOD_REPLACE);
3137 } else {
3138 hide_address_lists_v[0] = NULL;
3139 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3140 LDAP_MOD_REPLACE);
3141 }
3142 }
3143
909e0dc3 3144 mods[n] = NULL;
3145
3146 rc = ldap_modify_s(ldap_handle, TargetDn, mods);
df2a74ce 3147
909e0dc3 3148 for (i = 0; i < n; i++)
3149 free(mods[i]);
df2a74ce 3150
909e0dc3 3151 ldap_value_free_len(ppsValues);
3152 ldap_msgfree(psMsg);
df2a74ce 3153
909e0dc3 3154 if (rc != LDAP_SUCCESS)
3155 {
4a6e2ee4 3156 com_err(whoami, 0, "Unable to set security settings for group %s : %s",
909e0dc3 3157 TargetGroupName, ldap_err2string(rc));
df2a74ce 3158
909e0dc3 3159 if (AceSidCount != 0)
3160 {
df2a74ce 3161 com_err(whoami, 0,
3162 "Trying to set security for group %s without admin.",
909e0dc3 3163 TargetGroupName);
df2a74ce 3164
909e0dc3 3165 if (rc = ProcessGroupSecurity(ldap_handle, dn_path, TargetGroupName,
3166 HiddenGroup, "", ""))
3167 {
3168 com_err(whoami, 0, "Unable to set security for group %s.",
3169 TargetGroupName);
3170 return(rc);
3171 }
3172 }
3173 return(rc);
3174 }
df2a74ce 3175
909e0dc3 3176 return(rc);
3177}
3178
89db421e 3179int group_delete(LDAP *ldap_handle, char *dn_path, char *group_name,
3180 char *group_membership, char *MoiraId)
cd9e6b16 3181{
3182 LK_ENTRY *group_base;
f75f605a 3183 char temp[512];
89db421e 3184 char filter[128];
cd9e6b16 3185 int group_count;
3186 int rc;
3187
f75f605a 3188 if (!check_string(group_name))
78af4e6e 3189 {
df2a74ce 3190 com_err(whoami, 0,
3191 "Unable to process invalid LDAP list name %s", group_name);
89db421e 3192 return(AD_INVALID_NAME);
78af4e6e 3193 }
89db421e 3194
3195 memset(filter, '\0', sizeof(filter));
cd9e6b16 3196 group_count = 0;
3197 group_base = NULL;
cd9e6b16 3198 sprintf(temp, "%s,%s", group_ou_root, dn_path);
df2a74ce 3199
89db421e 3200 if (rc = ad_get_group(ldap_handle, temp, group_name,
3201 group_membership, MoiraId,
3202 "distinguishedName", &group_base,
3203 &group_count, filter))
3204 return(rc);
3205
cd9e6b16 3206 if (group_count == 1)
78af4e6e 3207 {
3208 if ((rc = ldap_delete_s(ldap_handle, group_base->value)) != LDAP_SUCCESS)
3209 {
f75f605a 3210 linklist_free(group_base);
3211 com_err(whoami, 0, "Unable to delete list %s from AD : %s",
3212 group_name, ldap_err2string(rc));
89db421e 3213 return(rc);
78af4e6e 3214 }
f75f605a 3215 linklist_free(group_base);
78af4e6e 3216 }
3217 else
3218 {
f75f605a 3219 linklist_free(group_base);
3220 com_err(whoami, 0, "Unable to find list %s in AD.", group_name);
89db421e 3221 return(AD_NO_GROUPS_FOUND);
78af4e6e 3222 }
df2a74ce 3223
78af4e6e 3224 return(0);
cd9e6b16 3225}
3226
909e0dc3 3227int BEREncodeSecurityBits(ULONG uBits, char *pBuffer)
3228{
3229 *pBuffer++ = 0x30;
3230 *pBuffer++ = 0x03;
3231 *pBuffer++ = 0x02;
3232 *pBuffer++ = 0x00;
3233 return(N_SD_BER_BYTES);
3234}
3235
f75f605a 3236int process_lists(int ac, char **av, void *ptr)
cd9e6b16 3237{
f75f605a 3238 int rc;
3239 int security_flag;
3240 char group_ou[256];
3241 char group_membership[2];
3242 char **call_args;
cd9e6b16 3243
3244 call_args = ptr;
3245
f75f605a 3246 security_flag = 0;
3247 memset(group_ou, '\0', sizeof(group_ou));
3248 memset(group_membership, '\0', sizeof(group_membership));
3249 get_group_membership(group_membership, group_ou, &security_flag, av);
3250 rc = member_add((LDAP *)call_args[0], (char *)call_args[1], av[L_NAME],
89db421e 3251 group_ou, group_membership, call_args[2],
3252 (char *)call_args[3], "");
cd9e6b16 3253 return(0);
3254}
3255
3256int member_list_build(int ac, char **av, void *ptr)
3257{
3258 LK_ENTRY *linklist;
78af4e6e 3259 char temp[1024];
cd9e6b16 3260 char **call_args;
df2a74ce 3261 char *s;
cd9e6b16 3262 call_args = ptr;
df2a74ce 3263
cd9e6b16 3264 strcpy(temp, av[ACE_NAME]);
df2a74ce 3265
cd9e6b16 3266 if (!check_string(temp))
3267 return(0);
df2a74ce 3268
f78c7eaf 3269 if (!strcmp(av[ACE_TYPE], "USER"))
cd9e6b16 3270 {
f75f605a 3271 if (!((int)call_args[3] & MOIRA_USERS))
f78c7eaf 3272 return(0);
3273 }
3274 else if (!strcmp(av[ACE_TYPE], "STRING"))
3275 {
df2a74ce 3276 if (Exchange)
3277 {
3278 if((s = strchr(temp, '@')) == (char *) NULL)
3279 {
3280 strcat(temp, "@mit.edu");
3281 }
3282
3283 if(!strncasecmp(&temp[strlen(temp) - 6], ".LOCAL", 6))
3284 {
3285 s = strrchr(temp, '.');
3286 *s = '\0';
3287 strcat(s, ".mit.edu");
3288 }
3289 }
3290
f75f605a 3291 if (!((int)call_args[3] & MOIRA_STRINGS))
f78c7eaf 3292 return(0);
df2a74ce 3293
f78c7eaf 3294 if (contact_create((LDAP *)call_args[0], call_args[1], temp, contact_ou))
3295 return(0);
df2a74ce 3296
cd9e6b16 3297 }
3298 else if (!strcmp(av[ACE_TYPE], "LIST"))
3299 {
f75f605a 3300 if (!((int)call_args[3] & MOIRA_LISTS))
f78c7eaf 3301 return(0);
cd9e6b16 3302 }
f78c7eaf 3303 else if (!strcmp(av[ACE_TYPE], "KERBEROS"))
cd9e6b16 3304 {
f75f605a 3305 if (!((int)call_args[3] & MOIRA_KERBEROS))
f78c7eaf 3306 return(0);
df2a74ce 3307
3308 if (contact_create((LDAP *)call_args[0], call_args[1], temp,
3309 kerberos_ou))
f78c7eaf 3310 return(0);
df2a74ce 3311
cd9e6b16 3312 }
f78c7eaf 3313 else
3314 return(0);
3315
cd9e6b16 3316 linklist = member_base;
df2a74ce 3317
cd9e6b16 3318 while (linklist)
3319 {
3320 if (!strcasecmp(temp, linklist->member))
3321 return(0);
df2a74ce 3322
cd9e6b16 3323 linklist = linklist->next;
3324 }
df2a74ce 3325
cd9e6b16 3326 linklist = calloc(1, sizeof(LK_ENTRY));
3327 linklist->op = 1;
3328 linklist->dn = NULL;
3329 linklist->list = calloc(1, strlen(call_args[2]) + 1);
3330 strcpy(linklist->list, call_args[2]);
3331 linklist->type = calloc(1, strlen(av[ACE_TYPE]) + 1);
3332 strcpy(linklist->type, av[ACE_TYPE]);
3333 linklist->member = calloc(1, strlen(temp) + 1);
3334 strcpy(linklist->member, temp);
3335 linklist->next = member_base;
3336 member_base = linklist;
df2a74ce 3337
cd9e6b16 3338 return(0);
3339}
3340
78af4e6e 3341int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
f75f605a 3342 char *group_ou, char *group_membership, char *user_name,
89db421e 3343 char *UserOu, char *MoiraId)
78af4e6e 3344{
3345 char distinguished_name[1024];
f75f605a 3346 char *modvalues[2];
78af4e6e 3347 char temp[256];
89db421e 3348 char filter[128];
df2a74ce 3349 char *attr_array[3];
78af4e6e 3350 int group_count;
3351 int i;
3352 int n;
3353 LDAPMod *mods[20];
3354 LK_ENTRY *group_base;
3355 ULONG rc;
df2a74ce 3356 char *s;
78af4e6e 3357
3358 if (!check_string(group_name))
89db421e 3359 return(AD_INVALID_NAME);
3360
3361 memset(filter, '\0', sizeof(filter));
3362 group_base = NULL;
3363 group_count = 0;
df2a74ce 3364
89db421e 3365 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3366 group_membership, MoiraId,
3367 "distinguishedName", &group_base,
3368 &group_count, filter))
3369 return(rc);
3370
78af4e6e 3371 if (group_count != 1)
3372 {
4a6e2ee4 3373 com_err(whoami, 0, "Unable to find list %s in AD",
f75f605a 3374 group_name);
3375 linklist_free(group_base);
3376 group_base = NULL;
3377 group_count = 0;
78af4e6e 3378 goto cleanup;
3379 }
df2a74ce 3380
78af4e6e 3381 strcpy(distinguished_name, group_base->value);
3382 linklist_free(group_base);
3383 group_base = NULL;
3384 group_count = 0;
78af4e6e 3385
f75f605a 3386 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
df2a74ce 3387
f75f605a 3388 modvalues[0] = temp;
3389 modvalues[1] = NULL;
3390
3391 n = 0;
3392 ADD_ATTR("member", modvalues, LDAP_MOD_DELETE);
3393 mods[n] = NULL;
3394 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
df2a74ce 3395
f75f605a 3396 for (i = 0; i < n; i++)
3397 free(mods[i]);
df2a74ce 3398
6c8f12af 3399 if (rc == LDAP_UNWILLING_TO_PERFORM)
3400 rc = LDAP_SUCCESS;
df2a74ce 3401
f75f605a 3402 if (rc != LDAP_SUCCESS)
78af4e6e 3403 {
4a6e2ee4 3404 com_err(whoami, 0, "Unable to modify list %s members : %s",
f75f605a 3405 group_name, ldap_err2string(rc));
3406 goto cleanup;
78af4e6e 3407 }
3408
df2a74ce 3409 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3410 {
3411 if (Exchange)
3412 {
3413 if(!strcmp(UserOu, contact_ou) &&
3414 ((s = strstr(user_name, "@mit.edu")) != (char *) NULL))
3415 {
3416 memset(temp, '\0', sizeof(temp));
3417 strcpy(temp, user_name);
3418 s = strchr(temp, '@');
3419 *s = '\0';
3420
3421 sprintf(filter, "(&(objectClass=user)(mailNickName=%s))", temp);
3422
3423 if ((rc = linklist_build(ldap_handle, dn_path, filter, NULL,
3424 &group_base, &group_count,
3425 LDAP_SCOPE_SUBTREE) != 0))
3426 return(rc);
3427
3428 if(group_count)
3429 goto cleanup;
3430
3431 linklist_free(group_base);
3432 group_base = NULL;
3433 group_count = 0;
3434 }
3435
3436 sprintf(filter, "(distinguishedName=%s)", temp);
3437 attr_array[0] = "memberOf";
3438 attr_array[1] = NULL;
3439
3440 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
3441 &group_base, &group_count,
3442 LDAP_SCOPE_SUBTREE) != 0))
3443 return(rc);
3444
3445
3446 if(!group_count)
3447 {
3448 com_err(whoami, 0, "Removing unreferenced object %s", temp);
3449
3450 if ((rc = ldap_delete_s(ldap_handle, temp)) != 0)
3451 return(rc);
3452 }
3453 }
3454 }
3455
3456 cleanup:
78af4e6e 3457 return(rc);
3458}
3459
f75f605a 3460int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
89db421e 3461 char *group_ou, char *group_membership, char *user_name,
3462 char *UserOu, char *MoiraId)
cd9e6b16 3463{
3464 char distinguished_name[1024];
f75f605a 3465 char *modvalues[2];
cd9e6b16 3466 char temp[256];
89db421e 3467 char filter[128];
cd9e6b16 3468 int group_count;
cd9e6b16 3469 int n;
f75f605a 3470 int i;
cd9e6b16 3471 LDAPMod *mods[20];
3472 LK_ENTRY *group_base;
cd9e6b16 3473 ULONG rc;
3474
89db421e 3475 if (!check_string(group_name))
3476 return(AD_INVALID_NAME);
3477
cd9e6b16 3478 rc = 0;
89db421e 3479 memset(filter, '\0', sizeof(filter));
cd9e6b16 3480 group_base = NULL;
3481 group_count = 0;
df2a74ce 3482
89db421e 3483 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
3484 group_membership, MoiraId,
3485 "distinguishedName", &group_base,
3486 &group_count, filter))
3487 return(rc);
cd9e6b16 3488
cd9e6b16 3489 if (group_count != 1)
3490 {
f75f605a 3491 linklist_free(group_base);
3492 group_base = NULL;
3493 group_count = 0;
4a6e2ee4 3494 com_err(whoami, 0, "Unable to find list %s in AD",
f75f605a 3495 group_name);
89db421e 3496 return(AD_MULTIPLE_GROUPS_FOUND);
cd9e6b16 3497 }
f75f605a 3498
cd9e6b16 3499 strcpy(distinguished_name, group_base->value);
3500 linklist_free(group_base);
3501 group_base = NULL;
3502 group_count = 0;
3503
f75f605a 3504 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
3505 modvalues[0] = temp;
3506 modvalues[1] = NULL;
cd9e6b16 3507
f75f605a 3508 n = 0;
3509 ADD_ATTR("member", modvalues, LDAP_MOD_ADD);
3510 mods[n] = NULL;
3511 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
df2a74ce 3512
f75f605a 3513 if (rc == LDAP_ALREADY_EXISTS)
3514 rc = LDAP_SUCCESS;
df2a74ce 3515
89db421e 3516 if ((!strcmp(UserOu, contact_ou)) || (!strcmp(UserOu, kerberos_ou)))
3517 {
3518 if (rc == LDAP_UNWILLING_TO_PERFORM)
3519 rc = LDAP_SUCCESS;
3520 }
df2a74ce 3521
f75f605a 3522 for (i = 0; i < n; i++)
3523 free(mods[i]);
df2a74ce 3524
f75f605a 3525 if (rc != LDAP_SUCCESS)
cd9e6b16 3526 {
4a6e2ee4 3527 com_err(whoami, 0, "Unable to add %s to list %s as a member : %s",
89db421e 3528 user_name, group_name, ldap_err2string(rc));
cd9e6b16 3529 }
df2a74ce 3530
f75f605a 3531 return(rc);
cd9e6b16 3532}
3533
df2a74ce 3534int contact_remove_email(LDAP *ld, char *bind_path,
3535 LK_ENTRY **linklist_base, int linklist_current)
cd9e6b16 3536{
df2a74ce 3537 LK_ENTRY *gPtr;
3538 int rc;
3539 char *mail_v[] = {NULL, NULL};
3540 LDAPMod *mods[20];
3541 int n;
3542 int i;
3543
3544 mail_v[0] = NULL;
3545
3546 n = 0;
3547 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
3548 ADD_ATTR("mailNickName", mail_v, LDAP_MOD_REPLACE);
3549 ADD_ATTR("proxyAddresses", mail_v, LDAP_MOD_REPLACE);
3550 ADD_ATTR("targetAddress", mail_v, LDAP_MOD_REPLACE);
3551 mods[n] = NULL;
3552
3553 gPtr = (*linklist_base);
3554
3555 while(gPtr) {
3556 rc = ldap_modify_s(ld, gPtr->dn, mods);
3557
3558 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3559 {
3560 com_err(whoami, 0, "Unable to modify contact %s in AD : %s",
3561 gPtr->dn, ldap_err2string(rc));
3562 return(rc);
3563 }
3564
3565 gPtr = gPtr->next;
3566 }
3567
3568 for (i = 0; i < n; i++)
3569 free(mods[i]);
3570
3571 return(rc);
3572}
3573
3574int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou)
3575{
3576 LDAPMod *mods[20];
3577 LK_ENTRY *group_base;
3578 int group_count;
3579 char new_dn[256];
3580 char cn_user_name[256];
3581 char contact_name[256];
3582 char mail_nickname[256];
3583 char proxy_address_internal[256];
3584 char proxy_address_external[256];
3585 char target_address[256];
3586 char internal_contact_name[256];
3587 char filter[128];
3588 char mail[256];
3589 char mit_address_book[256];
3590 char default_address_book[256];
3591 char contact_address_book[256];
f78c7eaf 3592 char *email_v[] = {NULL, NULL};
cd9e6b16 3593 char *cn_v[] = {NULL, NULL};
3594 char *contact_v[] = {NULL, NULL};
df2a74ce 3595 char *mail_nickname_v[] = {NULL, NULL};
3596 char *proxy_address_internal_v[] = {NULL, NULL};
3597 char *proxy_address_external_v[] = {NULL, NULL};
3598 char *target_address_v[] = {NULL, NULL};
3599 char *mit_address_book_v[] = {NULL, NULL};
3600 char *default_address_book_v[] = {NULL, NULL};
3601 char *contact_address_book_v[] = {NULL, NULL};
3602 char *hide_address_lists_v[] = {NULL, NULL};
3603 char *attr_array[3];
3604
cd9e6b16 3605 char *objectClass_v[] = {"top", "person",
3606 "organizationalPerson",
3607 "contact", NULL};
3608 char *name_v[] = {NULL, NULL};
3609 char *desc_v[] = {NULL, NULL};
df2a74ce 3610 char *s;
cd9e6b16 3611 int n;
3612 int rc;
3613 int i;
3614
3615 if (!check_string(user))
78af4e6e 3616 {
4a6e2ee4 3617 com_err(whoami, 0, "Unable to process invalid LDAP name %s", user);
89db421e 3618 return(AD_INVALID_NAME);
78af4e6e 3619 }
df2a74ce 3620
3621 strcpy(mail, user);
3622 strcpy(contact_name, mail);
3623 strcpy(internal_contact_name, mail);
3624
3625 if((s = strchr(internal_contact_name, '@')) != NULL) {
3626 *s = '?';
3627 }
3628
cd9e6b16 3629 sprintf(cn_user_name,"CN=%s,%s,%s", contact_name, group_ou, bind_path);
df2a74ce 3630 sprintf(target_address, "SMTP:%s", contact_name);
3631 sprintf(proxy_address_external, "SMTP:%s", contact_name);
3632 sprintf(mail_nickname, "%s", internal_contact_name);
3633
cd9e6b16 3634 cn_v[0] = cn_user_name;
3635 contact_v[0] = contact_name;
3636 name_v[0] = user;
3637 desc_v[0] = "Auto account created by Moira";
df2a74ce 3638 email_v[0] = mail;
3639 proxy_address_internal_v[0] = proxy_address_internal;
3640 proxy_address_external_v[0] = proxy_address_external;
3641 mail_nickname_v[0] = mail_nickname;
3642 target_address_v[0] = target_address;
3643 mit_address_book_v[0] = mit_address_book;
3644 default_address_book_v[0] = default_address_book;
3645 contact_address_book_v[0] = contact_address_book;
cd9e6b16 3646 strcpy(new_dn, cn_user_name);
3647 n = 0;
df2a74ce 3648
cd9e6b16 3649 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3650 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3651 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3652 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3653 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
df2a74ce 3654
3655 if (Exchange)
f78c7eaf 3656 {
df2a74ce 3657 if (!strcmp(group_ou, contact_ou) && email_isvalid(mail))
3658 {
3659 group_count = 0;
3660 group_base = NULL;
3661
3662 sprintf(filter, "(&(objectClass=user)(cn=%s))", mail);
3663 attr_array[0] = "cn";
3664 attr_array[1] = NULL;
3665
3666 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3667 &group_base, &group_count,
3668 LDAP_SCOPE_SUBTREE)) != 0)
3669 {
3670 com_err(whoami, 0, "Unable to process contact %s : %s",
3671 user, ldap_err2string(rc));
3672 return(rc);
3673 }
3674
3675 if (group_count)
3676 {
3677 com_err(whoami, 0, "Object already exists with name %s",
3678 user);
3679 return(1);
3680 }
3681
3682 linklist_free(group_base);
3683 group_base = NULL;
3684 group_count = 0;
3685
3686 sprintf(filter, "(&(objectClass=group)(cn=%s))", mail);
3687 attr_array[0] = "cn";
3688 attr_array[1] = NULL;
3689
3690 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3691 &group_base, &group_count,
3692 LDAP_SCOPE_SUBTREE)) != 0)
3693 {
3694 com_err(whoami, 0, "Unable to process contact %s : %s",
3695 user, ldap_err2string(rc));
3696 return(rc);
3697 }
3698
3699 if (group_count)
3700 {
3701 com_err(whoami, 0, "Object already exists with name %s",
3702 user);
3703 return(1);
3704 }
3705
3706 linklist_free(group_base);
3707 group_count = 0;
3708 group_base = NULL;
3709
3710 sprintf(filter, "(&(objectClass=user)(mail=%s))", mail);
3711 attr_array[0] = "cn";
3712 attr_array[1] = NULL;
3713
3714 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3715 &group_base, &group_count,
3716 LDAP_SCOPE_SUBTREE)) != 0)
3717 {
3718 com_err(whoami, 0, "Unable to process contact %s : %s",
3719 user, ldap_err2string(rc));
3720 return(rc);
3721 }
3722
3723 if (group_count)
3724 {
3725 com_err(whoami, 0, "Object already exists with name %s",
3726 user);
3727 return(1);
3728 }
3729
3730 linklist_free(group_base);
3731 group_base = NULL;
3732 group_count = 0;
3733
3734 sprintf(filter, "(&(objectClass=group)(mail=%s))", mail);
3735 attr_array[0] = "cn";
3736 attr_array[1] = NULL;
3737
3738 if ((rc = linklist_build(ld, bind_path, filter, attr_array,
3739 &group_base, &group_count,
3740 LDAP_SCOPE_SUBTREE)) != 0)
3741 {
3742 com_err(whoami, 0, "Unable to process contact %s : %s",
3743 user, ldap_err2string(rc));
3744 return(rc);
3745 }
3746
3747 if (group_count)
3748 {
3749 com_err(whoami, 0, "Object already exists with name %s",
3750 user);
3751 return(1);
3752 }
3753
3754 linklist_free(group_base);
3755 group_base = NULL;
3756 group_count = 0;
3757
3758 ADD_ATTR("mail", email_v, LDAP_MOD_ADD);
3759 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
3760 ADD_ATTR("proxyAddresses", proxy_address_external_v, LDAP_MOD_ADD);
3761 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_ADD);
3762
3763 hide_address_lists_v[0] = "TRUE";
3764 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3765 LDAP_MOD_ADD);
3766 }
f78c7eaf 3767 }
df2a74ce 3768
cd9e6b16 3769 mods[n] = NULL;
3770
3771 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
df2a74ce 3772
cd9e6b16 3773 for (i = 0; i < n; i++)
3774 free(mods[i]);
df2a74ce 3775
3776 if (Exchange)
3777 {
3778 if ((rc != LDAP_SUCCESS) && (rc == LDAP_ALREADY_EXISTS))
3779 {
3780 n = 0;
3781
3782 ADD_ATTR("mail", email_v, LDAP_MOD_REPLACE);
3783 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
3784 ADD_ATTR("proxyAddresses", proxy_address_external_v,
3785 LDAP_MOD_REPLACE);
3786 ADD_ATTR("targetAddress", target_address_v, LDAP_MOD_REPLACE);
3787
3788 hide_address_lists_v[0] = "TRUE";
3789 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
3790 LDAP_MOD_REPLACE);
3791
3792 mods[n] = NULL;
3793 rc = ldap_modify_s(ld, new_dn, mods);
3794
3795 if (rc)
3796 {
3797 com_err(whoami, 0, "Unable to update contact %s", mail);
3798 }
3799
3800 for (i = 0; i < n; i++)
3801 free(mods[i]);
3802 }
3803 }
3804
f78c7eaf 3805 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
3806 {
3807 n = 0;
3808 ADD_ATTR("cn", contact_v, LDAP_MOD_ADD);
3809 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
3810 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
3811 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
3812 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
3813 mods[n] = NULL;
3814 rc = ldap_add_ext_s(ld, new_dn, mods, NULL, NULL);
df2a74ce 3815
f78c7eaf 3816 for (i = 0; i < n; i++)
3817 free(mods[i]);
3818 }
df2a74ce 3819
cd9e6b16 3820 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
78af4e6e 3821 {
4a6e2ee4 3822 com_err(whoami, 0, "Unable to create contact %s : %s",
f75f605a 3823 user, ldap_err2string(rc));
89db421e 3824 return(rc);
78af4e6e 3825 }
df2a74ce 3826
78af4e6e 3827 return(0);
3828}
3829
f75f605a 3830int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3abb4456 3831 char *Uid, char *MitId, char *MoiraId, int State,
df2a74ce 3832 char *WinHomeDir, char *WinProfileDir, char *first,
3833 char *middle, char *last)
78af4e6e 3834{
3835 LDAPMod *mods[20];
3836 LK_ENTRY *group_base;
3837 int group_count;
3abb4456 3838 char distinguished_name[512];
df2a74ce 3839 char displayName[256];
89db421e 3840 char *mitMoiraId_v[] = {NULL, NULL};
78af4e6e 3841 char *uid_v[] = {NULL, NULL};
3842 char *mitid_v[] = {NULL, NULL};
f78c7eaf 3843 char *homedir_v[] = {NULL, NULL};
3844 char *winProfile_v[] = {NULL, NULL};
3845 char *drives_v[] = {NULL, NULL};
89db421e 3846 char *userAccountControl_v[] = {NULL, NULL};
df2a74ce 3847 char *alt_recipient_v[] = {NULL, NULL};
3848 char *hide_address_lists_v[] = {NULL, NULL};
3849 char *mail_v[] = {NULL, NULL};
89db421e 3850 char userAccountControlStr[80];
78af4e6e 3851 int n;
3852 int rc;
3853 int i;
3abb4456 3854 int OldUseSFU30;
df2a74ce 3855 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
3856 UF_PASSWD_CANT_CHANGE;
89db421e 3857 char filter[128];
78af4e6e 3858 char *attr_array[3];
c0bd7667 3859 char temp[256];
df2a74ce 3860 char mail[256];
3861 char contact_mail[256];
3862 char filter_exp[1024];
3863 char search_path[512];
3864 char TemplateDn[512];
3865 char TemplateSamName[128];
3866 char alt_recipient[256];
3867 char acBERBuf[N_SD_BER_BYTES];
3868 LDAPControl sControl = {"1.2.840.113556.1.4.801",
3869 { N_SD_BER_BYTES, acBERBuf },
3870 TRUE};
3871 LDAPControl *apsServerControls[] = {&sControl, NULL};
3872 LDAPMessage *psMsg;
3873 LDAP_BERVAL **ppsValues;
3874 ULONG dwInfo;
3875 char *argv[3];
3876 char *homeMDB;
3877 char *homeServerName;
3878 char *save_argv[7];
3879 char search_string[256];
3880
3881 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
3882 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
3883 BEREncodeSecurityBits(dwInfo, acBERBuf);
78af4e6e 3884
f75f605a 3885 if (!check_string(user_name))
78af4e6e 3886 {
df2a74ce 3887 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
3888 user_name);
89db421e 3889 return(AD_INVALID_NAME);
78af4e6e 3890 }
df2a74ce 3891
3892 memset(contact_mail, '\0', sizeof(contact_mail));
3893 sprintf(contact_mail, "%s@mit.edu", user_name);
3894 memset(mail, '\0', sizeof(mail));
3895 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
3896 memset(alt_recipient, '\0', sizeof(alt_recipient));
3897 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
3898 dn_path);
3899 sprintf(search_string, "@%s", uppercase(ldap_domain));
3900
3901 if (Exchange)
3902 {
3903 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
3904 {
3905 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
3906 }
3907 }
78af4e6e 3908
78af4e6e 3909 group_count = 0;
3910 group_base = NULL;
89db421e 3911
df2a74ce 3912 memset(displayName, '\0', sizeof(displayName));
3913
89db421e 3914 if (strlen(MoiraId) != 0)
78af4e6e 3915 {
c0bd7667 3916 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 3917 attr_array[0] = "cn";
3918 attr_array[1] = NULL;
3919 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 3920 &group_base, &group_count,
3921 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 3922 {
4a6e2ee4 3923 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 3924 user_name, ldap_err2string(rc));
3925 return(rc);
3926 }
3927 }
df2a74ce 3928
c0bd7667 3929 if (group_count != 1)
89db421e 3930 {
c0bd7667 3931 linklist_free(group_base);
3932 group_base = NULL;
3933 group_count = 0;
89db421e 3934 sprintf(filter, "(sAMAccountName=%s)", user_name);
3935 attr_array[0] = "cn";
3936 attr_array[1] = NULL;
c0bd7667 3937 sprintf(temp, "%s,%s", user_ou, dn_path);
3938 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
df2a74ce 3939 &group_base, &group_count,
3940 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 3941 {
4a6e2ee4 3942 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 3943 user_name, ldap_err2string(rc));
3944 return(rc);
3945 }
78af4e6e 3946 }
3947
3948 if (group_count != 1)
3949 {
4a6e2ee4 3950 com_err(whoami, 0, "Unable to find user %s in AD",
f75f605a 3951 user_name);
3952 linklist_free(group_base);
89db421e 3953 return(AD_NO_USER_FOUND);
78af4e6e 3954 }
df2a74ce 3955
78af4e6e 3956 strcpy(distinguished_name, group_base->dn);
3957
f75f605a 3958 linklist_free(group_base);
3959 group_count = 0;
4a6e2ee4 3960
7dc865bd 3961 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
df2a74ce 3962 rc = attribute_update(ldap_handle, distinguished_name, MitId,
3963 "employeeID", user_name);
3964 else
3965 rc = attribute_update(ldap_handle, distinguished_name, "none",
3966 "employeeID", user_name);
3967
3968 if(strlen(first)) {
3969 strcat(displayName, first);
3970 }
3971
3972 if(strlen(middle)) {
3973 if(strlen(first))
3974 strcat(displayName, " ");
3975
3976 strcat(displayName, middle);
3977 }
3978
3979 if(strlen(last)) {
3980 if(strlen(middle) || strlen(first))
3981 strcat(displayName, " ");
3982
3983 strcat(displayName, last);
3984 }
3985
3986 if(strlen(displayName))
3987 rc = attribute_update(ldap_handle, distinguished_name, displayName,
3988 "displayName", user_name);
3989 else
3990 rc = attribute_update(ldap_handle, distinguished_name, user_name,
3991 "displayName", user_name);
3992
3993 if(strlen(first))
3994 rc = attribute_update(ldap_handle, distinguished_name, first,
3995 "givenName", user_name);
7dc865bd 3996 else
df2a74ce 3997 rc = attribute_update(ldap_handle, distinguished_name, "",
3998 "givenName", user_name);
3999
4000 if(strlen(middle) == 1)
4001 rc = attribute_update(ldap_handle, distinguished_name, middle,
4002 "initials", user_name);
4003 else
4004 rc = attribute_update(ldap_handle, distinguished_name, "",
4005 "initials", user_name);
4006
4007 if(strlen(last))
4008 rc = attribute_update(ldap_handle, distinguished_name, last,
4009 "sn", user_name);
4010 else
4011 rc = attribute_update(ldap_handle, distinguished_name, "",
4012 "sn", user_name);
4013
4014 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4015 user_name);
4016 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4017 "mitMoiraId", user_name);
4a6e2ee4 4018
78af4e6e 4019 n = 0;
50b4a32b 4020 uid_v[0] = Uid;
df2a74ce 4021
3abb4456 4022 if (!UseSFU30)
4023 {
4024 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4025 }
4026 else
4027 {
4028 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4029 }
4a6e2ee4 4030
89db421e 4031 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
df2a74ce 4032 {
4033 userAccountControl |= UF_ACCOUNTDISABLE;
4034
4035 if (Exchange)
4036 {
4037 hide_address_lists_v[0] = "TRUE";
4038 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4039 LDAP_MOD_REPLACE);
4040 }
4041 }
4042 else
4043 {
4044 if (Exchange)
4045 {
4046 hide_address_lists_v[0] = NULL;
4047 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4048 LDAP_MOD_REPLACE);
4049 }
4050 }
4051
89db421e 4052 sprintf(userAccountControlStr, "%ld", userAccountControl);
4053 userAccountControl_v[0] = userAccountControlStr;
4054 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
3abb4456 4055
df2a74ce 4056 if (Exchange)
4057 {
4058 if (rc = moira_connect())
4059 {
4060 critical_alert("AD incremental",
4061 "Error contacting Moira server : %s",
4062 error_message(rc));
4063 return;
4064 }
4065
4066 argv[0] = user_name;
4067
4068 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4069 {
4070 if(!strcmp(save_argv[1], "EXCHANGE") ||
4071 (strstr(save_argv[3], search_string) != NULL))
4072 {
4073 alt_recipient_v[0] = NULL;
4074 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4075
4076 argv[0] = exchange_acl;
4077 argv[1] = "USER";
4078 argv[2] = user_name;
4079
4080 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4081
4082 if ((rc) && (rc != MR_EXISTS))
4083 {
4084 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4085 user_name, exchange_acl, error_message(rc));
4086 }
4087 }
4088 else
4089 {
4090 alt_recipient_v[0] = alt_recipient;
4091 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4092
4093 argv[0] = exchange_acl;
4094 argv[1] = "USER";
4095 argv[2] = user_name;
4096
4097 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4098
4099 if ((rc) && (rc != MR_NO_MATCH))
4100 {
4101 com_err(whoami, 0,
4102 "Unable to remove user %s from %s: %s, %d",
4103 user_name, exchange_acl, error_message(rc), rc);
4104 }
4105 }
4106 }
4107 else
4108 {
4109 alt_recipient_v[0] = alt_recipient;
4110 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4111
4112 argv[0] = exchange_acl;
4113 argv[1] = "USER";
4114 argv[2] = user_name;
4115
4116 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4117
4118 if ((rc) && (rc != MR_NO_MATCH))
4119 {
4120 com_err(whoami, 0,
4121 "Unable to remove user %s from %s: %s, %d",
4122 user_name, exchange_acl, error_message(rc), rc);
4123 }
4124 }
4125
4126 moira_disconnect();
4127 }
4128 else
4129 {
4130 mail_v[0] = contact_mail;
4131 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4132 }
4133
3abb4456 4134 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4135 WinProfileDir, homedir_v, winProfile_v,
4136 drives_v, mods, LDAP_MOD_REPLACE, n);
4137
df2a74ce 4138 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4139 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4140 attr_array[0] = "sAMAccountName";
4141 attr_array[1] = NULL;
4142 group_count = 0;
4143 group_base = NULL;
4144
4145 if ((rc = linklist_build(ldap_handle, search_path, filter_exp, attr_array,
4146 &group_base, &group_count,
4147 LDAP_SCOPE_SUBTREE) != 0))
4148 return(1);
4149
4150 if (group_count != 1)
4151 {
4152 com_err(whoami, 0, "Unable to process user security template: %s - "
4153 "security not set", "UserTemplate.u");
4154 return(1);
4155 }
4156
4157 strcpy(TemplateDn, group_base->dn);
4158 strcpy(TemplateSamName, group_base->value);
4159 linklist_free(group_base);
4160 group_base = NULL;
4161 group_count = 0;
4162
4163 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4164 filter_exp, NULL, 0, apsServerControls, NULL,
4165 NULL, 0, &psMsg);
4166
4167 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4168 {
4169 com_err(whoami, 0, "Unable to find user security template: %s - "
4170 "security not set", "UserTemplate.u");
4171 return(1);
4172 }
4173
4174 ppsValues = ldap_get_values_len(ldap_handle, psMsg, "ntSecurityDescriptor");
4175
4176 if (ppsValues == NULL)
4177 {
4178 com_err(whoami, 0, "Unable to find user security template: %s - "
4179 "security not set", "UserTemplate.u");
4180 return(1);
4181 }
4182
4183 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4184 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4185
78af4e6e 4186 mods[n] = NULL;
df2a74ce 4187
4188 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4189 mods)) != LDAP_SUCCESS)
78af4e6e 4190 {
df2a74ce 4191 OldUseSFU30 = UseSFU30;
4192 SwitchSFU(mods, &UseSFU30, n);
4193 if (OldUseSFU30 != UseSFU30)
4194 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4195 if (rc)
f78c7eaf 4196 {
df2a74ce 4197 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4198 user_name, ldap_err2string(rc));
f78c7eaf 4199 }
4200 }
df2a74ce 4201
3abb4456 4202 for (i = 0; i < n; i++)
4203 free(mods[i]);
df2a74ce 4204
f75f605a 4205 return(rc);
cd9e6b16 4206}
4207
f75f605a 4208int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
89db421e 4209 char *user_name)
9db0b148 4210{
4211 LDAPMod *mods[20];
4212 char new_dn[256];
4213 char old_dn[256];
9db0b148 4214 char upn[256];
df2a74ce 4215 char mail[256];
4216 char contact_mail[256];
4217 char proxy_address[256];
4218 char query_base_dn[256];
4219 char temp[256];
9db0b148 4220 char *userPrincipalName_v[] = {NULL, NULL};
4221 char *altSecurityIdentities_v[] = {NULL, NULL};
4222 char *name_v[] = {NULL, NULL};
78af4e6e 4223 char *samAccountName_v[] = {NULL, NULL};
df2a74ce 4224 char *mail_v[] = {NULL, NULL};
4225 char *mail_nickname_v[] = {NULL, NULL};
4226 char *proxy_address_v[] = {NULL, NULL};
4227 char *query_base_dn_v[] = {NULL, NULL};
9db0b148 4228 int n;
4229 int rc;
4230 int i;
9db0b148 4231
f75f605a 4232 if (!check_string(before_user_name))
78af4e6e 4233 {
df2a74ce 4234 com_err(whoami, 0,
4235 "Unable to process invalid LDAP user name %s", before_user_name);
89db421e 4236 return(AD_INVALID_NAME);
78af4e6e 4237 }
df2a74ce 4238
f75f605a 4239 if (!check_string(user_name))
78af4e6e 4240 {
df2a74ce 4241 com_err(whoami, 0,
4242 "Unable to process invalid LDAP user name %s", user_name);
89db421e 4243 return(AD_INVALID_NAME);
78af4e6e 4244 }
9db0b148 4245
f75f605a 4246 strcpy(user_name, user_name);
4247 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
9db0b148 4248 sprintf(new_dn, "cn=%s", user_name);
df2a74ce 4249 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4250 sprintf(contact_mail, "%s@mit.edu", user_name);
4251 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4252
f75f605a 4253 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
9db0b148 4254 NULL, NULL)) != LDAP_SUCCESS)
4255 {
4a6e2ee4 4256 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
89db421e 4257 before_user_name, user_name, ldap_err2string(rc));
f75f605a 4258 return(rc);
9db0b148 4259 }
4260
df2a74ce 4261 if (Exchange)
4262 {
4263 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4264 dn_path);
4265
4266 if(rc = ldap_delete_s(ldap_handle, temp))
4267 {
4268 com_err(whoami, 0, "Unable to delete user contact for %s",
4269 user_name);
4270 }
4271
4272 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4273 {
4274 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4275 }
4276 }
4277
9db0b148 4278 name_v[0] = user_name;
4279 sprintf(upn, "%s@%s", user_name, ldap_domain);
4280 userPrincipalName_v[0] = upn;
4281 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
df2a74ce 4282 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
9db0b148 4283 altSecurityIdentities_v[0] = temp;
78af4e6e 4284 samAccountName_v[0] = user_name;
df2a74ce 4285 mail_v[0] = mail;
4286 mail_nickname_v[0] = user_name;
4287 proxy_address_v[0] = proxy_address;
4288 query_base_dn_v[0] = query_base_dn;
9db0b148 4289
4290 n = 0;
4291 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4292 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4293 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
78af4e6e 4294 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
df2a74ce 4295
4296 if (Exchange)
4297 {
4298 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4299 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4300 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4301 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4302 }
4303 else
4304 {
4305 mail_v[0] = contact_mail;
4306 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4307 }
4308
9db0b148 4309 mods[n] = NULL;
df2a74ce 4310
f75f605a 4311 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
df2a74ce 4312
f75f605a 4313 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
9db0b148 4314 {
df2a74ce 4315 com_err(whoami, 0,
4316 "Unable to modify user data for %s after renaming : %s",
f75f605a 4317 user_name, ldap_err2string(rc));
9db0b148 4318 }
df2a74ce 4319
9db0b148 4320 for (i = 0; i < n; i++)
4321 free(mods[i]);
df2a74ce 4322
f75f605a 4323 return(rc);
9db0b148 4324}
4325
cd9e6b16 4326int user_create(int ac, char **av, void *ptr)
4327{
4328 LDAPMod *mods[20];
4329 char new_dn[256];
4330 char user_name[256];
9db0b148 4331 char sam_name[256];
5b8457c5 4332 char upn[256];
df2a74ce 4333 char mail[256];
4334 char contact_mail[256];
4335 char proxy_address[256];
4336 char mail_nickname[256];
4337 char query_base_dn[256];
4338 char displayName[256];
4339 char address_book[256];
4340 char alt_recipient[256];
cd9e6b16 4341 char *cn_v[] = {NULL, NULL};
4342 char *objectClass_v[] = {"top", "person",
4343 "organizationalPerson",
4344 "user", NULL};
4345
4346 char *samAccountName_v[] = {NULL, NULL};
4347 char *altSecurityIdentities_v[] = {NULL, NULL};
89db421e 4348 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 4349 char *name_v[] = {NULL, NULL};
4350 char *desc_v[] = {NULL, NULL};
cd9e6b16 4351 char *userPrincipalName_v[] = {NULL, NULL};
4352 char *userAccountControl_v[] = {NULL, NULL};
78af4e6e 4353 char *uid_v[] = {NULL, NULL};
4354 char *mitid_v[] = {NULL, NULL};
3abb4456 4355 char *homedir_v[] = {NULL, NULL};
4356 char *winProfile_v[] = {NULL, NULL};
4357 char *drives_v[] = {NULL, NULL};
df2a74ce 4358 char *mail_v[] = {NULL, NULL};
4359 char *givenName_v[] = {NULL, NULL};
4360 char *sn_v[] = {NULL, NULL};
4361 char *initials_v[] = {NULL, NULL};
4362 char *displayName_v[] = {NULL, NULL};
4363 char *proxy_address_v[] = {NULL, NULL};
4364 char *mail_nickname_v[] = {NULL, NULL};
4365 char *query_base_dn_v[] = {NULL, NULL};
4366 char *address_book_v[] = {NULL, NULL};
4367 char *homeMDB_v[] = {NULL, NULL};
4368 char *homeServerName_v[] = {NULL, NULL};
4369 char *mdbUseDefaults_v[] = {NULL, NULL};
4370 char *mailbox_guid_v[] = {NULL, NULL};
4371 char *user_culture_v[] = {NULL, NULL};
4372 char *user_account_control_v[] = {NULL, NULL};
4373 char *msexch_version_v[] = {NULL, NULL};
4374 char *alt_recipient_v[] = {NULL, NULL};
4375 char *hide_address_lists_v[] = {NULL, NULL};
cd9e6b16 4376 char userAccountControlStr[80];
4377 char temp[128];
df2a74ce 4378 char filter_exp[1024];
4379 char search_path[512];
4380 char *attr_array[3];
4381 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4382 UF_PASSWD_CANT_CHANGE;
cd9e6b16 4383 int n;
4384 int rc;
4385 int i;
3abb4456 4386 int OldUseSFU30;
cd9e6b16 4387 char **call_args;
3abb4456 4388 char WinHomeDir[1024];
4389 char WinProfileDir[1024];
df2a74ce 4390 char *homeMDB;
4391 char *homeServerName;
4392 ULONG dwInfo;
4393 char acBERBuf[N_SD_BER_BYTES];
4394 LK_ENTRY *group_base;
4395 int group_count;
4396 char TemplateDn[512];
4397 char TemplateSamName[128];
4398 LDAP_BERVAL **ppsValues;
4399 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4400 { N_SD_BER_BYTES, acBERBuf },
4401 TRUE};
4402 LDAPControl *apsServerControls[] = {&sControl, NULL};
4403 LDAPMessage *psMsg;
4404 char *argv[3];
4405 char *save_argv[7];
4406 char search_string[256];
cd9e6b16 4407
4408 call_args = ptr;
4409
df2a74ce 4410 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4411 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4412 BEREncodeSecurityBits(dwInfo, acBERBuf);
4413
78af4e6e 4414 if (!check_string(av[U_NAME]))
4415 {
89db421e 4416 callback_rc = AD_INVALID_NAME;
df2a74ce 4417 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4418 av[U_NAME]);
89db421e 4419 return(AD_INVALID_NAME);
78af4e6e 4420 }
9db0b148 4421
3abb4456 4422 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4423 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
df2a74ce 4424 memset(displayName, '\0', sizeof(displayName));
4425 memset(query_base_dn, '\0', sizeof(query_base_dn));
3abb4456 4426 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4427 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
cd9e6b16 4428 strcpy(user_name, av[U_NAME]);
4429 sprintf(upn, "%s@%s", user_name, ldap_domain);
78af4e6e 4430 sprintf(sam_name, "%s", av[U_NAME]);
df2a74ce 4431
4432 if(strlen(av[U_FIRST])) {
4433 strcat(displayName, av[U_FIRST]);
4434 }
4435
4436 if(strlen(av[U_MIDDLE])) {
4437 if(strlen(av[U_FIRST]))
4438 strcat(displayName, " ");
4439
4440 strcat(displayName, av[U_MIDDLE]);
4441 }
4442
4443 if(strlen(av[U_LAST])) {
4444 if(strlen(av[U_FIRST]) || strlen(av[U_LAST]))
4445 strcat(displayName, " ");
4446
4447 strcat(displayName, av[U_LAST]);
4448 }
4449
9db0b148 4450 samAccountName_v[0] = sam_name;
df2a74ce 4451 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4452 (atoi(av[U_STATE]) != US_REGISTERED))
4453 {
4454 userAccountControl |= UF_ACCOUNTDISABLE;
4455
4456 if (Exchange)
4457 {
4458 hide_address_lists_v[0] = "TRUE";
4459 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4460 LDAP_MOD_ADD);
4461 }
4462 }
4463
cd9e6b16 4464 sprintf(userAccountControlStr, "%ld", userAccountControl);
4465 userAccountControl_v[0] = userAccountControlStr;
4466 userPrincipalName_v[0] = upn;
cd9e6b16 4467 cn_v[0] = user_name;
4468 name_v[0] = user_name;
4469 desc_v[0] = "Auto account created by Moira";
df2a74ce 4470 mail_v[0] = mail;
4471 givenName_v[0] = av[U_FIRST];
4472 sn_v[0] = av[U_LAST];
4473 displayName_v[0] = displayName;
4474 mail_nickname_v[0] = user_name;
4475
cd9e6b16 4476 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4477 altSecurityIdentities_v[0] = temp;
4478 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
df2a74ce 4479 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
4480 sprintf(contact_mail, "%s@mit.edu", user_name);
4481 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
4482 query_base_dn_v[0] = query_base_dn;
4483 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
4484 call_args[1]);
4485 sprintf(search_string, "@%s", uppercase(ldap_domain));
4486
4487
4488 if (Exchange)
4489 {
4490 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
4491 contact_ou))
4492 {
4493 com_err(whoami, 0, "Unable to create user contact %s",
4494 contact_mail);
4495 }
4496
4497 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
4498 &homeServerName))
4499 {
4500 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
4501 return(1);
4502 }
4503
4504 com_err(whoami, 0, "homeMDB:%s", homeMDB);
4505 com_err(whoami, 0, "homeServerName:%s", homeServerName);
4506
4507 homeMDB_v[0] = homeMDB;
4508 homeServerName_v[0] = homeServerName;
4509 }
cd9e6b16 4510
4511 n = 0;
4512 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
4513 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
4514 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
4515 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
4516 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
4517 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
cd9e6b16 4518 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
df2a74ce 4519
4520 if (Exchange)
4521 {
4522 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
4523 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
4524 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
4525 mdbUseDefaults_v[0] = "TRUE";
4526 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
4527 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
4528
4529 argv[0] = user_name;
4530
4531 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4532 {
4533 if(!strcmp(save_argv[1], "EXCHANGE") ||
4534 (strstr(save_argv[3], search_string) != NULL))
4535 {
4536 argv[0] = exchange_acl;
4537 argv[1] = "USER";
4538 argv[2] = user_name;
4539
4540 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4541
4542 if ((rc) && (rc != MR_EXISTS))
4543 {
4544 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4545 user_name, exchange_acl, error_message(rc));
4546 }
4547 }
4548 else
4549 {
4550 alt_recipient_v[0] = alt_recipient;
4551 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4552 }
4553 }
4554 else
4555 {
4556 alt_recipient_v[0] = alt_recipient;
4557 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
4558
4559 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
4560 }
4561 }
4562 else
4563 {
4564 mail_v[0] = contact_mail;
4565 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
4566 }
4567
4568 if(strlen(av[U_FIRST])) {
4569 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
4570 }
4571
4572 if(strlen(av[U_LAST])) {
4573 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
4574 }
4575
4576 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
4577 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
4578 } else {
4579 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
4580 }
4581
4582 if (strlen(av[U_MIDDLE]) == 1) {
4583 initials_v[0] = av[U_MIDDLE];
4584 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
4585 }
4586
4587 if (strlen(call_args[2]) != 0)
89db421e 4588 {
4589 mitMoiraId_v[0] = call_args[2];
df2a74ce 4590 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
89db421e 4591 }
df2a74ce 4592
4593 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
4594
78af4e6e 4595 if (strlen(av[U_UID]) != 0)
4596 {
4597 uid_v[0] = av[U_UID];
4598 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
df2a74ce 4599
3abb4456 4600 if (!UseSFU30)
4601 {
4602 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
4603 }
4604 else
4605 {
4606 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
4607 }
78af4e6e 4608 }
df2a74ce 4609
7dc865bd 4610 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
78af4e6e 4611 mitid_v[0] = av[U_MITID];
4612 else
4613 mitid_v[0] = "none";
df2a74ce 4614
78af4e6e 4615 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
3abb4456 4616
4617 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn, WinHomeDir,
4618 WinProfileDir, homedir_v, winProfile_v,
4619 drives_v, mods, LDAP_MOD_ADD, n);
4620
df2a74ce 4621 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4622 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
4623 attr_array[0] = "sAMAccountName";
4624 attr_array[1] = NULL;
4625 group_count = 0;
4626 group_base = NULL;
4627
4628 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
4629 attr_array, &group_base, &group_count,
4630 LDAP_SCOPE_SUBTREE) != 0))
4631 return(1);
4632
4633 if (group_count != 1)
4634 {
4635 com_err(whoami, 0, "Unable to process user security template: %s - "
4636 "security not set", "UserTemplate.u");
4637 return(1);
4638 }
4639
4640 strcpy(TemplateDn, group_base->dn);
4641 strcpy(TemplateSamName, group_base->value);
4642 linklist_free(group_base);
4643 group_base = NULL;
4644 group_count = 0;
4645
4646 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path, LDAP_SCOPE_SUBTREE,
4647 filter_exp, NULL, 0, apsServerControls, NULL,
4648 NULL, 0, &psMsg);
4649
4650 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
4651 {
4652 com_err(whoami, 0, "Unable to find user security template: %s - "
4653 "security not set", "UserTemplate.u");
4654 return(1);
4655 }
4656
4657 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
4658 "ntSecurityDescriptor");
4659 if (ppsValues == NULL)
4660 {
4661 com_err(whoami, 0, "Unable to find user security template: %s - "
4662 "security not set", "UserTemplate.u");
4663 return(1);
4664 }
4665
4666 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4667 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4668
cd9e6b16 4669 mods[n] = NULL;
4670
4671 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
df2a74ce 4672
3abb4456 4673 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
df2a74ce 4674 {
3abb4456 4675 OldUseSFU30 = UseSFU30;
4676 SwitchSFU(mods, &UseSFU30, n);
4677 if (OldUseSFU30 != UseSFU30)
df2a74ce 4678 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
4679 }
3abb4456 4680
78af4e6e 4681 for (i = 0; i < n; i++)
4682 free(mods[i]);
df2a74ce 4683
5b8457c5 4684 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
4685 {
4a6e2ee4 4686 com_err(whoami, 0, "Unable to create user %s : %s",
5b8457c5 4687 user_name, ldap_err2string(rc));
4688 callback_rc = rc;
4689 return(rc);
4690 }
df2a74ce 4691
4692 if ((rc == LDAP_SUCCESS) && (SetPassword))
cd9e6b16 4693 {
f78c7eaf 4694 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
cd9e6b16 4695 {
26503e15 4696 ad_kdc_disconnect();
26503e15 4697 if (!ad_server_connect(default_server, ldap_domain))
4698 {
4699 com_err(whoami, 0, "Unable to set password for user %s : %s",
df2a74ce 4700 user_name,
4701 "cannot get changepw ticket from windows domain");
26503e15 4702 }
4703 else
4704 {
4705 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
4706 {
df2a74ce 4707 com_err(whoami, 0, "Unable to set password for user %s "
4708 ": %ld", user_name, rc);
26503e15 4709 }
4710 }
cd9e6b16 4711 }
4712 }
df2a74ce 4713
78af4e6e 4714 return(0);
cd9e6b16 4715}
4716
89db421e 4717int user_change_status(LDAP *ldap_handle, char *dn_path,
4718 char *user_name, char *MoiraId,
4719 int operation)
cd9e6b16 4720{
89db421e 4721 char filter[128];
cd9e6b16 4722 char *attr_array[3];
4723 char temp[256];
4724 char distinguished_name[1024];
cd9e6b16 4725 char **modvalues;
89db421e 4726 char *mitMoiraId_v[] = {NULL, NULL};
cd9e6b16 4727 LDAPMod *mods[20];
4728 LK_ENTRY *group_base;
4729 int group_count;
4730 int rc;
4731 int i;
4732 int n;
4733 ULONG ulongValue;
4734
f75f605a 4735 if (!check_string(user_name))
78af4e6e 4736 {
df2a74ce 4737 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4738 user_name);
89db421e 4739 return(AD_INVALID_NAME);
78af4e6e 4740 }
f75f605a 4741
cd9e6b16 4742 group_count = 0;
4743 group_base = NULL;
89db421e 4744
4745 if (strlen(MoiraId) != 0)
cd9e6b16 4746 {
c0bd7667 4747 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 4748 attr_array[0] = "UserAccountControl";
4749 attr_array[1] = NULL;
4750 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 4751 &group_base, &group_count,
4752 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 4753 {
4a6e2ee4 4754 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 4755 user_name, ldap_err2string(rc));
4756 return(rc);
4757 }
4758 }
df2a74ce 4759
c0bd7667 4760 if (group_count != 1)
89db421e 4761 {
c0bd7667 4762 linklist_free(group_base);
4763 group_count = 0;
4764 group_base = NULL;
89db421e 4765 sprintf(filter, "(sAMAccountName=%s)", user_name);
4766 attr_array[0] = "UserAccountControl";
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 return(rc);
4775 }
cd9e6b16 4776 }
df2a74ce 4777
78af4e6e 4778 if (group_count != 1)
cd9e6b16 4779 {
f75f605a 4780 linklist_free(group_base);
4a6e2ee4 4781 com_err(whoami, 0, "Unable to find user %s in AD",
f75f605a 4782 user_name);
4783 return(LDAP_NO_SUCH_OBJECT);
cd9e6b16 4784 }
4785
4786 strcpy(distinguished_name, group_base->dn);
4787 ulongValue = atoi((*group_base).value);
df2a74ce 4788
cd9e6b16 4789 if (operation == MEMBER_DEACTIVATE)
4790 ulongValue |= UF_ACCOUNTDISABLE;
4791 else
4792 ulongValue &= ~UF_ACCOUNTDISABLE;
df2a74ce 4793
cd9e6b16 4794 sprintf(temp, "%ld", ulongValue);
df2a74ce 4795
cd9e6b16 4796 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
4797 temp, &modvalues, REPLACE)) == 1)
f75f605a 4798 goto cleanup;
df2a74ce 4799
cd9e6b16 4800 linklist_free(group_base);
4801 group_base = NULL;
4802 group_count = 0;
4803 n = 0;
4804 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
df2a74ce 4805
89db421e 4806 if (strlen(MoiraId) != 0)
4807 {
4808 mitMoiraId_v[0] = MoiraId;
4809 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
4810 }
df2a74ce 4811
cd9e6b16 4812 mods[n] = NULL;
f75f605a 4813 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
df2a74ce 4814
cd9e6b16 4815 for (i = 0; i < n; i++)
4816 free(mods[i]);
df2a74ce 4817
cd9e6b16 4818 free_values(modvalues);
df2a74ce 4819
cd9e6b16 4820 if (rc != LDAP_SUCCESS)
4821 {
4a6e2ee4 4822 com_err(whoami, 0, "Unable to change status of user %s : %s",
f75f605a 4823 user_name, ldap_err2string(rc));
cd9e6b16 4824 }
df2a74ce 4825
4826 cleanup:
f75f605a 4827 return(rc);
cd9e6b16 4828}
4829
89db421e 4830int user_delete(LDAP *ldap_handle, char *dn_path,
4831 char *u_name, char *MoiraId)
cd9e6b16 4832{
89db421e 4833 char filter[128];
cd9e6b16 4834 char *attr_array[3];
4835 char distinguished_name[1024];
4836 char user_name[512];
4837 LK_ENTRY *group_base;
4838 int group_count;
4839 int rc;
df2a74ce 4840 char temp[256];
cd9e6b16 4841
4842 if (!check_string(u_name))
89db421e 4843 return(AD_INVALID_NAME);
4844
cd9e6b16 4845 strcpy(user_name, u_name);
4846 group_count = 0;
4847 group_base = NULL;
89db421e 4848
4849 if (strlen(MoiraId) != 0)
cd9e6b16 4850 {
c0bd7667 4851 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 4852 attr_array[0] = "name";
4853 attr_array[1] = NULL;
4854 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 4855 &group_base, &group_count,
4856 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 4857 {
4a6e2ee4 4858 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 4859 user_name, ldap_err2string(rc));
4860 goto cleanup;
4861 }
4862 }
df2a74ce 4863
c0bd7667 4864 if (group_count != 1)
89db421e 4865 {
c0bd7667 4866 linklist_free(group_base);
4867 group_count = 0;
4868 group_base = NULL;
89db421e 4869 sprintf(filter, "(sAMAccountName=%s)", user_name);
4870 attr_array[0] = "name";
4871 attr_array[1] = NULL;
4872 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 4873 &group_base, &group_count,
4874 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 4875 {
4a6e2ee4 4876 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 4877 user_name, ldap_err2string(rc));
4878 goto cleanup;
4879 }
cd9e6b16 4880 }
4881
78af4e6e 4882 if (group_count != 1)
cd9e6b16 4883 {
4a6e2ee4 4884 com_err(whoami, 0, "Unable to find user %s in AD",
f75f605a 4885 user_name);
cd9e6b16 4886 goto cleanup;
4887 }
df2a74ce 4888
cd9e6b16 4889 strcpy(distinguished_name, group_base->dn);
df2a74ce 4890
cd9e6b16 4891 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
4892 {
4a6e2ee4 4893 com_err(whoami, 0, "Unable to process user %s : %s",
f75f605a 4894 user_name, ldap_err2string(rc));
cd9e6b16 4895 }
4896
df2a74ce 4897 /* Need to add code to delete mit.edu contact */
4898
4899 if (Exchange)
4900 {
4901 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
4902
4903 if(rc = ldap_delete_s(ldap_handle, temp))
4904 {
4905 com_err(whoami, 0, "Unable to delete user contact for %s",
4906 user_name);
4907 }
4908 }
4909
4910 cleanup:
cd9e6b16 4911 linklist_free(group_base);
df2a74ce 4912
78af4e6e 4913 return(0);
cd9e6b16 4914}
4915
4916void linklist_free(LK_ENTRY *linklist_base)
4917{
4918 LK_ENTRY *linklist_previous;
4919
4920 while (linklist_base != NULL)
4921 {
4922 if (linklist_base->dn != NULL)
4923 free(linklist_base->dn);
df2a74ce 4924
cd9e6b16 4925 if (linklist_base->attribute != NULL)
4926 free(linklist_base->attribute);
df2a74ce 4927
cd9e6b16 4928 if (linklist_base->value != NULL)
4929 free(linklist_base->value);
df2a74ce 4930
cd9e6b16 4931 if (linklist_base->member != NULL)
4932 free(linklist_base->member);
df2a74ce 4933
cd9e6b16 4934 if (linklist_base->type != NULL)
4935 free(linklist_base->type);
df2a74ce 4936
cd9e6b16 4937 if (linklist_base->list != NULL)
4938 free(linklist_base->list);
df2a74ce 4939
cd9e6b16 4940 linklist_previous = linklist_base;
4941 linklist_base = linklist_previous->next;
4942 free(linklist_previous);
4943 }
4944}
4945
4946void free_values(char **modvalues)
4947{
4948 int i;
4949
4950 i = 0;
df2a74ce 4951
cd9e6b16 4952 if (modvalues != NULL)
4953 {
4954 while (modvalues[i] != NULL)
4955 {
4956 free(modvalues[i]);
4957 modvalues[i] = NULL;
4958 ++i;
4959 }
4960 free(modvalues);
4961 }
4962}
4963
cd9e6b16 4964static int illegalchars[] = {
4965 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
4966 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
4967 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
4968 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
f75f605a 4969 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
cd9e6b16 4970 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
4971 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
4972 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
4973 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4974 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4975 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4976 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4977 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4978 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4979 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4980 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
4981};
4982
4983int check_string(char *s)
4984{
78af4e6e 4985 char character;
4986
cd9e6b16 4987 for (; *s; s++)
4988 {
78af4e6e 4989 character = *s;
df2a74ce 4990
78af4e6e 4991 if (isupper(character))
4992 character = tolower(character);
df2a74ce 4993
78af4e6e 4994 if (illegalchars[(unsigned) character])
cd9e6b16 4995 return 0;
4996 }
df2a74ce 4997
4998 return(1);
cd9e6b16 4999}
5000
bb52f279 5001int check_container_name(char *s)
5002{
5003 char character;
5004
5005 for (; *s; s++)
5006 {
5007 character = *s;
df2a74ce 5008
bb52f279 5009 if (isupper(character))
5010 character = tolower(character);
5011
df2a74ce 5012 if (character == ' ')
5013 continue;
5014
bb52f279 5015 if (illegalchars[(unsigned) character])
5016 return 0;
5017 }
df2a74ce 5018
5019 return(1);
bb52f279 5020}
5021
cd9e6b16 5022int mr_connect_cl(char *server, char *client, int version, int auth)
5023{
984c91b7 5024 int status;
5025 char *motd;
5026 char temp[128];
cd9e6b16 5027
5028 status = mr_connect(server);
df2a74ce 5029
cd9e6b16 5030 if (status)
5031 {
5032 com_err(whoami, status, "while connecting to Moira");
aea5154c 5033 return status;
cd9e6b16 5034 }
5035
5036 status = mr_motd(&motd);
df2a74ce 5037
cd9e6b16 5038 if (status)
5039 {
5040 mr_disconnect();
5041 com_err(whoami, status, "while checking server status");
aea5154c 5042 return status;
cd9e6b16 5043 }
df2a74ce 5044
cd9e6b16 5045 if (motd)
5046 {
984c91b7 5047 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5048 com_err(whoami, status, temp);
cd9e6b16 5049 mr_disconnect();
aea5154c 5050 return status;
cd9e6b16 5051 }
5052
5053 status = mr_version(version);
df2a74ce 5054
cd9e6b16 5055 if (status)
5056 {
5057 if (status == MR_UNKNOWN_PROC)
f78c7eaf 5058 {
5059 if (version > 2)
5060 status = MR_VERSION_HIGH;
5061 else
5062 status = MR_SUCCESS;
5063 }
cd9e6b16 5064
5065 if (status == MR_VERSION_HIGH)
f78c7eaf 5066 {
df2a74ce 5067 com_err(whoami, 0, "Warning: This client is running newer code "
5068 "than the server.");
f78c7eaf 5069 com_err(whoami, 0, "Some operations may not work.");
5070 }
cd9e6b16 5071 else if (status && status != MR_VERSION_LOW)
f78c7eaf 5072 {
5073 com_err(whoami, status, "while setting query version number.");
5074 mr_disconnect();
aea5154c 5075 return status;
f78c7eaf 5076 }
cd9e6b16 5077 }
5078
5079 if (auth)
5080 {
991417e4 5081 status = mr_krb5_auth(client);
cd9e6b16 5082 if (status)
f78c7eaf 5083 {
5084 com_err(whoami, status, "while authenticating to Moira.");
5085 mr_disconnect();
aea5154c 5086 return status;
f78c7eaf 5087 }
cd9e6b16 5088 }
df2a74ce 5089
aea5154c 5090 return MR_SUCCESS;
cd9e6b16 5091}
5092
f78c7eaf 5093void AfsToWinAfs(char* path, char* winPath)
5094{
df2a74ce 5095 char* pathPtr;
5096 char* winPathPtr;
5097 strcpy(winPath, WINAFS);
5098 pathPtr = path + strlen(AFS);
5099 winPathPtr = winPath + strlen(WINAFS);
5100
5101 while (*pathPtr)
f78c7eaf 5102 {
df2a74ce 5103 if (*pathPtr == '/')
5104 *winPathPtr = '\\';
5105 else
5106 *winPathPtr = *pathPtr;
5107
5108 pathPtr++;
5109 winPathPtr++;
f78c7eaf 5110 }
5111}
89db421e 5112
909e0dc3 5113int GetAceInfo(int ac, char **av, void *ptr)
5114{
5115 char **call_args;
5116 int security_flag;
5117
5118 call_args = ptr;
df2a74ce 5119
909e0dc3 5120 strcpy(call_args[0], av[L_ACE_TYPE]);
5121 strcpy(call_args[1], av[L_ACE_NAME]);
5122 security_flag = 0;
5123 get_group_membership(call_args[2], call_args[3], &security_flag, av);
df2a74ce 5124 return(LDAP_SUCCESS);
909e0dc3 5125}
5126
bbef4f93 5127int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
909e0dc3 5128{
5129 char filter[128];
5130 char *attr_array[3];
5131 int group_count;
5132 int rc;
5133 LK_ENTRY *group_base;
df2a74ce 5134
909e0dc3 5135 group_count = 0;
5136 group_base = NULL;
df2a74ce 5137
909e0dc3 5138 sprintf(filter, "(sAMAccountName=%s)", Name);
5139 attr_array[0] = "sAMAccountName";
5140 attr_array[1] = NULL;
df2a74ce 5141
909e0dc3 5142 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5143 &group_base, &group_count,
5144 LDAP_SCOPE_SUBTREE)) != 0)
909e0dc3 5145 {
4a6e2ee4 5146 com_err(whoami, 0, "Unable to process ACE name %s : %s",
909e0dc3 5147 Name, ldap_err2string(rc));
5148 return(1);
5149 }
5150
5151 linklist_free(group_base);
5152 group_base = NULL;
df2a74ce 5153
909e0dc3 5154 if (group_count == 0)
5155 return(0);
df2a74ce 5156
909e0dc3 5157 return(1);
5158}
5159
5160#define MAX_ACE 7
5161
df2a74ce 5162int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5163 int UpdateGroup, int *ProcessGroup, char *maillist)
909e0dc3 5164{
5165 char *av[2];
5166 char GroupName[256];
5167 char *call_args[7];
5168 int rc;
5169 char *AceInfo[4];
5170 char AceType[32];
5171 char AceName[128];
5172 char AceMembership[2];
5173 char AceOu[256];
5174 char temp[128];
df2a74ce 5175 char *save_argv[U_END];
909e0dc3 5176
df2a74ce 5177 if (!SetGroupAce)
5178 {
5179 com_err(whoami, 0, "ProcessAce disabled, skipping");
5180 return(0);
5181 }
909e0dc3 5182
df2a74ce 5183 strcpy(GroupName, Name);
5184
909e0dc3 5185 if (strcasecmp(Type, "LIST"))
5186 return(1);
df2a74ce 5187
909e0dc3 5188 while (1)
5189 {
5190 av[0] = GroupName;
5191 AceInfo[0] = AceType;
5192 AceInfo[1] = AceName;
5193 AceInfo[2] = AceMembership;
5194 AceInfo[3] = AceOu;
5195 memset(AceType, '\0', sizeof(AceType));
5196 memset(AceName, '\0', sizeof(AceName));
5197 memset(AceMembership, '\0', sizeof(AceMembership));
5198 memset(AceOu, '\0', sizeof(AceOu));
5199 callback_rc = 0;
df2a74ce 5200
909e0dc3 5201 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
df2a74ce 5202 {
5203 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5204 GroupName, error_message(rc));
909e0dc3 5205 return(1);
5206 }
df2a74ce 5207
909e0dc3 5208 if (callback_rc)
5209 {
4a6e2ee4 5210 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
909e0dc3 5211 return(1);
5212 }
df2a74ce 5213
909e0dc3 5214 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5215 return(0);
df2a74ce 5216
909e0dc3 5217 strcpy(temp, AceName);
df2a74ce 5218
909e0dc3 5219 if (!strcasecmp(AceType, "LIST"))
df2a74ce 5220 sprintf(temp, "%s%s", AceName, group_suffix);
5221
909e0dc3 5222 if (!UpdateGroup)
5223 {
bbef4f93 5224 if (checkADname(ldap_handle, dn_path, temp))
909e0dc3 5225 return(0);
5226 (*ProcessGroup) = 1;
5227 }
df2a74ce 5228
909e0dc3 5229 if (!strcasecmp(AceInfo[0], "LIST"))
5230 {
df2a74ce 5231 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5232 AceMembership, 0, UpdateGroup, maillist))
909e0dc3 5233 return(1);
5234 }
5235 else if (!strcasecmp(AceInfo[0], "USER"))
5236 {
5237 av[0] = AceName;
5238 call_args[0] = (char *)ldap_handle;
5239 call_args[1] = dn_path;
5240 call_args[2] = "";
5241 call_args[3] = NULL;
909e0dc3 5242 callback_rc = 0;
df2a74ce 5243
5244 if (rc = mr_query("get_user_account_by_login", 1, av,
5245 save_query_info, save_argv))
909e0dc3 5246 {
df2a74ce 5247 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5248 AceName, Name);
909e0dc3 5249 return(1);
5250 }
df2a74ce 5251
5252 if (rc = user_create(U_END, save_argv, call_args))
5253 {
5254 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5255 AceName, Name);
5256 return(1);
5257 }
5258
909e0dc3 5259 if (callback_rc)
5260 {
df2a74ce 5261 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
5262 AceName, Name);
909e0dc3 5263 return(1);
5264 }
df2a74ce 5265
909e0dc3 5266 return(0);
5267 }
5268 else
5269 return(1);
df2a74ce 5270
909e0dc3 5271 if (!strcasecmp(AceType, "LIST"))
5272 {
5273 if (!strcasecmp(GroupName, AceName))
5274 return(0);
5275 }
df2a74ce 5276
909e0dc3 5277 strcpy(GroupName, AceName);
5278 }
df2a74ce 5279
909e0dc3 5280 return(1);
5281}
5282
89db421e 5283int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5284 char *group_name, char *group_ou, char *group_membership,
df2a74ce 5285 int group_security_flag, int updateGroup, char *maillist)
89db421e 5286{
5287 char *av[3];
df2a74ce 5288 char *call_args[8];
89db421e 5289 int rc;
df2a74ce 5290 LK_ENTRY *group_base;
5291 int group_count;
5292 char filter[128];
5293 char *attr_array[3];
89db421e 5294
5295 av[0] = group_name;
5296 call_args[0] = (char *)ldap_handle;
5297 call_args[1] = dn_path;
5298 call_args[2] = group_name;
5299 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5300 call_args[4] = (char *)updateGroup;
5301 call_args[5] = MoiraId;
df2a74ce 5302 call_args[6] = "0";
5303 call_args[7] = NULL;
89db421e 5304 callback_rc = 0;
df2a74ce 5305
5306 group_count = 0;
5307 group_base = NULL;
5308
89db421e 5309 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
5310 {
5311 moira_disconnect();
df2a74ce 5312 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
5313 error_message(rc));
89db421e 5314 return(rc);
5315 }
df2a74ce 5316
89db421e 5317 if (callback_rc)
5318 {
5319 moira_disconnect();
4a6e2ee4 5320 com_err(whoami, 0, "Unable to create list %s", group_name);
89db421e 5321 return(callback_rc);
5322 }
5323
89db421e 5324 return(0);
5325}
5326
5327int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
5328 char *group_ou, char *group_membership,
5329 int group_security_flag, char *MoiraId)
5330{
5331 char *av[3];
5332 char *call_args[7];
5333 char *pUserOu;
5334 LK_ENTRY *ptr;
5335 int rc;
df2a74ce 5336 char member[256];
5337 char *s;
89db421e 5338
5339 com_err(whoami, 0, "Populating group %s", group_name);
5340 av[0] = group_name;
5341 call_args[0] = (char *)ldap_handle;
5342 call_args[1] = dn_path;
5343 call_args[2] = group_name;
5344 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
5345 call_args[4] = NULL;
5346 member_base = NULL;
df2a74ce 5347
89db421e 5348 if (rc = mr_query("get_end_members_of_list", 1, av,
5349 member_list_build, call_args))
5350 {
4a6e2ee4 5351 com_err(whoami, 0, "Unable to populate list %s : %s",
89db421e 5352 group_name, error_message(rc));
5353 return(3);
5354 }
df2a74ce 5355
89db421e 5356 if (member_base != NULL)
5357 {
5358 ptr = member_base;
df2a74ce 5359
89db421e 5360 while (ptr != NULL)
5361 {
5362 if (!strcasecmp(ptr->type, "LIST"))
5363 {
5364 ptr = ptr->next;
5365 continue;
5366 }
df2a74ce 5367
89db421e 5368 pUserOu = user_ou;
df2a74ce 5369
89db421e 5370 if (!strcasecmp(ptr->type, "STRING"))
5371 {
df2a74ce 5372 if (contact_create(ldap_handle, dn_path, ptr->member,
5373 contact_ou))
89db421e 5374 return(3);
df2a74ce 5375
89db421e 5376 pUserOu = contact_ou;
5377 }
5378 else if (!strcasecmp(ptr->type, "KERBEROS"))
5379 {
df2a74ce 5380 if (contact_create(ldap_handle, dn_path, ptr->member,
5381 kerberos_ou))
89db421e 5382 return(3);
df2a74ce 5383
89db421e 5384 pUserOu = kerberos_ou;
5385 }
df2a74ce 5386
89db421e 5387 rc = member_add(ldap_handle, dn_path, group_name,
5388 group_ou, group_membership, ptr->member,
5389 pUserOu, MoiraId);
5390 ptr = ptr->next;
5391 }
df2a74ce 5392
89db421e 5393 linklist_free(member_base);
5394 member_base = NULL;
5395 }
df2a74ce 5396
89db421e 5397 return(0);
5398}
5399
5400int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
5401 char *group_name, char *group_ou, char *group_membership,
df2a74ce 5402 int group_security_flag, int type, char *maillist)
89db421e 5403{
5404 char before_desc[512];
5405 char before_name[256];
5406 char before_group_ou[256];
5407 char before_group_membership[2];
5408 char distinguishedName[256];
5409 char ad_distinguishedName[256];
5410 char filter[128];
5411 char *attr_array[3];
5412 int before_security_flag;
5413 int group_count;
5414 int rc;
5415 LK_ENTRY *group_base;
5416 LK_ENTRY *ptr;
5417 char ou_both[512];
5418 char ou_security[512];
5419 char ou_distribution[512];
5420 char ou_neither[512];
5421
5422 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
5423 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
5424
89db421e 5425 memset(filter, '\0', sizeof(filter));
5426 group_base = NULL;
5427 group_count = 0;
df2a74ce 5428
89db421e 5429 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5430 "*", MoiraId,
5431 "distinguishedName", &group_base,
5432 &group_count, filter))
5433 return(rc);
5434
5435 if (type == CHECK_GROUPS)
5436 {
5437 if (group_count == 1)
5438 {
5439 if (!strcasecmp(group_base->value, distinguishedName))
5440 {
5441 linklist_free(group_base);
5442 return(0);
5443 }
5444 }
df2a74ce 5445
89db421e 5446 linklist_free(group_base);
df2a74ce 5447
89db421e 5448 if (group_count == 0)
5449 return(AD_NO_GROUPS_FOUND);
df2a74ce 5450
89db421e 5451 if (group_count == 1)
5452 return(AD_WRONG_GROUP_DN_FOUND);
df2a74ce 5453
89db421e 5454 return(AD_MULTIPLE_GROUPS_FOUND);
5455 }
df2a74ce 5456
89db421e 5457 if (group_count == 0)
5458 {
5459 return(AD_NO_GROUPS_FOUND);
5460 }
df2a74ce 5461
89db421e 5462 if (group_count > 1)
5463 {
5464 ptr = group_base;
df2a74ce 5465
89db421e 5466 while (ptr != NULL)
5467 {
5468 if (!strcasecmp(distinguishedName, ptr->value))
5469 break;
df2a74ce 5470
89db421e 5471 ptr = ptr->next;
5472 }
df2a74ce 5473
89db421e 5474 if (ptr == NULL)
5475 {
df2a74ce 5476 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
5477 MoiraId);
89db421e 5478 ptr = group_base;
df2a74ce 5479
89db421e 5480 while (ptr != NULL)
5481 {
5482 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
5483 ptr = ptr->next;
5484 }
df2a74ce 5485
89db421e 5486 linklist_free(group_base);
5487 return(AD_MULTIPLE_GROUPS_FOUND);
6c8f12af 5488 }
df2a74ce 5489
89db421e 5490 ptr = group_base;
df2a74ce 5491
89db421e 5492 while (ptr != NULL)
5493 {
5494 if (strcasecmp(distinguishedName, ptr->value))
5495 rc = ldap_delete_s(ldap_handle, ptr->value);
df2a74ce 5496
89db421e 5497 ptr = ptr->next;
5498 }
df2a74ce 5499
89db421e 5500 linklist_free(group_base);
5501 memset(filter, '\0', sizeof(filter));
5502 group_base = NULL;
5503 group_count = 0;
df2a74ce 5504
89db421e 5505 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
5506 "*", MoiraId,
5507 "distinguishedName", &group_base,
5508 &group_count, filter))
5509 return(rc);
df2a74ce 5510
89db421e 5511 if (group_count == 0)
5512 return(AD_NO_GROUPS_FOUND);
df2a74ce 5513
89db421e 5514 if (group_count > 1)
5515 return(AD_MULTIPLE_GROUPS_FOUND);
5516 }
df2a74ce 5517
89db421e 5518 strcpy(ad_distinguishedName, group_base->value);
5519 linklist_free(group_base);
5520 group_base = NULL;
5521 group_count = 0;
5522
5523 attr_array[0] = "sAMAccountName";
5524 attr_array[1] = NULL;
df2a74ce 5525
89db421e 5526 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5527 &group_base, &group_count,
5528 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5529 {
4a6e2ee4 5530 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5531 MoiraId, ldap_err2string(rc));
5532 return(rc);
5533 }
89db421e 5534
df2a74ce 5535 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
5536
89db421e 5537 if (!strcasecmp(ad_distinguishedName, distinguishedName))
5538 {
5539 linklist_free(group_base);
5540 group_base = NULL;
5541 group_count = 0;
5542 return(0);
5543 }
df2a74ce 5544
89db421e 5545 linklist_free(group_base);
5546 group_base = NULL;
5547 group_count = 0;
5548 memset(ou_both, '\0', sizeof(ou_both));
5549 memset(ou_security, '\0', sizeof(ou_security));
5550 memset(ou_distribution, '\0', sizeof(ou_distribution));
5551 memset(ou_neither, '\0', sizeof(ou_neither));
5552 memset(before_name, '\0', sizeof(before_name));
5553 memset(before_desc, '\0', sizeof(before_desc));
5554 memset(before_group_membership, '\0', sizeof(before_group_membership));
5555 attr_array[0] = "name";
5556 attr_array[1] = NULL;
df2a74ce 5557
89db421e 5558 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5559 &group_base, &group_count,
5560 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5561 {
4a6e2ee4 5562 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
89db421e 5563 MoiraId, ldap_err2string(rc));
5564 return(rc);
5565 }
df2a74ce 5566
89db421e 5567 strcpy(before_name, group_base->value);
5568 linklist_free(group_base);
5569 group_base = NULL;
5570 group_count = 0;
5571 attr_array[0] = "description";
5572 attr_array[1] = NULL;
df2a74ce 5573
89db421e 5574 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5575 &group_base, &group_count,
5576 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5577 {
5578 com_err(whoami, 0,
4a6e2ee4 5579 "Unable to get list description with MoiraId = %s: %s",
89db421e 5580 MoiraId, ldap_err2string(rc));
5581 return(rc);
5582 }
df2a74ce 5583
c0bd7667 5584 if (group_count != 0)
5585 {
5586 strcpy(before_desc, group_base->value);
5587 linklist_free(group_base);
5588 group_base = NULL;
5589 group_count = 0;
5590 }
df2a74ce 5591
89db421e 5592 change_to_lower_case(ad_distinguishedName);
5593 strcpy(ou_both, group_ou_both);
5594 change_to_lower_case(ou_both);
5595 strcpy(ou_security, group_ou_security);
5596 change_to_lower_case(ou_security);
5597 strcpy(ou_distribution, group_ou_distribution);
5598 change_to_lower_case(ou_distribution);
5599 strcpy(ou_neither, group_ou_neither);
5600 change_to_lower_case(ou_neither);
df2a74ce 5601
89db421e 5602 if (strstr(ad_distinguishedName, ou_both))
5603 {
5604 strcpy(before_group_ou, group_ou_both);
5605 before_group_membership[0] = 'B';
5606 before_security_flag = 1;
5607 }
5608 else if (strstr(ad_distinguishedName, ou_security))
5609 {
5610 strcpy(before_group_ou, group_ou_security);
5611 before_group_membership[0] = 'S';
5612 before_security_flag = 1;
5613 }
5614 else if (strstr(ad_distinguishedName, ou_distribution))
5615 {
5616 strcpy(before_group_ou, group_ou_distribution);
5617 before_group_membership[0] = 'D';
5618 before_security_flag = 0;
5619 }
5620 else if (strstr(ad_distinguishedName, ou_neither))
5621 {
5622 strcpy(before_group_ou, group_ou_neither);
5623 before_group_membership[0] = 'N';
5624 before_security_flag = 0;
5625 }
5626 else
5627 return(AD_NO_OU_FOUND);
df2a74ce 5628
5629 rc = group_rename(ldap_handle, dn_path, before_name,
5630 before_group_membership,
89db421e 5631 before_group_ou, before_security_flag, before_desc,
df2a74ce 5632 group_name, group_membership, group_ou,
5633 group_security_flag,
5634 before_desc, MoiraId, filter, maillist);
5635
89db421e 5636 return(rc);
5637}
5638
5639void change_to_lower_case(char *ptr)
5640{
5641 int i;
5642
5643 for (i = 0; i < (int)strlen(ptr); i++)
5644 {
5645 ptr[i] = tolower(ptr[i]);
5646 }
5647}
5648
5649int ad_get_group(LDAP *ldap_handle, char *dn_path,
5650 char *group_name, char *group_membership,
5651 char *MoiraId, char *attribute,
5652 LK_ENTRY **linklist_base, int *linklist_count,
5653 char *rFilter)
5654{
3e586ecf 5655 LK_ENTRY *pPtr;
c0bd7667 5656 char filter[128];
5657 char *attr_array[3];
89db421e 5658 int rc;
5659
5660 (*linklist_base) = NULL;
5661 (*linklist_count) = 0;
df2a74ce 5662
89db421e 5663 if (strlen(rFilter) != 0)
5664 {
5665 strcpy(filter, rFilter);
5666 attr_array[0] = attribute;
5667 attr_array[1] = NULL;
df2a74ce 5668
89db421e 5669 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5670 linklist_base, linklist_count,
5671 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5672 {
4a6e2ee4 5673 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5674 MoiraId, ldap_err2string(rc));
5675 return(rc);
5676 }
df2a74ce 5677
89db421e 5678 if ((*linklist_count) == 1)
5679 {
5680 strcpy(rFilter, filter);
5681 return(0);
5682 }
5683 }
5684
5685 linklist_free((*linklist_base));
5686 (*linklist_base) = NULL;
5687 (*linklist_count) = 0;
df2a74ce 5688
89db421e 5689 if (strlen(MoiraId) != 0)
5690 {
c0bd7667 5691 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
89db421e 5692 attr_array[0] = attribute;
5693 attr_array[1] = NULL;
df2a74ce 5694
89db421e 5695 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5696 linklist_base, linklist_count,
5697 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5698 {
4a6e2ee4 5699 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5700 MoiraId, ldap_err2string(rc));
5701 return(rc);
5702 }
5703 }
df2a74ce 5704
3e586ecf 5705 if ((*linklist_count) > 1)
5706 {
5707 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
5708 pPtr = (*linklist_base);
df2a74ce 5709
3e586ecf 5710 while (pPtr)
5711 {
df2a74ce 5712 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
5713 MoiraId);
3e586ecf 5714 pPtr = pPtr->next;
5715 }
df2a74ce 5716
3e586ecf 5717 linklist_free((*linklist_base));
5718 (*linklist_base) = NULL;
5719 (*linklist_count) = 0;
5720 }
df2a74ce 5721
89db421e 5722 if ((*linklist_count) == 1)
5723 {
909e0dc3 5724 if (!memcmp(&(*linklist_base)->value[3], group_name, strlen(group_name)))
5725 {
5726 strcpy(rFilter, filter);
5727 return(0);
5728 }
89db421e 5729 }
5730
5731 linklist_free((*linklist_base));
5732 (*linklist_base) = NULL;
5733 (*linklist_count) = 0;
df2a74ce 5734 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
89db421e 5735 attr_array[0] = attribute;
5736 attr_array[1] = NULL;
df2a74ce 5737
89db421e 5738 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5739 linklist_base, linklist_count,
5740 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5741 {
4a6e2ee4 5742 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5743 MoiraId, ldap_err2string(rc));
5744 return(rc);
5745 }
df2a74ce 5746
89db421e 5747 if ((*linklist_count) == 1)
5748 {
5749 strcpy(rFilter, filter);
5750 return(0);
5751 }
5752
89db421e 5753 return(0);
5754}
5755
5756int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5757{
5758 char filter[128];
5759 char *attr_array[3];
5760 char SamAccountName[64];
5761 int group_count;
5762 int rc;
5763 LK_ENTRY *group_base;
c0bd7667 5764 LK_ENTRY *gPtr;
89db421e 5765
5766 group_count = 0;
5767 group_base = NULL;
5768
5769 if (strlen(MoiraId) != 0)
5770 {
c0bd7667 5771 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 5772 attr_array[0] = "sAMAccountName";
5773 attr_array[1] = NULL;
5774 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5775 &group_base, &group_count,
5776 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5777 {
4a6e2ee4 5778 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 5779 UserName, ldap_err2string(rc));
5780 return(rc);
5781 }
df2a74ce 5782
c0bd7667 5783 if (group_count > 1)
5784 {
5785 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5786 MoiraId);
5787 gPtr = group_base;
df2a74ce 5788
c0bd7667 5789 while (gPtr)
5790 {
5791 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5792 gPtr->value, MoiraId);
5793 gPtr = gPtr->next;
5794 }
5795 }
89db421e 5796 }
df2a74ce 5797
c0bd7667 5798 if (group_count != 1)
89db421e 5799 {
c0bd7667 5800 linklist_free(group_base);
5801 group_count = 0;
5802 group_base = NULL;
89db421e 5803 sprintf(filter, "(sAMAccountName=%s)", UserName);
5804 attr_array[0] = "sAMAccountName";
5805 attr_array[1] = NULL;
df2a74ce 5806
89db421e 5807 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5808 &group_base, &group_count,
5809 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5810 {
4a6e2ee4 5811 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 5812 UserName, ldap_err2string(rc));
5813 return(rc);
5814 }
5815 }
5816
5817 if (group_count != 1)
5818 {
5819 linklist_free(group_base);
5820 return(AD_NO_USER_FOUND);
5821 }
df2a74ce 5822
89db421e 5823 strcpy(SamAccountName, group_base->value);
5824 linklist_free(group_base);
5825 group_count = 0;
5826 rc = 0;
df2a74ce 5827
89db421e 5828 if (strcmp(SamAccountName, UserName))
5829 {
5830 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5831 UserName);
5832 }
df2a74ce 5833
89db421e 5834 return(0);
5835}
6c8f12af 5836
5837void container_get_dn(char *src, char *dest)
5838{
5839 char *sPtr;
5840 char *array[20];
5841 char name[256];
5842 int n;
5843
5844 memset(array, '\0', 20 * sizeof(array[0]));
5845
5846 if (strlen(src) == 0)
5847 return;
df2a74ce 5848
6c8f12af 5849 strcpy(name, src);
5850 sPtr = name;
5851 n = 0;
5852 array[n] = name;
5853 ++n;
df2a74ce 5854
6c8f12af 5855 while (*sPtr)
5856 {
5857 if ((*sPtr) == '/')
5858 {
5859 (*sPtr) = '\0';
5860 ++sPtr;
5861 array[n] = sPtr;
5862 ++n;
5863 }
5864 else
5865 ++sPtr;
5866 }
df2a74ce 5867
6c8f12af 5868 strcpy(dest, "OU=");
df2a74ce 5869
6c8f12af 5870 while (n != 0)
5871 {
5872 strcat(dest, array[n-1]);
5873 --n;
5874 if (n > 0)
5875 {
5876 strcat(dest, ",OU=");
5877 }
5878 }
df2a74ce 5879
6c8f12af 5880 return;
5881}
5882
5883void container_get_name(char *src, char *dest)
5884{
5885 char *sPtr;
5886 char *dPtr;
5887
5888 if (strlen(src) == 0)
5889 return;
df2a74ce 5890
6c8f12af 5891 sPtr = src;
5892 dPtr = src;
df2a74ce 5893
6c8f12af 5894 while (*sPtr)
5895 {
5896 if ((*sPtr) == '/')
5897 {
5898 dPtr = sPtr;
5899 ++dPtr;
5900 }
5901 ++sPtr;
5902 }
df2a74ce 5903
6c8f12af 5904 strcpy(dest, dPtr);
5905 return;
5906}
5907
5908void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5909{
5910 char cName[256];
5911 char *av[7];
5912 int i;
5913 int rc;
5914
5915 strcpy(cName, name);
df2a74ce 5916
6c8f12af 5917 for (i = 0; i < (int)strlen(cName); i++)
5918 {
5919 if (cName[i] == '/')
5920 {
5921 cName[i] = '\0';
5922 av[CONTAINER_NAME] = cName;
5923 av[CONTAINER_DESC] = "";
5924 av[CONTAINER_LOCATION] = "";
5925 av[CONTAINER_CONTACT] = "";
5926 av[CONTAINER_TYPE] = "";
5927 av[CONTAINER_ID] = "";
5928 av[CONTAINER_ROWID] = "";
5929 rc = container_create(ldap_handle, dn_path, 7, av);
df2a74ce 5930
6c8f12af 5931 if (rc == LDAP_SUCCESS)
5932 {
df2a74ce 5933 com_err(whoami, 0, "container %s created without a mitMoiraId",
5934 cName);
6c8f12af 5935 }
df2a74ce 5936
6c8f12af 5937 cName[i] = '/';
5938 }
5939 }
6c8f12af 5940}
5941
df2a74ce 5942int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5943 char **before, int afterc, char **after)
6c8f12af 5944{
5945 char dName[256];
5946 char cName[256];
5947 char new_cn[128];
5948 char new_dn_path[256];
5949 char temp[256];
5950 char distinguishedName[256];
5951 char *pPtr;
5952 int rc;
5953 int i;
5954
5955 memset(cName, '\0', sizeof(cName));
5956 container_get_name(after[CONTAINER_NAME], cName);
df2a74ce 5957
bb52f279 5958 if (!check_container_name(cName))
6c8f12af 5959 {
df2a74ce 5960 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5961 cName);
6c8f12af 5962 return(AD_INVALID_NAME);
5963 }
5964
5965 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 5966
5967 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5968 distinguishedName, beforec, before))
6c8f12af 5969 return(rc);
df2a74ce 5970
6c8f12af 5971 if (strlen(distinguishedName) == 0)
5972 {
5973 rc = container_create(ldap_handle, dn_path, afterc, after);
5974 return(rc);
5975 }
5976
5977 strcpy(temp, after[CONTAINER_NAME]);
9cfe334f 5978 pPtr = temp;
df2a74ce 5979
6c8f12af 5980 for (i = 0; i < (int)strlen(temp); i++)
5981 {
5982 if (temp[i] == '/')
5983 {
5984 pPtr = &temp[i];
5985 }
5986 }
df2a74ce 5987
9cfe334f 5988 (*pPtr) = '\0';
6c8f12af 5989
5990 container_get_dn(temp, dName);
df2a74ce 5991
9cfe334f 5992 if (strlen(temp) != 0)
5993 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5994 else
5995 sprintf(new_dn_path, "%s", dn_path);
df2a74ce 5996
6c8f12af 5997 sprintf(new_cn, "OU=%s", cName);
5998
5999 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6000
6001 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6002 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6003 {
4a6e2ee4 6004 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
df2a74ce 6005 before[CONTAINER_NAME], after[CONTAINER_NAME],
6006 ldap_err2string(rc));
6c8f12af 6007 return(rc);
6008 }
6009
6010 memset(dName, '\0', sizeof(dName));
6011 container_get_dn(after[CONTAINER_NAME], dName);
6012 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
df2a74ce 6013
6c8f12af 6014 return(rc);
6015}
6016
6017int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6018{
6019 char distinguishedName[256];
6020 int rc;
6021
6022 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 6023
6024 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6025 distinguishedName, count, av))
6c8f12af 6026 return(rc);
df2a74ce 6027
6c8f12af 6028 if (strlen(distinguishedName) == 0)
6029 return(0);
df2a74ce 6030
6c8f12af 6031 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6032 {
6033 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6034 container_move_objects(ldap_handle, dn_path, distinguishedName);
6035 else
4a6e2ee4 6036 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6c8f12af 6037 av[CONTAINER_NAME], ldap_err2string(rc));
6038 }
df2a74ce 6039
6c8f12af 6040 return(rc);
6041}
bbef4f93 6042
6c8f12af 6043int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6044{
6045 char *attr_array[3];
6046 LK_ENTRY *group_base;
6047 int group_count;
6048 LDAPMod *mods[20];
6049 char *objectClass_v[] = {"top",
6050 "organizationalUnit",
6051 NULL};
6052
6053 char *ou_v[] = {NULL, NULL};
6054 char *name_v[] = {NULL, NULL};
6055 char *moiraId_v[] = {NULL, NULL};
6056 char *desc_v[] = {NULL, NULL};
6057 char *managedBy_v[] = {NULL, NULL};
6058 char dName[256];
6059 char cName[256];
6060 char managedByDN[256];
6061 char filter[256];
6062 char temp[256];
6063 int n;
6064 int i;
6065 int rc;
6066
6067 memset(filter, '\0', sizeof(filter));
6068 memset(dName, '\0', sizeof(dName));
6069 memset(cName, '\0', sizeof(cName));
6070 memset(managedByDN, '\0', sizeof(managedByDN));
6071 container_get_dn(av[CONTAINER_NAME], dName);
6072 container_get_name(av[CONTAINER_NAME], cName);
6073
6074 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6075 {
df2a74ce 6076 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6077 cName);
6c8f12af 6078 return(AD_INVALID_NAME);
6079 }
6080
bb52f279 6081 if (!check_container_name(cName))
6c8f12af 6082 {
df2a74ce 6083 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6084 cName);
6c8f12af 6085 return(AD_INVALID_NAME);
6086 }
6087
6088 n = 0;
6089 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6090 name_v[0] = cName;
6091 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6092 ou_v[0] = cName;
6093 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
df2a74ce 6094
6c8f12af 6095 if (strlen(av[CONTAINER_ROWID]) != 0)
6096 {
6097 moiraId_v[0] = av[CONTAINER_ROWID];
6098 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6099 }
df2a74ce 6100
6c8f12af 6101 if (strlen(av[CONTAINER_DESC]) != 0)
6102 {
6103 desc_v[0] = av[CONTAINER_DESC];
6104 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6105 }
df2a74ce 6106
6c8f12af 6107 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6108 {
df2a74ce 6109 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6110 {
6111 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6112 kerberos_ou))
6113 {
6114 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6115 kerberos_ou, dn_path);
6116 managedBy_v[0] = managedByDN;
6117 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6118 }
6119 }
6120 else
6121 {
6122 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6123 {
6124 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6125 "(objectClass=user)))", av[CONTAINER_ID]);
6126 }
6127
6128 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6129 {
6130 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6131 av[CONTAINER_ID]);
6132 }
6133
6134 if (strlen(filter) != 0)
6135 {
6136 attr_array[0] = "distinguishedName";
6137 attr_array[1] = NULL;
6138 group_count = 0;
6139 group_base = NULL;
6140 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6141 attr_array,
6142 &group_base, &group_count,
6143 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6144 {
6145 if (group_count == 1)
6146 {
6147 strcpy(managedByDN, group_base->value);
6148 managedBy_v[0] = managedByDN;
6149 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6150 }
6151 linklist_free(group_base);
6152 group_base = NULL;
6153 group_count = 0;
6154 }
6155 }
6156 }
6c8f12af 6157 }
df2a74ce 6158
6c8f12af 6159 mods[n] = NULL;
6160
6161 sprintf(temp, "%s,%s", dName, dn_path);
6162 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
df2a74ce 6163
6c8f12af 6164 for (i = 0; i < n; i++)
6165 free(mods[i]);
df2a74ce 6166
6c8f12af 6167 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6168 {
4a6e2ee4 6169 com_err(whoami, 0, "Unable to create container %s : %s",
6c8f12af 6170 cName, ldap_err2string(rc));
6171 return(rc);
6172 }
df2a74ce 6173
6c8f12af 6174 if (rc == LDAP_ALREADY_EXISTS)
6175 {
6176 if (strlen(av[CONTAINER_ROWID]) != 0)
6177 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6178 }
df2a74ce 6179
6c8f12af 6180 return(rc);
6181}
6182
df2a74ce 6183int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6184 char **before, int afterc, char **after)
6c8f12af 6185{
6186 char distinguishedName[256];
6187 int rc;
6188
6189 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 6190
6191 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6192 distinguishedName, afterc, after))
6c8f12af 6193 return(rc);
df2a74ce 6194
6c8f12af 6195 if (strlen(distinguishedName) == 0)
6196 {
6197 rc = container_create(ldap_handle, dn_path, afterc, after);
6198 return(rc);
6199 }
df2a74ce 6200
6c8f12af 6201 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
df2a74ce 6202 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6203 after);
6c8f12af 6204
6205 return(rc);
6206}
6207
df2a74ce 6208int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6209 char *distinguishedName, int count,
6210 char **av)
6c8f12af 6211{
6212 char *attr_array[3];
6213 LK_ENTRY *group_base;
6214 int group_count;
6215 char dName[256];
6216 char cName[256];
6217 char filter[512];
6218 int rc;
6219
6220 memset(filter, '\0', sizeof(filter));
6221 memset(dName, '\0', sizeof(dName));
6222 memset(cName, '\0', sizeof(cName));
6223 container_get_dn(av[CONTAINER_NAME], dName);
6224 container_get_name(av[CONTAINER_NAME], cName);
6225
6226 if (strlen(dName) == 0)
6227 {
df2a74ce 6228 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6229 av[CONTAINER_NAME]);
6c8f12af 6230 return(AD_INVALID_NAME);
6231 }
6232
bb52f279 6233 if (!check_container_name(cName))
6c8f12af 6234 {
df2a74ce 6235 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6236 cName);
6c8f12af 6237 return(AD_INVALID_NAME);
6238 }
df2a74ce 6239
6240 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6241 av[CONTAINER_ROWID]);
6c8f12af 6242 attr_array[0] = "distinguishedName";
6243 attr_array[1] = NULL;
6244 group_count = 0;
6245 group_base = NULL;
df2a74ce 6246
6c8f12af 6247 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6248 &group_base, &group_count,
6249 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6c8f12af 6250 {
6251 if (group_count == 1)
6252 {
6253 strcpy(distinguishedName, group_base->value);
6254 }
df2a74ce 6255
6c8f12af 6256 linklist_free(group_base);
6257 group_base = NULL;
6258 group_count = 0;
6259 }
df2a74ce 6260
6c8f12af 6261 if (strlen(distinguishedName) == 0)
6262 {
df2a74ce 6263 sprintf(filter, "(&(objectClass=organizationalUnit)"
6264 "(distinguishedName=%s,%s))", dName, dn_path);
6c8f12af 6265 attr_array[0] = "distinguishedName";
6266 attr_array[1] = NULL;
6267 group_count = 0;
6268 group_base = NULL;
df2a74ce 6269
6c8f12af 6270 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6271 &group_base, &group_count,
6272 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6c8f12af 6273 {
6274 if (group_count == 1)
6275 {
6276 strcpy(distinguishedName, group_base->value);
6277 }
df2a74ce 6278
6c8f12af 6279 linklist_free(group_base);
6280 group_base = NULL;
6281 group_count = 0;
6282 }
6283 }
df2a74ce 6284
6c8f12af 6285 return(0);
6286}
6287
6288int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6289 char *distinguishedName, int count, char **av)
6290{
6291 char *attr_array[5];
6292 LK_ENTRY *group_base;
6293 LK_ENTRY *pPtr;
6294 LDAPMod *mods[20];
6295 int group_count;
6296 char filter[512];
6c8f12af 6297 char *moiraId_v[] = {NULL, NULL};
6298 char *desc_v[] = {NULL, NULL};
6299 char *managedBy_v[] = {NULL, NULL};
6300 char managedByDN[256];
6301 char moiraId[64];
6302 char desc[256];
4a6e2ee4 6303 char ad_path[512];
6c8f12af 6304 int rc;
6305 int i;
6306 int n;
6307
6308
4a6e2ee4 6309 strcpy(ad_path, distinguishedName);
df2a74ce 6310
6c8f12af 6311 if (strlen(dName) != 0)
4a6e2ee4 6312 sprintf(ad_path, "%s,%s", dName, dn_path);
6c8f12af 6313
df2a74ce 6314 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6315 ad_path);
6316
6c8f12af 6317 if (strlen(av[CONTAINER_ID]) != 0)
df2a74ce 6318 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6319 av[CONTAINER_ROWID]);
6320
6c8f12af 6321 attr_array[0] = "mitMoiraId";
6322 attr_array[1] = "description";
6323 attr_array[2] = "managedBy";
6324 attr_array[3] = NULL;
6325 group_count = 0;
6326 group_base = NULL;
df2a74ce 6327
6c8f12af 6328 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6329 &group_base, &group_count,
6330 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6c8f12af 6331 {
4a6e2ee4 6332 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6c8f12af 6333 av[CONTAINER_NAME], ldap_err2string(rc));
6334 return(rc);
6335 }
df2a74ce 6336
6c8f12af 6337 memset(managedByDN, '\0', sizeof(managedByDN));
6338 memset(moiraId, '\0', sizeof(moiraId));
6339 memset(desc, '\0', sizeof(desc));
6340 pPtr = group_base;
df2a74ce 6341
6c8f12af 6342 while (pPtr)
6343 {
6344 if (!strcasecmp(pPtr->attribute, "description"))
6345 strcpy(desc, pPtr->value);
9cfe334f 6346 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6c8f12af 6347 strcpy(managedByDN, pPtr->value);
9cfe334f 6348 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6c8f12af 6349 strcpy(moiraId, pPtr->value);
6350 pPtr = pPtr->next;
6351 }
df2a74ce 6352
6c8f12af 6353 linklist_free(group_base);
6354 group_base = NULL;
6355 group_count = 0;
6356
6357 n = 0;
6358 if (strlen(av[CONTAINER_ROWID]) != 0)
6359 {
6360 moiraId_v[0] = av[CONTAINER_ROWID];
6361 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6362 }
df2a74ce 6363
6c8f12af 6364 if (strlen(av[CONTAINER_DESC]) != 0)
6365 {
df2a74ce 6366 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6367 dName);
6c8f12af 6368 }
6369 else
6370 {
6371 if (strlen(desc) != 0)
6372 {
4a6e2ee4 6373 attribute_update(ldap_handle, ad_path, "", "description", dName);
6c8f12af 6374 }
6375 }
df2a74ce 6376
6c8f12af 6377 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6378 {
df2a74ce 6379 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6380 {
6381 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6382 kerberos_ou))
6383 {
6384 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6385 kerberos_ou, dn_path);
6386 managedBy_v[0] = managedByDN;
6387 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6388 }
6389 else
6390 {
6391 if (strlen(managedByDN) != 0)
6392 {
6393 attribute_update(ldap_handle, ad_path, "", "managedBy",
6394 dName);
6395 }
6396 }
6397 }
6398 else
6399 {
6400 memset(filter, '\0', sizeof(filter));
6401
6402 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6403 {
6404 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6405 "(objectClass=user)))", av[CONTAINER_ID]);
6406 }
6407
6408 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6409 {
6410 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6411 av[CONTAINER_ID]);
6412 }
6413
6414 if (strlen(filter) != 0)
6415 {
6416 attr_array[0] = "distinguishedName";
6417 attr_array[1] = NULL;
6418 group_count = 0;
6419 group_base = NULL;
6420 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6421 attr_array, &group_base, &group_count,
6422 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6423 {
6424 if (group_count == 1)
6425 {
6426 strcpy(managedByDN, group_base->value);
6427 managedBy_v[0] = managedByDN;
6428 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6429 }
0eae7c9b 6430 else
df2a74ce 6431 {
6432 if (strlen(managedByDN) != 0)
0eae7c9b 6433 {
df2a74ce 6434 attribute_update(ldap_handle, ad_path, "",
6435 "managedBy", dName);
0eae7c9b 6436 }
df2a74ce 6437 }
6438
6439 linklist_free(group_base);
6440 group_base = NULL;
6441 group_count = 0;
6442 }
6443 }
0eae7c9b 6444 else
df2a74ce 6445 {
6446 if (strlen(managedByDN) != 0)
6447 {
6448 attribute_update(ldap_handle, ad_path, "", "managedBy",
6449 dName);
6450 }
6451 }
6452 }
6c8f12af 6453 }
df2a74ce 6454
6c8f12af 6455 mods[n] = NULL;
df2a74ce 6456
6c8f12af 6457 if (n == 0)
6458 return(LDAP_SUCCESS);
6459
4a6e2ee4 6460 rc = ldap_modify_s(ldap_handle, ad_path, mods);
df2a74ce 6461
6c8f12af 6462 for (i = 0; i < n; i++)
6463 free(mods[i]);
df2a74ce 6464
6c8f12af 6465 if (rc != LDAP_SUCCESS)
6466 {
df2a74ce 6467 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6468 av[CONTAINER_NAME], ldap_err2string(rc));
6469 return(rc);
6c8f12af 6470 }
df2a74ce 6471
6c8f12af 6472 return(rc);
6473}
6474
6475int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6476{
6477 char *attr_array[3];
6478 LK_ENTRY *group_base;
6479 LK_ENTRY *pPtr;
6480 int group_count;
6481 char filter[512];
6482 char new_cn[128];
6483 char temp[256];
6484 int rc;
6485 int NumberOfEntries = 10;
6486 int i;
6487 int count;
6488
6489 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6490
6491 for (i = 0; i < 3; i++)
6492 {
6493 memset(filter, '\0', sizeof(filter));
df2a74ce 6494
6c8f12af 6495 if (i == 0)
6496 {
df2a74ce 6497 strcpy(filter, "(!(|(objectClass=computer)"
6498 "(objectClass=organizationalUnit)))");
6c8f12af 6499 attr_array[0] = "cn";
6500 attr_array[1] = NULL;
6501 }
6502 else if (i == 1)
6503 {
6504 strcpy(filter, "(objectClass=computer)");
6505 attr_array[0] = "cn";
6506 attr_array[1] = NULL;
6507 }
6508 else
6509 {
6510 strcpy(filter, "(objectClass=organizationalUnit)");
6511 attr_array[0] = "ou";
6512 attr_array[1] = NULL;
6513 }
6514
6515 while (1)
6516 {
6517 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
df2a74ce 6518 &group_base, &group_count,
6519 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6c8f12af 6520 {
6521 break;
6522 }
df2a74ce 6523
6c8f12af 6524 if (group_count == 0)
6525 break;
df2a74ce 6526
6c8f12af 6527 pPtr = group_base;
df2a74ce 6528
6c8f12af 6529 while(pPtr)
6530 {
6531 if (!strcasecmp(pPtr->attribute, "cn"))
6532 {
6533 sprintf(new_cn, "cn=%s", pPtr->value);
6534 if (i == 0)
6535 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6536 if (i == 1)
6537 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6538 count = 1;
df2a74ce 6539
6c8f12af 6540 while (1)
6541 {
6542 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6543 TRUE, NULL, NULL);
6544 if (rc == LDAP_ALREADY_EXISTS)
6545 {
6546 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6547 ++count;
6548 }
6549 else
6550 break;
6551 }
6552 }
6553 else if (!strcasecmp(pPtr->attribute, "ou"))
6554 {
6555 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6556 }
df2a74ce 6557
6c8f12af 6558 pPtr = pPtr->next;
6559 }
df2a74ce 6560
6c8f12af 6561 linklist_free(group_base);
6562 group_base = NULL;
6563 group_count = 0;
6564 }
6565 }
df2a74ce 6566
6c8f12af 6567 return(0);
6568}
5f7b0741 6569
df2a74ce 6570int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6571 char *machine_ou, char *NewMachineName)
5f7b0741 6572{
6573 LK_ENTRY *group_base;
6574 int group_count;
6575 int i;
6576 char filter[128];
6577 char *attr_array[3];
6578 char cn[256];
6579 char dn[256];
6580 char temp[256];
6581 char *pPtr;
6582 int rc;
6583
3abb4456 6584 strcpy(NewMachineName, member);
cc1e4a1d 6585 rc = moira_connect();
3abb4456 6586 rc = GetMachineName(NewMachineName);
cc1e4a1d 6587 moira_disconnect();
df2a74ce 6588
3abb4456 6589 if (strlen(NewMachineName) == 0)
6590 {
df2a74ce 6591 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6592 member);
3abb4456 6593 return(1);
6594 }
6595
5f7b0741 6596 pPtr = NULL;
3abb4456 6597 pPtr = strchr(NewMachineName, '.');
df2a74ce 6598
5f7b0741 6599 if (pPtr != NULL)
6600 (*pPtr) = '\0';
6601
6602 group_base = NULL;
6603 group_count = 0;
3abb4456 6604 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
5f7b0741 6605 attr_array[0] = "cn";
6606 attr_array[1] = NULL;
6607 sprintf(temp, "%s", dn_path);
df2a74ce 6608
5f7b0741 6609 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
df2a74ce 6610 &group_base, &group_count,
6611 LDAP_SCOPE_SUBTREE)) != 0)
5f7b0741 6612 {
4a6e2ee4 6613 com_err(whoami, 0, "Unable to process machine %s : %s",
5f7b0741 6614 member, ldap_err2string(rc));
6615 return(1);
6616 }
df2a74ce 6617
5f7b0741 6618 if (group_count != 1)
6619 {
df2a74ce 6620 com_err(whoami, 0,
6621 "Unable to process machine %s : machine not found in AD",
3abb4456 6622 NewMachineName);
5f7b0741 6623 return(1);
6624 }
df2a74ce 6625
5f7b0741 6626 strcpy(dn, group_base->dn);
6627 strcpy(cn, group_base->value);
df2a74ce 6628
5f7b0741 6629 for (i = 0; i < (int)strlen(dn); i++)
6630 dn[i] = tolower(dn[i]);
df2a74ce 6631
5f7b0741 6632 for (i = 0; i < (int)strlen(cn); i++)
6633 cn[i] = tolower(cn[i]);
df2a74ce 6634
5f7b0741 6635 linklist_free(group_base);
6636 pPtr = NULL;
6637 pPtr = strstr(dn, cn);
df2a74ce 6638
5f7b0741 6639 if (pPtr == NULL)
6640 {
4a6e2ee4 6641 com_err(whoami, 0, "Unable to process machine %s",
5f7b0741 6642 member);
6643 return(1);
6644 }
df2a74ce 6645
5f7b0741 6646 pPtr += strlen(cn) + 1;
6647 strcpy(machine_ou, pPtr);
6648 pPtr = NULL;
6649 pPtr = strstr(machine_ou, "dc=");
df2a74ce 6650
5f7b0741 6651 if (pPtr == NULL)
6652 {
4a6e2ee4 6653 com_err(whoami, 0, "Unable to process machine %s",
5f7b0741 6654 member);
6655 return(1);
6656 }
df2a74ce 6657
5f7b0741 6658 --pPtr;
6659 (*pPtr) = '\0';
df2a74ce 6660
5f7b0741 6661 return(0);
6662}
bbef4f93 6663
df2a74ce 6664int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6665 char *MoiraMachineName, char *DestinationOu)
bbef4f93 6666{
df2a74ce 6667 char NewCn[128];
6668 char OldDn[512];
6669 char MachineName[128];
6670 char filter[128];
6671 char *attr_array[3];
6672 char NewOu[256];
6673 char *cPtr = NULL;
6674 int group_count;
6675 long rc;
6676 LK_ENTRY *group_base;
bbef4f93 6677
df2a74ce 6678 group_count = 0;
6679 group_base = NULL;
6680
6681 strcpy(MachineName, MoiraMachineName);
6682 rc = GetMachineName(MachineName);
6683
6684 if (strlen(MachineName) == 0)
6685 {
6686 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6687 MoiraMachineName);
6688 return(1);
3abb4456 6689 }
df2a74ce 6690
6691 cPtr = strchr(MachineName, '.');
6692
6693 if (cPtr != NULL)
6694 (*cPtr) = '\0';
3abb4456 6695
df2a74ce 6696 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6697 attr_array[0] = "sAMAccountName";
6698 attr_array[1] = NULL;
6699
6700 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6701 &group_base,
6702 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
bbef4f93 6703 {
df2a74ce 6704 com_err(whoami, 0, "Unable to process machine %s : %s",
6705 MoiraMachineName, ldap_err2string(rc));
6706 return(1);
bbef4f93 6707 }
df2a74ce 6708
6709 if (group_count == 1)
6710 strcpy(OldDn, group_base->dn);
6711
6712 linklist_free(group_base);
6713 group_base = NULL;
bbef4f93 6714
df2a74ce 6715 if (group_count != 1)
bbef4f93 6716 {
df2a74ce 6717 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6718 MoiraMachineName);
6719 return(1);
bbef4f93 6720 }
df2a74ce 6721
6722 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6723 cPtr = strchr(OldDn, ',');
6724
6725 if (cPtr != NULL)
bbef4f93 6726 {
df2a74ce 6727 ++cPtr;
6728 if (!strcasecmp(cPtr, NewOu))
6729 return(0);
bbef4f93 6730 }
df2a74ce 6731
6732 sprintf(NewCn, "CN=%s", MachineName);
6733 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6734
6735 return(rc);
bbef4f93 6736}
6737
6738int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6739{
df2a74ce 6740 char Name[128];
6741 char *pPtr;
6742 int rc;
6743
6744 memset(Name, '\0', sizeof(Name));
6745 strcpy(Name, machine_name);
6746 pPtr = NULL;
6747 pPtr = strchr(Name, '.');
6748
6749 if (pPtr != NULL)
6750 (*pPtr) = '\0';
6751
6752 strcat(Name, "$");
6753 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
bbef4f93 6754}
6755
df2a74ce 6756int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6757 char *machine_name, char *container_name)
bbef4f93 6758{
df2a74ce 6759 int rc;
6760 char *av[2];
6761 char *call_args[2];
6762
6763 av[0] = machine_name;
6764 call_args[0] = (char *)container_name;
6765 rc = mr_query("get_machine_to_container_map", 1, av,
6766 machine_GetMoiraContainer, call_args);
6767 return(rc);
bbef4f93 6768}
6769
6770int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6771{
df2a74ce 6772 char **call_args;
6773
6774 call_args = ptr;
6775 strcpy(call_args[0], av[1]);
6776 return(0);
bbef4f93 6777}
6778
209367bd 6779int Moira_container_group_create(char **after)
6780{
6781 long rc;
6782 char GroupName[64];
c7fec834 6783 char *argv[20];
209367bd 6784
6785 memset(GroupName, '\0', sizeof(GroupName));
6786 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6787 after[CONTAINER_ROWID]);
6788 if (rc)
6789 return rc;
6790
6791 argv[L_NAME] = GroupName;
6792 argv[L_ACTIVE] = "1";
6793 argv[L_PUBLIC] = "0";
6794 argv[L_HIDDEN] = "0";
6795 argv[L_MAILLIST] = "0";
6796 argv[L_GROUP] = "1";
6797 argv[L_GID] = UNIQUE_GID;
6798 argv[L_NFSGROUP] = "0";
3fe96507 6799 argv[L_MAILMAN] = "0";
6800 argv[L_MAILMAN_SERVER] = "[NONE]";
209367bd 6801 argv[L_DESC] = "auto created container group";
6802 argv[L_ACE_TYPE] = "USER";
6803 argv[L_MEMACE_TYPE] = "USER";
6804 argv[L_ACE_NAME] = "sms";
6805 argv[L_MEMACE_NAME] = "sms";
6806
3fe96507 6807 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
209367bd 6808 {
df2a74ce 6809 com_err(whoami, 0,
6810 "Unable to create container group %s for container %s: %s",
209367bd 6811 GroupName, after[CONTAINER_NAME], error_message(rc));
6812 }
6813
6814 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6815 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6816
6817 return(rc);
6818}
6819
6820int Moira_container_group_update(char **before, char **after)
6821{
6822 long rc;
6823 char BeforeGroupName[64];
6824 char AfterGroupName[64];
c7fec834 6825 char *argv[20];
209367bd 6826
6827 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6828 return(0);
6829
6830 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6831 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6832 if (strlen(BeforeGroupName) == 0)
6833 return(0);
6834
6835 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6836 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6837 after[CONTAINER_ROWID]);
6838 if (rc)
6839 return rc;
6840
6841 if (strcasecmp(BeforeGroupName, AfterGroupName))
6842 {
6843 argv[L_NAME] = BeforeGroupName;
6844 argv[L_NAME + 1] = AfterGroupName;
6845 argv[L_ACTIVE + 1] = "1";
6846 argv[L_PUBLIC + 1] = "0";
50b4a32b 6847 argv[L_HIDDEN + 1] = "0";
209367bd 6848 argv[L_MAILLIST + 1] = "0";
6849 argv[L_GROUP + 1] = "1";
6850 argv[L_GID + 1] = UNIQUE_GID;
6851 argv[L_NFSGROUP + 1] = "0";
3fe96507 6852 argv[L_MAILMAN + 1] = "0";
6853 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
209367bd 6854 argv[L_DESC + 1] = "auto created container group";
6855 argv[L_ACE_TYPE + 1] = "USER";
6856 argv[L_MEMACE_TYPE + 1] = "USER";
6857 argv[L_ACE_NAME + 1] = "sms";
6858 argv[L_MEMACE_NAME + 1] = "sms";
6859
3fe96507 6860 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
209367bd 6861 {
df2a74ce 6862 com_err(whoami, 0,
6863 "Unable to rename container group from %s to %s: %s",
209367bd 6864 BeforeGroupName, AfterGroupName, error_message(rc));
6865 }
6866 }
6867
6868 return(rc);
6869}
6870
6871int Moira_container_group_delete(char **before)
6872{
6873 long rc = 0;
6874 char *argv[13];
6875 char GroupName[64];
6876 char ParentGroupName[64];
6877
6878 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6879 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6880
6881 memset(GroupName, '\0', sizeof(GroupName));
df2a74ce 6882
209367bd 6883 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6884 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6885
6886 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6887 {
6888 argv[0] = ParentGroupName;
6889 argv[1] = "LIST";
6890 argv[2] = GroupName;
df2a74ce 6891
209367bd 6892 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6893 {
df2a74ce 6894 com_err(whoami, 0,
6895 "Unable to delete container group %s from list: %s",
209367bd 6896 GroupName, ParentGroupName, error_message(rc));
6897 }
6898 }
6899
6900 if (strlen(GroupName) != 0)
6901 {
6902 argv[0] = GroupName;
df2a74ce 6903
209367bd 6904 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6905 {
4a6e2ee4 6906 com_err(whoami, 0, "Unable to delete container group %s : %s",
209367bd 6907 GroupName, error_message(rc));
6908 }
df2a74ce 6909 }
209367bd 6910
6911 return(rc);
6912}
6913
6914int Moira_groupname_create(char *GroupName, char *ContainerName,
6915 char *ContainerRowID)
6916{
6917 char *ptr;
6918 char *ptr1;
6919 char temp[64];
6920 char newGroupName[64];
6921 char tempGroupName[64];
e0e094af 6922 char tempgname[64];
209367bd 6923 char *argv[1];
6924 int i;
6925 long rc;
6926
6927 strcpy(temp, ContainerName);
6928
6929 ptr1 = strrchr(temp, '/');
df2a74ce 6930
209367bd 6931 if (ptr1 != NULL)
e0e094af 6932 {
6933 *ptr1 = '\0';
209367bd 6934 ptr = ++ptr1;
e0e094af 6935 ptr1 = strrchr(temp, '/');
df2a74ce 6936
e0e094af 6937 if (ptr1 != NULL)
6938 {
6939 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6940 }
6941 else
6942 strcpy(tempgname, ptr);
6943 }
209367bd 6944 else
e0e094af 6945 strcpy(tempgname, temp);
209367bd 6946
e0e094af 6947 if (strlen(tempgname) > 25)
6948 tempgname[25] ='\0';
209367bd 6949
e0e094af 6950 sprintf(newGroupName, "cnt-%s", tempgname);
209367bd 6951
6952 /* change everything to lower case */
6953 ptr = newGroupName;
df2a74ce 6954
209367bd 6955 while (*ptr)
6956 {
6957 if (isupper(*ptr))
6958 *ptr = tolower(*ptr);
df2a74ce 6959
209367bd 6960 if (*ptr == ' ')
6961 *ptr = '-';
df2a74ce 6962
209367bd 6963 ptr++;
6964 }
6965
6966 strcpy(tempGroupName, newGroupName);
6967 i = (int)'0';
df2a74ce 6968
209367bd 6969 /* append 0-9 then a-z if a duplicate is found */
6970 while(1)
6971 {
6972 argv[0] = newGroupName;
df2a74ce 6973
209367bd 6974 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6975 {
6976 if (rc == MR_NO_MATCH)
6977 break;
df2a74ce 6978 com_err(whoami, 0, "Moira error while creating group name for "
6979 "container %s : %s", ContainerName, error_message(rc));
209367bd 6980 return rc;
6981 }
df2a74ce 6982
209367bd 6983 sprintf(newGroupName, "%s-%c", tempGroupName, i);
df2a74ce 6984
209367bd 6985 if (i == (int)'z')
6986 {
df2a74ce 6987 com_err(whoami, 0, "Unable to find a unique group name for "
6988 "container %s: too many duplicate container names",
209367bd 6989 ContainerName);
6990 return 1;
6991 }
df2a74ce 6992
209367bd 6993 if (i == '9')
6994 i = 'a';
6995 else
6996 i++;
6997 }
6998
6999 strcpy(GroupName, newGroupName);
7000 return(0);
7001}
7002
7003int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7004{
7005 long rc;
7006 char *argv[3];
7007
7008 argv[0] = origContainerName;
7009 argv[1] = GroupName;
df2a74ce 7010
209367bd 7011 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7012 {
df2a74ce 7013 com_err(whoami, 0,
7014 "Unable to set container group %s in container %s: %s",
7015 GroupName, origContainerName, error_message(rc));
209367bd 7016 }
df2a74ce 7017
209367bd 7018 return(0);
7019}
7020
df2a74ce 7021int Moira_addGroupToParent(char *origContainerName, char *GroupName)
209367bd 7022 {
7023 char ContainerName[64];
7024 char ParentGroupName[64];
7025 char *argv[3];
7026 long rc;
7027
7028 strcpy(ContainerName, origContainerName);
df2a74ce 7029
209367bd 7030 Moira_getGroupName(ContainerName, ParentGroupName, 1);
df2a74ce 7031
209367bd 7032 /* top-level container */
7033 if (strlen(ParentGroupName) == 0)
7034 return(0);
7035
7036 argv[0] = ParentGroupName;
7037 argv[1] = "LIST";
7038 argv[2] = GroupName;
df2a74ce 7039
209367bd 7040 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7041 {
df2a74ce 7042 com_err(whoami, 0,
7043 "Unable to add container group %s to parent group %s: %s",
209367bd 7044 GroupName, ParentGroupName, error_message(rc));
7045 }
df2a74ce 7046
209367bd 7047 return(0);
7048 }
7049
7050int Moira_getContainerGroup(int ac, char **av, void *ptr)
7051{
7052 char **call_args;
7053
7054 call_args = ptr;
7055 strcpy(call_args[0], av[1]);
df2a74ce 7056
209367bd 7057 return(0);
7058}
7059
7060int Moira_getGroupName(char *origContainerName, char *GroupName,
7061 int ParentFlag)
7062{
209367bd 7063 char ContainerName[64];
7064 char *argv[3];
7065 char *call_args[3];
7066 char *ptr;
7067 long rc;
7068
7069 strcpy(ContainerName, origContainerName);
7070
7071 if (ParentFlag)
7072 {
7073 ptr = strrchr(ContainerName, '/');
df2a74ce 7074
209367bd 7075 if (ptr != NULL)
7076 (*ptr) = '\0';
7077 else
7078 return(0);
7079 }
7080
7081 argv[0] = ContainerName;
7082 argv[1] = NULL;
7083 call_args[0] = GroupName;
7084 call_args[1] = NULL;
7085
7086 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7087 call_args)))
7088 {
7089 if (strlen(GroupName) != 0)
7090 return(0);
7091 }
7092
7093 if (rc)
4a6e2ee4 7094 com_err(whoami, 0, "Unable to get container group from container %s: %s",
209367bd 7095 ContainerName, error_message(rc));
7096 else
4a6e2ee4 7097 com_err(whoami, 0, "Unable to get container group from container %s",
209367bd 7098 ContainerName);
df2a74ce 7099
7100 return(0);
209367bd 7101}
7102
7103int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7104 int DeleteMachine)
7105{
7106 char *argv[3];
7107 long rc;
df2a74ce 7108
209367bd 7109 if (strcmp(GroupName, "[none]") == 0)
7110 return 0;
7111
7112 argv[0] = GroupName;
7113 argv[1] = "MACHINE";
7114 argv[2] = MachineName;
df2a74ce 7115
209367bd 7116 if (!DeleteMachine)
7117 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7118 else
7119 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
df2a74ce 7120
209367bd 7121 if (rc)
7122 {
4a6e2ee4 7123 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
209367bd 7124 MachineName, GroupName, error_message(rc));
7125 }
df2a74ce 7126
209367bd 7127 return(0);
7128}
3abb4456 7129
7130int GetMachineName(char *MachineName)
7131{
df2a74ce 7132 char *args[2];
7133 char NewMachineName[1024];
7134 char *szDot;
7135 int rc = 0;
7136 int i;
7137 DWORD dwLen = 0;
7138 char *call_args[2];
7139
7140 // If the address happens to be in the top-level MIT domain, great!
7141 strcpy(NewMachineName, MachineName);
3abb4456 7142
df2a74ce 7143 for (i = 0; i < (int)strlen(NewMachineName); i++)
7144 NewMachineName[i] = toupper(NewMachineName[i]);
7145
7146 szDot = strchr(NewMachineName,'.');
7147
7148 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
3abb4456 7149 {
df2a74ce 7150 return(0);
3abb4456 7151 }
df2a74ce 7152
7153 // If not, see if it has a Moira alias in the top-level MIT domain.
7154 memset(NewMachineName, '\0', sizeof(NewMachineName));
7155 args[0] = "*";
7156 args[1] = MachineName;
7157 call_args[0] = NewMachineName;
7158 call_args[1] = NULL;
3abb4456 7159
df2a74ce 7160 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7161 {
7162 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7163 MachineName, error_message(rc));
7164 strcpy(MachineName, "");
7165 return(0);
7166 }
7167
7168 if (strlen(NewMachineName) != 0)
7169 strcpy(MachineName, NewMachineName);
7170 else
7171 strcpy(MachineName, "");
3abb4456 7172
df2a74ce 7173 return(0);
3abb4456 7174}
7175
7176int ProcessMachineName(int ac, char **av, void *ptr)
7177{
df2a74ce 7178 char **call_args;
7179 char MachineName[1024];
7180 char *szDot;
7181 int i;
7182
7183 call_args = ptr;
3abb4456 7184
df2a74ce 7185 if (strlen(call_args[0]) == 0)
3abb4456 7186 {
df2a74ce 7187 strcpy(MachineName, av[0]);
7188
7189 for (i = 0; i < (int)strlen(MachineName); i++)
7190 MachineName[i] = toupper(MachineName[i]);
7191
7192 szDot = strchr(MachineName,'.');
7193
3abb4456 7194 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
df2a74ce 7195 {
3abb4456 7196 strcpy(call_args[0], MachineName);
df2a74ce 7197 }
3abb4456 7198 }
df2a74ce 7199
7200 return(0);
3abb4456 7201}
7202
7203void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7204{
df2a74ce 7205 int i;
7206
7207 if (*UseSFU30)
3abb4456 7208 {
df2a74ce 7209 for (i = 0; i < n; i++)
3abb4456 7210 {
df2a74ce 7211 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7212 mods[i]->mod_type = "uidNumber";
3abb4456 7213 }
df2a74ce 7214
7215 (*UseSFU30) = 0;
3abb4456 7216 }
df2a74ce 7217 else
3abb4456 7218 {
df2a74ce 7219 for (i = 0; i < n; i++)
3abb4456 7220 {
df2a74ce 7221 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7222 mods[i]->mod_type = "msSFU30UidNumber";
3abb4456 7223 }
df2a74ce 7224
7225 (*UseSFU30) = 1;
3abb4456 7226 }
7227}
7228
df2a74ce 7229int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7230 char *DistinguishedName,
3abb4456 7231 char *WinHomeDir, char *WinProfileDir,
7232 char **homedir_v, char **winProfile_v,
7233 char **drives_v, LDAPMod **mods,
7234 int OpType, int n)
7235{
df2a74ce 7236 char **hp;
7237 char cWeight[3];
7238 char cPath[1024];
7239 char path[1024];
7240 char winPath[1024];
7241 char winProfile[1024];
7242 char homeDrive[8];
7243 int last_weight;
7244 int i;
7245 int rc;
7246 LDAPMod *DelMods[20];
7247
7248 memset(homeDrive, '\0', sizeof(homeDrive));
7249 memset(path, '\0', sizeof(path));
7250 memset(winPath, '\0', sizeof(winPath));
7251 memset(winProfile, '\0', sizeof(winProfile));
7252 hp = NULL;
7253
7254 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7255 (!strcasecmp(WinProfileDir, "[afs]")))
7256 {
7257 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
3abb4456 7258 {
df2a74ce 7259 memset(cWeight, 0, sizeof(cWeight));
7260 memset(cPath, 0, sizeof(cPath));
7261 last_weight = 1000;
7262 i = 0;
7263
7264 while (hp[i] != NULL)
3abb4456 7265 {
df2a74ce 7266 if (sscanf(hp[i], "%*s %s", cPath))
3abb4456 7267 {
df2a74ce 7268 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
3abb4456 7269 {
df2a74ce 7270 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
3abb4456 7271 {
df2a74ce 7272 if (atoi(cWeight) < last_weight)
3abb4456 7273 {
df2a74ce 7274 strcpy(path, cPath);
7275 last_weight = (int)atoi(cWeight);
3abb4456 7276 }
7277 }
df2a74ce 7278 else
7279 strcpy(path, cPath);
3abb4456 7280 }
7281 }
7282 ++i;
7283 }
df2a74ce 7284
7285 if (strlen(path))
3abb4456 7286 {
df2a74ce 7287 if (!strnicmp(path, AFS, strlen(AFS)))
3abb4456 7288 {
df2a74ce 7289 AfsToWinAfs(path, winPath);
7290 strcpy(winProfile, winPath);
7291 strcat(winProfile, "\\.winprofile");
3abb4456 7292 }
7293 }
7294 }
df2a74ce 7295 else
7296 return(n);
3abb4456 7297 }
7298
df2a74ce 7299 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7300 (!strcasecmp(WinProfileDir, "[dfs]")))
e0e094af 7301 {
df2a74ce 7302 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7303 user_name[0], user_name);
e0e094af 7304
df2a74ce 7305 if (!strcasecmp(WinProfileDir, "[dfs]"))
7306 {
7307 strcpy(winProfile, path);
7308 strcat(winProfile, "\\.winprofile");
7309 }
7310
7311 if (!strcasecmp(WinHomeDir, "[dfs]"))
7312 strcpy(winPath, path);
7313 }
7314
3abb4456 7315 if (hp != NULL)
df2a74ce 7316 {
3abb4456 7317 i = 0;
7318 while (hp[i])
df2a74ce 7319 {
3abb4456 7320 free(hp[i]);
7321 i++;
df2a74ce 7322 }
7323 }
7324
3abb4456 7325 if (!strcasecmp(WinHomeDir, "[local]"))
df2a74ce 7326 memset(winPath, '\0', sizeof(winPath));
7327 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7328 !strcasecmp(WinHomeDir, "[dfs]"))
7329 {
3abb4456 7330 strcpy(homeDrive, "H:");
df2a74ce 7331 }
3abb4456 7332 else
df2a74ce 7333 {
3abb4456 7334 strcpy(winPath, WinHomeDir);
7335 if (!strncmp(WinHomeDir, "\\\\", 2))
df2a74ce 7336 {
3abb4456 7337 strcpy(homeDrive, "H:");
df2a74ce 7338 }
7339 }
7340
3abb4456 7341 // nothing needs to be done if WinProfileDir is [afs].
7342 if (!strcasecmp(WinProfileDir, "[local]"))
df2a74ce 7343 memset(winProfile, '\0', sizeof(winProfile));
7344 else if (strcasecmp(WinProfileDir, "[afs]") &&
7345 strcasecmp(WinProfileDir, "[dfs]"))
7346 {
3abb4456 7347 strcpy(winProfile, WinProfileDir);
df2a74ce 7348 }
7349
3abb4456 7350 if (strlen(winProfile) != 0)
df2a74ce 7351 {
3abb4456 7352 if (winProfile[strlen(winProfile) - 1] == '\\')
df2a74ce 7353 winProfile[strlen(winProfile) - 1] = '\0';
7354 }
7355
3abb4456 7356 if (strlen(winPath) != 0)
df2a74ce 7357 {
3abb4456 7358 if (winPath[strlen(winPath) - 1] == '\\')
df2a74ce 7359 winPath[strlen(winPath) - 1] = '\0';
7360 }
7361
3abb4456 7362 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
df2a74ce 7363 strcat(winProfile, "\\");
3abb4456 7364
df2a74ce 7365 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7366 strcat(winPath, "\\");
7367
3abb4456 7368 if (strlen(winPath) == 0)
df2a74ce 7369 {
3abb4456 7370 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7371 {
3abb4456 7372 i = 0;
7373 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7374 DelMods[i] = NULL;
7375 //unset homeDirectory attribute for user.
7376 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7377 free(DelMods[0]);
df2a74ce 7378 }
7379 }
3abb4456 7380 else
df2a74ce 7381 {
3abb4456 7382 homedir_v[0] = strdup(winPath);
7383 ADD_ATTR("homeDirectory", homedir_v, OpType);
df2a74ce 7384 }
7385
3abb4456 7386 if (strlen(winProfile) == 0)
df2a74ce 7387 {
3abb4456 7388 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7389 {
3abb4456 7390 i = 0;
7391 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7392 DelMods[i] = NULL;
7393 //unset profilePate attribute for user.
7394 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7395 free(DelMods[0]);
df2a74ce 7396 }
7397 }
3abb4456 7398 else
df2a74ce 7399 {
3abb4456 7400 winProfile_v[0] = strdup(winProfile);
7401 ADD_ATTR("profilePath", winProfile_v, OpType);
df2a74ce 7402 }
7403
3abb4456 7404 if (strlen(homeDrive) == 0)
df2a74ce 7405 {
3abb4456 7406 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7407 {
3abb4456 7408 i = 0;
7409 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7410 DelMods[i] = NULL;
7411 //unset homeDrive attribute for user
7412 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7413 free(DelMods[0]);
df2a74ce 7414 }
7415 }
3abb4456 7416 else
df2a74ce 7417 {
3abb4456 7418 drives_v[0] = strdup(homeDrive);
7419 ADD_ATTR("homeDrive", drives_v, OpType);
df2a74ce 7420 }
3abb4456 7421
7422 return(n);
7423}
d7051053 7424
4a6e2ee4 7425int attribute_update(LDAP *ldap_handle, char *distinguished_name,
df2a74ce 7426 char *attribute_value, char *attribute, char *user_name)
4a6e2ee4 7427{
7428 char *mod_v[] = {NULL, NULL};
7429 LDAPMod *DelMods[20];
7430 LDAPMod *mods[20];
7431 int n;
7432 int i;
7433 int rc;
df2a74ce 7434
4a6e2ee4 7435 if (strlen(attribute_value) == 0)
7436 {
7437 i = 0;
7438 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7439 DelMods[i] = NULL;
7440 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7441 free(DelMods[0]);
7442 }
df2a74ce 7443 else
4a6e2ee4 7444 {
7445 n = 0;
7446 mod_v[0] = attribute_value;
7447 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7448 mods[n] = NULL;
df2a74ce 7449
7450 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7451 mods)) != LDAP_SUCCESS)
4a6e2ee4 7452 {
7453 free(mods[0]);
7454 n = 0;
7455 mod_v[0] = attribute_value;
7456 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7457 mods[n] = NULL;
df2a74ce 7458
7459 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7460 mods)) != LDAP_SUCCESS)
4a6e2ee4 7461 {
df2a74ce 7462 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7463 "in the AD : %s",
4a6e2ee4 7464 attribute, user_name, ldap_err2string(rc));
7465 }
7466 }
df2a74ce 7467
4a6e2ee4 7468 free(mods[0]);
7469 }
df2a74ce 7470
4a6e2ee4 7471 return(rc);
7472}
26503e15 7473
df2a74ce 7474void StringTrim(char *StringToTrim)
26503e15 7475{
df2a74ce 7476 char *t, *s;
7477 char *save;
26503e15 7478
df2a74ce 7479 save = strdup(StringToTrim);
26503e15 7480
df2a74ce 7481 s = save;
26503e15 7482
df2a74ce 7483 while (isspace(*s))
7484 s++;
26503e15 7485
df2a74ce 7486 /* skip to end of string */
7487 if (*s == '\0')
26503e15 7488 {
df2a74ce 7489 if (*save)
7490 *save = '\0';
7491 strcpy(StringToTrim, save);
7492 return;
26503e15 7493 }
df2a74ce 7494
7495 for (t = s; *t; t++)
7496 continue;
26503e15 7497
df2a74ce 7498 while (t > s)
26503e15 7499 {
df2a74ce 7500 --t;
7501 if (!isspace(*t))
7502 {
7503 t++;
7504 break;
7505 }
26503e15 7506 }
7507
df2a74ce 7508 if (*t)
7509 *t = '\0';
7510
7511 strcpy(StringToTrim, s);
7512 return;
26503e15 7513}
7514
6a4366ac 7515int ReadConfigFile(char *DomainName)
26503e15 7516{
7517 int Count;
7518 int i;
7519 int k;
7520 char temp[256];
7521 char temp1[256];
7522 FILE *fptr;
7523
7524 Count = 0;
7525
6a4366ac 7526 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
df2a74ce 7527
6a4366ac 7528 if ((fptr = fopen(temp, "r")) != NULL)
df2a74ce 7529 {
26503e15 7530 while (fgets(temp, sizeof(temp), fptr) != 0)
df2a74ce 7531 {
26503e15 7532 for (i = 0; i < (int)strlen(temp); i++)
df2a74ce 7533 temp[i] = toupper(temp[i]);
7534
26503e15 7535 if (temp[strlen(temp) - 1] == '\n')
df2a74ce 7536 temp[strlen(temp) - 1] = '\0';
7537
26503e15 7538 StringTrim(temp);
df2a74ce 7539
26503e15 7540 if (strlen(temp) == 0)
df2a74ce 7541 continue;
7542
26503e15 7543 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
df2a74ce 7544 {
26503e15 7545 if (strlen(temp) > (strlen(DOMAIN)))
df2a74ce 7546 {
26503e15 7547 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7548 StringTrim(ldap_domain);
df2a74ce 7549 }
7550 }
26503e15 7551 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
df2a74ce 7552 {
26503e15 7553 if (strlen(temp) > (strlen(PRINCIPALNAME)))
df2a74ce 7554 {
26503e15 7555 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7556 StringTrim(PrincipalName);
df2a74ce 7557 }
7558 }
26503e15 7559 else if (!strncmp(temp, SERVER, strlen(SERVER)))
df2a74ce 7560 {
26503e15 7561 if (strlen(temp) > (strlen(SERVER)))
df2a74ce 7562 {
26503e15 7563 ServerList[Count] = calloc(1, 256);
7564 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7565 StringTrim(ServerList[Count]);
7566 ++Count;
df2a74ce 7567 }
7568 }
26503e15 7569 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
df2a74ce 7570 {
26503e15 7571 if (strlen(temp) > (strlen(MSSFU)))
df2a74ce 7572 {
26503e15 7573 strcpy(temp1, &temp[strlen(MSSFU)]);
7574 StringTrim(temp1);
7575 if (!strcmp(temp1, SFUTYPE))
df2a74ce 7576 UseSFU30 = 1;
7577 }
7578 }
7579 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7580 {
7581 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7582 {
7583 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7584 StringTrim(temp1);
7585 if (!strcasecmp(temp1, "NO"))
7586 {
7587 UseGroupSuffix = 0;
7588 memset(group_suffix, '\0', sizeof(group_suffix));
7589 }
7590 }
7591 }
7592 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7593 {
7594 if (strlen(temp) > (strlen(GROUP_TYPE)))
7595 {
7596 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7597 StringTrim(temp1);
7598 if (!strcasecmp(temp1, "UNIVERSAL"))
7599 UseGroupUniversal = 1;
7600 }
7601 }
7602 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7603 {
7604 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7605 {
7606 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7607 StringTrim(temp1);
7608 if (!strcasecmp(temp1, "NO"))
7609 SetGroupAce = 0;
7610 }
7611 }
7612 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7613 {
7614 if (strlen(temp) > (strlen(SET_PASSWORD)))
7615 {
7616 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7617 StringTrim(temp1);
7618 if (!strcasecmp(temp1, "NO"))
7619 SetPassword = 0;
7620 }
7621 }
7622 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7623 {
7624 if (strlen(temp) > (strlen(EXCHANGE)))
7625 {
7626 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7627 StringTrim(temp1);
7628 if (!strcasecmp(temp1, "YES"))
7629 Exchange = 1;
7630 }
7631 }
7632 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7633 strlen(PROCESS_MACHINE_CONTAINER)))
7634 {
7635 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7636 {
7637 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7638 StringTrim(temp1);
7639 if (!strcasecmp(temp1, "NO"))
7640 ProcessMachineContainer = 0;
7641 }
7642 }
26503e15 7643 else
df2a74ce 7644 {
26503e15 7645 if (strlen(ldap_domain) != 0)
df2a74ce 7646 {
26503e15 7647 memset(ldap_domain, '\0', sizeof(ldap_domain));
7648 break;
df2a74ce 7649 }
7650
26503e15 7651 if (strlen(temp) != 0)
df2a74ce 7652 strcpy(ldap_domain, temp);
7653 }
7654 }
26503e15 7655 fclose(fptr);
df2a74ce 7656 }
7657
26503e15 7658 if (strlen(ldap_domain) == 0)
df2a74ce 7659 {
6a4366ac 7660 strcpy(ldap_domain, DomainName);
df2a74ce 7661 }
7662
26503e15 7663 if (Count == 0)
6a4366ac 7664 return(0);
df2a74ce 7665
26503e15 7666 for (i = 0; i < Count; i++)
df2a74ce 7667 {
26503e15 7668 if (ServerList[i] != 0)
df2a74ce 7669 {
26503e15 7670 strcat(ServerList[i], ".");
7671 strcat(ServerList[i], ldap_domain);
7672 for (k = 0; k < (int)strlen(ServerList[i]); k++)
df2a74ce 7673 ServerList[i][k] = toupper(ServerList[i][k]);
7674 }
7675 }
7676
6a4366ac 7677 return(0);
7678}
7679
7680int ReadDomainList()
7681{
7682 int Count;
7683 int i;
7684 char temp[128];
7685 char temp1[128];
7686 FILE *fptr;
7687 unsigned char c[11];
7688 unsigned char stuff[256];
7689 int rc;
7690 int ok;
7691
7692 Count = 0;
7693 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
df2a74ce 7694
6a4366ac 7695 if ((fptr = fopen(temp, "r")) != NULL)
7696 {
7697 while (fgets(temp, sizeof(temp), fptr) != 0)
7698 {
7699 for (i = 0; i < (int)strlen(temp); i++)
7700 temp[i] = toupper(temp[i]);
df2a74ce 7701
6a4366ac 7702 if (temp[strlen(temp) - 1] == '\n')
7703 temp[strlen(temp) - 1] = '\0';
df2a74ce 7704
6a4366ac 7705 StringTrim(temp);
df2a74ce 7706
6a4366ac 7707 if (strlen(temp) == 0)
7708 continue;
df2a74ce 7709
6a4366ac 7710 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7711 {
7712 if (strlen(temp) > (strlen(DOMAIN)))
7713 {
7714 strcpy(temp1, &temp[strlen(DOMAIN)]);
7715 StringTrim(temp1);
7716 strcpy(temp, temp1);
7717 }
7718 }
df2a74ce 7719
7720 strcpy(DomainNames[Count], temp);
7721 StringTrim(DomainNames[Count]);
7722 ++Count;
6a4366ac 7723 }
df2a74ce 7724
6a4366ac 7725 fclose(fptr);
7726 }
df2a74ce 7727
6a4366ac 7728 if (Count == 0)
7729 {
df2a74ce 7730 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7731 "configuration error in winad.cfg");
6a4366ac 7732 return(1);
7733 }
df2a74ce 7734
6a4366ac 7735 return(0);
7736}
26503e15 7737
df2a74ce 7738int email_isvalid(const char *address) {
7739 int count = 0;
7740 const char *c, *domain;
7741 static char *rfc822_specials = "()<>@,;:\\\"[]";
7742
7743 if(address[strlen(address) - 1] == '.')
7744 return 0;
7745
7746 /* first we validate the name portion (name@domain) */
7747 for (c = address; *c; c++) {
7748 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7749 '\"')) {
7750 while (*++c) {
7751 if (*c == '\"')
7752 break;
7753 if (*c == '\\' && (*++c == ' '))
7754 continue;
7755 if (*c <= ' ' || *c >= 127)
7756 return 0;
7757 }
7758
7759 if (!*c++)
7760 return 0;
7761 if (*c == '@')
7762 break;
7763 if (*c != '.')
7764 return 0;
7765 continue;
7766 }
7767
7768 if (*c == '@')
7769 break;
7770 if (*c <= ' ' || *c >= 127)
7771 return 0;
7772 if (strchr(rfc822_specials, *c))
7773 return 0;
7774 }
7775
7776 if (c == address || *(c - 1) == '.')
7777 return 0;
7778
7779 /* next we validate the domain portion (name@domain) */
7780 if (!*(domain = ++c)) return 0;
7781 do {
7782 if (*c == '.') {
7783 if (c == domain || *(c - 1) == '.')
7784 return 0;
7785 count++;
7786 }
7787 if (*c <= ' ' || *c >= 127)
7788 return 0;
7789 if (strchr(rfc822_specials, *c))
7790 return 0;
7791 } while (*++c);
7792
7793 return (count >= 1);
7794}
7795
7796int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7797 char **homeServerName)
6a4366ac 7798{
df2a74ce 7799 LK_ENTRY *group_base;
7800 LK_ENTRY *sub_group_base;
7801 LK_ENTRY *gPtr;
7802 LK_ENTRY *sub_gPtr;
7803 int group_count;
7804 int sub_group_count;
7805 char filter[1024];
7806 char sub_filter[1024];
7807 char search_path[1024];
7808 char range[1024];
7809 char *attr_array[3];
7810 char *s;
7811 int homeMDB_count = -1;
7812 int rc;
7813 int i;
7814 int mdbbl_count;
7815 int rangeStep = 1500;
7816 int rangeLow = 0;
7817 int rangeHigh = rangeLow + (rangeStep - 1);
7818 int isLast = 0;
7819
7820 /* Grumble..... microsoft not making it searchable from the root *grr* */
7821
7822 memset(filter, '\0', sizeof(filter));
7823 memset(search_path, '\0', sizeof(search_path));
6a4366ac 7824
df2a74ce 7825 sprintf(filter, "(objectClass=msExchMDB)");
7826 sprintf(search_path, "CN=Configuration,%s", dn_path);
7827 attr_array[0] = "distinguishedName";
7828 attr_array[1] = NULL;
7829
7830 group_base = NULL;
7831 group_count = 0;
7832
7833 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7834 &group_base, &group_count,
7835 LDAP_SCOPE_SUBTREE)) != 0)
6a4366ac 7836 {
df2a74ce 7837 com_err(whoami, 0, "Unable to find msExchMDB %s",
7838 ldap_err2string(rc));
7839 return(rc);
7840 }
7841
7842 if (group_count)
7843 {
7844 gPtr = group_base;
7845
7846 while(gPtr) {
552863f0 7847 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
7848 ((s = strstr(gPtr->dn, "Recovery")) != (char *) NULL))
20c27f25 7849 {
7850 gPtr = gPtr->next;
7851 continue;
7852 }
7853
df2a74ce 7854 /*
7855 * Due to limits in active directory we need to use the LDAP
7856 * range semantics to query and return all the values in
7857 * large lists, we will stop increasing the range when
7858 * the result count is 0.
7859 */
7860
7861 i = 0;
7862 mdbbl_count = 0;
7863
7864 for(;;)
7865 {
7866 memset(sub_filter, '\0', sizeof(sub_filter));
7867 memset(range, '\0', sizeof(range));
7868 sprintf(sub_filter, "(objectClass=msExchMDB)");
7869
7870 if(isLast)
7871 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
7872 else
7873 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
7874
7875 attr_array[0] = range;
7876 attr_array[1] = NULL;
7877
7878 sub_group_base = NULL;
7879 sub_group_count = 0;
7880
7881 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
7882 attr_array, &sub_group_base,
7883 &sub_group_count,
7884 LDAP_SCOPE_SUBTREE)) != 0)
7885 {
7886 com_err(whoami, 0, "Unable to find homeMDBBL %s",
7887 ldap_err2string(rc));
7888 return(rc);
7889 }
7890
7891 if(!sub_group_count)
7892 {
7893 if(isLast)
7894 {
7895 isLast = 0;
7896 rangeLow = 0;
7897 rangeHigh = rangeLow + (rangeStep - 1);
7898 break;
7899 }
7900 else
7901 isLast++;
7902 }
7903
7904 mdbbl_count += sub_group_count;
7905 rangeLow = rangeHigh + 1;
7906 rangeHigh = rangeLow + (rangeStep - 1);
7907 }
7908
7909 /* First time through, need to initialize or update the least used */
7910
7911 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
7912 mdbbl_count);
7913
7914 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
7915 {
7916 homeMDB_count = mdbbl_count;
7917 *homeMDB = strdup(gPtr->dn);
7918 }
7919
7920 gPtr = gPtr->next;
7921 linklist_free(sub_group_base);
7922 }
7923 }
7924
7925 linklist_free(group_base);
7926
7927 /*
7928 * Ok found the server least allocated need to now query to get its
7929 * msExchHomeServerName so we can set it as a user attribute
7930 */
7931
7932 attr_array[0] = "legacyExchangeDN";
7933 attr_array[1] = NULL;
7934
7935 group_count = 0;
7936 group_base = NULL;
7937
7938 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
7939 attr_array, &group_base,
7940 &group_count,
7941 LDAP_SCOPE_SUBTREE)) != 0)
7942 {
7943 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
7944 ldap_err2string(rc));
7945 return(rc);
7946 }
7947
7948 if(group_count)
7949 {
7950 *homeServerName = strdup(group_base->value);
7951 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
6a4366ac 7952 {
df2a74ce 7953 *s = '\0';
6a4366ac 7954 }
df2a74ce 7955 }
7956
7957 linklist_free(group_base);
7958
7959 return(rc);
7960}
7961
7962char *lowercase(char *s)
7963{
7964 char *p;
7965
7966 for (p = s; *p; p++)
7967 {
7968 if (isupper(*p))
7969 *p = tolower(*p);
7970 }
7971 return s;
7972}
7973
7974char *uppercase(char *s)
7975{
7976 char *p;
7977
7978 for (p = s; *p; p++)
7979 {
7980 if (islower(*p))
7981 *p = toupper(*p);
6a4366ac 7982 }
df2a74ce 7983 return s;
7984}
7985
7986int save_query_info(int argc, char **argv, void *hint)
7987{
7988 int i;
7989 char **nargv = hint;
7990
7991 for(i = 0; i < argc; i++)
7992 nargv[i] = strdup(argv[i]);
7993
7994 return MR_CONT;
26503e15 7995}
This page took 2.340524 seconds and 5 git commands to generate.