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