]> andersk Git - moira.git/blame - incremental/winad/winad.c
Replace filter with search_filter.
[moira.git] / incremental / winad / winad.c
CommitLineData
5d0a7127 1/* $Header$
df2a74ce 2/* winad.incr arguments example
cd9e6b16 3 *
df2a74ce 4 * arguments when moira creates the account - ignored by winad.incr since the
5 * account is unusable. users 0 11 #45198 45198 /bin/cmd cmd Last First Middle
6 * 0 950000001 2000 121049
7 *
8 * login, unix_uid, shell, winconsoleshell, last,
9 * first, middle, status, mitid, type, moiraid
cd9e6b16 10 *
89db421e 11 * arguments for creating or updating a user account
df2a74ce 12 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
13 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
14 * First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
15 * users 11 11 #45206 45206 /bin/cmd cmd Last First Middle 0 950000001 STAFF
16 * 121058 PathToHomeDir PathToProfileDir newuser 45206 /bin/cmd cmd Last
17 * First Middle 2 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
18 *
19 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
20 * mitid, type, moiraid
78af4e6e 21 *
89db421e 22 * arguments for deactivating/deleting a user account
df2a74ce 23 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
24 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
25 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
26 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF
27 * 121058 PathToHomeDir PathToProfileDir username 45206 /bin/cmd cmd Last
28 * First Middle 3 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
29 *
30 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
31 * mitid, type, moiraid
cd9e6b16 32 *
89db421e 33 * arguments for reactivating a user account
df2a74ce 34 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
35 * 121058 username 45206 /bin/cmd cmd Last First Middle 1 950000001 STAFF
36 * 121058
37 * users 11 11 username 45206 /bin/cmd cmd Last First Middle 3 950000001 STAFF
38 * 121058 username 45206 /bin/cmd cmd Last First Middle 2 950000001 STAFF 12105
39 *
40 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
41 * mitid, type, moiraid
cd9e6b16 42 *
89db421e 43 * arguments for changing user name
df2a74ce 44 * users 11 11 oldusername 45206 /bin/cmd cmd Last First Middle 1 950000001
45 * STAFF 121058 PathToHomeDir PathToProfileDir newusername 45206 /bin/cmd cmd
46 * Last First Middle 1 950000001 STAFF 121058 PathToHomeDir PathToProfileDir
47 *
48 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
49 * mitid, type, moiraid
cd9e6b16 50 *
89db421e 51 * arguments for expunging a user
df2a74ce 52 * users 11 0 username 45198 /bin/cmd cmd Last First Middle 0 950000001 2000
53 * 121049
54 *
55 * login, unix_uid, shell, winconsoleshell, last, first, middle, status,
56 * mitid, type, moiraid
89db421e 57 *
58 * arguments for creating a "special" group/list
59 * list 0 11 listname 1 1 0 0 0 -1 NONE 0 description 92616
df2a74ce 60 *
61 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
62 * acl_id, description, moiraid
9db0b148 63 *
89db421e 64 * arguments for creating a "mail" group/list
65 * list 0 11 listname 1 1 0 1 0 -1 NONE 0 description 92616
df2a74ce 66 *
67 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
68 * acl_id, description, moiraid
89db421e 69 *
70 * arguments for creating a "group" group/list
71 * list 0 11 listname 1 1 0 0 1 -1 NONE 0 description 92616
df2a74ce 72 *
73 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
74 * acl_id, description, moiraid
89db421e 75 *
76 * arguments for creating a "group/mail" group/list
77 * list 0 11 listname 1 1 0 1 1 -1 NONE 0 description 92616
df2a74ce 78 *
79 * listname, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
80 * acl_id, description, moiraid
89db421e 81 *
82 * arguments to add a USER member to group/list
83 * imembers 0 12 listname USER userName 1 1 0 0 0 -1 1 92616 121047
df2a74ce 84 *
85 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
86 * gid, userStatus, moiraListId, moiraUserId
89db421e 87 *
88 * arguments to add a STRING or KERBEROS member to group/list
89 * imembers 0 10 listname STRING stringName 1 1 0 0 0 -1 92616
90 * imembers 0 10 listlistnameName KERBEROS kerberosName 1 1 0 0 0 -1 92616
df2a74ce 91 *
92 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
93 * gid, moiraListId
89db421e 94 *
95 * NOTE: group members of type LIST are ignored.
96 *
97 * arguments to remove a USER member to group/list
98 * imembers 12 0 listname USER userName 1 1 0 0 0 -1 1 92616 121047
df2a74ce 99 *
100 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
101 * gid, userStatus, moiraListId, moiraUserId
89db421e 102 *
103 * arguments to remove a STRING or KERBEROS member to group/list
104 * imembers 10 0 listname STRING stringName 1 1 0 0 0 -1 92616
105 * imembers 10 0 listname KERBEROS kerberosName 1 1 0 0 0 -1 92616
df2a74ce 106 *
107 * list_name, user_type, name, active, publicflg, hidden, maillist, grouplist,
108 * gid, moiraListId
9db0b148 109 *
89db421e 110 * NOTE: group members of type LIST are ignored.
f75f605a 111 *
89db421e 112 * arguments for renaming a group/list
df2a74ce 113 * list 11 11 oldlistname 1 1 0 0 0 -1 NONE 0 description 92616 newlistname 1
114 * 1 0 0 0 -1 description 0 92616
115 *
116 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
117 * acl_id, description, moiraListId
f75f605a 118 *
89db421e 119 * arguments for deleting a group/list
120 * list 11 0 listname 1 1 0 0 0 -1 NONE 0 description 92616
df2a74ce 121 *
122 * name, active, publicflg, hidden, maillist, grouplist, gid, acl_type,
123 * acl_id, description, moiraListId
6c8f12af 124 *
89db421e 125 * arguments for adding a file system
df2a74ce 126 * filesys 0 12 username AFS ATHENA.MIT.EDU
127 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
128 * wheel 1 HOMEDIR 101727
89db421e 129 *
130 * arguments for deleting a file system
df2a74ce 131 * filesys 12 0 username AFS ATHENA.MIT.EDU
132 * /afs/athena.mit.edu/user/n/e/username /mit/username w descripton username
133 * wheel 1 HOMEDIR 101727
6c8f12af 134 *
135 * arguments when moira creates a container (OU).
df2a74ce 136 * containers 0 8 machines/test/bottom description location contact USER
137 * 105316 2222 [none]
6c8f12af 138 *
139 * arguments when moira deletes a container (OU).
df2a74ce 140 * containers 8 0 machines/test/bottom description location contact USER
141 * 105316 2222 groupname
9cfe334f 142 *
6c8f12af 143 * arguments when moira modifies a container information (OU).
df2a74ce 144 * containers 8 8 machines/test/bottom description location contact USER
145 * 105316 2222 groupname machines/test/bottom description1 location contact
146 * USER 105316 2222 groupname
bbef4f93 147 *
148 * arguments when moira adds a machine from an OU
149 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
209367bd 150 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
bbef4f93 151 *
152 * arguments when moira removes a machine from an OU
153 * table name, beforec, afterc, machine_name, container_name, mach_id, cnt_id
209367bd 154 * mcntmap 0 5 DAVIDT.MIT.EDU dttest/dttest1 76767 46 groupname
bbef4f93 155 *
cd9e6b16 156*/
df2a74ce 157
5d0a7127 158#include <mit-copyright.h>
df2a74ce 159
5d0a7127 160#ifdef _WIN32
4a6e2ee4 161#include <winsock2.h>
5d0a7127 162#include <windows.h>
163#include <stdlib.h>
164#include <malloc.h>
165#include <lmaccess.h>
166#endif
df2a74ce 167
f78c7eaf 168#include <hesiod.h>
cd9e6b16 169#include <string.h>
5d0a7127 170#include <ldap.h>
171#include <stdio.h>
172#include <moira.h>
173#include <moira_site.h>
cd9e6b16 174#include <mrclient.h>
5d0a7127 175#include <krb5.h>
5d0a7127 176#include <gsssasl.h>
df2a74ce 177#include <gssldap.h>
cd9e6b16 178#include "kpasswd.h"
179
180#ifdef _WIN32
181#ifndef ECONNABORTED
182#define ECONNABORTED WSAECONNABORTED
183#endif
184#ifndef ECONNREFUSED
185#define ECONNREFUSED WSAECONNREFUSED
186#endif
187#ifndef EHOSTUNREACH
188#define EHOSTUNREACH WSAEHOSTUNREACH
189#endif
190#define krb5_xfree free
0d958b3c 191#define F_OK 0
192#define sleep(A) Sleep(A * 1000);
cd9e6b16 193#endif /* _WIN32 */
5d0a7127 194
195#ifndef _WIN32
f78c7eaf 196#include <sys/types.h>
197#include <netinet/in.h>
198#include <arpa/nameser.h>
199#include <resolv.h>
5d0a7127 200#include <sys/utsname.h>
0d958b3c 201#include <unistd.h>
5d0a7127 202
6a4366ac 203#define CFG_PATH "/moira/winad/"
204#define WINADCFG "winad.cfg"
f78c7eaf 205#define strnicmp(A,B,C) strncasecmp(A,B,C)
cd9e6b16 206#define UCHAR unsigned char
207
5d0a7127 208#define UF_SCRIPT 0x0001
209#define UF_ACCOUNTDISABLE 0x0002
210#define UF_HOMEDIR_REQUIRED 0x0008
211#define UF_LOCKOUT 0x0010
212#define UF_PASSWD_NOTREQD 0x0020
213#define UF_PASSWD_CANT_CHANGE 0x0040
cd9e6b16 214#define UF_DONT_EXPIRE_PASSWD 0x10000
5d0a7127 215
216#define UF_TEMP_DUPLICATE_ACCOUNT 0x0100
217#define UF_NORMAL_ACCOUNT 0x0200
218#define UF_INTERDOMAIN_TRUST_ACCOUNT 0x0800
219#define UF_WORKSTATION_TRUST_ACCOUNT 0x1000
220#define UF_SERVER_TRUST_ACCOUNT 0x2000
221
909e0dc3 222#define OWNER_SECURITY_INFORMATION (0x00000001L)
223#define GROUP_SECURITY_INFORMATION (0x00000002L)
224#define DACL_SECURITY_INFORMATION (0x00000004L)
225#define SACL_SECURITY_INFORMATION (0x00000008L)
226
5d0a7127 227#ifndef BYTE
228#define BYTE unsigned char
229#endif
230typedef unsigned int DWORD;
231typedef unsigned long ULONG;
232
233typedef struct _GUID
234{
235 unsigned long Data1;
236 unsigned short Data2;
237 unsigned short Data3;
238 unsigned char Data4[8];
239} GUID;
240
241typedef struct _SID_IDENTIFIER_AUTHORITY {
242 BYTE Value[6];
243} SID_IDENTIFIER_AUTHORITY, *PSID_IDENTIFIER_AUTHORITY;
244
245typedef struct _SID {
246 BYTE Revision;
247 BYTE SubAuthorityCount;
248 SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
249 DWORD SubAuthority[512];
250} SID;
251#endif/*!WIN32*/
252
f75f605a 253#ifndef WINADCFG
254#define WINADCFG "winad.cfg"
255#endif
256
6a4366ac 257#ifndef CFG_PATH
258#define CFG_PATH ""
259#endif
260
f78c7eaf 261#define AFS "/afs/"
262#define WINAFS "\\\\afs\\all\\"
263
cd9e6b16 264#define ADS_GROUP_TYPE_GLOBAL_GROUP 0x00000002
f78c7eaf 265#define ADS_GROUP_TYPE_DOMAIN_LOCAL_GROUP 0x00000004
266#define ADS_GROUP_TYPE_LOCAL_GROUP 0x00000004
267#define ADS_GROUP_TYPE_UNIVERSAL_GROUP 0x00000008
268#define ADS_GROUP_TYPE_SECURITY_ENABLED 0x80000000
cd9e6b16 269
26503e15 270#define QUERY_VERSION -1
271#define PRIMARY_REALM "ATHENA.MIT.EDU"
272#define PRIMARY_DOMAIN "win.mit.edu"
273#define PRODUCTION_PRINCIPAL "sms"
274#define TEST_PRINCIPAL "smstest"
cd9e6b16 275
5d0a7127 276#define SUBSTITUTE 1
277#define REPLACE 2
278
cd9e6b16 279#define USERS 0
280#define GROUPS 1
281
5d0a7127 282#define MEMBER_ADD 1
283#define MEMBER_REMOVE 2
284#define MEMBER_CHANGE_NAME 3
285#define MEMBER_ACTIVATE 4
286#define MEMBER_DEACTIVATE 5
cd9e6b16 287#define MEMBER_CREATE 6
5d0a7127 288
f78c7eaf 289#define MOIRA_ALL 0x0
290#define MOIRA_USERS 0x1
291#define MOIRA_KERBEROS 0x2
292#define MOIRA_STRINGS 0x4
293#define MOIRA_LISTS 0x8
294
89db421e 295#define CHECK_GROUPS 1
296#define CLEANUP_GROUPS 2
297
298#define AD_NO_GROUPS_FOUND -1
299#define AD_WRONG_GROUP_DN_FOUND -2
300#define AD_MULTIPLE_GROUPS_FOUND -3
301#define AD_INVALID_NAME -4
302#define AD_LDAP_FAILURE -5
303#define AD_INVALID_FILESYS -6
304#define AD_NO_ATTRIBUTE_FOUND -7
305#define AD_NO_OU_FOUND -8
306#define AD_NO_USER_FOUND -9
307
6c8f12af 308/* container arguments */
209367bd 309#define CONTAINER_NAME 0
310#define CONTAINER_DESC 1
311#define CONTAINER_LOCATION 2
312#define CONTAINER_CONTACT 3
313#define CONTAINER_TYPE 4
314#define CONTAINER_ID 5
315#define CONTAINER_ROWID 6
316#define CONTAINER_GROUP_NAME 7
6c8f12af 317
bbef4f93 318/*mcntmap arguments*/
319#define OU_MACHINE_NAME 0
320#define OU_CONTAINER_NAME 1
321#define OU_MACHINE_ID 2
322#define OU_CONTAINER_ID 3
209367bd 323#define OU_CONTAINER_GROUP 4
bbef4f93 324
5d0a7127 325typedef struct lk_entry {
326 int op;
327 int length;
328 int ber_value;
329 char *dn;
330 char *attribute;
331 char *value;
332 char *member;
333 char *type;
334 char *list;
335 struct lk_entry *next;
336} LK_ENTRY;
337
0d958b3c 338#define STOP_FILE "/moira/winad/nowinad"
339#define file_exists(file) (access((file), F_OK) == 0)
340
909e0dc3 341#define N_SD_BER_BYTES 5
5d0a7127 342#define LDAP_BERVAL struct berval
cd9e6b16 343#define MAX_SERVER_NAMES 32
344
909e0dc3 345#define HIDDEN_GROUP "HiddenGroup.g"
346#define HIDDEN_GROUP_WITH_ADMIN "HiddenGroupWithAdmin.g"
347#define NOT_HIDDEN_GROUP "NotHiddenGroup.g"
348#define NOT_HIDDEN_GROUP_WITH_ADMIN "NotHiddenGroupWithAdmin.g"
349
df2a74ce 350#define ADDRESS_LIST_PREFIX "CN=MIT Directory,CN=All Address Lists,\
351CN=Address Lists Container,CN=Massachusetts Institute of Technology,\
352CN=Microsoft Exchange,CN=Services,CN=Configuration,"
353
cd9e6b16 354#define ADD_ATTR(t, v, o) \
355 mods[n] = malloc(sizeof(LDAPMod)); \
df2a74ce 356 mods[n]->mod_op = o; \
cd9e6b16 357 mods[n]->mod_type = t; \
358 mods[n++]->mod_values = v
5d0a7127 359
df2a74ce 360#define DEL_ATTR(t, o) \
3abb4456 361 DelMods[i] = malloc(sizeof(LDAPMod)); \
df2a74ce 362 DelMods[i]->mod_op = o; \
3abb4456 363 DelMods[i]->mod_type = t; \
364 DelMods[i++]->mod_values = NULL
365
366#define DOMAIN_SUFFIX "MIT.EDU"
26503e15 367#define DOMAIN "DOMAIN:"
368#define PRINCIPALNAME "PRINCIPAL:"
369#define SERVER "SERVER:"
370#define MSSFU "SFU:"
d7051053 371#define SFUTYPE "30"
df2a74ce 372#define GROUP_SUFFIX "GROUP_SUFFIX:"
373#define GROUP_TYPE "GROUP_TYPE:"
374#define SET_GROUP_ACE "SET_GROUP_ACE:"
375#define SET_PASSWORD "SET_PASSWORD:"
376#define EXCHANGE "EXCHANGE:"
377#define PROCESS_MACHINE_CONTAINER "PROCESS_MACHINE_CONTAINER:"
6a4366ac 378#define MAX_DOMAINS 10
379char DomainNames[MAX_DOMAINS][128];
3abb4456 380
5d0a7127 381LK_ENTRY *member_base = NULL;
df2a74ce 382
383char PrincipalName[128];
0d958b3c 384static char tbl_buf[1024];
89db421e 385char kerberos_ou[] = "OU=kerberos,OU=moira";
386char contact_ou[] = "OU=strings,OU=moira";
387char user_ou[] = "OU=users,OU=moira";
388char group_ou_distribution[] = "OU=mail,OU=lists,OU=moira";
389char group_ou_root[] = "OU=lists,OU=moira";
390char group_ou_security[] = "OU=group,OU=lists,OU=moira";
391char group_ou_neither[] = "OU=special,OU=lists,OU=moira";
392char group_ou_both[] = "OU=mail,OU=group,OU=lists,OU=moira";
6c8f12af 393char orphans_machines_ou[] = "OU=Machines,OU=Orphans";
394char orphans_other_ou[] = "OU=Other,OU=Orphans";
909e0dc3 395char security_template_ou[] = "OU=security_templates";
5d0a7127 396char *whoami;
cd9e6b16 397char ldap_domain[256];
d7051053 398char *ServerList[MAX_SERVER_NAMES];
f78c7eaf 399char default_server[256];
bfb6f0ad 400static char tbl_buf[1024];
df2a74ce 401char group_suffix[256];
402char exchange_acl[256];
403int mr_connections = 0;
404int callback_rc;
3abb4456 405int UseSFU30 = 0;
df2a74ce 406int UseGroupSuffix = 1;
407int UseGroupUniversal = 0;
408int SetGroupAce = 1;
409int SetPassword = 1;
410int Exchange = 0;
411int ProcessMachineContainer = 1;
6a4366ac 412int UpdateDomainList;
cd9e6b16 413
f78c7eaf 414extern int set_password(char *user, char *password, char *domain);
cd9e6b16 415
89db421e 416int ad_get_group(LDAP *ldap_handle, char *dn_path, char *group_name,
df2a74ce 417 char *group_membership, char *MoiraId, char *attribute,
418 LK_ENTRY **linklist_base, int *linklist_count,
419 char *rFilter);
f78c7eaf 420void AfsToWinAfs(char* path, char* winPath);
421int ad_connect(LDAP **ldap_handle, char *ldap_domain, char *dn_path,
422 char *Win2kPassword, char *Win2kUser, char *default_server,
26503e15 423 int connect_to_kdc, char **ServerList);
f78c7eaf 424void ad_kdc_disconnect();
26503e15 425int ad_server_connect(char *connectedServer, char *domain);
4a6e2ee4 426int attribute_update(LDAP *ldap_handle, char *distinguished_name,
df2a74ce 427 char *attribute_value, char *attribute, char *user_name);
909e0dc3 428int BEREncodeSecurityBits(ULONG uBits, char *pBuffer);
bbef4f93 429int checkADname(LDAP *ldap_handle, char *dn_path, char *Name);
6a4366ac 430int check_winad(void);
df2a74ce 431int check_user(LDAP *ldap_handle, char *dn_path, char *UserName,
432 char *MoiraId);
6c8f12af 433/* containers */
434int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
435 char *distinguishedName, int count, char **av);
436void container_check(LDAP *ldap_handle, char *dn_path, char *name);
437int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av);
438int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av);
439int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
df2a74ce 440 char *distinguishedName, int count,
441 char **av);
6c8f12af 442void container_get_dn(char *src, char *dest);
443void container_get_name(char *src, char *dest);
444int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName);
df2a74ce 445int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
446 char **before, int afterc, char **after);
447int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
448 char **before, int afterc, char **after);
6c8f12af 449
909e0dc3 450int GetAceInfo(int ac, char **av, void *ptr);
f75f605a 451int get_group_membership(char *group_membership, char *group_ou,
452 int *security_flag, char **av);
df2a74ce 453int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
454 char *machine_ou, char *pPtr);
209367bd 455int Moira_container_group_create(char **after);
456int Moira_container_group_delete(char **before);
457int Moira_groupname_create(char *GroupName, char *ContainerName,
458 char *ContainerRowID);
459int Moira_container_group_update(char **before, char **after);
460int Moira_process_machine_container_group(char *MachineName, char* groupName,
461 int DeleteMachine);
462int Moira_addGroupToParent(char *origContainerName, char *GroupName);
463int Moira_getContainerGroup(int ac, char **av, void *ptr);
464int Moira_getGroupName(char *origContainerName, char *GroupName,
465 int ParentFlag);
466int Moira_setContainerGroup(char *ContainerName, char *GroupName);
909e0dc3 467int ProcessAce(LDAP *ldap_handle, char *dn_path, char *group_name, char *Type,
df2a74ce 468 int UpdateGroup, int *ProcessGroup, char *maillist);
89db421e 469int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
470 char *group_name, char *group_ou, char *group_membership,
df2a74ce 471 int group_security_flag, int type, char *maillist);
f75f605a 472int process_lists(int ac, char **av, void *ptr);
df2a74ce 473int ProcessGroupSecurity(LDAP *ldap_handle, char *dn_path,
474 char *TargetGroupName, int HiddenGroup,
475 char *AceType, char *AceName);
3abb4456 476int ProcessMachineName(int ac, char **av, void *ptr);
6a4366ac 477int ReadConfigFile(char *DomainName);
478int ReadDomainList();
26503e15 479void StringTrim(char *StringToTrim);
df2a74ce 480int save_query_info(int argc, char **argv, void *hint);
cd9e6b16 481int user_create(int ac, char **av, void *ptr);
89db421e 482int user_change_status(LDAP *ldap_handle, char *dn_path,
483 char *user_name, char *MoiraId, int operation);
484int user_delete(LDAP *ldap_handle, char *dn_path,
485 char *u_name, char *MoiraId);
f75f605a 486int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
89db421e 487 char *user_name);
f75f605a 488int user_update(LDAP *ldap_handle, char *dn_path, char *user_name,
3abb4456 489 char *uid, char *MitId, char *MoiraId, int State,
df2a74ce 490 char *WinHomeDir, char *WinProfileDir, char *first,
491 char *middle, char *last);
89db421e 492void change_to_lower_case(char *ptr);
cd9e6b16 493int contact_create(LDAP *ld, char *bind_path, char *user, char *group_ou);
df2a74ce 494int contact_remove_email(LDAP *ld, char *bind_path,
495 LK_ENTRY **linklist_entry, int linklist_current);
cd9e6b16 496int group_create(int ac, char **av, void *ptr);
f75f605a 497int group_delete(LDAP *ldap_handle, char *dn_path,
89db421e 498 char *group_name, char *group_membership, char *MoiraId);
f75f605a 499int group_rename(LDAP *ldap_handle, char *dn_path,
500 char *before_group_name, char *before_group_membership,
df2a74ce 501 char *before_group_ou, int before_security_flag,
502 char *before_desc, char *after_group_name,
503 char *after_group_membership, char *after_group_ou,
504 int after_security_flag, char *after_desc,
505 char *MoiraId, char *filter, char *maillist);
bbef4f93 506int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name);
507int machine_GetMoiraContainer(int ac, char **av, void *ptr);
df2a74ce 508int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
509 char *machine_name, char *container_name);
510int machine_move_to_ou(LDAP *ldap_handle, char *dn_path,
511 char *MoiraMachineName, char *DestinationOu);
89db421e 512int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
513 char *group_name, char *group_ou, char *group_membership,
df2a74ce 514 int group_security_flag, int updateGroup, char *maillist);
cd9e6b16 515int member_list_build(int ac, char **av, void *ptr);
f75f605a 516int member_add(LDAP *ldap_handle, char *dn_path, char *group_name,
df2a74ce 517 char *group_ou, char *group_membership,
518 char *user_name, char *pUserOu, char *MoiraId);
78af4e6e 519int member_remove(LDAP *ldap_handle, char *dn_path, char *group_name,
f75f605a 520 char *group_ou, char *group_membership, char *user_name,
89db421e 521 char *pUserOu, char *MoiraId);
522int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
523 char *group_ou, char *group_membership,
524 int group_security_flag, char *MoiraId);
df2a74ce 525int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
526 char *DistinguishedName,
3abb4456 527 char *WinHomeDir, char *WinProfileDir,
528 char **homedir_v, char **winProfile_v,
529 char **drives_v, LDAPMod **mods,
530 int OpType, int n);
6a4366ac 531int sid_update(LDAP *ldap_handle, char *dn_path);
3abb4456 532void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n);
cd9e6b16 533int check_string(char *s);
bb52f279 534int check_container_name(char* s);
91d83263 535
cd9e6b16 536int mr_connect_cl(char *server, char *client, int version, int auth);
6c8f12af 537void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
df2a74ce 538 char **before, int beforec, char **after, int afterc);
6a4366ac 539void do_filesys(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
540 char **before, int beforec, char **after, int afterc);
f78c7eaf 541void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
542 char **before, int beforec, char **after, int afterc);
543void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 544 char **before, int beforec, char **after, int afterc);
5d0a7127 545void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 546 char **before, int beforec, char **after, int afterc);
bbef4f93 547void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
548 char **before, int beforec, char **after, int afterc);
cd9e6b16 549int linklist_create_entry(char *attribute, char *value,
550 LK_ENTRY **linklist_entry);
5d0a7127 551int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
cd9e6b16 552 char **attr_array, LK_ENTRY **linklist_base,
d7051053 553 int *linklist_count, unsigned long ScopeType);
5d0a7127 554void linklist_free(LK_ENTRY *linklist_base);
cd9e6b16 555
556int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
557 char *distinguished_name, LK_ENTRY **linklist_current);
558int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
559 LK_ENTRY **linklist_base, int *linklist_count);
560int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
561 char *Attribute, char *distinguished_name,
562 LK_ENTRY **linklist_current);
563
564int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
565 char *oldValue, char *newValue,
566 char ***modvalues, int type);
567void free_values(char **modvalues);
568
569int convert_domain_to_dn(char *domain, char **bind_path);
5d0a7127 570void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 571 char *distinguished_name);
5d0a7127 572int moira_disconnect(void);
573int moira_connect(void);
574void print_to_screen(const char *fmt, ...);
3abb4456 575int GetMachineName(char *MachineName);
26503e15 576int tickets_get_k5();
26503e15 577int destroy_cache(void);
578int dest_tkt(void);
5d0a7127 579
df2a74ce 580int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
581 char **homeServerName);
582
5d0a7127 583int main(int argc, char **argv)
584{
cd9e6b16 585 unsigned long rc;
586 int beforec;
587 int afterc;
cd9e6b16 588 int i;
d7051053 589 int j;
6a4366ac 590 int k;
d7051053 591 int OldUseSFU30;
cd9e6b16 592 char *table;
593 char **before;
594 char **after;
cd9e6b16 595 LDAP *ldap_handle;
f78c7eaf 596 char dn_path[256];
6a4366ac 597 char *orig_argv[64];
df2a74ce 598
5d0a7127 599 whoami = ((whoami = (char *)strrchr(argv[0], '/')) ? whoami+1 : argv[0]);
df2a74ce 600
cd9e6b16 601 if (argc < 4)
602 {
4a6e2ee4 603 com_err(whoami, 0, "Unable to process %s", "argc < 4");
cd9e6b16 604 exit(1);
605 }
df2a74ce 606
6a4366ac 607 if (argc < (4 + atoi(argv[2]) + atoi(argv[3])))
cd9e6b16 608 {
df2a74ce 609 com_err(whoami, 0, "Unable to process %s",
610 "argc < (4 + beforec + afterc)");
cd9e6b16 611 exit(1);
612 }
613
6a4366ac 614 if (!strcmp(argv[1], "filesys"))
74647f91 615 exit(0);
616
bfb6f0ad 617 for (i = 1; i < argc; i++)
0d958b3c 618 {
bfb6f0ad 619 strcat(tbl_buf, argv[i]);
620 strcat(tbl_buf, " ");
0d958b3c 621 }
df2a74ce 622
bfb6f0ad 623 com_err(whoami, 0, "%s", tbl_buf);
624
6a4366ac 625 if (check_winad())
626 {
627 com_err(whoami, 0, "%s failed", "check_winad()");
628 exit(1);
629 }
d7051053 630
5d0a7127 631 initialize_sms_error_table();
632 initialize_krb_error_table();
cd9e6b16 633
6a4366ac 634 UpdateDomainList = 0;
635 memset(DomainNames, '\0', sizeof(DomainNames[0]) * MAX_DOMAINS);
df2a74ce 636
6a4366ac 637 if (ReadDomainList())
cd9e6b16 638 {
6a4366ac 639 com_err(whoami, 0, "%s failed", "ReadDomainList()");
cd9e6b16 640 exit(1);
641 }
cd9e6b16 642
6a4366ac 643 for (i = 0; i < argc; i++)
644 orig_argv[i] = NULL;
645
646 for (k = 0; k < MAX_DOMAINS; k++)
d7051053 647 {
6a4366ac 648 if (strlen(DomainNames[k]) == 0)
649 continue;
650 for (i = 0; i < argc; i++)
651 {
652 if (orig_argv[i] != NULL)
653 free(orig_argv[i]);
654 orig_argv[i] = strdup(argv[i]);
655 }
656
657 memset(PrincipalName, '\0', sizeof(PrincipalName));
658 memset(ldap_domain, '\0', sizeof(ldap_domain));
659 memset(ServerList, '\0', sizeof(ServerList[0]) * MAX_SERVER_NAMES);
660 memset(default_server, '\0', sizeof(default_server));
661 memset(dn_path, '\0', sizeof(dn_path));
df2a74ce 662 memset(group_suffix, '\0', sizeof(group_suffix));
663 memset(exchange_acl, '\0', sizeof(exchange_acl));
664
6a4366ac 665 UseSFU30 = 0;
df2a74ce 666 UseGroupSuffix = 1;
667 UseGroupUniversal = 0;
668 SetGroupAce = 1;
669 SetPassword = 1;
670 Exchange = 0;
671 ProcessMachineContainer = 1;
672
673 sprintf(group_suffix, "%s", "_group");
674 sprintf(exchange_acl, "%s", "exchange-acl");
675
6a4366ac 676 beforec = atoi(orig_argv[2]);
677 afterc = atoi(orig_argv[3]);
678 table = orig_argv[1];
679 before = &orig_argv[4];
680 after = &orig_argv[4 + beforec];
681
682 if (afterc == 0)
683 after = NULL;
684
685 if (beforec == 0)
686 before = NULL;
687
688 if (ReadConfigFile(DomainNames[k]))
df2a74ce 689 continue;
6a4366ac 690
691 OldUseSFU30 = UseSFU30;
692
693 for (i = 0; i < 5; i++)
694 {
695 ldap_handle = (LDAP *)NULL;
696 if (!(rc = ad_connect(&ldap_handle, ldap_domain, dn_path, "", "",
697 default_server, 1, ServerList)))
698 {
699 com_err(whoami, 0, "connected to domain %s", DomainNames[k]);
700 break;
701 }
6a4366ac 702 }
703
704 if ((rc) || (ldap_handle == NULL))
705 {
706 critical_alert("incremental",
df2a74ce 707 "winad.incr cannot connect to any server in "
708 "domain %s", DomainNames[k]);
6a4366ac 709 continue;
710 }
711
712 for (i = 0; i < (int)strlen(table); i++)
713 table[i] = tolower(table[i]);
714
715 if (!strcmp(table, "users"))
716 do_user(ldap_handle, dn_path, ldap_domain, before, beforec, after,
717 afterc);
718 else if (!strcmp(table, "list"))
719 do_list(ldap_handle, dn_path, ldap_domain, before, beforec, after,
720 afterc);
721 else if (!strcmp(table, "imembers"))
722 do_member(ldap_handle, dn_path, ldap_domain, before, beforec, after,
723 afterc);
724 else if (!strcmp(table, "containers"))
725 do_container(ldap_handle, dn_path, ldap_domain, before, beforec, after,
726 afterc);
727 else if (!strcmp(table, "mcntmap"))
728 do_mcntmap(ldap_handle, dn_path, ldap_domain, before, beforec, after,
729 afterc);
df2a74ce 730
6a4366ac 731 ad_kdc_disconnect();
732
733 for (i = 0; i < MAX_SERVER_NAMES; i++)
734 {
735 if (ServerList[i] != NULL)
736 {
737 free(ServerList[i]);
738 ServerList[i] = NULL;
739 }
740 }
df2a74ce 741
6a4366ac 742 rc = ldap_unbind_s(ldap_handle);
d7051053 743 }
df2a74ce 744
5d0a7127 745 exit(0);
746}
747
bbef4f93 748void do_mcntmap(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
749 char **before, int beforec, char **after, int afterc)
750{
df2a74ce 751 char MoiraContainerName[128];
752 char ADContainerName[128];
753 char MachineName[1024];
754 char OriginalMachineName[1024];
755 long rc;
756 int DeleteMachine;
757 char MoiraContainerGroup[64];
bbef4f93 758
df2a74ce 759 if (!ProcessMachineContainer)
bbef4f93 760 {
df2a74ce 761 com_err(whoami, 0, "Process machines and containers disabled, skipping");
762 return;
bbef4f93 763 }
df2a74ce 764
765 DeleteMachine = 0;
766 memset(ADContainerName, '\0', sizeof(ADContainerName));
767 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
768
769 if ((beforec == 0) && (afterc == 0))
770 return;
771
772 if (rc = moira_connect())
773 {
774 critical_alert("AD incremental",
775 "Error contacting Moira server : %s",
776 error_message(rc));
777 return;
778 }
779
780 if ((beforec != 0) && (afterc == 0)) /*remove a machine*/
bbef4f93 781 {
df2a74ce 782 strcpy(OriginalMachineName, before[OU_MACHINE_NAME]);
783 strcpy(MachineName, before[OU_MACHINE_NAME]);
784 strcpy(MoiraContainerGroup, before[OU_CONTAINER_GROUP]);
785 DeleteMachine = 1;
786 com_err(whoami, 0, "removing machine %s from %s",
787 OriginalMachineName, before[OU_CONTAINER_NAME]);
bbef4f93 788 }
df2a74ce 789 else if ((beforec == 0) && (afterc != 0)) /*add a machine*/
bbef4f93 790 {
df2a74ce 791 strcpy(OriginalMachineName, after[OU_MACHINE_NAME]);
792 strcpy(MachineName, after[OU_MACHINE_NAME]);
793 strcpy(MoiraContainerGroup, after[OU_CONTAINER_GROUP]);
794 com_err(whoami, 0, "adding machine %s to container %s",
795 OriginalMachineName, after[OU_CONTAINER_NAME]);
bbef4f93 796 }
df2a74ce 797 else
798 {
799 moira_disconnect();
800 return;
801 }
802
803 rc = GetMachineName(MachineName);
bbef4f93 804
df2a74ce 805 if (strlen(MachineName) == 0)
3abb4456 806 {
df2a74ce 807 moira_disconnect();
808 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
809 OriginalMachineName);
810 return;
3abb4456 811 }
df2a74ce 812
813 Moira_process_machine_container_group(MachineName, MoiraContainerGroup,
814 DeleteMachine);
815
816 if (machine_check(ldap_handle, dn_path, MachineName))
bbef4f93 817 {
df2a74ce 818 com_err(whoami, 0, "Unable to find machine %s (alias %s) in AD.",
819 OriginalMachineName, MachineName);
820 moira_disconnect();
821 return;
bbef4f93 822 }
df2a74ce 823
824 memset(MoiraContainerName, '\0', sizeof(MoiraContainerName));
825 machine_get_moira_container(ldap_handle, dn_path, MachineName,
826 MoiraContainerName);
827
828 if (strlen(MoiraContainerName) == 0)
bbef4f93 829 {
df2a74ce 830 com_err(whoami, 0, "Unable to fine machine %s (alias %s) container "
831 "in Moira - moving to orphans OU.",
832 OriginalMachineName, MachineName);
833 machine_move_to_ou(ldap_handle, dn_path, MachineName,
834 orphans_machines_ou);
835 moira_disconnect();
836 return;
bbef4f93 837 }
df2a74ce 838
839 container_get_dn(MoiraContainerName, ADContainerName);
840
841 if (MoiraContainerName[strlen(MoiraContainerName) - 1] != '/')
842 strcat(MoiraContainerName, "/");
843
844 container_check(ldap_handle, dn_path, MoiraContainerName);
845 machine_move_to_ou(ldap_handle, dn_path, MachineName, ADContainerName);
846 moira_disconnect();
847 return;
bbef4f93 848}
849
6c8f12af 850void do_container(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
df2a74ce 851 char **before, int beforec, char **after, int afterc)
6c8f12af 852{
209367bd 853 long rc;
6c8f12af 854
df2a74ce 855 if (!ProcessMachineContainer)
856 {
857 com_err(whoami, 0, "Process machines and containers disabled, skipping");
858 return;
859 }
860
6c8f12af 861 if ((beforec == 0) && (afterc == 0))
862 return;
863
209367bd 864 if (rc = moira_connect())
865 {
866 critical_alert("AD incremental", "Error contacting Moira server : %s",
867 error_message(rc));
868 return;
869 }
870
6c8f12af 871 if ((beforec != 0) && (afterc == 0)) /*delete a new container*/
872 {
873 com_err(whoami, 0, "deleting container %s", before[CONTAINER_NAME]);
874 container_delete(ldap_handle, dn_path, beforec, before);
209367bd 875 Moira_container_group_delete(before);
876 moira_disconnect();
6c8f12af 877 return;
878 }
df2a74ce 879
6c8f12af 880 if ((beforec == 0) && (afterc != 0)) /*create a container*/
881 {
9cfe334f 882 com_err(whoami, 0, "creating container %s", after[CONTAINER_NAME]);
6c8f12af 883 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
884 container_create(ldap_handle, dn_path, afterc, after);
209367bd 885 Moira_container_group_create(after);
886 moira_disconnect();
6c8f12af 887 return;
888 }
889
890 if (strcasecmp(before[CONTAINER_NAME], after[CONTAINER_NAME]))
891 {
df2a74ce 892 com_err(whoami, 0, "renaming container %s to %s",
893 before[CONTAINER_NAME], after[CONTAINER_NAME]);
6c8f12af 894 container_rename(ldap_handle, dn_path, beforec, before, afterc, after);
209367bd 895 Moira_container_group_update(before, after);
896 moira_disconnect();
6c8f12af 897 return;
898 }
df2a74ce 899
900 com_err(whoami, 0, "updating container %s information",
901 after[CONTAINER_NAME]);
6c8f12af 902 container_update(ldap_handle, dn_path, beforec, before, afterc, after);
209367bd 903 Moira_container_group_update(before, after);
904 moira_disconnect();
6c8f12af 905 return;
906}
907
89db421e 908#define L_LIST_DESC 9
909#define L_LIST_ID 10
910
cd9e6b16 911void do_list(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
912 char **before, int beforec, char **after, int afterc)
5d0a7127 913{
89db421e 914 int updateGroup;
909e0dc3 915 int ProcessGroup;
f75f605a 916 long rc;
89db421e 917 char group_membership[6];
918 char list_id[32];
f75f605a 919 int security_flag;
89db421e 920 char filter[128];
f75f605a 921 char group_ou[256];
89db421e 922 char before_list_id[32];
f75f605a 923 char before_group_membership[1];
924 int before_security_flag;
925 char before_group_ou[256];
f75f605a 926 LK_ENTRY *ptr = NULL;
9db0b148 927
928 if (beforec == 0 && afterc == 0)
929 return;
930
89db421e 931 memset(list_id, '\0', sizeof(list_id));
932 memset(before_list_id, '\0', sizeof(before_list_id));
933 memset(before_group_ou, '\0', sizeof(before_group_ou));
934 memset(before_group_membership, '\0', sizeof(before_group_membership));
935 memset(group_ou, '\0', sizeof(group_ou));
936 memset(group_membership, '\0', sizeof(group_membership));
937 updateGroup = 0;
938
939 if (beforec > L_GID)
940 {
941 if (beforec < L_LIST_ID)
942 return;
943 if (beforec > L_LIST_DESC)
944 {
945 strcpy(before_list_id, before[L_LIST_ID]);
946 }
f75f605a 947 before_security_flag = 0;
df2a74ce 948 get_group_membership(before_group_membership, before_group_ou,
949 &before_security_flag, before);
f75f605a 950 }
df2a74ce 951
89db421e 952 if (afterc > L_GID)
f75f605a 953 {
89db421e 954 if (afterc < L_LIST_ID)
955 return;
956 if (afterc > L_LIST_DESC)
957 {
0a5e96ec 958 strcpy(list_id, after[L_LIST_ID]);
89db421e 959 }
f75f605a 960 security_flag = 0;
f75f605a 961 get_group_membership(group_membership, group_ou, &security_flag, after);
962 }
df2a74ce 963
89db421e 964 if ((beforec == 0) && (afterc == 0)) /*this case should never happen*/
f75f605a 965 return;
cd9e6b16 966
89db421e 967 updateGroup = 0;
df2a74ce 968
89db421e 969 if (beforec)
cd9e6b16 970 {
89db421e 971 updateGroup = 1;
df2a74ce 972
973 if ((rc = process_group(ldap_handle, dn_path, before_list_id,
974 before[L_NAME], before_group_ou,
975 before_group_membership,
976 before_security_flag, CHECK_GROUPS,
977 before[L_MAILLIST])))
89db421e 978 {
979 if (rc == AD_NO_GROUPS_FOUND)
980 updateGroup = 0;
981 else
f75f605a 982 {
df2a74ce 983 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
984 (rc == AD_MULTIPLE_GROUPS_FOUND))
89db421e 985 {
df2a74ce 986 rc = process_group(ldap_handle, dn_path, before_list_id,
987 before[L_NAME], before_group_ou,
988 before_group_membership,
989 before_security_flag, CLEANUP_GROUPS,
990 before[L_MAILLIST]);
89db421e 991 }
992 if ((rc != AD_NO_GROUPS_FOUND) && (rc != 0))
f75f605a 993 {
68ba2617 994 com_err(whoami, 0, "Unable to process list %s",
995 before[L_NAME]);
f75f605a 996 return;
997 }
89db421e 998 if (rc == AD_NO_GROUPS_FOUND)
999 updateGroup = 0;
1000 }
1001 }
1002 }
1003
1004 if ((beforec != 0) && (afterc != 0))
1005 {
1006 if (((strcmp(after[L_NAME], before[L_NAME])) ||
df2a74ce 1007 ((!strcmp(after[L_NAME], before[L_NAME])) &&
1008 (strcmp(before_group_ou, group_ou)))) &&
89db421e 1009 (updateGroup == 1))
1010 {
1011 com_err(whoami, 0, "Changing list name from %s to %s",
1012 before[L_NAME], after[L_NAME]);
df2a74ce 1013
1014 if ((strlen(before_group_ou) == 0) ||
1015 (strlen(before_group_membership) == 0) ||
89db421e 1016 (strlen(group_ou) == 0) || (strlen(group_membership) == 0))
1017 {
4a6e2ee4 1018 com_err(whoami, 0, "%s", "Unable to find the group OU's");
89db421e 1019 return;
1020 }
df2a74ce 1021
89db421e 1022 memset(filter, '\0', sizeof(filter));
df2a74ce 1023
89db421e 1024 if ((rc = group_rename(ldap_handle, dn_path,
1025 before[L_NAME], before_group_membership,
df2a74ce 1026 before_group_ou, before_security_flag,
1027 before[L_LIST_DESC], after[L_NAME],
1028 group_membership, group_ou, security_flag,
1029 after[L_LIST_DESC],
1030 list_id, filter, after[L_MAILLIST])))
89db421e 1031 {
1032 if (rc != AD_NO_GROUPS_FOUND)
f75f605a 1033 {
df2a74ce 1034 com_err(whoami, 0,
1035 "Unable to change list name from %s to %s",
89db421e 1036 before[L_NAME], after[L_NAME]);
f75f605a 1037 return;
1038 }
89db421e 1039 updateGroup = 0;
f75f605a 1040 }
89db421e 1041 beforec = 0;
f75f605a 1042 }
1043 else
89db421e 1044 beforec = 0;
cd9e6b16 1045 }
df2a74ce 1046
89db421e 1047 if (beforec)
984c91b7 1048 {
df2a74ce 1049 if ((strlen(before_group_ou) == 0) ||
1050 (strlen(before_group_membership) == 0))
984c91b7 1051 {
df2a74ce 1052 com_err(whoami, 0,
1053 "Unable to find the group OU for group %s", before[L_NAME]);
f75f605a 1054 return;
1055 }
df2a74ce 1056
984c91b7 1057 com_err(whoami, 0, "Deleting group %s", before[L_NAME]);
89db421e 1058 rc = group_delete(ldap_handle, dn_path, before[L_NAME],
1059 before_group_membership, before_list_id);
f75f605a 1060 return;
5d0a7127 1061 }
df2a74ce 1062
89db421e 1063 if (afterc)
5d0a7127 1064 {
89db421e 1065 if (!updateGroup)
1066 {
1067 com_err(whoami, 0, "Creating group %s", after[L_NAME]);
df2a74ce 1068
89db421e 1069 if (rc = process_group(ldap_handle, dn_path, list_id, after[L_NAME],
1070 group_ou, group_membership,
df2a74ce 1071 security_flag, CHECK_GROUPS,
1072 after[L_MAILLIST]))
89db421e 1073 {
1074 if (rc != AD_NO_GROUPS_FOUND)
1075 {
df2a74ce 1076 if ((rc == AD_WRONG_GROUP_DN_FOUND) ||
1077 (rc == AD_MULTIPLE_GROUPS_FOUND))
89db421e 1078 {
df2a74ce 1079 rc = process_group(ldap_handle, dn_path, list_id,
1080 after[L_NAME],
89db421e 1081 group_ou, group_membership,
df2a74ce 1082 security_flag, CLEANUP_GROUPS,
1083 after[L_MAILLIST]);
89db421e 1084 }
df2a74ce 1085
89db421e 1086 if (rc)
1087 {
df2a74ce 1088 com_err(whoami, 0,
1089 "Unable to create list %s", after[L_NAME]);
89db421e 1090 return;
1091 }
1092 }
1093 }
1094 }
1095 else
1096 com_err(whoami, 0, "Updating group %s information", after[L_NAME]);
cd9e6b16 1097
f75f605a 1098 if (rc = moira_connect())
1099 {
1100 critical_alert("AD incremental",
1101 "Error contacting Moira server : %s",
1102 error_message(rc));
1103 return;
1104 }
1105
909e0dc3 1106 ProcessGroup = 0;
df2a74ce 1107
1108 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 0,
1109 &ProcessGroup, after[L_MAILLIST]))
909e0dc3 1110 return;
df2a74ce 1111
909e0dc3 1112 if (ProcessGroup)
1113 {
df2a74ce 1114 if (ProcessAce(ldap_handle, dn_path, after[L_NAME], "LIST", 1,
1115 &ProcessGroup, after[L_MAILLIST]))
909e0dc3 1116 return;
1117 }
df2a74ce 1118
89db421e 1119 if (make_new_group(ldap_handle, dn_path, list_id, after[L_NAME],
df2a74ce 1120 group_ou, group_membership, security_flag,
1121 updateGroup, after[L_MAILLIST]))
cd9e6b16 1122 {
f75f605a 1123 moira_disconnect();
f75f605a 1124 return;
cd9e6b16 1125 }
df2a74ce 1126
89db421e 1127 if (atoi(after[L_ACTIVE]))
cd9e6b16 1128 {
89db421e 1129 populate_group(ldap_handle, dn_path, after[L_NAME], group_ou,
1130 group_membership, security_flag, list_id);
cd9e6b16 1131 }
df2a74ce 1132
f75f605a 1133 moira_disconnect();
5d0a7127 1134 }
f75f605a 1135 return;
5d0a7127 1136}
1137
f75f605a 1138#define LM_EXTRA_ACTIVE (LM_END)
1139#define LM_EXTRA_PUBLIC (LM_END+1)
1140#define LM_EXTRA_HIDDEN (LM_END+2)
1141#define LM_EXTRA_MAILLIST (LM_END+3)
1142#define LM_EXTRA_GROUP (LM_END+4)
1143#define LM_EXTRA_GID (LM_END+5)
89db421e 1144#define LMN_LIST_ID (LM_END+6)
1145#define LM_LIST_ID (LM_END+7)
1146#define LM_USER_ID (LM_END+8)
1147#define LM_EXTRA_END (LM_END+9)
984c91b7 1148
5d0a7127 1149void do_member(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
cd9e6b16 1150 char **before, int beforec, char **after, int afterc)
5d0a7127 1151{
df2a74ce 1152 LK_ENTRY *group_base;
1153 int group_count;
1154 char filter[128];
1155 char *attr_array[3];
cd9e6b16 1156 char group_name[128];
1157 char user_name[128];
9db0b148 1158 char user_type[128];
89db421e 1159 char moira_list_id[32];
1160 char moira_user_id[32];
f75f605a 1161 char group_membership[1];
f75f605a 1162 char group_ou[256];
5f7b0741 1163 char machine_ou[256];
df2a74ce 1164 char member[256];
f75f605a 1165 char *args[16];
1166 char **ptr;
89db421e 1167 char *av[7];
1168 char *call_args[7];
f75f605a 1169 char *pUserOu;
df2a74ce 1170 char *s;
cc1e4a1d 1171 char NewMachineName[1024];
89db421e 1172 int security_flag;
1173 int rc;
909e0dc3 1174 int ProcessGroup;
df2a74ce 1175 char *save_argv[U_END];
f75f605a 1176
1177 pUserOu = NULL;
1178 ptr = NULL;
89db421e 1179 memset(moira_list_id, '\0', sizeof(moira_list_id));
1180 memset(moira_user_id, '\0', sizeof(moira_user_id));
df2a74ce 1181
5d0a7127 1182 if (afterc)
1183 {
89db421e 1184 if (afterc < LM_EXTRA_GID)
f75f605a 1185 return;
df2a74ce 1186
984c91b7 1187 if (!atoi(after[LM_EXTRA_ACTIVE]))
4a6e2ee4 1188 {
df2a74ce 1189 com_err(whoami, 0,
1190 "Unable to add %s to group %s : group not active",
1191 after[2], after[0]);
1192 return;
4a6e2ee4 1193 }
df2a74ce 1194
f75f605a 1195 ptr = after;
df2a74ce 1196
89db421e 1197 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
2f62d71a 1198 return;
df2a74ce 1199
984c91b7 1200 strcpy(user_name, after[LM_MEMBER]);
1201 strcpy(group_name, after[LM_LIST]);
1202 strcpy(user_type, after[LM_TYPE]);
df2a74ce 1203
5f7b0741 1204 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1205 {
1206 if (afterc > LM_EXTRA_GROUP)
1207 {
f7c496a6 1208 strcpy(moira_list_id, after[LMN_LIST_ID]);
1209 strcpy(moira_user_id, after[LM_LIST_ID]);
5f7b0741 1210 }
1211 }
1212 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
89db421e 1213 {
1214 if (afterc > LMN_LIST_ID)
1215 {
1216 strcpy(moira_list_id, after[LM_LIST_ID]);
1217 strcpy(moira_user_id, after[LM_USER_ID]);
1218 }
1219 }
1220 else
1221 {
1222 if (afterc > LM_EXTRA_GID)
1223 strcpy(moira_list_id, after[LMN_LIST_ID]);
1224 }
5d0a7127 1225 }
1226 else if (beforec)
1227 {
89db421e 1228 if (beforec < LM_EXTRA_GID)
f75f605a 1229 return;
984c91b7 1230 if (!atoi(before[LM_EXTRA_ACTIVE]))
4a6e2ee4 1231 {
df2a74ce 1232 com_err(whoami, 0,
1233 "Unable to add %s to group %s : group not active",
1234 before[2], before[0]);
9db0b148 1235 return;
4a6e2ee4 1236 }
df2a74ce 1237
f75f605a 1238 ptr = before;
df2a74ce 1239
89db421e 1240 if (!strcasecmp(ptr[LM_TYPE], "LIST"))
2f62d71a 1241 return;
df2a74ce 1242
984c91b7 1243 strcpy(user_name, before[LM_MEMBER]);
1244 strcpy(group_name, before[LM_LIST]);
1245 strcpy(user_type, before[LM_TYPE]);
df2a74ce 1246
5f7b0741 1247 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1248 {
1249 if (beforec > LM_EXTRA_GROUP)
1250 {
f7c496a6 1251 strcpy(moira_list_id, before[LMN_LIST_ID]);
1252 strcpy(moira_user_id, before[LM_LIST_ID]);
5f7b0741 1253 }
1254 }
1255 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
89db421e 1256 {
1257 if (beforec > LMN_LIST_ID)
1258 {
1259 strcpy(moira_list_id, before[LM_LIST_ID]);
1260 strcpy(moira_user_id, before[LM_USER_ID]);
1261 }
1262 }
1263 else
1264 {
1265 if (beforec > LM_EXTRA_GID)
1266 strcpy(moira_list_id, before[LMN_LIST_ID]);
1267 }
5d0a7127 1268 }
cd9e6b16 1269
f75f605a 1270 if (ptr == NULL)
4a6e2ee4 1271 {
df2a74ce 1272 com_err(whoami, 0,
1273 "Unable to process group : beforec = %d, afterc = %d",
1274 beforec, afterc);
4a6e2ee4 1275 return;
1276 }
f75f605a 1277
1278 args[L_NAME] = ptr[LM_LIST];
1279 args[L_ACTIVE] = ptr[LM_EXTRA_ACTIVE];
1280 args[L_PUBLIC] = ptr[LM_EXTRA_PUBLIC];
1281 args[L_HIDDEN] = ptr[LM_EXTRA_HIDDEN];
1282 args[L_MAILLIST] = ptr[LM_EXTRA_MAILLIST];
1283 args[L_GROUP] = ptr[LM_EXTRA_GROUP];
1284 args[L_GID] = ptr[LM_EXTRA_GID];
1285
1286 security_flag = 0;
1287 memset(group_ou, '\0', sizeof(group_ou));
1288 get_group_membership(group_membership, group_ou, &security_flag, args);
df2a74ce 1289
f75f605a 1290 if (strlen(group_ou) == 0)
cd9e6b16 1291 {
df2a74ce 1292 com_err(whoami, 0, "Unable to find the group OU for group %s",
1293 group_name);
cd9e6b16 1294 return;
1295 }
df2a74ce 1296
1297 if (rc = process_group(ldap_handle, dn_path, moira_list_id, group_name,
1298 group_ou, group_membership, security_flag,
1299 CHECK_GROUPS, args[L_MAILLIST]))
89db421e 1300 {
1301 if (rc != AD_NO_GROUPS_FOUND)
1302 {
df2a74ce 1303 if (rc = process_group(ldap_handle, dn_path, moira_list_id,
1304 group_name, group_ou, group_membership,
1305 security_flag, CLEANUP_GROUPS,
1306 args[L_MAILLIST]))
89db421e 1307 {
1308 if (rc != AD_NO_GROUPS_FOUND)
1309 {
1310 if (afterc)
df2a74ce 1311 com_err(whoami, 0, "Unable to add %s to group %s - "
1312 "unable to process group", user_name, group_name);
89db421e 1313 else
df2a74ce 1314 com_err(whoami, 0, "Unable to remove %s from group %s - "
1315 "unable to process group", user_name, group_name);
89db421e 1316 return;
1317 }
1318 }
1319 }
1320 }
df2a74ce 1321
89db421e 1322 if (rc == AD_NO_GROUPS_FOUND)
1323 {
1324 if (rc = moira_connect())
1325 {
1326 critical_alert("AD incremental",
1327 "Error contacting Moira server : %s",
1328 error_message(rc));
1329 return;
1330 }
df2a74ce 1331
89db421e 1332 com_err(whoami, 0, "creating group %s", group_name);
909e0dc3 1333 ProcessGroup = 0;
df2a74ce 1334
1335 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 0,
1336 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
909e0dc3 1337 return;
df2a74ce 1338
909e0dc3 1339 if (ProcessGroup)
1340 {
df2a74ce 1341 if (ProcessAce(ldap_handle, dn_path, ptr[LM_LIST], "LIST", 1,
1342 &ProcessGroup, ptr[LM_EXTRA_MAILLIST]))
909e0dc3 1343 return;
1344 }
df2a74ce 1345
89db421e 1346 if (make_new_group(ldap_handle, dn_path, moira_list_id, ptr[LM_LIST],
df2a74ce 1347 group_ou, group_membership, security_flag, 0,
1348 ptr[LM_EXTRA_MAILLIST]))
89db421e 1349 {
1350 moira_disconnect();
1351 return;
1352 }
df2a74ce 1353
89db421e 1354 if (atoi(ptr[LM_EXTRA_ACTIVE]))
1355 {
1356 populate_group(ldap_handle, dn_path, ptr[LM_LIST], group_ou,
1357 group_membership, security_flag, moira_list_id);
1358 }
df2a74ce 1359
89db421e 1360 moira_disconnect();
1361 }
df2a74ce 1362
f75f605a 1363 rc = 0;
df2a74ce 1364
f75f605a 1365 if (beforec)
1366 {
df2a74ce 1367 com_err(whoami, 0, "removing user %s from list %s", user_name,
1368 group_name);
f75f605a 1369 pUserOu = user_ou;
df2a74ce 1370
5f7b0741 1371 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1372 {
1373 memset(machine_ou, '\0', sizeof(machine_ou));
cc1e4a1d 1374 memset(NewMachineName, '\0', sizeof(NewMachineName));
df2a74ce 1375 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER],
1376 machine_ou, NewMachineName))
5f7b0741 1377 return;
6a4366ac 1378 if (ptr[LM_MEMBER] != NULL)
1379 free(ptr[LM_MEMBER]);
1380 ptr[LM_MEMBER] = strdup(NewMachineName);
5f7b0741 1381 pUserOu = machine_ou;
1382 }
df2a74ce 1383
f75f605a 1384 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
cd9e6b16 1385 {
df2a74ce 1386 strcpy(member, ptr[LM_MEMBER]);
1387
1388 if (Exchange)
1389 {
1390 if((s = strchr(member, '@')) == (char *) NULL)
1391 {
1392 strcat(member, "@mit.edu");
1393
1394 if (ptr[LM_MEMBER] != NULL)
1395 free(ptr[LM_MEMBER]);
1396 ptr[LM_MEMBER] = strdup(member);
1397 }
1398
1399 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1400 {
1401 s = strrchr(member, '.');
1402 *s = '\0';
1403 strcat(s, ".mit.edu");
1404
1405 if (ptr[LM_MEMBER] != NULL)
1406 free(ptr[LM_MEMBER]);
1407 ptr[LM_MEMBER] = strdup(member);
1408 }
1409 }
1410
f75f605a 1411 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
1412 return;
df2a74ce 1413
f75f605a 1414 pUserOu = contact_ou;
1415 }
1416 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
df2a74ce 1417 {
1418 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER],
1419 kerberos_ou))
1420 return;
1421
1422 pUserOu = kerberos_ou;
1423 }
89db421e 1424 if (rc = member_remove(ldap_handle, dn_path, group_name,
df2a74ce 1425 group_ou, group_membership, ptr[LM_MEMBER],
1426 pUserOu, moira_list_id))
1427 com_err(whoami, 0, "Unable to remove %s from group %s", user_name,
1428 group_name);
1429
1430 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
1431 {
1432 if (rc = moira_connect())
1433 {
1434 critical_alert("AD incremental",
1435 "Error contacting Moira server : %s",
1436 error_message(rc));
1437 return;
1438 }
1439
1440 if (rc = populate_group(ldap_handle, dn_path, group_name,
1441 group_ou, group_membership, security_flag,
1442 moira_list_id))
1443 com_err(whoami, 0, "Unable to remove %s from group %s",
1444 user_name, group_name);
1445 moira_disconnect();
1446 }
89db421e 1447 return;
f75f605a 1448 }
df2a74ce 1449
89db421e 1450 com_err(whoami, 0, "Adding %s to list %s", user_name, group_name);
1451 pUserOu = user_ou;
df2a74ce 1452
5f7b0741 1453 if (!strcasecmp(ptr[LM_TYPE], "MACHINE"))
1454 {
1455 memset(machine_ou, '\0', sizeof(machine_ou));
cc1e4a1d 1456 memset(NewMachineName, '\0', sizeof(NewMachineName));
df2a74ce 1457
1458 if (get_machine_ou(ldap_handle, dn_path, ptr[LM_MEMBER], machine_ou,
1459 NewMachineName))
5f7b0741 1460 return;
df2a74ce 1461
6a4366ac 1462 if (ptr[LM_MEMBER] != NULL)
1463 free(ptr[LM_MEMBER]);
df2a74ce 1464
6a4366ac 1465 ptr[LM_MEMBER] = strdup(NewMachineName);
5f7b0741 1466 pUserOu = machine_ou;
1467 }
1468 else if (!strcasecmp(ptr[LM_TYPE], "STRING"))
f75f605a 1469 {
df2a74ce 1470 strcpy(member, ptr[LM_MEMBER]);
1471
1472 if (Exchange)
1473 {
1474 if((s = strchr(member, '@')) == (char *) NULL)
1475 {
1476 strcat(member, "@mit.edu");
1477
1478 if (ptr[LM_MEMBER] != NULL)
1479 free(ptr[LM_MEMBER]);
1480 ptr[LM_MEMBER] = strdup(member);
1481 }
1482
1483 if(!strncasecmp(&member[strlen(member) - 6], ".LOCAL", 6))
1484 {
1485 s = strrchr(member, '.');
1486 *s = '\0';
1487 strcat(s, ".mit.edu");
1488
1489 if (ptr[LM_MEMBER] != NULL)
1490 free(ptr[LM_MEMBER]);
1491 ptr[LM_MEMBER] = strdup(member);
1492 }
1493 }
1494
89db421e 1495 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], contact_ou))
f75f605a 1496 return;
df2a74ce 1497
89db421e 1498 pUserOu = contact_ou;
1499 }
1500 else if (!strcasecmp(ptr[LM_TYPE], "KERBEROS"))
1501 {
1502 if (contact_create(ldap_handle, dn_path, ptr[LM_MEMBER], kerberos_ou))
1503 return;
df2a74ce 1504
89db421e 1505 pUserOu = kerberos_ou;
1506 }
1507 else if (!strcasecmp(ptr[LM_TYPE], "USER"))
1508 {
1509 if ((rc = check_user(ldap_handle, dn_path, ptr[LM_MEMBER],
1510 moira_user_id)) == AD_NO_USER_FOUND)
f75f605a 1511 {
89db421e 1512 if (rc = moira_connect())
1513 {
1514 critical_alert("AD incremental",
1515 "Error connection to Moira : %s",
1516 error_message(rc));
1517 return;
1518 }
df2a74ce 1519
1520 com_err(whoami, 0, "creating user %s", ptr[LM_MEMBER]);
89db421e 1521 av[0] = ptr[LM_MEMBER];
1522 call_args[0] = (char *)ldap_handle;
1523 call_args[1] = dn_path;
1524 call_args[2] = moira_user_id;
1525 call_args[3] = NULL;
df2a74ce 1526
89db421e 1527 callback_rc = 0;
df2a74ce 1528
1529 if (Exchange)
1530 {
1531 group_count = 0;
1532 group_base = NULL;
1533
1534 sprintf(filter, "(&(objectClass=group)(cn=%s))", ptr[LM_MEMBER]);
1535 attr_array[0] = "cn";
1536 attr_array[1] = NULL;
1537 if ((rc = linklist_build(ldap_handle, dn_path, filter,
1538 attr_array, &group_base, &group_count,
1539 LDAP_SCOPE_SUBTREE)) != 0)
1540 {
1541 com_err(whoami, 0, "Unable to process user %s : %s",
1542 ptr[LM_MEMBER], ldap_err2string(rc));
1543 return;
1544 }
1545
1546 if (group_count)
1547 {
1548 com_err(whoami, 0, "Object already exists with name %s",
1549 ptr[LM_MEMBER]);
1550 return;
1551 }
1552
1553 linklist_free(group_base);
1554 group_count = 0;
1555 group_base = NULL;
1556 }
1557
1558 if (rc = mr_query("get_user_account_by_login", 1, av,
1559 save_query_info, save_argv))
89db421e 1560 {
1561 moira_disconnect();
4a6e2ee4 1562 com_err(whoami, 0, "Unable to create user %s : %s",
89db421e 1563 ptr[LM_MEMBER], error_message(rc));
1564 return;
1565 }
df2a74ce 1566
1567 if (rc = user_create(U_END, save_argv, call_args))
1568 {
1569 moira_disconnect();
1570 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
1571 return;
1572 }
1573
89db421e 1574 if (callback_rc)
1575 {
1576 moira_disconnect();
4a6e2ee4 1577 com_err(whoami, 0, "Unable to create user %s", ptr[LM_MEMBER]);
89db421e 1578 return;
1579 }
f75f605a 1580 }
89db421e 1581 else
f75f605a 1582 {
89db421e 1583 if (rc != 0)
f75f605a 1584 return;
cd9e6b16 1585 }
89db421e 1586 pUserOu = user_ou;
cd9e6b16 1587 }
df2a74ce 1588
89db421e 1589 if (rc = member_add(ldap_handle, dn_path, group_name,
df2a74ce 1590 group_ou, group_membership, ptr[LM_MEMBER],
1591 pUserOu, moira_list_id))
1592 com_err(whoami, 0, "Unable to add %s to group %s", user_name, group_name);
1593
1594 if (!strcasecmp(ptr[LM_TYPE], "STRING"))
cd9e6b16 1595 {
df2a74ce 1596 if (rc = moira_connect())
1597 {
1598 critical_alert("AD incremental",
1599 "Error contacting Moira server : %s",
1600 error_message(rc));
1601 return;
1602 }
1603
1604 if (rc = populate_group(ldap_handle, dn_path, group_name,
1605 group_ou, group_membership, security_flag,
1606 moira_list_id))
1607 com_err(whoami, 0, "Unable to add %s to group %s",
1608 user_name, group_name);
1609
1610 moira_disconnect();
f75f605a 1611 }
df2a74ce 1612
f75f605a 1613 return;
5d0a7127 1614}
1615
cd9e6b16 1616
3abb4456 1617#define U_USER_ID 10
1618#define U_HOMEDIR 11
1619#define U_PROFILEDIR 12
89db421e 1620
f78c7eaf 1621void do_user(LDAP *ldap_handle, char *dn_path, char *ldap_hostname,
1622 char **before, int beforec, char **after,
cd9e6b16 1623 int afterc)
5d0a7127 1624{
df2a74ce 1625 LK_ENTRY *group_base;
1626 int group_count;
1627 char filter[128];
1628 char *attr_array[3];
984c91b7 1629 int rc;
89db421e 1630 char *av[7];
1631 char after_user_id[32];
1632 char before_user_id[32];
1633 char *call_args[7];
df2a74ce 1634 char *save_argv[U_END];
984c91b7 1635
5b8457c5 1636 if ((beforec == 0) && (afterc == 0))
984c91b7 1637 return;
1638
89db421e 1639 memset(after_user_id, '\0', sizeof(after_user_id));
1640 memset(before_user_id, '\0', sizeof(before_user_id));
df2a74ce 1641
89db421e 1642 if (beforec > U_USER_ID)
1643 strcpy(before_user_id, before[U_USER_ID]);
df2a74ce 1644
89db421e 1645 if (afterc > U_USER_ID)
1646 strcpy(after_user_id, after[U_USER_ID]);
984c91b7 1647
89db421e 1648 if ((beforec == 0) && (afterc == 0)) /*this case should never happen */
984c91b7 1649 return;
cd9e6b16 1650
4a6e2ee4 1651 if ((beforec == 0) && (afterc != 0))
1652 {
1653 /*this case only happens when the account*/
1654 /*account is first created but not usable*/
df2a74ce 1655
1656 com_err(whoami, 0, "Unable to process user %s because the user account "
1657 "is not yet usable", after[U_NAME]);
4a6e2ee4 1658 return;
1659 }
df2a74ce 1660
1661 /*this case only happens when the account is expunged */
1662
1663 if ((beforec != 0) && (afterc == 0))
1664 {
89db421e 1665 if (atoi(before[U_STATE]) == 0)
cd9e6b16 1666 {
89db421e 1667 com_err(whoami, 0, "expunging user %s from AD", before[U_NAME]);
1668 user_delete(ldap_handle, dn_path, before[U_NAME], before_user_id);
cd9e6b16 1669 }
4a6e2ee4 1670 else
1671 {
df2a74ce 1672 com_err(whoami, 0, "Unable to process because user %s has been "
1673 "previously expungeded", before[U_NAME]);
4a6e2ee4 1674 }
f75f605a 1675 return;
5d0a7127 1676 }
f75f605a 1677
89db421e 1678 /*process anything that gets here*/
df2a74ce 1679
c0bd7667 1680 if ((rc = check_user(ldap_handle, dn_path, before[U_NAME],
1681 before_user_id)) == AD_NO_USER_FOUND)
5d0a7127 1682 {
6c8f12af 1683 if (!check_string(after[U_NAME]))
1684 return;
df2a74ce 1685
f75f605a 1686 if (rc = moira_connect())
1687 {
1688 critical_alert("AD incremental",
1689 "Error connection to Moira : %s",
1690 error_message(rc));
1691 return;
1692 }
5d0a7127 1693
df2a74ce 1694 com_err(whoami, 0, "creating user %s", after[U_NAME]);
1695
984c91b7 1696 av[0] = after[U_NAME];
cd9e6b16 1697 call_args[0] = (char *)ldap_handle;
1698 call_args[1] = dn_path;
89db421e 1699 call_args[2] = after_user_id;
9db0b148 1700 call_args[3] = NULL;
5b8457c5 1701 callback_rc = 0;
df2a74ce 1702
1703 if (Exchange)
1704 {
1705 group_count = 0;
1706 group_base = NULL;
1707
1708 sprintf(filter, "(&(objectClass=group)(cn=%s))", after[U_NAME]);
1709 attr_array[0] = "cn";
1710 attr_array[1] = NULL;
1711
1712 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
1713 &group_base, &group_count,
1714 LDAP_SCOPE_SUBTREE)) != 0)
1715 {
1716 com_err(whoami, 0, "Unable to process user %s : %s",
1717 after[U_NAME], ldap_err2string(rc));
1718 return;
1719 }
1720
1721 if (group_count >= 1)
1722 {
1723 com_err(whoami, 0, "Object already exists with name %s",
1724 after[U_NAME]);
1725 return;
1726 }
1727
1728 linklist_free(group_base);
1729 group_count = 0;
1730 group_base = NULL;
1731 }
1732
1733 if (rc = mr_query("get_user_account_by_login", 1, av,
1734 save_query_info, save_argv))
cd9e6b16 1735 {
f75f605a 1736 moira_disconnect();
4a6e2ee4 1737 com_err(whoami, 0, "Unable to create user %s : %s",
f75f605a 1738 after[U_NAME], error_message(rc));
1739 return;
cd9e6b16 1740 }
df2a74ce 1741
1742 if (rc = user_create(U_END, save_argv, call_args))
1743 {
1744 com_err(whoami, 0, "Unable to create user %s : %s",
1745 after[U_NAME], error_message(rc));
1746 return;
1747 }
1748
1749 if (callback_rc)
1750 {
1751 moira_disconnect();
1752 com_err(whoami, 0, "Unable to create user %s", after[U_NAME]);
5b8457c5 1753 return;
1754 }
df2a74ce 1755
89db421e 1756 return;
1757 }
1758 else
1759 {
1760 if (rc != 0)
1761 return;
1762 }
df2a74ce 1763
89db421e 1764 if (strcmp(before[U_NAME], after[U_NAME]))
1765 {
1766 if ((check_string(before[U_NAME])) && (check_string(after[U_NAME])))
f75f605a 1767 {
89db421e 1768 com_err(whoami, 0, "changing user %s to %s",
1769 before[U_NAME], after[U_NAME]);
df2a74ce 1770
89db421e 1771 if ((rc = user_rename(ldap_handle, dn_path, before[U_NAME],
1772 after[U_NAME])) != LDAP_SUCCESS)
f75f605a 1773 {
89db421e 1774 return;
f75f605a 1775 }
1776 }
cd9e6b16 1777 }
df2a74ce 1778
89db421e 1779 com_err(whoami, 0, "updating user %s information", after[U_NAME]);
1780 rc = user_update(ldap_handle, dn_path, after[U_NAME],
1781 after[U_UID], after[U_MITID],
df2a74ce 1782 after_user_id, atoi(after[U_STATE]),
1783 after[U_HOMEDIR], after[U_PROFILEDIR],
1784 after[U_FIRST], after[U_MIDDLE], after[U_LAST]);
1785
f75f605a 1786 return;
5d0a7127 1787}
1788
1789int construct_newvalues(LK_ENTRY *linklist_base, int modvalue_count,
cd9e6b16 1790 char *oldValue, char *newValue,
1791 char ***modvalues, int type)
5d0a7127 1792{
cd9e6b16 1793 LK_ENTRY *linklist_ptr;
1794 int i;
1795 char *cPtr;
df2a74ce 1796
1797 if (((*modvalues) = calloc(1,
1798 (modvalue_count + 1) * sizeof(char *))) == NULL)
cd9e6b16 1799 {
1800 return(1);
1801 }
df2a74ce 1802
5d0a7127 1803 for (i = 0; i < (modvalue_count + 1); i++)
cd9e6b16 1804 (*modvalues)[i] = NULL;
df2a74ce 1805
5d0a7127 1806 if (modvalue_count != 0)
1807 {
1808 linklist_ptr = linklist_base;
1809 for (i = 0; i < modvalue_count; i++)
cd9e6b16 1810 {
1811 if ((oldValue != NULL) && (newValue != NULL))
1812 {
1813 if ((cPtr = (char *)strstr(linklist_ptr->value, oldValue))
df2a74ce 1814 != (char *)NULL)
cd9e6b16 1815 {
1816 if (type == REPLACE)
1817 {
1818 if (((*modvalues)[i] = calloc(1, strlen(newValue) + 1))
1819 == NULL)
1820 return(1);
1821 memset((*modvalues)[i], '\0', strlen(newValue) + 1);
1822 strcpy((*modvalues)[i], newValue);
1823 }
1824 else
1825 {
1826 if (((*modvalues)[i] = calloc(1,
1827 (int)(cPtr - linklist_ptr->value) +
df2a74ce 1828 (linklist_ptr->length -
1829 strlen(oldValue)) +
1830 strlen(newValue) + 1)) == NULL)
cd9e6b16 1831 return(1);
1832 memset((*modvalues)[i], '\0',
1833 (int)(cPtr - linklist_ptr->value) +
1834 (linklist_ptr->length - strlen(oldValue)) +
1835 strlen(newValue) + 1);
1836 memcpy((*modvalues)[i], linklist_ptr->value,
1837 (int)(cPtr - linklist_ptr->value));
1838 strcat((*modvalues)[i], newValue);
1839 strcat((*modvalues)[i],
df2a74ce 1840 &linklist_ptr->value[(int)(cPtr -
1841 linklist_ptr->value) + strlen(oldValue)]);
cd9e6b16 1842 }
1843 }
1844 else
1845 {
1846 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1847 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1848 memcpy((*modvalues)[i], linklist_ptr->value,
1849 linklist_ptr->length);
1850 }
1851 }
1852 else
1853 {
1854 (*modvalues)[i] = calloc(1, linklist_ptr->length + 1);
1855 memset((*modvalues)[i], '\0', linklist_ptr->length + 1);
1856 memcpy((*modvalues)[i], linklist_ptr->value,
1857 linklist_ptr->length);
1858 }
1859 linklist_ptr = linklist_ptr->next;
1860 }
1861 (*modvalues)[i] = NULL;
5d0a7127 1862 }
1863 return(0);
1864}
1865
cd9e6b16 1866
5d0a7127 1867int linklist_build(LDAP *ldap_handle, char *dn_path, char *search_exp,
cd9e6b16 1868 char **attr_array, LK_ENTRY **linklist_base,
d7051053 1869 int *linklist_count, unsigned long ScopeType)
5d0a7127 1870{
cd9e6b16 1871 ULONG rc;
5d0a7127 1872 LDAPMessage *ldap_entry;
cd9e6b16 1873
1874 rc = 0;
5d0a7127 1875 ldap_entry = NULL;
1876 (*linklist_base) = NULL;
1877 (*linklist_count) = 0;
df2a74ce 1878
d7051053 1879 if ((rc = ldap_search_s(ldap_handle, dn_path, ScopeType,
df2a74ce 1880 search_exp, attr_array, 0,
1881 &ldap_entry)) != LDAP_SUCCESS)
6c8f12af 1882 {
1883 if (rc != LDAP_SIZELIMIT_EXCEEDED)
1884 return(0);
1885 }
1886
df2a74ce 1887 rc = retrieve_entries(ldap_handle, ldap_entry, linklist_base,
1888 linklist_count);
cd9e6b16 1889
5d0a7127 1890 ldap_msgfree(ldap_entry);
1891 return(rc);
1892}
1893
1894int retrieve_entries(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 1895 LK_ENTRY **linklist_base, int *linklist_count)
5d0a7127 1896{
cd9e6b16 1897 char distinguished_name[1024];
1898 LK_ENTRY *linklist_ptr;
1899 int rc;
1900
5d0a7127 1901 if ((ldap_entry = ldap_first_entry(ldap_handle, ldap_entry)) == NULL)
1902 return(0);
df2a74ce 1903
cd9e6b16 1904 memset(distinguished_name, '\0', sizeof(distinguished_name));
1905 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
1906
1907 if ((rc = retrieve_attributes(ldap_handle, ldap_entry, distinguished_name,
1908 linklist_base)) != 0)
5d0a7127 1909 return(rc);
cd9e6b16 1910
5d0a7127 1911 while ((ldap_entry = ldap_next_entry(ldap_handle, ldap_entry)) != NULL)
1912 {
cd9e6b16 1913 memset(distinguished_name, '\0', sizeof(distinguished_name));
1914 get_distinguished_name(ldap_handle, ldap_entry, distinguished_name);
df2a74ce 1915
1916 if ((rc = retrieve_attributes(ldap_handle, ldap_entry,
1917 distinguished_name, linklist_base)) != 0)
cd9e6b16 1918 return(rc);
5d0a7127 1919 }
cd9e6b16 1920
5d0a7127 1921 linklist_ptr = (*linklist_base);
1922 (*linklist_count) = 0;
df2a74ce 1923
5d0a7127 1924 while (linklist_ptr != NULL)
1925 {
1926 ++(*linklist_count);
1927 linklist_ptr = linklist_ptr->next;
1928 }
df2a74ce 1929
5d0a7127 1930 return(0);
1931}
1932
1933int retrieve_attributes(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 1934 char *distinguished_name, LK_ENTRY **linklist_current)
5d0a7127 1935{
cd9e6b16 1936 char *Attribute;
1937 BerElement *ptr;
1938
5d0a7127 1939 ptr = NULL;
df2a74ce 1940
1941 if ((Attribute = ldap_first_attribute(ldap_handle, ldap_entry,
1942 &ptr)) != NULL)
5d0a7127 1943 {
cd9e6b16 1944 retrieve_values(ldap_handle, ldap_entry, Attribute, distinguished_name,
1945 linklist_current);
5d0a7127 1946 ldap_memfree(Attribute);
cd9e6b16 1947 while ((Attribute = ldap_next_attribute(ldap_handle, ldap_entry,
1948 ptr)) != NULL)
1949 {
1950 retrieve_values(ldap_handle, ldap_entry, Attribute,
1951 distinguished_name, linklist_current);
1952 ldap_memfree(Attribute);
1953 }
5d0a7127 1954 }
df2a74ce 1955
cd9e6b16 1956 ldap_ber_free(ptr, 0);
df2a74ce 1957
5d0a7127 1958 return(0);
1959}
1960
cd9e6b16 1961int retrieve_values(LDAP *ldap_handle, LDAPMessage *ldap_entry,
1962 char *Attribute, char *distinguished_name,
1963 LK_ENTRY **linklist_current)
5d0a7127 1964{
cd9e6b16 1965 char **str_value;
1966 char temp[256];
1967 void **Ptr;
1968 int use_bervalue;
1969 LK_ENTRY *linklist_previous;
5d0a7127 1970 LDAP_BERVAL **ber_value;
cd9e6b16 1971 DWORD ber_length;
df2a74ce 1972
5d0a7127 1973#ifdef LDAP_DEBUG
cd9e6b16 1974 SID *sid;
1975 GUID *guid;
1976 int i;
1977 int intValue;
1978 DWORD *subauth;
1979 SID_IDENTIFIER_AUTHORITY *sid_auth;
1980 unsigned char *subauth_count;
1981#endif /*LDAP_BEGUG*/
5d0a7127 1982
1983 use_bervalue = 0;
1984 memset(temp, '\0', sizeof(temp));
df2a74ce 1985
5d0a7127 1986 if ((!strcmp(Attribute, "objectSid")) ||
1987 (!strcmp(Attribute, "objectGUID")))
1988 use_bervalue = 1;
df2a74ce 1989
5d0a7127 1990 if (use_bervalue)
1991 {
1992 ber_value = ldap_get_values_len(ldap_handle, ldap_entry, Attribute);
1993 Ptr = (void **)ber_value;
1994 str_value = NULL;
df2a74ce 1995 }
5d0a7127 1996 else
1997 {
1998 str_value = ldap_get_values(ldap_handle, ldap_entry, Attribute);
1999 Ptr = (void **)str_value;
2000 ber_value = NULL;
2001 }
df2a74ce 2002
5d0a7127 2003 if (Ptr != NULL)
2004 {
2005 for (; *Ptr; Ptr++)
cd9e6b16 2006 {
2007 if ((linklist_previous = calloc(1, sizeof(LK_ENTRY))) == NULL)
2008 return(1);
df2a74ce 2009
cd9e6b16 2010 memset(linklist_previous, '\0', sizeof(LK_ENTRY));
2011 linklist_previous->next = (*linklist_current);
2012 (*linklist_current) = linklist_previous;
df2a74ce 2013
cd9e6b16 2014 if (((*linklist_current)->attribute = calloc(1,
df2a74ce 2015 strlen(Attribute) + 1)) == NULL)
cd9e6b16 2016 return(1);
df2a74ce 2017
cd9e6b16 2018 memset((*linklist_current)->attribute, '\0', strlen(Attribute) + 1);
2019 strcpy((*linklist_current)->attribute, Attribute);
df2a74ce 2020
cd9e6b16 2021 if (use_bervalue)
2022 {
2023 ber_length = (*(LDAP_BERVAL **)Ptr)->bv_len;
df2a74ce 2024
cd9e6b16 2025 if (((*linklist_current)->value = calloc(1, ber_length)) == NULL)
2026 return(1);
df2a74ce 2027
cd9e6b16 2028 memset((*linklist_current)->value, '\0', ber_length);
df2a74ce 2029 memcpy((*linklist_current)->value,
2030 (*(LDAP_BERVAL **)Ptr)->bv_val, ber_length);
cd9e6b16 2031 (*linklist_current)->length = ber_length;
2032 }
2033 else
2034 {
2035 if (((*linklist_current)->value = calloc(1,
df2a74ce 2036 strlen(*Ptr) + 1)) == NULL)
cd9e6b16 2037 return(1);
df2a74ce 2038
cd9e6b16 2039 memset((*linklist_current)->value, '\0', strlen(*Ptr) + 1);
2040 (*linklist_current)->length = strlen(*Ptr);
2041 strcpy((*linklist_current)->value, *Ptr);
2042 }
df2a74ce 2043
cd9e6b16 2044 (*linklist_current)->ber_value = use_bervalue;
df2a74ce 2045
cd9e6b16 2046 if (((*linklist_current)->dn = calloc(1,
df2a74ce 2047 strlen(distinguished_name) + 1)) == NULL)
cd9e6b16 2048 return(1);
df2a74ce 2049
2050 memset((*linklist_current)->dn, '\0',
2051 strlen(distinguished_name) + 1);
cd9e6b16 2052 strcpy((*linklist_current)->dn, distinguished_name);
2053
5d0a7127 2054#ifdef LDAP_DEBUG
cd9e6b16 2055 if (!strcmp(Attribute, "objectGUID"))
2056 {
2057 guid = (GUID *)((*linklist_current)->value);
df2a74ce 2058 sprintf(temp,
2059 "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
cd9e6b16 2060 guid->Data1, guid->Data2, guid->Data3,
2061 guid->Data4[0], guid->Data4[1], guid->Data4[2],
2062 guid->Data4[3], guid->Data4[4], guid->Data4[5],
2063 guid->Data4[6], guid->Data4[7]);
2064 print_to_screen(" %20s : {%s}\n", Attribute, temp);
2065 }
2066 else if (!strcmp(Attribute, "objectSid"))
2067 {
2068 sid = (SID *)((*(LDAP_BERVAL **)Ptr)->bv_val);
df2a74ce 2069
5d0a7127 2070#ifdef _WIN32
cd9e6b16 2071 print_to_screen(" Revision = %d\n", sid->Revision);
2072 print_to_screen(" SID Identifier Authority:\n");
2073 sid_auth = &sid->IdentifierAuthority;
2074 if (sid_auth->Value[0])
2075 print_to_screen(" SECURITY_NULL_SID_AUTHORITY\n");
2076 else if (sid_auth->Value[1])
2077 print_to_screen(" SECURITY_WORLD_SID_AUTHORITY\n");
2078 else if (sid_auth->Value[2])
2079 print_to_screen(" SECURITY_LOCAL_SID_AUTHORITY\n");
2080 else if (sid_auth->Value[3])
df2a74ce 2081 print_to_screen(" SECURITY_CREATOR_SID_AUTHORITY\n");
cd9e6b16 2082 else if (sid_auth->Value[5])
2083 print_to_screen(" SECURITY_NT_AUTHORITY\n");
2084 else
2085 print_to_screen(" UNKNOWN SID AUTHORITY\n");
2086 subauth_count = GetSidSubAuthorityCount(sid);
2087 print_to_screen(" SidSubAuthorityCount = %d\n",
2088 *subauth_count);
2089 print_to_screen(" SidSubAuthority:\n");
2090 for (i = 0; i < *subauth_count; i++)
2091 {
2092 if ((subauth = GetSidSubAuthority(sid, i)) != NULL)
2093 print_to_screen(" %u\n", *subauth);
2094 }
5d0a7127 2095#endif
cd9e6b16 2096 }
2097 else if ((!memcmp(Attribute, "userAccountControl",
2098 strlen("userAccountControl"))) ||
2099 (!memcmp(Attribute, "sAMAccountType",
2100 strlen("sAmAccountType"))))
2101 {
2102 intValue = atoi(*Ptr);
2103 print_to_screen(" %20s : %ld\n",Attribute, intValue);
df2a74ce 2104
cd9e6b16 2105 if (!memcmp(Attribute, "userAccountControl",
2106 strlen("userAccountControl")))
2107 {
2108 if (intValue & UF_ACCOUNTDISABLE)
2109 print_to_screen(" %20s : %s\n",
2110 "", "Account disabled");
2111 else
2112 print_to_screen(" %20s : %s\n",
2113 "", "Account active");
2114 if (intValue & UF_HOMEDIR_REQUIRED)
2115 print_to_screen(" %20s : %s\n",
2116 "", "Home directory required");
2117 if (intValue & UF_LOCKOUT)
2118 print_to_screen(" %20s : %s\n",
2119 "", "Account locked out");
2120 if (intValue & UF_PASSWD_NOTREQD)
2121 print_to_screen(" %20s : %s\n",
2122 "", "No password required");
2123 if (intValue & UF_PASSWD_CANT_CHANGE)
2124 print_to_screen(" %20s : %s\n",
2125 "", "Cannot change password");
2126 if (intValue & UF_TEMP_DUPLICATE_ACCOUNT)
2127 print_to_screen(" %20s : %s\n",
2128 "", "Temp duplicate account");
2129 if (intValue & UF_NORMAL_ACCOUNT)
2130 print_to_screen(" %20s : %s\n",
2131 "", "Normal account");
2132 if (intValue & UF_INTERDOMAIN_TRUST_ACCOUNT)
2133 print_to_screen(" %20s : %s\n",
2134 "", "Interdomain trust account");
2135 if (intValue & UF_WORKSTATION_TRUST_ACCOUNT)
2136 print_to_screen(" %20s : %s\n",
2137 "", "Workstation trust account");
2138 if (intValue & UF_SERVER_TRUST_ACCOUNT)
2139 print_to_screen(" %20s : %s\n",
2140 "", "Server trust account");
2141 }
2142 }
2143 else
2144 {
2145 print_to_screen(" %20s : %s\n",Attribute, *Ptr);
2146 }
5d0a7127 2147#endif /*LDAP_DEBUG*/
cd9e6b16 2148 }
df2a74ce 2149
5d0a7127 2150 if (str_value != NULL)
cd9e6b16 2151 ldap_value_free(str_value);
df2a74ce 2152
5d0a7127 2153 if (ber_value != NULL)
cd9e6b16 2154 ldap_value_free_len(ber_value);
5d0a7127 2155 }
df2a74ce 2156
5d0a7127 2157 (*linklist_current) = linklist_previous;
df2a74ce 2158
5d0a7127 2159 return(0);
2160}
2161
5d0a7127 2162int moira_connect(void)
2163{
cd9e6b16 2164 long rc;
2165 char HostName[64];
2166
5d0a7127 2167 if (!mr_connections++)
2168 {
df2a74ce 2169
5d0a7127 2170#ifdef _WIN32
2171 memset(HostName, '\0', sizeof(HostName));
2172 strcpy(HostName, "ttsp");
cd9e6b16 2173 rc = mr_connect_cl(HostName, "winad.incr", QUERY_VERSION, 1);
5d0a7127 2174#else
2175 struct utsname uts;
2176 uname(&uts);
cd9e6b16 2177 rc = mr_connect_cl(uts.nodename, "winad.incr", QUERY_VERSION, 1);
5d0a7127 2178#endif /*WIN32*/
df2a74ce 2179
5d0a7127 2180 return rc;
2181 }
df2a74ce 2182
5d0a7127 2183 return 0;
2184}
2185
6a4366ac 2186int check_winad(void)
0d958b3c 2187{
2188 int i;
2189
2190 for (i = 0; file_exists(STOP_FILE); i++)
2191 {
2192 if (i > 30)
2193 {
f75f605a 2194 critical_alert("AD incremental",
f78c7eaf 2195 "WINAD incremental failed (%s exists): %s",
2196 STOP_FILE, tbl_buf);
6a4366ac 2197 return(1);
f78c7eaf 2198 }
df2a74ce 2199
0d958b3c 2200 sleep(60);
2201 }
df2a74ce 2202
6a4366ac 2203 return(0);
0d958b3c 2204}
2205
5d0a7127 2206int moira_disconnect(void)
2207{
5d0a7127 2208
cd9e6b16 2209 if (!--mr_connections)
5d0a7127 2210 {
cd9e6b16 2211 mr_disconnect();
5d0a7127 2212 }
df2a74ce 2213
cd9e6b16 2214 return 0;
5d0a7127 2215}
2216
5d0a7127 2217void get_distinguished_name(LDAP *ldap_handle, LDAPMessage *ldap_entry,
cd9e6b16 2218 char *distinguished_name)
5d0a7127 2219{
cd9e6b16 2220 char *CName;
df2a74ce 2221
5d0a7127 2222 CName = ldap_get_dn(ldap_handle, ldap_entry);
df2a74ce 2223
5d0a7127 2224 if (CName == NULL)
2225 return;
df2a74ce 2226
5d0a7127 2227 strcpy(distinguished_name, CName);
2228 ldap_memfree(CName);
2229}
2230
2231int linklist_create_entry(char *attribute, char *value,
cd9e6b16 2232 LK_ENTRY **linklist_entry)
5d0a7127 2233{
2234 (*linklist_entry) = calloc(1, sizeof(LK_ENTRY));
df2a74ce 2235
5d0a7127 2236 if (!(*linklist_entry))
2237 {
2238 return(1);
2239 }
df2a74ce 2240
5d0a7127 2241 memset((*linklist_entry), '\0', sizeof(LK_ENTRY));
2242 (*linklist_entry)->attribute = calloc(1, strlen(attribute) + 1);
2243 memset((*linklist_entry)->attribute, '\0', strlen(attribute) + 1);
2244 strcpy((*linklist_entry)->attribute, attribute);
2245 (*linklist_entry)->value = calloc(1, strlen(value) + 1);
2246 memset((*linklist_entry)->value, '\0', strlen(value) + 1);
2247 strcpy((*linklist_entry)->value, value);
2248 (*linklist_entry)->length = strlen(value);
2249 (*linklist_entry)->next = NULL;
df2a74ce 2250
5d0a7127 2251 return(0);
2252}
2253
2254void print_to_screen(const char *fmt, ...)
2255{
2256 va_list pvar;
cd9e6b16 2257
5d0a7127 2258 va_start(pvar, fmt);
2259 vfprintf(stderr, fmt, pvar);
2260 fflush(stderr);
2261 va_end(pvar);
2262}
cd9e6b16 2263
2264int get_group_membership(char *group_membership, char *group_ou,
2265 int *security_flag, char **av)
2266{
2267 int maillist_flag;
2268 int group_flag;
df2a74ce 2269
cd9e6b16 2270 maillist_flag = atoi(av[L_MAILLIST]);
2271 group_flag = atoi(av[L_GROUP]);
df2a74ce 2272
cd9e6b16 2273 if (security_flag != NULL)
2274 (*security_flag) = 0;
df2a74ce 2275
cd9e6b16 2276 if ((maillist_flag) && (group_flag))
2277 {
2278 if (group_membership != NULL)
2279 group_membership[0] = 'B';
df2a74ce 2280
cd9e6b16 2281 if (security_flag != NULL)
2282 (*security_flag) = 1;
df2a74ce 2283
cd9e6b16 2284 if (group_ou != NULL)
2285 strcpy(group_ou, group_ou_both);
2286 }
2287 else if ((!maillist_flag) && (group_flag))
2288 {
2289 if (group_membership != NULL)
2290 group_membership[0] = 'S';
df2a74ce 2291
cd9e6b16 2292 if (security_flag != NULL)
2293 (*security_flag) = 1;
df2a74ce 2294
cd9e6b16 2295 if (group_ou != NULL)
2296 strcpy(group_ou, group_ou_security);
2297 }
2298 else if ((maillist_flag) && (!group_flag))
2299 {
2300 if (group_membership != NULL)
2301 group_membership[0] = 'D';
df2a74ce 2302
cd9e6b16 2303 if (group_ou != NULL)
2304 strcpy(group_ou, group_ou_distribution);
2305 }
2306 else
2307 {
2308 if (group_membership != NULL)
2309 group_membership[0] = 'N';
df2a74ce 2310
cd9e6b16 2311 if (group_ou != NULL)
2312 strcpy(group_ou, group_ou_neither);
2313 }
df2a74ce 2314
cd9e6b16 2315 return(0);
2316}
2317
f75f605a 2318int group_rename(LDAP *ldap_handle, char *dn_path,
2319 char *before_group_name, char *before_group_membership,
df2a74ce 2320 char *before_group_ou, int before_security_flag,
2321 char *before_desc, char *after_group_name,
2322 char *after_group_membership, char *after_group_ou,
2323 int after_security_flag, char *after_desc,
2324 char *MoiraId, char *filter, char *maillist)
9db0b148 2325{
2326 LDAPMod *mods[20];
2327 char old_dn[512];
2328 char new_dn[512];
78af4e6e 2329 char new_dn_path[512];
78af4e6e 2330 char sam_name[256];
df2a74ce 2331 char mail[256];
2332 char mail_nickname[256];
2333 char proxy_address[256];
2334 char address_book[256];
9db0b148 2335 char *attr_array[3];
89db421e 2336 char *mitMoiraId_v[] = {NULL, NULL};
9db0b148 2337 char *name_v[] = {NULL, NULL};
78af4e6e 2338 char *samAccountName_v[] = {NULL, NULL};
c76c595a 2339 char *groupTypeControl_v[] = {NULL, NULL};
df2a74ce 2340 char *mail_v[] = {NULL, NULL};
2341 char *proxy_address_v[] = {NULL, NULL};
2342 char *mail_nickname_v[] = {NULL, NULL};
268bfb91 2343 char *report_to_originator_v[] = {NULL, NULL};
df2a74ce 2344 char *address_book_v[] = {NULL, NULL};
2345 char *legacy_exchange_dn_v[] = {NULL, NULL};
2346 u_int groupTypeControl;
c76c595a 2347 char groupTypeControlStr[80];
df2a74ce 2348 char contact_mail[256];
9db0b148 2349 int n;
2350 int i;
2351 int rc;
9db0b148 2352 LK_ENTRY *group_base;
2353 int group_count;
df2a74ce 2354 int MailDisabled = 0;
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 {
4064 critical_alert("AD incremental",
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);
fa8a8b32 5739 com_err(whoami, 0, "AD_GET_GROUP: samname is %s%s", group_name, group_suffix);
89db421e 5740 attr_array[0] = attribute;
5741 attr_array[1] = NULL;
df2a74ce 5742
89db421e 5743 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5744 linklist_base, linklist_count,
5745 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5746 {
4a6e2ee4 5747 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
89db421e 5748 MoiraId, ldap_err2string(rc));
5749 return(rc);
5750 }
df2a74ce 5751
89db421e 5752 if ((*linklist_count) == 1)
5753 {
5754 strcpy(rFilter, filter);
5755 return(0);
5756 }
5757
89db421e 5758 return(0);
5759}
5760
5761int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
5762{
5763 char filter[128];
5764 char *attr_array[3];
5765 char SamAccountName[64];
5766 int group_count;
5767 int rc;
5768 LK_ENTRY *group_base;
c0bd7667 5769 LK_ENTRY *gPtr;
89db421e 5770
5771 group_count = 0;
5772 group_base = NULL;
5773
5774 if (strlen(MoiraId) != 0)
5775 {
c0bd7667 5776 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
89db421e 5777 attr_array[0] = "sAMAccountName";
5778 attr_array[1] = NULL;
5779 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5780 &group_base, &group_count,
5781 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5782 {
4a6e2ee4 5783 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 5784 UserName, ldap_err2string(rc));
5785 return(rc);
5786 }
df2a74ce 5787
c0bd7667 5788 if (group_count > 1)
5789 {
5790 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
5791 MoiraId);
5792 gPtr = group_base;
df2a74ce 5793
c0bd7667 5794 while (gPtr)
5795 {
5796 com_err(whoami, 0, "user %s exist with MoiraId = %s",
5797 gPtr->value, MoiraId);
5798 gPtr = gPtr->next;
5799 }
5800 }
89db421e 5801 }
df2a74ce 5802
c0bd7667 5803 if (group_count != 1)
89db421e 5804 {
c0bd7667 5805 linklist_free(group_base);
5806 group_count = 0;
5807 group_base = NULL;
89db421e 5808 sprintf(filter, "(sAMAccountName=%s)", UserName);
5809 attr_array[0] = "sAMAccountName";
5810 attr_array[1] = NULL;
df2a74ce 5811
89db421e 5812 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 5813 &group_base, &group_count,
5814 LDAP_SCOPE_SUBTREE)) != 0)
89db421e 5815 {
4a6e2ee4 5816 com_err(whoami, 0, "Unable to process user %s : %s",
89db421e 5817 UserName, ldap_err2string(rc));
5818 return(rc);
5819 }
5820 }
5821
5822 if (group_count != 1)
5823 {
5824 linklist_free(group_base);
5825 return(AD_NO_USER_FOUND);
5826 }
df2a74ce 5827
89db421e 5828 strcpy(SamAccountName, group_base->value);
5829 linklist_free(group_base);
5830 group_count = 0;
5831 rc = 0;
df2a74ce 5832
89db421e 5833 if (strcmp(SamAccountName, UserName))
5834 {
5835 rc = user_rename(ldap_handle, dn_path, SamAccountName,
5836 UserName);
5837 }
df2a74ce 5838
89db421e 5839 return(0);
5840}
6c8f12af 5841
5842void container_get_dn(char *src, char *dest)
5843{
5844 char *sPtr;
5845 char *array[20];
5846 char name[256];
5847 int n;
5848
5849 memset(array, '\0', 20 * sizeof(array[0]));
5850
5851 if (strlen(src) == 0)
5852 return;
df2a74ce 5853
6c8f12af 5854 strcpy(name, src);
5855 sPtr = name;
5856 n = 0;
5857 array[n] = name;
5858 ++n;
df2a74ce 5859
6c8f12af 5860 while (*sPtr)
5861 {
5862 if ((*sPtr) == '/')
5863 {
5864 (*sPtr) = '\0';
5865 ++sPtr;
5866 array[n] = sPtr;
5867 ++n;
5868 }
5869 else
5870 ++sPtr;
5871 }
df2a74ce 5872
6c8f12af 5873 strcpy(dest, "OU=");
df2a74ce 5874
6c8f12af 5875 while (n != 0)
5876 {
5877 strcat(dest, array[n-1]);
5878 --n;
5879 if (n > 0)
5880 {
5881 strcat(dest, ",OU=");
5882 }
5883 }
df2a74ce 5884
6c8f12af 5885 return;
5886}
5887
5888void container_get_name(char *src, char *dest)
5889{
5890 char *sPtr;
5891 char *dPtr;
5892
5893 if (strlen(src) == 0)
5894 return;
df2a74ce 5895
6c8f12af 5896 sPtr = src;
5897 dPtr = src;
df2a74ce 5898
6c8f12af 5899 while (*sPtr)
5900 {
5901 if ((*sPtr) == '/')
5902 {
5903 dPtr = sPtr;
5904 ++dPtr;
5905 }
5906 ++sPtr;
5907 }
df2a74ce 5908
6c8f12af 5909 strcpy(dest, dPtr);
5910 return;
5911}
5912
5913void container_check(LDAP *ldap_handle, char *dn_path, char *name)
5914{
5915 char cName[256];
5916 char *av[7];
5917 int i;
5918 int rc;
5919
5920 strcpy(cName, name);
df2a74ce 5921
6c8f12af 5922 for (i = 0; i < (int)strlen(cName); i++)
5923 {
5924 if (cName[i] == '/')
5925 {
5926 cName[i] = '\0';
5927 av[CONTAINER_NAME] = cName;
5928 av[CONTAINER_DESC] = "";
5929 av[CONTAINER_LOCATION] = "";
5930 av[CONTAINER_CONTACT] = "";
5931 av[CONTAINER_TYPE] = "";
5932 av[CONTAINER_ID] = "";
5933 av[CONTAINER_ROWID] = "";
5934 rc = container_create(ldap_handle, dn_path, 7, av);
df2a74ce 5935
6c8f12af 5936 if (rc == LDAP_SUCCESS)
5937 {
df2a74ce 5938 com_err(whoami, 0, "container %s created without a mitMoiraId",
5939 cName);
6c8f12af 5940 }
df2a74ce 5941
6c8f12af 5942 cName[i] = '/';
5943 }
5944 }
6c8f12af 5945}
5946
df2a74ce 5947int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
5948 char **before, int afterc, char **after)
6c8f12af 5949{
5950 char dName[256];
5951 char cName[256];
5952 char new_cn[128];
5953 char new_dn_path[256];
5954 char temp[256];
5955 char distinguishedName[256];
5956 char *pPtr;
5957 int rc;
5958 int i;
5959
5960 memset(cName, '\0', sizeof(cName));
5961 container_get_name(after[CONTAINER_NAME], cName);
df2a74ce 5962
bb52f279 5963 if (!check_container_name(cName))
6c8f12af 5964 {
df2a74ce 5965 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
5966 cName);
6c8f12af 5967 return(AD_INVALID_NAME);
5968 }
5969
5970 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 5971
5972 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
5973 distinguishedName, beforec, before))
6c8f12af 5974 return(rc);
df2a74ce 5975
6c8f12af 5976 if (strlen(distinguishedName) == 0)
5977 {
5978 rc = container_create(ldap_handle, dn_path, afterc, after);
5979 return(rc);
5980 }
5981
5982 strcpy(temp, after[CONTAINER_NAME]);
9cfe334f 5983 pPtr = temp;
df2a74ce 5984
6c8f12af 5985 for (i = 0; i < (int)strlen(temp); i++)
5986 {
5987 if (temp[i] == '/')
5988 {
5989 pPtr = &temp[i];
5990 }
5991 }
df2a74ce 5992
9cfe334f 5993 (*pPtr) = '\0';
6c8f12af 5994
5995 container_get_dn(temp, dName);
df2a74ce 5996
9cfe334f 5997 if (strlen(temp) != 0)
5998 sprintf(new_dn_path, "%s,%s", dName, dn_path);
5999 else
6000 sprintf(new_dn_path, "%s", dn_path);
df2a74ce 6001
6c8f12af 6002 sprintf(new_cn, "OU=%s", cName);
6003
6004 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6005
6006 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6007 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6008 {
4a6e2ee4 6009 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
df2a74ce 6010 before[CONTAINER_NAME], after[CONTAINER_NAME],
6011 ldap_err2string(rc));
6c8f12af 6012 return(rc);
6013 }
6014
6015 memset(dName, '\0', sizeof(dName));
6016 container_get_dn(after[CONTAINER_NAME], dName);
6017 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
df2a74ce 6018
6c8f12af 6019 return(rc);
6020}
6021
6022int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6023{
6024 char distinguishedName[256];
6025 int rc;
6026
6027 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 6028
6029 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6030 distinguishedName, count, av))
6c8f12af 6031 return(rc);
df2a74ce 6032
6c8f12af 6033 if (strlen(distinguishedName) == 0)
6034 return(0);
df2a74ce 6035
6c8f12af 6036 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6037 {
6038 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6039 container_move_objects(ldap_handle, dn_path, distinguishedName);
6040 else
4a6e2ee4 6041 com_err(whoami, 0, "Unable to delete container %s from AD : %s",
6c8f12af 6042 av[CONTAINER_NAME], ldap_err2string(rc));
6043 }
df2a74ce 6044
6c8f12af 6045 return(rc);
6046}
bbef4f93 6047
6c8f12af 6048int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6049{
6050 char *attr_array[3];
6051 LK_ENTRY *group_base;
6052 int group_count;
6053 LDAPMod *mods[20];
6054 char *objectClass_v[] = {"top",
6055 "organizationalUnit",
6056 NULL};
6057
6058 char *ou_v[] = {NULL, NULL};
6059 char *name_v[] = {NULL, NULL};
6060 char *moiraId_v[] = {NULL, NULL};
6061 char *desc_v[] = {NULL, NULL};
6062 char *managedBy_v[] = {NULL, NULL};
6063 char dName[256];
6064 char cName[256];
6065 char managedByDN[256];
6066 char filter[256];
6067 char temp[256];
6068 int n;
6069 int i;
6070 int rc;
6071
6072 memset(filter, '\0', sizeof(filter));
6073 memset(dName, '\0', sizeof(dName));
6074 memset(cName, '\0', sizeof(cName));
6075 memset(managedByDN, '\0', sizeof(managedByDN));
6076 container_get_dn(av[CONTAINER_NAME], dName);
6077 container_get_name(av[CONTAINER_NAME], cName);
6078
6079 if ((strlen(cName) == 0) || (strlen(dName) == 0))
6080 {
df2a74ce 6081 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6082 cName);
6c8f12af 6083 return(AD_INVALID_NAME);
6084 }
6085
bb52f279 6086 if (!check_container_name(cName))
6c8f12af 6087 {
df2a74ce 6088 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6089 cName);
6c8f12af 6090 return(AD_INVALID_NAME);
6091 }
6092
6093 n = 0;
6094 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
6095 name_v[0] = cName;
6096 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
6097 ou_v[0] = cName;
6098 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
df2a74ce 6099
6c8f12af 6100 if (strlen(av[CONTAINER_ROWID]) != 0)
6101 {
6102 moiraId_v[0] = av[CONTAINER_ROWID];
6103 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
6104 }
df2a74ce 6105
6c8f12af 6106 if (strlen(av[CONTAINER_DESC]) != 0)
6107 {
6108 desc_v[0] = av[CONTAINER_DESC];
6109 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
6110 }
df2a74ce 6111
6c8f12af 6112 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6113 {
df2a74ce 6114 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6115 {
6116 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6117 kerberos_ou))
6118 {
6119 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6120 kerberos_ou, dn_path);
6121 managedBy_v[0] = managedByDN;
6122 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6123 }
6124 }
6125 else
6126 {
6127 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6128 {
6129 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6130 "(objectClass=user)))", av[CONTAINER_ID]);
6131 }
6132
6133 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6134 {
6135 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6136 av[CONTAINER_ID]);
6137 }
6138
6139 if (strlen(filter) != 0)
6140 {
6141 attr_array[0] = "distinguishedName";
6142 attr_array[1] = NULL;
6143 group_count = 0;
6144 group_base = NULL;
6145 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6146 attr_array,
6147 &group_base, &group_count,
6148 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6149 {
6150 if (group_count == 1)
6151 {
6152 strcpy(managedByDN, group_base->value);
6153 managedBy_v[0] = managedByDN;
6154 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
6155 }
6156 linklist_free(group_base);
6157 group_base = NULL;
6158 group_count = 0;
6159 }
6160 }
6161 }
6c8f12af 6162 }
df2a74ce 6163
6c8f12af 6164 mods[n] = NULL;
6165
6166 sprintf(temp, "%s,%s", dName, dn_path);
6167 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
df2a74ce 6168
6c8f12af 6169 for (i = 0; i < n; i++)
6170 free(mods[i]);
df2a74ce 6171
6c8f12af 6172 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
6173 {
4a6e2ee4 6174 com_err(whoami, 0, "Unable to create container %s : %s",
6c8f12af 6175 cName, ldap_err2string(rc));
6176 return(rc);
6177 }
df2a74ce 6178
6c8f12af 6179 if (rc == LDAP_ALREADY_EXISTS)
6180 {
6181 if (strlen(av[CONTAINER_ROWID]) != 0)
6182 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
6183 }
df2a74ce 6184
6c8f12af 6185 return(rc);
6186}
6187
df2a74ce 6188int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
6189 char **before, int afterc, char **after)
6c8f12af 6190{
6191 char distinguishedName[256];
6192 int rc;
6193
6194 memset(distinguishedName, '\0', sizeof(distinguishedName));
df2a74ce 6195
6196 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6197 distinguishedName, afterc, after))
6c8f12af 6198 return(rc);
df2a74ce 6199
6c8f12af 6200 if (strlen(distinguishedName) == 0)
6201 {
6202 rc = container_create(ldap_handle, dn_path, afterc, after);
6203 return(rc);
6204 }
df2a74ce 6205
6c8f12af 6206 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
df2a74ce 6207 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
6208 after);
6c8f12af 6209
6210 return(rc);
6211}
6212
df2a74ce 6213int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
6214 char *distinguishedName, int count,
6215 char **av)
6c8f12af 6216{
6217 char *attr_array[3];
6218 LK_ENTRY *group_base;
6219 int group_count;
6220 char dName[256];
6221 char cName[256];
6222 char filter[512];
6223 int rc;
6224
6225 memset(filter, '\0', sizeof(filter));
6226 memset(dName, '\0', sizeof(dName));
6227 memset(cName, '\0', sizeof(cName));
6228 container_get_dn(av[CONTAINER_NAME], dName);
6229 container_get_name(av[CONTAINER_NAME], cName);
6230
6231 if (strlen(dName) == 0)
6232 {
df2a74ce 6233 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6234 av[CONTAINER_NAME]);
6c8f12af 6235 return(AD_INVALID_NAME);
6236 }
6237
bb52f279 6238 if (!check_container_name(cName))
6c8f12af 6239 {
df2a74ce 6240 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6241 cName);
6c8f12af 6242 return(AD_INVALID_NAME);
6243 }
df2a74ce 6244
6245 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6246 av[CONTAINER_ROWID]);
6c8f12af 6247 attr_array[0] = "distinguishedName";
6248 attr_array[1] = NULL;
6249 group_count = 0;
6250 group_base = NULL;
df2a74ce 6251
6c8f12af 6252 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6253 &group_base, &group_count,
6254 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6c8f12af 6255 {
6256 if (group_count == 1)
6257 {
6258 strcpy(distinguishedName, group_base->value);
6259 }
df2a74ce 6260
6c8f12af 6261 linklist_free(group_base);
6262 group_base = NULL;
6263 group_count = 0;
6264 }
df2a74ce 6265
6c8f12af 6266 if (strlen(distinguishedName) == 0)
6267 {
df2a74ce 6268 sprintf(filter, "(&(objectClass=organizationalUnit)"
6269 "(distinguishedName=%s,%s))", dName, dn_path);
6c8f12af 6270 attr_array[0] = "distinguishedName";
6271 attr_array[1] = NULL;
6272 group_count = 0;
6273 group_base = NULL;
df2a74ce 6274
6c8f12af 6275 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6276 &group_base, &group_count,
6277 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6c8f12af 6278 {
6279 if (group_count == 1)
6280 {
6281 strcpy(distinguishedName, group_base->value);
6282 }
df2a74ce 6283
6c8f12af 6284 linklist_free(group_base);
6285 group_base = NULL;
6286 group_count = 0;
6287 }
6288 }
df2a74ce 6289
6c8f12af 6290 return(0);
6291}
6292
6293int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
6294 char *distinguishedName, int count, char **av)
6295{
6296 char *attr_array[5];
6297 LK_ENTRY *group_base;
6298 LK_ENTRY *pPtr;
6299 LDAPMod *mods[20];
6300 int group_count;
6301 char filter[512];
6c8f12af 6302 char *moiraId_v[] = {NULL, NULL};
6303 char *desc_v[] = {NULL, NULL};
6304 char *managedBy_v[] = {NULL, NULL};
6305 char managedByDN[256];
6306 char moiraId[64];
6307 char desc[256];
4a6e2ee4 6308 char ad_path[512];
6c8f12af 6309 int rc;
6310 int i;
6311 int n;
6312
6313
4a6e2ee4 6314 strcpy(ad_path, distinguishedName);
df2a74ce 6315
6c8f12af 6316 if (strlen(dName) != 0)
4a6e2ee4 6317 sprintf(ad_path, "%s,%s", dName, dn_path);
6c8f12af 6318
df2a74ce 6319 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
6320 ad_path);
6321
6c8f12af 6322 if (strlen(av[CONTAINER_ID]) != 0)
df2a74ce 6323 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
6324 av[CONTAINER_ROWID]);
6325
6c8f12af 6326 attr_array[0] = "mitMoiraId";
6327 attr_array[1] = "description";
6328 attr_array[2] = "managedBy";
6329 attr_array[3] = NULL;
6330 group_count = 0;
6331 group_base = NULL;
df2a74ce 6332
6c8f12af 6333 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
df2a74ce 6334 &group_base, &group_count,
6335 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6c8f12af 6336 {
4a6e2ee4 6337 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
6c8f12af 6338 av[CONTAINER_NAME], ldap_err2string(rc));
6339 return(rc);
6340 }
df2a74ce 6341
6c8f12af 6342 memset(managedByDN, '\0', sizeof(managedByDN));
6343 memset(moiraId, '\0', sizeof(moiraId));
6344 memset(desc, '\0', sizeof(desc));
6345 pPtr = group_base;
df2a74ce 6346
6c8f12af 6347 while (pPtr)
6348 {
6349 if (!strcasecmp(pPtr->attribute, "description"))
6350 strcpy(desc, pPtr->value);
9cfe334f 6351 else if (!strcasecmp(pPtr->attribute, "managedBy"))
6c8f12af 6352 strcpy(managedByDN, pPtr->value);
9cfe334f 6353 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
6c8f12af 6354 strcpy(moiraId, pPtr->value);
6355 pPtr = pPtr->next;
6356 }
df2a74ce 6357
6c8f12af 6358 linklist_free(group_base);
6359 group_base = NULL;
6360 group_count = 0;
6361
6362 n = 0;
6363 if (strlen(av[CONTAINER_ROWID]) != 0)
6364 {
6365 moiraId_v[0] = av[CONTAINER_ROWID];
6366 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
6367 }
df2a74ce 6368
6c8f12af 6369 if (strlen(av[CONTAINER_DESC]) != 0)
6370 {
df2a74ce 6371 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
6372 dName);
6c8f12af 6373 }
6374 else
6375 {
6376 if (strlen(desc) != 0)
6377 {
4a6e2ee4 6378 attribute_update(ldap_handle, ad_path, "", "description", dName);
6c8f12af 6379 }
6380 }
df2a74ce 6381
6c8f12af 6382 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
6383 {
df2a74ce 6384 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
6385 {
6386 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
6387 kerberos_ou))
6388 {
6389 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
6390 kerberos_ou, dn_path);
6391 managedBy_v[0] = managedByDN;
6392 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6393 }
6394 else
6395 {
6396 if (strlen(managedByDN) != 0)
6397 {
6398 attribute_update(ldap_handle, ad_path, "", "managedBy",
6399 dName);
6400 }
6401 }
6402 }
6403 else
6404 {
6405 memset(filter, '\0', sizeof(filter));
6406
6407 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
6408 {
6409 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
6410 "(objectClass=user)))", av[CONTAINER_ID]);
6411 }
6412
6413 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
6414 {
6415 sprintf(filter, "(&(objectClass=group)(cn=%s))",
6416 av[CONTAINER_ID]);
6417 }
6418
6419 if (strlen(filter) != 0)
6420 {
6421 attr_array[0] = "distinguishedName";
6422 attr_array[1] = NULL;
6423 group_count = 0;
6424 group_base = NULL;
6425 if ((rc = linklist_build(ldap_handle, dn_path, filter,
6426 attr_array, &group_base, &group_count,
6427 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
6428 {
6429 if (group_count == 1)
6430 {
6431 strcpy(managedByDN, group_base->value);
6432 managedBy_v[0] = managedByDN;
6433 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
6434 }
0eae7c9b 6435 else
df2a74ce 6436 {
6437 if (strlen(managedByDN) != 0)
0eae7c9b 6438 {
df2a74ce 6439 attribute_update(ldap_handle, ad_path, "",
6440 "managedBy", dName);
0eae7c9b 6441 }
df2a74ce 6442 }
6443
6444 linklist_free(group_base);
6445 group_base = NULL;
6446 group_count = 0;
6447 }
6448 }
0eae7c9b 6449 else
df2a74ce 6450 {
6451 if (strlen(managedByDN) != 0)
6452 {
6453 attribute_update(ldap_handle, ad_path, "", "managedBy",
6454 dName);
6455 }
6456 }
6457 }
6c8f12af 6458 }
df2a74ce 6459
6c8f12af 6460 mods[n] = NULL;
df2a74ce 6461
6c8f12af 6462 if (n == 0)
6463 return(LDAP_SUCCESS);
6464
4a6e2ee4 6465 rc = ldap_modify_s(ldap_handle, ad_path, mods);
df2a74ce 6466
6c8f12af 6467 for (i = 0; i < n; i++)
6468 free(mods[i]);
df2a74ce 6469
6c8f12af 6470 if (rc != LDAP_SUCCESS)
6471 {
df2a74ce 6472 com_err(whoami, 0, "Unable to modify container info for %s : %s",
6473 av[CONTAINER_NAME], ldap_err2string(rc));
6474 return(rc);
6c8f12af 6475 }
df2a74ce 6476
6c8f12af 6477 return(rc);
6478}
6479
6480int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
6481{
6482 char *attr_array[3];
6483 LK_ENTRY *group_base;
6484 LK_ENTRY *pPtr;
6485 int group_count;
6486 char filter[512];
6487 char new_cn[128];
6488 char temp[256];
6489 int rc;
6490 int NumberOfEntries = 10;
6491 int i;
6492 int count;
6493
6494 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
6495
6496 for (i = 0; i < 3; i++)
6497 {
6498 memset(filter, '\0', sizeof(filter));
df2a74ce 6499
6c8f12af 6500 if (i == 0)
6501 {
df2a74ce 6502 strcpy(filter, "(!(|(objectClass=computer)"
6503 "(objectClass=organizationalUnit)))");
6c8f12af 6504 attr_array[0] = "cn";
6505 attr_array[1] = NULL;
6506 }
6507 else if (i == 1)
6508 {
6509 strcpy(filter, "(objectClass=computer)");
6510 attr_array[0] = "cn";
6511 attr_array[1] = NULL;
6512 }
6513 else
6514 {
6515 strcpy(filter, "(objectClass=organizationalUnit)");
6516 attr_array[0] = "ou";
6517 attr_array[1] = NULL;
6518 }
6519
6520 while (1)
6521 {
6522 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
df2a74ce 6523 &group_base, &group_count,
6524 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
6c8f12af 6525 {
6526 break;
6527 }
df2a74ce 6528
6c8f12af 6529 if (group_count == 0)
6530 break;
df2a74ce 6531
6c8f12af 6532 pPtr = group_base;
df2a74ce 6533
6c8f12af 6534 while(pPtr)
6535 {
6536 if (!strcasecmp(pPtr->attribute, "cn"))
6537 {
6538 sprintf(new_cn, "cn=%s", pPtr->value);
6539 if (i == 0)
6540 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
6541 if (i == 1)
6542 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
6543 count = 1;
df2a74ce 6544
6c8f12af 6545 while (1)
6546 {
6547 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
6548 TRUE, NULL, NULL);
6549 if (rc == LDAP_ALREADY_EXISTS)
6550 {
6551 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
6552 ++count;
6553 }
6554 else
6555 break;
6556 }
6557 }
6558 else if (!strcasecmp(pPtr->attribute, "ou"))
6559 {
6560 rc = ldap_delete_s(ldap_handle, pPtr->dn);
6561 }
df2a74ce 6562
6c8f12af 6563 pPtr = pPtr->next;
6564 }
df2a74ce 6565
6c8f12af 6566 linklist_free(group_base);
6567 group_base = NULL;
6568 group_count = 0;
6569 }
6570 }
df2a74ce 6571
6c8f12af 6572 return(0);
6573}
5f7b0741 6574
df2a74ce 6575int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
6576 char *machine_ou, char *NewMachineName)
5f7b0741 6577{
6578 LK_ENTRY *group_base;
6579 int group_count;
6580 int i;
6581 char filter[128];
6582 char *attr_array[3];
6583 char cn[256];
6584 char dn[256];
6585 char temp[256];
6586 char *pPtr;
6587 int rc;
6588
3abb4456 6589 strcpy(NewMachineName, member);
cc1e4a1d 6590 rc = moira_connect();
3abb4456 6591 rc = GetMachineName(NewMachineName);
cc1e4a1d 6592 moira_disconnect();
df2a74ce 6593
3abb4456 6594 if (strlen(NewMachineName) == 0)
6595 {
df2a74ce 6596 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6597 member);
3abb4456 6598 return(1);
6599 }
6600
5f7b0741 6601 pPtr = NULL;
3abb4456 6602 pPtr = strchr(NewMachineName, '.');
df2a74ce 6603
5f7b0741 6604 if (pPtr != NULL)
6605 (*pPtr) = '\0';
6606
6607 group_base = NULL;
6608 group_count = 0;
3abb4456 6609 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
5f7b0741 6610 attr_array[0] = "cn";
6611 attr_array[1] = NULL;
6612 sprintf(temp, "%s", dn_path);
df2a74ce 6613
5f7b0741 6614 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
df2a74ce 6615 &group_base, &group_count,
6616 LDAP_SCOPE_SUBTREE)) != 0)
5f7b0741 6617 {
4a6e2ee4 6618 com_err(whoami, 0, "Unable to process machine %s : %s",
5f7b0741 6619 member, ldap_err2string(rc));
6620 return(1);
6621 }
df2a74ce 6622
5f7b0741 6623 if (group_count != 1)
6624 {
df2a74ce 6625 com_err(whoami, 0,
6626 "Unable to process machine %s : machine not found in AD",
3abb4456 6627 NewMachineName);
5f7b0741 6628 return(1);
6629 }
df2a74ce 6630
5f7b0741 6631 strcpy(dn, group_base->dn);
6632 strcpy(cn, group_base->value);
df2a74ce 6633
5f7b0741 6634 for (i = 0; i < (int)strlen(dn); i++)
6635 dn[i] = tolower(dn[i]);
df2a74ce 6636
5f7b0741 6637 for (i = 0; i < (int)strlen(cn); i++)
6638 cn[i] = tolower(cn[i]);
df2a74ce 6639
5f7b0741 6640 linklist_free(group_base);
6641 pPtr = NULL;
6642 pPtr = strstr(dn, cn);
df2a74ce 6643
5f7b0741 6644 if (pPtr == NULL)
6645 {
4a6e2ee4 6646 com_err(whoami, 0, "Unable to process machine %s",
5f7b0741 6647 member);
6648 return(1);
6649 }
df2a74ce 6650
5f7b0741 6651 pPtr += strlen(cn) + 1;
6652 strcpy(machine_ou, pPtr);
6653 pPtr = NULL;
6654 pPtr = strstr(machine_ou, "dc=");
df2a74ce 6655
5f7b0741 6656 if (pPtr == NULL)
6657 {
4a6e2ee4 6658 com_err(whoami, 0, "Unable to process machine %s",
5f7b0741 6659 member);
6660 return(1);
6661 }
df2a74ce 6662
5f7b0741 6663 --pPtr;
6664 (*pPtr) = '\0';
df2a74ce 6665
5f7b0741 6666 return(0);
6667}
bbef4f93 6668
df2a74ce 6669int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
6670 char *MoiraMachineName, char *DestinationOu)
bbef4f93 6671{
df2a74ce 6672 char NewCn[128];
6673 char OldDn[512];
6674 char MachineName[128];
6675 char filter[128];
6676 char *attr_array[3];
6677 char NewOu[256];
6678 char *cPtr = NULL;
6679 int group_count;
6680 long rc;
6681 LK_ENTRY *group_base;
bbef4f93 6682
df2a74ce 6683 group_count = 0;
6684 group_base = NULL;
6685
6686 strcpy(MachineName, MoiraMachineName);
6687 rc = GetMachineName(MachineName);
6688
6689 if (strlen(MachineName) == 0)
6690 {
6691 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
6692 MoiraMachineName);
6693 return(1);
3abb4456 6694 }
df2a74ce 6695
6696 cPtr = strchr(MachineName, '.');
6697
6698 if (cPtr != NULL)
6699 (*cPtr) = '\0';
3abb4456 6700
df2a74ce 6701 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
6702 attr_array[0] = "sAMAccountName";
6703 attr_array[1] = NULL;
6704
6705 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6706 &group_base,
6707 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
bbef4f93 6708 {
df2a74ce 6709 com_err(whoami, 0, "Unable to process machine %s : %s",
6710 MoiraMachineName, ldap_err2string(rc));
6711 return(1);
bbef4f93 6712 }
df2a74ce 6713
6714 if (group_count == 1)
6715 strcpy(OldDn, group_base->dn);
6716
6717 linklist_free(group_base);
6718 group_base = NULL;
bbef4f93 6719
df2a74ce 6720 if (group_count != 1)
bbef4f93 6721 {
df2a74ce 6722 com_err(whoami, 0, "Unable to find machine %s in AD: %s",
6723 MoiraMachineName);
6724 return(1);
bbef4f93 6725 }
df2a74ce 6726
6727 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
6728 cPtr = strchr(OldDn, ',');
6729
6730 if (cPtr != NULL)
bbef4f93 6731 {
df2a74ce 6732 ++cPtr;
6733 if (!strcasecmp(cPtr, NewOu))
6734 return(0);
bbef4f93 6735 }
df2a74ce 6736
6737 sprintf(NewCn, "CN=%s", MachineName);
6738 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
6739
6740 return(rc);
bbef4f93 6741}
6742
6743int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
6744{
df2a74ce 6745 char Name[128];
6746 char *pPtr;
6747 int rc;
6748
6749 memset(Name, '\0', sizeof(Name));
6750 strcpy(Name, machine_name);
6751 pPtr = NULL;
6752 pPtr = strchr(Name, '.');
6753
6754 if (pPtr != NULL)
6755 (*pPtr) = '\0';
6756
6757 strcat(Name, "$");
6758 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
bbef4f93 6759}
6760
df2a74ce 6761int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
6762 char *machine_name, char *container_name)
bbef4f93 6763{
df2a74ce 6764 int rc;
6765 char *av[2];
6766 char *call_args[2];
6767
6768 av[0] = machine_name;
6769 call_args[0] = (char *)container_name;
6770 rc = mr_query("get_machine_to_container_map", 1, av,
6771 machine_GetMoiraContainer, call_args);
6772 return(rc);
bbef4f93 6773}
6774
6775int machine_GetMoiraContainer(int ac, char **av, void *ptr)
6776{
df2a74ce 6777 char **call_args;
6778
6779 call_args = ptr;
6780 strcpy(call_args[0], av[1]);
6781 return(0);
bbef4f93 6782}
6783
209367bd 6784int Moira_container_group_create(char **after)
6785{
6786 long rc;
6787 char GroupName[64];
c7fec834 6788 char *argv[20];
209367bd 6789
6790 memset(GroupName, '\0', sizeof(GroupName));
6791 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
6792 after[CONTAINER_ROWID]);
6793 if (rc)
6794 return rc;
6795
6796 argv[L_NAME] = GroupName;
6797 argv[L_ACTIVE] = "1";
6798 argv[L_PUBLIC] = "0";
6799 argv[L_HIDDEN] = "0";
6800 argv[L_MAILLIST] = "0";
6801 argv[L_GROUP] = "1";
6802 argv[L_GID] = UNIQUE_GID;
6803 argv[L_NFSGROUP] = "0";
3fe96507 6804 argv[L_MAILMAN] = "0";
6805 argv[L_MAILMAN_SERVER] = "[NONE]";
209367bd 6806 argv[L_DESC] = "auto created container group";
6807 argv[L_ACE_TYPE] = "USER";
6808 argv[L_MEMACE_TYPE] = "USER";
6809 argv[L_ACE_NAME] = "sms";
6810 argv[L_MEMACE_NAME] = "sms";
6811
3fe96507 6812 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
209367bd 6813 {
df2a74ce 6814 com_err(whoami, 0,
6815 "Unable to create container group %s for container %s: %s",
209367bd 6816 GroupName, after[CONTAINER_NAME], error_message(rc));
6817 }
6818
6819 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
6820 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
6821
6822 return(rc);
6823}
6824
6825int Moira_container_group_update(char **before, char **after)
6826{
6827 long rc;
6828 char BeforeGroupName[64];
6829 char AfterGroupName[64];
c7fec834 6830 char *argv[20];
209367bd 6831
6832 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
6833 return(0);
6834
6835 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
6836 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
6837 if (strlen(BeforeGroupName) == 0)
6838 return(0);
6839
6840 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
6841 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
6842 after[CONTAINER_ROWID]);
6843 if (rc)
6844 return rc;
6845
6846 if (strcasecmp(BeforeGroupName, AfterGroupName))
6847 {
6848 argv[L_NAME] = BeforeGroupName;
6849 argv[L_NAME + 1] = AfterGroupName;
6850 argv[L_ACTIVE + 1] = "1";
6851 argv[L_PUBLIC + 1] = "0";
50b4a32b 6852 argv[L_HIDDEN + 1] = "0";
209367bd 6853 argv[L_MAILLIST + 1] = "0";
6854 argv[L_GROUP + 1] = "1";
6855 argv[L_GID + 1] = UNIQUE_GID;
6856 argv[L_NFSGROUP + 1] = "0";
3fe96507 6857 argv[L_MAILMAN + 1] = "0";
6858 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
209367bd 6859 argv[L_DESC + 1] = "auto created container group";
6860 argv[L_ACE_TYPE + 1] = "USER";
6861 argv[L_MEMACE_TYPE + 1] = "USER";
6862 argv[L_ACE_NAME + 1] = "sms";
6863 argv[L_MEMACE_NAME + 1] = "sms";
6864
3fe96507 6865 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
209367bd 6866 {
df2a74ce 6867 com_err(whoami, 0,
6868 "Unable to rename container group from %s to %s: %s",
209367bd 6869 BeforeGroupName, AfterGroupName, error_message(rc));
6870 }
6871 }
6872
6873 return(rc);
6874}
6875
6876int Moira_container_group_delete(char **before)
6877{
6878 long rc = 0;
6879 char *argv[13];
6880 char GroupName[64];
6881 char ParentGroupName[64];
6882
6883 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
6884 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
6885
6886 memset(GroupName, '\0', sizeof(GroupName));
df2a74ce 6887
209367bd 6888 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
6889 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
6890
6891 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
6892 {
6893 argv[0] = ParentGroupName;
6894 argv[1] = "LIST";
6895 argv[2] = GroupName;
df2a74ce 6896
209367bd 6897 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
6898 {
df2a74ce 6899 com_err(whoami, 0,
6900 "Unable to delete container group %s from list: %s",
209367bd 6901 GroupName, ParentGroupName, error_message(rc));
6902 }
6903 }
6904
6905 if (strlen(GroupName) != 0)
6906 {
6907 argv[0] = GroupName;
df2a74ce 6908
209367bd 6909 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
6910 {
4a6e2ee4 6911 com_err(whoami, 0, "Unable to delete container group %s : %s",
209367bd 6912 GroupName, error_message(rc));
6913 }
df2a74ce 6914 }
209367bd 6915
6916 return(rc);
6917}
6918
6919int Moira_groupname_create(char *GroupName, char *ContainerName,
6920 char *ContainerRowID)
6921{
6922 char *ptr;
6923 char *ptr1;
6924 char temp[64];
6925 char newGroupName[64];
6926 char tempGroupName[64];
e0e094af 6927 char tempgname[64];
209367bd 6928 char *argv[1];
6929 int i;
6930 long rc;
6931
6932 strcpy(temp, ContainerName);
6933
6934 ptr1 = strrchr(temp, '/');
df2a74ce 6935
209367bd 6936 if (ptr1 != NULL)
e0e094af 6937 {
6938 *ptr1 = '\0';
209367bd 6939 ptr = ++ptr1;
e0e094af 6940 ptr1 = strrchr(temp, '/');
df2a74ce 6941
e0e094af 6942 if (ptr1 != NULL)
6943 {
6944 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
6945 }
6946 else
6947 strcpy(tempgname, ptr);
6948 }
209367bd 6949 else
e0e094af 6950 strcpy(tempgname, temp);
209367bd 6951
e0e094af 6952 if (strlen(tempgname) > 25)
6953 tempgname[25] ='\0';
209367bd 6954
e0e094af 6955 sprintf(newGroupName, "cnt-%s", tempgname);
209367bd 6956
6957 /* change everything to lower case */
6958 ptr = newGroupName;
df2a74ce 6959
209367bd 6960 while (*ptr)
6961 {
6962 if (isupper(*ptr))
6963 *ptr = tolower(*ptr);
df2a74ce 6964
209367bd 6965 if (*ptr == ' ')
6966 *ptr = '-';
df2a74ce 6967
209367bd 6968 ptr++;
6969 }
6970
6971 strcpy(tempGroupName, newGroupName);
6972 i = (int)'0';
df2a74ce 6973
209367bd 6974 /* append 0-9 then a-z if a duplicate is found */
6975 while(1)
6976 {
6977 argv[0] = newGroupName;
df2a74ce 6978
209367bd 6979 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
6980 {
6981 if (rc == MR_NO_MATCH)
6982 break;
df2a74ce 6983 com_err(whoami, 0, "Moira error while creating group name for "
6984 "container %s : %s", ContainerName, error_message(rc));
209367bd 6985 return rc;
6986 }
df2a74ce 6987
209367bd 6988 sprintf(newGroupName, "%s-%c", tempGroupName, i);
df2a74ce 6989
209367bd 6990 if (i == (int)'z')
6991 {
df2a74ce 6992 com_err(whoami, 0, "Unable to find a unique group name for "
6993 "container %s: too many duplicate container names",
209367bd 6994 ContainerName);
6995 return 1;
6996 }
df2a74ce 6997
209367bd 6998 if (i == '9')
6999 i = 'a';
7000 else
7001 i++;
7002 }
7003
7004 strcpy(GroupName, newGroupName);
7005 return(0);
7006}
7007
7008int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7009{
7010 long rc;
7011 char *argv[3];
7012
7013 argv[0] = origContainerName;
7014 argv[1] = GroupName;
df2a74ce 7015
209367bd 7016 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7017 {
df2a74ce 7018 com_err(whoami, 0,
7019 "Unable to set container group %s in container %s: %s",
7020 GroupName, origContainerName, error_message(rc));
209367bd 7021 }
df2a74ce 7022
209367bd 7023 return(0);
7024}
7025
df2a74ce 7026int Moira_addGroupToParent(char *origContainerName, char *GroupName)
209367bd 7027 {
7028 char ContainerName[64];
7029 char ParentGroupName[64];
7030 char *argv[3];
7031 long rc;
7032
7033 strcpy(ContainerName, origContainerName);
df2a74ce 7034
209367bd 7035 Moira_getGroupName(ContainerName, ParentGroupName, 1);
df2a74ce 7036
209367bd 7037 /* top-level container */
7038 if (strlen(ParentGroupName) == 0)
7039 return(0);
7040
7041 argv[0] = ParentGroupName;
7042 argv[1] = "LIST";
7043 argv[2] = GroupName;
df2a74ce 7044
209367bd 7045 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7046 {
df2a74ce 7047 com_err(whoami, 0,
7048 "Unable to add container group %s to parent group %s: %s",
209367bd 7049 GroupName, ParentGroupName, error_message(rc));
7050 }
df2a74ce 7051
209367bd 7052 return(0);
7053 }
7054
7055int Moira_getContainerGroup(int ac, char **av, void *ptr)
7056{
7057 char **call_args;
7058
7059 call_args = ptr;
7060 strcpy(call_args[0], av[1]);
df2a74ce 7061
209367bd 7062 return(0);
7063}
7064
7065int Moira_getGroupName(char *origContainerName, char *GroupName,
7066 int ParentFlag)
7067{
209367bd 7068 char ContainerName[64];
7069 char *argv[3];
7070 char *call_args[3];
7071 char *ptr;
7072 long rc;
7073
7074 strcpy(ContainerName, origContainerName);
7075
7076 if (ParentFlag)
7077 {
7078 ptr = strrchr(ContainerName, '/');
df2a74ce 7079
209367bd 7080 if (ptr != NULL)
7081 (*ptr) = '\0';
7082 else
7083 return(0);
7084 }
7085
7086 argv[0] = ContainerName;
7087 argv[1] = NULL;
7088 call_args[0] = GroupName;
7089 call_args[1] = NULL;
7090
7091 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
7092 call_args)))
7093 {
7094 if (strlen(GroupName) != 0)
7095 return(0);
7096 }
7097
7098 if (rc)
4a6e2ee4 7099 com_err(whoami, 0, "Unable to get container group from container %s: %s",
209367bd 7100 ContainerName, error_message(rc));
7101 else
4a6e2ee4 7102 com_err(whoami, 0, "Unable to get container group from container %s",
209367bd 7103 ContainerName);
df2a74ce 7104
7105 return(0);
209367bd 7106}
7107
7108int Moira_process_machine_container_group(char *MachineName, char* GroupName,
7109 int DeleteMachine)
7110{
7111 char *argv[3];
7112 long rc;
df2a74ce 7113
209367bd 7114 if (strcmp(GroupName, "[none]") == 0)
7115 return 0;
7116
7117 argv[0] = GroupName;
7118 argv[1] = "MACHINE";
7119 argv[2] = MachineName;
df2a74ce 7120
209367bd 7121 if (!DeleteMachine)
7122 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
7123 else
7124 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
df2a74ce 7125
209367bd 7126 if (rc)
7127 {
4a6e2ee4 7128 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
209367bd 7129 MachineName, GroupName, error_message(rc));
7130 }
df2a74ce 7131
209367bd 7132 return(0);
7133}
3abb4456 7134
7135int GetMachineName(char *MachineName)
7136{
df2a74ce 7137 char *args[2];
7138 char NewMachineName[1024];
7139 char *szDot;
7140 int rc = 0;
7141 int i;
7142 DWORD dwLen = 0;
7143 char *call_args[2];
7144
7145 // If the address happens to be in the top-level MIT domain, great!
7146 strcpy(NewMachineName, MachineName);
3abb4456 7147
df2a74ce 7148 for (i = 0; i < (int)strlen(NewMachineName); i++)
7149 NewMachineName[i] = toupper(NewMachineName[i]);
7150
7151 szDot = strchr(NewMachineName,'.');
7152
7153 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
3abb4456 7154 {
df2a74ce 7155 return(0);
3abb4456 7156 }
df2a74ce 7157
7158 // If not, see if it has a Moira alias in the top-level MIT domain.
7159 memset(NewMachineName, '\0', sizeof(NewMachineName));
7160 args[0] = "*";
7161 args[1] = MachineName;
7162 call_args[0] = NewMachineName;
7163 call_args[1] = NULL;
3abb4456 7164
df2a74ce 7165 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
7166 {
7167 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
7168 MachineName, error_message(rc));
7169 strcpy(MachineName, "");
7170 return(0);
7171 }
7172
7173 if (strlen(NewMachineName) != 0)
7174 strcpy(MachineName, NewMachineName);
7175 else
7176 strcpy(MachineName, "");
3abb4456 7177
df2a74ce 7178 return(0);
3abb4456 7179}
7180
7181int ProcessMachineName(int ac, char **av, void *ptr)
7182{
df2a74ce 7183 char **call_args;
7184 char MachineName[1024];
7185 char *szDot;
7186 int i;
7187
7188 call_args = ptr;
3abb4456 7189
df2a74ce 7190 if (strlen(call_args[0]) == 0)
3abb4456 7191 {
df2a74ce 7192 strcpy(MachineName, av[0]);
7193
7194 for (i = 0; i < (int)strlen(MachineName); i++)
7195 MachineName[i] = toupper(MachineName[i]);
7196
7197 szDot = strchr(MachineName,'.');
7198
3abb4456 7199 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
df2a74ce 7200 {
3abb4456 7201 strcpy(call_args[0], MachineName);
df2a74ce 7202 }
3abb4456 7203 }
df2a74ce 7204
7205 return(0);
3abb4456 7206}
7207
7208void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
7209{
df2a74ce 7210 int i;
7211
7212 if (*UseSFU30)
3abb4456 7213 {
df2a74ce 7214 for (i = 0; i < n; i++)
3abb4456 7215 {
df2a74ce 7216 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
7217 mods[i]->mod_type = "uidNumber";
3abb4456 7218 }
df2a74ce 7219
7220 (*UseSFU30) = 0;
3abb4456 7221 }
df2a74ce 7222 else
3abb4456 7223 {
df2a74ce 7224 for (i = 0; i < n; i++)
3abb4456 7225 {
df2a74ce 7226 if (!strcmp(mods[i]->mod_type, "uidNumber"))
7227 mods[i]->mod_type = "msSFU30UidNumber";
3abb4456 7228 }
df2a74ce 7229
7230 (*UseSFU30) = 1;
3abb4456 7231 }
7232}
7233
df2a74ce 7234int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
7235 char *DistinguishedName,
3abb4456 7236 char *WinHomeDir, char *WinProfileDir,
7237 char **homedir_v, char **winProfile_v,
7238 char **drives_v, LDAPMod **mods,
7239 int OpType, int n)
7240{
df2a74ce 7241 char **hp;
7242 char cWeight[3];
7243 char cPath[1024];
7244 char path[1024];
7245 char winPath[1024];
7246 char winProfile[1024];
7247 char homeDrive[8];
7248 int last_weight;
7249 int i;
7250 int rc;
7251 LDAPMod *DelMods[20];
7252
7253 memset(homeDrive, '\0', sizeof(homeDrive));
7254 memset(path, '\0', sizeof(path));
7255 memset(winPath, '\0', sizeof(winPath));
7256 memset(winProfile, '\0', sizeof(winProfile));
7257 hp = NULL;
7258
7259 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
7260 (!strcasecmp(WinProfileDir, "[afs]")))
7261 {
7262 if ((hp = hes_resolve(user_name, "filsys")) != NULL)
3abb4456 7263 {
df2a74ce 7264 memset(cWeight, 0, sizeof(cWeight));
7265 memset(cPath, 0, sizeof(cPath));
7266 last_weight = 1000;
7267 i = 0;
7268
7269 while (hp[i] != NULL)
3abb4456 7270 {
df2a74ce 7271 if (sscanf(hp[i], "%*s %s", cPath))
3abb4456 7272 {
df2a74ce 7273 if (strnicmp(cPath, AFS, strlen(AFS)) == 0)
3abb4456 7274 {
df2a74ce 7275 if (sscanf(hp[i], "%*s %*s %*s %*s %s", cWeight))
3abb4456 7276 {
df2a74ce 7277 if (atoi(cWeight) < last_weight)
3abb4456 7278 {
df2a74ce 7279 strcpy(path, cPath);
7280 last_weight = (int)atoi(cWeight);
3abb4456 7281 }
7282 }
df2a74ce 7283 else
7284 strcpy(path, cPath);
3abb4456 7285 }
7286 }
7287 ++i;
7288 }
df2a74ce 7289
7290 if (strlen(path))
3abb4456 7291 {
df2a74ce 7292 if (!strnicmp(path, AFS, strlen(AFS)))
3abb4456 7293 {
df2a74ce 7294 AfsToWinAfs(path, winPath);
7295 strcpy(winProfile, winPath);
7296 strcat(winProfile, "\\.winprofile");
3abb4456 7297 }
7298 }
7299 }
df2a74ce 7300 else
7301 return(n);
3abb4456 7302 }
7303
df2a74ce 7304 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
7305 (!strcasecmp(WinProfileDir, "[dfs]")))
e0e094af 7306 {
df2a74ce 7307 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
7308 user_name[0], user_name);
e0e094af 7309
df2a74ce 7310 if (!strcasecmp(WinProfileDir, "[dfs]"))
7311 {
7312 strcpy(winProfile, path);
7313 strcat(winProfile, "\\.winprofile");
7314 }
7315
7316 if (!strcasecmp(WinHomeDir, "[dfs]"))
7317 strcpy(winPath, path);
7318 }
7319
3abb4456 7320 if (hp != NULL)
df2a74ce 7321 {
3abb4456 7322 i = 0;
7323 while (hp[i])
df2a74ce 7324 {
3abb4456 7325 free(hp[i]);
7326 i++;
df2a74ce 7327 }
7328 }
7329
3abb4456 7330 if (!strcasecmp(WinHomeDir, "[local]"))
df2a74ce 7331 memset(winPath, '\0', sizeof(winPath));
7332 else if (!strcasecmp(WinHomeDir, "[afs]") ||
7333 !strcasecmp(WinHomeDir, "[dfs]"))
7334 {
3abb4456 7335 strcpy(homeDrive, "H:");
df2a74ce 7336 }
3abb4456 7337 else
df2a74ce 7338 {
3abb4456 7339 strcpy(winPath, WinHomeDir);
7340 if (!strncmp(WinHomeDir, "\\\\", 2))
df2a74ce 7341 {
3abb4456 7342 strcpy(homeDrive, "H:");
df2a74ce 7343 }
7344 }
7345
3abb4456 7346 // nothing needs to be done if WinProfileDir is [afs].
7347 if (!strcasecmp(WinProfileDir, "[local]"))
df2a74ce 7348 memset(winProfile, '\0', sizeof(winProfile));
7349 else if (strcasecmp(WinProfileDir, "[afs]") &&
7350 strcasecmp(WinProfileDir, "[dfs]"))
7351 {
3abb4456 7352 strcpy(winProfile, WinProfileDir);
df2a74ce 7353 }
7354
3abb4456 7355 if (strlen(winProfile) != 0)
df2a74ce 7356 {
3abb4456 7357 if (winProfile[strlen(winProfile) - 1] == '\\')
df2a74ce 7358 winProfile[strlen(winProfile) - 1] = '\0';
7359 }
7360
3abb4456 7361 if (strlen(winPath) != 0)
df2a74ce 7362 {
3abb4456 7363 if (winPath[strlen(winPath) - 1] == '\\')
df2a74ce 7364 winPath[strlen(winPath) - 1] = '\0';
7365 }
7366
3abb4456 7367 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
df2a74ce 7368 strcat(winProfile, "\\");
3abb4456 7369
df2a74ce 7370 if ((winPath[1] == ':') && (strlen(winPath) == 2))
7371 strcat(winPath, "\\");
7372
3abb4456 7373 if (strlen(winPath) == 0)
df2a74ce 7374 {
3abb4456 7375 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7376 {
3abb4456 7377 i = 0;
7378 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
7379 DelMods[i] = NULL;
7380 //unset homeDirectory attribute for user.
7381 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7382 free(DelMods[0]);
df2a74ce 7383 }
7384 }
3abb4456 7385 else
df2a74ce 7386 {
3abb4456 7387 homedir_v[0] = strdup(winPath);
7388 ADD_ATTR("homeDirectory", homedir_v, OpType);
df2a74ce 7389 }
7390
3abb4456 7391 if (strlen(winProfile) == 0)
df2a74ce 7392 {
3abb4456 7393 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7394 {
3abb4456 7395 i = 0;
7396 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
7397 DelMods[i] = NULL;
7398 //unset profilePate attribute for user.
7399 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7400 free(DelMods[0]);
df2a74ce 7401 }
7402 }
3abb4456 7403 else
df2a74ce 7404 {
3abb4456 7405 winProfile_v[0] = strdup(winProfile);
7406 ADD_ATTR("profilePath", winProfile_v, OpType);
df2a74ce 7407 }
7408
3abb4456 7409 if (strlen(homeDrive) == 0)
df2a74ce 7410 {
3abb4456 7411 if (OpType == LDAP_MOD_REPLACE)
df2a74ce 7412 {
3abb4456 7413 i = 0;
7414 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
7415 DelMods[i] = NULL;
7416 //unset homeDrive attribute for user
7417 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
7418 free(DelMods[0]);
df2a74ce 7419 }
7420 }
3abb4456 7421 else
df2a74ce 7422 {
3abb4456 7423 drives_v[0] = strdup(homeDrive);
7424 ADD_ATTR("homeDrive", drives_v, OpType);
df2a74ce 7425 }
3abb4456 7426
7427 return(n);
7428}
d7051053 7429
4a6e2ee4 7430int attribute_update(LDAP *ldap_handle, char *distinguished_name,
df2a74ce 7431 char *attribute_value, char *attribute, char *user_name)
4a6e2ee4 7432{
7433 char *mod_v[] = {NULL, NULL};
7434 LDAPMod *DelMods[20];
7435 LDAPMod *mods[20];
7436 int n;
7437 int i;
7438 int rc;
df2a74ce 7439
4a6e2ee4 7440 if (strlen(attribute_value) == 0)
7441 {
7442 i = 0;
7443 DEL_ATTR(attribute, LDAP_MOD_DELETE);
7444 DelMods[i] = NULL;
7445 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
7446 free(DelMods[0]);
7447 }
df2a74ce 7448 else
4a6e2ee4 7449 {
7450 n = 0;
7451 mod_v[0] = attribute_value;
7452 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
7453 mods[n] = NULL;
df2a74ce 7454
7455 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7456 mods)) != LDAP_SUCCESS)
4a6e2ee4 7457 {
7458 free(mods[0]);
7459 n = 0;
7460 mod_v[0] = attribute_value;
7461 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
7462 mods[n] = NULL;
df2a74ce 7463
7464 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
7465 mods)) != LDAP_SUCCESS)
4a6e2ee4 7466 {
df2a74ce 7467 com_err(whoami, 0, "Unable to change the %s attribute for %s "
7468 "in the AD : %s",
4a6e2ee4 7469 attribute, user_name, ldap_err2string(rc));
7470 }
7471 }
df2a74ce 7472
4a6e2ee4 7473 free(mods[0]);
7474 }
df2a74ce 7475
4a6e2ee4 7476 return(rc);
7477}
26503e15 7478
df2a74ce 7479void StringTrim(char *StringToTrim)
26503e15 7480{
df2a74ce 7481 char *t, *s;
7482 char *save;
26503e15 7483
df2a74ce 7484 save = strdup(StringToTrim);
26503e15 7485
df2a74ce 7486 s = save;
26503e15 7487
df2a74ce 7488 while (isspace(*s))
7489 s++;
26503e15 7490
df2a74ce 7491 /* skip to end of string */
7492 if (*s == '\0')
26503e15 7493 {
df2a74ce 7494 if (*save)
7495 *save = '\0';
7496 strcpy(StringToTrim, save);
7497 return;
26503e15 7498 }
df2a74ce 7499
7500 for (t = s; *t; t++)
7501 continue;
26503e15 7502
df2a74ce 7503 while (t > s)
26503e15 7504 {
df2a74ce 7505 --t;
7506 if (!isspace(*t))
7507 {
7508 t++;
7509 break;
7510 }
26503e15 7511 }
7512
df2a74ce 7513 if (*t)
7514 *t = '\0';
7515
7516 strcpy(StringToTrim, s);
7517 return;
26503e15 7518}
7519
6a4366ac 7520int ReadConfigFile(char *DomainName)
26503e15 7521{
7522 int Count;
7523 int i;
7524 int k;
7525 char temp[256];
7526 char temp1[256];
7527 FILE *fptr;
7528
7529 Count = 0;
7530
6a4366ac 7531 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
df2a74ce 7532
6a4366ac 7533 if ((fptr = fopen(temp, "r")) != NULL)
df2a74ce 7534 {
26503e15 7535 while (fgets(temp, sizeof(temp), fptr) != 0)
df2a74ce 7536 {
26503e15 7537 for (i = 0; i < (int)strlen(temp); i++)
df2a74ce 7538 temp[i] = toupper(temp[i]);
7539
26503e15 7540 if (temp[strlen(temp) - 1] == '\n')
df2a74ce 7541 temp[strlen(temp) - 1] = '\0';
7542
26503e15 7543 StringTrim(temp);
df2a74ce 7544
26503e15 7545 if (strlen(temp) == 0)
df2a74ce 7546 continue;
7547
26503e15 7548 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
df2a74ce 7549 {
26503e15 7550 if (strlen(temp) > (strlen(DOMAIN)))
df2a74ce 7551 {
26503e15 7552 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
7553 StringTrim(ldap_domain);
df2a74ce 7554 }
7555 }
26503e15 7556 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
df2a74ce 7557 {
26503e15 7558 if (strlen(temp) > (strlen(PRINCIPALNAME)))
df2a74ce 7559 {
26503e15 7560 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
7561 StringTrim(PrincipalName);
df2a74ce 7562 }
7563 }
26503e15 7564 else if (!strncmp(temp, SERVER, strlen(SERVER)))
df2a74ce 7565 {
26503e15 7566 if (strlen(temp) > (strlen(SERVER)))
df2a74ce 7567 {
26503e15 7568 ServerList[Count] = calloc(1, 256);
7569 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
7570 StringTrim(ServerList[Count]);
7571 ++Count;
df2a74ce 7572 }
7573 }
26503e15 7574 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
df2a74ce 7575 {
26503e15 7576 if (strlen(temp) > (strlen(MSSFU)))
df2a74ce 7577 {
26503e15 7578 strcpy(temp1, &temp[strlen(MSSFU)]);
7579 StringTrim(temp1);
7580 if (!strcmp(temp1, SFUTYPE))
df2a74ce 7581 UseSFU30 = 1;
7582 }
7583 }
7584 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
7585 {
7586 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
7587 {
7588 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
7589 StringTrim(temp1);
7590 if (!strcasecmp(temp1, "NO"))
7591 {
7592 UseGroupSuffix = 0;
7593 memset(group_suffix, '\0', sizeof(group_suffix));
7594 }
7595 }
7596 }
7597 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
7598 {
7599 if (strlen(temp) > (strlen(GROUP_TYPE)))
7600 {
7601 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
7602 StringTrim(temp1);
7603 if (!strcasecmp(temp1, "UNIVERSAL"))
7604 UseGroupUniversal = 1;
7605 }
7606 }
7607 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
7608 {
7609 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
7610 {
7611 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
7612 StringTrim(temp1);
7613 if (!strcasecmp(temp1, "NO"))
7614 SetGroupAce = 0;
7615 }
7616 }
7617 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
7618 {
7619 if (strlen(temp) > (strlen(SET_PASSWORD)))
7620 {
7621 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
7622 StringTrim(temp1);
7623 if (!strcasecmp(temp1, "NO"))
7624 SetPassword = 0;
7625 }
7626 }
7627 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
7628 {
7629 if (strlen(temp) > (strlen(EXCHANGE)))
7630 {
7631 strcpy(temp1, &temp[strlen(EXCHANGE)]);
7632 StringTrim(temp1);
7633 if (!strcasecmp(temp1, "YES"))
7634 Exchange = 1;
7635 }
7636 }
7637 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
7638 strlen(PROCESS_MACHINE_CONTAINER)))
7639 {
7640 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
7641 {
7642 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
7643 StringTrim(temp1);
7644 if (!strcasecmp(temp1, "NO"))
7645 ProcessMachineContainer = 0;
7646 }
7647 }
26503e15 7648 else
df2a74ce 7649 {
26503e15 7650 if (strlen(ldap_domain) != 0)
df2a74ce 7651 {
26503e15 7652 memset(ldap_domain, '\0', sizeof(ldap_domain));
7653 break;
df2a74ce 7654 }
7655
26503e15 7656 if (strlen(temp) != 0)
df2a74ce 7657 strcpy(ldap_domain, temp);
7658 }
7659 }
26503e15 7660 fclose(fptr);
df2a74ce 7661 }
7662
26503e15 7663 if (strlen(ldap_domain) == 0)
df2a74ce 7664 {
6a4366ac 7665 strcpy(ldap_domain, DomainName);
df2a74ce 7666 }
7667
26503e15 7668 if (Count == 0)
6a4366ac 7669 return(0);
df2a74ce 7670
26503e15 7671 for (i = 0; i < Count; i++)
df2a74ce 7672 {
26503e15 7673 if (ServerList[i] != 0)
df2a74ce 7674 {
26503e15 7675 strcat(ServerList[i], ".");
7676 strcat(ServerList[i], ldap_domain);
7677 for (k = 0; k < (int)strlen(ServerList[i]); k++)
df2a74ce 7678 ServerList[i][k] = toupper(ServerList[i][k]);
7679 }
7680 }
7681
6a4366ac 7682 return(0);
7683}
7684
7685int ReadDomainList()
7686{
7687 int Count;
7688 int i;
7689 char temp[128];
7690 char temp1[128];
7691 FILE *fptr;
7692 unsigned char c[11];
7693 unsigned char stuff[256];
7694 int rc;
7695 int ok;
7696
7697 Count = 0;
7698 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
df2a74ce 7699
6a4366ac 7700 if ((fptr = fopen(temp, "r")) != NULL)
7701 {
7702 while (fgets(temp, sizeof(temp), fptr) != 0)
7703 {
7704 for (i = 0; i < (int)strlen(temp); i++)
7705 temp[i] = toupper(temp[i]);
df2a74ce 7706
6a4366ac 7707 if (temp[strlen(temp) - 1] == '\n')
7708 temp[strlen(temp) - 1] = '\0';
df2a74ce 7709
6a4366ac 7710 StringTrim(temp);
df2a74ce 7711
6a4366ac 7712 if (strlen(temp) == 0)
7713 continue;
df2a74ce 7714
6a4366ac 7715 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
7716 {
7717 if (strlen(temp) > (strlen(DOMAIN)))
7718 {
7719 strcpy(temp1, &temp[strlen(DOMAIN)]);
7720 StringTrim(temp1);
7721 strcpy(temp, temp1);
7722 }
7723 }
df2a74ce 7724
7725 strcpy(DomainNames[Count], temp);
7726 StringTrim(DomainNames[Count]);
7727 ++Count;
6a4366ac 7728 }
df2a74ce 7729
6a4366ac 7730 fclose(fptr);
7731 }
df2a74ce 7732
6a4366ac 7733 if (Count == 0)
7734 {
df2a74ce 7735 critical_alert("incremental", "%s", "winad.incr cannot run due to a "
7736 "configuration error in winad.cfg");
6a4366ac 7737 return(1);
7738 }
df2a74ce 7739
6a4366ac 7740 return(0);
7741}
26503e15 7742
df2a74ce 7743int email_isvalid(const char *address) {
7744 int count = 0;
7745 const char *c, *domain;
7746 static char *rfc822_specials = "()<>@,;:\\\"[]";
7747
7748 if(address[strlen(address) - 1] == '.')
7749 return 0;
7750
7751 /* first we validate the name portion (name@domain) */
7752 for (c = address; *c; c++) {
7753 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
7754 '\"')) {
7755 while (*++c) {
7756 if (*c == '\"')
7757 break;
7758 if (*c == '\\' && (*++c == ' '))
7759 continue;
7760 if (*c <= ' ' || *c >= 127)
7761 return 0;
7762 }
7763
7764 if (!*c++)
7765 return 0;
7766 if (*c == '@')
7767 break;
7768 if (*c != '.')
7769 return 0;
7770 continue;
7771 }
7772
7773 if (*c == '@')
7774 break;
7775 if (*c <= ' ' || *c >= 127)
7776 return 0;
7777 if (strchr(rfc822_specials, *c))
7778 return 0;
7779 }
7780
7781 if (c == address || *(c - 1) == '.')
7782 return 0;
7783
7784 /* next we validate the domain portion (name@domain) */
7785 if (!*(domain = ++c)) return 0;
7786 do {
7787 if (*c == '.') {
7788 if (c == domain || *(c - 1) == '.')
7789 return 0;
7790 count++;
7791 }
7792 if (*c <= ' ' || *c >= 127)
7793 return 0;
7794 if (strchr(rfc822_specials, *c))
7795 return 0;
7796 } while (*++c);
7797
7798 return (count >= 1);
7799}
7800
7801int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
7802 char **homeServerName)
6a4366ac 7803{
df2a74ce 7804 LK_ENTRY *group_base;
7805 LK_ENTRY *sub_group_base;
7806 LK_ENTRY *gPtr;
7807 LK_ENTRY *sub_gPtr;
7808 int group_count;
7809 int sub_group_count;
7810 char filter[1024];
7811 char sub_filter[1024];
7812 char search_path[1024];
7813 char range[1024];
7814 char *attr_array[3];
7815 char *s;
7816 int homeMDB_count = -1;
7817 int rc;
7818 int i;
7819 int mdbbl_count;
7820 int rangeStep = 1500;
7821 int rangeLow = 0;
7822 int rangeHigh = rangeLow + (rangeStep - 1);
7823 int isLast = 0;
7824
7825 /* Grumble..... microsoft not making it searchable from the root *grr* */
7826
7827 memset(filter, '\0', sizeof(filter));
7828 memset(search_path, '\0', sizeof(search_path));
6a4366ac 7829
df2a74ce 7830 sprintf(filter, "(objectClass=msExchMDB)");
7831 sprintf(search_path, "CN=Configuration,%s", dn_path);
7832 attr_array[0] = "distinguishedName";
7833 attr_array[1] = NULL;
7834
7835 group_base = NULL;
7836 group_count = 0;
7837
7838 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
7839 &group_base, &group_count,
7840 LDAP_SCOPE_SUBTREE)) != 0)
6a4366ac 7841 {
df2a74ce 7842 com_err(whoami, 0, "Unable to find msExchMDB %s",
7843 ldap_err2string(rc));
7844 return(rc);
7845 }
7846
7847 if (group_count)
7848 {
7849 gPtr = group_base;
7850
7851 while(gPtr) {
552863f0 7852 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
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.482518 seconds and 5 git commands to generate.