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