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