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