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