]> andersk Git - moira.git/blame - incremental/ldap/winad.c
Handle mail routing for users with no pobox.
[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 }
5d55a4bc 4349 } else if(rc==MR_NO_MATCH) {
4350
4351 n = 0;
4352 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_REPLACE);
4353 mods[n] = NULL;
4354 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4355
4356 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
4357 rc = LDAP_SUCCESS;
4358
4359 if(rc)
4360 com_err(whoami, 0,
4361 "Unable to set the mailRoutingAddress for %s : %s",
4362 user_name, ldap_err2string(rc));
61a2844b 4363 }
4364 moira_disconnect();
4365 }
4366
4367 if ((strlen(MitId) != 0) && (MitId[0] == '9'))
4368 rc = attribute_update(ldap_handle, distinguished_name, MitId,
4369 "employeeID", user_name);
4370 else
4371 rc = attribute_update(ldap_handle, distinguished_name, "none",
4372 "employeeID", user_name);
4373
4374 if(strlen(first)) {
4375 strcat(displayName, first);
4376 }
4377
4378 if(strlen(middle)) {
4379 if(strlen(first))
4380 strcat(displayName, " ");
4381
4382 strcat(displayName, middle);
4383 }
4384
4385 if(strlen(last)) {
4386 if(strlen(middle) || strlen(first))
4387 strcat(displayName, " ");
4388
4389 strcat(displayName, last);
4390 }
4391
4392 if(strlen(displayName))
4393 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4394 "displayName", user_name);
4395 else
4396 rc = attribute_update(ldap_handle, distinguished_name, user_name,
4397 "displayName", user_name);
4398
4399 if(!ActiveDirectory)
4400 {
4401 if(strlen(displayName))
4402 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4403 "cn", user_name);
4404 else
4405 rc = attribute_update(ldap_handle, distinguished_name, user_name,
4406 "cn", user_name);
4407 }
4408
4409 if(!ActiveDirectory)
4410 {
4411 rc = attribute_update(ldap_handle, distinguished_name, displayName,
4412 "eduPersonNickname", user_name);
4413 }
4414
4415 if(strlen(first))
4416 rc = attribute_update(ldap_handle, distinguished_name, first,
4417 "givenName", user_name);
4418 else
4419 rc = attribute_update(ldap_handle, distinguished_name, "",
4420 "givenName", user_name);
4421
4422 if(strlen(middle) == 1)
4423 rc = attribute_update(ldap_handle, distinguished_name, middle,
4424 "initials", user_name);
4425 else
4426 rc = attribute_update(ldap_handle, distinguished_name, "",
4427 "initials", user_name);
4428
4429 if(strlen(last))
4430 rc = attribute_update(ldap_handle, distinguished_name, last,
4431 "sn", user_name);
4432 else
4433 rc = attribute_update(ldap_handle, distinguished_name, "",
4434 "sn", user_name);
4435
4436 if(ActiveDirectory)
4437 {
4438 rc = attribute_update(ldap_handle, distinguished_name, Uid, "uid",
4439 user_name);
4440 }
4441 else
4442 {
4443 rc = attribute_update(ldap_handle, distinguished_name, user_name, "uid",
4444 user_name);
4445 }
4446
4447 rc = attribute_update(ldap_handle, distinguished_name, MoiraId,
4448 "mitMoiraId", user_name);
4449
4450 n = 0;
4451 uid_v[0] = Uid;
4452
4453 if(ActiveDirectory)
4454 {
4455 if (!UseSFU30)
4456 {
4457 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4458 }
4459 else
4460 {
4461 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_REPLACE);
4462 }
4463 }
4464 else
4465 {
4466 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4467 sprintf(status, "%d", State);
4468 principal_v[0] = principal;
4469 loginshell_v[0] = shell;
4470 mitMoiraClass_v[0] = class;
4471 mitMoiraStatus_v[0] = status;
4472 gid_v[0] = "101";
4473 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_REPLACE);
4474 ADD_ATTR("gidNumber", gid_v, LDAP_MOD_REPLACE);
4475 ADD_ATTR("loginShell", loginshell_v, LDAP_MOD_REPLACE);
4476 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_REPLACE);
4477 ADD_ATTR("mitMoiraClass", mitMoiraClass_v, LDAP_MOD_REPLACE);
4478 ADD_ATTR("mitMoiraStatus", mitMoiraStatus_v, LDAP_MOD_REPLACE);
4479 }
4480
4481 if ((State != US_NO_PASSWD) && (State != US_REGISTERED))
4482 {
4483 userAccountControl |= UF_ACCOUNTDISABLE;
4484
4485 if (Exchange)
4486 {
4487 hide_address_lists_v[0] = "TRUE";
4488 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4489 LDAP_MOD_REPLACE);
4490 }
4491 }
4492 else
4493 {
4494 if (Exchange)
4495 {
4496 hide_address_lists_v[0] = NULL;
4497 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4498 LDAP_MOD_REPLACE);
4499 }
4500 }
4501
4502 sprintf(userAccountControlStr, "%ld", userAccountControl);
4503 userAccountControl_v[0] = userAccountControlStr;
4504 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_REPLACE);
4505
4506 if (Exchange)
4507 {
4508 if (rc = moira_connect())
4509 {
a816420b 4510 critical_alert(whoami, "Ldap incremental",
61a2844b 4511 "Error contacting Moira server : %s",
4512 error_message(rc));
4513 return;
4514 }
4515
4516 argv[0] = user_name;
4517
4518 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
4519 {
4520 if(!strcmp(save_argv[1], "EXCHANGE") ||
4521 (strstr(save_argv[3], search_string) != NULL))
4522 {
4523 alt_recipient_v[0] = NULL;
4524 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4525
4526 argv[0] = exchange_acl;
4527 argv[1] = "USER";
4528 argv[2] = user_name;
4529
4530 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
4531
4532 if ((rc) && (rc != MR_EXISTS))
4533 {
4534 com_err(whoami, 0, "Unable to add user %s to %s: %s",
4535 user_name, exchange_acl, error_message(rc));
4536 }
4537 }
4538 else
4539 {
4540 alt_recipient_v[0] = alt_recipient;
4541 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4542
4543 argv[0] = exchange_acl;
4544 argv[1] = "USER";
4545 argv[2] = user_name;
4546
4547 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4548
4549 if ((rc) && (rc != MR_NO_MATCH))
4550 {
4551 com_err(whoami, 0,
4552 "Unable to remove user %s from %s: %s, %d",
4553 user_name, exchange_acl, error_message(rc), rc);
4554 }
4555 }
4556 }
4557 else
4558 {
4559 alt_recipient_v[0] = alt_recipient;
4560 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_REPLACE);
4561
4562 argv[0] = exchange_acl;
4563 argv[1] = "USER";
4564 argv[2] = user_name;
4565
4566 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
4567
4568 if ((rc) && (rc != MR_NO_MATCH))
4569 {
4570 com_err(whoami, 0,
4571 "Unable to remove user %s from %s: %s, %d",
4572 user_name, exchange_acl, error_message(rc), rc);
4573 }
4574 }
4575
4576 moira_disconnect();
4577 }
4578 else
4579 {
4580 mail_v[0] = contact_mail;
4581 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
08ca7a3e 4582
4583 if(!ActiveDirectory)
4584 {
4585 ADD_ATTR("mitMoiraMail", mail_v, LDAP_MOD_REPLACE);
4586 }
61a2844b 4587 }
4588
4589 n = SetHomeDirectory(ldap_handle, user_name, distinguished_name, WinHomeDir,
4590 WinProfileDir, homedir_v, winProfile_v,
4591 drives_v, mods, LDAP_MOD_REPLACE, n);
4592
4593 if(ActiveDirectory)
4594 {
4595 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
4596 sprintf(search_path, "%s,%s", security_template_ou, dn_path);
4597 attr_array[0] = "sAMAccountName";
4598 attr_array[1] = NULL;
4599 group_count = 0;
4600 group_base = NULL;
4601
4602 if ((rc = linklist_build(ldap_handle, search_path, filter_exp,
4603 attr_array,
4604 &group_base, &group_count,
4605 LDAP_SCOPE_SUBTREE) != 0))
4606 return(1);
4607
4608 if (group_count != 1)
4609 {
4610 com_err(whoami, 0, "Unable to process user security template: %s - "
4611 "security not set", "UserTemplate.u");
4612 return(1);
4613 }
4614
4615 strcpy(TemplateDn, group_base->dn);
4616 strcpy(TemplateSamName, group_base->value);
4617 linklist_free(group_base);
4618 group_base = NULL;
4619 group_count = 0;
4620
4621 rc = ldap_search_ext_s(ldap_handle, search_path, LDAP_SCOPE_SUBTREE,
4622 filter_exp, NULL, 0, apsServerControls, NULL,
4623 NULL, 0, &psMsg);
4624
4625 if ((psMsg = ldap_first_entry(ldap_handle, psMsg)) == NULL)
4626 {
4627 com_err(whoami, 0, "Unable to find user security template: %s - "
4628 "security not set", "UserTemplate.u");
4629 return(1);
4630 }
4631
4632 ppsValues = ldap_get_values_len(ldap_handle, psMsg,
4633 "ntSecurityDescriptor");
4634
4635 if (ppsValues == NULL)
4636 {
4637 com_err(whoami, 0, "Unable to find user security template: %s - "
4638 "security not set", "UserTemplate.u");
4639 return(1);
4640 }
4641
4642 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
4643 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
4644 }
4645
4646 mods[n] = NULL;
4647
4648 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
4649 mods)) != LDAP_SUCCESS)
4650 {
4651 OldUseSFU30 = UseSFU30;
4652 SwitchSFU(mods, &UseSFU30, n);
4653 if (OldUseSFU30 != UseSFU30)
4654 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
4655 if (rc)
4656 {
4657 com_err(whoami, 0, "Unable to modify user data for %s : %s",
4658 user_name, ldap_err2string(rc));
4659 }
4660 }
4661
4662 for (i = 0; i < n; i++)
4663 free(mods[i]);
4664
4665 return(rc);
4666}
4667
4668int user_rename(LDAP *ldap_handle, char *dn_path, char *before_user_name,
4669 char *user_name)
4670{
4671 LDAPMod *mods[20];
4672 char new_dn[256];
4673 char old_dn[256];
4674 char upn[256];
4675 char mail[256];
4676 char contact_mail[256];
4677 char proxy_address[256];
4678 char query_base_dn[256];
4679 char temp[256];
4680 char *userPrincipalName_v[] = {NULL, NULL};
4681 char *altSecurityIdentities_v[] = {NULL, NULL};
4682 char *name_v[] = {NULL, NULL};
4683 char *samAccountName_v[] = {NULL, NULL};
4684 char *mail_v[] = {NULL, NULL};
4685 char *mail_nickname_v[] = {NULL, NULL};
4686 char *proxy_address_v[] = {NULL, NULL};
4687 char *query_base_dn_v[] = {NULL, NULL};
4688 char *principal_v[] = {NULL, NULL};
4689 char principal[256];
4690 int n;
4691 int rc;
4692 int i;
4693
4694 if (!check_string(before_user_name))
4695 {
4696 com_err(whoami, 0,
4697 "Unable to process invalid LDAP user name %s", before_user_name);
4698 return(AD_INVALID_NAME);
4699 }
4700
4701 if (!check_string(user_name))
4702 {
4703 com_err(whoami, 0,
4704 "Unable to process invalid LDAP user name %s", user_name);
4705 return(AD_INVALID_NAME);
4706 }
4707
4708 strcpy(user_name, user_name);
4709
4710 if(ActiveDirectory)
4711 sprintf(old_dn, "cn=%s,%s,%s", before_user_name, user_ou, dn_path);
4712 else
4713 sprintf(old_dn, "uid=%s,%s,%s", before_user_name, user_ou, dn_path);
4714
4715 if(ActiveDirectory)
4716 sprintf(new_dn, "cn=%s", user_name);
4717 else
4718 sprintf(new_dn, "uid=%s", user_name);
4719
4720 sprintf(mail, "%s@%s", user_name, lowercase(ldap_domain));
4721 sprintf(contact_mail, "%s@mit.edu", user_name);
4722 sprintf(proxy_address, "SMTP:%s@%s", user_name, lowercase(ldap_domain));
4723 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4724
4725 if ((rc = ldap_rename_s(ldap_handle, old_dn, new_dn, NULL, TRUE,
4726 NULL, NULL)) != LDAP_SUCCESS)
4727 {
4728 com_err(whoami, 0, "Unable to rename user from %s to %s : %s",
4729 before_user_name, user_name, ldap_err2string(rc));
4730 return(rc);
4731 }
4732
4733 if (Exchange)
4734 {
4735 sprintf(temp, "cn=%s@mit.edu,%s,%s", before_user_name, contact_ou,
4736 dn_path);
4737
4738 if(rc = ldap_delete_s(ldap_handle, temp))
4739 {
4740 com_err(whoami, 0, "Unable to delete user contact for %s",
4741 user_name);
4742 }
4743
4744 if(contact_create(ldap_handle, dn_path, contact_mail, contact_ou))
4745 {
4746 com_err(whoami, 0, "Unable to create user contact %s", contact_mail);
4747 }
4748 }
4749
4750 name_v[0] = user_name;
4751 sprintf(upn, "%s@%s", user_name, ldap_domain);
4752 userPrincipalName_v[0] = upn;
4753 principal_v[0] = principal;
4754 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4755 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, dn_path);
4756 altSecurityIdentities_v[0] = temp;
4757 samAccountName_v[0] = user_name;
4758 mail_v[0] = mail;
4759 mail_nickname_v[0] = user_name;
4760 proxy_address_v[0] = proxy_address;
4761 query_base_dn_v[0] = query_base_dn;
4762
4763 n = 0;
4764 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_REPLACE);
4765 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_REPLACE);
4766 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4767 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_REPLACE);
4768
4769 if(!ActiveDirectory)
4770 {
4771 ADD_ATTR("uid", samAccountName_v, LDAP_MOD_REPLACE);
4772 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_REPLACE);
4773 ADD_ATTR("displayName", name_v, LDAP_MOD_REPLACE);
4774 ADD_ATTR("eduPersonNickname", name_v, LDAP_MOD_REPLACE);
4775 }
4776
4777 if (Exchange)
4778 {
4779 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_REPLACE);
4780 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_REPLACE);
4781 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
4782 ADD_ATTR("proxyAddresses", proxy_address_v, LDAP_MOD_REPLACE);
4783 }
4784 else
4785 {
4786 mail_v[0] = contact_mail;
4787 ADD_ATTR("mail", mail_v, LDAP_MOD_REPLACE);
08ca7a3e 4788
4789 if(!ActiveDirectory)
4790 {
4791 ADD_ATTR("mitMoiraMail", mail_v, LDAP_MOD_REPLACE);
4792 }
61a2844b 4793 }
4794
4795 mods[n] = NULL;
4796
4797 if(ActiveDirectory)
4798 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, dn_path);
4799 else
4800 sprintf(new_dn, "uid=%s,%s,%s", user_name, user_ou, dn_path);
4801
4802 if ((rc = ldap_modify_s(ldap_handle, new_dn, mods)) != LDAP_SUCCESS)
4803 {
4804 com_err(whoami, 0,
4805 "Unable to modify user data for %s after renaming : %s",
4806 user_name, ldap_err2string(rc));
4807 }
4808
4809 for (i = 0; i < n; i++)
4810 free(mods[i]);
4811
4812 return(rc);
4813}
4814
4815int user_create(int ac, char **av, void *ptr)
4816{
4817 LDAPMod *mods[20];
4818 char new_dn[256];
4819 char user_name[256];
4820 char sam_name[256];
4821 char upn[256];
4822 char mail[256];
4823 char contact_mail[256];
4824 char proxy_address[256];
4825 char mail_nickname[256];
4826 char query_base_dn[256];
4827 char displayName[256];
4828 char address_book[256];
4829 char alt_recipient[256];
4830 char *cn_v[] = {NULL, NULL};
4831 char *objectClass_v[] = {"top", "person", "organizationalPerson",
4832 "user", NULL};
4833 char *objectClass_ldap_v[] = {"top",
4834 "eduPerson", "posixAccount",
4835 "apple-user", "shadowAccount",
4836 "microsoftComTop", "securityPrincipal",
4837 "inetOrgPerson", "user",
4838 "organizationalPerson", "person",
4839 "mailRecipient", NULL};
4840
4841 char *samAccountName_v[] = {NULL, NULL};
4842 char *altSecurityIdentities_v[] = {NULL, NULL};
4843 char *mitMoiraId_v[] = {NULL, NULL};
4844 char *mitMoiraClass_v[] = {NULL, NULL};
4845 char *mitMoiraStatus_v[] = {NULL, NULL};
4846 char *name_v[] = {NULL, NULL};
4847 char *desc_v[] = {NULL, NULL};
4848 char *userPrincipalName_v[] = {NULL, NULL};
4849 char *userAccountControl_v[] = {NULL, NULL};
4850 char *uid_v[] = {NULL, NULL};
4851 char *gid_v[] = {NULL, NULL};
4852 char *mitid_v[] = {NULL, NULL};
4853 char *homedir_v[] = {NULL, NULL};
4854 char *winProfile_v[] = {NULL, NULL};
4855 char *drives_v[] = {NULL, NULL};
4856 char *mail_v[] = {NULL, NULL};
4857 char *givenName_v[] = {NULL, NULL};
4858 char *sn_v[] = {NULL, NULL};
4859 char *initials_v[] = {NULL, NULL};
4860 char *displayName_v[] = {NULL, NULL};
4861 char *proxy_address_v[] = {NULL, NULL};
4862 char *mail_nickname_v[] = {NULL, NULL};
4863 char *query_base_dn_v[] = {NULL, NULL};
4864 char *address_book_v[] = {NULL, NULL};
4865 char *homeMDB_v[] = {NULL, NULL};
4866 char *homeServerName_v[] = {NULL, NULL};
4867 char *mdbUseDefaults_v[] = {NULL, NULL};
4868 char *mailbox_guid_v[] = {NULL, NULL};
4869 char *user_culture_v[] = {NULL, NULL};
4870 char *user_account_control_v[] = {NULL, NULL};
4871 char *msexch_version_v[] = {NULL, NULL};
4872 char *alt_recipient_v[] = {NULL, NULL};
4873 char *hide_address_lists_v[] = {NULL, NULL};
4874 char *principal_v[] = {NULL, NULL};
4875 char *loginshell_v[] = {NULL, NULL};
4876 char userAccountControlStr[80];
4877 char temp[1024];
4878 char principal[256];
4879 char filter_exp[1024];
4880 char search_path[512];
4881 char *attr_array[3];
4882 u_int userAccountControl = UF_NORMAL_ACCOUNT | UF_DONT_EXPIRE_PASSWD |
4883 UF_PASSWD_CANT_CHANGE;
4884 int n;
4885 int rc;
4886 int i;
4887 int OldUseSFU30;
4888 char **call_args;
4889 char WinHomeDir[1024];
4890 char WinProfileDir[1024];
4891 char *homeMDB;
4892 char *homeServerName;
4893 ULONG dwInfo;
4894 char acBERBuf[N_SD_BER_BYTES];
4895 LK_ENTRY *group_base;
4896 int group_count;
4897 char TemplateDn[512];
4898 char TemplateSamName[128];
4899 LDAP_BERVAL **ppsValues;
4900 LDAPControl sControl = {"1.2.840.113556.1.4.801",
4901 { N_SD_BER_BYTES, acBERBuf },
4902 TRUE};
4903 LDAPControl *apsServerControls[] = {&sControl, NULL};
4904 LDAPMessage *psMsg;
4905 char *argv[3];
4906 char *save_argv[7];
4907 char search_string[256];
4908 char *o_v[] = {NULL, NULL};
4909 char *p, *q;
4910 char *mail_routing_v[] = {NULL, NULL};
4911 char *c;
4912
4913 call_args = ptr;
4914
4915 dwInfo = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
4916 DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION;
4917 BEREncodeSecurityBits(dwInfo, acBERBuf);
4918
4919 if (!check_string(av[U_NAME]))
4920 {
4921 callback_rc = AD_INVALID_NAME;
4922 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
4923 av[U_NAME]);
4924 return(AD_INVALID_NAME);
4925 }
4926
4927 memset(WinHomeDir, '\0', sizeof(WinHomeDir));
4928 memset(WinProfileDir, '\0', sizeof(WinProfileDir));
4929 memset(displayName, '\0', sizeof(displayName));
4930 memset(query_base_dn, '\0', sizeof(query_base_dn));
4931 strcpy(WinHomeDir, av[U_WINHOMEDIR]);
4932 strcpy(WinProfileDir, av[U_WINPROFILEDIR]);
4933 strcpy(user_name, av[U_NAME]);
4934 sprintf(upn, "%s@%s", user_name, ldap_domain);
4935 sprintf(sam_name, "%s", av[U_NAME]);
4936
4937 if(strlen(av[U_FIRST])) {
4938 strcat(displayName, av[U_FIRST]);
4939 }
4940
4941 if(strlen(av[U_MIDDLE])) {
4942 if(strlen(av[U_FIRST]))
4943 strcat(displayName, " ");
4944
4945 strcat(displayName, av[U_MIDDLE]);
4946 }
4947
4948 if(strlen(av[U_LAST])) {
4949 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]))
4950 strcat(displayName, " ");
4951
4952 strcat(displayName, av[U_LAST]);
4953 }
4954
4955 samAccountName_v[0] = sam_name;
4956 if ((atoi(av[U_STATE]) != US_NO_PASSWD) &&
4957 (atoi(av[U_STATE]) != US_REGISTERED))
4958 {
4959 userAccountControl |= UF_ACCOUNTDISABLE;
4960
4961 if (Exchange)
4962 {
4963 hide_address_lists_v[0] = "TRUE";
4964 ADD_ATTR("msExchHideFromAddressLists", hide_address_lists_v,
4965 LDAP_MOD_ADD);
4966 }
4967 }
4968
4969 sprintf(userAccountControlStr, "%ld", userAccountControl);
4970 userAccountControl_v[0] = userAccountControlStr;
4971 userPrincipalName_v[0] = upn;
4972
4973 if(ActiveDirectory)
4974 cn_v[0] = user_name;
4975 else
4976 cn_v[0] = displayName;
4977
4978 name_v[0] = user_name;
4979 desc_v[0] = "Auto account created by Moira";
4980 mail_v[0] = mail;
4981 givenName_v[0] = av[U_FIRST];
4982
4983 if(ActiveDirectory)
4984 sn_v[0] = av[U_LAST];
4985 else
4986 if(strlen(av[U_LAST]))
4987 sn_v[0] = av[U_LAST];
4988 else
4989 sn_v[0] = av[U_NAME];
4990
4991 displayName_v[0] = displayName;
4992 mail_nickname_v[0] = user_name;
4993 o_v[0] = "Massachusetts Institute of Technology";
4994
4995 sprintf(temp, "Kerberos:%s@%s", user_name, PRIMARY_REALM);
4996 sprintf(principal, "%s@%s", user_name, PRIMARY_REALM);
4997 altSecurityIdentities_v[0] = temp;
4998 principal_v[0] = principal;
4999
5000 if(ActiveDirectory)
5001 sprintf(new_dn, "cn=%s,%s,%s", user_name, user_ou, call_args[1]);
5002 else
5003 sprintf(new_dn, "uid=%s,%s,%s", user_name, user_ou, call_args[1]);
5004
5005 sprintf(mail,"%s@%s", user_name, lowercase(ldap_domain));
5006 sprintf(contact_mail, "%s@mit.edu", user_name);
5007 sprintf(query_base_dn, "%s%s", ADDRESS_LIST_PREFIX, call_args[1]);
5008 query_base_dn_v[0] = query_base_dn;
5009 sprintf(alt_recipient, "cn=%s@mit.edu,%s,%s", user_name, contact_ou,
5010 call_args[1]);
5011 sprintf(search_string, "@%s", uppercase(ldap_domain));
5012
5013 if (Exchange)
5014 {
5015 if(contact_create((LDAP *)call_args[0], call_args[1], contact_mail,
5016 contact_ou))
5017 {
5018 com_err(whoami, 0, "Unable to create user contact %s",
5019 contact_mail);
5020 }
5021
5022 if(find_homeMDB((LDAP *)call_args[0], call_args[1], &homeMDB,
5023 &homeServerName))
5024 {
5025 com_err(whoami, 0, "Unable to locate homeMB and homeServerName");
5026 return(1);
5027 }
5028
5029 com_err(whoami, 0, "homeMDB:%s", homeMDB);
5030 com_err(whoami, 0, "homeServerName:%s", homeServerName);
5031
5032 homeMDB_v[0] = homeMDB;
5033 homeServerName_v[0] = homeServerName;
5034 }
5035
5036 n = 0;
5037
5038 ADD_ATTR("cn", cn_v, LDAP_MOD_ADD);
5039
5040 if(ActiveDirectory)
5041 {
5042 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
5043 }
5044 else
5045 {
5046 ADD_ATTR("objectClass", objectClass_ldap_v, LDAP_MOD_ADD);
5047 }
5048
5049 ADD_ATTR("sAMAccountName", samAccountName_v, LDAP_MOD_ADD);
5050 ADD_ATTR("userPrincipalName", userPrincipalName_v, LDAP_MOD_ADD);
5051 ADD_ATTR("userAccountControl", userAccountControl_v, LDAP_MOD_ADD);
5052 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
5053 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
5054
5055 if (Exchange)
5056 {
5057 ADD_ATTR("msExchQueryBaseDN", query_base_dn_v, LDAP_MOD_ADD);
5058 ADD_ATTR("mailNickName", mail_nickname_v, LDAP_MOD_ADD);
5059 ADD_ATTR("homeMDB", homeMDB_v, LDAP_MOD_ADD);
5060 mdbUseDefaults_v[0] = "TRUE";
5061 ADD_ATTR("mdbUseDefaults", mdbUseDefaults_v, LDAP_MOD_ADD);
5062 ADD_ATTR("msExchHomeServerName", homeServerName_v, LDAP_MOD_ADD);
5063
5064 argv[0] = user_name;
5065
5066 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
5067 {
5068 if(!strcmp(save_argv[1], "EXCHANGE") ||
5069 (strstr(save_argv[3], search_string) != NULL))
5070 {
5071 argv[0] = exchange_acl;
5072 argv[1] = "USER";
5073 argv[2] = user_name;
5074
5075 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
5076
5077 if ((rc) && (rc != MR_EXISTS))
5078 {
5079 com_err(whoami, 0, "Unable to add user %s to %s: %s",
5080 user_name, exchange_acl, error_message(rc));
5081 }
5082 }
5083 else
5084 {
5085 alt_recipient_v[0] = alt_recipient;
5086 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
5087 }
5088 }
5089 else
5090 {
5091 alt_recipient_v[0] = alt_recipient;
5092 ADD_ATTR("altRecipient", alt_recipient_v, LDAP_MOD_ADD);
5093
5094 com_err(whoami, 0, "Unable to fetch pobox for %s", user_name);
5095 }
5096 }
5097 else
5098 {
5099 mail_v[0] = contact_mail;
5100 ADD_ATTR("mail", mail_v, LDAP_MOD_ADD);
08ca7a3e 5101
5102 if(!ActiveDirectory)
5103 {
5104 ADD_ATTR("mitMoiraMail", mail_v, LDAP_MOD_ADD);
5105 }
61a2844b 5106 }
5107
5108 if(strlen(av[U_FIRST])) {
5109 ADD_ATTR("givenName", givenName_v, LDAP_MOD_ADD);
5110 }
5111
5112 if(strlen(av[U_LAST]) || strlen(av[U_NAME])) {
5113 ADD_ATTR("sn", sn_v, LDAP_MOD_ADD);
5114 }
5115
5116 if(strlen(av[U_FIRST]) || strlen(av[U_MIDDLE]) || strlen(av[U_LAST])) {
5117 ADD_ATTR("displayName", displayName_v, LDAP_MOD_ADD);
5118
5119 if(!ActiveDirectory)
5120 {
5121 ADD_ATTR("eduPersonNickname", displayName_v, LDAP_MOD_ADD);
5122 }
5123 } else {
5124 ADD_ATTR("displayName", name_v, LDAP_MOD_ADD);
5125
5126 if(!ActiveDirectory)
5127 {
5128 ADD_ATTR("eduPersonNickname", name_v, LDAP_MOD_ADD);
5129 }
5130 }
5131
5132 if (strlen(av[U_MIDDLE]) == 1) {
5133 initials_v[0] = av[U_MIDDLE];
5134 ADD_ATTR("initials", initials_v, LDAP_MOD_ADD);
5135 }
5136
5137 if (strlen(call_args[2]) != 0)
5138 {
5139 mitMoiraId_v[0] = call_args[2];
5140 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_ADD);
5141 }
5142
5143 ADD_ATTR("altSecurityIdentities", altSecurityIdentities_v, LDAP_MOD_ADD);
5144
5145 if(!ActiveDirectory)
5146 {
5147 loginshell_v[0] = av[U_SHELL];
5148 mitMoiraClass_v[0] = av[U_CLASS];
5149 mitMoiraStatus_v[0] = av[U_STATE];
5150 ADD_ATTR("loginShell", loginshell_v, LDAP_MOD_ADD);
5151 ADD_ATTR("uid", samAccountName_v, LDAP_MOD_ADD);
5152 ADD_ATTR("eduPersonPrincipalName", mail_v, LDAP_MOD_ADD);
5153 ADD_ATTR("o", o_v, LDAP_MOD_ADD);
5154 ADD_ATTR("mitMoiraClass", mitMoiraClass_v, LDAP_MOD_ADD);
5155 ADD_ATTR("mitMoiraStatus", mitMoiraStatus_v, LDAP_MOD_ADD);
5156 }
5157
5158 if (strlen(av[U_UID]) != 0)
5159 {
5160 uid_v[0] = av[U_UID];
5161
5162 if(ActiveDirectory)
5163 {
5164 ADD_ATTR("uid", uid_v, LDAP_MOD_ADD);
5165 }
5166 else
5167 {
5168 gid_v[0] = "101";
5169 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
5170 ADD_ATTR("gidNumber", gid_v, LDAP_MOD_ADD);
5171 }
5172
5173 if(ActiveDirectory)
5174 {
5175 if (!UseSFU30)
5176 {
5177 ADD_ATTR("uidNumber", uid_v, LDAP_MOD_ADD);
5178 }
5179 else
5180 {
5181 ADD_ATTR("msSFU30UidNumber", uid_v, LDAP_MOD_ADD);
5182 }
5183 }
5184 }
5185
5186 if ((strlen(av[U_MITID]) != 0) && (av[U_MITID][0] == '9'))
5187 mitid_v[0] = av[U_MITID];
5188 else
5189 mitid_v[0] = "none";
5190
5191 ADD_ATTR("employeeID", mitid_v, LDAP_MOD_ADD);
5192
5193 n = SetHomeDirectory((LDAP *)call_args[0], user_name, new_dn,
5194 WinHomeDir, WinProfileDir, homedir_v, winProfile_v,
5195 drives_v, mods, LDAP_MOD_ADD, n);
5196
5197 if(ActiveDirectory)
5198 {
5199 sprintf(filter_exp, "(sAMAccountName=%s)", "UserTemplate.u");
5200 sprintf(search_path, "%s,%s", security_template_ou, call_args[1]);
5201 attr_array[0] = "sAMAccountName";
5202 attr_array[1] = NULL;
5203 group_count = 0;
5204 group_base = NULL;
5205
5206 if ((rc = linklist_build((LDAP *)call_args[0], search_path, filter_exp,
5207 attr_array, &group_base, &group_count,
5208 LDAP_SCOPE_SUBTREE) != 0))
5209 return(1);
5210
5211 if (group_count != 1)
5212 {
5213 com_err(whoami, 0, "Unable to process user security template: %s - "
5214 "security not set", "UserTemplate.u");
5215 return(1);
5216 }
5217
5218 strcpy(TemplateDn, group_base->dn);
5219 strcpy(TemplateSamName, group_base->value);
5220 linklist_free(group_base);
5221 group_base = NULL;
5222 group_count = 0;
5223
5224 rc = ldap_search_ext_s((LDAP *)call_args[0], search_path,
5225 LDAP_SCOPE_SUBTREE, filter_exp, NULL, 0,
5226 apsServerControls, NULL,
5227 NULL, 0, &psMsg);
5228
5229 if ((psMsg = ldap_first_entry((LDAP *)call_args[0], psMsg)) == NULL)
5230 {
5231 com_err(whoami, 0, "Unable to find user security template: %s - "
5232 "security not set", "UserTemplate.u");
5233 return(1);
5234 }
5235
5236 ppsValues = ldap_get_values_len((LDAP *)call_args[0], psMsg,
5237 "ntSecurityDescriptor");
5238 if (ppsValues == NULL)
5239 {
5240 com_err(whoami, 0, "Unable to find user security template: %s - "
5241 "security not set", "UserTemplate.u");
5242 return(1);
5243 }
5244
5245 ADD_ATTR("ntSecurityDescriptor", (char **)ppsValues,
5246 LDAP_MOD_REPLACE | LDAP_MOD_BVALUES);
5247 }
5248
5249 mods[n] = NULL;
5250
5251 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
5252
5253 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
5254 {
5255 OldUseSFU30 = UseSFU30;
5256 SwitchSFU(mods, &UseSFU30, n);
5257 if (OldUseSFU30 != UseSFU30)
5258 rc = ldap_add_ext_s((LDAP *)call_args[0], new_dn, mods, NULL, NULL);
5259 }
5260
5261 for (i = 0; i < n; i++)
5262 free(mods[i]);
5263
5264 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
5265 {
5266 com_err(whoami, 0, "Unable to create user %s : %s",
5267 user_name, ldap_err2string(rc));
5268 callback_rc = rc;
5269 return(rc);
5270 }
5271
5272 if ((rc == LDAP_SUCCESS) && (SetPassword))
5273 {
5274 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
5275 {
5276 ad_kdc_disconnect();
5277 if (!ad_server_connect(default_server, ldap_domain))
5278 {
5279 com_err(whoami, 0, "Unable to set password for user %s : %s",
5280 user_name,
5281 "cannot get changepw ticket from windows domain");
5282 }
5283 else
5284 {
5285 if ((rc = set_password(sam_name, "", ldap_domain)) != 0)
5286 {
5287 com_err(whoami, 0, "Unable to set password for user %s "
5288 ": %ld", user_name, rc);
5289 }
5290 }
5291 }
5292 }
5293
5294 if(!ActiveDirectory)
5295 {
5296 if (rc = moira_connect())
5297 {
a816420b 5298 critical_alert(whoami, "Ldap incremental",
61a2844b 5299 "Error contacting Moira server : %s",
5300 error_message(rc));
5301 return;
5302 }
5303
5304 argv[0] = user_name;
5305
5306 if (!(rc = mr_query("get_pobox", 1, argv, save_query_info, save_argv)))
5307 {
0384092e 5308 n = 0;
5309 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_REPLACE);
5310 mods[n] = NULL;
5311 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5312
5313 if (rc == LDAP_ALREADY_EXISTS || rc == LDAP_TYPE_OR_VALUE_EXISTS)
5314 rc = LDAP_SUCCESS;
5315
5316 if(rc)
5317 com_err(whoami, 0,
5318 "Unable to set the mailRoutingAddress for %s : %s",
5319 user_name, ldap_err2string(rc));
5320
61a2844b 5321 p = strdup(save_argv[3]);
5322
5323 if((c = strchr(p, ',')) != NULL) {
5324 q = strtok(p, ",");
5325 StringTrim(q);
5326
5327 if ((c = strchr(q, '@')) == NULL)
5328 sprintf(temp, "%s@mit.edu", q);
5329 else
5330 sprintf(temp, "%s", q);
5331
5332 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5333 {
5334 mail_routing_v[0] = temp;
5335
5336 n = 0;
5337 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5338 mods[n] = NULL;
5339 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5340
5341 if (rc == LDAP_ALREADY_EXISTS ||
5342 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5343 rc = LDAP_SUCCESS;
5344
5345 if(rc)
5346 com_err(whoami, 0,
5347 "Unable to set the mailRoutingAddress for %s : %s",
5348 user_name, ldap_err2string(rc));
5349 }
5350
5351 while((q = strtok(NULL, ",")) != NULL) {
5352 StringTrim(q);
5353
5354 if((c = strchr(q, '@')) == NULL)
5355 sprintf(temp, "%s@mit.edu", q);
5356 else
5357 sprintf(temp, "%s", q);
5358
5359 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5360 {
5361 mail_routing_v[0] = temp;
5362
5363 n = 0;
5364 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5365 mods[n] = NULL;
5366 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5367
5368 if (rc == LDAP_ALREADY_EXISTS ||
5369 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5370 rc = LDAP_SUCCESS;
5371
5372 if(rc)
5373 com_err(whoami, 0,
5374 "Unable to set the mailRoutingAddress for %s : %s",
5375 user_name, ldap_err2string(rc));
5376 }
5377 }
5378 } else {
5379 StringTrim(p);
5380
5381 if((c = strchr(p, '@')) == NULL)
5382 sprintf(temp, "%s@mit.edu", p);
5383 else
5384 sprintf(temp, "%s", p);
5385
5386 if(email_isvalid(temp) && atoi(av[U_STATE]) != US_DELETED)
5387 {
5388 mail_routing_v[0] = temp;
5389
5390 n = 0;
5391 ADD_ATTR("mailRoutingAddress", mail_routing_v, LDAP_MOD_ADD);
5392 mods[n] = NULL;
5393 rc = ldap_modify_s((LDAP *)call_args[0], new_dn, mods);
5394
5395 if (rc == LDAP_ALREADY_EXISTS ||
5396 rc == LDAP_TYPE_OR_VALUE_EXISTS)
5397 rc = LDAP_SUCCESS;
5398
5399 if(rc)
5400 com_err(whoami, 0,
5401 "Unable to set the mailRoutingAddress for %s : %s",
5402 user_name, ldap_err2string(rc));
5403 }
5404 }
5405 }
5406 moira_disconnect();
5407 }
5408
5409 return(0);
5410}
5411
5412int user_change_status(LDAP *ldap_handle, char *dn_path,
5413 char *user_name, char *MoiraId,
5414 int operation)
5415{
5416 char filter[128];
5417 char *attr_array[3];
5418 char temp[256];
5419 char distinguished_name[1024];
5420 char **modvalues;
5421 char *mitMoiraId_v[] = {NULL, NULL};
5422 LDAPMod *mods[20];
5423 LK_ENTRY *group_base;
5424 int group_count;
5425 int rc;
5426 int i;
5427 int n;
5428 ULONG ulongValue;
5429
5430 if (!check_string(user_name))
5431 {
5432 com_err(whoami, 0, "Unable to process invalid LDAP user name %s",
5433 user_name);
5434 return(AD_INVALID_NAME);
5435 }
5436
5437 group_count = 0;
5438 group_base = NULL;
5439
5440 if (strlen(MoiraId) != 0)
5441 {
5442 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5443 attr_array[0] = "UserAccountControl";
5444 attr_array[1] = NULL;
5445 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5446 &group_base, &group_count,
5447 LDAP_SCOPE_SUBTREE)) != 0)
5448 {
5449 com_err(whoami, 0, "Unable to process user %s : %s",
5450 user_name, ldap_err2string(rc));
5451 return(rc);
5452 }
5453 }
5454
5455 if (group_count != 1)
5456 {
5457 linklist_free(group_base);
5458 group_count = 0;
5459 group_base = NULL;
5460 sprintf(filter, "(sAMAccountName=%s)", user_name);
5461 attr_array[0] = "UserAccountControl";
5462 attr_array[1] = NULL;
5463 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5464 &group_base, &group_count,
5465 LDAP_SCOPE_SUBTREE)) != 0)
5466 {
5467 com_err(whoami, 0, "Unable to process user %s : %s",
5468 user_name, ldap_err2string(rc));
5469 return(rc);
5470 }
5471 }
5472
5473 if (group_count != 1)
5474 {
5475 linklist_free(group_base);
c9ef9269 5476 com_err(whoami, 0, "Unable to find user %s in directory",
61a2844b 5477 user_name);
5478 return(LDAP_NO_SUCH_OBJECT);
5479 }
5480
5481 strcpy(distinguished_name, group_base->dn);
5482 ulongValue = atoi((*group_base).value);
5483
5484 if (operation == MEMBER_DEACTIVATE)
5485 ulongValue |= UF_ACCOUNTDISABLE;
5486 else
5487 ulongValue &= ~UF_ACCOUNTDISABLE;
5488
5489 sprintf(temp, "%ld", ulongValue);
5490
5491 if ((rc = construct_newvalues(group_base, group_count, (*group_base).value,
5492 temp, &modvalues, REPLACE)) == 1)
5493 goto cleanup;
5494
5495 linklist_free(group_base);
5496 group_base = NULL;
5497 group_count = 0;
5498 n = 0;
5499 ADD_ATTR("UserAccountControl", modvalues, LDAP_MOD_REPLACE);
5500
5501 if (strlen(MoiraId) != 0)
5502 {
5503 mitMoiraId_v[0] = MoiraId;
5504 ADD_ATTR("mitMoiraId", mitMoiraId_v, LDAP_MOD_REPLACE);
5505 }
5506
5507 mods[n] = NULL;
5508 rc = ldap_modify_s(ldap_handle, distinguished_name, mods);
5509
5510 for (i = 0; i < n; i++)
5511 free(mods[i]);
5512
5513 free_values(modvalues);
5514
5515 if (rc != LDAP_SUCCESS)
5516 {
5517 com_err(whoami, 0, "Unable to change status of user %s : %s",
5518 user_name, ldap_err2string(rc));
5519 }
5520
5521 cleanup:
5522 return(rc);
5523}
5524
5525int user_delete(LDAP *ldap_handle, char *dn_path,
5526 char *u_name, char *MoiraId)
5527{
5528 char filter[128];
5529 char *attr_array[3];
5530 char distinguished_name[1024];
5531 char user_name[512];
5532 LK_ENTRY *group_base;
5533 int group_count;
5534 int rc;
5535 char temp[256];
5536
5537 if (!check_string(u_name))
5538 return(AD_INVALID_NAME);
5539
5540 strcpy(user_name, u_name);
5541 group_count = 0;
5542 group_base = NULL;
5543
5544 if (strlen(MoiraId) != 0)
5545 {
5546 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
5547 attr_array[0] = "name";
5548 attr_array[1] = NULL;
5549 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5550 &group_base, &group_count,
5551 LDAP_SCOPE_SUBTREE)) != 0)
5552 {
5553 com_err(whoami, 0, "Unable to process user %s : %s",
5554 user_name, ldap_err2string(rc));
5555 goto cleanup;
5556 }
5557 }
5558
5559 if (group_count != 1)
5560 {
5561 linklist_free(group_base);
5562 group_count = 0;
5563 group_base = NULL;
5564 sprintf(filter, "(sAMAccountName=%s)", user_name);
5565 attr_array[0] = "name";
5566 attr_array[1] = NULL;
5567 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5568 &group_base, &group_count,
5569 LDAP_SCOPE_SUBTREE)) != 0)
5570 {
5571 com_err(whoami, 0, "Unable to process user %s : %s",
5572 user_name, ldap_err2string(rc));
5573 goto cleanup;
5574 }
5575 }
5576
5577 if (group_count != 1)
5578 {
61a2844b 5579 goto cleanup;
5580 }
5581
5582 strcpy(distinguished_name, group_base->dn);
5583
5584 if (rc = ldap_delete_s(ldap_handle, distinguished_name))
5585 {
5586 com_err(whoami, 0, "Unable to process user %s : %s",
5587 user_name, ldap_err2string(rc));
5588 }
5589
5590 /* Need to add code to delete mit.edu contact */
5591
5592 if (Exchange)
5593 {
5594 sprintf(temp, "cn=%s@mit.edu,%s,%s", user_name, contact_ou, dn_path);
5595
5596 if(rc = ldap_delete_s(ldap_handle, temp))
5597 {
5598 com_err(whoami, 0, "Unable to delete user contact for %s",
5599 user_name);
5600 }
5601 }
5602
5603 cleanup:
5604 linklist_free(group_base);
5605
5606 return(0);
5607}
5608
5609void linklist_free(LK_ENTRY *linklist_base)
5610{
5611 LK_ENTRY *linklist_previous;
5612
5613 while (linklist_base != NULL)
5614 {
5615 if (linklist_base->dn != NULL)
5616 free(linklist_base->dn);
5617
5618 if (linklist_base->attribute != NULL)
5619 free(linklist_base->attribute);
5620
5621 if (linklist_base->value != NULL)
5622 free(linklist_base->value);
5623
5624 if (linklist_base->member != NULL)
5625 free(linklist_base->member);
5626
5627 if (linklist_base->type != NULL)
5628 free(linklist_base->type);
5629
5630 if (linklist_base->list != NULL)
5631 free(linklist_base->list);
5632
5633 linklist_previous = linklist_base;
5634 linklist_base = linklist_previous->next;
5635 free(linklist_previous);
5636 }
5637}
5638
5639void free_values(char **modvalues)
5640{
5641 int i;
5642
5643 i = 0;
5644
5645 if (modvalues != NULL)
5646 {
5647 while (modvalues[i] != NULL)
5648 {
5649 free(modvalues[i]);
5650 modvalues[i] = NULL;
5651 ++i;
5652 }
5653 free(modvalues);
5654 }
5655}
5656
5657static int illegalchars[] = {
5658 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5659 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
5660 1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, /* SPACE - / */
5661 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, /* 0 - ? */
5662 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5663 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, /* P - _ */
5664 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5665 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5666 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5667 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5668 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5669 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5670 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
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};
5675
5676static int illegalchars_ldap[] = {
5677 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^@ - ^O */
5678 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* ^P - ^_ */
a0407f40 5679 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* SPACE - / */
61a2844b 5680 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, /* 0 - ? */
5681 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* @ - O */
5682 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, /* P - _ */
5683 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* ` - o */
5684 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, /* p - ^? */
5685 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5686 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5687 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5688 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5689 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5690 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5691 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5692 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
5693};
5694
5695int check_string(char *s)
5696{
5697 char character;
b6e441c5 5698 char *string;
5699
5700 string = s;
61a2844b 5701
5702 for (; *s; s++)
5703 {
5704 character = *s;
5705
5706 if (isupper(character))
5707 character = tolower(character);
5708
5709 if(ActiveDirectory)
5710 {
5711 if (illegalchars[(unsigned) character])
a0407f40 5712 {
5713 com_err(whoami, 0, "Found illegal char '%c' (%d) in string %s",
b6e441c5 5714 character, (unsigned) character, string);
a0407f40 5715 return 0;
5716 }
61a2844b 5717 }
5718 else
5719 {
5720 if (illegalchars_ldap[(unsigned) character])
a0407f40 5721 {
5722 com_err(whoami, 0, "Found illegal char '%c' (%d) in string %s",
b6e441c5 5723 character, (unsigned) character, string);
a0407f40 5724 return 0;
5725 }
61a2844b 5726 }
5727 }
5728
5729 return(1);
5730}
5731
5732int check_container_name(char *s)
5733{
5734 char character;
5735
5736 for (; *s; s++)
5737 {
5738 character = *s;
5739
5740 if (isupper(character))
5741 character = tolower(character);
5742
5743 if (character == ' ')
5744 continue;
5745
5746 if (illegalchars[(unsigned) character])
5747 return 0;
5748 }
5749
5750 return(1);
5751}
5752
5753int mr_connect_cl(char *server, char *client, int version, int auth)
5754{
5755 int status;
5756 char *motd;
5757 char temp[128];
5758
5759 status = mr_connect(server);
5760
5761 if (status)
5762 {
5763 com_err(whoami, status, "while connecting to Moira");
5764 return status;
5765 }
5766
5767 status = mr_motd(&motd);
5768
5769 if (status)
5770 {
5771 mr_disconnect();
5772 com_err(whoami, status, "while checking server status");
5773 return status;
5774 }
5775
5776 if (motd)
5777 {
5778 sprintf(temp, "The Moira server is currently unavailable: %s", motd);
5779 com_err(whoami, status, temp);
5780 mr_disconnect();
5781 return status;
5782 }
5783
5784 status = mr_version(version);
5785
5786 if (status)
5787 {
5788 if (status == MR_UNKNOWN_PROC)
5789 {
5790 if (version > 2)
5791 status = MR_VERSION_HIGH;
5792 else
5793 status = MR_SUCCESS;
5794 }
5795
5796 if (status == MR_VERSION_HIGH)
5797 {
5798 com_err(whoami, 0, "Warning: This client is running newer code "
5799 "than the server.");
5800 com_err(whoami, 0, "Some operations may not work.");
5801 }
5802 else if (status && status != MR_VERSION_LOW)
5803 {
5804 com_err(whoami, status, "while setting query version number.");
5805 mr_disconnect();
5806 return status;
5807 }
5808 }
5809
5810 if (auth)
5811 {
5812 status = mr_krb5_auth(client);
5813 if (status)
5814 {
5815 com_err(whoami, status, "while authenticating to Moira.");
5816 mr_disconnect();
5817 return status;
5818 }
5819 }
5820
5821 return MR_SUCCESS;
5822}
5823
5824void AfsToWinAfs(char* path, char* winPath)
5825{
5826 char* pathPtr;
5827 char* winPathPtr;
5828 strcpy(winPath, WINAFS);
5829 pathPtr = path + strlen(AFS);
5830 winPathPtr = winPath + strlen(WINAFS);
5831
5832 while (*pathPtr)
5833 {
5834 if (*pathPtr == '/')
5835 *winPathPtr = '\\';
5836 else
5837 *winPathPtr = *pathPtr;
5838
5839 pathPtr++;
5840 winPathPtr++;
5841 }
5842}
5843
5844int GetAceInfo(int ac, char **av, void *ptr)
5845{
5846 char **call_args;
5847 int security_flag;
5848
5849 call_args = ptr;
5850
5851 strcpy(call_args[0], av[L_ACE_TYPE]);
5852 strcpy(call_args[1], av[L_ACE_NAME]);
5853 security_flag = 0;
5854 get_group_membership(call_args[2], call_args[3], &security_flag, av);
5855 return(LDAP_SUCCESS);
5856}
5857
5858int checkADname(LDAP *ldap_handle, char *dn_path, char *Name)
5859{
5860 char filter[128];
5861 char *attr_array[3];
5862 int group_count;
5863 int rc;
5864 LK_ENTRY *group_base;
5865
5866 group_count = 0;
5867 group_base = NULL;
5868
5869 sprintf(filter, "(sAMAccountName=%s)", Name);
5870 attr_array[0] = "sAMAccountName";
5871 attr_array[1] = NULL;
5872
5873 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
5874 &group_base, &group_count,
5875 LDAP_SCOPE_SUBTREE)) != 0)
5876 {
5877 com_err(whoami, 0, "Unable to process ACE name %s : %s",
5878 Name, ldap_err2string(rc));
5879 return(1);
5880 }
5881
5882 linklist_free(group_base);
5883 group_base = NULL;
5884
5885 if (group_count == 0)
5886 return(0);
5887
5888 return(1);
5889}
5890
5891#define MAX_ACE 7
5892
5893int ProcessAce(LDAP *ldap_handle, char *dn_path, char *Name, char *Type,
5894 int UpdateGroup, int *ProcessGroup, char *maillist)
5895{
5896 char *av[2];
5897 char GroupName[256];
5898 char *call_args[7];
5899 int rc;
5900 char *AceInfo[4];
5901 char AceType[32];
5902 char AceName[128];
5903 char AceMembership[2];
5904 char AceOu[256];
5905 char temp[128];
5906 char *save_argv[U_END];
5907
5908 if (!SetGroupAce)
5909 {
5910 com_err(whoami, 0, "ProcessAce disabled, skipping");
5911 return(0);
5912 }
5913
5914 strcpy(GroupName, Name);
5915
5916 if (strcasecmp(Type, "LIST"))
5917 return(1);
5918
5919 while (1)
5920 {
5921 av[0] = GroupName;
5922 AceInfo[0] = AceType;
5923 AceInfo[1] = AceName;
5924 AceInfo[2] = AceMembership;
5925 AceInfo[3] = AceOu;
5926 memset(AceType, '\0', sizeof(AceType));
5927 memset(AceName, '\0', sizeof(AceName));
5928 memset(AceMembership, '\0', sizeof(AceMembership));
5929 memset(AceOu, '\0', sizeof(AceOu));
5930 callback_rc = 0;
5931
5932 if (rc = mr_query("get_list_info", 1, av, GetAceInfo, AceInfo))
5933 {
a0407f40 5934 if(rc != MR_NO_MATCH)
a2aa35d9 5935 com_err(whoami, 0, "Unable to get ACE info for list %s : %s",
5936 GroupName, error_message(rc));
5937
61a2844b 5938 return(1);
5939 }
5940
5941 if (callback_rc)
5942 {
5943 com_err(whoami, 0, "Unable to get ACE info for list %s", GroupName);
5944 return(1);
5945 }
5946
5947 if ((strcasecmp(AceType, "USER")) && (strcasecmp(AceType, "LIST")))
5948 return(0);
5949
5950 strcpy(temp, AceName);
5951
5952 if (!strcasecmp(AceType, "LIST"))
5953 sprintf(temp, "%s%s", AceName, group_suffix);
5954
5955 if (!UpdateGroup)
5956 {
5957 if (checkADname(ldap_handle, dn_path, temp))
5958 return(0);
5959
5960 (*ProcessGroup) = 1;
5961 }
5962
5963 if (!strcasecmp(AceInfo[0], "LIST"))
5964 {
5965 if (make_new_group(ldap_handle, dn_path, "", AceName, AceOu,
5966 AceMembership, 0, UpdateGroup, maillist))
5967 return(1);
33448741 5968
5969 populate_group(ldap_handle, dn_path, AceName, AceOu, AceMembership,
8b76dea3 5970 0, "", 1);
61a2844b 5971 }
5972 else if (!strcasecmp(AceInfo[0], "USER"))
5973 {
5974 av[0] = AceName;
5975 call_args[0] = (char *)ldap_handle;
5976 call_args[1] = dn_path;
5977 call_args[2] = "";
5978 call_args[3] = NULL;
5979 callback_rc = 0;
5980
7c22be37 5981 if(!strcasecmp(AceName, PRODUCTION_PRINCIPAL) ||
5982 !strcasecmp(AceName, TEST_PRINCIPAL))
5983 {
5984 return(1);
5985 }
5986
61a2844b 5987 if (rc = mr_query("get_user_account_by_login", 1, av,
5988 save_query_info, save_argv))
5989 {
5990 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5991 AceName, Name);
5992 return(1);
5993 }
5994
5995 if (rc = user_create(U_END, save_argv, call_args))
5996 {
5997 com_err(whoami, 0, "Unable to process user ACE %s for group %s.",
5998 AceName, Name);
5999 return(1);
6000 }
6001
6002 if (callback_rc)
6003 {
6004 com_err(whoami, 0, "Unable to process user Ace %s for group %s",
6005 AceName, Name);
6006 return(1);
6007 }
6008
6009 return(0);
6010 }
6011 else
6012 return(1);
6013
6014 if (!strcasecmp(AceType, "LIST"))
6015 {
6016 if (!strcasecmp(GroupName, AceName))
6017 return(0);
6018 }
6019
6020 strcpy(GroupName, AceName);
6021 }
6022
6023 return(1);
6024}
6025
6026int make_new_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
6027 char *group_name, char *group_ou, char *group_membership,
6028 int group_security_flag, int updateGroup, char *maillist)
6029{
6030 char *av[3];
6031 char *call_args[8];
6032 int rc;
6033 LK_ENTRY *group_base;
6034 int group_count;
6035 char filter[128];
6036 char *attr_array[3];
6037
6038 av[0] = group_name;
6039 call_args[0] = (char *)ldap_handle;
6040 call_args[1] = dn_path;
6041 call_args[2] = group_name;
6042 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS);
6043 call_args[4] = (char *)updateGroup;
6044 call_args[5] = MoiraId;
6045 call_args[6] = "0";
6046 call_args[7] = NULL;
6047 callback_rc = 0;
6048
6049 group_count = 0;
6050 group_base = NULL;
6051
6052 if (rc = mr_query("get_list_info", 1, av, group_create, call_args))
6053 {
6054 moira_disconnect();
6055 com_err(whoami, 0, "Unable to create list %s : %s", group_name,
6056 error_message(rc));
6057 return(rc);
6058 }
6059
6060 if (callback_rc)
6061 {
6062 moira_disconnect();
6063 com_err(whoami, 0, "Unable to create list %s", group_name);
6064 return(callback_rc);
6065 }
6066
6067 return(0);
6068}
6069
6070int populate_group(LDAP *ldap_handle, char *dn_path, char *group_name,
6071 char *group_ou, char *group_membership,
8b76dea3 6072 int group_security_flag, char *MoiraId,
6073 int synchronize)
61a2844b 6074{
6075 char *av[3];
6076 char *call_args[7];
6077 char *pUserOu;
6078 LK_ENTRY *ptr;
6079 int rc;
6080 char member[512];
6081 char *s;
6082 char **members;
6083 int i = 0;
6084 int j = 0;
6085 int n = 0;
6086 char group_dn[512];
6087 LDAPMod *mods[20];
e8332ac3 6088 char *member_v[] = {NULL, NULL};
61a2844b 6089 char *save_argv[U_END];
e8332ac3 6090 char machine_ou[256];
6091 char NewMachineName[1024];
61a2844b 6092
6093 com_err(whoami, 0, "Populating group %s", group_name);
6094 av[0] = group_name;
6095 call_args[0] = (char *)ldap_handle;
6096 call_args[1] = dn_path;
6097 call_args[2] = group_name;
e8332ac3 6098 call_args[3] = (char *)(MOIRA_USERS | MOIRA_KERBEROS | MOIRA_STRINGS |
6099 MOIRA_MACHINE);
61a2844b 6100 call_args[4] = NULL;
6101 member_base = NULL;
8b76dea3 6102 group_members = 0;
61a2844b 6103
6104 if (rc = mr_query("get_end_members_of_list", 1, av,
6105 member_list_build, call_args))
6106 {
fe81e80b 6107 if(rc == MR_LIST)
6108 return(0);
6109
61a2844b 6110 com_err(whoami, 0, "Unable to populate list %s : %s",
6111 group_name, error_message(rc));
6112 return(3);
6113 }
6114
8b76dea3 6115 if (member_base != NULL)
6116 {
6117 ptr = member_base;
6118
6119 while(ptr != NULL)
6120 {
6121 if (!strcasecmp(ptr->type, "LIST"))
6122 {
6123 ptr = ptr->next;
6124 continue;
6125 }
6126
6127 if (!strcasecmp(ptr->type, "MACHINE") && !ProcessMachineContainer)
6128 {
6129 ptr = ptr->next;
6130 continue;
6131 }
6132
6133 if(!strcasecmp(ptr->type, "USER"))
6134 {
6135 if(!strcasecmp(ptr->member, PRODUCTION_PRINCIPAL) ||
6136 !strcasecmp(ptr->member, TEST_PRINCIPAL))
6137 {
6138 ptr = ptr->next;
6139 continue;
6140 }
6141 }
6142
6143 ptr = ptr->next;
6144 group_members++;
6145 }
6146 }
6147
6148 if(max_group_members && !synchronize && (group_members > max_group_members))
6149 {
6150 com_err(whoami, 0,
6151 "Group %s membership of %d exceeds maximum %d, skipping",
6152 group_name, group_members, max_group_members);
6153 return(0);
6154 }
6155
61a2844b 6156 members = (char **)malloc(sizeof(char *) * 2);
e8332ac3 6157
61a2844b 6158 if (member_base != NULL)
6159 {
6160 ptr = member_base;
6161
6162 while (ptr != NULL)
6163 {
6164 if (!strcasecmp(ptr->type, "LIST"))
6165 {
6166 ptr = ptr->next;
6167 continue;
6168 }
6169
e8332ac3 6170 if (!strcasecmp(ptr->type, "MACHINE") && !ProcessMachineContainer)
6171 {
6172 ptr = ptr->next;
6173 continue;
6174 }
6175
63d9f3c3 6176 if(!strcasecmp(ptr->type, "USER"))
61a2844b 6177 {
63d9f3c3 6178 if(!strcasecmp(ptr->member, PRODUCTION_PRINCIPAL) ||
6179 !strcasecmp(ptr->member, TEST_PRINCIPAL))
6180 {
6181 ptr = ptr->next;
6182 continue;
6183 }
6184
61a2844b 6185 if ((rc = check_user(ldap_handle, dn_path, ptr->member,
6186 "")) == AD_NO_USER_FOUND)
6187 {
6188 com_err(whoami, 0, "creating user %s", ptr->member);
6189
6190 av[0] = ptr->member;
6191 call_args[0] = (char *)ldap_handle;
6192 call_args[1] = dn_path;
6193 call_args[2] = "";
6194 call_args[3] = NULL;
6195 callback_rc = 0;
6196
6197 if (rc = mr_query("get_user_account_by_login", 1, av,
6198 save_query_info, save_argv))
6199 {
6200 com_err(whoami, 0, "Unable to create user %s "
6201 "while populating group %s.", ptr->member,
6202 group_name);
6203
6204 return(3);
6205 }
6206
6207 if (rc = user_create(U_END, save_argv, call_args))
6208 {
6209 com_err(whoami, 0, "Unable to create user %s "
6210 "while populating group %s.", ptr->member,
6211 group_name);
6212
6213 return(3);
6214 }
6215
6216 if (callback_rc)
6217 {
6218 com_err(whoami, 0, "Unable to create user %s "
6219 "while populating group %s", ptr->member,
6220 group_name);
6221
6222 return(3);
6223 }
6224 }
6225
6226 pUserOu = user_ou;
6227
6228 if(ActiveDirectory)
6229 {
6230 sprintf(member, "cn=%s,%s,%s", ptr->member, pUserOu,
6231 dn_path);
6232 }
6233 else
6234 {
6235 sprintf(member, "uid=%s,%s,%s", ptr->member, pUserOu,
6236 dn_path);
6237 }
61a2844b 6238 }
6239 else if (!strcasecmp(ptr->type, "STRING"))
6240 {
6241 if (contact_create(ldap_handle, dn_path, ptr->member,
6242 contact_ou))
6243 return(3);
6244
6245 pUserOu = contact_ou;
6246 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6247 pUserOu, dn_path);
6248 }
6249 else if (!strcasecmp(ptr->type, "KERBEROS"))
6250 {
6251 if (contact_create(ldap_handle, dn_path, ptr->member,
6252 kerberos_ou))
6253 return(3);
6254
6255 pUserOu = kerberos_ou;
6256 sprintf(member, "cn=%s,%s,%s", escape_string(ptr->member),
6257 pUserOu, dn_path);
6258 }
e8332ac3 6259 else if (!strcasecmp(ptr->type, "MACHINE"))
6260 {
6261 memset(machine_ou, '\0', sizeof(machine_ou));
6262 memset(NewMachineName, '\0', sizeof(NewMachineName));
6263
6264 if (!get_machine_ou(ldap_handle, dn_path, ptr->member,
6265 machine_ou, NewMachineName))
6266 {
6267 pUserOu = machine_ou;
6268 sprintf(member, "cn=%s,%s,%s", NewMachineName, pUserOu,
6269 dn_path);
6270 }
6271 else
6272 {
6273 ptr = ptr->next;
6274 continue;
6275 }
6276 }
61a2844b 6277
6278 if(i > 1)
6279 members = (char **)realloc(members, ((i + 2) * sizeof(char *)));
6280 members[i++] = strdup(member);
6281
6282 ptr = ptr->next;
6283 }
6284
6285 linklist_free(member_base);
6286 member_base = NULL;
6287 }
6288
6289 members[i] = NULL;
e8332ac3 6290
6291 sprintf(group_dn, "cn=%s,%s,%s", group_name, group_ou, dn_path);
6292
6293 if(GroupPopulateDelete)
6294 {
6295 n = 0;
6296 ADD_ATTR("member", member_v, LDAP_MOD_REPLACE);
6297 mods[n] = NULL;
6298
6299 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6300 mods)) != LDAP_SUCCESS)
6301 {
6302 com_err(whoami, 0,
6303 "Unable to populate group membership for %s: %s",
6304 group_dn, ldap_err2string(rc));
6305 }
61a2844b 6306
e8332ac3 6307 for (i = 0; i < n; i++)
6308 free(mods[i]);
6309 }
6310
61a2844b 6311 n = 0;
6312 ADD_ATTR("member", members, LDAP_MOD_REPLACE);
6313 mods[n] = NULL;
e8332ac3 6314
61a2844b 6315 if ((rc = ldap_modify_s(ldap_handle, group_dn,
6316 mods)) != LDAP_SUCCESS)
6317 {
6318 com_err(whoami, 0,
6319 "Unable to populate group membership for %s: %s",
6320 group_dn, ldap_err2string(rc));
6321 }
6322
6323 for (i = 0; i < n; i++)
6324 free(mods[i]);
e8332ac3 6325
61a2844b 6326 free(members);
6327
6328 return(0);
6329}
6330
6331int process_group(LDAP *ldap_handle, char *dn_path, char *MoiraId,
6332 char *group_name, char *group_ou, char *group_membership,
6333 int group_security_flag, int type, char *maillist)
6334{
6335 char before_desc[512];
6336 char before_name[256];
6337 char before_group_ou[256];
6338 char before_group_membership[2];
6339 char distinguishedName[256];
6340 char ad_distinguishedName[256];
6341 char filter[128];
6342 char *attr_array[3];
6343 int before_security_flag;
6344 int group_count;
6345 int rc;
6346 LK_ENTRY *group_base;
6347 LK_ENTRY *ptr;
6348 char ou_both[512];
6349 char ou_security[512];
6350 char ou_distribution[512];
6351 char ou_neither[512];
6352 char group_dn[512];
6353
6354 memset(ad_distinguishedName, '\0', sizeof(ad_distinguishedName));
6355 sprintf(distinguishedName, "CN=%s,%s,%s", group_name, group_ou, dn_path);
6356
6357 memset(filter, '\0', sizeof(filter));
6358 group_base = NULL;
6359 group_count = 0;
6360
6361 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6362 "*", MoiraId,
6363 "samAccountName", &group_base,
6364 &group_count, filter))
6365 return(rc);
6366
6367 if (type == CHECK_GROUPS)
6368 {
6369 if (group_count == 1)
6370 {
6371 strcpy(group_dn, group_base->dn);
6372
6373 if (!strcasecmp(group_dn, distinguishedName))
6374 {
6375 linklist_free(group_base);
6376 return(0);
6377 }
6378 }
6379
6380 linklist_free(group_base);
6381
6382 if (group_count == 0)
6383 return(AD_NO_GROUPS_FOUND);
6384
6385 if (group_count == 1)
6386 return(AD_WRONG_GROUP_DN_FOUND);
6387
6388 return(AD_MULTIPLE_GROUPS_FOUND);
6389 }
6390
6391 if (group_count == 0)
6392 {
6393 return(AD_NO_GROUPS_FOUND);
6394 }
6395
6396 if (group_count > 1)
6397 {
6398 ptr = group_base;
6399
6400 strcpy(group_dn, ptr->dn);
6401
6402 while (ptr != NULL)
6403 {
6404 if (!strcasecmp(group_dn, ptr->value))
6405 break;
6406
6407 ptr = ptr->next;
6408 }
6409
6410 if (ptr == NULL)
6411 {
6412 com_err(whoami, 0, "%d groups with moira id = %s", group_count,
6413 MoiraId);
6414 ptr = group_base;
6415
6416 while (ptr != NULL)
6417 {
6418 com_err(whoami, 0, "%s with moira id = %s", ptr->value, MoiraId);
6419 ptr = ptr->next;
6420 }
6421
6422 linklist_free(group_base);
6423 return(AD_MULTIPLE_GROUPS_FOUND);
6424 }
6425
6426 ptr = group_base;
6427
6428 while (ptr != NULL)
6429 {
6430 strcpy(group_dn, ptr->dn);
6431
6432 if (strcasecmp(group_dn, ptr->value))
6433 rc = ldap_delete_s(ldap_handle, ptr->value);
6434
6435 ptr = ptr->next;
6436 }
6437
6438 linklist_free(group_base);
6439 memset(filter, '\0', sizeof(filter));
6440 group_base = NULL;
6441 group_count = 0;
6442
6443 if (rc = ad_get_group(ldap_handle, dn_path, group_name,
6444 "*", MoiraId,
6445 "samAccountName", &group_base,
6446 &group_count, filter))
6447 return(rc);
6448
6449 if (group_count == 0)
6450 return(AD_NO_GROUPS_FOUND);
6451
6452 if (group_count > 1)
6453 return(AD_MULTIPLE_GROUPS_FOUND);
6454 }
6455
6456 strcpy(ad_distinguishedName, group_base->dn);
6457 linklist_free(group_base);
6458 group_base = NULL;
6459 group_count = 0;
6460
6461 attr_array[0] = "sAMAccountName";
6462 attr_array[1] = NULL;
6463
6464 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6465 &group_base, &group_count,
6466 LDAP_SCOPE_SUBTREE)) != 0)
6467 {
6468 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6469 MoiraId, ldap_err2string(rc));
6470 return(rc);
6471 }
6472
6473 sprintf(filter, "(sAMAccountName=%s)", group_base->value);
6474
6475 if (!strcasecmp(ad_distinguishedName, distinguishedName))
6476 {
6477 linklist_free(group_base);
6478 group_base = NULL;
6479 group_count = 0;
6480 return(0);
6481 }
6482
6483 linklist_free(group_base);
6484 group_base = NULL;
6485 group_count = 0;
6486 memset(ou_both, '\0', sizeof(ou_both));
6487 memset(ou_security, '\0', sizeof(ou_security));
6488 memset(ou_distribution, '\0', sizeof(ou_distribution));
6489 memset(ou_neither, '\0', sizeof(ou_neither));
6490 memset(before_name, '\0', sizeof(before_name));
6491 memset(before_desc, '\0', sizeof(before_desc));
6492 memset(before_group_membership, '\0', sizeof(before_group_membership));
6493
6494 attr_array[0] = "name";
6495 attr_array[1] = NULL;
6496
6497 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6498 &group_base, &group_count,
6499 LDAP_SCOPE_SUBTREE)) != 0)
6500 {
6501 com_err(whoami, 0, "Unable to get list name with MoiraId = %s: %s",
6502 MoiraId, ldap_err2string(rc));
6503 return(rc);
6504 }
6505
6506 strcpy(before_name, group_base->value);
6507 linklist_free(group_base);
6508 group_base = NULL;
6509 group_count = 0;
6510
6511 attr_array[0] = "description";
6512 attr_array[1] = NULL;
6513
6514 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6515 &group_base, &group_count,
6516 LDAP_SCOPE_SUBTREE)) != 0)
6517 {
6518 com_err(whoami, 0,
6519 "Unable to get list description with MoiraId = %s: %s",
6520 MoiraId, ldap_err2string(rc));
6521 return(rc);
6522 }
6523
6524 if (group_count != 0)
6525 {
6526 strcpy(before_desc, group_base->value);
6527 linklist_free(group_base);
6528 group_base = NULL;
6529 group_count = 0;
6530 }
6531
6532 change_to_lower_case(ad_distinguishedName);
6533 strcpy(ou_both, group_ou_both);
6534 change_to_lower_case(ou_both);
6535 strcpy(ou_security, group_ou_security);
6536 change_to_lower_case(ou_security);
6537 strcpy(ou_distribution, group_ou_distribution);
6538 change_to_lower_case(ou_distribution);
6539 strcpy(ou_neither, group_ou_neither);
6540 change_to_lower_case(ou_neither);
6541
6542 if (strstr(ad_distinguishedName, ou_both))
6543 {
6544 strcpy(before_group_ou, group_ou_both);
6545 before_group_membership[0] = 'B';
6546 before_security_flag = 1;
6547 }
6548 else if (strstr(ad_distinguishedName, ou_security))
6549 {
6550 strcpy(before_group_ou, group_ou_security);
6551 before_group_membership[0] = 'S';
6552 before_security_flag = 1;
6553 }
6554 else if (strstr(ad_distinguishedName, ou_distribution))
6555 {
6556 strcpy(before_group_ou, group_ou_distribution);
6557 before_group_membership[0] = 'D';
6558 before_security_flag = 0;
6559 }
6560 else if (strstr(ad_distinguishedName, ou_neither))
6561 {
6562 strcpy(before_group_ou, group_ou_neither);
6563 before_group_membership[0] = 'N';
6564 before_security_flag = 0;
6565 }
6566 else
6567 return(AD_NO_OU_FOUND);
6568
6569 rc = group_rename(ldap_handle, dn_path, before_name,
6570 before_group_membership,
6571 before_group_ou, before_security_flag, before_desc,
6572 group_name, group_membership, group_ou,
6573 group_security_flag,
6574 before_desc, MoiraId, filter, maillist);
6575
6576 return(rc);
6577}
6578
6579void change_to_lower_case(char *ptr)
6580{
6581 int i;
6582
6583 for (i = 0; i < (int)strlen(ptr); i++)
6584 {
6585 ptr[i] = tolower(ptr[i]);
6586 }
6587}
6588
6589int ad_get_group(LDAP *ldap_handle, char *dn_path,
6590 char *group_name, char *group_membership,
6591 char *MoiraId, char *attribute,
6592 LK_ENTRY **linklist_base, int *linklist_count,
6593 char *rFilter)
6594{
6595 LK_ENTRY *pPtr;
6596 char filter[128];
6597 char *attr_array[3];
6598 char *dn;
6599 int rc;
6600
6601 (*linklist_base) = NULL;
6602 (*linklist_count) = 0;
6603
6604 if (strlen(rFilter) != 0)
6605 {
6606 strcpy(filter, rFilter);
6607 attr_array[0] = attribute;
6608 attr_array[1] = NULL;
6609
6610 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6611 linklist_base, linklist_count,
6612 LDAP_SCOPE_SUBTREE)) != 0)
6613 {
6614 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6615 MoiraId, ldap_err2string(rc));
6616 return(rc);
6617 }
6618
6619 if ((*linklist_count) == 1)
6620 {
6621 strcpy(rFilter, filter);
6622 return(0);
6623 }
6624 }
6625
6626 linklist_free((*linklist_base));
6627 (*linklist_base) = NULL;
6628 (*linklist_count) = 0;
6629
6630 if (strlen(MoiraId) != 0)
6631 {
6632 sprintf(filter, "(&(objectClass=group)(mitMoiraId=%s))", MoiraId);
6633
6634 attr_array[0] = attribute;
6635 attr_array[1] = NULL;
6636
6637 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6638 linklist_base, linklist_count,
6639 LDAP_SCOPE_SUBTREE)) != 0)
6640 {
6641 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6642 MoiraId, ldap_err2string(rc));
6643 return(rc);
6644 }
6645 }
6646
6647 if ((*linklist_count) > 1)
6648 {
6649 com_err(whoami, 0, "multiple groups with mitMoiraId = %s", MoiraId);
6650 pPtr = (*linklist_base);
6651
6652 while (pPtr)
6653 {
6654 com_err(whoami, 0, "groups %s has mitMoiraId = %s", pPtr->value,
6655 MoiraId);
6656 pPtr = pPtr->next;
6657 }
6658
6659 linklist_free((*linklist_base));
6660 (*linklist_base) = NULL;
6661 (*linklist_count) = 0;
6662 }
6663
6664 if ((*linklist_count) == 1)
6665 {
6666
6667 pPtr = (*linklist_base);
6668 dn = strdup(pPtr->dn);
6669 dn += 3;
6670
6671 if (!memcmp(dn, group_name, strlen(group_name)))
6672 {
6673 strcpy(rFilter, filter);
6674 return(0);
6675 }
6676 }
6677
6678 linklist_free((*linklist_base));
6679 (*linklist_base) = NULL;
6680 (*linklist_count) = 0;
6681 sprintf(filter, "(sAMAccountName=%s%s)", group_name, group_suffix);
6682
6683 attr_array[0] = attribute;
6684 attr_array[1] = NULL;
6685
6686 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6687 linklist_base, linklist_count,
6688 LDAP_SCOPE_SUBTREE)) != 0)
6689 {
6690 com_err(whoami, 0, "Unable to get list info with MoiraId = %s: %s",
6691 MoiraId, ldap_err2string(rc));
6692 return(rc);
6693 }
6694
6695 if ((*linklist_count) == 1)
6696 {
6697 strcpy(rFilter, filter);
6698 return(0);
6699 }
6700
6701 return(0);
6702}
6703
6704int check_user(LDAP *ldap_handle, char *dn_path, char *UserName, char *MoiraId)
6705{
6706 char filter[128];
6707 char *attr_array[3];
6708 char SamAccountName[64];
6709 int group_count;
6710 int rc;
6711 LK_ENTRY *group_base;
6712 LK_ENTRY *gPtr;
6713
6714 group_count = 0;
6715 group_base = NULL;
6716
6717 if (strlen(MoiraId) != 0)
6718 {
6719 sprintf(filter, "(&(objectClass=user)(mitMoiraId=%s))", MoiraId);
6720
6721 attr_array[0] = "sAMAccountName";
6722 attr_array[1] = NULL;
6723 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6724 &group_base, &group_count,
6725 LDAP_SCOPE_SUBTREE)) != 0)
6726 {
6727 com_err(whoami, 0, "Unable to process user %s : %s",
6728 UserName, ldap_err2string(rc));
6729 return(rc);
6730 }
6731
6732 if (group_count > 1)
6733 {
6734 com_err(whoami, 0, "multiple users exist with MoiraId = %s",
6735 MoiraId);
6736 gPtr = group_base;
6737
6738 while (gPtr)
6739 {
6740 com_err(whoami, 0, "user %s exist with MoiraId = %s",
6741 gPtr->value, MoiraId);
6742 gPtr = gPtr->next;
6743 }
6744 }
6745 }
6746
6747 if (group_count != 1)
6748 {
6749 linklist_free(group_base);
6750 group_count = 0;
6751 group_base = NULL;
6752 sprintf(filter, "(sAMAccountName=%s)", UserName);
6753 attr_array[0] = "sAMAccountName";
6754 attr_array[1] = NULL;
6755
6756 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
6757 &group_base, &group_count,
6758 LDAP_SCOPE_SUBTREE)) != 0)
6759 {
6760 com_err(whoami, 0, "Unable to process user %s : %s",
6761 UserName, ldap_err2string(rc));
6762 return(rc);
6763 }
6764 }
6765
6766 if (group_count != 1)
6767 {
6768 linklist_free(group_base);
6769 return(AD_NO_USER_FOUND);
6770 }
6771
6772 strcpy(SamAccountName, group_base->value);
6773 linklist_free(group_base);
6774 group_count = 0;
6775 rc = 0;
6776
6777 if (strcmp(SamAccountName, UserName))
6778 {
a20c63cf 6779 com_err(whoami, 0,
6780 "User object %s with MoiraId %s has mismatched usernames "
6781 "(LDAP username %s, Moira username %s)", SamAccountName,
6782 MoiraId, SamAccountName, UserName);
61a2844b 6783 }
6784
6785 return(0);
6786}
6787
6788void container_get_dn(char *src, char *dest)
6789{
6790 char *sPtr;
6791 char *array[20];
6792 char name[256];
6793 int n;
6794
6795 memset(array, '\0', 20 * sizeof(array[0]));
6796
6797 if (strlen(src) == 0)
6798 return;
6799
6800 strcpy(name, src);
6801 sPtr = name;
6802 n = 0;
6803 array[n] = name;
6804 ++n;
6805
6806 while (*sPtr)
6807 {
6808 if ((*sPtr) == '/')
6809 {
6810 (*sPtr) = '\0';
6811 ++sPtr;
6812 array[n] = sPtr;
6813 ++n;
6814 }
6815 else
6816 ++sPtr;
6817 }
6818
6819 strcpy(dest, "OU=");
6820
6821 while (n != 0)
6822 {
6823 strcat(dest, array[n-1]);
6824 --n;
6825 if (n > 0)
6826 {
6827 strcat(dest, ",OU=");
6828 }
6829 }
6830
6831 return;
6832}
6833
6834void container_get_name(char *src, char *dest)
6835{
6836 char *sPtr;
6837 char *dPtr;
6838
6839 if (strlen(src) == 0)
6840 return;
6841
6842 sPtr = src;
6843 dPtr = src;
6844
6845 while (*sPtr)
6846 {
6847 if ((*sPtr) == '/')
6848 {
6849 dPtr = sPtr;
6850 ++dPtr;
6851 }
6852 ++sPtr;
6853 }
6854
6855 strcpy(dest, dPtr);
6856 return;
6857}
6858
6859void container_check(LDAP *ldap_handle, char *dn_path, char *name)
6860{
6861 char cName[256];
6862 char *av[7];
6863 int i;
6864 int rc;
6865
6866 strcpy(cName, name);
6867
6868 for (i = 0; i < (int)strlen(cName); i++)
6869 {
6870 if (cName[i] == '/')
6871 {
6872 cName[i] = '\0';
6873 av[CONTAINER_NAME] = cName;
6874 av[CONTAINER_DESC] = "";
6875 av[CONTAINER_LOCATION] = "";
6876 av[CONTAINER_CONTACT] = "";
6877 av[CONTAINER_TYPE] = "";
6878 av[CONTAINER_ID] = "";
6879 av[CONTAINER_ROWID] = "";
6880 rc = container_create(ldap_handle, dn_path, 7, av);
6881
6882 if (rc == LDAP_SUCCESS)
6883 {
6884 com_err(whoami, 0, "container %s created without a mitMoiraId",
6885 cName);
6886 }
6887
6888 cName[i] = '/';
6889 }
6890 }
6891}
6892
6893int container_rename(LDAP *ldap_handle, char *dn_path, int beforec,
6894 char **before, int afterc, char **after)
6895{
6896 char dName[256];
6897 char cName[256];
6898 char new_cn[128];
6899 char new_dn_path[256];
6900 char temp[256];
6901 char distinguishedName[256];
6902 char *pPtr;
6903 int rc;
6904 int i;
6905
6906 memset(cName, '\0', sizeof(cName));
6907 container_get_name(after[CONTAINER_NAME], cName);
6908
6909 if (!check_container_name(cName))
6910 {
6911 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
6912 cName);
6913 return(AD_INVALID_NAME);
6914 }
6915
6916 memset(distinguishedName, '\0', sizeof(distinguishedName));
6917
6918 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6919 distinguishedName, beforec, before))
6920 return(rc);
6921
6922 if (strlen(distinguishedName) == 0)
6923 {
6924 rc = container_create(ldap_handle, dn_path, afterc, after);
6925 return(rc);
6926 }
6927
6928 strcpy(temp, after[CONTAINER_NAME]);
6929 pPtr = temp;
6930
6931 for (i = 0; i < (int)strlen(temp); i++)
6932 {
6933 if (temp[i] == '/')
6934 {
6935 pPtr = &temp[i];
6936 }
6937 }
6938
6939 (*pPtr) = '\0';
6940
6941 container_get_dn(temp, dName);
6942
6943 if (strlen(temp) != 0)
6944 sprintf(new_dn_path, "%s,%s", dName, dn_path);
6945 else
6946 sprintf(new_dn_path, "%s", dn_path);
6947
6948 sprintf(new_cn, "OU=%s", cName);
6949
6950 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
6951
6952 if ((rc = ldap_rename_s(ldap_handle, distinguishedName, new_cn, new_dn_path,
6953 TRUE, NULL, NULL)) != LDAP_SUCCESS)
6954 {
6955 com_err(whoami, 0, "Unable to rename container from %s to %s : %s",
6956 before[CONTAINER_NAME], after[CONTAINER_NAME],
6957 ldap_err2string(rc));
6958 return(rc);
6959 }
6960
6961 memset(dName, '\0', sizeof(dName));
6962 container_get_dn(after[CONTAINER_NAME], dName);
6963 rc = container_adupdate(ldap_handle, dn_path, dName, "", afterc, after);
6964
6965 return(rc);
6966}
6967
6968int container_delete(LDAP *ldap_handle, char *dn_path, int count, char **av)
6969{
6970 char distinguishedName[256];
6971 int rc;
6972
6973 memset(distinguishedName, '\0', sizeof(distinguishedName));
6974
6975 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
6976 distinguishedName, count, av))
6977 return(rc);
6978
6979 if (strlen(distinguishedName) == 0)
6980 return(0);
6981
6982 if ((rc = ldap_delete_s(ldap_handle, distinguishedName)) != LDAP_SUCCESS)
6983 {
6984 if (rc == LDAP_NOT_ALLOWED_ON_NONLEAF)
6985 container_move_objects(ldap_handle, dn_path, distinguishedName);
6986 else
c9ef9269 6987 com_err(whoami, 0, "Unable to delete container %s from directory : %s",
61a2844b 6988 av[CONTAINER_NAME], ldap_err2string(rc));
6989 }
6990
6991 return(rc);
6992}
6993
6994int container_create(LDAP *ldap_handle, char *dn_path, int count, char **av)
6995{
6996 char *attr_array[3];
6997 LK_ENTRY *group_base;
6998 int group_count;
6999 LDAPMod *mods[20];
7000 char *objectClass_v[] = {"top",
7001 "organizationalUnit",
7002 NULL};
7003
7004 char *ou_v[] = {NULL, NULL};
7005 char *name_v[] = {NULL, NULL};
7006 char *moiraId_v[] = {NULL, NULL};
7007 char *desc_v[] = {NULL, NULL};
7008 char *managedBy_v[] = {NULL, NULL};
7009 char dName[256];
7010 char cName[256];
7011 char managedByDN[256];
7012 char filter[256];
7013 char temp[256];
7014 int n;
7015 int i;
7016 int rc;
7017
7018 memset(filter, '\0', sizeof(filter));
7019 memset(dName, '\0', sizeof(dName));
7020 memset(cName, '\0', sizeof(cName));
7021 memset(managedByDN, '\0', sizeof(managedByDN));
7022 container_get_dn(av[CONTAINER_NAME], dName);
7023 container_get_name(av[CONTAINER_NAME], cName);
7024
7025 if ((strlen(cName) == 0) || (strlen(dName) == 0))
7026 {
7027 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7028 cName);
7029 return(AD_INVALID_NAME);
7030 }
7031
7032 if (!check_container_name(cName))
7033 {
7034 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7035 cName);
7036 return(AD_INVALID_NAME);
7037 }
7038
7039 n = 0;
7040 ADD_ATTR("objectClass", objectClass_v, LDAP_MOD_ADD);
7041 name_v[0] = cName;
7042 ADD_ATTR("name", name_v, LDAP_MOD_ADD);
7043 ou_v[0] = cName;
7044 ADD_ATTR("ou", ou_v, LDAP_MOD_ADD);
7045
7046 if (strlen(av[CONTAINER_ROWID]) != 0)
7047 {
7048 moiraId_v[0] = av[CONTAINER_ROWID];
7049 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_ADD);
7050 }
7051
7052 if (strlen(av[CONTAINER_DESC]) != 0)
7053 {
7054 desc_v[0] = av[CONTAINER_DESC];
7055 ADD_ATTR("description", desc_v, LDAP_MOD_ADD);
7056 }
7057
7058 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
7059 {
7060 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
7061 {
7062 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
7063 kerberos_ou))
7064 {
7065 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
7066 kerberos_ou, dn_path);
7067 managedBy_v[0] = managedByDN;
7068 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
7069 }
7070 }
7071 else
7072 {
7073 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
7074 {
7075 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
7076 "(objectClass=user)))", av[CONTAINER_ID]);
7077 }
7078
7079 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
7080 {
7081 sprintf(filter, "(&(objectClass=group)(cn=%s))",
7082 av[CONTAINER_ID]);
7083 }
7084
7085 if (strlen(filter) != 0)
7086 {
7087 attr_array[0] = "distinguishedName";
7088 attr_array[1] = NULL;
7089 group_count = 0;
7090 group_base = NULL;
7091 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7092 attr_array,
7093 &group_base, &group_count,
7094 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7095 {
7096 if (group_count == 1)
7097 {
7098 strcpy(managedByDN, group_base->value);
7099 managedBy_v[0] = managedByDN;
7100 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_ADD);
7101 }
7102 linklist_free(group_base);
7103 group_base = NULL;
7104 group_count = 0;
7105 }
7106 }
7107 }
7108 }
7109
7110 mods[n] = NULL;
7111
7112 sprintf(temp, "%s,%s", dName, dn_path);
7113 rc = ldap_add_ext_s(ldap_handle, temp, mods, NULL, NULL);
7114
7115 for (i = 0; i < n; i++)
7116 free(mods[i]);
7117
7118 if ((rc != LDAP_SUCCESS) && (rc != LDAP_ALREADY_EXISTS))
7119 {
7120 com_err(whoami, 0, "Unable to create container %s : %s",
7121 cName, ldap_err2string(rc));
7122 return(rc);
7123 }
7124
7125 if (rc == LDAP_ALREADY_EXISTS)
7126 {
7127 if (strlen(av[CONTAINER_ROWID]) != 0)
7128 rc = container_adupdate(ldap_handle, dn_path, dName, "", count, av);
7129 }
7130
7131 return(rc);
7132}
7133
7134int container_update(LDAP *ldap_handle, char *dn_path, int beforec,
7135 char **before, int afterc, char **after)
7136{
7137 char distinguishedName[256];
7138 int rc;
7139
7140 memset(distinguishedName, '\0', sizeof(distinguishedName));
7141
7142 if (rc = container_get_distinguishedName(ldap_handle, dn_path,
7143 distinguishedName, afterc, after))
7144 return(rc);
7145
7146 if (strlen(distinguishedName) == 0)
7147 {
7148 rc = container_create(ldap_handle, dn_path, afterc, after);
7149 return(rc);
7150 }
7151
7152 container_check(ldap_handle, dn_path, after[CONTAINER_NAME]);
7153 rc = container_adupdate(ldap_handle, dn_path, "", distinguishedName, afterc,
7154 after);
7155
7156 return(rc);
7157}
7158
7159int container_get_distinguishedName(LDAP *ldap_handle, char *dn_path,
7160 char *distinguishedName, int count,
7161 char **av)
7162{
7163 char *attr_array[3];
7164 LK_ENTRY *group_base;
7165 int group_count;
7166 char dName[256];
7167 char cName[256];
7168 char filter[512];
7169 int rc;
7170
7171 memset(filter, '\0', sizeof(filter));
7172 memset(dName, '\0', sizeof(dName));
7173 memset(cName, '\0', sizeof(cName));
7174 container_get_dn(av[CONTAINER_NAME], dName);
7175 container_get_name(av[CONTAINER_NAME], cName);
7176
7177 if (strlen(dName) == 0)
7178 {
7179 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7180 av[CONTAINER_NAME]);
7181 return(AD_INVALID_NAME);
7182 }
7183
7184 if (!check_container_name(cName))
7185 {
7186 com_err(whoami, 0, "Unable to process invalid LDAP container name %s",
7187 cName);
7188 return(AD_INVALID_NAME);
7189 }
7190
7191 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7192 av[CONTAINER_ROWID]);
7193 attr_array[0] = "distinguishedName";
7194 attr_array[1] = NULL;
7195 group_count = 0;
7196 group_base = NULL;
7197
7198 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7199 &group_base, &group_count,
7200 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7201 {
7202 if (group_count == 1)
7203 {
7204 strcpy(distinguishedName, group_base->value);
7205 }
7206
7207 linklist_free(group_base);
7208 group_base = NULL;
7209 group_count = 0;
7210 }
7211
7212 if (strlen(distinguishedName) == 0)
7213 {
7214 sprintf(filter, "(&(objectClass=organizationalUnit)"
7215 "(distinguishedName=%s,%s))", dName, dn_path);
7216 attr_array[0] = "distinguishedName";
7217 attr_array[1] = NULL;
7218 group_count = 0;
7219 group_base = NULL;
7220
7221 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7222 &group_base, &group_count,
7223 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7224 {
7225 if (group_count == 1)
7226 {
7227 strcpy(distinguishedName, group_base->value);
7228 }
7229
7230 linklist_free(group_base);
7231 group_base = NULL;
7232 group_count = 0;
7233 }
7234 }
7235
7236 return(0);
7237}
7238
7239int container_adupdate(LDAP *ldap_handle, char *dn_path, char *dName,
7240 char *distinguishedName, int count, char **av)
7241{
7242 char *attr_array[5];
7243 LK_ENTRY *group_base;
7244 LK_ENTRY *pPtr;
7245 LDAPMod *mods[20];
7246 int group_count;
7247 char filter[512];
7248 char *moiraId_v[] = {NULL, NULL};
7249 char *desc_v[] = {NULL, NULL};
7250 char *managedBy_v[] = {NULL, NULL};
7251 char managedByDN[256];
7252 char moiraId[64];
7253 char desc[256];
7254 char ad_path[512];
7255 int rc;
7256 int i;
7257 int n;
7258
7259
7260 strcpy(ad_path, distinguishedName);
7261
7262 if (strlen(dName) != 0)
7263 sprintf(ad_path, "%s,%s", dName, dn_path);
7264
7265 sprintf(filter, "(&(objectClass=organizationalUnit)(distinguishedName=%s))",
7266 ad_path);
7267
7268 if (strlen(av[CONTAINER_ID]) != 0)
7269 sprintf(filter, "(&(objectClass=organizationalUnit)(mitMoiraId=%s))",
7270 av[CONTAINER_ROWID]);
7271
7272 attr_array[0] = "mitMoiraId";
7273 attr_array[1] = "description";
7274 attr_array[2] = "managedBy";
7275 attr_array[3] = NULL;
7276 group_count = 0;
7277 group_base = NULL;
7278
7279 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7280 &group_base, &group_count,
7281 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7282 {
7283 com_err(whoami, 0, "Unable to retreive container info for %s : %s",
7284 av[CONTAINER_NAME], ldap_err2string(rc));
7285 return(rc);
7286 }
7287
7288 memset(managedByDN, '\0', sizeof(managedByDN));
7289 memset(moiraId, '\0', sizeof(moiraId));
7290 memset(desc, '\0', sizeof(desc));
7291 pPtr = group_base;
7292
7293 while (pPtr)
7294 {
7295 if (!strcasecmp(pPtr->attribute, "description"))
7296 strcpy(desc, pPtr->value);
7297 else if (!strcasecmp(pPtr->attribute, "managedBy"))
7298 strcpy(managedByDN, pPtr->value);
7299 else if (!strcasecmp(pPtr->attribute, "mitMoiraId"))
7300 strcpy(moiraId, pPtr->value);
7301 pPtr = pPtr->next;
7302 }
7303
7304 linklist_free(group_base);
7305 group_base = NULL;
7306 group_count = 0;
7307
7308 n = 0;
7309 if (strlen(av[CONTAINER_ROWID]) != 0)
7310 {
7311 moiraId_v[0] = av[CONTAINER_ROWID];
7312 ADD_ATTR("mitMoiraId", moiraId_v, LDAP_MOD_REPLACE);
7313 }
7314
7315 if (strlen(av[CONTAINER_DESC]) != 0)
7316 {
7317 attribute_update(ldap_handle, ad_path, av[CONTAINER_DESC], "description",
7318 dName);
7319 }
7320 else
7321 {
7322 if (strlen(desc) != 0)
7323 {
7324 attribute_update(ldap_handle, ad_path, "", "description", dName);
7325 }
7326 }
7327
7328 if ((strlen(av[CONTAINER_TYPE]) != 0) && (strlen(av[CONTAINER_ID]) != 0))
7329 {
7330 if (!strcasecmp(av[CONTAINER_TYPE], "KERBEROS"))
7331 {
7332 if (!contact_create(ldap_handle, dn_path, av[CONTAINER_ID],
7333 kerberos_ou))
7334 {
7335 sprintf(managedByDN, "CN=%s,%s,%s", av[CONTAINER_ID],
7336 kerberos_ou, dn_path);
7337 managedBy_v[0] = managedByDN;
7338 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7339 }
7340 else
7341 {
7342 if (strlen(managedByDN) != 0)
7343 {
7344 attribute_update(ldap_handle, ad_path, "", "managedBy",
7345 dName);
7346 }
7347 }
7348 }
7349 else
7350 {
7351 memset(filter, '\0', sizeof(filter));
7352
7353 if (!strcasecmp(av[CONTAINER_TYPE], "USER"))
7354 {
7355 sprintf(filter, "(&(cn=%s)(&(objectCategory=person)"
7356 "(objectClass=user)))", av[CONTAINER_ID]);
7357 }
7358
7359 if (!strcasecmp(av[CONTAINER_TYPE], "LIST"))
7360 {
7361 sprintf(filter, "(&(objectClass=group)(cn=%s))",
7362 av[CONTAINER_ID]);
7363 }
7364
7365 if (strlen(filter) != 0)
7366 {
7367 attr_array[0] = "distinguishedName";
7368 attr_array[1] = NULL;
7369 group_count = 0;
7370 group_base = NULL;
7371 if ((rc = linklist_build(ldap_handle, dn_path, filter,
7372 attr_array, &group_base, &group_count,
7373 LDAP_SCOPE_SUBTREE)) == LDAP_SUCCESS)
7374 {
7375 if (group_count == 1)
7376 {
7377 strcpy(managedByDN, group_base->value);
7378 managedBy_v[0] = managedByDN;
7379 ADD_ATTR("managedBy", managedBy_v, LDAP_MOD_REPLACE);
7380 }
7381 else
7382 {
7383 if (strlen(managedByDN) != 0)
7384 {
7385 attribute_update(ldap_handle, ad_path, "",
7386 "managedBy", dName);
7387 }
7388 }
7389
7390 linklist_free(group_base);
7391 group_base = NULL;
7392 group_count = 0;
7393 }
7394 }
7395 else
7396 {
7397 if (strlen(managedByDN) != 0)
7398 {
7399 attribute_update(ldap_handle, ad_path, "", "managedBy",
7400 dName);
7401 }
7402 }
7403 }
7404 }
7405
7406 mods[n] = NULL;
7407
7408 if (n == 0)
7409 return(LDAP_SUCCESS);
7410
7411 rc = ldap_modify_s(ldap_handle, ad_path, mods);
7412
7413 for (i = 0; i < n; i++)
7414 free(mods[i]);
7415
7416 if (rc != LDAP_SUCCESS)
7417 {
7418 com_err(whoami, 0, "Unable to modify container info for %s : %s",
7419 av[CONTAINER_NAME], ldap_err2string(rc));
7420 return(rc);
7421 }
7422
7423 return(rc);
7424}
7425
7426int container_move_objects(LDAP *ldap_handle, char *dn_path, char *dName)
7427{
7428 char *attr_array[3];
7429 LK_ENTRY *group_base;
7430 LK_ENTRY *pPtr;
7431 int group_count;
7432 char filter[512];
7433 char new_cn[128];
7434 char temp[256];
7435 int rc;
7436 int NumberOfEntries = 10;
7437 int i;
7438 int count;
7439
7440 rc = ldap_set_option(ldap_handle, LDAP_OPT_SIZELIMIT, &NumberOfEntries);
7441
7442 for (i = 0; i < 3; i++)
7443 {
7444 memset(filter, '\0', sizeof(filter));
7445
7446 if (i == 0)
7447 {
7448 strcpy(filter, "(!(|(objectClass=computer)"
7449 "(objectClass=organizationalUnit)))");
7450 attr_array[0] = "cn";
7451 attr_array[1] = NULL;
7452 }
7453 else if (i == 1)
7454 {
7455 strcpy(filter, "(objectClass=computer)");
7456 attr_array[0] = "cn";
7457 attr_array[1] = NULL;
7458 }
7459 else
7460 {
7461 strcpy(filter, "(objectClass=organizationalUnit)");
7462 attr_array[0] = "ou";
7463 attr_array[1] = NULL;
7464 }
7465
7466 while (1)
7467 {
7468 if ((rc = linklist_build(ldap_handle, dName, filter, attr_array,
7469 &group_base, &group_count,
7470 LDAP_SCOPE_SUBTREE)) != LDAP_SUCCESS)
7471 {
7472 break;
7473 }
7474
7475 if (group_count == 0)
7476 break;
7477
7478 pPtr = group_base;
7479
7480 while(pPtr)
7481 {
7482 if (!strcasecmp(pPtr->attribute, "cn"))
7483 {
7484 sprintf(new_cn, "cn=%s", pPtr->value);
7485 if (i == 0)
7486 sprintf(temp, "%s,%s", orphans_other_ou, dn_path);
7487 if (i == 1)
7488 sprintf(temp, "%s,%s", orphans_machines_ou, dn_path);
7489 count = 1;
7490
7491 while (1)
7492 {
7493 rc = ldap_rename_s(ldap_handle, pPtr->dn, new_cn, temp,
7494 TRUE, NULL, NULL);
7495 if (rc == LDAP_ALREADY_EXISTS)
7496 {
7497 sprintf(new_cn, "cn=%s_%d", pPtr->value, count);
7498 ++count;
7499 }
7500 else
7501 break;
7502 }
7503 }
7504 else if (!strcasecmp(pPtr->attribute, "ou"))
7505 {
7506 rc = ldap_delete_s(ldap_handle, pPtr->dn);
7507 }
7508
7509 pPtr = pPtr->next;
7510 }
7511
7512 linklist_free(group_base);
7513 group_base = NULL;
7514 group_count = 0;
7515 }
7516 }
7517
7518 return(0);
7519}
7520
7521int get_machine_ou(LDAP *ldap_handle, char *dn_path, char *member,
7522 char *machine_ou, char *NewMachineName)
7523{
7524 LK_ENTRY *group_base;
7525 int group_count;
7526 int i;
7527 char filter[128];
7528 char *attr_array[3];
7529 char cn[256];
7530 char dn[256];
7531 char temp[256];
7532 char *pPtr;
7533 int rc;
7534
7535 strcpy(NewMachineName, member);
7536 rc = moira_connect();
7537 rc = GetMachineName(NewMachineName);
7538 moira_disconnect();
7539
7540 if (strlen(NewMachineName) == 0)
7541 {
7542 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7543 member);
7544 return(1);
7545 }
7546
7547 pPtr = NULL;
7548 pPtr = strchr(NewMachineName, '.');
7549
7550 if (pPtr != NULL)
7551 (*pPtr) = '\0';
7552
7553 group_base = NULL;
7554 group_count = 0;
7555 sprintf(filter, "(sAMAccountName=%s$)", NewMachineName);
7556 attr_array[0] = "cn";
7557 attr_array[1] = NULL;
7558 sprintf(temp, "%s", dn_path);
7559
7560 if ((rc = linklist_build(ldap_handle, temp, filter, attr_array,
7561 &group_base, &group_count,
7562 LDAP_SCOPE_SUBTREE)) != 0)
7563 {
7564 com_err(whoami, 0, "Unable to process machine %s : %s",
7565 member, ldap_err2string(rc));
7566 return(1);
7567 }
7568
7569 if (group_count != 1)
7570 {
61a2844b 7571 return(1);
7572 }
7573
7574 strcpy(dn, group_base->dn);
7575 strcpy(cn, group_base->value);
7576
7577 for (i = 0; i < (int)strlen(dn); i++)
7578 dn[i] = tolower(dn[i]);
7579
7580 for (i = 0; i < (int)strlen(cn); i++)
7581 cn[i] = tolower(cn[i]);
7582
7583 linklist_free(group_base);
7584 pPtr = NULL;
7585 pPtr = strstr(dn, cn);
7586
7587 if (pPtr == NULL)
7588 {
7589 com_err(whoami, 0, "Unable to process machine %s",
7590 member);
7591 return(1);
7592 }
7593
7594 pPtr += strlen(cn) + 1;
7595 strcpy(machine_ou, pPtr);
7596 pPtr = NULL;
7597 pPtr = strstr(machine_ou, "dc=");
7598
7599 if (pPtr == NULL)
7600 {
7601 com_err(whoami, 0, "Unable to process machine %s",
7602 member);
7603 return(1);
7604 }
7605
7606 --pPtr;
7607 (*pPtr) = '\0';
7608
7609 return(0);
7610}
7611
7612int machine_move_to_ou(LDAP *ldap_handle, char * dn_path,
7613 char *MoiraMachineName, char *DestinationOu)
7614{
7615 char NewCn[128];
7616 char OldDn[512];
7617 char MachineName[128];
7618 char filter[128];
7619 char *attr_array[3];
7620 char NewOu[256];
7621 char *cPtr = NULL;
7622 int group_count;
7623 long rc;
7624 LK_ENTRY *group_base;
7625
7626 group_count = 0;
7627 group_base = NULL;
7628
7629 strcpy(MachineName, MoiraMachineName);
7630 rc = GetMachineName(MachineName);
7631
7632 if (strlen(MachineName) == 0)
7633 {
7634 com_err(whoami, 0, "Unable to find alais for machine %s in Moira",
7635 MoiraMachineName);
7636 return(1);
7637 }
7638
7639 cPtr = strchr(MachineName, '.');
7640
7641 if (cPtr != NULL)
7642 (*cPtr) = '\0';
7643
7644 sprintf(filter, "(sAMAccountName=%s$)", MachineName);
7645 attr_array[0] = "sAMAccountName";
7646 attr_array[1] = NULL;
7647
7648 if ((rc = linklist_build(ldap_handle, dn_path, filter, attr_array,
7649 &group_base,
7650 &group_count, LDAP_SCOPE_SUBTREE)) != 0)
7651 {
7652 com_err(whoami, 0, "Unable to process machine %s : %s",
7653 MoiraMachineName, ldap_err2string(rc));
7654 return(1);
7655 }
7656
7657 if (group_count == 1)
7658 strcpy(OldDn, group_base->dn);
7659
7660 linklist_free(group_base);
7661 group_base = NULL;
7662
7663 if (group_count != 1)
7664 {
c9ef9269 7665 com_err(whoami, 0, "Unable to find machine %s in directory: %s",
61a2844b 7666 MoiraMachineName);
7667 return(1);
7668 }
7669
7670 sprintf(NewOu, "%s,%s", DestinationOu, dn_path);
7671 cPtr = strchr(OldDn, ',');
7672
7673 if (cPtr != NULL)
7674 {
7675 ++cPtr;
7676 if (!strcasecmp(cPtr, NewOu))
7677 return(0);
7678 }
7679
7680 sprintf(NewCn, "CN=%s", MachineName);
7681 rc = ldap_rename_s(ldap_handle, OldDn, NewCn, NewOu, TRUE, NULL, NULL);
7682
7683 return(rc);
7684}
7685
7686int machine_check(LDAP *ldap_handle, char *dn_path, char *machine_name)
7687{
7688 char Name[128];
7689 char *pPtr;
7690 int rc;
7691
7692 memset(Name, '\0', sizeof(Name));
7693 strcpy(Name, machine_name);
7694 pPtr = NULL;
7695 pPtr = strchr(Name, '.');
7696
7697 if (pPtr != NULL)
7698 (*pPtr) = '\0';
7699
7700 strcat(Name, "$");
7701 return(!(rc = checkADname(ldap_handle, dn_path, Name)));
7702}
7703
7704int machine_get_moira_container(LDAP *ldap_handle, char *dn_path,
7705 char *machine_name, char *container_name)
7706{
7707 int rc;
7708 char *av[2];
7709 char *call_args[2];
7710
7711 av[0] = machine_name;
7712 call_args[0] = (char *)container_name;
7713 rc = mr_query("get_machine_to_container_map", 1, av,
7714 machine_GetMoiraContainer, call_args);
7715 return(rc);
7716}
7717
7718int machine_GetMoiraContainer(int ac, char **av, void *ptr)
7719{
7720 char **call_args;
7721
7722 call_args = ptr;
7723 strcpy(call_args[0], av[1]);
7724 return(0);
7725}
7726
7727int Moira_container_group_create(char **after)
7728{
7729 long rc;
7730 char GroupName[64];
7731 char *argv[20];
7732
7733 memset(GroupName, '\0', sizeof(GroupName));
7734 rc = Moira_groupname_create(GroupName, after[CONTAINER_NAME],
7735 after[CONTAINER_ROWID]);
7736 if (rc)
7737 return rc;
7738
7739 argv[L_NAME] = GroupName;
7740 argv[L_ACTIVE] = "1";
7741 argv[L_PUBLIC] = "0";
7742 argv[L_HIDDEN] = "0";
7743 argv[L_MAILLIST] = "0";
7744 argv[L_GROUP] = "1";
7745 argv[L_GID] = UNIQUE_GID;
7746 argv[L_NFSGROUP] = "0";
7747 argv[L_MAILMAN] = "0";
7748 argv[L_MAILMAN_SERVER] = "[NONE]";
7749 argv[L_DESC] = "auto created container group";
7750 argv[L_ACE_TYPE] = "USER";
7751 argv[L_MEMACE_TYPE] = "USER";
7752 argv[L_ACE_NAME] = "sms";
7753 argv[L_MEMACE_NAME] = "sms";
7754
7755 if (rc = mr_query("add_list", 15, argv, NULL, NULL))
7756 {
7757 com_err(whoami, 0,
7758 "Unable to create container group %s for container %s: %s",
7759 GroupName, after[CONTAINER_NAME], error_message(rc));
7760 }
7761
7762 Moira_setContainerGroup(after[CONTAINER_NAME], GroupName);
7763 Moira_addGroupToParent(after[CONTAINER_NAME], GroupName);
7764
7765 return(rc);
7766}
7767
7768int Moira_container_group_update(char **before, char **after)
7769{
7770 long rc;
7771 char BeforeGroupName[64];
7772 char AfterGroupName[64];
7773 char *argv[20];
7774
7775 if (!strcasecmp(after[CONTAINER_NAME], before[CONTAINER_NAME]))
7776 return(0);
7777
7778 memset(BeforeGroupName, '\0', sizeof(BeforeGroupName));
7779 Moira_getGroupName(after[CONTAINER_NAME], BeforeGroupName, 0);
7780 if (strlen(BeforeGroupName) == 0)
7781 return(0);
7782
7783 memset(AfterGroupName, '\0', sizeof(AfterGroupName));
7784 rc = Moira_groupname_create(AfterGroupName, after[CONTAINER_NAME],
7785 after[CONTAINER_ROWID]);
7786 if (rc)
7787 return rc;
7788
7789 if (strcasecmp(BeforeGroupName, AfterGroupName))
7790 {
7791 argv[L_NAME] = BeforeGroupName;
7792 argv[L_NAME + 1] = AfterGroupName;
7793 argv[L_ACTIVE + 1] = "1";
7794 argv[L_PUBLIC + 1] = "0";
7795 argv[L_HIDDEN + 1] = "0";
7796 argv[L_MAILLIST + 1] = "0";
7797 argv[L_GROUP + 1] = "1";
7798 argv[L_GID + 1] = UNIQUE_GID;
7799 argv[L_NFSGROUP + 1] = "0";
7800 argv[L_MAILMAN + 1] = "0";
7801 argv[L_MAILMAN_SERVER + 1] = "[NONE]";
7802 argv[L_DESC + 1] = "auto created container group";
7803 argv[L_ACE_TYPE + 1] = "USER";
7804 argv[L_MEMACE_TYPE + 1] = "USER";
7805 argv[L_ACE_NAME + 1] = "sms";
7806 argv[L_MEMACE_NAME + 1] = "sms";
7807
7808 if (rc = mr_query("update_list", 16, argv, NULL, NULL))
7809 {
7810 com_err(whoami, 0,
7811 "Unable to rename container group from %s to %s: %s",
7812 BeforeGroupName, AfterGroupName, error_message(rc));
7813 }
7814 }
7815
7816 return(rc);
7817}
7818
7819int Moira_container_group_delete(char **before)
7820{
7821 long rc = 0;
7822 char *argv[13];
7823 char GroupName[64];
7824 char ParentGroupName[64];
7825
7826 memset(ParentGroupName, '\0', sizeof(ParentGroupName));
7827 Moira_getGroupName(before[CONTAINER_NAME], ParentGroupName, 1);
7828
7829 memset(GroupName, '\0', sizeof(GroupName));
7830
7831 if (strcmp(before[CONTAINER_GROUP_NAME], "[none]"))
7832 strcpy(GroupName, before[CONTAINER_GROUP_NAME]);
7833
7834 if ((strlen(ParentGroupName) != 0) && (strlen(GroupName) != 0))
7835 {
7836 argv[0] = ParentGroupName;
7837 argv[1] = "LIST";
7838 argv[2] = GroupName;
7839
7840 if (rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL))
7841 {
7842 com_err(whoami, 0,
7843 "Unable to delete container group %s from list: %s",
7844 GroupName, ParentGroupName, error_message(rc));
7845 }
7846 }
7847
7848 if (strlen(GroupName) != 0)
7849 {
7850 argv[0] = GroupName;
7851
7852 if (rc = mr_query("delete_list", 1, argv, NULL, NULL))
7853 {
7854 com_err(whoami, 0, "Unable to delete container group %s : %s",
7855 GroupName, error_message(rc));
7856 }
7857 }
7858
7859 return(rc);
7860}
7861
7862int Moira_groupname_create(char *GroupName, char *ContainerName,
7863 char *ContainerRowID)
7864{
7865 char *ptr;
7866 char *ptr1;
7867 char temp[64];
7868 char newGroupName[64];
7869 char tempGroupName[64];
7870 char tempgname[64];
7871 char *argv[1];
7872 int i;
7873 long rc;
7874
7875 strcpy(temp, ContainerName);
7876
7877 ptr1 = strrchr(temp, '/');
7878
7879 if (ptr1 != NULL)
7880 {
7881 *ptr1 = '\0';
7882 ptr = ++ptr1;
7883 ptr1 = strrchr(temp, '/');
7884
7885 if (ptr1 != NULL)
7886 {
7887 sprintf(tempgname, "%s-%s", ++ptr1, ptr);
7888 }
7889 else
7890 strcpy(tempgname, ptr);
7891 }
7892 else
7893 strcpy(tempgname, temp);
7894
7895 if (strlen(tempgname) > 25)
7896 tempgname[25] ='\0';
7897
7898 sprintf(newGroupName, "cnt-%s", tempgname);
7899
7900 /* change everything to lower case */
7901 ptr = newGroupName;
7902
7903 while (*ptr)
7904 {
7905 if (isupper(*ptr))
7906 *ptr = tolower(*ptr);
7907
7908 if (*ptr == ' ')
7909 *ptr = '-';
7910
7911 ptr++;
7912 }
7913
7914 strcpy(tempGroupName, newGroupName);
7915 i = (int)'0';
7916
7917 /* append 0-9 then a-z if a duplicate is found */
7918 while(1)
7919 {
7920 argv[0] = newGroupName;
7921
7922 if (rc = mr_query("get_list_info", 1, argv, NULL, NULL))
7923 {
7924 if (rc == MR_NO_MATCH)
7925 break;
7926 com_err(whoami, 0, "Moira error while creating group name for "
7927 "container %s : %s", ContainerName, error_message(rc));
7928 return rc;
7929 }
7930
7931 sprintf(newGroupName, "%s-%c", tempGroupName, i);
7932
7933 if (i == (int)'z')
7934 {
7935 com_err(whoami, 0, "Unable to find a unique group name for "
7936 "container %s: too many duplicate container names",
7937 ContainerName);
7938 return 1;
7939 }
7940
7941 if (i == '9')
7942 i = 'a';
7943 else
7944 i++;
7945 }
7946
7947 strcpy(GroupName, newGroupName);
7948 return(0);
7949}
7950
7951int Moira_setContainerGroup(char *origContainerName, char *GroupName)
7952{
7953 long rc;
7954 char *argv[3];
7955
7956 argv[0] = origContainerName;
7957 argv[1] = GroupName;
7958
7959 if ((rc = mr_query("set_container_list", 2, argv, NULL, NULL)))
7960 {
7961 com_err(whoami, 0,
7962 "Unable to set container group %s in container %s: %s",
7963 GroupName, origContainerName, error_message(rc));
7964 }
7965
7966 return(0);
7967}
7968
7969int Moira_addGroupToParent(char *origContainerName, char *GroupName)
7970 {
7971 char ContainerName[64];
7972 char ParentGroupName[64];
7973 char *argv[3];
7974 long rc;
7975
7976 strcpy(ContainerName, origContainerName);
7977
7978 Moira_getGroupName(ContainerName, ParentGroupName, 1);
7979
7980 /* top-level container */
7981 if (strlen(ParentGroupName) == 0)
7982 return(0);
7983
7984 argv[0] = ParentGroupName;
7985 argv[1] = "LIST";
7986 argv[2] = GroupName;
7987
7988 if ((rc = mr_query("add_member_to_list", 3, argv, NULL, NULL)))
7989 {
7990 com_err(whoami, 0,
7991 "Unable to add container group %s to parent group %s: %s",
7992 GroupName, ParentGroupName, error_message(rc));
7993 }
7994
7995 return(0);
7996 }
7997
7998int Moira_getContainerGroup(int ac, char **av, void *ptr)
7999{
8000 char **call_args;
8001
8002 call_args = ptr;
8003 strcpy(call_args[0], av[1]);
8004
8005 return(0);
8006}
8007
8008int Moira_getGroupName(char *origContainerName, char *GroupName,
8009 int ParentFlag)
8010{
8011 char ContainerName[64];
8012 char *argv[3];
8013 char *call_args[3];
8014 char *ptr;
8015 long rc;
8016
8017 strcpy(ContainerName, origContainerName);
8018
8019 if (ParentFlag)
8020 {
8021 ptr = strrchr(ContainerName, '/');
8022
8023 if (ptr != NULL)
8024 (*ptr) = '\0';
8025 else
8026 return(0);
8027 }
8028
8029 argv[0] = ContainerName;
8030 argv[1] = NULL;
8031 call_args[0] = GroupName;
8032 call_args[1] = NULL;
8033
8034 if (!(rc = mr_query("get_container_list", 1, argv, Moira_getContainerGroup,
8035 call_args)))
8036 {
8037 if (strlen(GroupName) != 0)
8038 return(0);
8039 }
8040
8041 if (rc)
8042 com_err(whoami, 0, "Unable to get container group from container %s: %s",
8043 ContainerName, error_message(rc));
8044 else
8045 com_err(whoami, 0, "Unable to get container group from container %s",
8046 ContainerName);
8047
8048 return(0);
8049}
8050
8051int Moira_process_machine_container_group(char *MachineName, char* GroupName,
8052 int DeleteMachine)
8053{
8054 char *argv[3];
8055 long rc;
8056
8057 if (strcmp(GroupName, "[none]") == 0)
8058 return 0;
8059
8060 argv[0] = GroupName;
8061 argv[1] = "MACHINE";
8062 argv[2] = MachineName;
8063
8064 if (!DeleteMachine)
8065 rc = mr_query("add_member_to_list", 3, argv, NULL, NULL);
8066 else
8067 rc = mr_query("delete_member_from_list", 3, argv, NULL, NULL);
8068
8069 if (rc)
8070 {
8071 com_err(whoami, 0, "Unable to add machine %s to container group%s: %s",
8072 MachineName, GroupName, error_message(rc));
8073 }
8074
8075 return(0);
8076}
8077
8078int GetMachineName(char *MachineName)
8079{
8080 char *args[2];
8081 char NewMachineName[1024];
8082 char *szDot;
8083 int rc = 0;
8084 int i;
8085 DWORD dwLen = 0;
8086 char *call_args[2];
8087
8088 // If the address happens to be in the top-level MIT domain, great!
8089 strcpy(NewMachineName, MachineName);
8090
8091 for (i = 0; i < (int)strlen(NewMachineName); i++)
8092 NewMachineName[i] = toupper(NewMachineName[i]);
8093
8094 szDot = strchr(NewMachineName,'.');
8095
8096 if ((szDot) && (!strcasecmp(szDot+1, DOMAIN_SUFFIX)))
8097 {
8098 return(0);
8099 }
8100
8101 // If not, see if it has a Moira alias in the top-level MIT domain.
8102 memset(NewMachineName, '\0', sizeof(NewMachineName));
8103 args[0] = "*";
8104 args[1] = MachineName;
8105 call_args[0] = NewMachineName;
8106 call_args[1] = NULL;
8107
8108 if (rc = mr_query("get_hostalias", 2, args, ProcessMachineName, call_args))
8109 {
8110 com_err(whoami, 0, "Unable to resolve machine name %s : %s",
8111 MachineName, error_message(rc));
8112 strcpy(MachineName, "");
8113 return(0);
8114 }
8115
8116 if (strlen(NewMachineName) != 0)
8117 strcpy(MachineName, NewMachineName);
8118 else
8119 strcpy(MachineName, "");
8120
8121 return(0);
8122}
8123
8124int ProcessMachineName(int ac, char **av, void *ptr)
8125{
8126 char **call_args;
8127 char MachineName[1024];
8128 char *szDot;
8129 int i;
8130
8131 call_args = ptr;
8132
8133 if (strlen(call_args[0]) == 0)
8134 {
8135 strcpy(MachineName, av[0]);
8136
8137 for (i = 0; i < (int)strlen(MachineName); i++)
8138 MachineName[i] = toupper(MachineName[i]);
8139
8140 szDot = strchr(MachineName,'.');
8141
8142 if ((szDot) && (!strcasecmp(szDot+1,DOMAIN_SUFFIX)))
8143 {
8144 strcpy(call_args[0], MachineName);
8145 }
8146 }
8147
8148 return(0);
8149}
8150
8151void SwitchSFU(LDAPMod **mods, int *UseSFU30, int n)
8152{
8153 int i;
8154
8155 if (*UseSFU30)
8156 {
8157 for (i = 0; i < n; i++)
8158 {
8159 if (!strcmp(mods[i]->mod_type, "msSFU30UidNumber"))
8160 mods[i]->mod_type = "uidNumber";
8161 }
8162
8163 (*UseSFU30) = 0;
8164 }
8165 else
8166 {
8167 for (i = 0; i < n; i++)
8168 {
8169 if (!strcmp(mods[i]->mod_type, "uidNumber"))
8170 mods[i]->mod_type = "msSFU30UidNumber";
8171 }
8172
8173 (*UseSFU30) = 1;
8174 }
8175}
8176
8177int SetHomeDirectory(LDAP *ldap_handle, char *user_name,
8178 char *DistinguishedName,
8179 char *WinHomeDir, char *WinProfileDir,
8180 char **homedir_v, char **winProfile_v,
8181 char **drives_v, LDAPMod **mods,
8182 int OpType, int n)
8183{
61a2844b 8184 char cWeight[3];
8185 char cPath[1024];
8186 char path[1024];
8187 char winPath[1024];
8188 char winProfile[1024];
8189 char homeDrive[8];
8190 char homedir[1024];
8191 char apple_homedir[1024];
8192 char *apple_homedir_v[] = {NULL, NULL};
8193 int last_weight;
8194 int i;
8195 int rc;
8196 LDAPMod *DelMods[20];
5f6343e6 8197 char *argv[3];
8198 char *save_argv[FS_END];
8199 char *fsgroup_save_argv[2];
8200
61a2844b 8201 memset(homeDrive, '\0', sizeof(homeDrive));
8202 memset(path, '\0', sizeof(path));
8203 memset(winPath, '\0', sizeof(winPath));
8204 memset(winProfile, '\0', sizeof(winProfile));
61a2844b 8205
8206 if(!ActiveDirectory)
8207 {
5f6343e6 8208 if (rc = moira_connect())
8209 {
a816420b 8210 critical_alert(whoami, "Ldap incremental",
5f6343e6 8211 "Error contacting Moira server : %s",
8212 error_message(rc));
8213 return;
8214 }
8215
8216 argv[0] = user_name;
8217
8218 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8219 save_argv)))
8220 {
8221 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8222 !strcmp(save_argv[FS_TYPE], "MUL"))
61a2844b 8223 {
5f6343e6 8224
8225 argv[0] = save_argv[FS_NAME];
8226 fsgCount = 0;
8227
8228 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8229 save_fsgroup_info, fsgroup_save_argv)))
61a2844b 8230 {
5f6343e6 8231 if(fsgCount)
8232 {
8233 argv[0] = fsgroup_save_argv[0];
8234
8235 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8236 save_query_info, save_argv)))
8237 {
8238 strcpy(path, save_argv[FS_PACK]);
8239 }
8240 }
61a2844b 8241 }
8242 }
5f6343e6 8243 else
8244 {
8245 strcpy(path, save_argv[FS_PACK]);
8246 }
61a2844b 8247 }
5f6343e6 8248
8249 moira_disconnect();
8250
8251 if (strlen(path))
61a2844b 8252 {
5f6343e6 8253 if (!strnicmp(path, AFS, strlen(AFS)))
61a2844b 8254 {
5f6343e6 8255 sprintf(homedir, "%s", path);
8256 sprintf(apple_homedir, "%s/MacData", path);
8257 homedir_v[0] = homedir;
8258 apple_homedir_v[0] = apple_homedir;
61a2844b 8259 ADD_ATTR("homeDirectory", homedir_v, OpType);
8260 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8261 OpType);
8262 }
8263 }
5f6343e6 8264 else
8265 {
8266 homedir_v[0] = "NONE";
8267 apple_homedir_v[0] = "NONE";
8268 ADD_ATTR("homeDirectory", homedir_v, OpType);
8269 ADD_ATTR("apple-user-homeDirectory", apple_homedir_v,
8270 OpType);
8271 }
8272
61a2844b 8273 return(n);
8274 }
5f6343e6 8275
61a2844b 8276 if ((!strcasecmp(WinHomeDir, "[afs]")) ||
8277 (!strcasecmp(WinProfileDir, "[afs]")))
8278 {
5f6343e6 8279 if (rc = moira_connect())
8280 {
a816420b 8281 critical_alert(whoami, "Ldap incremental",
5f6343e6 8282 "Error contacting Moira server : %s",
8283 error_message(rc));
8284 return;
8285 }
8286
8287 argv[0] = user_name;
61a2844b 8288
5f6343e6 8289 if (!(rc = mr_query("get_filesys_by_label", 1, argv, save_query_info,
8290 save_argv)))
8291 {
8292 if(!strcmp(save_argv[FS_TYPE], "FSGROUP") ||
8293 !strcmp(save_argv[FS_TYPE], "MUL"))
8294 {
8295
8296 argv[0] = save_argv[FS_NAME];
8297 fsgCount = 0;
8298
8299 if (!(rc = mr_query("get_fsgroup_members", 1, argv,
8300 save_fsgroup_info, fsgroup_save_argv)))
8301 {
8302 if(fsgCount)
8303 {
8304 argv[0] = fsgroup_save_argv[0];
8305
8306 if (!(rc = mr_query("get_filesys_by_label", 1, argv,
8307 save_query_info, save_argv)))
8308 {
8309 strcpy(path, save_argv[FS_PACK]);
8310 }
8311 }
8312 }
8313 }
8314 else
8315 {
8316 strcpy(path, save_argv[FS_PACK]);
8317 }
8318 }
8319
8320 moira_disconnect();
61a2844b 8321
5f6343e6 8322 if (strlen(path))
8323 {
8324 if (!strnicmp(path, AFS, strlen(AFS)))
8325 {
8326 AfsToWinAfs(path, winPath);
8327 strcpy(winProfile, winPath);
8328 strcat(winProfile, "\\.winprofile");
8329 }
8330 }
61a2844b 8331 else
8332 return(n);
8333 }
8334
8335 if ((!strcasecmp(WinHomeDir, "[dfs]")) ||
8336 (!strcasecmp(WinProfileDir, "[dfs]")))
8337 {
8338 sprintf(path, "\\\\%s\\dfs\\profiles\\%c\\%s", ldap_domain,
8339 user_name[0], user_name);
8340
8341 if (!strcasecmp(WinProfileDir, "[dfs]"))
8342 {
8343 strcpy(winProfile, path);
8344 strcat(winProfile, "\\.winprofile");
8345 }
8346
8347 if (!strcasecmp(WinHomeDir, "[dfs]"))
8348 strcpy(winPath, path);
8349 }
8350
61a2844b 8351 if (!strcasecmp(WinHomeDir, "[local]"))
8352 memset(winPath, '\0', sizeof(winPath));
8353 else if (!strcasecmp(WinHomeDir, "[afs]") ||
8354 !strcasecmp(WinHomeDir, "[dfs]"))
8355 {
8356 strcpy(homeDrive, "H:");
8357 }
8358 else
8359 {
8360 strcpy(winPath, WinHomeDir);
8361 if (!strncmp(WinHomeDir, "\\\\", 2))
8362 {
8363 strcpy(homeDrive, "H:");
8364 }
8365 }
8366
8367 // nothing needs to be done if WinProfileDir is [afs].
8368 if (!strcasecmp(WinProfileDir, "[local]"))
8369 memset(winProfile, '\0', sizeof(winProfile));
8370 else if (strcasecmp(WinProfileDir, "[afs]") &&
8371 strcasecmp(WinProfileDir, "[dfs]"))
8372 {
8373 strcpy(winProfile, WinProfileDir);
8374 }
8375
8376 if (strlen(winProfile) != 0)
8377 {
8378 if (winProfile[strlen(winProfile) - 1] == '\\')
8379 winProfile[strlen(winProfile) - 1] = '\0';
8380 }
8381
8382 if (strlen(winPath) != 0)
8383 {
8384 if (winPath[strlen(winPath) - 1] == '\\')
8385 winPath[strlen(winPath) - 1] = '\0';
8386 }
8387
8388 if ((winProfile[1] == ':') && (strlen(winProfile) == 2))
8389 strcat(winProfile, "\\");
8390
8391 if ((winPath[1] == ':') && (strlen(winPath) == 2))
8392 strcat(winPath, "\\");
8393
8394 if (strlen(winPath) == 0)
8395 {
8396 if (OpType == LDAP_MOD_REPLACE)
8397 {
8398 i = 0;
8399 DEL_ATTR("homeDirectory", LDAP_MOD_DELETE);
8400 DelMods[i] = NULL;
8401 //unset homeDirectory attribute for user.
8402 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8403 free(DelMods[0]);
8404 }
8405 }
8406 else
8407 {
8408 homedir_v[0] = strdup(winPath);
8409 ADD_ATTR("homeDirectory", homedir_v, OpType);
8410 }
8411
8412 if (strlen(winProfile) == 0)
8413 {
8414 if (OpType == LDAP_MOD_REPLACE)
8415 {
8416 i = 0;
8417 DEL_ATTR("profilePath", LDAP_MOD_DELETE);
8418 DelMods[i] = NULL;
8419 //unset profilePate attribute for user.
8420 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8421 free(DelMods[0]);
8422 }
8423 }
8424 else
8425 {
8426 winProfile_v[0] = strdup(winProfile);
8427 ADD_ATTR("profilePath", winProfile_v, OpType);
8428 }
8429
8430 if (strlen(homeDrive) == 0)
8431 {
8432 if (OpType == LDAP_MOD_REPLACE)
8433 {
8434 i = 0;
8435 DEL_ATTR("homeDrive", LDAP_MOD_DELETE);
8436 DelMods[i] = NULL;
8437 //unset homeDrive attribute for user
8438 rc = ldap_modify_s(ldap_handle, DistinguishedName, DelMods);
8439 free(DelMods[0]);
8440 }
8441 }
8442 else
8443 {
8444 drives_v[0] = strdup(homeDrive);
8445 ADD_ATTR("homeDrive", drives_v, OpType);
8446 }
8447
8448 return(n);
8449}
8450
8451int attribute_update(LDAP *ldap_handle, char *distinguished_name,
8452 char *attribute_value, char *attribute, char *user_name)
8453{
8454 char *mod_v[] = {NULL, NULL};
8455 LDAPMod *DelMods[20];
8456 LDAPMod *mods[20];
8457 int n;
8458 int i;
8459 int rc;
8460
8461 if (strlen(attribute_value) == 0)
8462 {
8463 i = 0;
8464 DEL_ATTR(attribute, LDAP_MOD_DELETE);
8465 DelMods[i] = NULL;
8466 rc = ldap_modify_s(ldap_handle, distinguished_name, DelMods);
8467 free(DelMods[0]);
8468 }
8469 else
8470 {
8471 n = 0;
8472 mod_v[0] = attribute_value;
8473 ADD_ATTR(attribute, mod_v, LDAP_MOD_REPLACE);
8474 mods[n] = NULL;
8475
8476 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8477 mods)) != LDAP_SUCCESS)
8478 {
8479 free(mods[0]);
8480 n = 0;
8481 mod_v[0] = attribute_value;
8482 ADD_ATTR(attribute, mod_v, LDAP_MOD_ADD);
8483 mods[n] = NULL;
8484
8485 if ((rc = ldap_modify_s(ldap_handle, distinguished_name,
8486 mods)) != LDAP_SUCCESS)
8487 {
8488 com_err(whoami, 0, "Unable to change the %s attribute for %s "
c9ef9269 8489 "in the directory : %s",
61a2844b 8490 attribute, user_name, ldap_err2string(rc));
8491 }
8492 }
8493
8494 free(mods[0]);
8495 }
8496
8497 return(rc);
8498}
8499
8500void StringTrim(char *StringToTrim)
8501{
8502 char *t, *s;
8503 char *save;
8504
8505 save = strdup(StringToTrim);
8506
8507 s = save;
8508
8509 while (isspace(*s))
8510 s++;
8511
8512 /* skip to end of string */
8513 if (*s == '\0')
8514 {
8515 if (*save)
8516 *save = '\0';
8517 strcpy(StringToTrim, save);
8518 return;
8519 }
8520
8521 for (t = s; *t; t++)
8522 continue;
8523
8524 while (t > s)
8525 {
8526 --t;
8527 if (!isspace(*t))
8528 {
8529 t++;
8530 break;
8531 }
8532 }
8533
8534 if (*t)
8535 *t = '\0';
8536
8537 strcpy(StringToTrim, s);
8538 return;
8539}
8540
8541int ReadConfigFile(char *DomainName)
8542{
8543 int Count;
8544 int i;
8545 int k;
8546 char temp[256];
8547 char temp1[256];
8548 FILE *fptr;
8549
8550 Count = 0;
8551
8552 sprintf(temp, "%s%s.cfg", CFG_PATH, DomainName);
8553
8554 if ((fptr = fopen(temp, "r")) != NULL)
8555 {
8556 while (fgets(temp, sizeof(temp), fptr) != 0)
8557 {
8558 for (i = 0; i < (int)strlen(temp); i++)
8559 temp[i] = toupper(temp[i]);
8560
8561 if (temp[strlen(temp) - 1] == '\n')
8562 temp[strlen(temp) - 1] = '\0';
8563
8564 StringTrim(temp);
8565
8566 if (strlen(temp) == 0)
8567 continue;
8568
8569 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8570 {
8571 if (strlen(temp) > (strlen(DOMAIN)))
8572 {
8573 strcpy(ldap_domain, &temp[strlen(DOMAIN)]);
8574 StringTrim(ldap_domain);
8575 }
8576 }
8577 else if (!strncmp(temp, REALM, strlen(REALM)))
8578 {
8579 if (strlen(temp) > (strlen(REALM)))
8580 {
8581 strcpy(ldap_realm, &temp[strlen(REALM)]);
8582 StringTrim(ldap_realm);
8583 }
8584 }
8585 else if (!strncmp(temp, PORT, strlen(PORT)))
8586 {
8587 if (strlen(temp) > (strlen(PORT)))
8588 {
8589 strcpy(ldap_port, &temp[strlen(PORT)]);
8590 StringTrim(ldap_port);
8591 }
8592 }
8593 else if (!strncmp(temp, PRINCIPALNAME, strlen(PRINCIPALNAME)))
8594 {
8595 if (strlen(temp) > (strlen(PRINCIPALNAME)))
8596 {
8597 strcpy(PrincipalName, &temp[strlen(PRINCIPALNAME)]);
8598 StringTrim(PrincipalName);
8599 }
8600 }
8601 else if (!strncmp(temp, SERVER, strlen(SERVER)))
8602 {
8603 if (strlen(temp) > (strlen(SERVER)))
8604 {
8605 ServerList[Count] = calloc(1, 256);
8606 strcpy(ServerList[Count], &temp[strlen(SERVER)]);
8607 StringTrim(ServerList[Count]);
8608 ++Count;
8609 }
8610 }
8611 else if (!strncmp(temp, MSSFU, strlen(MSSFU)))
8612 {
8613 if (strlen(temp) > (strlen(MSSFU)))
8614 {
8615 strcpy(temp1, &temp[strlen(MSSFU)]);
8616 StringTrim(temp1);
8617 if (!strcmp(temp1, SFUTYPE))
8618 UseSFU30 = 1;
8619 }
8620 }
8621 else if (!strncmp(temp, GROUP_SUFFIX, strlen(GROUP_SUFFIX)))
8622 {
8623 if (strlen(temp) > (strlen(GROUP_SUFFIX)))
8624 {
8625 strcpy(temp1, &temp[strlen(GROUP_SUFFIX)]);
8626 StringTrim(temp1);
8627 if (!strcasecmp(temp1, "NO"))
8628 {
8629 UseGroupSuffix = 0;
8630 memset(group_suffix, '\0', sizeof(group_suffix));
8631 }
8632 }
8633 }
8634 else if (!strncmp(temp, GROUP_TYPE, strlen(GROUP_TYPE)))
8635 {
8636 if (strlen(temp) > (strlen(GROUP_TYPE)))
8637 {
8638 strcpy(temp1, &temp[strlen(GROUP_TYPE)]);
8639 StringTrim(temp1);
8640 if (!strcasecmp(temp1, "UNIVERSAL"))
8641 UseGroupUniversal = 1;
8642 }
8643 }
8644 else if (!strncmp(temp, SET_GROUP_ACE, strlen(SET_GROUP_ACE)))
8645 {
8646 if (strlen(temp) > (strlen(SET_GROUP_ACE)))
8647 {
8648 strcpy(temp1, &temp[strlen(SET_GROUP_ACE)]);
8649 StringTrim(temp1);
8650 if (!strcasecmp(temp1, "NO"))
8651 SetGroupAce = 0;
8652 }
8653 }
8654 else if (!strncmp(temp, SET_PASSWORD, strlen(SET_PASSWORD)))
8655 {
8656 if (strlen(temp) > (strlen(SET_PASSWORD)))
8657 {
8658 strcpy(temp1, &temp[strlen(SET_PASSWORD)]);
8659 StringTrim(temp1);
8660 if (!strcasecmp(temp1, "NO"))
8661 SetPassword = 0;
8662 }
8663 }
8664 else if (!strncmp(temp, EXCHANGE, strlen(EXCHANGE)))
8665 {
8666 if (strlen(temp) > (strlen(EXCHANGE)))
8667 {
8668 strcpy(temp1, &temp[strlen(EXCHANGE)]);
8669 StringTrim(temp1);
8670 if (!strcasecmp(temp1, "YES"))
8671 Exchange = 1;
8672 }
8673 }
8674 else if (!strncmp(temp, PROCESS_MACHINE_CONTAINER,
8675 strlen(PROCESS_MACHINE_CONTAINER)))
8676 {
8677 if (strlen(temp) > (strlen(PROCESS_MACHINE_CONTAINER)))
8678 {
8679 strcpy(temp1, &temp[strlen(PROCESS_MACHINE_CONTAINER)]);
8680 StringTrim(temp1);
8681 if (!strcasecmp(temp1, "NO"))
8682 ProcessMachineContainer = 0;
8683 }
8684 }
8685 else if (!strncmp(temp, ACTIVE_DIRECTORY,
8686 strlen(ACTIVE_DIRECTORY)))
8687 {
8688 if (strlen(temp) > (strlen(ACTIVE_DIRECTORY)))
8689 {
8690 strcpy(temp1, &temp[strlen(ACTIVE_DIRECTORY)]);
8691 StringTrim(temp1);
8692 if (!strcasecmp(temp1, "NO"))
8693 ActiveDirectory = 0;
8694 }
8695 }
e8332ac3 8696 else if (!strncmp(temp, GROUP_POPULATE_MEMBERS,
8697 strlen(GROUP_POPULATE_MEMBERS)))
8698 {
8699 if (strlen(temp) > (strlen(GROUP_POPULATE_MEMBERS)))
8700 {
8701 strcpy(temp1, &temp[strlen(GROUP_POPULATE_MEMBERS)]);
8702 StringTrim(temp1);
8703 if (!strcasecmp(temp1, "DELETE"))
8704 {
8705 GroupPopulateDelete = 1;
8706 }
8707 }
8708 }
8b76dea3 8709 else if (!strncmp(temp, MAX_MEMBERS, strlen(MAX_MEMBERS)))
8710 {
8711 if (strlen(temp) > (strlen(MAX_MEMBERS)))
8712 {
8713 strcpy(temp1, &temp[strlen(MAX_MEMBERS)]);
8714 StringTrim(temp1);
8715 max_group_members = atoi(temp1);
8716 }
8717 }
61a2844b 8718 else
8719 {
8720 if (strlen(ldap_domain) != 0)
8721 {
8722 memset(ldap_domain, '\0', sizeof(ldap_domain));
8723 break;
8724 }
8725
8726 if (strlen(temp) != 0)
8727 strcpy(ldap_domain, temp);
8728 }
8729 }
8730 fclose(fptr);
8731 }
8732
8733 if (strlen(ldap_domain) == 0)
8734 {
8735 strcpy(ldap_domain, DomainName);
8736 }
8737
8738 if (Count == 0)
8739 return(0);
8740
8741 for (i = 0; i < Count; i++)
8742 {
8743 if (ServerList[i] != 0)
8744 {
8745 for (k = 0; k < (int)strlen(ServerList[i]); k++)
8746 ServerList[i][k] = toupper(ServerList[i][k]);
8747 }
8748 }
8749
8750 return(0);
8751}
8752
8753int ReadDomainList()
8754{
8755 int Count;
8756 int i;
8757 char temp[128];
8758 char temp1[128];
8759 FILE *fptr;
8760 unsigned char c[11];
8761 unsigned char stuff[256];
8762 int rc;
8763 int ok;
8764
8765 Count = 0;
8766 sprintf(temp, "%s%s", CFG_PATH, WINADCFG);
8767
8768 if ((fptr = fopen(temp, "r")) != NULL)
8769 {
8770 while (fgets(temp, sizeof(temp), fptr) != 0)
8771 {
8772 for (i = 0; i < (int)strlen(temp); i++)
8773 temp[i] = toupper(temp[i]);
8774
8775 if (temp[strlen(temp) - 1] == '\n')
8776 temp[strlen(temp) - 1] = '\0';
8777
8778 StringTrim(temp);
8779
8780 if (strlen(temp) == 0)
8781 continue;
8782
8783 if (!strncmp(temp, DOMAIN, strlen(DOMAIN)))
8784 {
8785 if (strlen(temp) > (strlen(DOMAIN)))
8786 {
8787 strcpy(temp1, &temp[strlen(DOMAIN)]);
8788 StringTrim(temp1);
8789 strcpy(temp, temp1);
8790 }
8791 }
8792
8793 strcpy(DomainNames[Count], temp);
8794 StringTrim(DomainNames[Count]);
8795 ++Count;
8796 }
8797
8798 fclose(fptr);
8799 }
8800
8801 if (Count == 0)
8802 {
a816420b 8803 critical_alert(whoami, "incremental", "%s", "ldap.incr cannot run due to a "
61a2844b 8804 "configuration error in ldap.cfg");
8805 return(1);
8806 }
8807
8808 return(0);
8809}
8810
8811int email_isvalid(const char *address) {
8812 int count = 0;
8813 const char *c, *domain;
8814 static char *rfc822_specials = "()<>@,;:\\\"[]";
8815
8816 if(address[strlen(address) - 1] == '.')
8817 return 0;
8818
8819 /* first we validate the name portion (name@domain) */
8820 for (c = address; *c; c++) {
8821 if (*c == '\"' && (c == address || *(c - 1) == '.' || *(c - 1) ==
8822 '\"')) {
8823 while (*++c) {
8824 if (*c == '\"')
8825 break;
8826 if (*c == '\\' && (*++c == ' '))
8827 continue;
8828 if (*c <= ' ' || *c >= 127)
8829 return 0;
8830 }
8831
8832 if (!*c++)
8833 return 0;
8834 if (*c == '@')
8835 break;
8836 if (*c != '.')
8837 return 0;
8838 continue;
8839 }
8840
8841 if (*c == '@')
8842 break;
8843 if (*c <= ' ' || *c >= 127)
8844 return 0;
8845 if (strchr(rfc822_specials, *c))
8846 return 0;
8847 }
8848
8849 if (c == address || *(c - 1) == '.')
8850 return 0;
8851
8852 /* next we validate the domain portion (name@domain) */
8853 if (!*(domain = ++c)) return 0;
8854 do {
8855 if (*c == '.') {
8856 if (c == domain || *(c - 1) == '.')
8857 return 0;
8858 count++;
8859 }
8860 if (*c <= ' ' || *c >= 127)
8861 return 0;
8862 if (strchr(rfc822_specials, *c))
8863 return 0;
8864 } while (*++c);
8865
8866 return (count >= 1);
8867}
8868
8869int find_homeMDB(LDAP *ldap_handle, char *dn_path, char **homeMDB,
8870 char **homeServerName)
8871{
8872 LK_ENTRY *group_base;
8873 LK_ENTRY *sub_group_base;
8874 LK_ENTRY *gPtr;
8875 LK_ENTRY *sub_gPtr;
8876 int group_count;
8877 int sub_group_count;
8878 char filter[1024];
8879 char sub_filter[1024];
8880 char search_path[1024];
8881 char range[1024];
8882 char *attr_array[3];
8883 char *s;
8884 int homeMDB_count = -1;
8885 int rc;
8886 int i;
8887 int mdbbl_count;
8888 int rangeStep = 1500;
8889 int rangeLow = 0;
8890 int rangeHigh = rangeLow + (rangeStep - 1);
8891 int isLast = 0;
8892
8893 /* Grumble..... microsoft not making it searchable from the root *grr* */
8894
8895 memset(filter, '\0', sizeof(filter));
8896 memset(search_path, '\0', sizeof(search_path));
8897
8898 sprintf(filter, "(objectClass=msExchMDB)");
8899 sprintf(search_path, "CN=Configuration,%s", dn_path);
8900 attr_array[0] = "distinguishedName";
8901 attr_array[1] = NULL;
8902
8903 group_base = NULL;
8904 group_count = 0;
8905
8906 if ((rc = linklist_build(ldap_handle, search_path, filter, attr_array,
8907 &group_base, &group_count,
8908 LDAP_SCOPE_SUBTREE)) != 0)
8909 {
8910 com_err(whoami, 0, "Unable to find msExchMDB %s",
8911 ldap_err2string(rc));
8912 return(rc);
8913 }
8914
8915 if (group_count)
8916 {
8917 gPtr = group_base;
8918
8919 while(gPtr) {
8920 if (((s = strstr(gPtr->dn, "Public")) != (char *) NULL) ||
8921 ((s = strstr(gPtr->dn, "Recover")) != (char *) NULL) ||
8922 ((s = strstr(gPtr->dn, "Reserve")) != (char *) NULL))
8923 {
8924 gPtr = gPtr->next;
8925 continue;
8926 }
8927
8928 /*
8929 * Due to limits in active directory we need to use the LDAP
8930 * range semantics to query and return all the values in
8931 * large lists, we will stop increasing the range when
8932 * the result count is 0.
8933 */
8934
8935 i = 0;
8936 mdbbl_count = 0;
8937
8938 for(;;)
8939 {
8940 memset(sub_filter, '\0', sizeof(sub_filter));
8941 memset(range, '\0', sizeof(range));
8942 sprintf(sub_filter, "(objectClass=msExchMDB)");
8943
8944 if(isLast)
8945 sprintf(range, "homeMDBBL;Range=%d-*", rangeLow);
8946 else
8947 sprintf(range, "homeMDBBL;Range=%d-%d", rangeLow, rangeHigh);
8948
8949 attr_array[0] = range;
8950 attr_array[1] = NULL;
8951
8952 sub_group_base = NULL;
8953 sub_group_count = 0;
8954
8955 if ((rc = linklist_build(ldap_handle, gPtr->dn, sub_filter,
8956 attr_array, &sub_group_base,
8957 &sub_group_count,
8958 LDAP_SCOPE_SUBTREE)) != 0)
8959 {
8960 com_err(whoami, 0, "Unable to find homeMDBBL %s",
8961 ldap_err2string(rc));
8962 return(rc);
8963 }
8964
8965 if(!sub_group_count)
8966 {
8967 if(isLast)
8968 {
8969 isLast = 0;
8970 rangeLow = 0;
8971 rangeHigh = rangeLow + (rangeStep - 1);
8972 break;
8973 }
8974 else
8975 isLast++;
8976 }
8977
8978 mdbbl_count += sub_group_count;
8979 rangeLow = rangeHigh + 1;
8980 rangeHigh = rangeLow + (rangeStep - 1);
8981 }
8982
8983 /* First time through, need to initialize or update the least used */
8984
8985 com_err(whoami, 0, "Mail store %s, count %d", gPtr->dn,
8986 mdbbl_count);
8987
8988 if(mdbbl_count < homeMDB_count || homeMDB_count == -1)
8989 {
8990 homeMDB_count = mdbbl_count;
8991 *homeMDB = strdup(gPtr->dn);
8992 }
8993
8994 gPtr = gPtr->next;
8995 linklist_free(sub_group_base);
8996 }
8997 }
8998
8999 linklist_free(group_base);
9000
9001 /*
9002 * Ok found the server least allocated need to now query to get its
9003 * msExchHomeServerName so we can set it as a user attribute
9004 */
9005
9006 attr_array[0] = "legacyExchangeDN";
9007 attr_array[1] = NULL;
9008
9009 group_count = 0;
9010 group_base = NULL;
9011
9012 if ((rc = linklist_build(ldap_handle, *homeMDB, filter,
9013 attr_array, &group_base,
9014 &group_count,
9015 LDAP_SCOPE_SUBTREE)) != 0)
9016 {
9017 com_err(whoami, 0, "Unable to find msExchHomeServerName %s",
9018 ldap_err2string(rc));
9019 return(rc);
9020 }
9021
9022 if(group_count)
9023 {
9024 *homeServerName = strdup(group_base->value);
9025 if((s = strrchr(*homeServerName, '/')) != (char *) NULL)
9026 {
9027 *s = '\0';
9028 }
9029 }
9030
9031 linklist_free(group_base);
9032
9033 return(rc);
9034}
9035
9036char *lowercase(char *s)
9037{
9038 char *p;
9039
9040 for (p = s; *p; p++)
9041 {
9042 if (isupper(*p))
9043 *p = tolower(*p);
9044 }
9045 return s;
9046}
9047
9048char *uppercase(char *s)
9049{
9050 char *p;
9051
9052 for (p = s; *p; p++)
9053 {
9054 if (islower(*p))
9055 *p = toupper(*p);
9056 }
9057 return s;
9058}
9059
9060char *escape_string(char *s)
9061{
9062 char *p, *q;
9063 char string[1024];
9064 char temp[1024];
9065 int i = 0;
9066 int spaces = 0;
9067
9068 memset(string, '\0', sizeof(string));
9069
9070 q = s;
9071
61a2844b 9072 /* Escape any special characters */
9073
9074 for(; *q != '\0'; q++) {
9075 if(*q == ',')
9076 string[i++] = '\\';
9077 if(*q == '+')
9078 string[i++] = '\\';
9079 if(*q == '"')
9080 string[i++] = '\\';
9081 if(*q == '\\')
9082 string[i++] = '\\';
9083 if(*q == '<')
9084 string[i++] = '\\';
9085 if(*q == '>')
9086 string[i++] = '\\';
9087 if(*q == ';')
9088 string[i++] = '\\';
9089 if(*q == '#')
9090 string[i++] = '\\';
9091 if(*q == '=')
9092 string[i++] = '\\';
9093
9094 string[i++] = *q;
9095 }
9096
9097 return strdup(string);
9098}
9099
9100int save_query_info(int argc, char **argv, void *hint)
9101{
9102 int i;
9103 char **nargv = hint;
9104
9105 for(i = 0; i < argc; i++)
9106 nargv[i] = strdup(argv[i]);
9107
9108 return MR_CONT;
9109}
5f6343e6 9110
9111int save_fsgroup_info(int argc, char **argv, void *hint)
9112{
9113 int i;
9114 char **nargv = hint;
9115
9116 if(!fsgCount)
9117 {
9118 for(i = 0; i < argc; i++)
9119 nargv[i] = strdup(argv[i]);
9120
9121 fsgCount++;
9122 }
9123
9124 return MR_CONT;
9125}
d6232129 9126
9127int contains_member(LDAP *ldap_handle, char *dn_path, char *group_name,
9128 char *UserOu, char *user_name)
9129{
9130 char search_filter[1024];
9131 char *attr_array[3];
9132 LK_ENTRY *group_base;
9133 int group_count;
9134 int rc;
9135 char temp[256];
9136
9137 if(ActiveDirectory)
9138 {
9139 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
9140 }
9141 else
9142 {
9143 if(!strcmp(UserOu, user_ou))
9144 sprintf(temp, "uid=%s,%s,%s", user_name, UserOu, dn_path);
9145 else
9146 sprintf(temp, "CN=%s,%s,%s", user_name, UserOu, dn_path);
9147 }
9148
9149 group_base = NULL;
9150 group_count = 0;
9151
9152 sprintf(search_filter, "(&(objectClass=group)(cn=%s)(member=%s))",
9153 group_name, temp);
9154
9155 attr_array[0] = "mitMoiraId";
9156 attr_array[1] = NULL;
9157
9158 if ((rc = linklist_build(ldap_handle, dn_path, search_filter,
9159 attr_array, &group_base, &group_count,
9160 LDAP_SCOPE_SUBTREE)) != 0)
9161 {
9162 com_err(whoami, 0, "Unable to check group %s for membership of %s : %s",
9163 group_name, user_name, ldap_err2string(rc));
9164 return(-1);
9165 }
9166
9167 if (group_count)
58995e0a 9168 rc = 1;
d6232129 9169 else
58995e0a 9170 rc = 0;
d6232129 9171
9172 linklist_free(group_base);
9173 group_count = 0;
9174 group_base = NULL;
9175
9176 return(rc);
9177}
This page took 5.728501 seconds and 5 git commands to generate.